[Pygame series] new version of thunder duel. The enemy and players have unique skills and burst fire ~ (upgraded version)

Posted by Stevis2002 on Wed, 22 Dec 2021 01:36:27 +0100

Introduction

"Flying in the blue sky is everyone's dream, but the dream must have a starting point. Now the starting point is in front of you“

- Gu Muzi

Hello, hello! Hello, I'm kimiko~

Update online every day. If you have time today, please upgrade the source code of the last aircraft war!

Lightning on the computer when I was a child, and then the plane war on wechat. Please raise your hand if you haven't played the plane war game! The mysterious sky is still

What will happen? You write it! Then, follow me to officially start today's journey~

 

text

Game ideas:

In the last issue of the "space meteorite VS large fighter duel" game, this time the function will increase the difficulty: direct aircraft

During the battle, the enemy and bullets will be added.

Rules of the game:

The upgraded thunder fighter duel is a classic flight air combat game. Players will have a wonderful and exciting air combat

Playing method, combined with high-definition game image quality, will definitely bring you an extraordinary experience, with a powerful firepower system and cool

Shooting effects, come and experience it! Complete project source code didi I I get HA are free to share~

1, In preparation

1) Picture material

2) Sound effect material (essential)

3) Environment installation

The environment used in this paper is as follows: Python 3, pychar, Pygame game module and some self-contained modules.

Module installation:

pip install +Module name or Douban image source pip install -i https://pypi.douban.com/simple / + module name

2, Code demonstration

1) Main program

#Import module
import pygame
import random
from pygame.locals import *
from os import path

#######################################Basic parameter configuration#######################################

#Get picture library and sound library path
img_dir = path.join(path.dirname(__file__),'pic')
sound_folder = path.join(path.dirname(__file__),'sounds')

#Define the game window, player's blood bar size, game running speed, artillery duration and other parameters
WIDTH = 480
HEIGHT = 600
FPS = 60
POWERUP_TIME = 5000
BAR_LENGTH = 100
BAR_HEIGHT = 10

#Define RGB parameters of white, black, red, green, blue and yellow 
WHITE = (255, 255, 255)
BLACK = (0, 0, 0)
RED = (255, 0, 0)
GREEN = (0, 255, 0)
BLUE = (0, 0, 255)
YELLOW = (255, 255, 0)

#Initialize the pygame module, create a game window, name the game window, and create a tracking time object
pygame.init()
pygame.mixer.init()  #Initialize sound
screen = pygame.display.set_mode((WIDTH,HEIGHT))
pygame.display.set_caption("Aircraft Battle")
clock = pygame.time.Clock()

#Define text font
font_name = pygame.font.match_font('arial')

#######################################Load picture#######################################

#Load the background picture of the game in progress
background = pygame.image.load(path.join(img_dir,'starfield.png')).convert()
background = pygame.transform.scale(background,(WIDTH,1536))
height = -936

#Load player pictures
player_img = pygame.image.load(path.join(img_dir,'player.png')).convert()
player_mini_img = pygame.transform.scale(player_img,(25, 19))
player_mini_img.set_colorkey(BLACK)

#Load player shell and missile pictures
bullet_img = pygame.image.load(path.join(img_dir,'bullet.png')).convert()
missile_img = pygame.image.load(path.join(img_dir,'missile.png')).convert_alpha()

#Loading pictures of enemy shells
enemies_bullet_img = pygame.image.load(path.join(img_dir,'enemies_bullet.png')).convert()

#Load shield and lightning pictures
powerup_images = {}
powerup_images['shield'] = pygame.image.load(path.join(img_dir, 'shield.png')).convert()
powerup_images['gun'] = pygame.image.load(path.join(img_dir, 'bolt.png')).convert()

#Load pictures of enemy aircraft and volcanic rocks
enemies_images = []
lava_images = []
#enemy airplane
enemies_list = [
    'enemies1.png',
    'enemies2.png',
    'enemies3.png'
]
#Volcanic rock
lava_list = [
    'lava_med.png',
    'lava_small1.png',
    'lava_small2.png',
    'lava_tiny.png'
]
for image in enemies_list:
    enemies_img = pygame.image.load(path.join(img_dir,image)).convert()
    enemies_img = pygame.transform.scale(enemies_img,(80, 60))
    enemies_images.append(enemies_img)
for image in lava_list:
    lava_images.append(pygame.image.load(path.join(img_dir,image)).convert())

#Load explosion picture
explosion_anim = {}
explosion_anim['lg'] = []
explosion_anim['sm'] = []
explosion_anim['player'] = []
for i in range(9):
    #Enemy aircraft and volcanic rock explosion
    filename = 'regularExplosion0{}.png'.format(i)
    img = pygame.image.load(path.join(img_dir,filename)).convert()
    img.set_colorkey(BLACK)
    #big bang    
    img_lg = pygame.transform.scale(img,(75,75))
    explosion_anim['lg'].append(img_lg)
    #Small explosion
    img_sm = pygame.transform.scale(img,(32,32))
    explosion_anim['sm'].append(img_sm)
    #Player explosion
    filename = 'sonicExplosion0{}.png'.format(i)
    img = pygame.image.load(path.join(img_dir,filename)).convert()
    img.set_colorkey(BLACK)
    explosion_anim['player'].append(img)

#######################################Load sound#######################################

#Loading shells and missile launching sound
shooting_sound = pygame.mixer.Sound(path.join(sound_folder,'pew.wav'))
missile_sound = pygame.mixer.Sound(path.join(sound_folder,'rocket.ogg'))

#Load the explosion sound of enemy aircraft and volcanic rocks
expl_sounds = []
for sound in ['expl3.wav', 'expl6.wav']:
    expl_sounds.append(pygame.mixer.Sound(path.join(sound_folder,sound)))
#Volume down 
pygame.mixer.music.set_volume(0.2)

#Load player explosion sound
player_die_sound = pygame.mixer.Sound(path.join(sound_folder,'rumble1.ogg'))

#######################################Function area#######################################

#Game initial interface and preparation start interface functions
def main_menu():
    global screen
    #Load the background music of the initial game interface
    menu_song = pygame.mixer.music.load(path.join(sound_folder,"menu.ogg"))
    #Loop Playback
    pygame.mixer.music.play(-1)
    #Load the background picture of the initial game interface
    title = pygame.image.load(path.join(img_dir,"main.png")).convert()
    title = pygame.transform.scale(title,(WIDTH, HEIGHT),screen)
    screen.blit(title,(0,0))
    pygame.display.update()
    #Detect player operation events
    while True:
        ev = pygame.event.poll()
        if ev.type == pygame.KEYDOWN:
            if ev.key == pygame.K_RETURN:
                break
        elif ev.type == pygame.QUIT:
                pygame.quit()
                quit()
        else:
            draw_text(screen, "Press [ENTER] To Begin", 30, WIDTH/2, HEIGHT/2)
            draw_text(screen, "[A] ←  [S] ↓  [D] →  [W] ↑", 30, WIDTH/2, 2*HEIGHT/3) 
            draw_text(screen, "[Space] fire", 30, WIDTH/2, 3*HEIGHT/4)           
            pygame.display.update()
    #Load ready sound
    ready = pygame.mixer.Sound(path.join(sound_folder,'getready.ogg'))
    ready.play()
    #Loading ready to start interface background color and text
    screen.fill(BLACK)
    draw_text(screen, "GET READY!", 40, WIDTH/2, HEIGHT/3)
    pygame.display.update()

#Set text property function
def draw_text(surf,text,size,x,y):
    #Define text parameters
    font = pygame.font.Font(font_name,size)
    text_surface = font.render(text,True,WHITE)
    text_rect = text_surface.get_rect()
    text_rect.midtop = (x,y)
    surf.blit(text_surface,text_rect)

#Set player's health bar attribute function
def draw_shield_bar(surf,x,y,pct):
    pct = max(pct,0)
    fill = (pct/100)*BAR_LENGTH
    outline_rect = pygame.Rect(x,y,BAR_LENGTH,BAR_HEIGHT)
    fill_rect = pygame.Rect(x,y,fill,BAR_HEIGHT)
    pygame.draw.rect(surf,GREEN,fill_rect)
    pygame.draw.rect(surf,WHITE,outline_rect,2)

#Set player's life attribute function
def draw_lives(surf,x,y,lives,img):
    for i in range(lives):
        img_rect = img.get_rect()
        img_rect.x = x+30*i
        img_rect.y = y
        surf.blit(img,img_rect)

#Add enemy function
def newmob():
    mob_element = Mob()
    all_sprites.add(mob_element)
    mobs.add(mob_element)

#Add volcanic function
def newlava():
    lava_element = Lava()
    all_sprites.add(lava_element)
    lavas.add(lava_element)

#######################################Class area#######################################

class Explosion(pygame.sprite.Sprite):
    '''Create explosion class'''
    def __init__(self,center,size):
        pygame.sprite.Sprite.__init__(self)
        self.size = size
        self.image = explosion_anim[self.size][0]
        self.rect = self.image.get_rect()
        self.rect.center = center
        self.frame = 0 
        self.last_update = pygame.time.get_ticks()
        self.frame_rate = 75

    def update(self):        
        now = pygame.time.get_ticks()
        if now - self.last_update > self.frame_rate:
            self.last_update = now
            self.frame += 1
            if self.frame == len(explosion_anim[self.size]):
                self.kill()
            else:
                center = self.rect.center
                self.image = explosion_anim[self.size][self.frame]
                self.rect = self.image.get_rect()
                self.rect.center = center

class Player(pygame.sprite.Sprite):
    '''Create player class'''
    def __init__(self):
        pygame.sprite.Sprite.__init__(self)
        self.image = pygame.transform.scale(player_img,(50, 38))
        self.image.set_colorkey(BLACK)
        self.rect = self.image.get_rect()
        self.radius = 20
        self.rect.centerx = WIDTH/2
        self.rect.bottom = HEIGHT-10
        self.speedx = 0
        self.speedy = 0
        self.shield = 100
        self.shoot_delay = 250
        self.last_shot = pygame.time.get_ticks()
        self.lives = 3
        self.hidden = False
        self.hide_timer = pygame.time.get_ticks()
        self.power = 1
        self.power_timer = pygame.time.get_ticks()

    def update(self):
        if self.power >= 2 and pygame.time.get_ticks() - self.power_time > POWERUP_TIME: 
            self.power -= 1
            self.power_time = pygame.time.get_ticks()
        if self.hidden and pygame.time.get_ticks() - self.hide_timer > 1000:
            self.hidden = False
            self.rect.centerx = WIDTH/2
            self.rect.bottom = HEIGHT-30
        self.speedx = 0
        self.speedy = 0
        #Direction control: A controls left, D controls right, w controls up, s controls down, A+W controls up left, A+S controls down left, D+W controls up right, D+S controls down right
        keystate = pygame.key.get_pressed()
        if keystate[K_a]:
            self.speedx = -5
        if keystate[K_d]:
            self.speedx = 5
        if keystate[K_w]:
            self.speedy = -5
        if keystate[K_s]:
            self.speedy = 5
        #Emission control: spaces
        if keystate[pygame.K_SPACE]:
            self.shoot()
        #Set player movement boundary
        if self.rect.right > WIDTH:
            self.rect.right = WIDTH
        if self.rect.left < 0:
            self.rect.left = 0
        if self.rect.top < 10:
            self.rect.top = 10
        if self.rect.bottom > HEIGHT-10:
            self.rect.bottom = HEIGHT-10
        self.rect.x += self.speedx
        self.rect.y += self.speedy

    def shoot(self):
        now = pygame.time.get_ticks()
        if now-self.last_shot > self.shoot_delay:
            self.last_shot = now
            #Single fire
            if self.power == 1:
                bullet = Bullet(self.rect.centerx, self.rect.top)
                all_sprites.add(bullet)
                bullets.add(bullet)
                shooting_sound.play()
            #Double fire
            if self.power == 2:
                bullet1 = Bullet(self.rect.left, self.rect.centery)
                bullet2 = Bullet(self.rect.right, self.rect.centery)
                all_sprites.add(bullet1)
                all_sprites.add(bullet2)
                bullets.add(bullet1)
                bullets.add(bullet2)
                shooting_sound.play()
            #Three firepower
            if self.power >= 3:
                bullet1 = Bullet(self.rect.left, self.rect.centery)
                bullet2 = Bullet(self.rect.right, self.rect.centery)
                missile1 = Missile(self.rect.centerx, self.rect.top) # Missile
                all_sprites.add(bullet1)
                all_sprites.add(bullet2)
                all_sprites.add(missile1)
                bullets.add(bullet1)
                bullets.add(bullet2)
                bullets.add(missile1)
                shooting_sound.play()
                missile_sound.play()

    def powerup(self):
        self.power += 1
        self.power_time = pygame.time.get_ticks()

    def hide(self):
        self.hidden = True
        self.hide_timer = pygame.time.get_ticks()
        self.rect.center = (WIDTH/2, HEIGHT+200)

class Mob(pygame.sprite.Sprite):
    '''Create enemy class'''
    def __init__(self):
        pygame.sprite.Sprite.__init__(self)
        self.image_orig = random.choice(enemies_images)
        self.image_orig.set_colorkey(BLACK)
        self.image = self.image_orig.copy()
        self.rect = self.image.get_rect()
        self.radius = int(self.rect.width*.90/2)
        self.rect.x = random.randrange(0, WIDTH-self.rect.width)
        self.rect.y = random.randrange(-150,-100)       
        self.speedy = random.randrange(5,10)
        self.speedx = random.randrange(-3,3)
        self.shoot_delay = 1000
        self.last_shot = pygame.time.get_ticks()        

    def update(self):
        self.rect.x += self.speedx
        self.rect.y += self.speedy
        if random.randrange(10) >= 6:
            self.enemies_shoot()        
        if (self.rect.top > HEIGHT+10) or (self.rect.left < -25) or (self.rect.right > WIDTH+20):
            self.rect.x = random.randrange(0,WIDTH-self.rect.width)
            self.rect.y = random.randrange(-100,-40)
            self.speedy = random.randrange(1,8)
    
    def enemies_shoot(self):
        now = pygame.time.get_ticks()
        if now-self.last_shot > self.shoot_delay:
            self.last_shot = now
            enemies_bullet = EnemiesBullet(self.rect.centerx, self.rect.bottom)
            all_sprites.add(enemies_bullet)
            enemies_bullets.add(enemies_bullet)
            shooting_sound.play()

class Lava(pygame.sprite.Sprite):
    '''Create volcanic rock class'''
    def __init__(self):
        pygame.sprite.Sprite.__init__(self)
        self.image_orig = random.choice(lava_images)
        self.image_orig.set_colorkey(BLACK)
        self.image = self.image_orig.copy()
        self.rect = self.image.get_rect()
        self.radius = int(self.rect.width*.90/2)
        self.rect.x = random.randrange(0, WIDTH-self.rect.width)
        self.rect.y = random.randrange(-150,-100)       
        self.speedy = random.randrange(5,10)
        self.speedx = random.randrange(-3,3)
        self.rotation = 0
        self.rotation_speed = random.randrange(-8, 8)
        self.last_update = pygame.time.get_ticks()

    #Add volcanic rock rotation effect
    def rotate(self):
        time_now = pygame.time.get_ticks()
        if time_now-self.last_update > 50:
            self.last_update = time_now
            self.rotation = (self.rotation+self.rotation_speed)%360 
            new_image = pygame.transform.rotate(self.image_orig,self.rotation)
            old_center = self.rect.center
            self.image = new_image
            self.rect = self.image.get_rect()
            self.rect.center = old_center                

    def update(self):
        self.rotate()
        self.rect.x += self.speedx
        self.rect.y += self.speedy               
        if (self.rect.top > HEIGHT+10) or (self.rect.left < -25) or (self.rect.right > WIDTH+20):
            self.rect.x = random.randrange(0,WIDTH-self.rect.width)
            self.rect.y = random.randrange(-100,-40)
            self.speedy = random.randrange(1,8)       

class Bullet(pygame.sprite.Sprite):
    '''Create player shell class'''
    def __init__(self, x, y):
        pygame.sprite.Sprite.__init__(self)
        self.image = bullet_img
        self.image.set_colorkey(BLACK)
        self.rect = self.image.get_rect()
        self.rect.bottom = y 
        self.rect.centerx = x
        self.speedy = -10

    def update(self):
        self.rect.y += self.speedy
        if self.rect.bottom < 0:
            self.kill()

class EnemiesBullet(pygame.sprite.Sprite):
    '''Create enemy shell class'''
    def __init__(self, x, y):
        pygame.sprite.Sprite.__init__(self)
        self.image = enemies_bullet_img
        self.image.set_colorkey(BLACK)
        self.rect = self.image.get_rect()
        self.rect.top = y 
        self.rect.centerx = x
        self.speedy = 10

    def update(self):
        self.rect.y += self.speedy
        if self.rect.top > 600:
            self.kill()

class Missile(pygame.sprite.Sprite):
    '''Create missile class'''
    def __init__(self, x, y):
        pygame.sprite.Sprite.__init__(self)
        self.image = missile_img
        self.image.set_colorkey(BLACK)
        self.rect = self.image.get_rect()
        self.rect.bottom = y
        self.rect.centerx = x
        self.speedy = -10

    def update(self):
        self.rect.y += self.speedy
        if self.rect.bottom < 0:
            self.kill()

class Pow(pygame.sprite.Sprite):
    '''Create supply class'''
    def __init__(self, center):
        pygame.sprite.Sprite.__init__(self)
        self.type = random.choice(['shield', 'gun'])
        self.image = powerup_images[self.type]
        self.image.set_colorkey(BLACK)
        self.rect = self.image.get_rect()
        self.rect.center = center
        self.speedy = 4

    def update(self):
        self.rect.y += self.speedy
        if self.rect.top > HEIGHT:
            self.kill()

#######################################Main cycle#######################################

#Define game start interface ID
running = True
menu_display = True

while running:
    if menu_display:
        main_menu()
        pygame.time.wait(3000)
        pygame.mixer.music.stop()
        pygame.mixer.music.load(path.join(sound_folder,'tgfcoder-FrozenJam-SeamlessLoop.ogg'))
        pygame.mixer.music.play(-1)
        menu_display = False

        all_sprites = pygame.sprite.Group()
        player = Player()
        all_sprites.add(player)        
        mobs = pygame.sprite.Group()
        for i in range(4):
            newmob()
        lavas = pygame.sprite.Group()
        for i in range(4): 
            newlava()
        bullets = pygame.sprite.Group()
        enemies_bullets = pygame.sprite.Group()
        powerups = pygame.sprite.Group()

        score = 0   

    clock.tick(FPS)
    
    for event in pygame.event.get():
        if event.type == pygame.QUIT:
            running = False
        if event.type == pygame.KEYDOWN:
            if event.key == pygame.K_ESCAPE:
                running = False

    all_sprites.update()
    
    #Collision detection between enemy aircraft and player shells
    hits = pygame.sprite.groupcollide(mobs,bullets,True,True)    
    for hit in hits:
        score += 50-hit.radius
        random.choice(expl_sounds).play()       
        expl = Explosion(hit.rect.center,'lg')
        all_sprites.add(expl)
        if random.random() > 0.9:
            pow = Pow(hit.rect.center)
            all_sprites.add(pow)
            powerups.add(pow)
        newmob()
    
    #Collision detection between volcanic stone and player shell
    hits = pygame.sprite.groupcollide(lavas,bullets,True,True)    
    for hit in hits:
        score += 50-hit.radius
        random.choice(expl_sounds).play()      
        expl = Explosion(hit.rect.center,'lg')
        all_sprites.add(expl)
        if random.random() > 0.9:
            pow = Pow(hit.rect.center)
            all_sprites.add(pow)
            powerups.add(pow)
        newlava()

    #Collision detection between player and enemy aircraft
    hits = pygame.sprite.spritecollide(player,mobs,True,pygame.sprite.collide_circle)
    for hit in hits:
        player.shield -= hit.radius*2
        expl = Explosion(hit.rect.center,'sm')
        all_sprites.add(expl)
        newmob()
        if player.shield <= 0: 
            player_die_sound.play()
            death_explosion = Explosion(player.rect.center,'player')
            all_sprites.add(death_explosion)
            player.hide()
            player.lives -= 1
            player.shield = 100

    #Collision detection between player and volcanic rock
    hits = pygame.sprite.spritecollide(player,lavas,True,pygame.sprite.collide_circle)
    for hit in hits:
        player.shield -= hit.radius*2
        expl = Explosion(hit.rect.center,'sm')
        all_sprites.add(expl)
        newlava()
        if player.shield <= 0: 
            player_die_sound.play()
            death_explosion = Explosion(player.rect.center,'player')
            all_sprites.add(death_explosion)
            player.hide()
            player.lives -= 1
            player.shield = 100
    
    #Collision detection between players and enemy shells
    hits = pygame.sprite.spritecollide(player,enemies_bullets,True,pygame.sprite.collide_circle)
    for hit in hits:
        player.shield -= hit.radius*2
        expl = Explosion(hit.rect.center,'sm')
        all_sprites.add(expl)        
        if player.shield <= 0: 
            player_die_sound.play()
            death_explosion = Explosion(player.rect.center,'player')
            all_sprites.add(death_explosion)
            player.hide()
            player.lives -= 1
            player.shield = 100
    
    #Player and supply collision detection
    hits = pygame.sprite.spritecollide(player,powerups,True)
    for hit in hits:
        if hit.type == 'shield':
            player.shield += random.randrange(10,30)
            if player.shield >= 100:
                player.shield = 100
        if hit.type == 'gun':
            player.powerup()

    if player.lives == 0 and not death_explosion.alive():
        pygame.time.wait(1000)
        screen.fill(BLACK)
        draw_text(screen, "Game Over", 40, WIDTH/2, HEIGHT/3)
        pygame.display.update()
        pygame.time.wait(3000)
        menu_display = True

    #Background scroll down
    screen.fill(BLACK)    
    screen.blit(background,(0,height))
    height += 2
    if height >= -168:
        height = -936

    all_sprites.draw(screen)
    draw_text(screen,str(score),18,WIDTH/2,10)
    draw_shield_bar(screen,5,5,player.shield)    
    draw_lives(screen,WIDTH-100,5,player.lives,player_mini_img)

    pygame.display.flip()    

pygame.quit()

3, Effect display

1) Video effects

The new version of thunder duel: the enemy and players have unique skills and burst out of firepower~

2) Screenshot effect

The game begins——

The game begins - exciting duel!

Game over——

summary

OK ~ the upgraded version of the aircraft war is over here. Next time, I'll write you the highest version. Look forward to it!?

After learning, remember three consecutive Oh ~ you can drop me if you need the source code!

Source base——

Didi, I can! See my home page (you can also get your own drops on the pc)~

🎉 Recommended reading in previous periods——

Project collection 1.0 All kinds of game source code are here for free!

Project collection 1.1 All kinds of manual source code projects can only be found here!

Project collection 1.2 All kinds of confession project source code are here to see!

Project collection 1.3 All kinds of Turtle codes are looking for here!

🎄 Article summary——

Item 1.0 Python-2021 | summary of existing articles | continuously updated. It's enough to read this article directly

(more content + source code are summarized in the article!! welcome to read ~)

Topics: Python pygame