#python #pygame
#python #pygame
Вопрос:
Я создаю игру, в которой игрок перемещается по уровню, цель перемещается случайным образом по уровню, и есть охранники (пока не часть игры). У меня возникли проблемы с реализацией столкновения со стеной, поскольку мои спрайты представляют собой круги, а мои стены — прямоугольники, поэтому я не знаю, как это сделать, стены и спрайты находятся в разных классах и группах.
Я думал об использовании масок для своих спрайтов, но я не уверен, как это сделать. Я также не знаю, как разработать метод для столкновений со стеной, поскольку текущий отправляет моего игрока (у меня он тоже не работает для цели) в нижнюю часть любой стены.
class characters(pygame.sprite.Sprite):
def __init__(self, colour, width, height):
super().__init__()
self.colour = colour
self.width = width
self.height = height
self.image = pygame.Surface([self.width, self.height])
self.image.fill(white)
self.image.set_colorkey(white)
self.rect = self.image.get_rect()
pygame.draw.circle(self.image, self.colour, [int(self.width/2), int(self.height/2)], int(self.width/2))
def moveRight(self, pixels):
self.rect.x = pixels
def moveLeft(self, pixels):
self.rect.x -= pixels
def moveUp(self, pixels):
self.rect.y -= pixels
def moveDown(self, pixels):
self.rect.y = pixels
def moveRandom(self, pixels, clockrate, count, xdirection, ydirection):
self.rect.x = pixels * xdirection
self.rect.y = pixels * ydirection
#print(self.rect.x,self.rect.y)
def wallCollide(self):
x = self.rect.x
for xpos in [-5,5]:
self.rect.x = xpos
if pygame.sprite.spritecollide(self, wallSet, False, pygame.sprite.collide_rect):
self.rect.x -= xpos
else:
self.rect.x = x
y = self.rect.y
for ypos in [-5,5]:
self.rect.y = ypos
if pygame.sprite.spritecollide(self, wallSet, False, pygame.sprite.collide_rect):
self.rect.y -= ypos
else:
self.rect.y = y
Я попытался использовать маску в классе wall ниже, не думаю, что это работает.
class walls(pygame.sprite.Sprite):
def __init__(self, x, y, width, height):
super().__init__()
self.width = width
self.height = height
self.x = x
self.y = y
self.image = pygame.Surface([width,height])
self.image.fill(black)
#self.image.set_colorkey(black) Using this will make the walls invisible as I have textured walls drawn over
self.rect = self.image.get_rect(topleft=(self.x, self.y))
pygame.mask.from_surface(self.image)
Я предоставил только одну стену и уменьшил разрешение, так как это намного проще, пока я пишу свой код. Разрешение должно быть 1920 на 1080. Используйте 600 на 650, чтобы увидеть две стены.
characterSet = pygame.sprite.Group()
player = characters(black, 30, 30)
target = characters(green, 30, 30)
characterSet.add(player, target)
wallSet = pygame.sprite.Group()
Wall1 = walls(288,176, 200,142)
Wall2 = walls(286,427, 201,140)
wallSet.add(Wall1,Wall2)
Основной игровой цикл
while not end:
for event in pygame.event.get():
if event.type == pygame.QUIT:
end = True
keys = pygame.key.get_pressed()
if keys[pygame.K_LEFT]:
player.moveLeft(5)
if keys[pygame.K_RIGHT]:
player.moveRight(5)
if keys[pygame.K_UP]:
player.moveUp(5)
if keys[pygame.K_DOWN]:
player.moveDown(5)
if count%clockrate == 0:
xdirection = random.choice(direction)
ydirection = random.choice(direction)
target.moveRandom(2, clockrate, count, xdirection, ydirection)
count = 1
if pygame.sprite.spritecollide(player, wallSet, False, pygame.sprite.collide_rect):
player.wallCollide()
gameDisplay.blit(level1,[0,0])
wallSet.draw(gameDisplay)
gameDisplay.blit(innerWalls,[0,0])
characterSet.draw(gameDisplay)
Ответ №1:
Если я правильно понимаю, у вас есть список объектов wall и список объектов character, и вы хотите проверить столкновение между ними всеми. это можно быстро выполнить, выполнив цикл по обоим спискам:
for wall in WallSet:
for character in CharacterSet:
character.checkCollision(wall)
checkCollision()
Метод может быть очень простым, проверка того, перекрываются ли прямоугольники вокруг ваших объектов, будет просто несколькими операторами if . Если вы хотите, чтобы этот checkCollisions()
метод хорошо работал для округленных символов, вам нужно написать что-нибудь более причудливое. Я бы предложил:
-
Напишите функцию, которая даст точку внутри прямоугольника, которая ближе всего к другой точке (сложная часть! Хотя я уверен, что есть учебные пособия о том, как это сделать в Интернете)
-
Возьмите эту точку внутри прямоугольника стены и проверьте, достаточно ли она далеко от средней позиции персонажа, чтобы не сталкиваться.
Надеюсь, это поможет! Для будущих вопросов я бы посоветовал попытаться очень четко задать 1 вопрос и сократить код, который вы публикуете дальше. Для вопроса, который вы задаете, объем опубликованного вами кода слишком велик и, вероятно, отвернул потенциальных ответчиков за последние 2 дня.
Комментарии:
1. Спасибо, Хуг, я даже не был уверен, с чего начать с устранения этой проблемы с столкновением, поэтому я разместил часть столкновения внутри игрового цикла и двух классов, что было слишком много. И я продолжал изменять свой вопрос, поскольку я продолжал исправлять его небольшие части, но он все еще не работал, поэтому вопрос оказался очень неоднозначным. Надеюсь, мой следующий вопрос будет намного лучше, еще раз спасибо.