A game a week #2
2021-03-19
I captured the momentum of last week, and began this game on Sunday evening.
There was certainly more time spent on this game, but I spread it out over several evenings. I've also shared the first week's post with a few people, and I've had some interesting conversations. I've started to develop a rough project list in my head, building complexity. This list is very likely to change.
- Tetris
- Sokoban
- Conway's Game of Life
- A perspective/sprite scale based racing game (think Outrun)
- A raycaster
snake.py
This was a level up in complexity from last week. There was a lot more game state to manage, and while I understood the game pretty well before I began, there was some mis-steps.
I managed to build this quite quickly. I probably has the game fully 'working' after two short sessions of work, so maybe 3 hours in total. I then has plenty of remaining time to refactor, which I'm glad of. The final version of the code (which would probably be tightened up further) is much more elegant due to the time I could spend analysing the code and making improvements.
I also spent time on 'game'-related things (on the web, I guess we would call this UX), like a score and a lives system, useful information for the player in intermission screens, and some really basic sound. All these add up to make it feel like a real game rather than pong.py
from last week.
I think my primary problem was one of manageing game state. I ended up with an awkward system where the SnakeGame
contains the Snake
instance, and sometimes when they need to reference each other (like in Snake.collide()
), I pass a complete reference to the game. This is pointless, and really both should just be in the global scope for a simple game like this.
I also think there is some subtle duplication between the collision detection functions on the Snake, and the SnakeGame.empty_location()
function. empty_location()
is used to find a position in the game world which is not occuped by anything else (eg. a wall, or the snake's body), in order to place down a new item of food. So really this is just the inverse of detecting a collision, so I think I could refactor this more to simplify.
While I was browsing the PyGame documentation, I came across the Rect
collision detection functions, too. So I wonder if there's a 'stateless' version of this game which just operates based on collisions between thing on the screen. I expect I'll explore that more soon, because I want to make better use of the Sprite
classes rather than just drawing everything manually as tiles.