Games with Python and Pygame
or
how to make PacMan...
@DominikWro
https://slid.es/dominikwronski/pacman/
https://github.com/DominikWro/pacman/
PacMan Facts
1980
Toru Iwanati
24 kb
256 levels
Most recognizable game charcter ever
Toru Iwanati
24 kb
256 levels
Most recognizable game charcter ever
Pygame
GPL License
SDL
Simple DirectMedia Layer
development library which
provide low level access to
audio, keyboard, mouse,
joystick, and graphics hardware
via
OpenGL and Direct3D.
import pygame, sys from pygame.locals import *
pygame.init() DISPLAYSURF = pygame.display.set_mode((400, 300)) pygame.display.set_caption('Hello World!')while True: # main game loop for event in pygame.event.get(): if event.type == QUIT: pygame.quit() sys.exit() pygame.display.update()
The Game itself
import
import pygame._view
black = (0,0,0)
white = (255,255,255)
blue = (0,0,255)
green = (0,255,0)
red = (255,0,0)
purple = (255,0,255)
yellow = ( 255, 255, 0)
Trollicon=pygame.image.load('images/Trollman.png')
pygame.display.set_icon(Trollicon)
#Add music
pygame.mixer.init()
pygame.mixer.music.load('pacman.mp3')
pygame.mixer.music.play(-1, 0.0)
class Wall(pygame.sprite.Sprite):
# Constructor function
def __init__(self,x,y,width,height, color):
# Call the parent's constructor
pygame.sprite.Sprite.__init__(self)
# Make a blue wall, of the size specified in the parameters
self.image = pygame.Surface([width, height])
self.image.fill(color)
# Make our top-left corner the passed-in location.
self.rect = self.image.get_rect()
self.rect.top = y
self.rect.left = x
Draw the map
def setupRoomOne(all_sprites_list):
# Make the walls. (x_pos, y_pos, width, height)
wall_list=pygame.sprite.RenderPlain()
# List of walls.
walls = [ [0,0,6,600], [0,0,600,6], [0,600,606,6], [600,0,6,606],
[300,0,6,66], [60,60,186,6] ......
]
for item in walls:
wall=Wall(item[0],item[1],item[2],item[3],blue)
wall_list.add(wall)
all_sprites_list.add(wall)
return wall_list
class Player(pygame.sprite.Sprite):
# Set speed vector
change_x=0
change_y=0
def __init__(self,x,y, filename):
pygame.sprite.Sprite.__init__(self)
# Set height, width
self.image = pygame.image.load(filename).convert()
self.rect = self.image.get_rect()
self.rect.top = y
self.rect.left = x
self.prev_x = x
self.prev_y = y
def prevdirection(self):
self.prev_x = self.change_x
self.prev_y = self.change_y
def changespeed(self,x,y):
self.change_x+=x
self.change_y+=y
def update(self,walls,gate):
old_x=self.rect.left
new_x=old_x+self.change_x
prev_x=old_x+self.prev_x
self.rect.left = new_x
old_y=self.rect.top
new_y=old_y+self.change_y
prev_y=old_y+self.prev_y
# Did this update cause us to hit a wall?
x_collide = pygame.sprite.spritecollide(self, walls, False)
if x_collide:
self.rect.left=old_x
else:
self.rect.top = new_y
y_collide = pygame.sprite.spritecollide(self, walls, False)
if y_collide:
self.rect.top=old_y
if gate != False:
gate_hit = pygame.sprite.spritecollide(self, gate, False)
if gate_hit:
self.rect.left=old_x
self.rect.top=old_y
class Ghost(Player):
def changespeed(self,list,ghost,turn,steps,l):
try:
z=list[turn][2]
if steps < z:
self.change_x=list[turn][0]
self.change_y=list[turn][1]
steps+=1
else:
if turn < l:
turn+=1
elif ghost == "clyde":
turn = 2
else:
turn = 0
self.change_x=list[turn][0]
self.change_y=list[turn][1]
steps = 0
return [turn,steps]
except IndexError:
return [0,0]
Control Pac-man
if event.type == pygame.KEYDOWN:
if event.key == pygame.K_LEFT:
Pacman.changespeed(-30,0)
if event.key == pygame.K_RIGHT:
Pacman.changespeed(30,0)
if event.key == pygame.K_UP:
Pacman.changespeed(0,-30)
if event.key == pygame.K_DOWN:
Pacman.changespeed(0,30)
if event.type == pygame.KEYUP:
if event.key == pygame.K_LEFT:
Pacman.changespeed(30,0)
if event.key == pygame.K_RIGHT:
Pacman.changespeed(-30,0)
if event.key == pygame.K_UP:
Pacman.changespeed(0,30)
if event.key == pygame.K_DOWN:
Pacman.changespeed(0,-30)
Ghost chasing algorithm
chasing Pacman (A* algorithm)
set a trap
goes at random
Chase - Scatter - Chase
Behavior is not identical due to error in orginal ASM code
def doNext(message,left,all_sprites_list,block_list,monsta_list,pacman_collide,wall_list,gate):while True:# ALL EVENT PROCESSING SHOULD GO BELOW THIS COMMENTfor event in pygame.event.get():if event.type == pygame.QUIT:pygame.quit()if event.type == pygame.KEYDOWN:if event.key == pygame.K_ESCAPE:pygame.quit()if event.key == pygame.K_RETURN:del all_sprites_listdel block_listdel monsta_listdel pacman_collidedel wall_listdel gatestartGame()#Grey backgroundw = pygame.Surface((400,200)) # the size of your rectw.set_alpha(10) # alpha levelw.fill((128,128,128)) # this fills the entire surfacescreen.blit(w, (100,200)) # (0,0) are the top-left coordinates#Won or losttext1=font.render(message, True, white)screen.blit(text1, [left, 233])text2=font.render("To play again, press ENTER.", True, white)screen.blit(text2, [135, 303])text3=font.render("To quit, press ESCAPE.", True, white)screen.blit(text3, [165, 333])pygame.display.flip()clock.tick(10)startGame()pygame.quit()
While running
Rule 1 runs every 0.1 secs calling the following methods to keep the Pacman moving and check if it's in ghost killing mode:
- Decide which way to move based on user input of arrow keys
- Move over certain agents (floor, pills, ghosts, etc)
- Kill ghosts if the "heat" value is set to -1000 rather than +1000 (meaning a power pill has been eaten)
- Heat can be explained more here.
Decide which way to move
class Player(pygame.sprite.Sprite):
# Set speed vector
change_x=0
change_y=0
# Constructor function
def __init__(self,x,y, filename):
# Call the parent's constructor
pygame.sprite.Sprite.__init__(self)
# Set height, width
self.image = pygame.image.load(filename).convert()
# Make our top-left corner the passed-in location.
self.rect = self.image.get_rect()
self.rect.top = y
self.rect.left = x
self.prev_x = x
self.prev_y = y
# Clear the speed of the player
def prevdirection(self):
self.prev_x = self.change_x
self.prev_y = self.change_y
# Change the speed of the player
def changespeed(self,x,y):
self.change_x+=x
self.change_y+=y
# Find a new position for the player
def update(self,walls,gate):
# Get the old position, in case we
Title
def update(self,walls,gate):
# Get the old position, in case we need to go back to it
old_x=self.rect.left
new_x=old_x+self.change_x
prev_x=old_x+self.prev_x
self.rect.left = new_x
old_y=self.rect.top
new_y=old_y+self.change_y
prev_y=old_y+self.prev_y
# Did this update cause us to hit a wall?
x_collide = pygame.sprite.spritecollide(self, walls, False)
if x_collide:
# Whoops, hit a wall. Go back to the old position
self.rect.left=old_x
# self.rect.top=prev_y
# y_collide = pygame.sprite.spritecollide(self, walls, False)
# if y_collide:
# # Whoops, hit a wall. Go back to the old position
# self.rect.top=old_y
# print('a')
else:
self.rect.top = new_y
# Did this update cause us to hit a wall?
y_collide = pygame.sprite.spritecollide(self, walls, False)
if y_collide:
# Whoops, hit a wall. Go back to the old position
self.rect.top=old_y
# self.rect.left=prev_x
# x_collide = pygame.sprite.spritecollide(self, walls, False)
# if x_collide:
# # Whoops, hit a wall. Go back to the old position
# self.rect.left=old_x
# print('b')
if gate != False:
gate_hit = pygame.sprite.spritecollide(self, gate, False)
if gate_hit:
self.rect.left=old_x
self.rect.top=old_y
def startGame():
all_sprites_list = pygame.sprite.RenderPlain()
block_list = pygame.sprite.RenderPlain()
monsta_list = pygame.sprite.RenderPlain()
pacman_collide = pygame.sprite.RenderPlain()
wall_list = setupRoomOne(all_sprites_list)
gate = setupGate(all_sprites_list)
p_turn = 0
p_steps = 0
b_turn = 0
b_steps = 0
i_turn = 0
i_steps = 0
c_turn = 0
c_steps = 0
Pacman = Player( w, p_h, "images/Trollman.png" )
all_sprites_list.add(Pacman)
pacman_collide.add(Pacman)
Blinky=Ghost( w, b_h, "images/Blinky.png" )
monsta_list.add(Blinky)
all_sprites_list.add(Blinky)
Pinky=Ghost( w, m_h, "images/Pinky.png" )
monsta_list.add(Pinky)
all_sprites_list.add(Pinky)
Title
# Draw the grid
for row in range(19):
for column in range(19):
if (row == 7 or row == 8) and (column == 8 or column == 9 or column == 10):
continue
else:
block = Block(yellow, 4, 4)
# Set a random location for the block
block.rect.x = (30*column+6)+26
block.rect.y = (30*row+6)+26
b_collide = pygame.sprite.spritecollide(block, wall_list, False)
p_collide = pygame.sprite.spritecollide(block, pacman_collide, False)
if b_collide:
continue
elif p_collide:
continue
else:
# Add the block to the list of objects
block_list.add(block)
all_sprites_list.add(block)
bll = len(block_list)
score = 0
done = False
i = 0
while done == False:
PacMan
By Dominik Wronski
PacMan
How to write PacMan with Python and Pygame. Based on "Making Games with Python & Pygame" by Al Sweigart >>> PRESENTATION NOT FINISHED YET <<<
- 4,999