我需要帮助。我是编码新手,所以我用 pygame 开发了一个游戏。 这是一款你作为机器人对抗僵尸的游戏。如果火球与僵尸相撞,心脏图片会从填充更新为一半,依此类推。
Tech-Lead 说这段代码效率不高,因为 Enemy 类的 defhearts() 方法中有很多 if 语句。
你能帮我缩短一下吗?我完全不知道我能做什么。想到了循环,但不知道怎么做。请帮助我
这是我的代码:
#pygame importieren
import pygame
#pygame initialisieren
pygame.init()
#Konstante für die Farben initialisieren
WHITE = [0xFF, 0xFF, 0xFF]
ORANGE = [0xFF, 0x8C, 0x00]
RED = [0xFF, 0x00, 0x00]
GREEN = [0x00, 0xFF, 0x00]
BLUE = [0x00, 0x00, 0xFF]
BLACK = [0x00, 0x00, 0x00]
#Hintergrundbilder und Sounds einer Variablen zuweisen
background = pygame.image.load("Grafiken/hintergrund.jpg")
attackLeft = pygame.image.load("Grafiken/angriffLinks.png")
attackRight = pygame.image.load("Grafiken/angriffRechts.png")
jumping = pygame.image.load("Grafiken/sprung.png")
going_right = [pygame.image.load("Grafiken/rechts1.png"), pygame.image.load("Grafiken/rechts2.png"), pygame.image.load("Grafiken/rechts3.png"), pygame.image.load("Grafiken/rechts4.png"), pygame.image.load("Grafiken/rechts5.png"), pygame.image.load("Grafiken/rechts6.png"), pygame.image.load("Grafiken/rechts7.png"), pygame.image.load("Grafiken/rechts8.png")]
going_left = [pygame.image.load("Grafiken/links1.png"), pygame.image.load("Grafiken/links2.png"), pygame.image.load("Grafiken/links3.png"), pygame.image.load("Grafiken/links4.png"), pygame.image.load("Grafiken/links5.png"), pygame.image.load("Grafiken/links6.png"), pygame.image.load("Grafiken/links7.png"), pygame.image.load("Grafiken/links8.png")]
jumping_sound = pygame.mixer.Sound("Sound/sprung.wav")
shooting_sound = pygame.mixer.Sound("Sound/shoot.mp3")
#Fenster erstellen
screen = pygame.display.set_mode([1280, 800])
#Fenstertitel erstellen
pygame.display.set_caption("Mein erstes pygame-Spiel")
#Spielerklasse
class Spieler:
def __init__(self, x, y, speed, jump, player_width, player_height, direction, steps_left, steps_right):
self.x = x
self.y = y
self.speed = speed
self.jump = jump
self.player_width = player_width
self.player_height = player_height
self.direction = direction
self.steps_left = steps_left
self.steps_right = steps_right
#Springt er?
self.sprung = False
#Anfangsposition des Spielers
self.lastPosition = [1, 0]
#Schießbereitschaft
self.ready2shoot = True
#Eine Methode zum nach links und nach rechts laufen
def walking(self, liste):
if liste[0]:
#Index 0 des Arrays direction ist Links. Wenn nach Links, dann Position des Spielers auf x - Geschwindigkeit
self.x -= self.speed
self.direction = [1, 0, 0, 0]
self.steps_left += 1
if liste[1]:
#Index 1 des Arrays direction ist Rechts. Wenn nach Rechts, dann Position des Spielers auf x + Geschwindigkeit
self.x += self.speed
self.direction = [0, 1, 0, 0]
self.steps_right += 1
#Schritte werden zurückgesetzt
def resetsteps(self):
self.steps_left = 0
self.steps_right = 0
#Index 3 des Arrays direction ist stehen. Wenn stehen, dann werden die Schritte zurückgesetzt
def standing(self):
self.direction = [0, 0, 1, 0]
self.resetsteps()
#Sprungmethode wenn die springen-Taste gedrückt wird
def sprungsetzen(self):
#Wenn der SPieler -16px springen will, ist die Sprungbereitschaft True.
if self.jump == -16:
self.sprung = True
self.jump = 15
pygame.mixer.Sound.play(jumping_sound)
#Berechnung des Sprunges
def springen(self):
if self.sprung:
self.direction = [0, 0, 0, 1]
if self.jump >= -15:
n = 1
if self.jump < 0:
n = - 1
self.y -= (self.jump**2)*0.15*n
self.jump -= 1
else:
self.sprung = False
#Die Erstellung des Spielers
def spZeichnen(self):
if self.steps_left == 63:
self.steps_left = 0
if self.steps_right == 63:
self.steps_right = 0
if self.direction[0]:
screen.blit(going_left[self.steps_left//8], (self.x, self.y))
self.lastPosition = [1, 0]
if self.direction[1]:
screen.blit(going_right[self.steps_right//8], (self.x, self.y))
self.lastPosition = [0, 1]
if self.direction[2]:
if self.lastPosition[0]:
screen.blit(attackLeft, (self.x, self.y))
else:
screen.blit(attackRight, (self.x, self.y))
if self.direction[3]:
screen.blit(jumping, (self.x, self.y))
class Enemy:
def __init__(self, x, y, speed, player_width, player_height, direction, xMin, xMax):
self.x = x
self.y = y
self.speed = speed
self.player_width = player_width
self.player_height = player_height
self.direction = direction
self.xMin = xMin
self.xMax = xMax
self.steps_left = 0
self.steps_right = 0
self.health = 12
self.left_walk = [pygame.image.load("Grafiken/l1.png"), pygame.image.load("Grafiken/l2.png"), pygame.image.load("Grafiken/l3.png"), pygame.image.load("Grafiken/l4.png"), pygame.image.load("Grafiken/l5.png"),
pygame.image.load("Grafiken/l6.png"), pygame.image.load("Grafiken/l7.png"), pygame.image.load("Grafiken/l8.png")]
self.right_walk = [pygame.image.load("Grafiken/r1.png"), pygame.image.load("Grafiken/r2.png"), pygame.image.load("Grafiken/r3.png"), pygame.image.load("Grafiken/r4.png"), pygame.image.load("Grafiken/r5.png"),
pygame.image.load("Grafiken/r6.png"), pygame.image.load("Grafiken/r7.png"), pygame.image.load("Grafiken/r8.png")]
self.health_full = pygame.image.load("Grafiken/voll.png")
self.health_half = pygame.image.load("Grafiken/halb.png")
self.health_zero = pygame.image.load("Grafiken/leer.png")
def hearts(self):
if self.health >= 2:
screen.blit(self.health_full, (440, 75))
if self.health >= 4:
screen.blit(self.health_full, (500, 75))
if self.health >= 6:
screen.blit(self.health_full, (560, 75))
if self.health >= 8:
screen.blit(self.health_full, (620, 75))
if self.health >= 10:
screen.blit(self.health_full, (680, 75))
if self.health == 12:
screen.blit(self.health_full, (740, 75))
if self.health == 1:
screen.blit(self.health_half, (440, 75))
if self.health == 3:
screen.blit(self.health_half, (500, 75))
if self.health == 5:
screen.blit(self.health_half, (560, 75))
if self.health == 7:
screen.blit(self.health_half, (620, 75))
if self.health == 9:
screen.blit(self.health_half, (680, 75))
if self.health == 11:
screen.blit(self.health_half, (740, 75))
if self.health == 0:
screen.blit(self.health_zero, (440, 75))
if self.health <= 2:
screen.blit(self.health_zero, (500, 75))
if self.health <= 4:
screen.blit(self.health_zero, (560, 75))
if self.health <= 6:
screen.blit(self.health_zero, (680, 75))
if self.health <= 8:
screen.blit(self.health_zero, (680, 75))
if self.health <= 10:
screen.blit(self.health_zero, (740, 75))
def enemy_zeichnen(self):
if self.steps_left == 63:
self.steps_left = 0
if self.steps_right == 63:
self.steps_right = 0
if self.direction[0]:
screen.blit(self.left_walk[self.steps_left//8], (self.x, self.y))
if self.direction[1]:
screen.blit(self.right_walk[self.steps_right//8], (self.x, self.y))
def enemy_walking(self):
self.x += self.speed
if self.speed < 0:
self.direction = [1, 0]
self.steps_left += 1
if self.speed > 0:
self.direction = [0, 1]
self.steps_right += 1
def enemy_back_forth(self):
if self.x > self.xMax:
self.speed *= -1
elif self.x < self.xMin:
self.speed *= -1
self.enemy_walking()
class FireBall:
def __init__(self, spX, spY, fb_Direction, fb_radius, fb_color, speed):
#Der Feuerball befindet sich auf der selben Position wie der Spieler
self.x = spX
self.y = spY
#Feuerballrichtung nach Links, befindet sich immer 5px vom Spieler entfernt und bewegt sich *1,5 des speeds in - y-Richtung (-1 * speed)
if fb_Direction[0]:
self.x += 5
self.speed = - 1 * speed * 1.5
#Feuerballrichtung nach Rechts, befindet sich immer 90px vom Spieler entfernt und bewegt sich * 1,5 des speeds in y-Richtung
elif fb_Direction[1]:
self.x += 90
self.speed = speed * 1.5
#Feuerball ist 90px unter dem Spieler
self.y += 90
self.fb_radius = fb_radius
self.fb_color = fb_color
#Bewegung des Feuerballs
def move(self):
self.x += self.speed
#Zeichnung des Feuerballs
def fb_Zeichnen(self):
pygame.draw.circle(screen, self.fb_color, (self.x, self.y), self.fb_radius, 0)
#Methode um Zeichnungen anzuzeigen
def show_player():
screen.blit(background, (0,0))
for f in fireball:
f.fb_Zeichnen()
spieler1.spZeichnen()
zombie.hearts()
zombie.enemy_zeichnen()
zombie.hearts()
pygame.display.flip()
#Verhalten vom Feuerball
def feuerkugeln():
for f in fireball:
if f.x >= 0 and f.x <= 1270:
f.move()
else:
fireball.remove(f)
def collision():
global fireball, win, loose, game_active
zombieRect = pygame.Rect(spieler1.x+18,spieler1.y+36,spieler1.player_width-36, spieler1.player_height-36)
player_rect = pygame.Rect(zombie.x+18,zombie.y+24,zombie.player_width-36, zombie.player_height-24)
for f in fireball:
fbRect = pygame.Rect(f.x-f.radius,f.y-f.radius,f.radius*2,f.radius*2)
if zombieRect.colliderect(fbRect):
fireball.remove(f)
zombie.health -= 1
if zombie.health <=0 and not verloren:
gewonnen = True
game_active = False
if zombieRect.colliderect(player_rect):
loose = True
won = False
game_active = False
#Grenzen erstellen
left_border = pygame.draw.rect(screen, BLACK, [0, 0, 2, 800], 0)
right_border = pygame.draw.rect(screen, BLACK, [1225, 0, 2, 800], 0)
#Klasse aufrufen
spieler1 = Spieler(300, 575, 5, -16, 30, 50, [0, 0, 1, 0], 0, 0)
zombie = Enemy(600, 575, 8, 30, 50, [0,0], 0, 1200)
loose = False
win = False
#fireball Array. Wieviele fireballs auf einmal auf dem Spielfeld sein können
fireball = []
#Bedingung für den Spielstart
game_active = True
#Bildschirmaktualisierung einstellen
clock = pygame.time.Clock()
#Hauptschleife des Spiels
while game_active:
#Nutzeraktion überprüfen
for event in pygame.event.get():
if event.type == pygame.QUIT:
game_active = False
player_rect = pygame.Rect(spieler1.x, spieler1.y, spieler1.player_width, spieler1.player_height)
pressed = pygame.key.get_pressed()
#Spielelogik wird berechnet (Bewegung der Figur, Kollision etc)
#Ereignis wenn man sich nach links bewegt und auf die Grenze stößt
if pressed[pygame.K_LEFT] and not player_rect.colliderect(left_border):
spieler1.walking([1, 0])
#Ereignis wenn man sich nach rechts bewegt und auf die Grenze stößt
elif pressed[pygame.K_RIGHT] and not player_rect.colliderect(right_border):
spieler1.walking([0, 1])
#Ereignis wenn keine Taste gedrückt wird
else:
spieler1.standing()
#Ereignis wenn die Sprung-Taste gedrückt wird
if pressed[pygame.K_UP]:
spieler1.sprungsetzen()
#Ereignis wenn die Space-Taste gedrückt wird
if pressed[pygame.K_SPACE]:
#Solange 5 oder weniger Feuerbälle im fireball Array sind und der Spieler schießt, nimmt der Array um einen Index zu.
if len(fireball) <= 4 and spieler1.ready2shoot:
fireball.append(FireBall(spieler1.x, spieler1.y, spieler1.lastPosition, 8, RED, 7))
pygame.mixer.Sound.play(shooting_sound)
spieler1.ready2shoot = False
if not pressed[pygame.K_SPACE]:
spieler1.ready2shoot = True
feuerkugeln()
#Sprungvorgang
spieler1.springen()
#Die Anzeige vom Spieler
show_player()
zombie.hearts()
#Die Anzeige vom Zombie
zombie.enemy_back_forth()
collision()
#Framerate des Spiels
clock.tick(60)
while True:
for event in pygame.event.get():
if event.type == pygame.QUIT:
game_active = False
show_player()
pygame.quit()
最佳答案
技术主管错了:您的代码按照其编写方式是非常高效的。缩短代码并不会使其更快或更“优雅”。
但是,较短的代码更容易维护和更改。只要心脏容器的数量始终恰好是 12,您的代码就可以。但是如果您想更改它(增加/减少游戏的难度,或者让玩家获得新的心脏容器),那么此代码将不会工作。它被硬编码为仅适用于 12 个心脏容器。
要更改此设置,请将此重复代码放入循环中。您需要查看数字变化的模式并为其创建一个小的数学公式。我想出了以下内容。 (我还添加了常量而不是整数文字,以便代码更易于阅读和更改。)
MAX_HEALTH = 12
LEFTMOST_HEART = 440
TOPMOST_HEART = 75
HEART_HALF_WIDTH = 30
def hearts(self):
# Draw all the full hearts:
for i in range(0, self.health, 2):
screen.blit(self.health_full(LEFTMOST_HEART + (i * HEART_HALF_WIDTH), TOPMOST_HEART))
# Draw the half-heart, if needed:
if self.health % 2 == 1:
screen.blit(self.health_half(LEFTMOST_HEART + ((i - 1) * HEART_HALF_WIDTH), TOPMOST_HEART))
# Draw the empty hearts:
for i in range(MAX_HEALTH, self.health, -2):
screen.blit(self.health_zero(LEFTMOST_HEART + ((i - 2) * HEART_HALF_WIDTH), TOPMOST_HEART))
此代码适用于任意数量的生命值(只要它是偶数)。您还可以通过更改 LEFMOST_HEART
和 TOPMOST_HEART
来更改心形的位置。
此代码与您的代码一样“高效”,但更容易维护,因为更改最大生命值或心脏位置只需要更改一些常量。
关于python - 如何处理许多几乎相同的 if 语句?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/71432303/