我正在尝试模拟玩家精灵和墙精灵组之间的基本碰撞。使用单独的功能检测玩家与墙的碰撞(几个功能存储在单独的库“ 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()