Как сделать стену в pygame?

Я пытаюсь изучить основы 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

я посмотрел на несколько похожих вопросов здесь, но я не могу понять, как это работает. Итак, если кто-нибудь может помочь, у меня возникают проблемы с проверкой столкновения между кругом и прямоугольником, а также с предотвращением движения круга/пакмана.

Пожалуйста, обрежьте свой код, чтобы было легче найти вашу проблему. Следуйте этим рекомендациям, чтобы создать минимальный воспроизводимый пример.

another victim of the mouse 12.05.2022 20:52

«Я просмотрел здесь несколько похожих вопросов, но я не совсем понимаю, как это работает. Итак, если кто-нибудь может помочь, у меня проблемы с проверкой столкновения между кругом и прямоугольником, а также предотвращение круг/пакман от перехода». Добро пожаловать в Stack Overflow. Прочтите Как спросить и попробуйте задать конкретный вопрос. "У меня проблемы с XYZ" не подходит. Начните с удаления из вашей программы как можно большего количества не проблемы столкновения круга и прямоугольника, которую вы пытаетесь решить; см. минимальный воспроизводимый пример.

Karl Knechtel 12.05.2022 20:53

Затем узнайте эти вещи и расскажите нам: как вы тестируете получившуюся программу? Когда вы это сделаете, что должно произойти? Что происходит вместо этого, и чем это отличается? Как вы понимаете, почему происходит что-то неправильное? Наконец, используйте вопрос, начинающийся с вопросительного слова, такого как «почему» или «как», и заканчивающийся вопросительным знаком (?), чтобы запросить у нас конкретную информацию, которая вам нужна.

Karl Knechtel 12.05.2022 20:54

«но я не знаю, как остановить пакмана и призрака». Что ж, попробуй подумать об этом логически. Почему проходит? Потому что это двигаться в этом направлении, верно? Чтобы это исправить, он должен двигаться в направлении другой, верно? (Какое направление имеет физический смысл?) Итак, когда происходит столкновение, что должен знать сдача об объекте? С другой стороны, должно ли это быть останавливаться? Замедлять? что-то другое?

Karl Knechtel 12.05.2022 20:57
Почему в Python есть оператор "pass"?
Почему в Python есть оператор "pass"?
Оператор pass в Python - это простая концепция, которую могут быстро освоить даже новички без опыта программирования.
Некоторые методы, о которых вы не знали, что они существуют в Python
Некоторые методы, о которых вы не знали, что они существуют в Python
Python - самый известный и самый простой в изучении язык в наши дни. Имея широкий спектр применения в области машинного обучения, Data Science,...
Основы Python Часть I
Основы Python Часть I
Вы когда-нибудь задумывались, почему в программах на Python вы видите приведенный ниже код?
LeetCode - 1579. Удаление максимального числа ребер для сохранения полной проходимости графа
LeetCode - 1579. Удаление максимального числа ребер для сохранения полной проходимости графа
Алиса и Боб имеют неориентированный граф из n узлов и трех типов ребер:
Оптимизация кода с помощью тернарного оператора Python
Оптимизация кода с помощью тернарного оператора Python
И последнее, что мы хотели бы показать вам, прежде чем двигаться дальше, это
Советы по эффективной веб-разработке с помощью Python
Советы по эффективной веб-разработке с помощью Python
Как веб-разработчик, Python может стать мощным инструментом для создания эффективных и масштабируемых веб-приложений.
1
4
30
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

Ответ принят как подходящий

Чтобы проверить, сталкивается ли круг со стеной, вам просто нужно сделать 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

и это должно работать, спасибо.

Спасибо! Это сработало, но только для одного пункта. Я расширил и сделал, как мне кажется, очень неэффективный способ проверки каждой точки на прямоугольнике/стене, но он работает.

blank blanks 13.05.2022 01:49

Другие вопросы по теме