2017-09-09 6 views
1

Je veux faire un jeu méga homme similaire où vous sautez et tirer des trucs. Mais je l'ai remarqué, il y a quelque chose de mal avec la collision, j'ai une vidéo ci-dessous:Bullet pas entrer en collision avec l'ennemi Pygame (Python 3)

https://youtu.be/p2VCtbBkefo

Je prévois de faire de ce projet open source, donc tout le monde peut le personnaliser. S'il vous plaît ne pas voler ce code, mais vous pouvez utiliser des morceaux de celui-ci pour vous aider avec quelque chose. parce que je ne l'ai pas encore mis sur GitHub publiquement.

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 

Merci toute l'aide est appréciée.

+0

'S'il vous plaît ne pas voler ce code' -> Cela m'a fait sourire. Je veux dire, c'est vraiment génial d'apprendre et d'essayer de s'améliorer, mais ... vous savez, il y a beaucoup de code source libre/open-source pour les jeux là-bas, et je doute que quelqu'un puisse être intéressé par * voler * le sources partielles du prototype d'un jeu ... En tout cas, je pense à votre problème :) –

+0

Ok jambe droite, je vais prendre cela en compte. :) – Smilez

+0

où est la partie de votre code qui gère les collisions? –

Répondre

0

Cette partie de la méthode loadLevel le problème provoque:

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

Vous ajoutez 4 différents à ces groupes d'objets FlyingEnemy et la liste (BTW, la liste est inutile), de sorte que les sprites dans le self.all_sprites groupe et dans le groupe self.enemies ne sont pas les mêmes.

Puisque vous êtes seulement la mise à jour du all_sprites et non le enemies, les sprites du groupe enemies, qui sont utilisés pour la détection de collision, rester au bord gauche de l'écran tout le temps et sont également invisibles, parce que vous n » t dessine ce groupe.

Pour résoudre le problème, créez une instance et ajoutez cette instance aux deux groupes:

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

J'ai trouvé le bug en imprimant le rect d'un sprite ennemi dans le groupe self.enemies. Ensuite, j'ai vérifié la méthode update de cette image-objet, mais il semblait correct, donc je suis allé à la partie d'instanciation dans loadLevel et remarqué l'erreur.

+0

Merci beaucoup skrx, vous m'avez sauvé beaucoup de temps. – Smilez