Я пытаюсь смоделировать базовое столкновение между спрайтом игрока и настенной группой спрайтов.Столкновения между игроком и стеной обнаруживаются с помощью отдельной функции (несколько функций хранятся в отдельной библиотеке: 'game_functions.py', все они отображаются подробно и закомментированы).
Программа проходит через все стены в группе, и, если есть столкновение, проверьте, какая сторона спрайта игрока столкнулась с соответствующей стороной стены.
Во время столкновения программа, кажется, проверяет наличие столкновений на основе всех стен в группе.Я хотел бы знать, как обращаться только к тем стенам, к которым прикасались.
Я пытался назначить метки каждой стене в группе, но проблема остается (и это может быть утомительно, если делать это с большимиколичество стен).
Я все еще новичок в Pygame и на этом сайте, поэтому любая помощь приветствуется!
import pygame
import sys
from pygame.sprite import Sprite, Group
from settings import Settings
import game_functions as gf
# I'M TRYING TO SIMULATE BASIC COLLISIONS BETWEEN PLAYER AND WALL SPRITES
# ALL LARGE COMMENTED BLOCKS REPRESENT CODE FROM "GAME_FUNCTION"S FILE
# IF NEEDED I CAN SHOW THE OTHER FUNCTIONS IN GREATER DETAIL
class Wall(Sprite):
"""Creates basic walls for wall_demo.py"""
def __init__(self, ai_settings, screen,x=0, y=0, width=64, height=64):
super(Wall, self).__init__()
self.ai_settings = ai_settings
self.screen = screen
self.screen_rect = self.screen.get_rect()
# Create rect and set position
self.rect = pygame.Rect(x, y, width, height)
def draw_wall(self):
"""Draw wall to screen"""
pygame.draw.rect(self.screen, self.ai_settings.wall_color, self.rect)
class Player(Sprite):
"""Represents player sprite for wall_demo.py"""
def __init__(self, ai_settings, screen):
super(Player, self).__init__()
self.ai_settings = ai_settings
self.screen = screen
self.screen_rect = self.screen.get_rect()
# Create rect and set position
self.rect = pygame.Rect(0, 0, ai_settings.player_width,
ai_settings.player_height)
self.rect.center = self.screen_rect.center
# Convert rect position to float
self.centerx = float(self.rect.centerx)
self.centery = float(self.rect.centery)
# Set flags for movement and acceleration
self.moving_up = False
self.moving_down = False
self.moving_left = False
self.moving_right = False
self.accelerate = False
self.speedx = self.ai_settings.player_speed
self.speedy = self.ai_settings.player_speed
def update(self):
"""Move player based on movement flags"""
# Set player speed
if self.accelerate:
self.speedx = self.ai_settings.player_accelerate
self.speedy = self.ai_settings.player_accelerate
else:
self.speedx = self.ai_settings.player_speed
self.speedy = self.ai_settings.player_speed
# Move across x and y axis
if self.moving_up and self.rect.top > 0:
self.centery -= self.speedy
if self.moving_down and self.rect.bottom < self.screen_rect.bottom:
self.centery += self.speedy
if self.moving_left and self.rect.left > 0:
self.centerx -= self.speedx
if self.moving_right and self.rect.right < self.screen_rect.right:
self.centerx += self.speedx
# Convert rect back to int
self.rect.centerx = self.centerx
self.rect.centery = self.centery
def draw_player(self):
"""Draw player to screen"""
pygame.draw.rect(self.screen, self.ai_settings.player_color, self.rect)
def main():
pygame.init()
ai_settings = Settings()
screen = pygame.display.set_mode((ai_settings.screen_width,
ai_settings.screen_height))
player = Player(ai_settings, screen)
walls = gf.make_border(ai_settings, screen)
"""
def make_border(ai_settings, screen):
'''Creates a border of walls around screen'''
# Top wall
wall_top = Wall(ai_settings, screen, width=ai_settings.screen_width,
height=16)
# Bottom wall
wall_bottom = Wall(ai_settings, screen, width=ai_settings.screen_width,
height = 16)
wall_bottom.rect.bottom = wall_bottom.screen_rect.bottom
# Left wall
wall_left = Wall(ai_settings, screen, width=16,
height=ai_settings.screen_height)
# Right wall
wall_right = Wall(ai_settings, screen, width=16,
height=ai_settings.screen_height)
wall_right.rect.right = wall_right.screen_rect.right
walls = Group(wall_top, wall_bottom, wall_left, wall_right)
return walls
"""
clock = pygame.time.Clock()
while True:
clock.tick(60)
gf.check_events(player)
"""
def check_events(player)
for event in pygame.event.get():
if event.type == pygame.QUIT:
sys.exit()
elif event.type == pygame.KEYDOWN:
if event.key == pygame.K_ESCAPE:
sys.exit()
elif event.key == pygame.K_LSHIFT:
player.accelerate = True
elif event.key == pygame.K_UP:
player.moving_up = True
elif event.key == pygame.K_DOWN:
player.moving_down = True
elif event.key == pygame.K_LEFT:
player.moving_left = True
elif event.key == pygame.K_RIGHT:
player.moving_right = True
elif event.type == pygame.KEYUP:
if event.key == pygame.K_UP:
player.moving_up = False
elif event.key == pygame.K_LSHIFT:
player.accelerate = False
elif event.key == pygame.K_DOWN:
player.moving_down = False
elif event.key == pygame.K_LEFT:
player.moving_left = False
elif event.key == pygame.K_RIGHT:
player.moving_right = False
"""
gf.player_wall_collide(player, walls)
"""
def player_wall_collide(player, walls):
''' Respond to collisions between
player and walls'''
for wall in walls:
if pygame.sprite.spritecollide(player, walls, False):
print("HIT")
if player.rect.top <= wall.rect.bottom:
player.rect.top = wall.rect.bottom
if player.rect.bottom >= wall.rect.top:
player.rect.bottom = wall.rect.top
if player.rect.left <= wall.rect.right:
player.rect.left = wall.rect.right
if player.rect.right >= wall.rect.left:
player.rect.right = wall.rect.left
"""
player.update()
gf.update_screen(ai_settings, screen, player, walls)
main()