如何在 pygame 中建造一堵墙?

How do I make a wall in pygame?

我正在尝试通过与朋友制作一个简单的吃豆人游戏来学习 pygame 的基础知识,但我一直无法弄清楚如何制作墙壁并检查与吃豆人和墙壁的碰撞,并通过墙壁停止运动。 (这是一个 2 人吃豆人,幽灵是方向键,吃豆人是 wasd)

这是main.py

import pygame
import random
import time
from Pacman import pacman
from Ghost import ghost

#colors
Yellow = (255,255,0)
Blackish_Blue = (20,0,70)
Red = (255,0,0)
P_B = (40,60,100)



clock = pygame.time.Clock()



#display
pygame.init()
pygame.display.set_caption('  Scuffed Pacman')
width, height = 640, 480
screen = pygame.display.set_mode((width, height))

pacman = pacman(screen)
ghost = ghost(screen)


font = pygame.font.Font('freesansbold.ttf', 32)
text = font.render('Game Over', True, Yellow)
textRect = text.get_rect()
textRect.center = (width / 2, height / 2)

run = True
while run == True:
  pygame.time.delay(10)
  clock.tick(60)
  screen.fill(Blackish_Blue)

  for event in pygame.event.get():
    if event.type == pygame.QUIT:
      run = False

  

  
  
  
  color = (182,163,192)
  #attempt to make wall and check collision
  ghostspawn = pygame.Rect(0,0,60,40)
  ghostspawn.center = (width / 2, (height / 2)-50)
  pygame.draw.rect(screen, color, ghostspawn)
  if ghostspawn.collidepoint(pacman.x, pacman.y):
    print("collision detected")
  
  
  pacman.draw(screen)
  ghost.draw(screen)
  ghost.update()
  pacman.update()


  distance = (((pacman.x - ghost.x)**2) + ((pacman.y - ghost.y)**2))**(1/2)
  sumrad = pacman.radius + ghost.radius

  if distance < sumrad:
    while True:
      screen.fill(P_B)
      screen.blit(text, textRect)
      for event in pygame.event.get():
        if event.type == pygame.QUIT:
            pygame.quit()
            quit()
        pygame.display.update()
  
  pygame.display.update()

pygame.quit()

这是 pacman 的代码:

import pygame

Yellow = (255,255,0)
class pacman(pygame.sprite.Sprite):
  def __init__(self, mainscreen):
    super().__init__()
    self.x = 320
    self.y = 240
    self.radius = 15
    self.velocity = 2
    self.origin = (self.x, self.y)
  
  def draw(self, mainscreen):
    pygame.draw.circle(mainscreen, Yellow, (self.x, self.y), self.radius)
  
  
  def update(self):
    self.movement()
    self.origin = (self.x, self.y)
    
  def movement(self):
    keys = pygame.key.get_pressed()

    if keys[pygame.K_d] and self.velocity > 0 and self.x < 625:
        self.x += self.velocity
    if keys[pygame.K_a] and self.velocity > 0 and self.x > 15:
      self.x -= self.velocity
    if keys[pygame.K_w] and self.velocity > 0 and self.y > 15:
      self.y -= self.velocity
    if keys[pygame.K_s] and self.velocity > 0 and self.y < 465:
      self.y += self.velocity

这是幽灵的代码:

import pygame
Red = (255,0,0)
class ghost(pygame.sprite.Sprite):
  def __init__(self, mainscreen):
    super().__init__()
    self.x = 213
    self.y = 240
    self.radius = 15
    self.velocity = 2
    self.origin = (self.x, self.y)
  
  def draw(self, mainscreen):
    pygame.draw.circle(mainscreen, Red, (self.x, self.y), self.radius)
  
  
  def update(self):
    self.movement()
    self.origin = (self.x, self.y)
    
  def movement(self):
    keys = pygame.key.get_pressed()
    if keys[pygame.K_RIGHT] and self.velocity > 0 and self.x < 625:
      self.x += self.velocity
    if keys[pygame.K_LEFT] and self.velocity > 0 and self.x > 15:
      self.x -= self.velocity
    if keys[pygame.K_UP] and self.velocity > 0 and self.y > 15:
      self.y -= self.velocity
    if keys[pygame.K_DOWN] and self.velocity > 0 and self.y < 465:
      self.y += self.velocity

这是我检查墙壁碰撞的尝试,但我不知道如何阻止 pacman 和幽灵通过。碰撞也只检查圆的中间。

ghostspawn = pygame.Rect(0,0,60,40)
ghostspawn.center = (width / 2, (height / 2)-50)
pygame.draw.rect(screen, color, ghostspawn)
if ghostspawn.collidepoint(pacman.x, pacman.y):
  print("allowed")

这是我如何检测 pacman 和 ghost 之间的碰撞,因为它可能对墙壁有帮助,但我不知道如何。

distance = (((pacman.x - ghost.x)**2) + ((pacman.y - ghost.y)**2))**(1/2)
sumrad = pacman.radius + ghost.radius

我在这里看过几个类似的问题,但我不太明白它是如何工作的。 所以,如果有人能提供帮助,我在检查圆形和矩形之间的碰撞以及阻止 circle/pacman 移动时遇到了麻烦。

要检查圆是否与墙碰撞,您只需要做两件事

获取圆与墙的距离

然后检查距离是否小于或等于圆距离

差不多是这样的:

distance = abs(circle.x - wall.x) + abs(circle.y - wall.y)
if distance <= circle.radius: # abs() Makes the value in the brackets positive
    circle.x = oldX
    circle.y = oldY

为了在你的游戏中实现这一点,我首先会在 pacman 和 ghost 类 的 self.__init__() 中添加一个 self.oldX 和一个 self.oldY。我暂时将它们设置为 0。

然后我会在移动对象之前更新 movement 函数中的 oldX 和 oldY,如下所示:

def movement(self):
    keys = pygame.key.get_pressed()
    self.oldX = self.x
    self.oldY = self.y

    if keys[pygame.K_d] and self.velocity > 0 and self.x < 625:
        self.x += self.velocity
    if keys[pygame.K_a] and self.velocity > 0 and self.x > 15:
        self.x -= self.velocity
    if keys[pygame.K_w] and self.velocity > 0 and self.y > 15:
        self.y -= self.velocity
    if keys[pygame.K_s] and self.velocity > 0 and self.y < 465:
        self.y += self.velocity

然后我会得到一个包含游戏中每一面墙的列表和一个包含游戏中所有鬼魂的列表(如果你想拥有多个鬼魂)。

然后我会进入主循环(你有的 while 循环)我会添加这个 在调用幽灵和吃豆人的移动函数之后:

for wall in walls:
    distance = abs(pacman.x - wall.x) + abs(pacman.y - wall.y)
       if distance <= pacman.radius:
           pacman.x = pacman.oldX
           pacman.y = pacman.oldY

    for ghost in ghosts:
        distance = abs(ghost.x - wall.x) + abs(ghost.y - wall.y)
           if distance <= ghost.radius:
               ghost.x = ghost.oldX
               ghost.y = ghost.oldY

那应该可以,谢谢。