多个sprite碰撞检测

2024-05-26 21:53:16 发布

您现在位置:Python中文网/ 问答频道 /正文

好的,所以我一直在想如何设置它,但无法使它正常工作。如果您熟悉游戏Frogger,我正在尝试获得类似于游戏中移动日志的功能。到目前为止,我只对一个pygame.sprite.Group()进行了碰撞检测

import pygame
import os
import random

os.environ['SDL_VIDEO_CENTERED'] = '1'

WIDTH = 480
HEIGHT = 720
FPS = 60

# Moving Object spacing setup first row 
INSTANCE_COUNT = 0
BOX_WIDTH = 30
SPACING = 120

# object speed
pos_objspeed = 1
neg_objspeed = -1

BLACK = (0, 0, 0)
RED = (255, 0, 0)
GREEN = (0, 255, 0)

pygame.init()
pygame.mixer.init()
screen = pygame.display.set_mode((WIDTH, HEIGHT))
clock = pygame.time.Clock()

class Player(pygame.sprite.Sprite):
    def __init__(self):
        pygame.sprite.Sprite.__init__(self)
        self.image = pygame.Surface((30, 30))
        self.image.fill(GREEN)
        self.rect = self.image.get_rect()
        self.rect.centerx = WIDTH / 2
        self.rect.bottom = HEIGHT - 96
        self.speedx = 0
        self.speedy = 0

class MovingObj_Test(pygame.sprite.Sprite):
    def __init__(self):
        pygame.sprite.Sprite.__init__(self)
        self.image = pygame.Surface((90, 30))
        self.image.fill(RED)
        self.rect = self.image.get_rect()
        self.rect.x = (INSTANCE_COUNT * (SPACING+ BOX_WIDTH))
        #self.rect.x = random.randrange(WIDTH)
        self.rect.bottom = 384
        self.speedx = pos_objspeed

    def update(self):
        self.rect.x += self.speedx
        if self.rect.x >= 480:
            self.rect.x = -30
            self.rect.bottom = 384
            self.speedx = pos_objspeed        

class MovingObj_TestTwo(pygame.sprite.Sprite):
    def __init__(self):
        pygame.sprite.Sprite.__init__(self)
        self.image = pygame.Surface((90, 30))
        self.image.fill(RED)
        self.rect = self.image.get_rect()
        self.rect.x = (INSTANCE_COUNT * (SPACING+ BOX_WIDTH))
        #self.rect.x = random.randrange(WIDTH)
        self.rect.bottom = 336
        self.speedx = neg_objspeed

    def update(self):
        self.rect.x += self.speedx
        if self.rect.x >= 480:
            self.rect.x = -30
            self.rect.bottom = 336
            self.speedx = neg_objspeed

all_sprites = pygame.sprite.Group()
movingobj_l = pygame.sprite.Group()
movingobj_r = pygame.sprite.Group()

for i in range (3):
    INSTANCE_COUNT = i + 1
    obj1 = MovingObj_Test()
    all_sprites.add(obj1)
    movingobj_l.add(obj1)

for i in range (3):
    INSTANCE_COUNT = i + 1
    obj2 = MovingObj_TestTwo()
    all_sprites.add(obj2)
    movingobj_r.add(obj2)

player = Player()
all_sprites.add(player)

running = True
onLogLeft = False
onLogRight = False
groundSpd = 48
while running:

    clock.tick(FPS)

    hitsleft = pygame.sprite.spritecollide(player, movingobj_l, False, pygame.sprite.collide_rect)
    for hit in hitsleft:
        player.speedx = pos_objspeed
        player.speedy = 0
        onLogLeft = True
    if len(hitsleft) == 0:
        onLogLeft = False
        player.speedx = 0
        player.speedy = 0
    hitsright = pygame.sprite.spritecollide(player, movingobj_r, False, pygame.sprite.collide_rect)
    for hit in hitsright:
        player.speedx = neg_objspeed
        player.speedy = 0
        onLogRight = True
    if len(hitsright) == 0:
        onLogRight = False
        player.speedx = 0
        player.speedy = 0


    for event in pygame.event.get():
        if event.type == pygame.KEYDOWN:
            if event.key == pygame.K_LEFT:
                player.speedx = -groundSpd
            if event.key == pygame.K_RIGHT:
                player.speedx = groundSpd
            if event.key == pygame.K_UP:
                player.speedy = -groundSpd
            if event.key == pygame.K_DOWN:
                player.speedy = groundSpd

        if event.type == pygame.KEYUP and onLogLeft == False and onLogRight == False:
            if event.key == pygame.K_LEFT:
                player.speedx = 0
            if event.key == pygame.K_RIGHT:
                player.speedx = 0
            if event.key == pygame.K_UP:
                player.speedy = 0
            if event.key == pygame.K_DOWN:
                player.speedy = 0

    if onLogLeft == False and onLogRight == False and player.rect.bottom <= 384:
        running = False

    player.rect.x += player.speedx
    player.rect.y += player.speedy

    if event.type == pygame.QUIT:
        running = False



    #player.rect.x += player.speedx
    #player.rect.y += player.speedy

    all_sprites.update()
    screen.fill(BLACK)
    all_sprites.draw(screen)
    pygame.display.flip()



pygame.quit()
quit()

好的,在我的代码中

hitsright = pygame.sprite.spritecollide(player, movingobj_r, False, pygame.sprite.collide_rect)

检查碰撞并更新玩家的速度,我期待它如何,但是

hitsleft = pygame.sprite.spritecollide(player, movingobj_l, False, pygame.sprite.collide_rect)

他没有这样做

如果有人有任何想法,我不明白为什么会这样。还有,我怎样才能使它同时适用于这两种情况


Tags: rectimageselfeventfalseifinitwidth
1条回答
网友
1楼 · 发布于 2024-05-26 21:53:16

左侧和右侧的代码行为不同,因为如果检测到与hitsleft的冲突,则设置player.speedx

for hit in hitsleft:
   player.speedx = pos_objspeed

但如果与hitsleft发生冲突,则不会立即重置与hitsrightplayer.speedx的冲突:

if len(hitsright) == 0:
   onLogRight = False
   player.speedx = 0

必须根据这两个条件设置player.speedx(例如,在if-elif-else语句中):

while running:
    # [...]

    hitsleft = pygame.sprite.spritecollide(player, movingobj_l, False, pygame.sprite.collide_rect)
    onLogLeft = any(hitsleft)

    hitsright = pygame.sprite.spritecollide(player, movingobj_r, False, pygame.sprite.collide_rect)
    onLogRight = any(hitsright)

    player.speedy = 0
    if onLogLeft:
        player.speedx = pos_objspeed
    elif onLogRight:
        player.speedx = neg_objspeed
    else:
        player.speedx = 0

相关问题 更多 >

    热门问题