Я пытаюсь изучить основы pygame, создавая простую игру pacman с другом, но у меня возникли проблемы с выяснением того, как делать стены и проверять столкновение с pacman и стеной, а также останавливать движение через стену. (это пакман для 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
это моя попытка проверить столкновение со стеной, но я не знаю, как остановить Пакмана и призрака. столкновение также проверяет только середину круга.
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 и призраком, так как это может быть полезно для того, чтобы делать это со стенами, но я не знаю, как это сделать.
distance = (((pacman.x - ghost.x)**2) + ((pacman.y - ghost.y)**2))**(1/2)
sumrad = pacman.radius + ghost.radius
я посмотрел на несколько похожих вопросов здесь, но я не могу понять, как это работает. Итак, если кто-нибудь может помочь, у меня возникают проблемы с проверкой столкновения между кругом и прямоугольником, а также с предотвращением движения круга/пакмана.
«Я просмотрел здесь несколько похожих вопросов, но я не совсем понимаю, как это работает. Итак, если кто-нибудь может помочь, у меня проблемы с проверкой столкновения между кругом и прямоугольником, а также предотвращение круг/пакман от перехода». Добро пожаловать в Stack Overflow. Прочтите Как спросить и попробуйте задать конкретный вопрос. "У меня проблемы с XYZ" не подходит. Начните с удаления из вашей программы как можно большего количества не проблемы столкновения круга и прямоугольника, которую вы пытаетесь решить; см. минимальный воспроизводимый пример.
Затем узнайте эти вещи и расскажите нам: как вы тестируете получившуюся программу? Когда вы это сделаете, что должно произойти? Что происходит вместо этого, и чем это отличается? Как вы понимаете, почему происходит что-то неправильное? Наконец, используйте вопрос, начинающийся с вопросительного слова, такого как «почему» или «как», и заканчивающийся вопросительным знаком (?), чтобы запросить у нас конкретную информацию, которая вам нужна.
«но я не знаю, как остановить пакмана и призрака». Что ж, попробуй подумать об этом логически. Почему проходит? Потому что это двигаться в этом направлении, верно? Чтобы это исправить, он должен двигаться в направлении другой, верно? (Какое направление имеет физический смысл?) Итак, когда происходит столкновение, что должен знать сдача об объекте? С другой стороны, должно ли это быть останавливаться? Замедлять? что-то другое?






Чтобы проверить, сталкивается ли круг со стеной, вам просто нужно сделать 2 вещи.
Получить расстояние между кругом и стеной
Затем проверьте, меньше ли расстояние или равно расстоянию кругов
Примерно так:
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
Чтобы реализовать это, я бы в вашей игре сначала добавил self.oldX и self.oldY в self.__init__() как в классах pacman, так и в классах призраков. И я бы поставил их на 0 на данный момент.
Затем я бы обновил 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
и это должно работать, спасибо.
Спасибо! Это сработало, но только для одного пункта. Я расширил и сделал, как мне кажется, очень неэффективный способ проверки каждой точки на прямоугольнике/стене, но он работает.
Пожалуйста, обрежьте свой код, чтобы было легче найти вашу проблему. Следуйте этим рекомендациям, чтобы создать минимальный воспроизводимый пример.