子弹不与敌人的Pygame相撞(Python 3)

时间:2017-09-09 06:22:27

标签: python python-3.x pygame

我想制作一个类似的大型游戏,你跳来跳去拍摄东西。但是我发现碰撞有问题,我有一个视频:

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()

player.py

    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

enemy.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

levels.py

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

}

block.py

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

感谢所有帮助表示赞赏。

1 个答案:

答案 0 :(得分:1)

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组中用于碰撞检测的精灵会保留在左侧屏幕边缘时间也是看不见的,因为你不画这个组。

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

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

我通过在self.enemies组中打印一个敌方精灵的矩形来发现错误。然后我检查了这个精灵的update方法,但它看起来是正确的,所以我去了loadLevel的实例化部分并注意到了错误。