我真的是一个初学者,我正在寻找一个错误。 这是 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
答案 0 :(得分: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 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
我需要有条件地跳出嵌套循环和主循环。