Part 11: OOP Introduced – Detect collision for multiple objects

11_collisionmultipleobjects

Now to leverage the power of Object oriented programming. Suppose we have multiple walls(rectangles), where shall we store the Pygame.Rect’s that we need?
Will we write 100 such lines for 100 walls?

circlerect.colliderect(wallrect)

The answer is we create a “Wall” class which is akin to a cookie cutter mould for all the walls (it is the template/stencil) and the objects (instances) aka the actual walls (cookies made using the moulds, drawings made using the stencil).

Then for each of the instances of the walls (the actual walls created), we check for collision with the circle.


Let us see how this works and what the syntax is.

Delete or comment out the lines.

#RECTXPOS = 100
#RECTYPOS = 100
##RECT = pygame.Rect(RECTXPOS,RECTYPOS, RECTWIDTH, RECTHEIGHT)
###Last parameter is zero by default
##wallrect = pygame.draw.rect(SCREEN, COLOR, RECT)
#pygame.display.update(wallrect)

Create a “Wall” class that has a template for X, Y positions of any rectangle.
Create a list of Walls (a bag that holds lots of the real walls – instances of Wall). Create Wall objects and add them to the list.
Code..

class Wall():
    def __init__(self, x, y):
        self.rect = pygame.Rect(x,y, RECTWIDTH, RECTHEIGHT)

walls = []
for i in range(0, 2):
    wall = Wall(random.randint(0, SCREENWIDTH),random.randint(0,500))
    walls.append(wall)

The

def __init__(self,x,y):

is the constructor, it is called once when every “Wall” instance is created (akin to when every cookie is cut from the mould). Every “__init__” we pass a parameter(input) called “self”, which is the actual object to the constructor. This is a syntax followed by Python.

Then we assign to “self.rect” – an attribute (nature) that every Wall object will have, the pygame rectangle created using the X and Y coordinates provided.

def __init__(self, x, y):
        self.rect = pygame.Rect(x,y, RECTWIDTH, RECTHEIGHT)

Create an instance of “Wall”, the actual Wall object (the cookie) here.

wall = Wall(random.randint(0, SCREENWIDTH),random.randint(0,SCREENHEIGHT))

Notice, we are not passing “self” (the variable “wall”) here. It is implicit(taken automatically). We only pass two random numbers for the X and Y positions of the rectangle, which is any random number between 0 and 500.

We add the “wall” object to the list (bag) – the variable “walls”.

walls.append(wall)

Inside the “while” loop comment out the place, we redrew the rectangle.

#wallrect = pygame.draw.rect(SCREEN, COLOR, RECT)
#if(circlerect.colliderect(wallrect)):
# print(“collision”)

Draw all the rectangles by retrieving(extracting) the position from the “wall” objects and check if each collides with the circle.

for i in range(0, NOOFWALLS):
        pygame.draw.rect(SCREEN, COLOR, walls[i].rect)
        if(circlerect.colliderect(walls[i].rect)):
            print("collision : " + str(i))

The “i” in the “for” loop will range through 0,1 (1 lesser than the NOOFWALLS – NOOFWALLS times)

print("collision : " + str(i))

is a way to print “collision : 0” or “collision : 1” when the circle collides with the 0th or 1st rectangle.

The entire code.

#Import statements are to enable the code to use the functions from the library
import pygame
import sys
import os
import random
from pygame.locals import *

#instructions to windows to center the game window in the center of
#the screen, which it might ignore
os.environ["SDL_VIDEO_CENTERED"] = "1"

#initialize pygame
pygame.init()

#Right way
SCREENWIDTH = 500
SCREENHEIGHT = 500
SCREENSIZE = [SCREENWIDTH, SCREENHEIGHT]
SCREEN = pygame.display.set_mode(SCREENSIZE)

#caption for the game
pygame.display.set_caption("My first game in pygame")

RADIUS = 20
ZEROINTENSITY = 0
MAXINTENSITY = 255

X = 40
Y = 40
CIRCLEPOS = (X, Y)
COLOR = (random.randint(ZEROINTENSITY, MAXINTENSITY), random.randint(ZEROINTENSITY, MAXINTENSITY), random.randint(ZEROINTENSITY, MAXINTENSITY))
circlerect = pygame.draw.circle(SCREEN, COLOR, CIRCLEPOS, RADIUS)
pygame.display.update(circlerect)

#Draw a rectangle to collide with
RECTWIDTH = 100
RECTHEIGHT = 20
NOOFWALLS = 2

class Wall():
    def __init__(self, x, y):
        self.rect = pygame.Rect(x,y, RECTWIDTH, RECTHEIGHT)

walls = []
for i in range(0, NOOFWALLS):
    wall = Wall(random.randint(0, SCREENWIDTH),random.randint(0,SCREENHEIGHT))
    walls.append(wall)

BLACK = (0,0,0)

while True:
    for events in pygame.event.get():
        if events.type == pygame.QUIT:
            pygame.quit()
            sys.exit()
        #Here for any commands inside the for loop
        #if (events.type == pygame.KEYDOWN) and (events.key == pygame.K_SPACE):
        if (events.type == pygame.MOUSEBUTTONDOWN):
            COLOR = (random.randint(ZEROINTENSITY, MAXINTENSITY), random.randint(ZEROINTENSITY, MAXINTENSITY), random.randint(ZEROINTENSITY, MAXINTENSITY))
            #note- we have skipped the last parameter and by default, 0 is taken
            circlerect = pygame.draw.circle(SCREEN, COLOR, CIRCLEPOS, RADIUS)
            pygame.display.update(circlerect)
    #beware of the positioning of this line. It should be inside the while
    #for all the commands that need to be executed inside the while

    user_input = pygame.key.get_pressed()
    
    if(user_input[pygame.K_UP]):
        Y=Y-1
        if(YSCREENHEIGHT):Y=0
    elif(user_input[pygame.K_LEFT]):
        X=X-1
        if(XSCREENWIDTH):X=0
    CIRCLEPOS = (X,Y)
    #exits the borders reposition

    SCREEN.fill(BLACK)
    circlerect = pygame.draw.circle(SCREEN, COLOR, CIRCLEPOS, RADIUS)
    
    for i in range(0,NOOFWALLS):
        pygame.draw.rect(SCREEN, COLOR, walls[i].rect)
        if(circlerect.colliderect(walls[i].rect)):
            print("collision : " + str(i))
    pygame.display.update()

What can be the next challenge? Instead of rectangles as Walls, can we have an image instead?
How do we draw images? Pygame has Sprites, that supports handling many actors (objects) in the game. This is akin to the “Sprite” definition in Scratch.
And on collision, how do we make the “Wall” or “obstacle” disappear?

Are we not very close to creating a full fledged game? Do not quit and persevere.
Come on!

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s