// 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