Ejemplo n.º 1
0
    def __init__(self):
        # set up the window with size and title
        super().__init__(800, 600, 'Asteroids')

        # set the background color
        arcade.set_background_color(ThemeColors.BACKGROUND.color)

        # The player object
        self.player_ship = PlayerShip(400, 300)

        # active bullets
        self.bullets: List[Bullet] = []

        # asteroids
        self.asteroids: List[Asteroid] = []

        # pause state
        self.is_paused = False

        # input states
        self.input = {
            arcade.key.LEFT: False,
            arcade.key.RIGHT: False,
            arcade.key.UP: False,
            arcade.key.DOWN: False,
            arcade.key.SPACE: False
        }
        self.last_frame = 1
        self.spawn_asteroids()
Ejemplo n.º 2
0
 def initialize(self):
     """Skapar alla objekt och nollställer bakgrunder osv."""
     pygame.display.set_caption('Fishwars > Gogo! ^^')        
     # Spel inställningar
     self.paused = False
     self.player_score = 0
     # Skapa grupper för fiender
     self.enemy_grp = pygame.sprite.Group()
     self.bonus_enemy_grp = pygame.sprite.Group()
     self.spawn_bonus_monsterfiskar()
     self.creeps = pygame.sprite.Group()
     # Skapa spelaren
     self.player = PlayerShip(self.screen)
     self.player_grp = pygame.sprite.Group()
     # För att hantera kollisioner
     self.player_grp.add(self.player)
     # Powerups!
     self.powerup_grp = pygame.sprite.Group()
     font = pygame.font.SysFont('Arial Black', 80)
     self.gameOverImage = font.render("GAME OVER", True, (255,0,0))
     self.woo = font.render("YOU WIN! :)", True, (0,255,0))
     self.wooo = font.render("WELL DONE!", True, (0,255,0))
     mindre_font = pygame.font.SysFont('Arial Black', 25)
     self.gameOverRetry = mindre_font.render("Back to main menu? [y/n]", True, (255,0,0))
     # Nollställ alla bakgrunder
     self.bg_x = 0
     self.fg_x = 0
     self.ffg_x = 0
Ejemplo n.º 3
0
class Game(object):
    
    SCREEN_SIZE = SCREEN_WIDTH, SCREEN_HEIGHT = 640, 480
    SCORE_RECT = pygame.Rect(10, 10, 150, 60)
    
    def __init__(self):
        """Startar spelet.
        
        Laddar ljud och grafik.
        
        """
        pygame.init()
        self.screen = pygame.display.set_mode(self.SCREEN_SIZE, 0, 32)
        pygame.display.set_caption('Fishwars > Intro') 
        # Ladda ljud
        pygame.mixer.music.load(os.path.join('sound','soundtrack.mp3'))
        # Volym anges mellan 0 och 1              
        pygame.mixer.music.set_volume(0.5)  
        pygame.mixer.music.play(-1)
        self.coin = pygame.mixer.Sound(os.path.join('sound','102_coin.wav'))
        self.coin.set_volume(0.3)
        self.bubble = pygame.mixer.Sound(os.path.join('sound','bubbla_liten.wav'))
        # Ladda grafik
        self.clock = pygame.time.Clock()
        self.my_font = pygame.font.SysFont('arial', 20)
        self.intropic = pygame.image.load(os.path.join('images','intro.png'))
        self.background_image = pygame.image.load(os.path.join('images','sea-background.jpg'))
        self.foreground_image = pygame.image.load(os.path.join('images','foreground.png'))
        self.fore_foreground_image = pygame.image.load(os.path.join('images','fore_foreground.png'))           
        
    def quit(self):
        """Avslutar spelet."""
        pygame.quit()
        sys.exit()

    def initialize(self):
        """Skapar alla objekt och nollställer bakgrunder osv."""
        pygame.display.set_caption('Fishwars > Gogo! ^^')        
        # Spel inställningar
        self.paused = False
        self.player_score = 0
        # Skapa grupper för fiender
        self.enemy_grp = pygame.sprite.Group()
        self.bonus_enemy_grp = pygame.sprite.Group()
        self.spawn_bonus_monsterfiskar()
        self.creeps = pygame.sprite.Group()
        # Skapa spelaren
        self.player = PlayerShip(self.screen)
        self.player_grp = pygame.sprite.Group()
        # För att hantera kollisioner
        self.player_grp.add(self.player)
        # Powerups!
        self.powerup_grp = pygame.sprite.Group()
        font = pygame.font.SysFont('Arial Black', 80)
        self.gameOverImage = font.render("GAME OVER", True, (255,0,0))
        self.woo = font.render("YOU WIN! :)", True, (0,255,0))
        self.wooo = font.render("WELL DONE!", True, (0,255,0))
        mindre_font = pygame.font.SysFont('Arial Black', 25)
        self.gameOverRetry = mindre_font.render("Back to main menu? [y/n]", True, (255,0,0))
        # Nollställ alla bakgrunder
        self.bg_x = 0
        self.fg_x = 0
        self.ffg_x = 0
        
    def spawn_bonus_monsterfiskar(self):
        """Spawnar fem stycken fiskar man kan få powerups av!
        De kommer i rad med 50 px mellan varje.
        
        """
        random_y = random.randint(0,self.SCREEN_HEIGHT-100)
        x = self.SCREEN_WIDTH
        for i in range(5):
            self.bonus_enemy_grp.add(Enemy(screen=self.screen,
                               img_filename=os.path.join('images','monsterfisk.png'),
                               init_position=(x, random_y) 
                               ))
            # Nästa fiende lite åt sidan
            x += 50

    def spawn_monster(self, antal, pref=None, lila=None):
        """Spawnar vanliga mobs.
        
        @param antal: Hur många mobs
        @param pref: Vilken typ 
        
        """
        x = self.SCREEN_WIDTH
        all_monsters = [os.path.join('images','dygaddaa.png'),
                        os.path.join('images','taggfisk.png'),
                        os.path.join('images','monsterfisk.png'),
                        os.path.join('images','taggfisk-blue.png'),
                        os.path.join('images','taggfisk-green.png')]
        if pref:
            img = all_monsters[pref]
        elif lila:
            img = os.path.join('images','taggfisk-lila.png')
        else:
            img = random.choice(all_monsters)
        for i in range(antal):
            random_y = random.randint(0,self.SCREEN_HEIGHT-100)
            temp = Enemy(screen=self.screen,
                                   img_filename=img,
                                   init_position=(x, random_y) 
                                   )
            temp.set_speed(random.randint(-7, -3))
            self.enemy_grp.add(temp)
            # Nästa fiende lite åt sidan
            x += 60         
                
    def spawn_creeps(self):
        """Spawnar ett studsande kryp.
        Random riktning vid initialisering.
        
        """
        random_y = random.randint(0,self.SCREEN_HEIGHT-100)
        self.creeps.add(Creep(self.screen,
                    os.path.join('images','new_creep.png'),
                    # Position
                    (   self.SCREEN_WIDTH, random_y),
                    # Riktning
                    (   random.choice([-1, -0.7]),
                        random.choice([-0.7, 0, 0.7])),
                    # Hastighet
                    0.1))        

    def draw_instructions(self):
        """Ritar upp spelets instruktioner.
        Aktiveras mha space-tangenten vid startskärmen.        
        
        """
        INSTR_RECT = pygame.Rect(20, 240, 200, 205)
        # Rita den vit-transparenta lådan
        transparent_box = pygame.Surface((INSTR_RECT.w, INSTR_RECT.h))
        transparent_box.fill(pygame.Color(255, 255, 255))
        transparent_box.set_alpha(50)
        self.screen.blit(transparent_box, INSTR_RECT)
        # Rita instruktionerna
        my_font = pygame.font.SysFont('arial', 20)        
        INSTR_RECT = INSTR_RECT.move(10, 5)
        instructions = ['Instructions:',
                        '[w] up',
                        '[a] left',
                        '[s] right',
                        '[d] down',
                        '[Enter] shoot',
                        '[Space] pause',
                        '[Escape] exit']
        for instruction in instructions:
            msg = my_font.render(instruction, True, pygame.Color('white'))
            self.screen.blit(msg, INSTR_RECT)
            # Flytta positionen nedåt för nästa instruktion
            INSTR_RECT = INSTR_RECT.move(0, msg.get_height())

    def draw_rimmed_box(self, box_rect, box_color, 
                        rim_width=0, 
                        rim_color=pygame.Color('black')):
        """ Ritar en streckad låda. Strecket ritas utanför lådan."""
        if rim_width:
            # Räkna ut streckets kanter
            rim_rect = pygame.Rect(box_rect.left - rim_width,
                            box_rect.top - rim_width,
                            box_rect.width + rim_width * 2,
                            box_rect.height + rim_width * 2)
            # Och rita strecket
            pygame.draw.rect(self.screen, rim_color, rim_rect)
        # Därefter rita själva lådan
        pygame.draw.rect(self.screen, box_color, box_rect)    

    def draw_score(self):
        """Ritar upp spelarens score i vänstra hörnet."""
        score = 'Score: ' + str(self.player_score)
        score_msg = self.my_font.render(score, True, pygame.Color('white'))
        self.screen.blit(score_msg, self.SCORE_RECT)

    def intro(self):
        """Spelets intro loop.
        
        Spelar musik. Visar logo, om man trycker space visas 
        instruktioner. Enter för att starta spelet!
        
        """
        show_instructions = False
        while True:
            # Sätt spelet till 30 FPS
            time_passed = self.clock.tick(30)
            # Kontrollera spelarens input        
            for event in pygame.event.get():
                if event.type == pygame.QUIT:
                    self.quit()    
                elif event.type == pygame.KEYDOWN: 
                    if event.key == pygame.locals.K_ESCAPE: 
                        self.quit() 
                    elif event.key == pygame.K_SPACE: 
                        show_instructions = not show_instructions
                    elif event.key == pygame.locals.K_RETURN:
                        self.coin.play()
                        # Den spelar långsamt.. så vänta lite
                        time.sleep(1)
                        self.initialize()
                        self.run()
            # Rita introbilden
            self.screen.blit(self.intropic, (0, 0))
            # Om spelaren vill se instruktiner, rita de över
            if show_instructions:
                self.draw_instructions()
            # Uppdatera skärmen sist
            pygame.display.flip()
        
    def run(self):
        """Spelets main loop."""
        timer = 0
        bosstimer = 0
        creep_timer = 0
        self.bosstime = False
        self.bonus_active = False
        self.bonus_done = False
        self.big_bad_boss = None
        self.phase_two = False
        self.second_boss = False
        self.other_boss = None
        bonus_timer = 0 
        
        while True:
            # Limit frame speed to 30 FPS
            time_passed = self.clock.tick(30) 
            timer += time_passed
            bosstimer += time_passed
            bonus_timer += time_passed
            creep_timer += time_passed
            
            # Kolla spel-timers
            # TODO! NGT SNYGGARE UTAN ALLA IFSATSER!
            # Gör random monster varje sekund!
            if(timer>1000 and not self.bosstime and not self.second_boss):
                r = random.randint(0,100)
                # Chans att nytt monster spawnar varje sekund!
                if(r<65):
                    self.spawn_monster(1)
                    timer = 0
            # Bonus efter X sekunder
            if(bonus_timer>13000 and not self.player.power==5 and not self.bosstime):
                self.spawn_bonus_monsterfiskar();
                bonus_timer = 0
            # BOSS EFTER 20 SEKUNDER
            if(bosstimer>20000 and not self.bosstime and not self.phase_two):
                y = 50
                x = self.SCREEN_WIDTH
                self.bosstime = True
                self.big_bad_boss = BossTaggfiskEnemy(screen=self.screen,
                                   img_filename=os.path.join('images','taggfisk-mindre.png'),
                                   init_position=(x, y))
                self.enemy_grp.add(self.big_bad_boss)
                bosstimer = 0
            # IF BOSS MAKE EXTRA MOBS
            if(timer>1000 and self.bosstime):
                r = random.randint(0,100)
                if(r<25):
                    self.spawn_monster(1, 1)
                    timer = 0
            # CHECK IF BOSS DEAD
            if(self.big_bad_boss and self.big_bad_boss.is_dead() and self.bosstime):
                self.bosstime = False
                self.phase_two = True
                bosstimer = 0
            # Och x sekunder efter första bossen dör kommer nästa!
            if bosstimer > 20000 and self.phase_two and not self.second_boss:
                self.second_boss = True
                y = 50
                x = self.SCREEN_WIDTH
                self.other_boss = BossBlackfiskEnemy(screen=self.screen,
                                   img_filename=os.path.join('images','bigger_blackfisk.png'),
                                   init_position=(x, y))
                self.enemy_grp.add(self.other_boss)   
            if creep_timer>1000 and self.phase_two and not self.second_boss:
                r = random.randint(0,100)
                # 25% chans att nytt monster spawnar varje sekund!
                if(r<25):
                    self.spawn_creeps()
                    creep_timer = 0
                r_lila = random.randint(0, 100)
                if(r_lila<5):
                    self.spawn_monster(1, lila=True)       
            if self.other_boss:
                if self.other_boss.is_dead():
                    self.endloop()        
                
            # KONTROLLERA PLAYER INPUT ----------------------------------------    
            for event in pygame.event.get():
                if event.type == pygame.QUIT:
                    self.quit()    
                elif event.type == pygame.KEYDOWN: 
                    # Om Escape - avsluta spelet
                    if event.key == pygame.locals.K_ESCAPE: 
                        self.quit()
                    # Skeppets rörelse
                    elif event.key == pygame.locals.K_a: 
                        self.player.x = -6
                    elif event.key == pygame.locals.K_d: 
                        self.player.x = 6
                    elif event.key == pygame.locals.K_w: 
                        self.player.y = -6 
                    elif event.key == pygame.locals.K_s: 
                        self.player.y = 6 
                    # Om return - Spela ljud och avfyra vapnet!                        
                    elif event.key == pygame.locals.K_RETURN:
                        self.bubble.play()
                        self.player.fire_weapon()
                # Om uppknapp - sluta röra skeppet                             
                elif event.type == pygame.locals.KEYUP:
                    if event.key == pygame.locals.K_a:
                        self.player.x = 0
                    elif event.key == pygame.locals.K_d:
                        self.player.x = 0
                    elif event.key == pygame.locals.K_w:
                        self.player.y = 0
                    elif event.key == pygame.locals.K_s:
                        self.player.y = 0
   
            # UPPDATERA ALLA OBJEKT -------------------------------------------
            self.player_grp.update()
            self.player.playershots_grp.update()
            self.powerup_grp.update(time_passed)
            self.bonus_enemy_grp.update(time_passed)            
            self.enemy_grp.update(time_passed)
            if self.big_bad_boss:
                self.big_bad_boss.shot_grp.update(time_passed)
            if self.other_boss:
                self.other_boss.shot_grp.update(time_passed)                
            for creep in self.creeps:
                creep.update(time_passed)                
            # Förflytta bakgrunderna x pixlar vänster/uppdatering
            self.bg_x -= 0.5
            self.fg_x -= 2
            self.ffg_x -= 2.5
            # Om hela bakgrunden spelats upp, börja om
            # !TODO VERKAR INTE FUNGERA!
            if(self.bg_x==-4167):
                print "change bg"
                self.bg_x = 0
            if(self.fg_x==-8000):
                print "change fg"
                self.fg_x = 0
               
            # KONTROLLERA KOLLISIONER ----------------------------------------
            for hit in pygame.sprite.groupcollide(self.player_grp, self.enemy_grp, 1, 1):
                self.game_over()
            for hit in pygame.sprite.groupcollide(self.player_grp, self.bonus_enemy_grp, 1, 1):
                self.game_over()
            for hit in pygame.sprite.groupcollide(self.player_grp, self.creeps, 1, 1):
                self.game_over()                
            if self.big_bad_boss:
                for hit in pygame.sprite.groupcollide(self.player_grp, self.big_bad_boss.shot_grp, 1, 1):
                    self.game_over()
            if self.other_boss:
                for hit in pygame.sprite.groupcollide(self.player_grp, self.other_boss.shot_grp, 1, 1):
                    self.game_over()                    
            # Kontrollera kollisioner fiende/player-skott
            for enemy in pygame.sprite.groupcollide(self.enemy_grp, self.player.playershots_grp, 0, 1):
                self.player_score += 1000
                enemy.decrease_health(1)
            for enemy in pygame.sprite.groupcollide(self.creeps, self.player.playershots_grp, 0, 1):
                self.player_score += 1000
                enemy.decrease_health(1)
            # Kontrollera kollisioner bonus/player-skott
            for enemy in pygame.sprite.groupcollide(self.bonus_enemy_grp, self.player.playershots_grp, 0, 1):
                # Ge spelaren poäng
                self.player_score += 1000
                # Och skada fienden
                enemy.decrease_health(1)
                if len(self.bonus_enemy_grp)==1 and not self.bonus_active:
                    self.bonus_active = True
                    self.powerup_grp.add(Powerup(self.screen, (enemy.rect.x, enemy.rect.y)))
            # Kontrollera kollisioner bonus/spelaren
            for powerup in pygame.sprite.groupcollide(self.powerup_grp, self.player_grp, 1, 0):
                powerup.powerup_sound.play()   
                self.bonus_active = False
                self.player.power += 2
                
            # RITA ALLA OBJEKT ------------------------------------------------ 
            # Bakgrunden måste ritas först = längst bak
            self.screen.blit(self.background_image, (self.bg_x, 0))
            self.screen.blit(self.foreground_image, (self.fg_x, 0))
            self.player_grp.draw(self.screen)
            self.powerup_grp.draw(self.screen)
            for creep in self.creeps:
                creep.draw()
            for enemy in self.bonus_enemy_grp:
                enemy.draw()            
            for enemy in self.enemy_grp:
                enemy.draw()
            if self.big_bad_boss:
                for shot in self.big_bad_boss.shot_grp:
                    shot.rita()
            if self.other_boss:
                for shot in self.other_boss.shot_grp:
                    shot.rita()                    
            self.player.playershots_grp.draw(self.screen)
            # Växter i förgrunden! ^__^
            self.screen.blit(self.fore_foreground_image, (self.ffg_x, 0))
            self.draw_score()            
            
            # BOUNDARY TEST            
            #self.player.show_boundary()
            #for shot in self.playershots_grp:
            #    shot.show_boundary()
            #for enemy in self.enemy_grp:
            #   enemy.show_boundary()
            
            # Flippa displayen
            pygame.display.flip()

    def game_over(self):
        """Game over loop."""
        while True:
            # Kontrollera player inputs       
            for event in pygame.event.get():
                if event.type == pygame.QUIT:
                    self.quit()    
                elif event.type == pygame.KEYDOWN: 
                    # Om Escape - avsluta spelet
                    if event.key == pygame.locals.K_ESCAPE: 
                        self.quit()
                    elif event.key == pygame.locals.K_y:
                        self.intro()
                    elif event.key == pygame.locals.K_n:
                        self.quit()                 
            self.screen.blit(self.gameOverImage, (45,170))
            self.screen.blit(self.gameOverRetry, (135,280))
            pygame.display.flip()    
            
    def endloop(self):
        """End loop."""
        while True:
            # Kontrollera player inputs       
            for event in pygame.event.get():
                if event.type == pygame.QUIT:
                    self.quit()    
                elif event.type == pygame.KEYDOWN: 
                    # Om Escape - avsluta spelet
                    if event.key == pygame.locals.K_ESCAPE: 
                        self.quit()
                    elif event.key == pygame.locals.K_y:
                        self.intro()
                    elif event.key == pygame.locals.K_n:
                        self.quit()                 
            self.screen.blit(self.woo, (45,100))
            self.screen.blit(self.wooo, (45,190))
            pygame.display.flip()         
Ejemplo n.º 4
0
class AsteroidsGame(arcade.Window):
    def __init__(self):
        # set up the window with size and title
        super().__init__(800, 600, 'Asteroids')

        # set the background color
        arcade.set_background_color(ThemeColors.BACKGROUND.color)

        # The player object
        self.player_ship = PlayerShip(400, 300)

        # active bullets
        self.bullets: List[Bullet] = []

        # asteroids
        self.asteroids: List[Asteroid] = []

        # pause state
        self.is_paused = False

        # input states
        self.input = {
            arcade.key.LEFT: False,
            arcade.key.RIGHT: False,
            arcade.key.UP: False,
            arcade.key.DOWN: False,
            arcade.key.SPACE: False
        }
        self.last_frame = 1
        self.spawn_asteroids()

    def spawn_asteroids(self):
        w, h = self.get_size()
        center_x = w / 2
        center_y = h / 2
        spawn_radius = w * 0.35

        for i in range(0, 5):
            angle = round(math.radians(random.randint(0, 360)), 2)
            offset_x = math.sin(angle) * spawn_radius
            offset_y = math.cos(angle) * spawn_radius
            spawn_x = center_x + offset_x
            spawn_y = center_y + offset_y
            new_asteroid = Asteroid(spawn_x, spawn_y, AsteroidSize.LARGE)
            self.asteroids.append(new_asteroid)

    def on_draw(self):
        """ Handle drawing here. """
        arcade.start_render()

        # draw player if alive
        if self.player_ship.alive:
            self.player_ship.draw()

        # draw bullets
        for bullet in self.bullets:
            bullet.draw()

        # draw asteroids
        for asteroid in self.asteroids:
            asteroid.draw()

        # draw framerate in bottom-left corner
        arcade.draw_text(f'FPS: {round(1.0 / self.last_frame, 1)}', 5, 5,
                         arcade.color.BLACK, 12)

    def on_update(self, delta):
        self.last_frame = delta
        screen_width, screen_height = self.get_size()

        # if game is paused, we're done already
        if self.is_paused:
            return

        # only update the player ship if it is alive
        if self.player_ship.alive:
            # apply user movement input
            if self.input[arcade.key.LEFT]:
                self.player_ship.add_rotation(1, delta)
            if self.input[arcade.key.RIGHT]:
                self.player_ship.add_rotation(-1, delta)
            if self.input[arcade.key.UP]:
                self.player_ship.add_acceleration()

            # update player cooldowns
            self.player_ship.update(delta)

            # if the player has asked to fire and can, then create a bullet:
            if self.input[arcade.key.SPACE] and self.player_ship.fire():
                b = Bullet((self.player_ship.x, self.player_ship.y),
                           self.player_ship.rotation)
                self.bullets.append(b)

            # apply ship movement
            self.player_ship.apply_velocity(delta)

            # keep the ship on the screen
            if self.player_ship.x < 0:
                self.player_ship.x = screen_width
            elif self.player_ship.x > screen_width:
                self.player_ship.x = 0
            if self.player_ship.y < 0:
                self.player_ship.y = screen_height
            elif self.player_ship.y > screen_height:
                self.player_ship.y = 0

        # update bullets and remove dead ones
        for bullet in self.bullets:
            bullet.update(delta)
        self.bullets = [bullet for bullet in self.bullets if bullet.alive]

        # update asteroids
        for asteroid in self.asteroids:
            asteroid.update(delta, screen_width, screen_height)
            # handle collisions with bullets
            for bullet in self.bullets:
                if not bullet.alive:
                    continue
                # TODO: narrow down this loop based on distance from asteroid
                if asteroid.collides_with_point(bullet.x, bullet.y):
                    bullet.alive = False
                    asteroid.alive = False
                    if asteroid.size != AsteroidSize.SMALL:
                        for i in range(0, 3):
                            smaller_asteroid = Asteroid(
                                asteroid.x, asteroid.y,
                                AsteroidSize(asteroid.size - 1))
                            self.asteroids.append(smaller_asteroid)
                    break

            if not asteroid.alive:
                continue

            # check each of the player ships's points for intersection with the asteroid
            if self.player_ship.alive:
                for ship_point in self.player_ship.rotated_points():
                    if asteroid.collides_with_point(ship_point[0],
                                                    ship_point[1]):
                        asteroid.alive = False
                        # TODO: handle player lives
                        self.player_ship.alive = False
                        break

        self.asteroids = [
            asteroid for asteroid in self.asteroids if asteroid.alive
        ]

    def on_key_press(self, key, modifiers):
        if key == arcade.key.ESCAPE:
            # kill the game
            arcade.close_window()
        elif key == arcade.key.F3:
            # pause the game
            self.is_paused = not self.is_paused

        # apply input
        if key in self.input:
            self.input[key] = True

    def on_key_release(self, key, modifiers):
        if key in self.input:
            self.input[key] = False