Create a Vector class in Pygame

What is Vector?

Suppose we want to move from point A to point B where point A is situated at (33.0, 35.0) and point B is at (55.0, 45.0) then Vector AB will be the different between these two points, or the x and the y distance between this two points is (x2-x1, y2-y1) or (55.0-33.0, 45.0-35.0).

Why do we need to create a vector class?

Vector module helps game developer to perform various operations, for example moves an object from point A to point B as well as find out the vector magnitude of that object, therefore it is always better if we can create a Vector module before we create our game.

Create a Vector2D class in python

Vector class is just like any other module class with methods that we can use to move an object or modify the property of that object.

import math

class Vector2D(object):
    
    def __init__(self, x=0.0, y=0.0):
        self.x = x
        self.y = y
        
    def __str__(self):
        return "(%s, %s)"%(self.x, self.y)
    
    @classmethod
    def next_vector(cls, args):
        return cls(args[2]-args[0], args[3]-args[1])
    
    def get_magnitude(self):
        return math.sqrt( self.x**2 + self.y**2 )
    
    def normalize(self): # find the unit vector
        magnitude = self.get_magnitude()
        self.x /= magnitude
        self.y /= magnitude
        
    # rhs stands for Right Hand Side
    def __add__(self, rhs):
        return Vector2D(self.x + rhs.x, self.y + rhs.y)
    
    def __sub__(self, rhs):
        return Vector2D(self.x - rhs.x, self.y - rhs.y)
    
    def __neg__(self):
        return Vector2D(–self.x, –self.y)
    
    def __mul__(self, scalar):
        return Vector2D(self.x * scalar, self.y * scalar)
    
    def __div__(self, scalar):
        return Vector2D(self.x / scalar, self.y / scalar)

A few methods above are the overload methods where they will be called when the Vector class instance performs certain operation, for example the __div__, __mul__, __sub__ and __add__ method will be called when we divide, multiply, subtract and add two vectors together. The __neg__ method will be called if we want to point a Vector in the opposite direction.

The __init__ method will be called at the moment we initialized the Vector2D’s instance and __str__ will be called when we print that object with the python print function.

The get_magnitude method will return the magnitude of the Vector and the normalize method will divide the x and the y length of the Vector with it’s magnitude.

Finally next_vector will take in the combine value of two tuples and return a new Vector2D object.

Create a separate python module with below script.

from vector2d import Vector2D

if __name__ == "__main__":
    A = (10.0, 20.0)
    B = (30.0, 35.0)
    C = (15.0, 45.0)
    AB = Vector2D.next_vector(A+B)
    BC = Vector2D.next_vector(B+C)
    AC = AB+BC
    print(AC)
    AC = Vector2D.next_vector(A+C)
    print(AC)

If you run the above module then you can see that when you add up two vectors AC = AB + BC the overload __add__ method of vector AB will be called which will then return a new Vector2D object. AC = Vector2D.next_vector(A+C) will create the same outcome as AC = AB + BC when we print the vector out with the print function. In this example the result is (5.0, 25.0).

The above Vector2D function will get you started where you can now include more methods into the Vector2D module for the future expansion purposes.

How to detect boundary in Pygame

When we design a game first thing we need to do is to make sure our game character stays within the game boundary. In order to make sure our game character will move within the game boundary we will create a set of rule such as if the top-left corner of that game character moves pass the x or the y boundary of the screen then we will need to reset the coordinate for the top-left corner of that game character accordingly. Below script will create a bouncing ball which will change color randomly and moves within the boundary of the screen.

import pygame
from pygame.locals import *
from sys import exit

from random import *

pygame.init()
screen = pygame.display.set_mode((640, 480), 0, 32)

clock = pygame.time.Clock()

x, y = 10., 10.
speed_x, speed_y = 100., 90.

circle_radius = 7
circle_pos = (int(x), int(y))


while True:
    
    for event in pygame.event.get():
        if event.type == QUIT:
            exit()
            
    random_color = (randint(100,255), randint(30,255), randint(155,255))
    screen.fill((255, 255, 255))
    
    pygame.draw.circle(screen, random_color, circle_pos, circle_radius)
    
    time_has_passed = clock.tick(30) #return the time delta after each frame
    time_has_passed_in_second = time_has_passed / 1000.0
    
    x += speed_x * time_has_passed_in_second
    y += speed_y * time_has_passed_in_second
    
    # If the ball goes off the edge of the screen,
    # reset it's position and then move it in the opposite direction
    if x > 640 - (circle_radius * 2):
        speed_x = -speed_x
        x = 640 - (circle_radius * 2)
    elif x < 0:
        speed_x = -speed_x
        x = 0.
    if y > 480 - (circle_radius * 2):
        speed_y = -speed_y
        y = 480 - (circle_radius * 2)
    elif y < 0:
        speed_y = -speed_y
        y = 0
        
    circle_pos = (int(x), int(y))
            
    pygame.display.update()

The script above also shows us that we can actually use the pygame.draw module to draw out our gaming character instead of loading graphic into the computer memory.

If you run the above script then you will see the below outcome!

Draw lines with Pygame

The pygame.draw.lines method which takes in 1) Screen surface 2) Line color 3) Boolean value to indicate whether should close the lines or not 4) Line coordinates and 5) Line width, will produce the below outcome.

Pygame draw lines
Pygame draw lines

Just like pygame.draw.line, there is also an antialiased version of pygame.draw.lines which will draw smooth lines on the screen.

The drawlines script is as follow.

import pygame
from pygame.locals import *
from sys import exit

pygame.init()
screen = pygame.display.set_mode((640, 480), 0, 32)

coordinate  = []

while True:
    
    for event in pygame.event.get():
        if event.type == QUIT:
            exit()
            
        if event.type == MOUSEMOTION:
            coordinate.append(event.pos)
            
    screen.fill((255, 255, 255))

    if len(coordinate)>1:
        pygame.draw.lines(screen, (0,255,0), False, coordinate, 3)
            
    pygame.display.update()

The script above will append a tuple which consists of x, y coordinate to the coordinate array every time we touch a point on the screen, the coordinate array will then be used in the pygame.draw.lines method.

Draw Arc with Pygame

Drawing arc with Pygame is just like drawing ellipse, the pygame.draw.arc method takes these arguments.

1) The screen surface
2) The color of that arc
3) The rectangle object where the arc will fit into
4) The starting angle of the arc
5) The ending angle of the arc
6) An optional line width of the arc

Below script will draw the arc which will fit in the entire width and height of the screen.

import pygame
from pygame.locals import *
from sys import exit

from math import pi

pygame.init()
screen = pygame.display.set_mode((640, 480), 0, 32)

while True:
    
    for event in pygame.event.get():
        if event.type == QUIT:
            exit()
            
    angle = 0.5*pi*2.
    screen.fill((255,255,255))
    pygame.draw.arc(screen, (0,0,0), (0,0,639,479), 0, angle, 3)
        
    pygame.display.update()

The above script will produce the following outcome.

Pygame arc
Pygame arc

Drawing an Ellipse with Pygame

Drawing an Ellipse with Pygame is just like drawing other shape, basically Pygame will stretch a circle to fit within a rectangle object specified by a tuple contains the top left corner of the rectangle and the width and height of that rectangle. Below is the entire script showing you how to draw an ellipse on the screen surface.

import pygame
from pygame.locals import *
from sys import exit

pygame.init()
screen = pygame.display.set_mode((640, 480), 0, 32)

while True:
    
    for event in pygame.event.get():
        if event.type == QUIT:
            exit()
            
        
        screen.fill((255,255,255))
        screen.lock()
        pygame.draw.ellipse(screen, (0,255,0), (30,30,200,300))
        screen.unlock()
        
            
    pygame.display.update()

The above script will produce the following outcome.

Pygame Ellipse
Pygame Ellipse

The pygame.draw.ellipse method takes in these parameters.

1) Screen surface to draw on it
2) Color tuple for ellipse
3) Rectangle tuple
4) An optional line width which if stated will create a hollow ellipse instead of a solid one

Draw a line with Pygame

In this article we will draw a new line with Pygame every time the user clicks on a new position on the screen. The method we will use here is the pygame.draw.line method which takes in these arguments:

1) The screen surface to draw on.
2) The color of the line.
3) The first point of the line.
4) The second point of the line.
5) An optional width value of the line.

The python script to draw the line is as follow:

import pygame
from pygame.locals import *
from sys import exit

pygame.init()
screen = pygame.display.set_mode((640, 480), 0, 32)

origin = (30, 30)

while True:
    
    for event in pygame.event.get():

        if event.type == QUIT:
            exit()
            
        if event.type == MOUSEBUTTONDOWN:
            screen.fill((255,255,255))
            screen.lock()
            pygame.draw.line(screen, (30, 0, 20), origin, event.pos, 2)
            screen.unlock()
        
            
    pygame.display.update()

Below is the outcome.

Pygame drawing line
Pygame drawing line

The line will change every time you click on the different place on the screen!

Besides the pygame.draw.line method, Pygame also offers the pygame.draw.aaline method which takes in the same parameters as pygame.draw.line but draws smoother line by using the antialiasing technique to draw the line!

Draw Polygon with Pygame

Today we will continue with our draw’s class in Pygame and in this article we will draw a Polygon object with the pygame.draw.polygon method. This polygon method will take in a few arguments. 1) The screen surface 2) The color of the Polygon 3) An array of tuples contain the x, y coordinate 4) An optional width value if stated then the pygame.draw.polygon method will draw a hollow Polygon object or else the Polygon will be filled with solid color.

In the following script, after you have clicked on any 5 locations on the screen then the pygame.draw.polygon method will start to draw Polygon on the surface of that screen!

import pygame
from pygame.locals import *
from sys import exit

pygame.init()
screen = pygame.display.set_mode((640, 480), 0, 32)
cooordinate = []

while True:
    for event in pygame.event.get():
        if event.type == QUIT:
            exit()
        if event.type == MOUSEBUTTONDOWN: #if mouse click then coordinate array will append x,y tuple 
            cooordinate.append(event.pos)
    screen.fill((255,255,255))
    screen.lock()
    if len(cooordinate) >= 5:
        pygame.draw.polygon(screen, (255,255,100), cooordinate, 3)
    
    screen.unlock()
    pygame.display.update()

Click on more positions on the screen and the shape will now change accordingly.

Pygame draw polygon
Pygame draw polygon

How to draw circle with Pygame

Drawing circle with Pygame is just like drawing a rectangle which I have shown you in the previous post. Let draw a circle on the screen this time with the pygame.draw.circle method. This method takes in the screen surface argument, a tuple consists of the RGB color value for the circle, the tuple consists of the position of the circle on the screen, the radius of the circle as well as an optional line width property which we have previously used in the previous rectangle example! Below is the entire script to draw a solid circle (no outline) on the screen.

import pygame
from pygame.locals import *
from sys import exit
from random import *
pygame.init()
screen = pygame.display.set_mode((640, 480), 0, 32)

while True:
    for event in pygame.event.get():
        if event.type == QUIT:
            exit()
    screen.fill((255,255,255))
    screen.lock()

    circle_pos = (290, 220)
    circle_radius = 100
    circle_color = (255, 100, 230)
    pygame.draw.circle(screen, circle_color, circle_pos, circle_radius)
    
    screen.unlock()
    pygame.display.update()

The rest of the script above is almost the same as the previous script which uses to create two rectangle objects.

Python circle
Python circle

How to draw a rectangle with Pygame

There are two methods you can use to put a game character on the screen with Pygame. The first method which I have shown you before is to insert either a png or a jpeg image on the screen with the screen.blit method. The second method which I am about to show you now is to draw on the screen. Actually you can create a game without using any image by just drawing square or circle on the screen and I am going to show you how to draw a few different shapes on the screen with Pygame in this pygame tutorial series. In this post we will draw two rectangles, one will be filled with color and another one is a hollow rectangle.

In order to draw a rectangle on the screen we will use the

pygame.draw.rect

method which will take a few arguments as shown in the below example.

pygame.draw.rect(screen, (100, 100, 150), Rect((150, 150), (100, 100)), 3)

The first argument is the surface of the screen, the second one is the tuple which contains the RGB value of the color which will be used to fill the entire rectangle or to be used as the color of the line if that rectangle is a hollow one. The third argument is the rectangle object itself which takes two arguments (the tuple which contains the top left corner’s (x and y coordinate point) of that rectangle (on the screen) as well as the tuple which contains the width and height of that rectangle). The fourth argument is an optional line width argument which if you use it will draw line around the hollow rectangle according to the width you have specified. If you leave out that fourth argument then the rectangle will be filled up with the color which we have specified.

Before we start to draw on a surface we will also need to lock that surface first with the following method.

screen.lock()

Then we also need to unlock that same surface again once we have finished drawing on it with this method.

screen.unlock()

Below is the entire script which I use to draw two rectangles on the screen, one is the hollow rectangle and another one is the rectangle filled with color.

import pygame
from pygame.locals import *
from sys import exit
from random import *
pygame.init()
screen = pygame.display.set_mode((640, 480), 0, 32)

while True:
    for event in pygame.event.get():
        if event.type == QUIT:
            exit()
    screen.lock()
    rectangle_pos = (150, 150)
    rectangle_pos2 = (250, 350)
    rectangle_size = (100, 100)
    screen.fill((255,255,255))
    pygame.draw.rect(screen, (100, 100, 150), Rect(rectangle_pos, rectangle_size), 3)
    pygame.draw.rect(screen, (100, 100, 150), Rect(rectangle_pos2, rectangle_size))
    screen.unlock()
    pygame.display.update()

If you run the above script you will get the following outcome.

Draw rectangle with Pygame script
Draw rectangle with Pygame script

There are more tutorials on Pygame coming everyday so make sure to bookmark this Pygame channel for the daily Pygame tutorial : http://gamingdirectional.com/blog/category/pygame/

Pygame tutorial 2 – Moving the object with keyboard

Before we start, make sure you have read the first tutorial of creating game in python with pygame, if you not then just go ahead and read the first part of this pygame tutorial series.

In this tutorial I am going to show you how to move the game object within the pygame’s display screen with your keyboard.

In order to move our object within pygame we will need to find out whether the user has pressed a certain key or not from the value of the event’s key property and also we will only move our character if the user is continue pressing that key.

Below is the entire python script to move a boat in the right or the left direction on the display screen. The display portion of the script is almost the same as the previous one but with an additional loop to retrieve the value of the event’s key property (in this example the left or the right arrow key on your keyboard) as well as to detect whether you are continue pressing that key or have already released it, if you have released the key then the direction will again set to zero which means no movement will be made by that object at the moment or else the object will move to either left or the right by 0.05 unit (if you pressed the left arrow key then the boat will move left or else it will move right if right arrow key is pressed).

#!/usr/bin/env python

import pygame
from pygame.locals import *
from sys import exit

background_image = 'terain7.png'
boat = 'boat.png'

pygame.init()
SCREEN_SIZE = (500, 500)
screen = pygame.display.set_mode(SCREEN_SIZE, 0, 32)
pygame.display.set_caption("Pygame Demo")
background = pygame.image.load(background_image).convert()
player = pygame.image.load(boat).convert_alpha()

x, y = 150, 353
MOVE_RIGHT = 1
MOVE_LEFT = 2
direction = 0

while True:
   
    for event in pygame.event.get():
        
        if event.type == QUIT:
            exit()
            
        if event.type == KEYDOWN:
            if event.key == K_LEFT:
                direction = MOVE_LEFT
            elif event.key == K_RIGHT:
                direction = MOVE_RIGHT
                
        elif event.type == KEYUP:
            if event.key == K_LEFT:
                direction = 0
            elif event.key == K_RIGHT:
                direction = 0
                
        
    if(direction == MOVE_LEFT):
        x-=0.05
    elif(direction == MOVE_RIGHT):
        x+=0.05
    
    screen.blit(background, (0, 0))
    screen.blit(player, (x, y))
    pygame.display.update()

Run the above script in NetBeans 8.1 and you will see the below outcome.

If you are interested in pygame then don’t miss my daily pygame tutorial because starting from today I will write one to three posts per day on pygame so do visit this blog everyday and master the entire pygame tutorial within a week!