i’m trying to make a pacman game like pygame, now i just want him to walk through the maze without going beyond the walls of the maze. However I have faced some problems, when I press the keys to move the pacman, he ends up telephoning between the walls, although he does not exceed them it ends up bugging the coordinate system and starts to give a series of errors during the game commands . Does anyone know why this is happening and how to solve it?
JavaScript
x
157
157
1
import pygame
2
pygame.init()
3
window = pygame.display.set_mode((800, 600), 0)
4
# Color used in the game
5
YELLOW = (255,255,0)
6
BLACK = (0,0,0)
7
BLUE = (13,56,143)
8
speed = 1
9
class Scenery:
10
def __init__(self, size, character):
11
self.character = character
12
self.size = size
13
self.matrix = [
14
[2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2],
15
[2, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 2, 2, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 2],
16
[2, 1, 2, 2, 2, 2, 1, 2, 2, 2, 2, 2, 1, 2, 2, 1, 2, 2, 2, 2, 2, 1, 2, 2, 2, 2, 1, 2],
17
[2, 1, 2, 2, 2, 2, 1, 2, 2, 2, 2, 2, 1, 1, 1, 1, 2, 2, 2, 2, 2, 1, 2, 2, 2, 2, 1, 2],
18
[2, 1, 2, 2, 2, 2, 1, 2, 2, 2, 2, 2, 1, 2, 2, 1, 2, 2, 2, 2, 2, 1, 2, 2, 2, 2, 1, 2],
19
[2, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 2, 2, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 2],
20
[2, 1, 2, 2, 2, 2, 1, 2, 2, 1, 2, 2, 2, 2, 2, 2, 2, 2, 1, 2, 2, 1, 2, 2, 2, 2, 1, 2],
21
[2, 1, 2, 2, 2, 2, 1, 2, 2, 1, 2, 2, 2, 2, 2, 2, 2, 2, 1, 2, 2, 1, 2, 2, 2, 2, 1, 2],
22
[2, 1, 1, 1, 1, 1, 1, 2, 2, 1, 1, 1, 1, 2, 2, 1, 1, 1, 1, 2, 2, 1, 1, 1, 1, 1, 1, 2],
23
[2, 2, 2, 1, 2, 2, 1, 2, 2, 2, 2, 2, 1, 2, 2, 1, 2, 2, 2, 2, 2, 1, 2, 2, 1, 2, 2, 2],
24
[2, 2, 2, 1, 2, 2, 1, 2, 2, 2, 2, 2, 1, 2, 2, 1, 2, 2, 2, 2, 2, 1, 2, 2, 1, 2, 2, 2],
25
[2, 1, 1, 1, 2, 2, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 2, 2, 1, 1, 1, 2],
26
[2, 1, 2, 2, 2, 2, 1, 2, 2, 1, 2, 2, 0, 0, 0, 0, 2, 2, 1, 2, 2, 1, 2, 2, 2, 2, 1, 2],
27
[2, 1, 2, 2, 2, 2, 1, 2, 2, 1, 2, 0, 0, 0, 0, 0, 0, 2, 1, 2, 2, 1, 2, 2, 2, 2, 1, 2],
28
[2, 1, 1, 1, 1, 1, 1, 2, 2, 1, 2, 0, 0, 0, 0, 0, 0, 2, 1, 2, 2, 1, 1, 1, 1, 1, 1, 2],
29
[2, 1, 2, 2, 2, 2, 1, 2, 2, 1, 2, 0, 0, 0, 0, 0, 0, 2, 1, 2, 2, 1, 2, 2, 2, 2, 1, 2],
30
[2, 1, 2, 2, 2, 2, 1, 2, 2, 1, 2, 2, 2, 2, 2, 2, 2, 2, 1, 2, 2, 1, 2, 2, 2, 2, 1, 2],
31
[2, 1, 1, 1, 2, 2, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 2, 2, 1, 1, 1, 2],
32
[2, 2, 2, 1, 2, 2, 1, 2, 2, 2, 2, 2, 1, 2, 2, 1, 2, 2, 2, 2, 2, 1, 2, 2, 1, 2, 2, 2],
33
[2, 2, 2, 1, 2, 2, 1, 2, 2, 2, 2, 2, 1, 2, 2, 1, 2, 2, 2, 2, 2, 1, 2, 2, 1, 2, 2, 2],
34
[2, 1, 1, 1, 1, 1, 1, 2, 2, 1, 1, 1, 1, 2, 2, 1, 1, 1, 1, 2, 2, 1, 1, 1, 1, 1, 1, 2],
35
[2, 1, 2, 2, 2, 2, 1, 2, 2, 1, 2, 2, 2, 2, 2, 2, 2, 2, 1, 2, 2, 1, 2, 2, 2, 2, 1, 2],
36
[2, 1, 2, 2, 2, 2, 1, 2, 2, 1, 2, 2, 2, 2, 2, 2, 2, 2, 1, 2, 2, 1, 2, 2, 2, 2, 1, 2],
37
[2, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 2, 2, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 2],
38
[2, 1, 2, 2, 2, 2, 1, 2, 2, 2, 2, 2, 1, 2, 2, 1, 2, 2, 2, 2, 2, 1, 2, 2, 2, 2, 1, 2],
39
[2, 1, 2, 2, 2, 2, 1, 2, 2, 2, 2, 2, 1, 1, 1, 1, 2, 2, 2, 2, 2, 1, 2, 2, 2, 2, 1, 2],
40
[2, 1, 2, 2, 2, 2, 1, 2, 2, 2, 2, 2, 1, 2, 2, 1, 2, 2, 2, 2, 2, 1, 2, 2, 2, 2, 1, 2],
41
[2, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 2, 2, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 2],
42
[2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2]
43
]
44
def paint_line(self, surface, line_index, line):
45
for column_index, column in enumerate(line):
46
x_box = column_index * self.size
47
y_box = line_index * self.size
48
half_size = self.size // 2
49
color = BLACK
50
if column == 2:
51
color = BLUE
52
pygame.draw.rect(surface, color, (x_box, y_box, self.size, self.size), 0)
53
if column == 1:
54
pygame.draw.circle(surface, YELLOW, (x_box + half_size, y_box + half_size), self.size//10, 0)
55
def paint_scenery(self, surface):
56
for line_index, line in enumerate(self.matrix):
57
self.paint_line(surface, line_index, line)
58
def calculate_rules(self):
59
column_character = self.character.intention_column
60
line_character = self.character.intention_line
61
if 0 <= column_character < 28 and 0 <= line_character < 29:
62
if self.matrix[line_character][column_character] != 2:
63
self.character.aprove_movement()
64
class Pacman:
65
def __init__(self, size):
66
self.column = 1
67
self.line = 1
68
self.x_center = 400
69
self.y_center = 300
70
self.size = size # 2x radius and size/number of the cells
71
self.speed_x = 0
72
self.speed_y = 0
73
self.radius = self.size // 2
74
self.intention_column = self.column
75
self.intention_line = self.line
76
77
def calculate_rules(self):
78
# calculate the movimentantion
79
self.intention_column = self.intention_column + self.speed_x
80
self.intention_line = self.intention_line + self.speed_y
81
self.x_center = int( self.column * self.size + self.radius )
82
self.y_center = int( self.line * self.size + self.radius )
83
84
def draw_pacman(self, surface):
85
# Draw pacman's character
86
pacman_body = pygame.draw.circle(surface, YELLOW, (self.x_center, self.y_center), self.radius, 0)
87
88
89
# Coordinates
90
x_eye_position = ( self.x_center + int( self.radius/4 ) )
91
y_eye_position = ( self.y_center - int( (self.radius/2) ) )
92
point_a = (self.x_center, self.y_center) # Center
93
point_b = ((self.x_center + self.radius), self.y_center) # Right Center
94
point_c = ((self.x_center + self.radius), (self.y_center - self.radius)) # Superior Right Center
95
points = [point_a, point_b, point_c]
96
# Pacman
97
pacman_eye = pygame.draw.circle(surface, BLACK, (x_eye_position, y_eye_position), int(self.radius/10), 0)
98
pacman_mouth = pygame.draw.polygon(surface, BLACK, points, 0)
99
# Make the draws
100
pacman_body
101
pacman_eye
102
pacman_mouth
103
104
def calculate_events(self, events):
105
for e in events:
106
if e.type == pygame.QUIT: # check if the user have clicked on the X box to quit
107
exit()
108
elif e.type == pygame.KEYDOWN:
109
if e.key == pygame.K_RIGHT or e.key == pygame.K_d:
110
self.speed_x = speed
111
elif e.key == pygame.K_LEFT or e.key == pygame.K_a:
112
self.speed_x = -speed
113
elif e.key == pygame.K_UP or e.key == pygame.K_w:
114
self.speed_y = -speed
115
elif e.key == pygame.K_DOWN or e.key == pygame.K_s:
116
self.speed_y = speed
117
elif e.type == pygame.KEYUP:
118
if e.key == pygame.K_RIGHT or e.key == pygame.K_d:
119
self.speed_x = 0
120
elif e.key == pygame.K_LEFT or e.key == pygame.K_a:
121
self.speed_x = 0
122
elif e.key == pygame.K_UP or e.key == pygame.K_w:
123
self.speed_y = 0
124
elif e.key == pygame.K_DOWN or e.key == pygame.K_s:
125
self.speed_y = 0
126
127
def aprove_movement(self):
128
self.column = self.intention_column
129
self.line = self.intention_line
130
131
132
if __name__ == '__main__':
133
size = 600 // 30
134
pacman = Pacman(size)
135
scenary = Scenery(size, pacman)
136
137
138
while True:
139
140
# Game Rules
141
pacman.calculate_rules()
142
scenary.calculate_rules()
143
144
145
# Figures
146
window.fill(BLACK)
147
scenary.paint_scenery(window)
148
pacman.draw_pacman(window)
149
pygame.display.update()
150
pygame.time.delay(100)
151
152
153
events = pygame.event.get()
154
pacman.calculate_events(events)
155
156
157
SO every time i hold the keys to move for a few seconds the pacman goes over the blue walls of the project, does anyone know why and how to fix it?
Looks like he just teleports to the other sides and than bug the role coordinate system
Advertisement
Answer
There are 2 issues:
- The
intention_column
andintention_line
depends on the currentcolume
andline
instead of the previousintention_column
andintention_line
.intention_column
andintention_line
are incremented even if there is a wall.colume
andline
however are only incremented if the movement is possible:
JavaScript
1
8
1
class Pacman:
2
# [...]
3
4
def calculate_rules(self):
5
# calculate the movimentantion
6
self.intention_column = self.column + self.speed_x
7
self.intention_line = self.line + self.speed_y
8
- Only update
x_center
andy_center
ifcolumn
orline
are changed:
JavaScript
1
9
1
class Pacman:
2
# [...]
3
4
def aprove_movement(self):
5
self.column = self.intention_column
6
self.line = self.intention_line
7
self.x_center = int( self.column * self.size + self.radius )
8
self.y_center = int( self.line * self.size + self.radius )
9