Add grid lines and Kinematic objects

CODE can be found at my Git Repository

Add background with lines

We want a grid, but we don’t want to draw the lines every frame. We will create a white background with lines on it using code.

#colors
white = (255,255,255)
black = (0,0,0)

#clear the display
screen.fill(white)

# Create a background
background = pygame.Surface.copy(screen)

#draw lines for the grid on the background
for y in range(0, height, 40):
    pygame.draw.line(background, black, (0,y), (width,y))
for x in range(0, width,  40):
    pygame.draw.line(background, black, (x,0), (x,height))

# blit the background to screen
screen.blit(background,(0,0))

We replace the

screen.fill(white) 

in the loop with

screen.blit(background,(0,0))

We

  • set the screen white
  • copied the screen to a background image
  • added black color
  • draw our lines, using length and height and spaced every 40 pixels
  • then draw that image to the screen every frame

Scale player image

The player looks large compared with the grid. This step is simple. Place the code below after the image loading

self.img = pygame.transform.scale_by(self.img, 0.5 )

After play testing we see we need to adjust the position and set the speed to about half

player = GameObject("assets/player/blue_body_squircle.png", (width/2 - 20, height/2))
speed = 0.2

Add a Kinematic Object

Kinetics and Kinematics are two of the main branches of dynamics, that is, the study of forces and motion.

  • Kinetics deals with forces and motion only and reveals how forces affect motion.

  • Kinematics deals with motion only or how an object moves through space without reference to any associated force.

We are not using a force so kinematic it is.

class KinematicObject(GameObject):
    def __init__(self, img_name, initial_pos):
        super().__init__(img_name, initial_pos)
        

    def move(self, dir, dt , speed):
        self.speed = speed
        velocity = (int(dir[0] * dt * self.speed), int(dir[1] * dt * self.speed))
        self.rect = self.rect.move(velocity)

We add the object. So we grab the move code we have and place it in the new object.

We change the code where we create the player to use the new object

player = KinematicObject( "assets/player/blue_body_squircle.png" ,(width/2 - 20, height/2) )

And finally we change all that velocity code to a simple call.

player.move(dir, dt, speed)

Add a Player Object

Now we reach the git commit “Add Player Object”

The final clean up we have been delaying for player - we move any remaining player related code into the player object.

class Player(KinematicObject):
    speed = 0.2

    def __init__(self, initial_pos, speed):
        super().__init__("assets/player/blue_body_squircle.png",  initial_pos)
        self.speed = speed

    def move(self, dir, dt ):
        super().move(dir, dt, self.speed)

    def set_speed(self, speed):
        self.speed = speed

This change includes our image name. We hide it and speed in the Player class. Plus I will want to be able to change the speed. For this we use a “set speed” method sometimes known as a setter.

player move becomes slightly easier

player = Player((width/2 - 20, height/2), 0.2)

and

player.move(dir, dt)

This code is definitely “clean as you go”. Doing a lot, then refactoring later is much more difficult. A large refactor can be necessary if you want to move things around when you have existing code.

In later posts we will deal with

  • a tail
  • eating food
  • Grid movement
  • screen wrap

We don’t get into Score, Menus, Sound etc. Getting some basic idea of using code at the moment is more important than the actual game.

We can come back and address that at another time.