2014-05-18 170 views
-2

這已經被編輯,原帖是關於塊傳輸的啓動畫面 我使用pygame的一個簡單的遊戲工作,遊戲已接近完成,但是我遇到一些問題與啓動畫面。目前的問題是,當遊戲運行時,啓動畫面會像預期的那樣閃爍,但是如果用戶在屏幕上的任何地方點擊或試圖退出遊戲,它就會崩潰。有沒有人知道解決這個問題的方法,我希望的是用戶甚至可以退出遊戲,甚至可以在顯示時跳過啓動畫面。pygame的閃屏死機遊戲

def main(): 
    '''Here the game is being initialised''' 
    pygame.init() #Initialising Pygame 
    pygame.key.set_repeat(1, 20) #Registers event every 20MS if a key is held down 
    countFont = pygame.font.Font(None,18) #Font being set 
    statusFont = pygame.font.Font(None,18) #Font being set 
    screen = pygame.display.set_mode([WINDOW_WIDTH, WINDOW_HEIGHT]) 
    pygame.display.set_caption('Do Not Get Capped') 

    #Drawable surface 
    background = pygame.Surface(screen.get_size()) 

    #Used for converting color maps 
    background = background.convert() 

    #Splashscreen 

    #image fades in 
    for i in range (225): 
      background.fill((0,0,0)) 
      image = pygame.image.load("splash_screen1.png") 
      image.set_alpha(i) 
      logoimage = screen.blit(image,(0,0)) 
      pygame.display.flip() 

    pygame.time.delay(2000) 

    for i in range (225): 
      background.fill((0,0,0)) 
      image = pygame.image.load("splash_screen2.png") 
      image.set_alpha(i) 
      logoimage = screen.blit(image,(0,0)) 
      pygame.display.flip() 

    pygame.time.delay(4000)   

    '''The main function which is called at the end of this code''' 
    class Game(): 
      '''This class's purpose is to keep track of the current score''' 
      def __init__(self): 
        self.score=0 
        self.goalNumbers=0 

    class Gun(pygame.sprite.Sprite): 
      '''This is the gun that the user controls''' 
      def __init__(self): 
        '''This is the class contructor''' 
        pygame.sprite.Sprite.__init__(self) 
        self.image=pygame.image.load("turret.png") #Loading the gun's image 
        self.rect = self.image.get_rect() #Getting the image's Rect 
        self.rect.x = 240 #Setting the rect's X position 
        self.rect.y = 630 #Setting the rect's Y position 

      def moveGun(self,orientation): 
        '''This function allows the gun to move on the screen. 
         If the orientation is facing left and the gun is 5 pixels 
         away from the wall, the gun is moved left & vice-a-versa''' 
        if orientation=="left" and self.rect.x>5: 
          self.rect.x-=5 
        if orientation=="right" and self.rect.x<(480-self.rect.width): 
          self.rect.x+=5 

    class Projectile(pygame.sprite.Sprite): 
      '''This class sets up the projectile/bullets that are controlled 
       by the user''' 
      def __init__(self,gun): 
        pygame.sprite.Sprite.__init__(self) 
        self.image=pygame.image.load("bullet.png") 
        self.rect=self.image.get_rect() 
        '''The code below places the projectile on top of the gun''' 
        self.rect.x=gun.rect.x+(gun.rect.width/2)-(self.rect.width/2) 
        self.rect.y=gun.rect.y-gun.rect.height 

      def updateProjectile(self): 
        '''This checks if the projectile has reached the top of the screen 
         if it hasn't it will continue to move up. If it has it will be deleted''' 
        if self.rect.y>0-self.rect.height: 
          self.rect.y-=5 
        else: 
          self.kill() 

    class Objects(pygame.sprite.Sprite): 
      '''This class creates the objects, they are loaded from the computer 
       and assigned to variables''' 
      def __init__(self): 
        pygame.sprite.Sprite.__init__(self) 
        self.obj=random.randint(1,3) 
        if self.obj==1: imagefile="capped" 
        if self.obj==2: imagefile="notcapped1" 
        if self.obj==3: imagefile="notcapped2" 
        self.image=pygame.image.load(imagefile+".png") 
        self.rect=self.image.get_rect() 
        self.rect.y=-0-self.rect.height 
        self.rect.x=(random.randint(2,44)*10) 

      def updateProjectile(self,game): 
        '''This function allows for the objects to move down the screen''' 
        if self.rect.y<640: 
          self.rect.y+=7 #This controls the amount of pixels the objects move down thus contrlling the speed 
        else: 
          if self.obj==1: 
            '''Here the code is tracking the users score''' 
            game.score+=10 #This adds 10 to the game's score 
            game.goalNumbers+=1 
          else: 
            game.score-=50 
          self.kill() 

      def shot(self,game): 
        '''This function updates the score as well as removing the objects when they are hit by a projectile''' 
        if self.obj == 1: 
          game.score-=50 
        else: 
          game.score+=10 
        self.kill() 


    # Create initial object instances 
    '''Here i am creating objects based on the classes i created''' 
    game=Game() 
    gun=Gun() 
    sprites=pygame.sprite.Group() 
    sprites.add(gun) 
    obstacles=pygame.sprite.Group() 
    projectiles=pygame.sprite.Group() 
    '''This variable will be used to control when to come out of the loop, i will state when this happens belows''' 
    finish=False 
    clock=pygame.time.Clock() #Initialising the clock 
    tick=0 

    '''This is the start of the main while loop, this loop will continue 
     until the variable 'finish' becomes false''' 
    while finish == False: 
      clock.tick(30) #Loop will run 30 times a second 
      tick+=1 
      screen.fill(bColour) 

      '''Here the main events are being run''' 
      for event in pygame.event.get(): 
        if event.type==pygame.QUIT: 
          '''If the user clicks the exit button, the finish variable is made True, 
           this means that rather than exiting the game, the user's score is displayed after 
           which the game closes''' 
          finish = True 
        if event.type==pygame.KEYDOWN: 
          '''Here the script is checking for KEYDOWN events, these are events triggered 
           when the user presses on a keyboard key. In this case events are triggered when the left, right 
           and space keys are pressed.''' 
          if event.key==pygame.K_LEFT: 
            gun.moveGun("left") #If this is activated the 'orientation' changes to 'left' which shunts the gun 5 pixels to the left 
          if event.key==pygame.K_RIGHT: 
            gun.moveGun("right") #'Orientation' changes to 'right' which shunts the gun 5 pixels to the right 
          if event.key==pygame.K_SPACE: 
            '''This triggers the projectiles function''' 
            projectile=Projectile(gun) 
            projectiles.add(projectile)  

      '''This controls the projectiles and objects moving around the window''' 
      for projectile in projectiles: 
        projectile.updateProjectile() 

      for obstacle in obstacles: 
        obstacle.updateProjectile(game) 

      if tick>60: 
        '''This controls at what rate the objects fall which is now once every two 
         seconds, this is because the loop runs in 30 second intervals and the 
         clock is ticking at 60 seconds''' 
        if len(obstacles)<10: 
          obstacle=Objects() 
          obstacles.add(obstacle) 
        tick=0 

      collisions=pygame.sprite.groupcollide(obstacles,projectiles,False,True) 
      '''Here the script is checking whether the objects are hit by a projectile 
       if they are, the 'shot' function is triggered''' 
      if collisions: 
        for obstacle in collisions: 
          obstacle.shot(game) 

      '''This block of code constantly updates the player's scores'''     
      scoreText=countFont.render('Your current score is:'+str(game.score),True,(255,255,255),bColour) 
      screen.blit(scoreText,(0,620)) 
      statusText=statusFont.render('You have '+str(10-game.goalNumbers)+' more tries',True,(255,255,255),bColour) 
      screen.blit(statusText,(0,10)) 

      '''This code below updates and blits the objects to the screen''' 
      sprites.draw(screen) 
      projectiles.draw(screen) 
      obstacles.draw(screen) 
      pygame.display.flip() 
      if game.goalNumbers>=10: 
        '''This if statement is checking whether 'obj1' has touched the floor 10 times 
         and if it did, the finish variable is made true thus ending the game''' 
        finish=True 

    '''This is the last piece of code visible to the user, 
     what happens here is that the final message showing the final score is shown''' 
    scoreCountHolder=pygame.image.load("scoreframe.png") 
    scoreCountHolder.convert_alpha() 
    left=90 
    top=250 
    screen.blit(scoreCountHolder,(left,top)) 
    countFont=pygame.font.Font(None,52) 
    statusText=countFont.render('Your Score:'+str(game.score),True,bColour,(255,255,255)) 
    screen.blit(statusText,(105,300)) 
    pygame.display.flip() 

    while True: 
      '''This waits for the user to quit the game''' 
      for event in pygame.event.get(): 
        if event.type==pygame.QUIT: 
          sys.exit() 

if __name__ == '__main__': 
     '''The main function being called''' 
     main() 
+2

http://codereview.stackexchange。com /是這類問題的一個更好的地方; StackOverflow更喜歡特定的,非常有針對性的,可重複使用的技術問題(其他人可以輕鬆地從問題及其答案中學習,而不需要通過無關聯的問題涉水)。一個SSCCE和一個更具體的「崩潰」的解釋(你有一個堆棧跟蹤?哪個信號被殺死?等)將使這是一個更合適的SO問題。 –

回答

0

發生什麼事是你放了一個框架,Pygame然後希望你把事件發生在它的事件隊列中。如果你不這樣認爲,那個應用程序就卡住了!

如果您想允許用戶跳過閃屏,則需要在顯示啓動畫面時處理事件。

下面是圍繞這個問題的一種方式,它允許您添加特定的事件處理閃屏:

class SplashScreen(object): 
    def __init__(self): 
     super().__init__() 
     # Use numbers for ordering, make them continuous. 
     self.image_dict = { 
      1: "splash_screen1.png", 
      2: "splash_screen2.png", 
     } 
     # Current image we are on! 
     self.current_index = min(self.image_dict) 
     # Last image 
     self.end_index = max(self.image_dict) 

     # Minimum alpha value 
     self.alpha_min = 0 
     # Maximum alpha value 
     self.alpha_max = 225 
     # Current alpha value 
     self.alpha = self.alpha_min 

     self.show = True 

    # I leave it to you to figure out this function. 
    def get_image(self): 
     image_name = self.image_dict[self.current_index] 
     image = pygame.image.load(image_name) 
     image.set_alpha(self.alpha) 
     self.alpha += 1 
     if self.alpha > self.alpha_max: 
      self.alpha = self.alpha_min 
      self.current_index += 1 
      if self.current_index == self.end_index: 
       self.show = False 
     return image 


splash_screen = SplashScreen() 

while True: 
    # The ever-green event handling loop! 
    for event in pygame.event.get(): 
     ... 

    if splash_screen.show: 
     # Splash screen stuff, one frame at a time 
     background.fill((0, 0, 0)) 
     img = splash_screen.get_image() 
     screen.blit(img, (0, 0)) 
    else: 
     # Game stuff, no need to call display.flip here, called at the end. 
     ... 

    # Called at the end after frame is ready! 
    pygame.display.flip() 

作爲練習
您應該加載和image_dict中添加加載的圖像__init__。每次你刷新它們時,從磁盤上重新加載圖像並不是一個好主意。

+0

我剛試圖將這個遊戲集成到遊戲中並沒有取得成功,遊戲加載完畢,但是按下按鍵時啓動畫面閃爍。我粘貼了我的所有代碼,如果你能看看問題是什麼,我會非常感激。 – SublimeTheMan

+0

你已經理解錯誤的三重引號字符串。你已經在你應該使用評論的地方使用過它們。所有的代碼不需要在一個函數中! **閱讀[PEP-8](http://legacy.python.org/dev/peps/pep-0008/)!**遵循它!相應地更改代碼,然後我會看看我能做些什麼。 (你會理解爲什麼我在閱讀PEP-8並將其應用於此代碼後看到此代碼時說了這些。) – pradyunsg

0

當你有一個pygame應用程序時,你從輸入隊列中獲取所有事件。

操作系統在應用程序刪除它們時將新事件添加到隊列中。

由於您不刪除事件,操作系統認爲您的應用程序凍結。

爲了解決這個問題,你應該叫pygame.event.pump()

從pygame的文檔:

你的遊戲的每一幀,您將需要某種形式的呼叫 事件隊列中。這可以確保您的程序可以在內部與其他操作系統交互 。如果你在遊戲中沒有使用其他的 事件函數,你應該調用pygame.event.pump()到 允許pygame處理內部操作。

如果您的程序始終如此,則此功能不是必需的 通過其他pygame.eventpygame 模塊處理隊列上的事件以便與事件和隊列功能交互。

有一些重要的事情必須在 事件隊列內部處理。主窗口可能需要重新繪製或對系統做出響應。如果您無法撥打長達 長時間的事件隊列,系統可能會決定您的程序已被鎖定。