Minigame Monday: Break-In
Break-In:
- The concept:
This time I made a twist on the classic game breakout. Rather than controlling a paddle to hit blocks with the ball at the top of the screen, instead you would control the blocks themselves at the bottom of the screen. As before, if the ball gets past the blocks, you would lose (or as I later decided was fairer, lose a life). Again because of needing a simple graphical interface, I chose Python and pygame.
- The challenge:
The complexity of this minigame comes from implementing the physics of the ball. As is quite common, I decided to calculate positions in line with draw calls, so every loop the input would be handled once, the movement of the ball would be updated once, and the screen would be drawn once. I decided that the ball at the start should be moving with a set speed, but in a random direction, so I added a bit of Pythagoras to allow this to be a settable parameter in the code. The details of the ball can be given by two tuples (for people more used to C++ than Python read tuple as '2D array'), one to store the position of the ball, and one to store the movement of the ball. I was a bit surprised to find that Python doesn't support tuple arithmetic (perhaps I shouldn't have been, seeing as C like languages certainly don't support arithmetic over arrays), so I added some quick helper functions to make the ball calculations more readable:
#Helper functions for tuples
def tupAdd(A, B):
return (A[0] + B[0], A[1] + B[1])
def tupSub(A, B):
return (A[0] - B[0], A[1] - B[1])
The next related challenge is of course collision. For bouncing off the walls this is simple: check if the ball has passed the wall, if so reverse the direction of the ball's movement based on which wall it is (left/right the x component, top is y). For bocks this was a bit more difficult, as I ideally wanted the calculations for collision to happen within the block class only (I made the blocks a separate class for reasons I'll get into in a bit), and then for it to return the new direction of the ball, but with just the position of the ball and the block this wasn't possible. The issue was corners; if the ball had moved into the position of the block at a corner, the block didn't know which direction the ball had come from and could bounce it in the wrong direction as a result. As a result, I moved some of the calculations of the bounce out of the block class, which as it turned out I needed later anyway, because I wanted to modify the speed (and not just the direction) of the ball based on the movements of the blocks, so the player could change it's trajectory.
The reason why I wanted blocks in their own class was because that way instances of the class could be made at the start and stored in a list, then they could be deleted from the list as the blocks are cleared. This is the same rational as you might use by having a prototype in Unity or Unreal, so you can insatiate and remove members as needed.
- The result:
The finished game is decently tricky, but becomes much easier with the right strategy, namely clearing the sides first to give you the maximum space to move, and slowing the x speed of the ball down by hitting it with the paddle moving in the opposite direction to make it easier to aim. There are a number of things I'd look into if I was going to put more time into this project; I'd like to put a bit more into the physics changing as the ball bounces off moving paddles, perhaps do some real world calculations to base the interaction off. As well as that, to expand the game, I could add more levels, with different organisations of blocks, and even different geometry at the top or middle of the screen to make the path of the ball more interesting. You can download the game from https://reddragonmakesgames.itch.io/break-in, and the source code is on Github.
Comments
Post a Comment