2016-04-23 186 views
2

我剛剛開始使用Pygame,我正在嘗試一些基本的移動功能。Pygame似乎「避免」循環

當我嘗試將我的移動條件編碼到我的對象類而不是遊戲循環中時遇到了問題。

我這工作的第一次嘗試如下:

classes.py:

import pygame, sys 
from pygame.locals import * 
class GameObject: 
    def __init__(self, image, height, speed): 
     self.speed = speed 
     self.image = image 
     self.pos = image.get_rect().move(0, height) #initial placement 

    def move_south(self): 
     self.pos = self.pos.move(0, self.speed) 
     if self.pos.right > 600: 
      self.pos.left = 0 

    def move_east(self): 
     self.pos = self.pos.move(self.speed , 0) 
     if self.pos.right > 600: 
      self.pos.left = 0 

main.py:

import pygame, sys 
from pygame.locals import * 
from classes import * 

screen = pygame.display.set_mode((640, 480)) 
#Importing Chars 
player = pygame.image.load('green_hunter_small.png').convert() 
#player.set_alpha(100) #makes whole player transparent 
player.set_colorkey((0,0,0)) #sets background colour to transparent 

ennemi = pygame.image.load('red_hunter_small.png').convert() 
ennemi.set_colorkey((0,0,0)) 

background = pygame.image.load('grass_map_640x640.png').convert() 
screen.blit(background, (0, 0)) 
objects = [] 
objects.append(GameObject(player, 80, 0)) 
for x in range(2):  #create 2 objects 
    o = GameObject(ennemi, x*40, 0) 
    objects.append(o) 
while True: 
    for event in pygame.event.get(): #setting up quit 
     if event.type == QUIT: 
      pygame.quit() 
      sys.exit() 
     if event.type == KEYDOWN: 
      if event.key == K_DOWN: 
       for o in objects: 
        screen.blit(background, o.pos, o.pos) #erases players by bliting bg 
       for o in objects: 
        o.speed = 4 
        o.move_south() #moves player 
        o.speed = 0 
        screen.blit(o.image, o.pos) #draws player 
      if event.key == K_RIGHT: 
       for o in objects: 
        screen.blit(background, o.pos, o.pos) #erases players by bliting bg 
       for o in objects: 
        o.speed = 4 
        o.move_east() #moves player 
        o.speed = 0 
        screen.blit(o.image, o.pos) #draws player      
    pygame.display.update() 
    pygame.time.delay(50) 

我沒有工作第二次嘗試與DP :

classes.py:

import pygame, sys 
from pygame.locals import * 

class GameObject: 
    def __init__(self, image, height, speed): 
     self.speed = speed 
     self.image = image 
     self.pos = image.get_rect().move(0, height) #initial placement 

    def move_south(self): 
     self.pos = self.pos.move(0, self.speed) 
     if self.pos.right > 600: 
      self.pos.left = 0 

    def move_east(self): 
     self.pos = self.pos.move(self.speed , 0) 
     if self.pos.right > 600: 
      self.pos.left = 0 

    def move(self): 
     for event in pygame.event.get(): 
      if event.type == KEYDOWN: 
       if event.key == K_DOWN: 
        screen.blit(background, self.pos, self.pos) #erases players by bliting bg 
        self.speed = 4 
        self.move_south() #moves player 
        self.speed = 0 
       if event.key == K_RIGHT: 
        screen.blit(background, self.pos, self.pos) #erases players by bliting bg 
        self.speed = 4 
        self.move_east() #moves player 
        self.speed = 0 
       screen.blit(self.image, self.pos) #draws player 

main.py:

import pygame, sys 
from pygame.locals import * 
from classes import * 

screen = pygame.display.set_mode((640, 480)) 
#Importing Chars 
player = pygame.image.load('green_hunter_small.png').convert() 
#player.set_alpha(100) #makes whole player transparent 
player.set_colorkey((0,0,0)) #sets background colour to transparent 

ennemi = pygame.image.load('red_hunter_small.png').convert() 
ennemi.set_colorkey((0,0,0)) 

background = pygame.image.load('grass_map_640x640.png').convert() 
screen.blit(background, (0, 0)) 
objects = [] 
objects.append(GameObject(player, 80, 0)) 
for x in range(2):  #create 2 objects 
    o = GameObject(ennemi, x*40, 0) 
    objects.append(o) 
while True: 
    for event in pygame.event.get(): #setting up quit 
     if event.type == QUIT: 
      pygame.quit() 
      sys.exit() 
    for o in objects: 
     o.move()   
    pygame.display.update() 
    pygame.time.delay(50) 

如此看來,代碼鬥爭去檢查從實例事件循環。我想將運動編碼爲一種方法而不是直接編碼的原因是爲了節省空間,並且稍後添加字符變得更加容易。

+0

只是想讓你知道,我認爲這是一個很好的嘗試和假設的問題。我在火車上,現在無法解決這個問題,但這對於一個「初學者」來說尤其是個好問題, – Torxed

+0

謝謝您的評論。我已經做了一些更多的工作,並且感謝其他評論意識到它更好一點。我改變了我的系統,將我的玩家的位置與鼠標位置進行比較,並使玩家向點擊位置移動。目前,我被卡住了,因爲儘管我的新系統能夠正常工作,但我必須點擊很多才能將它移動到點擊位置。理想情況下,我希望它繼續向自己的點擊位置移動。 – Sorade

+0

@Sorade需要點擊很多是一個單獨的問題,應該[單獨提問](http://stackoverflow.com/questions/ask) – ppperry

回答

2

你的代碼有一個競爭條件(使用這個術語非常鬆散)。

您的角色沒有移動的原因是第一個pygame.event.get調用(當您檢查QUIT事件時)會佔用隊列上的所有KEYDOWN事件。然後(除非您在第一個循環運行時按下某個鍵),則當第一個GameObject檢查事件時,隊列中不會有KEYDOWN事件。 Diddo其他所有GameObjects

你需要在一個循環中處理所有的pygame事件。示例代碼:

class GameObject(): 
    #rest of class 
    def move(self,event): 
     if event.key == K_DOWN: 
      screen.blit(background, self.pos, self.pos) #erases players by bliting bg 
      self.speed = 4 
      self.move_south() #moves player 
      self.speed = 0 
     #repeat for all other directions 
     screen.blit(self.image, self.pos) #draws player 
#initialize objects 
while True: 
    for event in pygame.event.get(): 
     if event.type == QUIT: #handle quit event 
     elif event.type == KEYDOWN: 
      for o in objects: 
       o.move(event) 
    #do non-eventhandling tasks. 
+0

謝謝你的回覆,這非常有用。我得到它的工作。然而,我必須通過「背景」作爲我的移動(自我,背景)方法的參數才能發揮作用。否則,我得到錯誤,全局變量未定義的錯誤。有沒有辦法繞過,或者我必須列出方法中使用的所有變量作爲參數? – Sorade

+0

你不必將所有的變量列爲參數 – ppperry

+0

我已經改變了一下代碼(我尋找鼠標的位置,而不是移動它)但我得到錯誤,當我不這樣做: – Sorade