简易飞机大战
今天小白给大家介绍如何用Python制作简易的飞机大战小游戏,如果大家经常看抖音、简书或是CSDN,那么肯定会类似遇到下面的视频。
小白给大家详细介绍一下,这款小游戏是如何制作的?
可以绘制程序流程图,便于了解程序结构。
首先,定义子弹类
import pygameimport sys,os,randomfrom pygame.locals import *class Bullet(pygame.sprite.Sprite): #调用精灵类,后面实现子弹与敌机碰撞检测、敌机与玩家的碰撞检测 def __init__(self,bullet_image,bullet_pos): #子弹图片,初始位置 pygame.sprite.Sprite.__init__(self) #初始化 self.image = bullet_image self.rect = self.image.get_rect() self.rect.midbottom = bullet_pos self.speed = 10 def move(self): self.rect.top -= self.speed
定义飞机类
class Player(pygame.sprite.Sprite): def __init__(self,images,player_rect,player_pos): pygame.sprite.Sprite.__init__(self) self.image = [] self.rect = player_rect[0] for i in range(len(player_rect)): self.image.append(images.subsurface(player_rect[i]).convert_alpha()) self.rect.midbottom = player_pos self.speed = 10 #飞机移动频率 self.bullets = pygame.sprite.Group() #存储子弹 self.is_hit = False #用于判断是否撞击 def shoot(self,bullet_image): bullet = Bullet(bullet_image,self.rect.midtop) self.bullets.add(bullet) def moveup(self): if self.rect.top <= 0: self.rect.top = 0 else: self.rect.top -= self.speed def movedown(self): if self.rect.top >= window_height-self.rect.height: self.rect.top = window_height-self.rect.height else: self.rect.top += self.speed def moveleft(self): if self.rect.left <= 0 : self.rect.left = 0 else: self.rect.left -= self.speed def moveright(self): if self.rect.left >= window_weight - self.rect.width: self.rect.left = window_weight - self.rect.width else: self.rect.left += self.speed
定义敌机类
class Enemy(pygame.sprite.Sprite): def __init__(self,enemy_img,enemy_down_img,init_pos): pygame.sprite.Sprite.__init__(self) self.image = enemy_img #敌机的图片 self.rect = enemy_img.get_rect() #获取敌机矩形框 self.rect.topleft = init_pos self.image_down = enemy_down_img #敌机坠毁的图片 self.speed = 2 def move(self): self.rect.top += self.speed #敌机向下移动
绘制玩家飞机、玩家飞机坠毁、子弹、敌机和敌机坠毁需要的图片,调用类似下面的代码。
images = pygame.image.load('resources\image\shoot.png')enemy_rect = pygame.Rect(534,612,57,43) #图片左上角坐标,宽高enemy_image = images.subsurface(enemy_rect) #截取图片中的敌机
绘制敌机、敌机和玩家碰撞检测
for enemy in enemies: enemy.move() if pygame.sprite.collide_circle(enemy,player): #敌机和玩家碰撞 enemies_down.add(enemy) enemies.remove(enemy) screen.blit(player.image[1], player.rect) running = False if enemy.rect.top < 0: enemies.remove(enemy)
子弹与敌机碰撞,实现加分,并绘制敌机坠毁的图片
enemies_down1 = pygame.sprite.groupcollide(enemies, player.bullets, 1, 1) #敌机和子弹碰撞 图片之间有了交集 for enemy_down in enemies_down: score += 1 enemies_down.remove(enemy_down) screen.blit(enemy_down.image_down,enemy_down.rect)
控制玩家飞机移动
if key_pressed[K_w] or key_pressed[K_UP]: player.moveup()elif key_pressed[K_s] or key_pressed[K_DOWN]: player.movedown()elif key_pressed[K_a] or key_pressed[K_LEFT]: player.moveleft()elif key_pressed[K_d] or key_pressed[K_RIGHT]: player.moveright()
完整代码
import pygameimport sys,os,randomfrom pygame.locals import *class Bullet(pygame.sprite.Sprite): def __init__(self,bullet_image,bullet_pos): pygame.sprite.Sprite.__init__(self) self.image = bullet_image self.rect = self.image.get_rect() self.rect.midbottom = bullet_pos self.speed = 10 def move(self): self.rect.top -= self.speedclass Player(pygame.sprite.Sprite): def __init__(self,images,player_rect,player_pos): pygame.sprite.Sprite.__init__(self) self.image = [] self.rect = player_rect[0] for i in range(len(player_rect)): self.image.append(images.subsurface(player_rect[i]).convert_alpha()) self.rect.midbottom = player_pos self.speed = 10 self.bullets = pygame.sprite.Group() self.is_hit = False def shoot(self,bullet_image): bullet = Bullet(bullet_image,self.rect.midtop) self.bullets.add(bullet) def moveup(self): if self.rect.top <= 0: self.rect.top = 0 else: self.rect.top -= self.speed def movedown(self): if self.rect.top >= window_height-self.rect.height: self.rect.top = window_height-self.rect.height else: self.rect.top += self.speed def moveleft(self): if self.rect.left <= 0 : self.rect.left = 0 else: self.rect.left -= self.speed def moveright(self): if self.rect.left >= window_weight - self.rect.width: self.rect.left = window_weight - self.rect.width else: self.rect.left += self.speedclass Enemy(pygame.sprite.Sprite): def __init__(self,enemy_img,enemy_down_img,init_pos): pygame.sprite.Sprite.__init__(self) self.image = enemy_img self.rect = enemy_img.get_rect() self.rect.topleft = init_pos self.image_down = enemy_down_img self.speed = 2 def move(self): self.rect.top += self.speedpygame.init() #游戏初始化window_height = 600window_weight = 400#窗口左上角坐标(0,50)os.environ['SDL_VIDEO_WINDOW_POS'] = '%d,%d'% (0,50)screen = pygame.display.set_mode((window_weight,window_height))pygame.display.set_caption('飞机大战')player_pos = [200,600] #玩家初始位置background = pygame.image.load(r'resources\image\background.png')images = pygame.image.load('resources\image\shoot.png')player_rect = []player_rect.append(pygame.Rect(0,99,102,106))player_rect.append(pygame.Rect(165,234,102,126))player = Player(images,player_rect,player_pos)bullet_rect = pygame.Rect(1004,987,9,21)bullet_img = images.subsurface(bullet_rect)enemy_rect = pygame.Rect(534,612,57,43)enemy_image = images.subsurface(enemy_rect)enemy_down_image = images.subsurface(pygame.Rect(267,347,57,43))enemies = pygame.sprite.Group() #放置所有敌机enemies_down = pygame.sprite.Group() #放置所有坠毁的敌机shoot_frequency = 0 #子弹发射频率enemy_frequency = 0 #敌机出现频率score = 0clock = pygame.time.Clock() #控制频率running = Truewhile running: clock.tick(60) #60帧 screen.blit(background, (0, 0)) if player.is_hit == False: screen.blit(player.image[0], player.rect) if shoot_frequency % 15 == 0: #每隔15帧 发送一枚子弹 player.shoot(bullet_img) shoot_frequency += 1 for bullet in player.bullets: bullet.move() #子弹子弹 if bullet.rect.bottom < 0: player.bullets.remove(bullet) player.bullets.draw(screen) #绘制所有子弹 if enemy_frequency % 50 == 0: #每隔50帧出现一部敌机 enemy_pos = [random.randint(0,window_weight-enemy_rect.width),0] enemy = Enemy(enemy_image,enemy_down_image,enemy_pos) enemies.add(enemy) enemy_frequency += 1 for enemy in enemies: enemy.move() #控制所有敌机自动移动 if pygame.sprite.collide_circle(enemy,player): #敌机和玩家碰撞 enemies_down.add(enemy) enemies.remove(enemy) screen.blit(player.image[1], player.rect) #玩家飞机坠毁,出现玩家坠毁图片 running = False #结束游戏运行主体 if enemy.rect.top < 0: enemies.remove(enemy) enemies_down1 = pygame.sprite.groupcollide(enemies, player.bullets, 1, 1) #敌机和子弹碰撞 图片之间有了交集 for enemy_down in enemies_down1: #enemies_down1用于碰撞检测 enemies_down.add(enemy_down) #enemies_down用于计分 for enemy_down in enemies_down: score += 1 enemies_down.remove(enemy_down) screen.blit(enemy_down.image_down,enemy_down.rect) enemies.draw(screen) score_font = pygame.font.Font(None,40) #可以不用字体 score_text = score_font.render('score: '+str(score),True,(128,128,128)) #True表达文本图像显示更光滑 text_rect = score_text.get_rect() screen.blit(score_text,text_rect) pygame.display.update() key_pressed = pygame.key.get_pressed() if key_pressed[K_w] or key_pressed[K_UP]: player.moveup() elif key_pressed[K_s] or key_pressed[K_DOWN]: player.movedown() elif key_pressed[K_a] or key_pressed[K_LEFT]: player.moveleft() elif key_pressed[K_d] or key_pressed[K_RIGHT]: player.moveright() for event in pygame.event.get(): if event.type == QUIT: pygame.quit() sys.exit()gameover = pygame.image.load('resources/image/gameover.png')screen.blit(gameover,(0,0))font = pygame.font.Font(None,100)over_score = font.render('score:'+str(score),True,(255,0,0)) #True文本更加光滑over_rect = over_score.get_rect()over_rect.centerx = screen.get_rect().centerx #分数的横坐标,屏幕中心over_rect.centery = screen.get_rect().centery - 100 #分数的纵坐标,屏幕中心-100screen.blit(over_score,over_rect) #显示最终分数while 1: for event in pygame.event.get(): if event.type == QUIT: pygame.quit() sys.exit() pygame.display.update()
完~