首页 > 解决方案 > 碰撞评估中的故障状况

问题描述

我真的是一个初学者,我正在寻找一个错误。这是“碰撞”方法中 Game 类中的一个条件。我需要检测导弹与敌人之间的碰撞。问题:当导弹与敌人处于同一坐标时,会检测到碰撞。但是,如果其中一个炮弹在 X 坐标之外,则直到敌人 X 坐标之外的炮弹消失在屏幕顶部边缘之外时才会检测到另一次碰撞。

import pygame
import os
import sys
import random
from pygame.locals import *

pygame.init()
pygame.font.init()
DIR = os.path.dirname(os.path.realpath(__file__)) # získání cesty k adresáři se soubory
OKNO_X = 1024
OKNO_Y = 768
CLOCK = pygame.time.Clock()
SCREEN = pygame.display.set_mode((OKNO_X, OKNO_Y))
BACKGROUND = pygame.image.load(os.path.join(DIR, "universe.jpg"))
DEBUGFONT = pygame.font.SysFont("Comic Sans MS", 20)

class Spaceship():

    def __init__(self, x=510, y=OKNO_Y-50):
        self.x = x
        self.y = y

    def vykresli(self):
        ship = pygame.image.load(os.path.join(DIR, "spaceship.png"))
        SCREEN.blit(ship, (self.x, self.y))
    
    def pohyb(self, x, y):
        self.x += x
        self.y += y
        if self.x < 0: self.x = 0
        if self.x > OKNO_X - 50: self.x = OKNO_X - 54
        if self.y < 0: self.y = 0
        if self.y > OKNO_Y - 50: self.y = OKNO_Y - 54

class Enemies():

    def __init__(self):
        self.enem_x = []
        self.enem_y = []
        self.enem_invader = []
        self.enem_speed = []

    def vygeneruj(self):
        #generování nepřátel
        invader_green = pygame.image.load(os.path.join(DIR, "invader_green.png"))
        invader_blue = pygame.image.load(os.path.join(DIR, "invader_blue.png"))
        invader_yellow = pygame.image.load(os.path.join(DIR, "invader_yellow.png"))
        invader_red = pygame.image.load(os.path.join(DIR, "invader_red.png"))
        if random.randrange(0, 50) == 1:
            #self.enem_x.append(random.randrange(50, 970))
            self.enem_x.append(510)
            self.enem_y.append(0)
            self.enem_invader.append(random.choice([invader_green, invader_blue, invader_yellow, invader_red]))
            self.enem_speed.append(random.randrange(1,5))
            #self.enem_speed.append(10)

    def vykresli(self):
        #vykreslení nepřátel
        for i in range(len(self.enem_invader)):
            SCREEN.blit(self.enem_invader[i], (self.enem_x[i], self.enem_y[i]))
            self.enem_y[i] += self.enem_speed[i]

            ##############DEBUG################x
            label_d1 = DEBUGFONT.render(str(self.enem_x[i]), 1, (255,255,255))
            SCREEN.blit(label_d1, (self.enem_x[i], self.enem_y[i]-10))
            label_d1 = DEBUGFONT.render(str(self.enem_y[i]), 1, (255,255,255))
            SCREEN.blit(label_d1, (self.enem_x[i]+30, self.enem_y[i]-10))

        #smazání nepřátel, co přeletěly za hranu
        e = 0
        pocet_enemies = len(self.enem_invader) 
        while e < pocet_enemies:
            if self.enem_y[e] > OKNO_Y:
                del self.enem_x[e]
                del self.enem_y[e]
                del self.enem_invader[e]
                del self.enem_speed[e]
                pocet_enemies -= 1
            e += 1

class Game():

    def __init__(self):
        self.sestreleno = 0

    def kolize(self):
        #vyhodnocuje střet střely s enemies
        x, y = 0, 0
        pocet_enemies = len(enemies.enem_x)
        pocet_shots = len(shot.x)
        while y < pocet_shots:
            while x < pocet_enemies:
                if (shot.y[y] - 23 > enemies.enem_y[x] and shot.y[y] - 23 < enemies.enem_y[x] + 50) and (shot.x[y] >= enemies.enem_x[x]-50 and shot.x[y] <= enemies.enem_x[x]+50):
                    del shot.x[y]
                    del shot.y[y]
                    del enemies.enem_x[x]
                    del enemies.enem_y[x]
                    del enemies.enem_invader[x]
                    del enemies.enem_speed[x]
                    pocet_enemies -= 1
                    pocet_shots -= 1
                    self.sestreleno += 1
                    break 
                x += 1
            y += 1

    def skore(self):
        myfont_skore = pygame.font.SysFont("Comic Sans MS", 30)
        label_skore = myfont_skore.render("Sestřeleno: " + str(self.sestreleno), 1, (100,100,100))
        SCREEN.blit(label_skore, (10, 10))       

class Shot():

    def __init__(self):
        self.x = []
        self.y = []
        self.missile = pygame.image.load(os.path.join(DIR, "missile.png"))

    def vystrel(self, x, y):
        #přidání střely do seznamu střel
        self.x.append(x)
        self.y.append(y)

    def strela(self):
        #vykreslení střely
        for m in range(len(self.x)):
            SCREEN.blit(self.missile, (self.x[m]+23, self.y[m]-50))
            self.y[m] -= 5

             ##############DEBUG################x
            label_d1 = DEBUGFONT.render(str(self.x[m]), 1, (255,255,255))
            SCREEN.blit(label_d1, (self.x[m], self.y[m]-10))
            label_d1 = DEBUGFONT.render(str(self.y[m]), 1, (255,255,255))
            SCREEN.blit(label_d1, (self.x[m]+30, self.y[m]-10))
            label_d1 = DEBUGFONT.render(str(m), 1, (255,255,255))
            SCREEN.blit(label_d1, (self.x[m]+40, self.y[m]-20))



        
        #smazání střely ze seznamu pokud vletí za hranu screenu
        for s in range(len(self.y)):
            if self.y[s] <= 0:
                del self.x[s]
                del self.y[s]
                break
        #print(self.x)

 
#instance
spaceship = Spaceship()
enemies = Enemies()
shot = Shot()
game = Game()

        
while True:

    SCREEN.blit(BACKGROUND, (0, 0, OKNO_X, OKNO_Y))  # překreslení pozadí

    KEY = pygame.key.get_pressed()
    if KEY[pygame.K_LEFT]:
        spaceship.pohyb(-10, 0)
    if KEY[pygame.K_RIGHT]:
        spaceship.pohyb(+10, 0)
    if KEY[pygame.K_UP]:
        spaceship.pohyb(0, -10)
    if KEY[pygame.K_DOWN]:
        spaceship.pohyb(0, +10)

    if KEY[pygame.K_ESCAPE]:
        pygame.quit()
        sys.exit()

    for event in pygame.event.get():
        if event.type == KEYDOWN:
            if event.key == K_SPACE:
                shot.vystrel(spaceship.x, spaceship.y+30)
        if event.type == KEYUP:
            if event.key == K_p:
                pygame.time.wait(5000)
        if event.type == pygame.QUIT:
            pygame.quit()
            sys.exit()
            
    spaceship.vykresli()
    enemies.vygeneruj()
    enemies.vykresli()
    shot.strela()
    game.kolize()
    game.skore()
    CLOCK.tick(30)  # rychlost FPS
    pygame.display.update()  # obnovení obrazovky

标签: pythonpygame

解决方案


而不是一种方法,

def kolize(self):
    #vyhodnocuje střet střely s enemies
    x, y = 0, 0
    pocet_enemies = len(enemies.enem_x)
    pocet_shots = len(shot.x)
    while y < pocet_shots:
        while x < pocet_enemies:
            if (shot.y[y] - 23 > enemies.enem_y[x] and shot.y[y] - 23 < enemies.enem_y[x] + 50) and (shot.x[y] >= enemies.enem_x[x]-50 and shot.x[y] <= enemies.enem_x[x]+50):
                del shot.x[y]
                del shot.y[y]
                del enemies.enem_x[x]
                del enemies.enem_y[x]
                del enemies.enem_invader[x]
                del enemies.enem_speed[x]
                pocet_enemies -= 1
                pocet_shots -= 1
                self.sestreleno += 1
                break 
            x += 1
        y += 1

我不得不使用这种方法。

    def kolize(self):
    #vyhodnocuje střet střely s invaderem
    myBreak = False
    pocet_enemies = len(enemies.enem_x)
    pocet_shots = len(shot.x)
    for y in range(pocet_shots):
        for x in range(pocet_enemies):
            if (shot.y[y] - 23 > enemies.enem_y[x] and shot.y[y] - 23 < enemies.enem_y[x] + 50) and (shot.x[y]-23 >= enemies.enem_x[x]-50 and shot.x[y] <= enemies.enem_x[x]+27):
                game.explosion(enemies.enem_x[x], enemies.enem_y[x]) # předání souřadnic výbuchu
                game.delShots(y)
                game.delEnem(x)
                pocet_enemies -= 1
                pocet_shots -= 1
                self.sestreleno += 1
                if spaceship.health < 50: spaceship.health += 1
                myBreak = True
                break
        if myBreak == True:
            myBreak = False
            break

我需要有条件地跳出嵌套循环并跳出主循环。


推荐阅读