├── pacmanlvl1.jpg ├── pacman pieces.PNG ├── assets ├── player_images │ ├── 1.png │ ├── 2.png │ ├── 3.png │ └── 4.png └── ghost_images │ ├── blue.png │ ├── dead.png │ ├── pink.png │ ├── red.png │ ├── orange.png │ └── powerup.png ├── board.py └── pacman.py /pacmanlvl1.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/plemaster01/PythonPacman/HEAD/pacmanlvl1.jpg -------------------------------------------------------------------------------- /pacman pieces.PNG: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/plemaster01/PythonPacman/HEAD/pacman pieces.PNG -------------------------------------------------------------------------------- /assets/player_images/1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/plemaster01/PythonPacman/HEAD/assets/player_images/1.png -------------------------------------------------------------------------------- /assets/player_images/2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/plemaster01/PythonPacman/HEAD/assets/player_images/2.png -------------------------------------------------------------------------------- /assets/player_images/3.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/plemaster01/PythonPacman/HEAD/assets/player_images/3.png -------------------------------------------------------------------------------- /assets/player_images/4.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/plemaster01/PythonPacman/HEAD/assets/player_images/4.png -------------------------------------------------------------------------------- /assets/ghost_images/blue.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/plemaster01/PythonPacman/HEAD/assets/ghost_images/blue.png -------------------------------------------------------------------------------- /assets/ghost_images/dead.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/plemaster01/PythonPacman/HEAD/assets/ghost_images/dead.png -------------------------------------------------------------------------------- /assets/ghost_images/pink.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/plemaster01/PythonPacman/HEAD/assets/ghost_images/pink.png -------------------------------------------------------------------------------- /assets/ghost_images/red.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/plemaster01/PythonPacman/HEAD/assets/ghost_images/red.png -------------------------------------------------------------------------------- /assets/ghost_images/orange.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/plemaster01/PythonPacman/HEAD/assets/ghost_images/orange.png -------------------------------------------------------------------------------- /assets/ghost_images/powerup.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/plemaster01/PythonPacman/HEAD/assets/ghost_images/powerup.png -------------------------------------------------------------------------------- /board.py: -------------------------------------------------------------------------------- 1 | # 0 = empty black rectangle, 1 = dot, 2 = big dot, 3 = vertical line, 2 | # 4 = horizontal line, 5 = top right, 6 = top left, 7 = bot left, 8 = bot right 3 | # 9 = gate 4 | boards = [ 5 | [6, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 5], 6 | [3, 6, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 5, 6, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 5, 3], 7 | [3, 3, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 3, 3, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 3, 3], 8 | [3, 3, 1, 6, 4, 4, 5, 1, 6, 4, 4, 4, 5, 1, 3, 3, 1, 6, 4, 4, 4, 5, 1, 6, 4, 4, 5, 1, 3, 3], 9 | [3, 3, 2, 3, 0, 0, 3, 1, 3, 0, 0, 0, 3, 1, 3, 3, 1, 3, 0, 0, 0, 3, 1, 3, 0, 0, 3, 2, 3, 3], 10 | [3, 3, 1, 7, 4, 4, 8, 1, 7, 4, 4, 4, 8, 1, 7, 8, 1, 7, 4, 4, 4, 8, 1, 7, 4, 4, 8, 1, 3, 3], 11 | [3, 3, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 3, 3], 12 | [3, 3, 1, 6, 4, 4, 5, 1, 6, 5, 1, 6, 4, 4, 4, 4, 4, 4, 5, 1, 6, 5, 1, 6, 4, 4, 5, 1, 3, 3], 13 | [3, 3, 1, 7, 4, 4, 8, 1, 3, 3, 1, 7, 4, 4, 5, 6, 4, 4, 8, 1, 3, 3, 1, 7, 4, 4, 8, 1, 3, 3], 14 | [3, 3, 1, 1, 1, 1, 1, 1, 3, 3, 1, 1, 1, 1, 3, 3, 1, 1, 1, 1, 3, 3, 1, 1, 1, 1, 1, 1, 3, 3], 15 | [3, 7, 4, 4, 4, 4, 5, 1, 3, 7, 4, 4, 5, 0, 3, 3, 0, 6, 4, 4, 8, 3, 1, 6, 4, 4, 4, 4, 8, 3], 16 | [3, 0, 0, 0, 0, 0, 3, 1, 3, 6, 4, 4, 8, 0, 7, 8, 0, 7, 4, 4, 5, 3, 1, 3, 0, 0, 0, 0, 0, 3], 17 | [3, 0, 0, 0, 0, 0, 3, 1, 3, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 3, 1, 3, 0, 0, 0, 0, 0, 3], 18 | [8, 0, 0, 0, 0, 0, 3, 1, 3, 3, 0, 6, 4, 4, 9, 9, 4, 4, 5, 0, 3, 3, 1, 3, 0, 0, 0, 0, 0, 7], 19 | [4, 4, 4, 4, 4, 4, 8, 1, 7, 8, 0, 3, 0, 0, 0, 0, 0, 0, 3, 0, 7, 8, 1, 7, 4, 4, 4, 4, 4, 4], 20 | [0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0], 21 | [4, 4, 4, 4, 4, 4, 5, 1, 6, 5, 0, 3, 0, 0, 0, 0, 0, 0, 3, 0, 6, 5, 1, 6, 4, 4, 4, 4, 4, 4], 22 | [5, 0, 0, 0, 0, 0, 3, 1, 3, 3, 0, 7, 4, 4, 4, 4, 4, 4, 8, 0, 3, 3, 1, 3, 0, 0, 0, 0, 0, 6], 23 | [3, 0, 0, 0, 0, 0, 3, 1, 3, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 3, 1, 3, 0, 0, 0, 0, 0, 3], 24 | [3, 0, 0, 0, 0, 0, 3, 1, 3, 3, 0, 6, 4, 4, 4, 4, 4, 4, 5, 0, 3, 3, 1, 3, 0, 0, 0, 0, 0, 3], 25 | [3, 6, 4, 4, 4, 4, 8, 1, 7, 8, 0, 7, 4, 4, 5, 6, 4, 4, 8, 0, 7, 8, 1, 7, 4, 4, 4, 4, 5, 3], 26 | [3, 3, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 3, 3, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 3, 3], 27 | [3, 3, 1, 6, 4, 4, 5, 1, 6, 4, 4, 4, 5, 1, 3, 3, 1, 6, 4, 4, 4, 5, 1, 6, 4, 4, 5, 1, 3, 3], 28 | [3, 3, 1, 7, 4, 5, 3, 1, 7, 4, 4, 4, 8, 1, 7, 8, 1, 7, 4, 4, 4, 8, 1, 3, 6, 4, 8, 1, 3, 3], 29 | [3, 3, 2, 1, 1, 3, 3, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 3, 3, 1, 1, 2, 3, 3], 30 | [3, 7, 4, 5, 1, 3, 3, 1, 6, 5, 1, 6, 4, 4, 4, 4, 4, 4, 5, 1, 6, 5, 1, 3, 3, 1, 6, 4, 8, 3], 31 | [3, 6, 4, 8, 1, 7, 8, 1, 3, 3, 1, 7, 4, 4, 5, 6, 4, 4, 8, 1, 3, 3, 1, 7, 8, 1, 7, 4, 5, 3], 32 | [3, 3, 1, 1, 1, 1, 1, 1, 3, 3, 1, 1, 1, 1, 3, 3, 1, 1, 1, 1, 3, 3, 1, 1, 1, 1, 1, 1, 3, 3], 33 | [3, 3, 1, 6, 4, 4, 4, 4, 8, 7, 4, 4, 5, 1, 3, 3, 1, 6, 4, 4, 8, 7, 4, 4, 4, 4, 5, 1, 3, 3], 34 | [3, 3, 1, 7, 4, 4, 4, 4, 4, 4, 4, 4, 8, 1, 7, 8, 1, 7, 4, 4, 4, 4, 4, 4, 4, 4, 8, 1, 3, 3], 35 | [3, 3, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 3, 3], 36 | [3, 7, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 8, 3], 37 | [7, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 8] 38 | ] 39 | -------------------------------------------------------------------------------- /pacman.py: -------------------------------------------------------------------------------- 1 | # Build Pac-Man from Scratch in Python with PyGame!! 2 | import copy 3 | from board import boards 4 | import pygame 5 | import math 6 | 7 | pygame.init() 8 | 9 | WIDTH = 900 10 | HEIGHT = 950 11 | screen = pygame.display.set_mode([WIDTH, HEIGHT]) 12 | timer = pygame.time.Clock() 13 | fps = 60 14 | font = pygame.font.Font('freesansbold.ttf', 20) 15 | level = copy.deepcopy(boards) 16 | color = 'blue' 17 | PI = math.pi 18 | player_images = [] 19 | for i in range(1, 5): 20 | player_images.append(pygame.transform.scale(pygame.image.load(f'assets/player_images/{i}.png'), (45, 45))) 21 | blinky_img = pygame.transform.scale(pygame.image.load(f'assets/ghost_images/red.png'), (45, 45)) 22 | pinky_img = pygame.transform.scale(pygame.image.load(f'assets/ghost_images/pink.png'), (45, 45)) 23 | inky_img = pygame.transform.scale(pygame.image.load(f'assets/ghost_images/blue.png'), (45, 45)) 24 | clyde_img = pygame.transform.scale(pygame.image.load(f'assets/ghost_images/orange.png'), (45, 45)) 25 | spooked_img = pygame.transform.scale(pygame.image.load(f'assets/ghost_images/powerup.png'), (45, 45)) 26 | dead_img = pygame.transform.scale(pygame.image.load(f'assets/ghost_images/dead.png'), (45, 45)) 27 | player_x = 450 28 | player_y = 663 29 | direction = 0 30 | blinky_x = 56 31 | blinky_y = 58 32 | blinky_direction = 0 33 | inky_x = 440 34 | inky_y = 388 35 | inky_direction = 2 36 | pinky_x = 440 37 | pinky_y = 438 38 | pinky_direction = 2 39 | clyde_x = 440 40 | clyde_y = 438 41 | clyde_direction = 2 42 | counter = 0 43 | flicker = False 44 | # R, L, U, D 45 | turns_allowed = [False, False, False, False] 46 | direction_command = 0 47 | player_speed = 2 48 | score = 0 49 | powerup = False 50 | power_counter = 0 51 | eaten_ghost = [False, False, False, False] 52 | targets = [(player_x, player_y), (player_x, player_y), (player_x, player_y), (player_x, player_y)] 53 | blinky_dead = False 54 | inky_dead = False 55 | clyde_dead = False 56 | pinky_dead = False 57 | blinky_box = False 58 | inky_box = False 59 | clyde_box = False 60 | pinky_box = False 61 | moving = False 62 | ghost_speeds = [2, 2, 2, 2] 63 | startup_counter = 0 64 | lives = 3 65 | game_over = False 66 | game_won = False 67 | 68 | 69 | class Ghost: 70 | def __init__(self, x_coord, y_coord, target, speed, img, direct, dead, box, id): 71 | self.x_pos = x_coord 72 | self.y_pos = y_coord 73 | self.center_x = self.x_pos + 22 74 | self.center_y = self.y_pos + 22 75 | self.target = target 76 | self.speed = speed 77 | self.img = img 78 | self.direction = direct 79 | self.dead = dead 80 | self.in_box = box 81 | self.id = id 82 | self.turns, self.in_box = self.check_collisions() 83 | self.rect = self.draw() 84 | 85 | def draw(self): 86 | if (not powerup and not self.dead) or (eaten_ghost[self.id] and powerup and not self.dead): 87 | screen.blit(self.img, (self.x_pos, self.y_pos)) 88 | elif powerup and not self.dead and not eaten_ghost[self.id]: 89 | screen.blit(spooked_img, (self.x_pos, self.y_pos)) 90 | else: 91 | screen.blit(dead_img, (self.x_pos, self.y_pos)) 92 | ghost_rect = pygame.rect.Rect((self.center_x - 18, self.center_y - 18), (36, 36)) 93 | return ghost_rect 94 | 95 | def check_collisions(self): 96 | # R, L, U, D 97 | num1 = ((HEIGHT - 50) // 32) 98 | num2 = (WIDTH // 30) 99 | num3 = 15 100 | self.turns = [False, False, False, False] 101 | if 0 < self.center_x // 30 < 29: 102 | if level[(self.center_y - num3) // num1][self.center_x // num2] == 9: 103 | self.turns[2] = True 104 | if level[self.center_y // num1][(self.center_x - num3) // num2] < 3 \ 105 | or (level[self.center_y // num1][(self.center_x - num3) // num2] == 9 and ( 106 | self.in_box or self.dead)): 107 | self.turns[1] = True 108 | if level[self.center_y // num1][(self.center_x + num3) // num2] < 3 \ 109 | or (level[self.center_y // num1][(self.center_x + num3) // num2] == 9 and ( 110 | self.in_box or self.dead)): 111 | self.turns[0] = True 112 | if level[(self.center_y + num3) // num1][self.center_x // num2] < 3 \ 113 | or (level[(self.center_y + num3) // num1][self.center_x // num2] == 9 and ( 114 | self.in_box or self.dead)): 115 | self.turns[3] = True 116 | if level[(self.center_y - num3) // num1][self.center_x // num2] < 3 \ 117 | or (level[(self.center_y - num3) // num1][self.center_x // num2] == 9 and ( 118 | self.in_box or self.dead)): 119 | self.turns[2] = True 120 | 121 | if self.direction == 2 or self.direction == 3: 122 | if 12 <= self.center_x % num2 <= 18: 123 | if level[(self.center_y + num3) // num1][self.center_x // num2] < 3 \ 124 | or (level[(self.center_y + num3) // num1][self.center_x // num2] == 9 and ( 125 | self.in_box or self.dead)): 126 | self.turns[3] = True 127 | if level[(self.center_y - num3) // num1][self.center_x // num2] < 3 \ 128 | or (level[(self.center_y - num3) // num1][self.center_x // num2] == 9 and ( 129 | self.in_box or self.dead)): 130 | self.turns[2] = True 131 | if 12 <= self.center_y % num1 <= 18: 132 | if level[self.center_y // num1][(self.center_x - num2) // num2] < 3 \ 133 | or (level[self.center_y // num1][(self.center_x - num2) // num2] == 9 and ( 134 | self.in_box or self.dead)): 135 | self.turns[1] = True 136 | if level[self.center_y // num1][(self.center_x + num2) // num2] < 3 \ 137 | or (level[self.center_y // num1][(self.center_x + num2) // num2] == 9 and ( 138 | self.in_box or self.dead)): 139 | self.turns[0] = True 140 | 141 | if self.direction == 0 or self.direction == 1: 142 | if 12 <= self.center_x % num2 <= 18: 143 | if level[(self.center_y + num3) // num1][self.center_x // num2] < 3 \ 144 | or (level[(self.center_y + num3) // num1][self.center_x // num2] == 9 and ( 145 | self.in_box or self.dead)): 146 | self.turns[3] = True 147 | if level[(self.center_y - num3) // num1][self.center_x // num2] < 3 \ 148 | or (level[(self.center_y - num3) // num1][self.center_x // num2] == 9 and ( 149 | self.in_box or self.dead)): 150 | self.turns[2] = True 151 | if 12 <= self.center_y % num1 <= 18: 152 | if level[self.center_y // num1][(self.center_x - num3) // num2] < 3 \ 153 | or (level[self.center_y // num1][(self.center_x - num3) // num2] == 9 and ( 154 | self.in_box or self.dead)): 155 | self.turns[1] = True 156 | if level[self.center_y // num1][(self.center_x + num3) // num2] < 3 \ 157 | or (level[self.center_y // num1][(self.center_x + num3) // num2] == 9 and ( 158 | self.in_box or self.dead)): 159 | self.turns[0] = True 160 | else: 161 | self.turns[0] = True 162 | self.turns[1] = True 163 | if 350 < self.x_pos < 550 and 370 < self.y_pos < 480: 164 | self.in_box = True 165 | else: 166 | self.in_box = False 167 | return self.turns, self.in_box 168 | 169 | def move_clyde(self): 170 | # r, l, u, d 171 | # clyde is going to turn whenever advantageous for pursuit 172 | if self.direction == 0: 173 | if self.target[0] > self.x_pos and self.turns[0]: 174 | self.x_pos += self.speed 175 | elif not self.turns[0]: 176 | if self.target[1] > self.y_pos and self.turns[3]: 177 | self.direction = 3 178 | self.y_pos += self.speed 179 | elif self.target[1] < self.y_pos and self.turns[2]: 180 | self.direction = 2 181 | self.y_pos -= self.speed 182 | elif self.target[0] < self.x_pos and self.turns[1]: 183 | self.direction = 1 184 | self.x_pos -= self.speed 185 | elif self.turns[3]: 186 | self.direction = 3 187 | self.y_pos += self.speed 188 | elif self.turns[2]: 189 | self.direction = 2 190 | self.y_pos -= self.speed 191 | elif self.turns[1]: 192 | self.direction = 1 193 | self.x_pos -= self.speed 194 | elif self.turns[0]: 195 | if self.target[1] > self.y_pos and self.turns[3]: 196 | self.direction = 3 197 | self.y_pos += self.speed 198 | if self.target[1] < self.y_pos and self.turns[2]: 199 | self.direction = 2 200 | self.y_pos -= self.speed 201 | else: 202 | self.x_pos += self.speed 203 | elif self.direction == 1: 204 | if self.target[1] > self.y_pos and self.turns[3]: 205 | self.direction = 3 206 | elif self.target[0] < self.x_pos and self.turns[1]: 207 | self.x_pos -= self.speed 208 | elif not self.turns[1]: 209 | if self.target[1] > self.y_pos and self.turns[3]: 210 | self.direction = 3 211 | self.y_pos += self.speed 212 | elif self.target[1] < self.y_pos and self.turns[2]: 213 | self.direction = 2 214 | self.y_pos -= self.speed 215 | elif self.target[0] > self.x_pos and self.turns[0]: 216 | self.direction = 0 217 | self.x_pos += self.speed 218 | elif self.turns[3]: 219 | self.direction = 3 220 | self.y_pos += self.speed 221 | elif self.turns[2]: 222 | self.direction = 2 223 | self.y_pos -= self.speed 224 | elif self.turns[0]: 225 | self.direction = 0 226 | self.x_pos += self.speed 227 | elif self.turns[1]: 228 | if self.target[1] > self.y_pos and self.turns[3]: 229 | self.direction = 3 230 | self.y_pos += self.speed 231 | if self.target[1] < self.y_pos and self.turns[2]: 232 | self.direction = 2 233 | self.y_pos -= self.speed 234 | else: 235 | self.x_pos -= self.speed 236 | elif self.direction == 2: 237 | if self.target[0] < self.x_pos and self.turns[1]: 238 | self.direction = 1 239 | self.x_pos -= self.speed 240 | elif self.target[1] < self.y_pos and self.turns[2]: 241 | self.direction = 2 242 | self.y_pos -= self.speed 243 | elif not self.turns[2]: 244 | if self.target[0] > self.x_pos and self.turns[0]: 245 | self.direction = 0 246 | self.x_pos += self.speed 247 | elif self.target[0] < self.x_pos and self.turns[1]: 248 | self.direction = 1 249 | self.x_pos -= self.speed 250 | elif self.target[1] > self.y_pos and self.turns[3]: 251 | self.direction = 3 252 | self.y_pos += self.speed 253 | elif self.turns[1]: 254 | self.direction = 1 255 | self.x_pos -= self.speed 256 | elif self.turns[3]: 257 | self.direction = 3 258 | self.y_pos += self.speed 259 | elif self.turns[0]: 260 | self.direction = 0 261 | self.x_pos += self.speed 262 | elif self.turns[2]: 263 | if self.target[0] > self.x_pos and self.turns[0]: 264 | self.direction = 0 265 | self.x_pos += self.speed 266 | elif self.target[0] < self.x_pos and self.turns[1]: 267 | self.direction = 1 268 | self.x_pos -= self.speed 269 | else: 270 | self.y_pos -= self.speed 271 | elif self.direction == 3: 272 | if self.target[1] > self.y_pos and self.turns[3]: 273 | self.y_pos += self.speed 274 | elif not self.turns[3]: 275 | if self.target[0] > self.x_pos and self.turns[0]: 276 | self.direction = 0 277 | self.x_pos += self.speed 278 | elif self.target[0] < self.x_pos and self.turns[1]: 279 | self.direction = 1 280 | self.x_pos -= self.speed 281 | elif self.target[1] < self.y_pos and self.turns[2]: 282 | self.direction = 2 283 | self.y_pos -= self.speed 284 | elif self.turns[2]: 285 | self.direction = 2 286 | self.y_pos -= self.speed 287 | elif self.turns[1]: 288 | self.direction = 1 289 | self.x_pos -= self.speed 290 | elif self.turns[0]: 291 | self.direction = 0 292 | self.x_pos += self.speed 293 | elif self.turns[3]: 294 | if self.target[0] > self.x_pos and self.turns[0]: 295 | self.direction = 0 296 | self.x_pos += self.speed 297 | elif self.target[0] < self.x_pos and self.turns[1]: 298 | self.direction = 1 299 | self.x_pos -= self.speed 300 | else: 301 | self.y_pos += self.speed 302 | if self.x_pos < -30: 303 | self.x_pos = 900 304 | elif self.x_pos > 900: 305 | self.x_pos - 30 306 | return self.x_pos, self.y_pos, self.direction 307 | 308 | def move_blinky(self): 309 | # r, l, u, d 310 | # blinky is going to turn whenever colliding with walls, otherwise continue straight 311 | if self.direction == 0: 312 | if self.target[0] > self.x_pos and self.turns[0]: 313 | self.x_pos += self.speed 314 | elif not self.turns[0]: 315 | if self.target[1] > self.y_pos and self.turns[3]: 316 | self.direction = 3 317 | self.y_pos += self.speed 318 | elif self.target[1] < self.y_pos and self.turns[2]: 319 | self.direction = 2 320 | self.y_pos -= self.speed 321 | elif self.target[0] < self.x_pos and self.turns[1]: 322 | self.direction = 1 323 | self.x_pos -= self.speed 324 | elif self.turns[3]: 325 | self.direction = 3 326 | self.y_pos += self.speed 327 | elif self.turns[2]: 328 | self.direction = 2 329 | self.y_pos -= self.speed 330 | elif self.turns[1]: 331 | self.direction = 1 332 | self.x_pos -= self.speed 333 | elif self.turns[0]: 334 | self.x_pos += self.speed 335 | elif self.direction == 1: 336 | if self.target[0] < self.x_pos and self.turns[1]: 337 | self.x_pos -= self.speed 338 | elif not self.turns[1]: 339 | if self.target[1] > self.y_pos and self.turns[3]: 340 | self.direction = 3 341 | self.y_pos += self.speed 342 | elif self.target[1] < self.y_pos and self.turns[2]: 343 | self.direction = 2 344 | self.y_pos -= self.speed 345 | elif self.target[0] > self.x_pos and self.turns[0]: 346 | self.direction = 0 347 | self.x_pos += self.speed 348 | elif self.turns[3]: 349 | self.direction = 3 350 | self.y_pos += self.speed 351 | elif self.turns[2]: 352 | self.direction = 2 353 | self.y_pos -= self.speed 354 | elif self.turns[0]: 355 | self.direction = 0 356 | self.x_pos += self.speed 357 | elif self.turns[1]: 358 | self.x_pos -= self.speed 359 | elif self.direction == 2: 360 | if self.target[1] < self.y_pos and self.turns[2]: 361 | self.direction = 2 362 | self.y_pos -= self.speed 363 | elif not self.turns[2]: 364 | if self.target[0] > self.x_pos and self.turns[0]: 365 | self.direction = 0 366 | self.x_pos += self.speed 367 | elif self.target[0] < self.x_pos and self.turns[1]: 368 | self.direction = 1 369 | self.x_pos -= self.speed 370 | elif self.target[1] > self.y_pos and self.turns[3]: 371 | self.direction = 3 372 | self.y_pos += self.speed 373 | elif self.turns[3]: 374 | self.direction = 3 375 | self.y_pos += self.speed 376 | elif self.turns[0]: 377 | self.direction = 0 378 | self.x_pos += self.speed 379 | elif self.turns[1]: 380 | self.direction = 1 381 | self.x_pos -= self.speed 382 | elif self.turns[2]: 383 | self.y_pos -= self.speed 384 | elif self.direction == 3: 385 | if self.target[1] > self.y_pos and self.turns[3]: 386 | self.y_pos += self.speed 387 | elif not self.turns[3]: 388 | if self.target[0] > self.x_pos and self.turns[0]: 389 | self.direction = 0 390 | self.x_pos += self.speed 391 | elif self.target[0] < self.x_pos and self.turns[1]: 392 | self.direction = 1 393 | self.x_pos -= self.speed 394 | elif self.target[1] < self.y_pos and self.turns[2]: 395 | self.direction = 2 396 | self.y_pos -= self.speed 397 | elif self.turns[2]: 398 | self.direction = 2 399 | self.y_pos -= self.speed 400 | elif self.turns[0]: 401 | self.direction = 0 402 | self.x_pos += self.speed 403 | elif self.turns[1]: 404 | self.direction = 1 405 | self.x_pos -= self.speed 406 | elif self.turns[3]: 407 | self.y_pos += self.speed 408 | if self.x_pos < -30: 409 | self.x_pos = 900 410 | elif self.x_pos > 900: 411 | self.x_pos - 30 412 | return self.x_pos, self.y_pos, self.direction 413 | 414 | def move_inky(self): 415 | # r, l, u, d 416 | # inky turns up or down at any point to pursue, but left and right only on collision 417 | if self.direction == 0: 418 | if self.target[0] > self.x_pos and self.turns[0]: 419 | self.x_pos += self.speed 420 | elif not self.turns[0]: 421 | if self.target[1] > self.y_pos and self.turns[3]: 422 | self.direction = 3 423 | self.y_pos += self.speed 424 | elif self.target[1] < self.y_pos and self.turns[2]: 425 | self.direction = 2 426 | self.y_pos -= self.speed 427 | elif self.target[0] < self.x_pos and self.turns[1]: 428 | self.direction = 1 429 | self.x_pos -= self.speed 430 | elif self.turns[3]: 431 | self.direction = 3 432 | self.y_pos += self.speed 433 | elif self.turns[2]: 434 | self.direction = 2 435 | self.y_pos -= self.speed 436 | elif self.turns[1]: 437 | self.direction = 1 438 | self.x_pos -= self.speed 439 | elif self.turns[0]: 440 | if self.target[1] > self.y_pos and self.turns[3]: 441 | self.direction = 3 442 | self.y_pos += self.speed 443 | if self.target[1] < self.y_pos and self.turns[2]: 444 | self.direction = 2 445 | self.y_pos -= self.speed 446 | else: 447 | self.x_pos += self.speed 448 | elif self.direction == 1: 449 | if self.target[1] > self.y_pos and self.turns[3]: 450 | self.direction = 3 451 | elif self.target[0] < self.x_pos and self.turns[1]: 452 | self.x_pos -= self.speed 453 | elif not self.turns[1]: 454 | if self.target[1] > self.y_pos and self.turns[3]: 455 | self.direction = 3 456 | self.y_pos += self.speed 457 | elif self.target[1] < self.y_pos and self.turns[2]: 458 | self.direction = 2 459 | self.y_pos -= self.speed 460 | elif self.target[0] > self.x_pos and self.turns[0]: 461 | self.direction = 0 462 | self.x_pos += self.speed 463 | elif self.turns[3]: 464 | self.direction = 3 465 | self.y_pos += self.speed 466 | elif self.turns[2]: 467 | self.direction = 2 468 | self.y_pos -= self.speed 469 | elif self.turns[0]: 470 | self.direction = 0 471 | self.x_pos += self.speed 472 | elif self.turns[1]: 473 | if self.target[1] > self.y_pos and self.turns[3]: 474 | self.direction = 3 475 | self.y_pos += self.speed 476 | if self.target[1] < self.y_pos and self.turns[2]: 477 | self.direction = 2 478 | self.y_pos -= self.speed 479 | else: 480 | self.x_pos -= self.speed 481 | elif self.direction == 2: 482 | if self.target[1] < self.y_pos and self.turns[2]: 483 | self.direction = 2 484 | self.y_pos -= self.speed 485 | elif not self.turns[2]: 486 | if self.target[0] > self.x_pos and self.turns[0]: 487 | self.direction = 0 488 | self.x_pos += self.speed 489 | elif self.target[0] < self.x_pos and self.turns[1]: 490 | self.direction = 1 491 | self.x_pos -= self.speed 492 | elif self.target[1] > self.y_pos and self.turns[3]: 493 | self.direction = 3 494 | self.y_pos += self.speed 495 | elif self.turns[1]: 496 | self.direction = 1 497 | self.x_pos -= self.speed 498 | elif self.turns[3]: 499 | self.direction = 3 500 | self.y_pos += self.speed 501 | elif self.turns[0]: 502 | self.direction = 0 503 | self.x_pos += self.speed 504 | elif self.turns[2]: 505 | self.y_pos -= self.speed 506 | elif self.direction == 3: 507 | if self.target[1] > self.y_pos and self.turns[3]: 508 | self.y_pos += self.speed 509 | elif not self.turns[3]: 510 | if self.target[0] > self.x_pos and self.turns[0]: 511 | self.direction = 0 512 | self.x_pos += self.speed 513 | elif self.target[0] < self.x_pos and self.turns[1]: 514 | self.direction = 1 515 | self.x_pos -= self.speed 516 | elif self.target[1] < self.y_pos and self.turns[2]: 517 | self.direction = 2 518 | self.y_pos -= self.speed 519 | elif self.turns[2]: 520 | self.direction = 2 521 | self.y_pos -= self.speed 522 | elif self.turns[1]: 523 | self.direction = 1 524 | self.x_pos -= self.speed 525 | elif self.turns[0]: 526 | self.direction = 0 527 | self.x_pos += self.speed 528 | elif self.turns[3]: 529 | self.y_pos += self.speed 530 | if self.x_pos < -30: 531 | self.x_pos = 900 532 | elif self.x_pos > 900: 533 | self.x_pos - 30 534 | return self.x_pos, self.y_pos, self.direction 535 | 536 | def move_pinky(self): 537 | # r, l, u, d 538 | # inky is going to turn left or right whenever advantageous, but only up or down on collision 539 | if self.direction == 0: 540 | if self.target[0] > self.x_pos and self.turns[0]: 541 | self.x_pos += self.speed 542 | elif not self.turns[0]: 543 | if self.target[1] > self.y_pos and self.turns[3]: 544 | self.direction = 3 545 | self.y_pos += self.speed 546 | elif self.target[1] < self.y_pos and self.turns[2]: 547 | self.direction = 2 548 | self.y_pos -= self.speed 549 | elif self.target[0] < self.x_pos and self.turns[1]: 550 | self.direction = 1 551 | self.x_pos -= self.speed 552 | elif self.turns[3]: 553 | self.direction = 3 554 | self.y_pos += self.speed 555 | elif self.turns[2]: 556 | self.direction = 2 557 | self.y_pos -= self.speed 558 | elif self.turns[1]: 559 | self.direction = 1 560 | self.x_pos -= self.speed 561 | elif self.turns[0]: 562 | self.x_pos += self.speed 563 | elif self.direction == 1: 564 | if self.target[1] > self.y_pos and self.turns[3]: 565 | self.direction = 3 566 | elif self.target[0] < self.x_pos and self.turns[1]: 567 | self.x_pos -= self.speed 568 | elif not self.turns[1]: 569 | if self.target[1] > self.y_pos and self.turns[3]: 570 | self.direction = 3 571 | self.y_pos += self.speed 572 | elif self.target[1] < self.y_pos and self.turns[2]: 573 | self.direction = 2 574 | self.y_pos -= self.speed 575 | elif self.target[0] > self.x_pos and self.turns[0]: 576 | self.direction = 0 577 | self.x_pos += self.speed 578 | elif self.turns[3]: 579 | self.direction = 3 580 | self.y_pos += self.speed 581 | elif self.turns[2]: 582 | self.direction = 2 583 | self.y_pos -= self.speed 584 | elif self.turns[0]: 585 | self.direction = 0 586 | self.x_pos += self.speed 587 | elif self.turns[1]: 588 | self.x_pos -= self.speed 589 | elif self.direction == 2: 590 | if self.target[0] < self.x_pos and self.turns[1]: 591 | self.direction = 1 592 | self.x_pos -= self.speed 593 | elif self.target[1] < self.y_pos and self.turns[2]: 594 | self.direction = 2 595 | self.y_pos -= self.speed 596 | elif not self.turns[2]: 597 | if self.target[0] > self.x_pos and self.turns[0]: 598 | self.direction = 0 599 | self.x_pos += self.speed 600 | elif self.target[0] < self.x_pos and self.turns[1]: 601 | self.direction = 1 602 | self.x_pos -= self.speed 603 | elif self.target[1] > self.y_pos and self.turns[3]: 604 | self.direction = 3 605 | self.y_pos += self.speed 606 | elif self.turns[1]: 607 | self.direction = 1 608 | self.x_pos -= self.speed 609 | elif self.turns[3]: 610 | self.direction = 3 611 | self.y_pos += self.speed 612 | elif self.turns[0]: 613 | self.direction = 0 614 | self.x_pos += self.speed 615 | elif self.turns[2]: 616 | if self.target[0] > self.x_pos and self.turns[0]: 617 | self.direction = 0 618 | self.x_pos += self.speed 619 | elif self.target[0] < self.x_pos and self.turns[1]: 620 | self.direction = 1 621 | self.x_pos -= self.speed 622 | else: 623 | self.y_pos -= self.speed 624 | elif self.direction == 3: 625 | if self.target[1] > self.y_pos and self.turns[3]: 626 | self.y_pos += self.speed 627 | elif not self.turns[3]: 628 | if self.target[0] > self.x_pos and self.turns[0]: 629 | self.direction = 0 630 | self.x_pos += self.speed 631 | elif self.target[0] < self.x_pos and self.turns[1]: 632 | self.direction = 1 633 | self.x_pos -= self.speed 634 | elif self.target[1] < self.y_pos and self.turns[2]: 635 | self.direction = 2 636 | self.y_pos -= self.speed 637 | elif self.turns[2]: 638 | self.direction = 2 639 | self.y_pos -= self.speed 640 | elif self.turns[1]: 641 | self.direction = 1 642 | self.x_pos -= self.speed 643 | elif self.turns[0]: 644 | self.direction = 0 645 | self.x_pos += self.speed 646 | elif self.turns[3]: 647 | if self.target[0] > self.x_pos and self.turns[0]: 648 | self.direction = 0 649 | self.x_pos += self.speed 650 | elif self.target[0] < self.x_pos and self.turns[1]: 651 | self.direction = 1 652 | self.x_pos -= self.speed 653 | else: 654 | self.y_pos += self.speed 655 | if self.x_pos < -30: 656 | self.x_pos = 900 657 | elif self.x_pos > 900: 658 | self.x_pos - 30 659 | return self.x_pos, self.y_pos, self.direction 660 | 661 | 662 | def draw_misc(): 663 | score_text = font.render(f'Score: {score}', True, 'white') 664 | screen.blit(score_text, (10, 920)) 665 | if powerup: 666 | pygame.draw.circle(screen, 'blue', (140, 930), 15) 667 | for i in range(lives): 668 | screen.blit(pygame.transform.scale(player_images[0], (30, 30)), (650 + i * 40, 915)) 669 | if game_over: 670 | pygame.draw.rect(screen, 'white', [50, 200, 800, 300],0, 10) 671 | pygame.draw.rect(screen, 'dark gray', [70, 220, 760, 260], 0, 10) 672 | gameover_text = font.render('Game over! Space bar to restart!', True, 'red') 673 | screen.blit(gameover_text, (100, 300)) 674 | if game_won: 675 | pygame.draw.rect(screen, 'white', [50, 200, 800, 300],0, 10) 676 | pygame.draw.rect(screen, 'dark gray', [70, 220, 760, 260], 0, 10) 677 | gameover_text = font.render('Victory! Space bar to restart!', True, 'green') 678 | screen.blit(gameover_text, (100, 300)) 679 | 680 | 681 | def check_collisions(scor, power, power_count, eaten_ghosts): 682 | num1 = (HEIGHT - 50) // 32 683 | num2 = WIDTH // 30 684 | if 0 < player_x < 870: 685 | if level[center_y // num1][center_x // num2] == 1: 686 | level[center_y // num1][center_x // num2] = 0 687 | scor += 10 688 | if level[center_y // num1][center_x // num2] == 2: 689 | level[center_y // num1][center_x // num2] = 0 690 | scor += 50 691 | power = True 692 | power_count = 0 693 | eaten_ghosts = [False, False, False, False] 694 | return scor, power, power_count, eaten_ghosts 695 | 696 | 697 | def draw_board(): 698 | num1 = ((HEIGHT - 50) // 32) 699 | num2 = (WIDTH // 30) 700 | for i in range(len(level)): 701 | for j in range(len(level[i])): 702 | if level[i][j] == 1: 703 | pygame.draw.circle(screen, 'white', (j * num2 + (0.5 * num2), i * num1 + (0.5 * num1)), 4) 704 | if level[i][j] == 2 and not flicker: 705 | pygame.draw.circle(screen, 'white', (j * num2 + (0.5 * num2), i * num1 + (0.5 * num1)), 10) 706 | if level[i][j] == 3: 707 | pygame.draw.line(screen, color, (j * num2 + (0.5 * num2), i * num1), 708 | (j * num2 + (0.5 * num2), i * num1 + num1), 3) 709 | if level[i][j] == 4: 710 | pygame.draw.line(screen, color, (j * num2, i * num1 + (0.5 * num1)), 711 | (j * num2 + num2, i * num1 + (0.5 * num1)), 3) 712 | if level[i][j] == 5: 713 | pygame.draw.arc(screen, color, [(j * num2 - (num2 * 0.4)) - 2, (i * num1 + (0.5 * num1)), num2, num1], 714 | 0, PI / 2, 3) 715 | if level[i][j] == 6: 716 | pygame.draw.arc(screen, color, 717 | [(j * num2 + (num2 * 0.5)), (i * num1 + (0.5 * num1)), num2, num1], PI / 2, PI, 3) 718 | if level[i][j] == 7: 719 | pygame.draw.arc(screen, color, [(j * num2 + (num2 * 0.5)), (i * num1 - (0.4 * num1)), num2, num1], PI, 720 | 3 * PI / 2, 3) 721 | if level[i][j] == 8: 722 | pygame.draw.arc(screen, color, 723 | [(j * num2 - (num2 * 0.4)) - 2, (i * num1 - (0.4 * num1)), num2, num1], 3 * PI / 2, 724 | 2 * PI, 3) 725 | if level[i][j] == 9: 726 | pygame.draw.line(screen, 'white', (j * num2, i * num1 + (0.5 * num1)), 727 | (j * num2 + num2, i * num1 + (0.5 * num1)), 3) 728 | 729 | 730 | def draw_player(): 731 | # 0-RIGHT, 1-LEFT, 2-UP, 3-DOWN 732 | if direction == 0: 733 | screen.blit(player_images[counter // 5], (player_x, player_y)) 734 | elif direction == 1: 735 | screen.blit(pygame.transform.flip(player_images[counter // 5], True, False), (player_x, player_y)) 736 | elif direction == 2: 737 | screen.blit(pygame.transform.rotate(player_images[counter // 5], 90), (player_x, player_y)) 738 | elif direction == 3: 739 | screen.blit(pygame.transform.rotate(player_images[counter // 5], 270), (player_x, player_y)) 740 | 741 | 742 | def check_position(centerx, centery): 743 | turns = [False, False, False, False] 744 | num1 = (HEIGHT - 50) // 32 745 | num2 = (WIDTH // 30) 746 | num3 = 15 747 | # check collisions based on center x and center y of player +/- fudge number 748 | if centerx // 30 < 29: 749 | if direction == 0: 750 | if level[centery // num1][(centerx - num3) // num2] < 3: 751 | turns[1] = True 752 | if direction == 1: 753 | if level[centery // num1][(centerx + num3) // num2] < 3: 754 | turns[0] = True 755 | if direction == 2: 756 | if level[(centery + num3) // num1][centerx // num2] < 3: 757 | turns[3] = True 758 | if direction == 3: 759 | if level[(centery - num3) // num1][centerx // num2] < 3: 760 | turns[2] = True 761 | 762 | if direction == 2 or direction == 3: 763 | if 12 <= centerx % num2 <= 18: 764 | if level[(centery + num3) // num1][centerx // num2] < 3: 765 | turns[3] = True 766 | if level[(centery - num3) // num1][centerx // num2] < 3: 767 | turns[2] = True 768 | if 12 <= centery % num1 <= 18: 769 | if level[centery // num1][(centerx - num2) // num2] < 3: 770 | turns[1] = True 771 | if level[centery // num1][(centerx + num2) // num2] < 3: 772 | turns[0] = True 773 | if direction == 0 or direction == 1: 774 | if 12 <= centerx % num2 <= 18: 775 | if level[(centery + num1) // num1][centerx // num2] < 3: 776 | turns[3] = True 777 | if level[(centery - num1) // num1][centerx // num2] < 3: 778 | turns[2] = True 779 | if 12 <= centery % num1 <= 18: 780 | if level[centery // num1][(centerx - num3) // num2] < 3: 781 | turns[1] = True 782 | if level[centery // num1][(centerx + num3) // num2] < 3: 783 | turns[0] = True 784 | else: 785 | turns[0] = True 786 | turns[1] = True 787 | 788 | return turns 789 | 790 | 791 | def move_player(play_x, play_y): 792 | # r, l, u, d 793 | if direction == 0 and turns_allowed[0]: 794 | play_x += player_speed 795 | elif direction == 1 and turns_allowed[1]: 796 | play_x -= player_speed 797 | if direction == 2 and turns_allowed[2]: 798 | play_y -= player_speed 799 | elif direction == 3 and turns_allowed[3]: 800 | play_y += player_speed 801 | return play_x, play_y 802 | 803 | 804 | def get_targets(blink_x, blink_y, ink_x, ink_y, pink_x, pink_y, clyd_x, clyd_y): 805 | if player_x < 450: 806 | runaway_x = 900 807 | else: 808 | runaway_x = 0 809 | if player_y < 450: 810 | runaway_y = 900 811 | else: 812 | runaway_y = 0 813 | return_target = (380, 400) 814 | if powerup: 815 | if not blinky.dead and not eaten_ghost[0]: 816 | blink_target = (runaway_x, runaway_y) 817 | elif not blinky.dead and eaten_ghost[0]: 818 | if 340 < blink_x < 560 and 340 < blink_y < 500: 819 | blink_target = (400, 100) 820 | else: 821 | blink_target = (player_x, player_y) 822 | else: 823 | blink_target = return_target 824 | if not inky.dead and not eaten_ghost[1]: 825 | ink_target = (runaway_x, player_y) 826 | elif not inky.dead and eaten_ghost[1]: 827 | if 340 < ink_x < 560 and 340 < ink_y < 500: 828 | ink_target = (400, 100) 829 | else: 830 | ink_target = (player_x, player_y) 831 | else: 832 | ink_target = return_target 833 | if not pinky.dead: 834 | pink_target = (player_x, runaway_y) 835 | elif not pinky.dead and eaten_ghost[2]: 836 | if 340 < pink_x < 560 and 340 < pink_y < 500: 837 | pink_target = (400, 100) 838 | else: 839 | pink_target = (player_x, player_y) 840 | else: 841 | pink_target = return_target 842 | if not clyde.dead and not eaten_ghost[3]: 843 | clyd_target = (450, 450) 844 | elif not clyde.dead and eaten_ghost[3]: 845 | if 340 < clyd_x < 560 and 340 < clyd_y < 500: 846 | clyd_target = (400, 100) 847 | else: 848 | clyd_target = (player_x, player_y) 849 | else: 850 | clyd_target = return_target 851 | else: 852 | if not blinky.dead: 853 | if 340 < blink_x < 560 and 340 < blink_y < 500: 854 | blink_target = (400, 100) 855 | else: 856 | blink_target = (player_x, player_y) 857 | else: 858 | blink_target = return_target 859 | if not inky.dead: 860 | if 340 < ink_x < 560 and 340 < ink_y < 500: 861 | ink_target = (400, 100) 862 | else: 863 | ink_target = (player_x, player_y) 864 | else: 865 | ink_target = return_target 866 | if not pinky.dead: 867 | if 340 < pink_x < 560 and 340 < pink_y < 500: 868 | pink_target = (400, 100) 869 | else: 870 | pink_target = (player_x, player_y) 871 | else: 872 | pink_target = return_target 873 | if not clyde.dead: 874 | if 340 < clyd_x < 560 and 340 < clyd_y < 500: 875 | clyd_target = (400, 100) 876 | else: 877 | clyd_target = (player_x, player_y) 878 | else: 879 | clyd_target = return_target 880 | return [blink_target, ink_target, pink_target, clyd_target] 881 | 882 | 883 | run = True 884 | while run: 885 | timer.tick(fps) 886 | if counter < 19: 887 | counter += 1 888 | if counter > 3: 889 | flicker = False 890 | else: 891 | counter = 0 892 | flicker = True 893 | if powerup and power_counter < 600: 894 | power_counter += 1 895 | elif powerup and power_counter >= 600: 896 | power_counter = 0 897 | powerup = False 898 | eaten_ghost = [False, False, False, False] 899 | if startup_counter < 180 and not game_over and not game_won: 900 | moving = False 901 | startup_counter += 1 902 | else: 903 | moving = True 904 | 905 | screen.fill('black') 906 | draw_board() 907 | center_x = player_x + 23 908 | center_y = player_y + 24 909 | if powerup: 910 | ghost_speeds = [1, 1, 1, 1] 911 | else: 912 | ghost_speeds = [2, 2, 2, 2] 913 | if eaten_ghost[0]: 914 | ghost_speeds[0] = 2 915 | if eaten_ghost[1]: 916 | ghost_speeds[1] = 2 917 | if eaten_ghost[2]: 918 | ghost_speeds[2] = 2 919 | if eaten_ghost[3]: 920 | ghost_speeds[3] = 2 921 | if blinky_dead: 922 | ghost_speeds[0] = 4 923 | if inky_dead: 924 | ghost_speeds[1] = 4 925 | if pinky_dead: 926 | ghost_speeds[2] = 4 927 | if clyde_dead: 928 | ghost_speeds[3] = 4 929 | 930 | game_won = True 931 | for i in range(len(level)): 932 | if 1 in level[i] or 2 in level[i]: 933 | game_won = False 934 | 935 | player_circle = pygame.draw.circle(screen, 'black', (center_x, center_y), 20, 2) 936 | draw_player() 937 | blinky = Ghost(blinky_x, blinky_y, targets[0], ghost_speeds[0], blinky_img, blinky_direction, blinky_dead, 938 | blinky_box, 0) 939 | inky = Ghost(inky_x, inky_y, targets[1], ghost_speeds[1], inky_img, inky_direction, inky_dead, 940 | inky_box, 1) 941 | pinky = Ghost(pinky_x, pinky_y, targets[2], ghost_speeds[2], pinky_img, pinky_direction, pinky_dead, 942 | pinky_box, 2) 943 | clyde = Ghost(clyde_x, clyde_y, targets[3], ghost_speeds[3], clyde_img, clyde_direction, clyde_dead, 944 | clyde_box, 3) 945 | draw_misc() 946 | targets = get_targets(blinky_x, blinky_y, inky_x, inky_y, pinky_x, pinky_y, clyde_x, clyde_y) 947 | 948 | turns_allowed = check_position(center_x, center_y) 949 | if moving: 950 | player_x, player_y = move_player(player_x, player_y) 951 | if not blinky_dead and not blinky.in_box: 952 | blinky_x, blinky_y, blinky_direction = blinky.move_blinky() 953 | else: 954 | blinky_x, blinky_y, blinky_direction = blinky.move_clyde() 955 | if not pinky_dead and not pinky.in_box: 956 | pinky_x, pinky_y, pinky_direction = pinky.move_pinky() 957 | else: 958 | pinky_x, pinky_y, pinky_direction = pinky.move_clyde() 959 | if not inky_dead and not inky.in_box: 960 | inky_x, inky_y, inky_direction = inky.move_inky() 961 | else: 962 | inky_x, inky_y, inky_direction = inky.move_clyde() 963 | clyde_x, clyde_y, clyde_direction = clyde.move_clyde() 964 | score, powerup, power_counter, eaten_ghost = check_collisions(score, powerup, power_counter, eaten_ghost) 965 | # add to if not powerup to check if eaten ghosts 966 | if not powerup: 967 | if (player_circle.colliderect(blinky.rect) and not blinky.dead) or \ 968 | (player_circle.colliderect(inky.rect) and not inky.dead) or \ 969 | (player_circle.colliderect(pinky.rect) and not pinky.dead) or \ 970 | (player_circle.colliderect(clyde.rect) and not clyde.dead): 971 | if lives > 0: 972 | lives -= 1 973 | startup_counter = 0 974 | powerup = False 975 | power_counter = 0 976 | player_x = 450 977 | player_y = 663 978 | direction = 0 979 | direction_command = 0 980 | blinky_x = 56 981 | blinky_y = 58 982 | blinky_direction = 0 983 | inky_x = 440 984 | inky_y = 388 985 | inky_direction = 2 986 | pinky_x = 440 987 | pinky_y = 438 988 | pinky_direction = 2 989 | clyde_x = 440 990 | clyde_y = 438 991 | clyde_direction = 2 992 | eaten_ghost = [False, False, False, False] 993 | blinky_dead = False 994 | inky_dead = False 995 | clyde_dead = False 996 | pinky_dead = False 997 | else: 998 | game_over = True 999 | moving = False 1000 | startup_counter = 0 1001 | if powerup and player_circle.colliderect(blinky.rect) and eaten_ghost[0] and not blinky.dead: 1002 | if lives > 0: 1003 | powerup = False 1004 | power_counter = 0 1005 | lives -= 1 1006 | startup_counter = 0 1007 | player_x = 450 1008 | player_y = 663 1009 | direction = 0 1010 | direction_command = 0 1011 | blinky_x = 56 1012 | blinky_y = 58 1013 | blinky_direction = 0 1014 | inky_x = 440 1015 | inky_y = 388 1016 | inky_direction = 2 1017 | pinky_x = 440 1018 | pinky_y = 438 1019 | pinky_direction = 2 1020 | clyde_x = 440 1021 | clyde_y = 438 1022 | clyde_direction = 2 1023 | eaten_ghost = [False, False, False, False] 1024 | blinky_dead = False 1025 | inky_dead = False 1026 | clyde_dead = False 1027 | pinky_dead = False 1028 | else: 1029 | game_over = True 1030 | moving = False 1031 | startup_counter = 0 1032 | if powerup and player_circle.colliderect(inky.rect) and eaten_ghost[1] and not inky.dead: 1033 | if lives > 0: 1034 | powerup = False 1035 | power_counter = 0 1036 | lives -= 1 1037 | startup_counter = 0 1038 | player_x = 450 1039 | player_y = 663 1040 | direction = 0 1041 | direction_command = 0 1042 | blinky_x = 56 1043 | blinky_y = 58 1044 | blinky_direction = 0 1045 | inky_x = 440 1046 | inky_y = 388 1047 | inky_direction = 2 1048 | pinky_x = 440 1049 | pinky_y = 438 1050 | pinky_direction = 2 1051 | clyde_x = 440 1052 | clyde_y = 438 1053 | clyde_direction = 2 1054 | eaten_ghost = [False, False, False, False] 1055 | blinky_dead = False 1056 | inky_dead = False 1057 | clyde_dead = False 1058 | pinky_dead = False 1059 | else: 1060 | game_over = True 1061 | moving = False 1062 | startup_counter = 0 1063 | if powerup and player_circle.colliderect(pinky.rect) and eaten_ghost[2] and not pinky.dead: 1064 | if lives > 0: 1065 | powerup = False 1066 | power_counter = 0 1067 | lives -= 1 1068 | startup_counter = 0 1069 | player_x = 450 1070 | player_y = 663 1071 | direction = 0 1072 | direction_command = 0 1073 | blinky_x = 56 1074 | blinky_y = 58 1075 | blinky_direction = 0 1076 | inky_x = 440 1077 | inky_y = 388 1078 | inky_direction = 2 1079 | pinky_x = 440 1080 | pinky_y = 438 1081 | pinky_direction = 2 1082 | clyde_x = 440 1083 | clyde_y = 438 1084 | clyde_direction = 2 1085 | eaten_ghost = [False, False, False, False] 1086 | blinky_dead = False 1087 | inky_dead = False 1088 | clyde_dead = False 1089 | pinky_dead = False 1090 | else: 1091 | game_over = True 1092 | moving = False 1093 | startup_counter = 0 1094 | if powerup and player_circle.colliderect(clyde.rect) and eaten_ghost[3] and not clyde.dead: 1095 | if lives > 0: 1096 | powerup = False 1097 | power_counter = 0 1098 | lives -= 1 1099 | startup_counter = 0 1100 | player_x = 450 1101 | player_y = 663 1102 | direction = 0 1103 | direction_command = 0 1104 | blinky_x = 56 1105 | blinky_y = 58 1106 | blinky_direction = 0 1107 | inky_x = 440 1108 | inky_y = 388 1109 | inky_direction = 2 1110 | pinky_x = 440 1111 | pinky_y = 438 1112 | pinky_direction = 2 1113 | clyde_x = 440 1114 | clyde_y = 438 1115 | clyde_direction = 2 1116 | eaten_ghost = [False, False, False, False] 1117 | blinky_dead = False 1118 | inky_dead = False 1119 | clyde_dead = False 1120 | pinky_dead = False 1121 | else: 1122 | game_over = True 1123 | moving = False 1124 | startup_counter = 0 1125 | if powerup and player_circle.colliderect(blinky.rect) and not blinky.dead and not eaten_ghost[0]: 1126 | blinky_dead = True 1127 | eaten_ghost[0] = True 1128 | score += (2 ** eaten_ghost.count(True)) * 100 1129 | if powerup and player_circle.colliderect(inky.rect) and not inky.dead and not eaten_ghost[1]: 1130 | inky_dead = True 1131 | eaten_ghost[1] = True 1132 | score += (2 ** eaten_ghost.count(True)) * 100 1133 | if powerup and player_circle.colliderect(pinky.rect) and not pinky.dead and not eaten_ghost[2]: 1134 | pinky_dead = True 1135 | eaten_ghost[2] = True 1136 | score += (2 ** eaten_ghost.count(True)) * 100 1137 | if powerup and player_circle.colliderect(clyde.rect) and not clyde.dead and not eaten_ghost[3]: 1138 | clyde_dead = True 1139 | eaten_ghost[3] = True 1140 | score += (2 ** eaten_ghost.count(True)) * 100 1141 | 1142 | for event in pygame.event.get(): 1143 | if event.type == pygame.QUIT: 1144 | run = False 1145 | if event.type == pygame.KEYDOWN: 1146 | if event.key == pygame.K_RIGHT: 1147 | direction_command = 0 1148 | if event.key == pygame.K_LEFT: 1149 | direction_command = 1 1150 | if event.key == pygame.K_UP: 1151 | direction_command = 2 1152 | if event.key == pygame.K_DOWN: 1153 | direction_command = 3 1154 | if event.key == pygame.K_SPACE and (game_over or game_won): 1155 | powerup = False 1156 | power_counter = 0 1157 | lives -= 1 1158 | startup_counter = 0 1159 | player_x = 450 1160 | player_y = 663 1161 | direction = 0 1162 | direction_command = 0 1163 | blinky_x = 56 1164 | blinky_y = 58 1165 | blinky_direction = 0 1166 | inky_x = 440 1167 | inky_y = 388 1168 | inky_direction = 2 1169 | pinky_x = 440 1170 | pinky_y = 438 1171 | pinky_direction = 2 1172 | clyde_x = 440 1173 | clyde_y = 438 1174 | clyde_direction = 2 1175 | eaten_ghost = [False, False, False, False] 1176 | blinky_dead = False 1177 | inky_dead = False 1178 | clyde_dead = False 1179 | pinky_dead = False 1180 | score = 0 1181 | lives = 3 1182 | level = copy.deepcopy(boards) 1183 | game_over = False 1184 | game_won = False 1185 | 1186 | if event.type == pygame.KEYUP: 1187 | if event.key == pygame.K_RIGHT and direction_command == 0: 1188 | direction_command = direction 1189 | if event.key == pygame.K_LEFT and direction_command == 1: 1190 | direction_command = direction 1191 | if event.key == pygame.K_UP and direction_command == 2: 1192 | direction_command = direction 1193 | if event.key == pygame.K_DOWN and direction_command == 3: 1194 | direction_command = direction 1195 | 1196 | if direction_command == 0 and turns_allowed[0]: 1197 | direction = 0 1198 | if direction_command == 1 and turns_allowed[1]: 1199 | direction = 1 1200 | if direction_command == 2 and turns_allowed[2]: 1201 | direction = 2 1202 | if direction_command == 3 and turns_allowed[3]: 1203 | direction = 3 1204 | 1205 | if player_x > 900: 1206 | player_x = -47 1207 | elif player_x < -50: 1208 | player_x = 897 1209 | 1210 | if blinky.in_box and blinky_dead: 1211 | blinky_dead = False 1212 | if inky.in_box and inky_dead: 1213 | inky_dead = False 1214 | if pinky.in_box and pinky_dead: 1215 | pinky_dead = False 1216 | if clyde.in_box and clyde_dead: 1217 | clyde_dead = False 1218 | 1219 | pygame.display.flip() 1220 | pygame.quit() 1221 | 1222 | 1223 | # sound effects, restart and winning messages 1224 | --------------------------------------------------------------------------------