2014-05-18 4 views
-2

Cela a été modifié, le message original était sur blitting les écrans de démarrage je travaille sur un jeu simple en utilisant pygame, le jeu est presque terminé mais je vais avoir quelques problèmes avec l'écran de démarrage. Le problème actuel est que lorsque le jeu est lancé, les écrans de démarrage sont comme ils le devraient, mais si l'utilisateur clique n'importe où sur l'écran ou tente de quitter le jeu, il se bloque. Est-ce que quelqu'un sait un moyen de contourner ce problème, ce que j'espère, c'est que l'utilisateur serait même capable de quitter le jeu ou même passer l'écran de démarrage pendant qu'ils sont affichés.écran de démarrage Pygame plante jeu

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/est un meilleur endroit pour ce genre de question; StackOverflow préfère des questions techniques spécifiques, très ciblées et réutilisables (où d'autres peuvent facilement apprendre de la question et de ses réponses sans patauger dans un crocodile sans rapport). Un SSCCE et une explication plus spécifique de "crashs" (avez-vous une trace de pile? Quel signal est-il tué avec? Etc) rendrait cette question de SO plus appropriée. –

Répondre

0

Ce qui se passe est que vous mettez un cadre, Pygame vous attend de prendre les événements qui se sont produits dans le même temps de sa file d'attente. Si vous ne pensez pas à l'OS, cette application s'est bloquée!

Vous devez gérer les événements lorsque vous affichez l'écran de démarrage si vous souhaitez autoriser l'utilisateur à ignorer l'écran flash.

est ici un moyen de contourner ce problème, il vous permet d'ajouter des événements spécifiques de manipulation pour écran de démarrage:

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() 

gauche comme un exercice
vous devez charger et ajouter les images chargées dans le image_dict en __init__. Ce n'est pas une bonne idée de continuer à recharger les images du disque chaque fois que vous les blittez.

+0

Je viens d'essayer d'intégrer cela dans le jeu sans succès, le jeu se charge mais l'écran de démarrage se bloque quand une touche est pressée. J'ai collé tout mon code, j'apprécierais vraiment si vous pouviez regarder quel est le problème. – SublimeTheMan

+0

Vous avez mal compris les chaînes à trois guillemets. Vous les avez utilisés dans des endroits où vous devriez utiliser des commentaires. Tout le code n'a pas besoin d'être dans une fonction! ** LISEZ [PEP-8] (http://legacy.python.org/dev/peps/pep-0008/)! ** Suivez-le! Changez le code en conséquence, alors je verrai ce que je peux faire. (Vous comprendrez pourquoi j'ai dit cela quand vous verrez ce code après avoir lu PEP-8 et l'avoir appliqué sur ce code.) – pradyunsg

0

Lorsque vous avez une application pygame, vous prenez tous les événements de la file d'attente d'entrée.

Le système d'exploitation ajoute de nouveaux événements à la file d'attente pendant que votre application les supprime.

Puisque vous ne supprimez pas les événements, le système d'exploitation pense que votre application a gelé.

Pour résoudre ce problème, vous devez appeler pygame.event.pump()

Des Pygame docs:

Pour chaque image de votre jeu, vous aurez besoin de faire une sorte d'appel à la file d'attente d'événements. Cela garantit que votre programme peut interagir en interne avec le reste du système d'exploitation. Si vous n'utilisez pas d'autres fonctions d'événements dans votre jeu, vous devez appeler pygame.event.pump() à pour permettre à pygame de gérer les actions internes.

Cette fonction n'est pas nécessaire si votre programme traite uniformément les événements de la file d'attente via l'autre module pygame.eventpygame pour interagir avec les fonctions d'événements et de files d'attente.

Il existe des éléments importants qui doivent être traités en interne dans la file d'attente d'événements . La fenêtre principale peut devoir être repeinte ou répondre à le système. Si vous ne parvenez pas à appeler la file d'attente trop longtemps, le système peut décider que votre programme est verrouillé.