2017-10-08 96 views
0

我一直在做一個遊戲,'arkanoid' 我有什麼是一個球和一個槳。pygame,鍵盤事件和控制OOP遊戲

這是我正在嘗試使用面向對象的第一場遊戲,所以我非常感謝您的所有評論。我創建了一個Objectmanager類來管理遊戲中的所有對象,現在我不知道應該在哪裏放置鍵盤控制和播放器槳板運動。

  1. 寫了Objectevent的keyevent方法並將event.key傳遞給它,然後操縱槳 - 沒有很好的工作。
  2. 同樣的方法,但路過pygame.key.getpressed()和的ObjectManager

兩種方式檢查按鈕,使一個壞的方式槳移動或不停止時,我希望它停止。

我認爲1.是更好的,但我不能完美,所以我問你一些提示。 我會在一個循環中輕鬆完成它,但我真的很想學習OOP,並且我不知道是否應該將它放在ObjectManager或主循環中。 我也在考慮將Paddle放入主循環中,而不是ObjectManager中。你怎麼看?謝謝你們。

import random, pygame, sys, math, itertools 
from pygame.locals import * 
#   R G B 
BLACK = ( 0, 0, 0) 
GRAY  = (100, 100, 100) 
NAVYBLUE = (60, 60, 100) 
WHITE = (255, 255, 255) 
RED  = (255, 0, 0) 
GREEN = ( 0, 255, 0) 
BLUE  = ( 0, 0, 255) 
YELLOW = (255, 255, 0) 
ORANGE = (255, 128, 0) 
PURPLE = (255, 0, 255) 
CYAN  = ( 0, 255, 255) 
BALLSIZE = 15 
BALLSPEED = 5 
FPS = 60 
PADDLEWIDTH = 80 
PADDLEHEIGHT = 20 

class Ball: 
    def __init__(self): 
     self.middle = [250,250] 
     self.angle = math.radians(random.randint(1, 360)) 
     self.speed = BALLSPEED 
    def update(self): 
     xspeed = self.speed * math.sin(self.angle) 
     yspeed = self.speed * math.cos(self.angle) 
     deltax = round(xspeed) 
     deltay = round(yspeed) 
     self.middle[0] += deltax 
     if self.middle[0] <= 0 or self.middle[0] >= 500: 
      self.middle[0] -= 2*deltax 
      self.angle = 2*math.pi - self.angle 
     self.middle[1] += deltay 
     if self.middle[1] <= 0 or self.middle[1] >= 500: 
      self.middle[1] -= 2*deltay 
      self.angle = math.pi - self.angle 
    def draw(self,surface): 
     pygame.draw.circle(surface,WHITE,self.middle,BALLSIZE) 

class Paddle: 
    def __init__(self): 
     self.middle = [250,480] 
     self.deltax = 0 
    def update(self): 
     self.middle[0] += self.deltax 
    def rect(self): 
     return pygame.Rect(self.middle[0]-(PADDLEWIDTH/2),self.middle[1]-(PADDLEHEIGHT/2),PADDLEWIDTH,PADDLEHEIGHT) 
    def moveleft(self): 
     self.deltax -= 10 
    def moveright(self): 
     self.deltax += 10 
    def stop(self): 
     self.deltax = 0 
    def draw(self,surface): 
     pygame.draw.rect(surface,WHITE,self.rect()) 
     pygame.draw.rect(surface, GRAY, self.rect(),4) 

class ObjectManager: 
    def __init__(self): 
     self.balls = [Ball(),] 
     self.paddle = Paddle() 
    def add(self,object): 
     if type(object) == Ball: 
      self.balls.append(object) 

    def update(self): 
     for object in itertools.chain(self.balls,(self.paddle,)): 
      object.update() 
    def keyevent(self,keys): 
     if keys[K_RIGHT]: 
      self.paddle.moveright() 
     elif keys[K_LEFT]: 
      self.paddle.moveleft() 
     else: 
      self.paddle.stop() 
    def draw(self,surface): 
     for object in itertools.chain(self.balls,(self.paddle,)): 
      object.draw(surface) 

class Game: 
    def __init__(self): 
     pygame.init() 
     self.FPS = FPS 
     self.fpsClock = pygame.time.Clock() 
     DISPLAYSURF = pygame.display.set_mode((500,500),0,32) 
     pygame.display.set_caption('arkanoid') 
     manager = ObjectManager() 

     while True: 
      for event in pygame.event.get(): 
       if event.type == QUIT: 
        pygame.quit() 
        sys.exit() 
       elif event.type == KEYDOWN: 
        if event.key == K_ESCAPE: 
         pygame.quit() 
         sys.exit() 

      manager.keyevent(pygame.key.get_pressed()) 
      manager.update() 

      DISPLAYSURF.fill(BLACK) 
      manager.draw(DISPLAYSURF) 
      pygame.display.update() 
      self.fpsClock.tick(self.FPS) 
game = Game() 

回答

1

ObjectManager應該只負責你的自定義GameObject,這可能是一個抽象類或接口定義move(), update()等等。 (你的球和槳可以繼承/實現這個)。

所以從我的角度來看,我認爲你應該在你的主循環中處理事件。 (創建一個EventManager也是一個選項。)你應該問自己,這個類負責什麼?並儘可能簡單地讓他們分擔擔憂。

而且我會把色入類型的字典e.g列表:

['black':{'R':0,'G':0,'B':0}] 

所以,你可以在運行時改變顏色更容易,例如選擇一個隨機的顏色。

1

的ObjectManager:

def keydown(self,key): 
    if key == K_RIGHT: 
     self.paddle.moveright() 
    elif key == K_LEFT: 
     self.paddle.moveleft() 
def keyup(self): 
    self.paddle.stop() 

主循環:

for event in pygame.event.get(): 
     if event.type == QUIT: 
      pygame.quit() 
      sys.exit() 
     elif event.type == KEYDOWN: 
      if event.key == K_ESCAPE: 
       pygame.quit() 
       sys.exit() 
      else: 
       manager.keydown(event.key) 
     else: 
      manager.keyup() 

你覺得呢?這工作得很好,我剛一到這個時候我發表我的問題....