Преамбула: я чувствую, что, возможно, я потратил столько времени на простую ситуацию ...
Теперь я делаю игру с Pygame, и в какой-то момент я хотел разделить файлы на два, а именно main.py
и configurations.py
, чтобы сделать его более читабельным.
Все шло хорошо, пока я не столкнулся с этой проблемой.
Я поделюсь всем код внизу, но я хочу сначала подвести итог:
Теперь, во-первых, в main.py
, я импортирую по,
from configurations import *
сейчас, игра l oop на main.py
зависит от переменной running
от
while running:
.......
.......
.......
А переменная running
инициализируется в configurations.py
с помощью
# initialize some variables
running = True
Итак, main.py
должен получать переменную running
, поскольку он не выдает никакой ошибки и использует ее в операторе while running
.
В главном l oop есть раздел, где Я проверяю события следующим образом:
for event in pygame.event.get():
# check for closing window
if event.type == pygame.QUIT:
running = False
Эта часть работает так же, как и ожидалось, она изменяет работу переменной, и программа выходит из строя в то время, как l oop.
* 1 038 * Теперь здесь возникает проблематичная c часть.
В одном из классов (класс Player) есть метод как decrease_HP
,
def decrease_HP(self):
self.HP -= 1
print("-1 HP", "Current HP:", self.HP)
if self.HP <= 0:
running = False
Однако, точка Я не мог понять, что он не изменяет переменную бега должным образом, и игра никогда не останавливается (выходит из режима l oop). Вот один пример вывода, который показывает проблему.
pygame 1.9.6
Hello from the pygame community. https://www.pygame.org/contribute.html
-1 HP Current HP: 2
-1 HP Current HP: 1
-1 HP Current HP: 0
-1 HP Current HP: -1
-1 HP Current HP: -2
-1 HP Current HP: -3
-1 HP Current HP: -4
-1 HP Current HP: -5
-1 HP Current HP: -6
Итак, я надеюсь, что смогу прояснить это. Возможно, у меня возникло недоразумение по поводу импорта переменных или областей действия переменных.
Кстати, я попытался добавить global running
над оператором running = False
в функции Player.decrease_HP
.
Заранее спасибо .
Точные коды в файлах
main.py
# Pygame template - skeleton for a new pygame project
from configurations import *
# initiate some variables
max_bullet = 10
# initialize pygame and create window
pygame.init()
pygame.mixer.init()
screen = pygame.display.set_mode((WIDTH, HEIGHT))
pygame.display.set_caption("CORONA RACE")
clock = pygame.time.Clock()
player = Player()
all_sprites.add(player)
# initialize some variables
running = True
# have to use this because, otherwise, for the first SPACE key pressing, the newest_bullet is not defined yet.
newest_bullet = Bullet(0, 0)
# Game loop
while running:
# keep loop running at the right speed
clock.tick(FPS)
# Process input (events)
for event in pygame.event.get():
# check for closing window
if event.type == pygame.QUIT:
running = False
else:
pass
while len(mobs) != 5:
m = Mob()
all_sprites.add(m)
mobs.add(m)
keystate = pygame.key.get_pressed()
player.speedx = 0
if keystate[pygame.K_RIGHT]:
player.speedx += player.SPEED
if keystate[pygame.K_LEFT]:
player.speedx -= player.SPEED
if keystate[pygame.K_SPACE] and player.rect.top - newest_bullet.rect.bottom > BULLET_H + MARGIN and not len(bullets) >= max_bullet:
newest_bullet = player.shoot()
# BULLET_H refers to height of the bullet and margin refers to the minimum allowable margin between two consequent b
# If there are more than 10 bullets at a time on the screen, then no more new bullets can be fired.
if keystate[pygame.K_ESCAPE]:
running = False
if random.randint(0, 14530) > 14470:
power_up = PowerUp()
all_sprites.add(power_up)
powerups.add(power_up)
hits = pygame.sprite.spritecollide(player, powerups, True)
for pu in hits:
power_up_funcs[pu.type](player)
hits = pygame.sprite.groupcollide(mobs, bullets, True, True)
for m in hits:
pass
hits = pygame.sprite.spritecollide(player, mobs, True)
if hits:
player.decrease_HP()
# print(player.HP)
# Update
all_sprites.update()
# Draw / render
screen.fill(WHITE)
all_sprites.draw(screen)
# *after* drawing everything, flip the display
pygame.display.flip()
pygame.quit()
raise SystemExit # to exit python
configurations.py
import pygame
import random
# define constants
WIDTH = 600
HEIGHT = 960
FPS = 30
BULLET_H = 24
BULLET_W = 8
POWERUP_H = 30
POWERUP_W = 30
MOB_W = 50
MOB_H = 80
MARGIN = 10
# define colors
WHITE = (255, 255, 255)
BLACK = (0, 0, 0)
RED = (255, 0, 0)
GREEN = (0, 255, 0)
BLUE = (0, 0, 255)
YELLOW = (255, 255, 0)
MAGENTA = (255, 0, 255)
CYAN = (0, 255, 255)
# create sprite groups
all_sprites = pygame.sprite.Group()
bullets = pygame.sprite.Group()
powerups = pygame.sprite.Group()
mobs = pygame.sprite.Group()
# initialize some variables
running = True
# player sprite
class Player(pygame.sprite.Sprite):
SPEED = 15
def __init__(self):
super().__init__()
# pygame.sprite.Sprite.__init__(self)
self.image = pygame.Surface((100, 150))
self.image.fill(CYAN)
pygame.draw.circle(self.image, RED, (50, 75), 15, 5)
self.rect = self.image.get_rect()
self.rect.centerx = WIDTH / 2
self.rect.bottom = HEIGHT - 5
self.speedx = 0
self.HP = 3
def update(self):
self.rect.x += self.speedx
if self.rect.right > WIDTH:
self.rect.right = WIDTH
if self.rect.left < 0:
self.rect.left = 0
def shoot(self):
bullet = Bullet(self.rect.centerx, self.rect.top)
all_sprites.add(bullet)
bullets.add(bullet)
return bullet # I need this to set the margin in continious fire.
def change_color(self):
pass
def increase_HP(self):
if self.HP <= 2:
self.HP += 1
print("+1 HP", "Current HP:", self.HP)
else:
print("HP IS ALREADY FULL", "Current HP:", self.HP)
def decrease_HP(self):
self.HP -= 1
print("-1 HP", "Current HP:", self.HP)
if self.HP <= 0:
running = False
class Mob(pygame.sprite.Sprite):
def __init__(self):
super().__init__()
self.image = pygame.Surface((MOB_W, MOB_H))
self.image.fill(MAGENTA)
self.rect = self.image.get_rect()
self.rect.left = random.randint(0, WIDTH - POWERUP_W)
self.rect.bottom = random.randint(-2 * MOB_H, 0)
def update(self):
self.rect.y += 6
if self.rect.top > HEIGHT:
self.kill()
# Bullet sprite
class Bullet(pygame.sprite.Sprite):
def __init__(self, x, y):
super().__init__()
self.image = pygame.Surface((BULLET_W, BULLET_H))
self.image.fill(RED)
self.rect = self.image.get_rect()
self.rect.centerx = x
self.rect.bottom = y
self.speedx = 0
self.speedy = -20
def update(self):
self.rect.y += self.speedy
# kill it if it moves away from the screen
if self.rect.bottom < 0:
self.kill() # built in method of pygame.sprite
# powerup sprite
power_up_funcs = [Player.increase_HP, print] # container for to-do functs.
class PowerUp(pygame.sprite.Sprite):
SPEEDY = 8
def __init__(self):
super().__init__()
self.type = random.randint(0, 1) # [0,1] integer
if self.type == 0: # HP power up
self.image = pygame.Surface((POWERUP_W, POWERUP_H))
self.image.fill(GREEN)
self.rect = self.image.get_rect()
self.rect.left = random.randint(0, WIDTH - POWERUP_W)
# self.rect.centerx = player.rect.centerx #debug
self.rect.bottom = 0
elif self.type == 1: # shield
self.image = pygame.Surface((POWERUP_W, POWERUP_H))
self.image.fill(BLUE)
self.rect = self.image.get_rect()
self.rect.left = random.randint(0, WIDTH - POWERUP_W)
# self.rect.centerx = player.rect.centerx # debug
self.rect.bottom = 0
else:
pass
def update(self):
self.rect.y += self.SPEEDY
if self.rect.top > HEIGHT:
self.kill()