如何在 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
那应该可以,谢谢。
我正在尝试通过与朋友制作一个简单的吃豆人游戏来学习 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
那应该可以,谢谢。