// Photon.h -- written 16 Mar 1996 by Max Hailperin
//
// Declares the class Photon, which is the "heart" of the Photon game.
//
// Its primary responsibility is mediating between the
// graphical user interface script on the one hand and the Obstacles and Ball
// on the other hand.
//
// It keeps track of all the Obstacles in the field, and of the Ball, and
// when asked by the user interface to do a time step makes use of those
// other objects.
//
// Conversely, it keeps track of the underlying TCL interpreter and its drawing
// canvas, so that when an Obstacle or Ball wants to draw itself on the canvas
// (for example), it can do so with the Photon object's help.
#ifndef PHOTON_H
#define PHOTON_H
#include
class Ball;
class Obstacle;
class Photon {
public:
// createCmd is installed as the TCL command called photon, used so that
// the user interface script (written in TCL) can create a new Photon game
static int createCmd(ClientData, Tcl_Interp *, int argc, char *argv[]);
// the next two member functions let an Obstacle or Ball get the TCL
// interpreter and canvas, for drawing etc.
Tcl_Interp *interpreter() {return interp;}
const char *canvas() {return cnvs;}
// to actually do anything in the interpreter, you can eval a script
// or as a shortcut you can use the draw command, which prepends the
// canvas's name
int eval(char *script) {return Tcl_Eval(interp, script);}
int draw(const char *scriptTail);
// mapX and mapY translate coordinates from the system used in the program
// to real pixel coordinates, as needed for drawing on the canvas; the
// program's coordinate system has integer coordinates at the centers of
// the playing field's cells, with (0,0) being the center of the lower
// left cell; pixel coordinates have (0,0) at the top left w/ a reversed y-axis
int mapX(float x) {return int((x+0.5f)*fieldWidthPixels/fieldWidth);}
int mapY(float y)
{return int((fieldHeight-y-0.5f)*fieldHeightPixels/fieldHeight);}
// moveObstacle moves the obstacle in a particular cell to another
// cell, which must be unoccupied; this doesn't update the canvas display
// at all, it just changes the record of what's where; see moveCanvasItem
void moveObstacle(int oldX, int oldY, int newX, int newY);
// moveCanvasItem moves a particular visual item on the canvas to a
// new location; the old and new locations are give in the standard
// cell coordinate system (*not* pixels); this can be used by an Obstacle
// or Ball to move its visual representation, but other record keeping
// will need doing as well -- see e.g. moveObstacle
int moveCanvasItem(int id, int oldX, int oldY, int newX, int newY);
// deleteCanvasItem does what it says
int deleteCanvasItem(int id);
// pickTargetLocation finds a cell with no Obstacle or Ball in it
void pickTargetLocation(int &x, int &y);
private:
enum Command {none, neg, pos, erase};
int doTimeStep(Command);
static int cmd(ClientData thePhoton, Tcl_Interp *interp,
int argc, char *argv[]);
static void deleteProc(ClientData thePhoton);
Photon(Tcl_Interp *theInterp, char *canvas);
int okForTarget(int x, int y);
~Photon();
Tcl_Interp *interp;
char *cnvs;
int tclCode;
Ball *ball;
enum {fieldWidth=30, fieldHeight=30};
int fieldWidthPixels, fieldHeightPixels;
Obstacle *field[fieldWidth][fieldHeight];
};
#endif