sur mon tirage, je l'ai fait, mais l'explosion ne manifeste pas une seconde et je ne jette que
Existe-t-il une meilleure façon de faire cela au lieu de dire si la santé de l'ennemi est plus grande, alors ce chargement ceci? Ma classe d'explosion P> for enemyshoot in enemyshooting:
for bullet in bullets:
if bullet.rect.colliderect(enemyshoot.hitbox):
if enemyshoot.health > -8:
enemyshoot.health -= 1
bullets.pop(bullets.index(bullet))
else:
del enemyshooting[one]
3 Réponses :
Vous avez un bon départ. Si rien ne doit se produire pendant que l'explosion se passe, vous pouvez utiliser une commande de sommeil dans votre boucle. >> temps.sleep (0.01) p>
Si l'action doit continuer sur l'écran pendant l'explosion, vous devrez utiliser une minuterie et continuer à revenir à cette fonction après chaque durée pour dessiner la trame suivante. Initialise simplement en utilisant >> T0 = Time.Temps () Avant l'explosion, visitez la fonction lorsque le temps.Time () - T0> 0,01 seconde (par exemple) et réinitialiser t0 = temps () après que chaque image soit tirée. Renvoie une valeur "finie" lorsque l'animation est terminée, vous pouvez ainsi le supprimer de votre liste ennemie. P>
Pourriez-vous m'aider avec ça?
Sûr. Permettez-moi d'écrire un exemple pour vous ce soir après le dîner et je le posterai ici. Vérifiez ce soir ou demain.
Il est assez rare que vous ayez une explosion ou un autre événement dans un match où rien d'autre n'a besoin de se produire pendant cette animation. Un sommeil à l'intérieur d'un match est presque toujours une mauvaise idée puisqu'il bloque toute autre activité de jeu, qui n'est presque jamais une option viable.
dans le dans le Il n'y a vraiment aucune différence entre cela et une autre animation d'objet, autre qu'une fois le cycle terminé l'objet (l'explosion) va une manière. P> __ init __ () code> pour
exploser code> Notez l'heure à laquelle il s'appelle et sauvegardez-le. P>
exploser code> S
dessine () code> Seulement incrément
self.anim_index code> Lorsque suffisant de temps est passé depuis la dernière fois qu'il a été incrémenté (basé sur Sur la valeur de l'heure que vous avez enregistrée dans le
__ init __ () code>). Cela vous permettra d'aller plus lentement à travers les cadres de l'animation explosive. P>
Voici l'exemple que j'ai promis. Remarquez comment l'horloge système et un drapeau sont utilisés pour contrôler la vitesse d'animation afin que différentes actions puissent arriver à l'écran à différentes vitesses. Ce programme est écrit rapide et sale. Il existe des moyens beaucoup plus efficaces de gérer l'animation afin que l'écran soit seulement attiré lorsqu'il est temps de bouger quelque chose, et seules les parties de l'écran qui ont changé sont dessinées et rafraîchies. Mais ne vous inquiétez pas pour ça. La leçon ici est comment utiliser l'horloge pour ralentir votre vitesse d'animation. Quel est le vieil adage? Code maintenant, refacteur plus tard? Mots à vivre par.
import pygame from pygame.locals import * # Pygame Constants such as FULLSCREEN and KEYDOWN. from pygame import Color pygame.init() import time # ============================================================== # Disable Windows Auto-scaling # The windows auto-scaling feature can mess with pygame graphics. # Windows-Specific: Delete if you are not on a Windows machine # If you are on Windows, comment section to see the effect. import ctypes awareness = ctypes.c_int() errorCode = ctypes.windll.shcore.GetProcessDpiAwareness(0, ctypes.byref(awareness)) errorCode = ctypes.windll.shcore.SetProcessDpiAwareness(2) # Awareness levels can be 0, 1 or 2: # =============================================================== # I will base the example on your explode class. If I were writing the # game, I would use a sprite class along with a sprite group to simplify # the code. However, these topics are an entirely different branch of study # so I won't use them in the example. Forgive my quick-and-dirty code. # I don't have your image files, but it looks as though # you have an actual animation to use for your explosion that is # made up of several different frames. We will emulate this for the # sake of our demonstration. class EXPLODE: def create_spark(self): TRANSPARENT = (254,255,255) # You can chose your own transparent color. # Lacking the spark files, let's draw our own. spark_img = pygame.Surface((31,31)) spark_img.fill(TRANSPARENT) spark_img.set_colorkey(TRANSPARENT) spark_rec = spark_img.get_rect() left_center = (spark_rec.left,spark_rec.centery) right_center = (spark_rec.right,spark_rec.centery) top_center = (spark_rec.centerx,spark_rec.top) bottom_center = (spark_rec.centerx,spark_rec.bottom) top_left = spark_rec.topleft top_right = spark_rec.topright bottom_left = spark_rec.bottomleft bottom_right = spark_rec.bottomright pygame.draw.circle(spark_img,Color("yellow"),spark_rec.center,spark_rec.width//2,0) pygame.draw.line(spark_img,Color("indianred"),left_center,right_center,2) pygame.draw.line(spark_img,Color("red"),top_center,bottom_center,2) pygame.draw.line(spark_img,Color("burlywood3"),top_left,bottom_right,3) pygame.draw.line(spark_img,Color("orange"),top_right,bottom_left,3) # Now crop line segments that fall outside the spark circle.. pygame.draw.circle(spark_img,TRANSPARENT,spark_rec.center,spark_rec.width//2+8,8) return spark_img def __init__(self,window,x,y,height,width,color = (255,0,0)): self.window = window # Needed so class can draw to the screen. self.T0 = time.time() # Holds the starting time for the timer. self.x = x self.y = y self.height = height self.width = width self.anim_index = 0 image = self.create_spark() # Standing in for actual animation pages, we scale up the spark image. self.explode = [ image, pygame.transform.scale(image,(image.get_width()*2,image.get_height()*2)), pygame.transform.scale(image,(image.get_width()*4,image.get_height()*4)), pygame.transform.scale(image,(image.get_width()*6,image.get_height()*6)), pygame.transform.scale(image,(image.get_width()*8,image.get_height()*8))] ''' # Or you can load your spark frames as before. self.explode = [ pygame.image.load("spark_01.png"), pygame.image.load("spark_02.png"), pygame.image.load("spark_03.png"), pygame.image.load("spark_04.png"), pygame.image.load("spark_05.png"), pygame.image.load("spark_06.png"), pygame.image.load("spark_07.png")] # All of the loaded images are scaled down to 1/5 their size. self.explode = [pygame.transform.scale(image,(image.get_width()//5,image.get_height()//5)) for image in self.explode] ''' self.rect = image.get_rect() self.direction = "blobright" # <-- I don't know what this is, so I've ignored it. self.anim_index = 0 def draw(self,enemy_rec,anin_speed): # Create an animation method to handle the draw routine. clock = time.time() elapsed_time = clock - self.T0 finish_flg = False if elapsed_time > anin_speed: # Animation Speed Controlled Here!! self.anim_index +=1 self.T0 = time.time() # Reset the start time. if self.anim_index == len(self.explode)-1: finish_flg = True frame = self.explode[self.anim_index] rec = frame.get_rect() rec.center = enemy_rec.center self.window.blit(frame,rec) return finish_flg # The finish flag lets the main program know it can delete the enemy. # ================== MAIN() =================== # ---------------------------------------------- def main(): # By using a 'main()' function, your code will run faster! screen = pygame.display.set_mode((3000,2000),pygame.FULLSCREEN,32) screen_rec = screen.get_rect() screen.fill(Color("steelblue1")) # Declare and initialie an instance of the EXPLODE class. # Only one enemy can blow up at the same time for any give instance # of the class, so you may want each ship to have its own instance # if there is a chance of simultanious explosions. # I wouldn't normally use this aproach, but I wanted to stay # as close as possible to your existing code. explode = EXPLODE(screen,screen_rec.centerx,screen_rec.centery,30,20,Color('blue')) # Let's create some "enemy" units. # You would use an enemy class for this (and for drawing them) # but this example is qick and dirty, so.. Two enemies coming up! # One enemy to blow up when it hits the wall. enemy1_img = pygame.Surface((30,30)) enemy1_rec = enemy1_img.get_rect() enemy1_img.fill(Color("Green")) pygame.draw.rect(enemy1_img,Color("Red"),enemy1_rec,5) # And one 'enemy' to move while the other is blowing up. enemy2_img = enemy1_img.copy() enemy2_rec = enemy2_img.get_rect() # Give enemies screen positions. enemy1_rec.center = (screen_rec.centerx-300, screen_rec.centery-300) enemy2_rec.center = (screen_rec.centerx-800,screen_rec.centery-300) # Create a wall for a ship to crash into. wall_img = pygame.Surface((100,60)) wall_img.fill(Color("Indianred")) wall_rec = wall_img.get_rect() wall_rec.center = screen_rec.center wall_rec = wall_rec.move((400,0)) # Oh, this list is ugly. Forgive me! Used instead of a list of Enemy-Class objects. enemy_list = [[10,enemy1_img,enemy1_rec,(2,1)],[10,enemy2_img,enemy2_rec,(3,0)]] # [Life, Image, Rectangle, Speed] # Ok, the setup is finished. Time for some action! # =============== BODY =================== # ------------------------------------------ anin_speed = 0.3 # You can control explosion speed here! pygame.mouse.set_visible(False) run_cycle = True while run_cycle == True: # There are much better ways to erase images, but this will do for now. screen.fill(Color("steelblue1")) # Erase old sprites. screen.blit(wall_img,wall_rec) # Put the wall back in place. # Because it is bad idea to modify an object being looped through, # we will construct a new list, called 'hold', and copy it back at the end. hold = [] for enmy in enemy_list: life,enemy_img,enemy_rec,speed = enmy if life > 4: screen.blit(enemy_img,enemy_rec) # If enemy is healthy, put it on the screen. enemy_rec = enemy_rec.move(speed) if enemy_rec.colliderect(wall_rec) == True: life = 0 if enemy_rec.left > screen_rec.right+10: # End the program after top ship leaves the screen. run_cycle = False hold.append([life,enemy_img,enemy_rec,speed]) else: # Otherwise draw the explosion. finish_flg = explode.draw(enemy_rec,anin_speed) if finish_flg == False: # If TRUE the enemy is ommitted from the hold list! hold.append(enmy) enemy_list = hold.copy() # And now the possibly modified list is copied back to the enemy_list. pygame.display.flip() # ================ # Main # ---------------- main() # Hint! For technical reasons related to the compiler being able # to control scope and predict variable sizes, keeping your # main body encapsulated in a function like this will improve # efficiency and run speeds.