[英]How to make ghost in pacman move slower? Python
我在 pygame 寫 pacman。我有鬼移動的問題。 它移動得太快了。 當它以速度 1 移動時,它非常快。 當速度為 0.1 時,我的代碼不起作用。
這是幽靈運動代碼:
#GHOST MOVE
move_list = ['right', 'left', 'up', 'down']
move_chise = random.choice(move_list)
if move_chise == 'right':
while not sprite.spritecollide(ghost, walls, False):
ghost.rect.x += speed
ghost.rect.x -= 2
elif move_chise == 'left':
while not sprite.spritecollide(ghost, walls, False):
ghost.rect.x -= speed
ghost.rect.x += 2
elif move_chise == 'up':
while not sprite.spritecollide(ghost, walls, False):
ghost.rect.y -= speed
ghost.rect.y += 2
elif move_chise == 'down':
while not sprite.spritecollide(ghost, walls, False):
ghost.rect.y += speed
ghost.rect.y -= 2
這是我的所有代碼:
import random
from pygame import *
animCount = 0
class GameSprite(sprite.Sprite):
def __init__(self, player_image, player_x, player_y, size_x, size_y, player_speed):
super().__init__()
self.image = transform.scale(image.load(player_image), (size_x, size_y))
self.speed = player_speed
self.rect = self.image.get_rect()
self.rect.x = player_x
self.rect.y = player_y
def show(player):
window.blit(player.image, (player.rect.x, player.rect.y))
class Hero(GameSprite):
def update(player):
print('fff')
class Enemy(GameSprite):
def move(self):
pass
class Wall(sprite.Sprite):
def __init__(self, color1, color2, color3, wall_x, wall_y, wall_width, wall_height):
super().__init__()
self.color1 = color1
self.color2 = color2
self.color3 = color3
self.width = wall_width
self.height = wall_height
self.image = Surface((self.width, self.height))
self.image.fill((color1, color2, color3))
self.rect = self.image.get_rect()
self.rect.x = wall_x
self.rect.y = wall_y
def draw_wall(self):
window.blit(self.image, (self.rect.x, self.rect.y))
class Coins_s(sprite.Sprite):
def __init__(self, color1, color2, color3, wall_x, wall_y, wall_width, wall_height):
super().__init__()
self.color1 = color1
self.color2 = color2
self.color3 = color3
self.width = wall_width
self.height = wall_height
self.image = Surface((self.width, self.height))
self.image.fill((color1, color2, color3))
self.rect = self.image.get_rect()
self.rect.x = wall_x
self.rect.y = wall_y
def draw_wall(self):
window.blit(self.image, (self.rect.x, self.rect.y))
coins = sprite.Group()
win_height = 700
win_width = 700
window = display.set_mode((win_width, win_height))
display.set_caption('Pacman Game')
clock = time.Clock()
back = transform.scale(image.load('photo_2022-06-05_21-28-54.jpg'), (700, 700))
player = Hero('photo_2022-06-05_20-54-50.jpg', 10, 309, 15, 15, 2)
ghost = Enemy('photo_2022-06-05_20-56-46.jpg', 350, 309, 20, 25, 2)
w1 = Wall(169,169,169, 0, 0, 700, 31)
w2 = Wall(169,169,169, 0, 20, 31, 210)
w3 = Wall(169,169,169, 0, 200, 145, 31)
w4 = Wall(169,169,169, 115, 200, 31, 95)
w5 = Wall(169,169,169, 0, 270, 145, 31)
w7 = Wall(169,169,169, 670, 20, 31, 210)
w8 = Wall(169,169,169, 556, 200, 145, 31)
w9 = Wall(169,169,169, 556, 200, 31, 95)
w10 = Wall(169,169,169, 556, 270, 150, 31)
w11 = Wall(169,169,169, 335, 0, 31, 95)
w12 = Wall(169,169,169, 187, 70, 110, 31)
w13 = Wall(169,169,169, 406, 70, 110, 31)
w14 = Wall(169,169,169, 187, 470, 110, 31)
w15 = Wall(169,169,169, 406, 470, 110, 31)
w16 = Wall(169,169,169, 190, 335, 31, 95)
w17 = Wall(169,169,169, 485, 335, 31, 95)
w18 = Wall(169,169,169, 0, 670, 700, 31)
w19 = Wall(169,169,169, 0, 400, 31, 280)
w20 = Wall(169,169,169, 0, 400, 145, 31)
w21 = Wall(169,169,169, 115, 340, 31, 70)
w22 = Wall(169,169,169, 0, 334, 145, 31)
w23 = Wall(169,169,169, 670, 400, 31, 280)
w24 = Wall(169,169,169, 556, 340, 31, 70)
w25 = Wall(169,169,169, 556, 334, 145, 31)
w26 = Wall(169,169,169, 556, 400, 150, 31)
w27 = Wall(169,169,169, 16, 531, 60, 31)
w28 = Wall(169,169,169, 624, 531, 60, 31)
w29 = Wall(169,169,169, 260, 340, 180, 31)
w30 = Wall(169,169,169, 260, 135, 180, 31)
w31 = Wall(169,169,169, 260, 531, 180, 31)
w32 = Wall(169,169,169, 260, 400, 180, 31)
w33 = Wall(169,169,169, 190, 135, 31, 160)
w34 = Wall(169,169,169, 335, 135, 31, 95)
w35 = Wall(169,169,169, 335, 405, 31, 95)
w36 = Wall(169,169,169, 335, 542, 31, 95)
w37 = Wall(169,169,169, 190, 535, 31, 95)
w38 = Wall(169,169,169, 485, 535, 31, 95)
w39 = Wall(169,169,169, 485, 135, 31, 160)
w40 = Wall(169,169,169, 75, 70, 70, 31)
w41 = Wall(169,169,169, 75, 133, 70, 31)
w42 = Wall(169,169,169, 555, 70, 70, 31)
w43 = Wall(169,169,169, 555, 133, 70, 31)
w44 = Wall(169,169,169, 555, 470, 70, 31)
w45 = Wall(169,169,169, 75, 470, 70, 31)
w46 = Wall(169,169,169, 115, 470, 31, 95)
w47 = Wall(169,169,169, 555, 470, 31, 95)
w48 = Wall(169,169,169, 75, 600, 220, 31)
w49 = Wall(169,169,169, 405, 600, 220, 31)
w50 = Wall(169,169,169, 215, 200, 85, 31)
w51 = Wall(169,169,169, 405, 200, 85, 31)
w52 = Wall(169,169,169, 260, 270, 30, 31)
w53 = Wall(169,169,169, 410, 270, 30, 31)
w54 = Wall(169,169,169, 260, 275, 31, 95)
w55 = Wall(169,169,169, 410, 275, 31, 95)
C1 = Coins_s(255,255,0, 130, 309, 5, 5)
C2 = Coins_s(255,255,0, 240, 309, 5, 5)
C3 = Coins_s(255,255,0, 340, 250, 5, 5)
C4 = Coins_s(255,255,0, 460, 309, 5, 5)
C5 = Coins_s(255,255,0, 570, 309, 5, 5)
C6 = Coins_s(255,255,0, 240, 180, 5, 5)
C7 = Coins_s(255,255,0, 460, 180, 5, 5)
C8 = Coins_s(255,255,0, 310, 111, 5, 5)
C9 = Coins_s(255,255,0, 390, 111, 5, 5)
C10 = Coins_s(255,255,0, 60, 180, 5, 5)
C11 = Coins_s(255,255,0, 640, 180, 5, 5)
C12 = Coins_s(255,255,0, 60, 50, 5, 5)
C13 = Coins_s(255,255,0, 640, 50, 5, 5)
C14 = Coins_s(255,255,0, 160, 409, 5, 5)
C15 = Coins_s(255,255,0, 240, 380, 5, 5)
C16 = Coins_s(255,255,0, 340, 380, 5, 5)
C17 = Coins_s(255,255,0, 460, 380, 5, 5)
C18 = Coins_s(255,255,0, 530, 409, 5, 5)
C19 = Coins_s(255,255,0, 460, 450, 5, 5)
C20 = Coins_s(255,255,0, 240, 450, 5, 5)
C21 = Coins_s(255,255,0, 390, 450, 5, 5)
C22 = Coins_s(255,255,0, 310, 450, 5, 5)
C23 = Coins_s(255,255,0, 630, 450, 5, 5)
C24 = Coins_s(255,255,0, 50, 450, 5, 5)
C25 = Coins_s(255,255,0, 600, 520, 5, 5)
C26 = Coins_s(255,255,0, 90, 520, 5, 5)
C27 = Coins_s(255,255,0, 530, 570, 5, 5)
C28 = Coins_s(255,255,0, 160, 570, 5, 5)
C29 = Coins_s(255,255,0, 60, 640, 5, 5)
C30 = Coins_s(255,255,0, 640, 640, 5, 5)
C31 = Coins_s(255,255,0, 350, 640, 5, 5)
coins.add(C1)
coins.add(C2)
coins.add(C3)
coins.add(C4)
coins.add(C5)
coins.add(C6)
coins.add(C7)
coins.add(C8)
coins.add(C9)
coins.add(C10)
coins.add(C11)
coins.add(C12)
coins.add(C13)
coins.add(C14)
coins.add(C15)
coins.add(C16)
coins.add(C17)
coins.add(C18)
coins.add(C19)
coins.add(C20)
coins.add(C21)
coins.add(C22)
coins.add(C23)
coins.add(C24)
coins.add(C25)
coins.add(C26)
coins.add(C27)
coins.add(C28)
coins.add(C29)
coins.add(C30)
coins.add(C31)
walls = [ w1, w2, w3, w4, w5, w7, w8, w9,
w10, w11, w12, w13, w14, w15, w16, w17, w18, w19, w20, w21, w22, w23, w24,
w25, w26, w27, w28, w29, w30, w31, w32, w33, w34, w35, w36, w37, w38, w39,
w40, w41, w42, w43, w44, w45, w46, w47, w48, w49, w50, w51, w52, w53, w54,
w55]
finish = False
game = True
coins_count = 0
count = 0
speed = 1
while game:
for e in event.get():
if e.type == QUIT:
exit()
#GHOST MOVE
move_list = ['right', 'left', 'up', 'down']
move_chise = random.choice(move_list)
if move_chise == 'right':
while not sprite.spritecollide(ghost, walls, False):
ghost.rect.x += speed
ghost.rect.x -= 2
elif move_chise == 'left':
while not sprite.spritecollide(ghost, walls, False):
ghost.rect.x -= speed
ghost.rect.x += 2
elif move_chise == 'up':
while not sprite.spritecollide(ghost, walls, False):
ghost.rect.y -= speed
ghost.rect.y += 2
elif move_chise == 'down':
while not sprite.spritecollide(ghost, walls, False):
ghost.rect.y += speed
ghost.rect.y -= 2
#PACMAN MOVE
side = 'None'
keyPressed = key.get_pressed()
if keyPressed[K_LEFT] and player.rect.x > 5:
player.rect.x -= 2
if sprite.spritecollide(player, walls, False):
side = 'Right'
if side == 'Right':
print(side)
player.rect.x += 2
if keyPressed[K_RIGHT] and player.rect.x < win_width - 40:
player.rect.x += player.speed
if sprite.spritecollide(player, walls, False):
side = 'Left'
if side == 'Left':
print(side)
player.rect.x -= 2
if keyPressed[K_UP] and player.rect.y > 5:
player.rect.y -= player.speed
if sprite.spritecollide(player, walls, False):
side = 'Down'
if side == 'Down':
print(side)
player.rect.y += 2
if keyPressed[K_DOWN] and player.rect.y < win_height - 40:
player.rect.y += player.speed
if sprite.spritecollide(player, walls, False):
side = 'Up'
if side == 'Up':
print(side)
player.rect.y -= 2
if player.rect.x == 660 and 300 < player.rect.y < 330:
player.rect.x , player.rect.y = 10 ,308
if sprite.spritecollide(player, coins, True):
coins_count += 10
if finish != True:
window.fill((0, 0, 0))
for w in walls:
w.draw_wall()
coins.draw(window)
player.show()
ghost.show()
display.update()
clock.tick(60)
你能說出問題是什么以及我該如何解決嗎?
這是我的游戲的樣子:
問題是您使用while
來檢查碰撞 - 因此,在while Game
的每個循環中,它都會重復直到發生碰撞。 這會改變變量的值,但不會改變屏幕上的圖像。
在每個while game
循環中,您應該只檢查一次碰撞。 並在下一個循環中重復它。 所以你應該使用if
而不是while
。
但這還需要其他改變。 你還需要else:
當它檢測到碰撞時向后移動,它也應該 select 一個新的方向。
#GHOST MOVE
move_list = ['right', 'left', 'up', 'down']
move_chise = random.choice(move_list) # first direction at start.
while game:
for e in event.get():
if e.type == QUIT:
exit()
if move_chise == 'right':
if not sprite.spritecollide(ghost, walls, False):
ghost.rect.x += speed
else:
ghost.rect.x -= 2
move_chise = random.choice(move_list)
elif move_chise == 'left':
if not sprite.spritecollide(ghost, walls, False):
ghost.rect.x -= speed
else:
ghost.rect.x += 2
move_chise = random.choice(move_list)
elif move_chise == 'up':
if not sprite.spritecollide(ghost, walls, False):
ghost.rect.y -= speed
else:
ghost.rect.y += 2
move_chise = random.choice(move_list)
elif move_chise == 'down':
if not sprite.spritecollide(ghost, walls, False):
ghost.rect.y += speed
else:
ghost.rect.y -= 2
move_chise = random.choice(move_list)
編輯:
完整的工作代碼。
而不是圖像jpg
我使用Surface()
填充紅色 - 這樣每個人都可以簡單地復制並運行它而不需要圖像jpg
。
我也改變了:
rect.bottom
, rect.top
而不是rect.y
和rect.left
, rect.right
而不是rect.x
。blit()
中,我使用player.rect
而不是(player.rect.x, player.rect.y)
。Player.move()
和Enemy.move()
。draw(window)
而不是draw()
、 show()
或draw_wall()
。x,y,width,height
而不是player_x
、 wall_x
等。(R,G,B)
而不是分隔值color1, color2, color3
。import random
from pygame import *
class GameSprite(sprite.Sprite):
def __init__(self, image, x, y, width, height, speed):
super().__init__()
#img = image.load(image)
img = Surface((1000, 1000))
img.fill((255,0,0))
self.image = transform.scale(img, (width, height))
self.speed = speed
self.rect = self.image.get_rect()
self.rect.x = x
self.rect.y = y
def draw(self, window):
window.blit(self.image, self.rect)
class Hero(GameSprite):
def update(self):
print('TODO: Update Hero')
def move(self, keyPressed):
side = None
if keyPressed[K_LEFT] and self.rect.left > 5:
self.rect.x -= self.speed
if sprite.spritecollide(self, walls, False):
side = 'Right'
self.rect.x += 2
if keyPressed[K_RIGHT] and self.rect.right < win_width:
self.rect.x += self.speed
if sprite.spritecollide(player, walls, False):
side = 'Left'
self.rect.x -= 2
if keyPressed[K_UP] and self.rect.top > 5:
self.rect.y -= self.speed
if sprite.spritecollide(self, walls, False):
side = 'Down'
self.rect.y += 2
if keyPressed[K_DOWN] and self.rect.bottom < win_height:
self.rect.y += self.speed
if sprite.spritecollide(self, walls, False):
side = 'Up'
self.rect.y -= 2
if side:
print('Hero collision:', side)
if self.rect.right > win_width-10 and 300 < self.rect.top < 330:
self.rect.left = 10
elif self.rect.left < 10 and 300 < self.rect.top < 330:
self.rect.right = win_width-10
class Enemy(GameSprite):
def __init__(self, image, x, y, width, height, speed):
super().__init__(image, x, y, width, height, speed)
self.move_list = ['right', 'left', 'up', 'down']
self.direction = random.choice(self.move_list)
def move(self):
if self.direction == 'right':
if not sprite.spritecollide(self, walls, False):
self.rect.x += speed
else:
self.rect.x -= 2
self.direction = random.choice(self.move_list)
elif self.direction == 'left':
if not sprite.spritecollide(self, walls, False):
self.rect.x -= speed
else:
self.rect.x += 2
self.direction = random.choice(self.move_list)
elif self.direction == 'up':
if not sprite.spritecollide(self, walls, False):
self.rect.y -= speed
else:
self.rect.y += 2
self.direction = random.choice(self.move_list)
elif self.direction == 'down':
if not sprite.spritecollide(self, walls, False):
self.rect.y += speed
else:
self.rect.y -= 2
self.direction = random.choice(self.move_list)
class Wall(sprite.Sprite):
def __init__(self, color, x, y, width, height):
super().__init__()
self.color = color
self.width = width
self.height = height
self.image = Surface((self.width, self.height))
self.image.fill(color)
self.rect = self.image.get_rect()
self.rect.x = x
self.rect.y = y
def draw(self, window):
window.blit(self.image, self.rect)
# it keeps single coin so name `Coin` without `s` seems better
class Coin(sprite.Sprite):
def __init__(self, color, x, y, width, height):
super().__init__()
self.color = color
self.width = width
self.height = height
self.image = Surface((self.width, self.height))
self.image.fill(color)
self.rect = self.image.get_rect()
self.rect.x = x
self.rect.y = y
def draw(self, window):
window.blit(self.image, self.rect)
# --- main ---
win_height = 700
win_width = 700
init() # pygame.init()
window = display.set_mode((win_width, win_height))
display.set_caption('Pacman Game')
#back = transform.scale(image.load('photo_2022-06-05_21-28-54.jpg'), (700, 700))
player = Hero('photo_2022-06-05_20-54-50.jpg', 10, 309, 15, 15, 2)
player.image.fill((0,255,0))
ghost_chise = Enemy('photo_2022-06-05_20-56-46.jpg', 350, 309, 20, 25, 2)
ghost_chise.image.fill((0,255,255))
ghost_other = Enemy('photo_2022-06-05_20-56-46.jpg', 350, 309, 20, 25, 2)
ghost_other.image.fill((255,255,0))
ghost_third = Enemy('photo_2022-06-05_20-56-46.jpg', 350, 309, 20, 25, 2)
ghost_third.image.fill((255,0,255))
walls = [
Wall( (169,169,169), 0, 0, 700, 31),
Wall( (169,169,169), 0, 20, 31, 210),
Wall( (169,169,169), 0, 200, 145, 31),
Wall( (169,169,169), 115, 200, 31, 95),
Wall( (169,169,169), 0, 270, 145, 31),
Wall( (169,169,169), 670, 20, 31, 210),
Wall( (169,169,169), 556, 200, 145, 31),
Wall( (169,169,169), 556, 200, 31, 95),
Wall( (169,169,169), 556, 270, 150, 31),
Wall( (169,169,169), 335, 0, 31, 95),
Wall( (169,169,169), 187, 70, 110, 31),
Wall( (169,169,169), 406, 70, 110, 31),
Wall( (169,169,169), 187, 470, 110, 31),
Wall( (169,169,169), 406, 470, 110, 31),
Wall( (169,169,169), 190, 335, 31, 95),
Wall( (169,169,169), 485, 335, 31, 95),
Wall( (169,169,169), 0, 670, 700, 31),
Wall( (169,169,169), 0, 400, 31, 280),
Wall( (169,169,169), 0, 400, 145, 31),
Wall( (169,169,169), 115, 340, 31, 70),
Wall( (169,169,169), 0, 334, 145, 31),
Wall( (169,169,169), 670, 400, 31, 280),
Wall( (169,169,169), 556, 340, 31, 70),
Wall( (169,169,169), 556, 334, 145, 31),
Wall( (169,169,169), 556, 400, 150, 31),
Wall( (169,169,169), 16, 531, 60, 31),
Wall( (169,169,169), 624, 531, 60, 31),
Wall( (169,169,169), 260, 340, 180, 31),
Wall( (169,169,169), 260, 135, 180, 31),
Wall( (169,169,169), 260, 531, 180, 31),
Wall( (169,169,169), 260, 400, 180, 31),
Wall( (169,169,169), 190, 135, 31, 160),
Wall( (169,169,169), 335, 135, 31, 95),
Wall( (169,169,169), 335, 405, 31, 95),
Wall( (169,169,169), 335, 542, 31, 95),
Wall( (169,169,169), 190, 535, 31, 95),
Wall( (169,169,169), 485, 535, 31, 95),
Wall( (169,169,169), 485, 135, 31, 160),
Wall( (169,169,169), 75, 70, 70, 31),
Wall( (169,169,169), 75, 133, 70, 31),
Wall( (169,169,169), 555, 70, 70, 31),
Wall( (169,169,169), 555, 133, 70, 31),
Wall( (169,169,169), 555, 470, 70, 31),
Wall( (169,169,169), 75, 470, 70, 31),
Wall( (169,169,169), 115, 470, 31, 95),
Wall( (169,169,169), 555, 470, 31, 95),
Wall( (169,169,169), 75, 600, 220, 31),
Wall( (169,169,169), 405, 600, 220, 31),
Wall( (169,169,169), 215, 200, 85, 31),
Wall( (169,169,169), 405, 200, 85, 31),
Wall( (169,169,169), 260, 270, 30, 31),
Wall( (169,169,169), 410, 270, 30, 31),
Wall( (169,169,169), 260, 275, 31, 95),
Wall( (169,169,169), 410, 275, 31, 95),
]
coins = sprite.Group()
coins.add([
Coin( (255,255,0), 130, 309, 5, 5),
Coin( (255,255,0), 240, 309, 5, 5),
Coin( (255,255,0), 340, 250, 5, 5),
Coin( (255,255,0), 460, 309, 5, 5),
Coin( (255,255,0), 570, 309, 5, 5),
Coin( (255,255,0), 240, 180, 5, 5),
Coin( (255,255,0), 460, 180, 5, 5),
Coin( (255,255,0), 310, 111, 5, 5),
Coin( (255,255,0), 390, 111, 5, 5),
Coin( (255,255,0), 60, 180, 5, 5),
Coin( (255,255,0), 640, 180, 5, 5),
Coin( (255,255,0), 60, 50, 5, 5),
Coin( (255,255,0), 640, 50, 5, 5),
Coin( (255,255,0), 160, 409, 5, 5),
Coin( (255,255,0), 240, 380, 5, 5),
Coin( (255,255,0), 340, 380, 5, 5),
Coin( (255,255,0), 460, 380, 5, 5),
Coin( (255,255,0), 530, 409, 5, 5),
Coin( (255,255,0), 460, 450, 5, 5),
Coin( (255,255,0), 240, 450, 5, 5),
Coin( (255,255,0), 390, 450, 5, 5),
Coin( (255,255,0), 310, 450, 5, 5),
Coin( (255,255,0), 630, 450, 5, 5),
Coin( (255,255,0), 50, 450, 5, 5),
Coin( (255,255,0), 600, 520, 5, 5),
Coin( (255,255,0), 90, 520, 5, 5),
Coin( (255,255,0), 530, 570, 5, 5),
Coin( (255,255,0), 160, 570, 5, 5),
Coin( (255,255,0), 60, 640, 5, 5),
Coin( (255,255,0), 640, 640, 5, 5),
Coin( (255,255,0), 350, 640, 5, 5),
])
finish = False
game = True
coins_count = 0
count = 0
speed = 1
clock = time.Clock()
while game:
for e in event.get():
if e.type == QUIT:
exit()
# GHOSTS
ghost_chise.move()
ghost_other.move()
ghost_third.move()
# PACMAN
keyPressed = key.get_pressed()
player.move(keyPressed)
if sprite.spritecollide(player, coins, True):
coins_count += 10
# UPDATE SCREEN
if not finish:
window.fill((0, 0, 0))
for w in walls:
w.draw(window)
coins.draw(window)
player.draw(window)
ghost_chise.draw(window)
ghost_other.draw(window)
ghost_third.draw(window)
display.update()
clock.tick(60)
if finish:
game = False
由於 while 循環,精靈盡可能向下移動。 這確實使速度變得無關緊要,因為它們確實以該速度移動,直到它們不能再移動每一幀。 因此,您應該刪除 while 循環並將其內容直接放在它們所在的 if 語句中。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.