【问题标题】:How can I have multiple objects moving at once in PYGAME如何在 PYGAME 中同时移动多个对象
【发布时间】:2013-06-01 11:34:08
【问题描述】:

我想制作一个游戏,其中有来自屏幕两侧的敌人。 现在我有它,以便敌人一次滚动一个屏幕。 我希望一次多来一个,慢慢增加他们遇到的频率。 这是我的代码

import pygame, sys, time, random
from pygame.locals import *
pygame.init()
winW = 1000
winH = 600
surface = pygame.display.set_mode ((winW, winH),0,32)


pygame.display.set_caption ('Moving Orc')

class Enemy:
    def __init__(self, char, startY, startX):
        self.char=char
        self.startY=startY
        self.startX=startX
        self.drawChar()

    def drawChar (self):
        self.space = pygame.image.load (self.char)
        self.spaceRect = self.space.get_rect ()
        self.spaceRect.topleft = (self.startX,self.startY)
        self.moveChar()

    def moveChar (self):
        if self.startX == 0:
            self.xMoveAmt = 5
        elif self.startX == 800:
            self.xMoveAmt = -5

        while True:
            surface.fill ((255,255,255))
            self.spaceRect.left += self.xMoveAmt

            surface.blit (self.space, self.spaceRect)

            pygame.display.update()

            time.sleep (0.02)

            if self.spaceRect.right >= winW:
                surface.fill ((255,255,255))
                break

            elif self.spaceRect.left <= 0:
                surface.fill ((255,255,255))
                break


#MAINLINE
while True:
    enemyList=[]
    leftOrRight = random.randint(0,1)
    if leftOrRight == 0:
        leftOrRight = 0
    elif leftOrRight == 1:
        leftOrRight = 800
    enemyList.append(Enemy(("orc.png"), random.randint(50, 500), leftOrRight))

    for i in range (0,len(enemyList)):
        enemyList[i].drawChar()
        break

我有它,所以每次你进入循环时,它都会重置它在我创建的类中运行的列表。一个人会从左边或右边穿过屏幕。

我什至会从哪里开始?

【问题讨论】:

    标签: python class pygame


    【解决方案1】:

    去掉drawChar函数;让 Enemy 类知道应该只存在于游戏逻辑中的 surface 是不好的做法。更改moveChar 函数,使其仅更新对象的位置。从moveChar 中取出循环并在主游戏循环中处理移动。

    敌人类:

    class Enemy(object):
        def __init__(self, char, startX=0, startY=0, xMovAmnt=0):
            self.char = char
            self.x = startX
            self.y = startY
            self.xMovAmnt = xMovAmnt
            # no reason to load the image every time you want to draw, do it here
            self.image = pygame.image.load(self.char)
            self.rect = self.image.get_rect()
    
        def moveChar(self):
            self.x += self.xMovAmnt
    

    游戏循环

    enemyList = []
    while True:
        ...
        # you never specified when you want to create a new Enemy, 
        #    so you need to figure that out on your own
        ...
    
        # this is a more "Pythonic" way of looping over a list than using a range
        for enemy in enemyList:
            enemy.movChar()
            surface.blit(enemy.image, (enemy.x, enemy.y))
    
        pygame.display.update()
    

    【讨论】:

      【解决方案2】:

      为了拥有多个敌人,您应该解决一些问题。

      一个简单的 pygame 程序结构是什么样子的

      init() 
      While(True):
          draw()
          update()
          checkInput()
      

      我看到你已经为敌人编写了一个绘制和移动函数,但他们没有做他们应该做的。

      您的 draw 方法加载图像,并调用移动函数。加载通常应在__init__() 中完成。

      您的 move 函数绘制和移动角色,但它有一个 While 循环,这会使其卡住,直到该角色离开屏幕为止。

      示例解决方案:

      def draw(self,surface):
          surface.blit (self.space, self.spaceRect)
      
      def move(self):
          self.spaceRect.left += self.xMoveAmt
          if self.spaceRect.right >= winW:
              self.kill()
          elif self.spaceRect.left <= 0:
              self.kill()
      

      杀死一个对象的一种可能方法是设置一个标志,并在 While 方法中检查它是否可以从对象列表中删除。

      现在您可以创建一个敌人列表,然后调用 draw 并为每个敌人更新。在 for 循环中。

      【讨论】:

      • 我认为即使在 Enemy 类中有一个 draw 函数也很糟糕。即使更改它以使您必须传入对表面的引用,您仍然会限制对象表面的绘制方式。我更喜欢只为其图像提供对象属性,并让游戏循环或实用程序模块处理它在各种场景中的绘制方式。编辑:此外,它向 Pygame 添加了更多依赖项。理论上,您可以在类外部加载图像并将加载的表面传递给类的构造函数,并使其可用于多个框架。
      • 我同意绘图功能不是大型项目的方式。这就是为什么我称它为简单的 pygame 程序。 OP的游戏区域是屏幕区域本身,所以精灵的坐标将与屏幕的坐标相同。把一个简单的游戏复杂化是没有意义的
      • 我现在拥有它,以便在屏幕上进行多个跨度和滚动。我怎样才能使产卵和移动不会同时发生?每次它移动时,都会过快地填充屏幕。
      • @StephenSparks 您可以使用 pygame 的 Time 模块跟踪上次生成的时间:pygame.org/docs/ref/time.html
      • 好的,我明白了。当对象到达另一边时如何删除它?
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2013-09-27
      • 1970-01-01
      • 2016-01-21
      相关资源
      最近更新 更多