Introduction
Mood in December: half excellent, half happy.
December sky: half sunny, half rainy.
The wind in December: no longer so gentle, with wordless irritability! Even wrapped in painful rain.
The tail of 2022: has come quietly!
Approaching the new year, Xiaobian has prepared a series of "from simple to luxury version - three versions of" aircraft war "games for everyone
You can start by yourself 💭 Imagine ~ hey hey. When I slowly update this series, today I will update you with a basic version of the big plane
Fight!
In fact, if it's basic, it's not very basic: the interface is particularly exquisite, and then there are corresponding protective shield and other functions, just because of the first model
The aircraft war is a meteorite falling from the sky, and then the enemy aircraft won't get it. I'll write it to you when I upgrade it next time!
So -- let's get down to work 👇👇👇👇👇👇
text
Story background: (pure fiction, don't be serious)
In the early morning of the evening of December 30, 🌏 A meteorite fell. The live video shows that the night sky was suddenly illuminated that night, and a red light was drawn from the air
After a few seconds, it disappeared quickly. After research, it is expected that a new wave of meteorites will fall from the sky today, and even this large number of meteorites
The landing threatened people's lives and caused many medical accidents, so the defense team was sent out to destroy the meteorites in the universe
Plan! We should smash or even destroy these meteorites as much as possible....... The plan begins
1, Rules of the game
We designed an aircraft war game developed by Pygame module based on Python.
Aircraft war game is a leisure puzzle game, which is simple and playable. In the initial interface, we can start the game and exit the game
There are two options.
After starting the game, players can use the up, down, left and right direction keys to control the aircraft to move in any direction on the screen and shoot meteorites through the space bar
Stone score, shield, life and lightning ⚡ Add attack shells and initialize life to 3 times. You can see the current life in the upper right corner of the screen
Life, you can see the score in the middle.
2, In preparation
1) Material picture
2) Have some Music
3, Code demonstration
from __future__ import division import pygame import random from os import path img_dir = path.join(path.dirname(__file__), 'assets') sound_folder = path.join(path.dirname(__file__), 'sounds') WIDTH = 480 HEIGHT = 600 FPS = 60 POWERUP_TIME = 5000 BAR_LENGTH = 100 BAR_HEIGHT = 10 WHITE = (255, 255, 255) BLACK = (0, 0, 0) RED = (255, 0, 0) GREEN = (0, 255, 0) BLUE = (0, 0, 255) YELLOW = (255, 255, 0) pygame.init() pygame.mixer.init() ## For sound screen = pygame.display.set_mode((WIDTH, HEIGHT)) pygame.display.set_caption("Space Shooter") clock = pygame.time.Clock() ## For syncing the FPS font_name = pygame.font.match_font('arial') def main_menu(): global screen menu_song = pygame.mixer.music.load(path.join(sound_folder, "menu.ogg")) pygame.mixer.music.play(-1) 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() while True: ev = pygame.event.poll() if ev.type == pygame.KEYDOWN: if ev.key == pygame.K_RETURN: break elif ev.key == pygame.K_q: pygame.quit() quit() elif ev.type == pygame.QUIT: pygame.quit() quit() else: draw_text(screen, "Press [ENTER] To Begin", 30, WIDTH/2, HEIGHT/2) draw_text(screen, "or [Q] To Quit", 30, WIDTH/2, (HEIGHT/2)+40) pygame.display.update() #pygame.mixer.music.stop() ready = pygame.mixer.Sound(path.join(sound_folder,'getready.ogg')) ready.play() screen.fill(BLACK) draw_text(screen, "GET READY!", 40, WIDTH/2, HEIGHT/2) pygame.display.update() def draw_text(surf, text, size, x, y): ## selecting a cross platform font to display the score font = pygame.font.Font(font_name, size) text_surface = font.render(text, True, WHITE) ## True denotes the font to be anti-aliased text_rect = text_surface.get_rect() text_rect.midtop = (x, y) surf.blit(text_surface, text_rect) def draw_shield_bar(surf, x, y, pct): # if pct < 0: # pct = 0 pct = max(pct, 0) ## moving them to top # BAR_LENGTH = 100 # BAR_HEIGHT = 10 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) 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) def newmob(): mob_element = Mob() all_sprites.add(mob_element) mobs.add(mob_element) class Explosion(pygame.sprite.Sprite): 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): def __init__(self): pygame.sprite.Sprite.__init__(self) ## scale the player img down 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.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): ## time out for powerups if self.power >=2 and pygame.time.get_ticks() - self.power_time > POWERUP_TIME: self.power -= 1 self.power_time = pygame.time.get_ticks() ## unhide 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 ## makes the player static in the screen by default. # then we have to check whether there is an event hanlding being done for the arrow keys being ## pressed ## will give back a list of the keys which happen to be pressed down at that moment keystate = pygame.key.get_pressed() if keystate[pygame.K_LEFT]: self.speedx = -5 elif keystate[pygame.K_RIGHT]: self.speedx = 5 #Fire weapons by holding spacebar if keystate[pygame.K_SPACE]: self.shoot() ## check for the borders at the left and right if self.rect.right > WIDTH: self.rect.right = WIDTH if self.rect.left < 0: self.rect.left = 0 self.rect.x += self.speedx def shoot(self): ## to tell the bullet where to spawn now = pygame.time.get_ticks() if now - self.last_shot > self.shoot_delay: self.last_shot = now if self.power == 1: bullet = Bullet(self.rect.centerx, self.rect.top) all_sprites.add(bullet) bullets.add(bullet) shooting_sound.play() 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() """ MOAR POWAH """ 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 shoots from center of ship 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) # defines the enemies class Mob(pygame.sprite.Sprite): def __init__(self): pygame.sprite.Sprite.__init__(self) self.image_orig = random.choice(meteor_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, 20) ## for randomizing the speed of the Mob ## randomize the movements a little more self.speedx = random.randrange(-3, 3) ## adding rotation to the mob element self.rotation = 0 self.rotation_speed = random.randrange(-8, 8) self.last_update = pygame.time.get_ticks() ## time when the rotation has to happen def rotate(self): time_now = pygame.time.get_ticks() if time_now - self.last_update > 50: # in milliseconds 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 ## now what if the mob element goes out of the screen 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) ## for randomizing the speed of the Mob ## defines the sprite for Powerups class Pow(pygame.sprite.Sprite): 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() ## place the bullet according to the current position of the player self.rect.center = center self.speedy = 2 def update(self): """should spawn right in front of the player""" self.rect.y += self.speedy ## kill the sprite after it moves over the top border if self.rect.top > HEIGHT: self.kill() ## defines the sprite for bullets class Bullet(pygame.sprite.Sprite): 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() ## place the bullet according to the current position of the player self.rect.bottom = y self.rect.centerx = x self.speedy = -10 def update(self): """should spawn right in front of the player""" self.rect.y += self.speedy ## kill the sprite after it moves over the top border if self.rect.bottom < 0: self.kill() ## now we need a way to shoot ## lets bind it to "spacebar". ## adding an event for it in Game loop ## FIRE ZE MISSILES class Missile(pygame.sprite.Sprite): 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): """should spawn right in front of the player""" self.rect.y += self.speedy if self.rect.bottom < 0: self.kill() ################################################### ## Load all game images background = pygame.image.load(path.join(img_dir, 'starfield.png')).convert() background_rect = background.get_rect() ## ^^ draw this rect first player_img = pygame.image.load(path.join(img_dir, 'playerShip1_orange.png')).convert() player_mini_img = pygame.transform.scale(player_img, (25, 19)) player_mini_img.set_colorkey(BLACK) bullet_img = pygame.image.load(path.join(img_dir, 'laserRed16.png')).convert() missile_img = pygame.image.load(path.join(img_dir, 'missile.png')).convert_alpha() # meteor_img = pygame.image.load(path.join(img_dir, 'meteorBrown_med1.png')).convert() meteor_images = [] meteor_list = [ 'meteorBrown_big1.png', 'meteorBrown_big2.png', 'meteorBrown_med1.png', 'meteorBrown_med3.png', 'meteorBrown_small1.png', 'meteorBrown_small2.png', 'meteorBrown_tiny1.png' ] for image in meteor_list: meteor_images.append(pygame.image.load(path.join(img_dir, image)).convert()) ## meteor explosion explosion_anim = {} explosion_anim['lg'] = [] explosion_anim['sm'] = [] explosion_anim['player'] = [] for i in range(9): filename = 'regularExplosion0{}.png'.format(i) img = pygame.image.load(path.join(img_dir, filename)).convert() img.set_colorkey(BLACK) ## resize the explosion img_lg = pygame.transform.scale(img, (75, 75)) explosion_anim['lg'].append(img_lg) 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 power ups powerup_images = {} powerup_images['shield'] = pygame.image.load(path.join(img_dir, 'shield_gold.png')).convert() powerup_images['gun'] = pygame.image.load(path.join(img_dir, 'bolt_gold.png')).convert() ################################################### ################################################### ### Load all game sounds shooting_sound = pygame.mixer.Sound(path.join(sound_folder, 'pew.wav')) missile_sound = pygame.mixer.Sound(path.join(sound_folder, 'rocket.ogg')) expl_sounds = [] for sound in ['expl3.wav', 'expl6.wav']: expl_sounds.append(pygame.mixer.Sound(path.join(sound_folder, sound))) ## main background music #pygame.mixer.music.load(path.join(sound_folder, 'tgfcoder-FrozenJam-SeamlessLoop.ogg')) pygame.mixer.music.set_volume(0.2) ## simmered the sound down a little player_die_sound = pygame.mixer.Sound(path.join(sound_folder, 'rumble1.ogg')) ################################################### ## TODO: make the game music loop over again and again. play(loops=-1) is not working # Error : # TypeError: play() takes no keyword arguments #pygame.mixer.music.play() ############################# ## Game loop running = True menu_display = True while running: if menu_display: main_menu() pygame.time.wait(3000) #Stop menu music pygame.mixer.music.stop() #Play the gameplay music pygame.mixer.music.load(path.join(sound_folder, 'tgfcoder-FrozenJam-SeamlessLoop.ogg')) pygame.mixer.music.play(-1) ## makes the gameplay sound in an endless loop menu_display = False ## group all the sprites together for ease of update all_sprites = pygame.sprite.Group() player = Player() all_sprites.add(player) ## spawn a group of mob mobs = pygame.sprite.Group() for i in range(8): ## 8 mobs # mob_element = Mob() # all_sprites.add(mob_element) # mobs.add(mob_element) newmob() ## group for bullets bullets = pygame.sprite.Group() powerups = pygame.sprite.Group() #### Score board variable score = 0 #1 Process input/events clock.tick(FPS) ## will make the loop run at the same speed all the time for event in pygame.event.get(): # gets all the events which have occured till now and keeps tab of them. ## listening for the the X button at the top if event.type == pygame.QUIT: running = False ## Press ESC to exit game if event.type == pygame.KEYDOWN: if event.key == pygame.K_ESCAPE: running = False # ## event for shooting the bullets # elif event.type == pygame.KEYDOWN: # if event.key == pygame.K_SPACE: # player.shoot() ## we have to define the shoot() function #2 Update all_sprites.update() ## check if a bullet hit a mob ## now we have a group of bullets and a group of mob hits = pygame.sprite.groupcollide(mobs, bullets, True, True) ## now as we delete the mob element when we hit one with a bullet, we need to respawn them again ## as there will be no mob_elements left out for hit in hits: score += 50 - hit.radius ## give different scores for hitting big and small metoers random.choice(expl_sounds).play() # m = Mob() # all_sprites.add(m) # mobs.add(m) 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() ## spawn a new mob ## ^^ the above loop will create the amount of mob objects which were killed spawn again ######################### ## check if the player collides with the mob hits = pygame.sprite.spritecollide(player, mobs, True, pygame.sprite.collide_circle) ## gives back a list, True makes the mob element disappear 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) # running = False ## GAME OVER 3:D player.hide() player.lives -= 1 player.shield = 100 ## if the player hit a power up 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 died and the explosion has finished, end game if player.lives == 0 and not death_explosion.alive(): running = False # menu_display = True # pygame.display.update() #3 Draw/render screen.fill(BLACK) ## draw the stargaze.png image screen.blit(background, background_rect) all_sprites.draw(screen) draw_text(screen, str(score), 18, WIDTH / 2, 10) ## 10px down from the screen draw_shield_bar(screen, 5, 5, player.shield) # Draw lives draw_lives(screen, WIDTH - 100, 5, player.lives, player_mini_img) ## Done after drawing everything to the screen pygame.display.flip() pygame.quit()
4, Game effect
1) Video display effect
Pygame series: another aircraft War: space meteorite VS large fighter duel!
2) Screenshot display effect
Game interface:
Normal effect
With a shield+ ⚡:
summary
All right! This aircraft war is officially over here ~ work overtime to upgrade everyone and make a mutual battle with enemy aircraft!
Hey, hey ~ remember to collect what you like~
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——
(more content + source code are summarized in the article!! welcome to read ~)