我想制作一个类似《超人》的游戏,让您跳来跳去射击。但是我注意到碰撞出了点问题,下面有一个视频:

https://youtu.be/p2VCtbBkefo

我打算使该项目开源,因此任何人都可以对其进行自定义。请不要窃取此代码,但是您可以使用其中的大部分代码来帮助您。因为我还没有公开发布到GitHub上。

main.py:

import pygame as pg
from player import *
from settings import *
from levels import *
from block import *
from enemy import *

class Game:
    def __init__(self):
        pg.init()
        pg.mixer.init()
        self.screen = pg.display.set_mode((width, height))
        pg.display.set_caption("wait until realesed.")
        self.clock = pg.time.Clock()
        self.enemiesList = []
        self.running = True
        self.shootRight = True

    def loadLevel(self, level, enemies, group, group2, group3):

        for y in range(0, len(level)):
            for x in range(0, len(level[y])):
                if (level[y][x] == 1):
                    blockList.append(Block(x*32, y*32))
                    group.add(Block(x*32, y*32))
                    group2.add(Block(x*32, y*32))

        for amount in range(0, enemies):
            group2.add(FlyingEnemy(self))
            group3.add(FlyingEnemy(self))
            self.enemies.add(FlyingEnemy(self))
            self.enemiesList.append(FlyingEnemy(self))

    def new(self):

        self.platforms = pg.sprite.Group()
        self.all_sprites = pg.sprite.Group()
        self.enemies = pg.sprite.Group()
        self.bullets = pg.sprite.Group()

        self.player = Player()
        self.loadLevel(level1["platform"], level1["enemies"], self.platforms, self.all_sprites, self.enemies)
        self.all_sprites.add(self.player)
        self.run()

    def shoot(self):
        if self.shootRight:
            self.bullet = Bullet(self.player.rect.centerx, self.player.rect.centery)
            self.bullet.speed = 10
            self.all_sprites.add(self.bullet)
            self.bullets.add(self.bullet)
            print(self.bullet)
        elif self.shootRight == False:
            self.bullet = Bullet(self.player.rect.centerx, self.player.rect.centery)
            self.bullet.speed = -10
            self.all_sprites.add(self.bullet)
            self.bullets.add(self.bullet)
            print(self.bullet)


    def run(self):

        self.playing = True
        while self.playing:
            self.clock.tick(FPS)
            self.events()
            self.update()
            self.draw()

    def update(self):
        self.all_sprites.update()

        self.enemy_hits = pg.sprite.spritecollide(self.player, self.enemies, False)

        #print(enemy_hits)
        if self.enemy_hits:
            pass
            #print("hit")
        self.bullet_hits = pg.sprite.groupcollide(self.enemies, self.bullets, True, True)

        if self.bullet_hits:
            print(self.bullet_hits)
            pygame.quit()





        hits = pg.sprite.spritecollide(self.player, self.platforms, False)

        if hits:
            self.player.pos.y = hits[0].rect.top + 1
            self.player.vel.y = 0

    def events(self):
        for event in pg.event.get():
            if event.type == pg.QUIT:
                if self.playing:
                    self.playing = False
                    self.running = false
            if event.type == pg.KEYDOWN:
                if event.key == pg.K_UP:
                    self.player.jump()
                if event.key == pg.K_SPACE:
                    self.shoot()
                if event.key == pg.K_RIGHT:
                    self.shootRight = True
                if event.key == pg.K_LEFT:
                    self.shootRight = False



    def draw(self):
        self.screen.fill((255, 255, 255))
        self.all_sprites.draw(self.screen)
        pg.display.flip()

    def show_start_screen(self):
        pass
    def show_go_screen(self):
        pass

g = Game()
g.show_start_screen()
while g.running:
    g.new()
    g.show_go_screen()

pg.quit()


"""width = 800
height = 600
FPS = 60

pg.init()
pg.mixer.init()
screen = pg.display.set_mode((width, height))
pg.display.set_caption("doom room")
clock = pg.time.Clock()


running = True

while running:
    for event in pg.event.get():
        clock.tick(FPS)
        if event.type == pg.QUIT:
            running = false

    screen.fill((255, 255, 255))
    pg.display.flip()

pg.quit()"""


    import pygame

class Bullet(pygame.sprite.Sprite):
    def __init__(self, x, y):
        pygame.sprite.Sprite.__init__(self)
        self.image  = pygame.Surface((20, 10))
        self.image.fill((240, 43, 12))
        self.rect = self.image.get_rect()
        self.rect.bottom = y
        self.rect.centerx = x
        self.speed = -10

    def update(self):
        self.rect.x += self.speed

        if self.rect.bottom < 0:
            self.kill()


玩家

    import pygame as pg
from settings import *
from laser import *
vec = pg.math.Vector2

class Player(pg.sprite.Sprite):
    def __init__(self):
        pg.sprite.Sprite.__init__(self)
        self.image = pg.Surface((40, 40))
        self.image.fill((80, 123, 255))
        self.rect = self.image.get_rect()
        self.rect.center = (width / 2, height / 2)
        self.pos = vec(width / 2, height / 2)
        self.vel = vec(0, 0)
        self.acc = vec(0, 0)
        #self.vx = 0
        #self.vy = 0

    def jump(self):
        self.vel.y = -15



    def update(self):

        self.acc = vec(0, player_gravity)
        keys = pg.key.get_pressed()
        if keys[pg.K_LEFT]:
            self.acc.x = -player_acc
        if keys[pg.K_RIGHT]:
            self.acc.x = player_acc

        self.acc.x += self.vel.x * player_friction
        self.vel += self.acc
        self.pos += self.vel + 0.5 * self.acc

        if self.pos.x > width:
            self.pos.x = 0
        if self.pos.x < 0:
            self.pos.x = width
        if self.pos.y <= 0:
            self.pos.y += 15

        self.rect.midbottom = self.pos


py.py

    import pygame as pg
from random import *
from settings import *
class FlyingEnemy(pg.sprite.Sprite):
    def __init__(self, game):
        pg.sprite.Sprite.__init__(self)
        self.game = game
        self.image = pg.Surface((45, 45))
        self.image.fill((20, 203, 50))
        self.rect = self.image.get_rect()
        self.rect.centerx = choice([-100, width + 100])
        self.vx = randrange(4, 7)
        if self.rect.centerx > width:
            self.vx *= -1
        self.rect.y = height / 4
        self.rect.x = 0
        self.vy = 0
        self.dy = 0.5



    def update(self):
        if self.rect.x > width:
            self.rect.x = 0
        if self.rect.x < 0:
            self.rect.x = width

        self.rect.x += self.vx
        self.vy += self.dy
        if self.vy > 3 or self.vy < -3:
            self.dy *= -1
        center = self.rect.center
        if self.dy < 0:
            pass
            #print("bobbed up")
        else:
            pass
            #print("bobbed down")


settings.py

import pygame

blockList = []


player_acc = 1.0
player_friction = -0.12
player_gravity = 0.5

bullets = pygame.sprite.Group()

true = True
false = False
width = 800
height = 600
FPS = 60


等级

level1 = {

"platform": [
    [0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0],
    [0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0],
    [0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0],
    [0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0],
    [0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0],
    [0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0],
    [0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0],
    [0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0],
    [0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0],
    [0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1],
    [1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0],
    [0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0],
    [0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0],
    [0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0],
    [0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0],
    [0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0],
    [0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0],
    [0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,1,0,0,0,0,0,0,0,0,0],
    [1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1],

],
"enemies": 5

}




import pygame as pg

class Block(pg.sprite.Sprite):
    def __init__(self, x, y):
        pg.sprite.Sprite.__init__(self)
        self.image = pg.Surface((32, 32))
        self.image.fill((0, 0, 0))
        self.rect = self.image.get_rect()
        self.rect.x = x
        self.rect.y = y


谢谢所有帮助。

最佳答案

loadLevel方法的这一部分导致问题:

for amount in range(0, enemies):
    group2.add(FlyingEnemy(self))
    group3.add(FlyingEnemy(self))
    self.enemies.add(FlyingEnemy(self))
    self.enemiesList.append(FlyingEnemy(self))


您要向这些组和列表中添加4个不同的FlyingEnemy对象(顺便说一句,该列表无用),因此self.all_sprites组和self.enemies组中的精灵不相同。

由于仅更新all_sprites而不是enemies,用于冲突检测的enemies组中的sprite始终保持在屏幕的左边缘,并且也不可见,因为不要画这个组。

要解决该问题,请创建一个实例并将该实例添加到两组中:

for amount in range(0, enemies):
    enemy = FlyingEnemy(self)
    self.enemies.add(enemy)
    self.all_sprites.add(enemy)




我通过在self.enemies组中打印一个敌方精灵的矩形找到了该错误。然后,我检查了此精灵的update方法,但看起来正确,因此我进入了loadLevel的实例化部分,并注意到了错误。

关于python - 子弹未与敌方Pygame碰撞(Python 3),我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/46127776/

10-09 19:10