【问题标题】:Pygame let a class have multiple instancesPygame让一个类有多个实例
【发布时间】:2016-12-13 11:08:19
【问题描述】:

我需要有关如何使我的塔防游戏具有多个实例的类的帮助。我想让新实例在最后一个实例之后大约一秒钟出现,但已经卡住了几个小时。我的代码如下。

import pygame
import os
import time

img_path = os.path.join('test.jpg')

class redEnemy(object): 
    def __init__(self):
        self.image = pygame.image.load(img_path)
        self.x = 0
        self.y = 208

    def moveEnemy(self):
        dist =  3
        if True:
            self.x += dist

    def draw(self, surface):
        surface.blit(self.image, (self.x, self.y))
        lifes(self)


def lifeText(life):
    font = pygame.font.SysFont("monospace", 20)
    text = font.render("Lifes %s" % life, True, black)
    textpos = text.get_rect()
    textpos.center = (50,20)
    screen.blit(text, textpos)

def lifes(self):
    global life
    life = 50
    if self.x > 950:
        life = life - 1
        enemies.append(redEnemy())
    lifeText(life)

pygame.init()
screen = pygame.display.set_mode((960, 720))

black = (0,0,0)
enemies = []

redenemy = redEnemy()
clock = pygame.time.Clock()
mapImg = pygame.image.load("mapimage.jpg")

running = True
while running:
    for event in pygame.event.get():
        if event.type == pygame.QUIT:
            pygame.quit()
            running = False
        for enemy in enemies:
            enemy.update()
        for enemy in enemies:
            enemy.draw(screen)

    redenemy.moveEnemy()
    screen.blit(mapImg, (0,0))

    redenemy.draw(screen)
    pygame.display.update()

    clock.tick(60)

【问题讨论】:

  • 您对多重实例的确切含义是什么?类似的东西: a = redEnemy(); b = redEnemy();打印 id(a),id(b)
  • 我希望班级能够同时在屏幕上有多个敌人但我不知道怎么做,我在网上看到你使用列表来做到这一点但我仍然感到困惑。
  • 您只创建了一个 redenemy redenemy = redEnemy() 的实例,因此当您将其添加到列表时,它将始终指向同一个敌人。你也调用enemy.update(),但它没有任何这样的方法。
  • 那我该如何解决呢?
  • 如何解决?通常 - 在你的班级中定义def update(self)。要拥有许多实例,只需执行 instance_1 = redEnemy()instance_2 = redEnemy() 等。您可以将所有实例保留在列表中 - instances = []instances.append(redEnemy())

标签: python class pygame instances


【解决方案1】:

我不知道您在 lifes() 中尝试做什么,但其余代码可能如下所示:

import pygame
import random

# --- constants --- (UPPER_CASE names)

WIDTH  = 960
HEIGHT = 720

BLACK = (  0,   0,   0)
WHITE = (255, 255, 255)

FPS = 60

# --- classes --- (CamelCase names)

class RedEnemy(object):

    # one image for all instances
    image = pygame.image.load('test.jpg')

    def __init__(self, x, y, screen):
        self.screen = screen
        self.screen_rect = screen.get_rect()

        # every instance can have own image
        #self.image = pygame.image.load('test.jpg')

        self.rect = self.image.get_rect()
        self.rect.x = x
        self.rect.y = y

        self.dist_x = 3
        self.dist_y = 0


    def update(self):
        # move to right side and start at left side

        if self.rect.right < self.screen_rect.right:      
            self.rect.x += self.dist_x
            self.rect.y += self.dist_y
        else:
            self.rect.left = 0

    def draw(self, screen):
        screen.blit(self.image, self.rect)

# --- functions --- (lower_case names)

def life_text(screen, life, font):

    text = font.render("Lifes %s" % life, True, BLACK)

    text_rect = text.get_rect()
    text_rect.center = (50,20)

    screen.blit(text, text_rect)

# --- main --- (lower_case names)

pygame.init()

screen = pygame.display.set_mode((WIDTH, HEIGHT))
screen_rect = screen.get_rect()

# - objects -

# background

map_img = pygame.image.load("mapimage.jpg")

# enemies - 10 enemies in random places

enemies = []

for i in range(10):

    x = random.randint(0, WIDTH)
    y = random.randint(0, HEIGHT)
    enemies.append(RedEnemy(x, y, screen))

# player

lifes = 50

# player = Player() # you need class Player()

# - other -

font = pygame.font.SysFont("monospace", 20)
clock = pygame.time.Clock()

# - mainloop - 

running = True

while running:

    # - events -

    for event in pygame.event.get():
        if event.type == pygame.QUIT:
            running = False

    # - updates -

    for enemy in enemies:
        enemy.update()
        if enemy.rect.right >= screen_rect.right:
            lifes -= 1

    # - draws -

    # background

    screen.blit(map_img, (0,0))

    # enemies

    for enemy in enemies:
        enemy.draw(screen)

    # other

    life_text(screen, lifes, font)

    # send buffer to monitor

    pygame.display.update()

    # - FPS -

    clock.tick(FPS)

# - end -

pygame.quit()

【讨论】:

  • 谢谢你,你已经很好地向我解释了这一点,并教会了我很多东西。如您所见,我是 pygame 的新手。
【解决方案2】:

我必须说,在改进这段代码方面肯定有工作要做,但我们都必须从某个地方开始。 (而且我当然会继续学习这个过程)。

幸运的是,通过一些随机图像,我能够运行您的代码,并且我相信我理解您的意思。但是,首先,我认为需要解决的是您应该添加

screen.fill((0,0,0))

在循环开始时。

但至于你打算解决的问题,我相信你只是忘记将“redEnemy”放在你的敌人列表中。通过删除事件处理器循环中的奇数函数,并在循环的敌人迭代器上应用“redEnemy”的方法,您可以获得所需的结果。此外,在你的生命功能中,我认为移除之前的飞船是合适的,因为有源源不断的敌人从屏幕的一侧倾泻而出。尽管如此,这里(希望)是您想要的代码:

import pygame
import os
import time

img_path = os.path.join('test.jpg')

class redEnemy(object): 
    def __init__(self):
        self.image = pygame.image.load(img_path)
        self.x = 0
        self.y = 208

    def moveEnemy(self):
        dist =  3
        if True:
            self.x += dist

    def draw(self, surface):
        surface.blit(self.image, (self.x, self.y))
        lifes(self)


def lifeText(life):
    font = pygame.font.SysFont("monospace", 20)
    text = font.render("Lifes %s" % life, True, black)
    textpos = text.get_rect()
    textpos.center = (50,20)
    screen.blit(text, textpos)

def lifes(self):
    global life
    life = 50
    if self.x > 950:
        life = life - 1
        enemies.append(redEnemy())
        enemies.remove(self)
    lifeText(life)

pygame.init()
screen = pygame.display.set_mode((960, 720))

black = (0,0,0)
enemies = [redEnemy()]

redenemy = enemies[0]
clock = pygame.time.Clock()
mapImg = pygame.image.load("mapimage.jpg")

running = True
while running:
    screen.fill((0,0,0))

    for event in pygame.event.get():
        if event.type == pygame.QUIT:
            pygame.quit()
            running = False

    for enemy in enemies:
        enemy.moveEnemy()
    screen.blit(mapImg, (0,0))

    for enemy in enemies:
        enemy.draw(screen)
    pygame.display.update()

    clock.tick(60)

只需运行它,并希望您的预期问题得到解决。

【讨论】:

  • 非常感谢我是 pygame 的新手,这向我展示了我需要执行代码以及解决问题的顺序。
猜你喜欢
  • 2021-02-06
  • 2020-04-20
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2017-01-11
相关资源
最近更新 更多