我是一个半新手编程,我正在使用python和pygame进行游戏。 基本思想是,玩家在一个大的tilemap上四处走动并执行操作。 因此,会有各种各样的对象在做事情。 NPC移动,草长,灌木丛长,吃草的动物等。
我以游戏的模拟版为例。
import pygame
class Plant():
def __init__(self,name,location,size,edible):
self.name = name
self.location = location
self.size = size
self.edible = edible
class Person():
def __init__(self,location,name):
self.location = location
self.name = name
class Game():
def __init__(self):
pygame.init()
self.mainScreen = pygame.display.set_mode(200,200)
self.objects = []
self.running = False # start stopped
def launch(self):
self.running=True
self.running_loop()
def running_loop(self):
while self.running:
self.mainScreen.fill((255,255,255))
# main game loop
for object in self.objects:
if type(object) == Person:
#do code related to persons
pass
elif type(object) == Plant:
# do code related to persons
pass
for object in self.objects:
pygame.draw(self.mainScreen,object)
# event handling
for event in pygame.event.get():
if event.type == pygame.QUIT:
pygame.quit()
#create game instance
game = Game()
#create things in the game
person1 = Person((0,0),"Player")
plant1 = Plant("Bush",(1,1),2,False)
plant2 = Plant("Strawberries",(2,3),1,True)
game.objects.append(person1)
game.objects.append(plant1)
game.objects.append(plant2)
game.launch()
所以我的问题是关于这部分的:
def running_loop(self):
while self.running:
# main game loop
for object in self.objects:
if type(object) == Person:
#do code related to persons
pass
elif type(object) == Plant:
# do code related to persons
pass
for object in self.objects:
pygame.draw(self.mainScreen,object)
列表中会有很多不同的对象,可以容纳游戏中的所有对象。但是,并非所有方法都具有相同的方法,因此不是if type(object)。我一直在想,还有一种更优雅的方式可以做到这一点。我可以做多态并只编写一个在每个实例中调用其他方法的更新方法吗?该解决方案的问题在于,我可能还需要导入pygame的Rect
之类的类。由于这是一个项目,可能会变得非常混乱,我想从一开始就尝试这样做。
答案 0 :(得分:1)
在pygame中,通常建议从pygame.sprite.Sprite
继承并将实例放入sprite groups。 Sprite
类具有一个update
方法,该方法应该被特定子画面对象的相关逻辑所覆盖。您可以通过调用子图形组的update
方法来更新子图形组中的所有子图形,子方法随后将调用所有包含的子图形的update
方法,还可以使用sprite_group.draw(display_surface)
绘制子图形。
如果小精灵应该以预定的顺序出现,则还有layered groups的顺序。
这是introduction to sprites and groups,这是我的pygame模板之一:
import pygame as pg
class Player(pg.sprite.Sprite):
def __init__(self, pos, key_left, key_right, key_up, key_down):
super().__init__()
self.image = pg.Surface((30, 50))
self.image.fill(pg.Color('dodgerblue'))
self.rect = self.image.get_rect(topleft=pos)
self.vel = pg.math.Vector2(0, 0)
self.pos = pg.math.Vector2(self.rect.topleft)
self.speed = 5
self.key_left = key_left
self.key_right = key_right
self.key_up = key_up
self.key_down = key_down
def update(self):
self.pos += self.vel
self.rect.center = self.pos
def handle_event(self, event):
if event.type == pg.KEYDOWN:
if event.key == self.key_left:
self.vel.x = -self.speed
elif event.key == self.key_right:
self.vel.x = self.speed
elif event.key == self.key_up:
self.vel.y = -self.speed
elif event.key == self.key_down:
self.vel.y = self.speed
elif event.type == pg.KEYUP:
if event.key == self.key_left and self.vel.x < 0:
self.vel.x = 0
elif event.key == self.key_right and self.vel.x > 0:
self.vel.x = 0
elif event.key == self.key_up and self.vel.y < 0:
self.vel.y = 0
elif event.key == self.key_down and self.vel.y > 0:
self.vel.y = 0
class Game:
def __init__(self):
pg.init()
self.fps = 60
self.done = False
self.clock = pg.time.Clock()
self.screen = pg.display.set_mode((800, 600))
self.player1 = Player((100, 100), pg.K_a, pg.K_d, pg.K_w, pg.K_s)
self.player2 = Player((200, 200), pg.K_j, pg.K_l, pg.K_i, pg.K_k)
self.all_sprites = pg.sprite.Group(self.player1, self.player2)
self.background_color = pg.Color('gray12')
def run(self):
while not self.done:
self.dt = self.clock.tick(self.fps) / 1000
self.handle_events()
self.run_logic()
self.draw()
def handle_events(self):
for event in pg.event.get():
if event.type == pg.QUIT:
self.done = True
for sprite in self.all_sprites:
sprite.handle_event(event)
def run_logic(self):
self.all_sprites.update()
def draw(self):
self.screen.fill(self.background_color)
self.all_sprites.draw(self.screen)
pg.display.flip()
if __name__ == '__main__':
Game().run()
pg.quit()