Well, I've gotten through my first round of experimenting with Cells, and I have to say I like it a lot. If you want to see some code, take a look at:
http://common-lisp.net/websvn/filedetails.php?repname=graphic-forms&path...
which is the data model for a simple game where you click on blocks to score points (and where the remaining blocks fall down to fill in the hole(s)). The game gets progressively harder as you pass from one level to the next. The UI displays the current level, current score, and points needed for the next level. Screenshot here:
http://sourceforge.net/project/screenshots.php?group_id=163034&ssid=3154...
If you look at the model, there is a shape-data slot that really ought to be ephemeral based on how the score slot's formula depends on it (the 'shape' score should only be added to the overall score tally once, no matter how many times the UI asks for the score). But I was seeing some intermittent behavior where it seemed like the shape-data value had already been propagated (and thus cleared) by the time that my UI code asked for the score. So I took the :ephemeral attribute off until I get some more time to figure that out. I'm sure this is a bug in my understanding, not in Cells.
It would be good to document some typical strategies for dealing with self-referential slots (circularity) but in thinking about how I would describe what I did, I can see how it would be hard to explain to someone else :-)
-- Jack Unrue
On 4/9/06, Jack Unrue jdunrue@gmail.com wrote:
Well, I've gotten through my first round of experimenting with Cells, and I have to say I like it a lot. If you want to see some code, take a look at:
http://common-lisp.net/websvn/filedetails.php?repname=graphic-forms&path...
which is the data model for a simple game where you click on blocks to score points (and where the remaining blocks fall down to fill in the hole(s)). The game gets progressively harder as you pass from one level to the next. The UI displays the current level, current score, and points needed for the next level. Screenshot here:
http://sourceforge.net/project/screenshots.php?group_id=163034&ssid=3154...
If you look at the model, there is a shape-data slot that really ought to be ephemeral based on how the score slot's formula depends on it (the 'shape' score should only be added to the overall score tally once, no matter how many times the UI asks for the score). But I was seeing some intermittent behavior where it seemed like the shape-data value had already been propagated (and thus cleared) by the time that my UI code asked for the score. So I took the :ephemeral attribute off until I get some more time to figure that out. I'm sure this is a bug in my understanding, not in Cells.
It would be good to document some typical strategies for dealing with self-referential slots (circularity) but in thinking about how I would describe what I did, I can see how it would be hard to explain to someone else :-)
it is pretty clear to me as an old Cells hand. I am toast right now, but I'll send some comments tomorrow. One Q: where does game-shape-data get called, in some imperative logic responding to events, that detects that a shape has been placed?
ken
On 4/9/06, Ken Tilton kentilton@gmail.com wrote:
it is pretty clear to me as an old Cells hand. I am toast right now, but I'll send some comments tomorrow. One Q: where does game-shape-data get called, in some imperative logic responding to events, that detects that a shape has been placed?
In tiles-panel.lisp, look for gfw:event-mouse-up. Basically if the location of the mouse up occurs within the same tile shape as the mouse down that started the selection, then the list of points comprising that shape become the input data that tickles the game model. The internal representation of the board gets modified accordingly (the selected shape is removed and points are awarded), then the scoreboard and tile panels are told to redraw themselves via observers on the score and tiles slots.
Thanks for taking a look.
-- Jack Unrue
Jack Unrue wrote:
On 4/9/06, Ken Tilton kentilton@gmail.com wrote:
it is pretty clear to me as an old Cells hand. I am toast right now, but I'll send some comments tomorrow. One Q: where does game-shape-data get called, in some imperative logic responding to events, that detects that a shape has been placed?
In tiles-panel.lisp, look for gfw:event-mouse-up. Basically if the location of the mouse up occurs within the same tile shape as the mouse down that started the selection, then the list of points comprising that shape become the input data that tickles the game model.
Ok. One thing that might pay off in more elaborate (as in reall-world) models is to move as much semantics as possible into the Cells realm. In this case you might just have the event handler do:
(setf (clicked shape) t)
...where clicked is ephemeral. Then elsewhere some other ephemeral "new-points-earned" ephemeral converts that to points, while other cells might worry about a sound to be generated or graphic transformations to apply. In my GUIs I go further and get mouse-downs and mouse-ups into the game. Since I am usually rolling my own GUI, I need this to do the higlighting changes as mouse-down, mouse-over, and mouse-up events go by. IIRC, in Cello I even created a class called mouse-click, which came into existence on mouse-down (remembering on which GUI element if any the mousedown happened) and then expired on mouseup. anyway, what you did is fine, just offering food for thought if you kepe going with cells.
The internal representation of the board gets modified accordingly (the selected shape is removed and points are awarded), then the scoreboard and tile panels are told to redraw themselves via observers on the score and tiles slots.
Yep. Again, if one wants to go a little further one can have ruled cells for appearance that watched other cells for score and and other game state. The nice thing here is that there are only so many (tho quite a few) cells that affect screen draws. Once all those have observers that call the "update me" function, yer done. From now on one just rights rules connecting appearance to program state and it all Just Works. (btw, in this case the "update me" function is merely flagging things for update, otherwise it gets done repeatedly as dozens of appearance cells decide they have changed.
kt