Space Invaders project

前端 未结 2 1042
刺人心
刺人心 2020-12-10 23:11

I\'m making a game similar to Space Invaders. Is there a way to check for an event like shooting less frequently? Right now, if you press space bar fast enough the top shot

相关标签:
2条回答
  • 2020-12-10 23:20

    A few tips: Your first blit is pointless. Since you already start bliting in the while loop.

    You could store ship_left and ship_top in a tuple, so there will be less clutter in your code.

    Use functions, and give them meaningful names, this way it will be easier for you and others that read your code.

    One more thing - your movement function takes in a parameter, but does not do anything with it. It does use an event, so you should pass this instead.

    Back to your question. This is how it is normally solved in games like these.

    You make a list of missiles. Each KEYDOWN event would create a new missile, and append it to the list. If let's say there are 10 missiles in the list, the missile is not created.

    It best to create a separate class Missile. For each object in the list, you should do the following:

    1. Draw based on its position.
    2. Update - Move the missiles closer to the top.
    3. Check if any missiles are out of the screen, if so remove them.

    This way, there is no need for a timer, and you can limit the shots so that the player does not spam the keyboard. If you really want to limit it based on time, you can use the return value of pygame.Clock.tick() to increment a time_since_last_shot variable. Each keypress would check if the value is big enough, and if so shoot and reset the variable back to 0.

    0 讨论(0)
  • 2020-12-10 23:27

    You could use counter to count loops in main loop since last shot - if it is bigger than (for example) 10 than you clear counter and shoot - in more complicated game you could use pygame.time.get_ticks() to count time in milliseconds since last shot

    Another method is to fire shot only if you have less than 2 shot on screen.

    EDIT:

    Your code would look like this - simple example. Use keys: LEFT, RIGHT, SPACE, P (for pause).

    There is still much to do. For example better collision detect - pygame.sprite.collide_rect()

    (I attached my bitmaps at the end)

    #-----!!!!SPACE INVADERS!!!!-----
    
    import pygame
    from pygame.locals import *
    
    #----------------------------------------------------------------------
    
    class Ship():
    
        def __init__(self, screen_rect):
    
            #self.image = pygame.image.load("spaceship.png")
            self.image = pygame.image.load("ball1.png")
            self.image = pygame.transform.scale(self.image, (100,50))
    
            self.rect = self.image.get_rect()
    
            # put ship bottom, center x 
            self.rect.bottom = screen_rect.bottom 
            self.rect.centerx = screen_rect.centerx
    
            self.move_x = 0
    
            self.shots = []
            self.shots_count = 0
    
            self.max_shots = 2
    
        #--------------------
    
        def event_handler(self, event):
    
            #print "debug: Ship.event_handler"
    
            if event.type == KEYDOWN:
                if event.key == K_LEFT:
                    self.move_x = -5
                elif event.key == K_RIGHT:
                    self.move_x = 5
                elif event.key == K_SPACE:
                    if len(self.shots) < self.max_shots:
                        self.shots.append(Bullet(self.rect.centerx, self.rect.top))
    
            if event.type == KEYUP:
                if event.key in (K_LEFT, K_RIGHT):
                    self.move_x = 0
    
        def update(self):
    
            #print "debug: Ship.update: move_x", self.move_x
            self.rect.x += self.move_x
    
            for s in self.shots:
                s.update()
    
            for i in range(len(self.shots)-1, -1, -1):
                print "debug: Ship.update: testing bullet ", i
                if not self.shots[i].is_alive:
                    print "debug: Ship.update: removing bullet ", i
                    del self.shots[i]
    
        #--------------------
    
        def draw(self, screen):
    
            #print "debug: Ship.draw"
    
            screen.blit(self.image, self.rect.topleft)
    
            for s in self.shots:
                s.draw(screen)
    
        def bullet_detect_collison(self, enemy_list):
    
            for s in self.shots:
                for e in enemy_list:
                    if pygame.sprite.collide_circle(s, e):
                        s.is_alive = False
                        e.is_alive = False
    
    #----------------------------------------------------------------------
    
    class Bullet():
    
        def __init__(self, x, y):
    
            #self.image = pygame.image.load("SingleBullet.png")
            self.image = pygame.image.load("ball2.png")
            self.image = pygame.transform.scale(self.image, (25,25))
    
            self.rect = self.image.get_rect()
            self.rect.centerx = x
            self.rect.centery = y
    
            self.is_alive = True
    
        #--------------------
    
        def update(self):
    
            self.rect.y -= 15
    
            if self.rect.y < 0:
                self.is_alive = False
    
        #--------------------
    
        def draw(self, screen):
    
            screen.blit(self.image, self.rect.topleft)
    
    #----------------------------------------------------------------------
    
    class Enemy():
    
        def __init__(self, x, y):
    
            self.image = pygame.image.load("ball3.png")
    
            self.rect = self.image.get_rect()
            self.rect.centerx = x
            self.rect.centery = y
    
            self.is_alive = True
    
        #--------------------
    
        def update(self):
    
            self.rect.y += 1
    
            #~ if self.rect.y < 0:
                #~ self.is_alive = False
    
        #--------------------
    
        def draw(self, screen):
    
            screen.blit(self.image, self.rect.topleft)
    
    #----------------------------------------------------------------------
    
    class Game():
    
        def __init__(self):
    
            pygame.init()
    
            w, h = 800, 800
            self.screen = pygame.display.set_mode((w,h))
    
            pygame.mouse.set_visible(False)
    
            self.ship = Ship(self.screen.get_rect())
    
            self.enemies = []
    
            for i in range(100, 800, 100):
                self.enemies.append(Enemy(i, 100))
    
            font = pygame.font.SysFont("", 72)
            self.text_paused = font.render("PAUSED", True, (255, 0, 0))
            self.text_paused_rect = self.text_paused.get_rect(center=self.screen.get_rect().center)
    
        #-----MAIN GAME LOOP-----
    
        def run(self):
    
            clock = pygame.time.Clock()
    
            RUNNING = True
            PAUSED = False
    
            while RUNNING:
    
                clock.tick(30)
    
                #--- events ---
    
                for event in pygame.event.get():
    
                    if event.type == pygame.QUIT:
                        RUNNING = False
    
                    if event.type == KEYDOWN:
                        if event.key == K_ESCAPE:
                            RUNNING = False
    
                        if event.key == K_p:
                            PAUSED = not PAUSED
    
                    if not PAUSED:
                        self.ship.event_handler(event)
    
                #--- changes ---
                if not PAUSED:
    
                    self.ship.update()
    
                    for e in self.enemies:
                        e.update()
    
                    self.ship.bullet_detect_collison(self.enemies)
    
                    for i in range(len(self.enemies)-1, -1, -1):
                        print "debug: Ship.update: testing bullet ", i
                        if not self.enemies[i].is_alive:
                            print "debug: Ship.update: removing bullet ", i
                            del self.enemies[i]
    
                #--- draws ---
    
                self.screen.fill((0,0,0))
    
                self.ship.draw(self.screen)
    
                for e in self.enemies:
                    e.draw(self.screen)
    
                if PAUSED:
                    self.screen.blit(self.text_paused, self.text_paused_rect)
    
                pygame.display.update()
    
            #--- quit ---
    
            pygame.quit()
    
    #---------------------------------------------------------------------
    
    Game().run()
    

    ball1.png enter image description here ball2.png enter image description here ball3.png enter image description here

    Screenshot enter image description here

    0 讨论(0)
提交回复
热议问题