【02】做一个精美的打飞机小游戏,python开发小游戏-鹰击长空—优雅草央千澈-持续更新-分享源代码和游戏包供游玩-记录完整开发过程-用做好的素材来完善鹰击长空1.0.1版本
背景
之前优雅草央千澈在AE特效制作处博文已经完整介绍了本款游戏的素材开发,本文开始把素材利用起来放进去,本游戏命名为鹰击长空,Eagles strike across the sky,简称名字ESAS!
内容概要
·加入boss机
·将图像换成png序列图(AE开发博文制作的AE特效)
·规范资源文件目录加入static
·代码开源发布
开源源代码下载地址
https://gitee.com/youyacao/esas
游戏运行包
还未打包,下个版本稍微完整在打包。
完善飞机大战小游戏-换上制作的特效序列png图片-加入boss机
换上png特效序列图
接上一篇,
pygame.image.load(f”explosion_{i}.png”).提示我们要加载序列图
首先我们把素材都放进去,但是我们直接放根目录肯定不太对,因此我们安规矩建立目录 \static\png 我们放进去
额外建立img是预留来放背景素材等内容。
导入所有的素材,首先我们修改爆炸序列图,原来的代码
# 加载爆炸动画序列 explosion_frames = [] for i in range(10): # 假设有10帧 frame = pygame.image.load(f"explosion_{i}.png").convert_alpha() explosion_frames.append(frame)
修改后:
# 加载爆炸动画序列 explosion_frames = [] for i in range(15): # 假设有15帧,从00到14 frame = pygame.image.load(f"img/png/explosion{i:02d}.png").convert_alpha() explosion_frames.append(frame)
再次运行
报错,嗷嗷,马虎了 我的文件名是”static, 修改后再次运行
成功,但是我飞机爆炸的画面实在是太大了,不关心,后面再改
接下来把其他几个部分也改掉,
# 加载玩家动画序列 player_frames = [] for i in range(12): # 假设有12帧,从player_100.png到player_111.png frame = pygame.image.load(f"static/png/player_{100 + i:03d}.png").convert_alpha() player_frames.append(frame) # 加载敌人动画序列 enemy_frames = [] for i in range(10): # 假设有10帧,从boss00.png到boss09.png frame = pygame.image.load(f"static/png/boss{i:02d}.png").convert_alpha() enemy_frames.append(frame) # 加载子弹动画序列 bullet_frames = [] for i in range(6): # 假设有6帧,从bullet0.png到bullet5.png frame = pygame.image.load(f"static/png/bullet{i}.png").convert_alpha() bullet_frames.append(frame)
改造后代码
# 玩家类 class Player(pygame.sprite.Sprite): def __init__(self): super().__init__() self.frames = player_frames self.frame = 0 self.image = self.frames[self.frame] self.rect = self.image.get_rect(center=(player_x, player_y)) self.last_update = pygame.time.get_ticks() self.frame_rate = 100 # 每100毫秒切换一帧 def update(self): keys = pygame.key.get_pressed() if keys[pygame.K_LEFT] and self.rect.left > 0: self.rect.x -= player_speed if keys[pygame.K_RIGHT] and self.rect.right < screen_width: self.rect.x += player_speed # 更新动画帧 now = pygame.time.get_ticks() if now - self.last_update > self.frame_rate: self.last_update = now self.frame = (self.frame + 1) % len(self.frames) self.image = self.frames[self.frame] def shoot(self): bullet = Bullet(self.rect.centerx, self.rect.top) bullets.add(bullet) # 使用 add 方法将子弹添加到组中 bullet_sound.play() # 子弹类 class Bullet(pygame.sprite.Sprite): def __init__(self, x, y): super().__init__() self.frames = bullet_frames self.frame = 0 self.image = self.frames[self.frame] self.rect = self.image.get_rect(center=(x, y)) self.last_update = pygame.time.get_ticks() self.frame_rate = 100 # 每100毫秒切换一帧 def update(self): self.rect.y -= bullet_speed if self.rect.bottom < 0: self.kill() # 更新动画帧 now = pygame.time.get_ticks() if now - self.last_update > self.frame_rate: self.last_update = now self.frame = (self.frame + 1) % len(self.frames) self.image = self.frames[self.frame] # 敌人类 class Enemy(pygame.sprite.Sprite): def __init__(self): super().__init__() self.frames = enemy_frames self.frame = 0 self.image = self.frames[self.frame] self.rect = self.image.get_rect(center=(random.randint(50, screen_width - 50), -50)) self.last_update = pygame.time.get_ticks() self.frame_rate = 100 # 每100毫秒切换一帧 def update(self): self.rect.y += enemy_speed if self.rect.top > screen_height: self.kill() # 更新动画帧 now = pygame.time.get_ticks() if now - self.last_update > self.frame_rate: self.last_update = now self.frame = (self.frame + 1) % len(self.frames) self.image = self.frames[self.frame] # 爆炸类 class Explosion(pygame.sprite.Sprite): def __init__(self, center): super().__init__() self.frames = explosion_frames self.frame = 0 self.image = self.frames[self.frame] self.rect = self.image.get_rect(center=center) self.last_update = pygame.time.get_ticks() self.frame_rate = 50 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(self.frames): self.kill() else: center = self.rect.center self.image = self.frames[self.frame] self.rect = self.image.get_rect(center=center)
改造后的类,哎哟妈呀再次运行吓一跳
图像太大了,我们得改下他的大小,这个步骤的话我们就在AE中处理了。
改变类的尺寸调整游戏整体大小
因为是飞机游戏,因此我们宽高改一下,720*1280
对AI魔法;限制玩家类Player的图像宽高分别是150px ,150px ,限制子弹类Bullet的图像宽高分别为50px,50px ,限制敌人类的图像高分别为80px,80px ,
frame = pygame.transform.scale(frame, (150, 150)) # 调整为150x150像素
大概就是加这段代码,
我们分别加上。
再次运行,满意,不过我发现个问题,把boss机和小敌机搞反了,反了就反了吧、因为不影响美观,还是很好看。
为对方加入BOSS机,设定为10秒出场
为对方加入BOSS机,设定为10秒出场,为啥要设定是10秒出场只是为了看看效果,后续直接改就行。
先把小飞机的图像换了,这次我们加入boss机,其次我们加入boss机肯定需要加入一个强大的背景音乐咯,因此, 我们加入背景音乐
还记得free sounds吗?找到个非常好听 非常紧张的boss音乐,我加入进去
建立sound 目录,放入我们的音乐文件
施法 :为游戏中加入敌人机BOSS,增加boss这个类,boss在游戏开始的10秒后进入战场,进入战场的时候加入背景音乐,背景音乐的文件目录为boss.wav
然后 再修改,加入boss类
# BOSS 类 class Boss(pygame.sprite.Sprite): def __init__(self): super().__init__() self.frames = [pygame.image.load(f"static/png/boss{i:02d}.png").convert_alpha() for i in range(15)] self.frame = 0 self.image = self.frames[self.frame] self.rect = self.image.get_rect(center=(screen_width // 2, -100)) self.last_update = pygame.time.get_ticks() self.frame_rate = 100 # 每100毫秒切换一帧 self.health = 100 # BOSS 的生命值 def update(self): # 移动 BOSS self.rect.y += 2 # BOSS 向下移动 # 更新动画帧 now = pygame.time.get_ticks() if now - self.last_update > self.frame_rate: self.last_update = now self.frame = (self.frame + 1) % len(self.frames) self.image = self.frames[self.frame] # 检查 BOSS 是否超出屏幕 if self.rect.top > screen_height: self.kill()
然后加入游戏主循环中,
# 游戏主循环 boss_spawned = False boss_spawn_time = 10000 # 10秒后生成BOSS while running: for event in pygame.event.get(): if event.type == pygame.QUIT: running = False if event.type == pygame.KEYDOWN: if event.key == pygame.K_SPACE: player.shoot() # 更新所有精灵 all_sprites.update() all_enemies.update() # 生成敌人 if random.randint(1, 100) < 5: enemy = Enemy() all_enemies.add(enemy) all_sprites.add(enemy) # 检测碰撞 hits = pygame.sprite.groupcollide(all_enemies, bullets, True, True) for hit in hits: explosion = Explosion(hit.rect.center) all_sprites.add(explosion) # 检测 BOSS 是否生成 if not boss_spawned and pygame.time.get_ticks() > boss_spawn_time: boss = Boss() all_sprites.add(boss) all_enemies.add(boss) boss_spawned = True pygame.mixer.music.load("boss.wav") # 加载背景音乐 pygame.mixer.music.play(-1) # 播放背景音乐,-1表示循环播放 # 绘制屏幕 screen.fill((0, 0, 0)) all_sprites.draw(screen) pygame.display.flip() # 控制帧率 clock.tick(60) # 退出游戏 pygame.quit() sys.exit()
完成,再次测试。
笑死了 boss直接飞上来撞我脸上了,因此要改造boss,boss进入后在上方,
# BOSS 类 class Boss(pygame.sprite.Sprite): def __init__(self): super().__init__() self.frames = [pygame.image.load(f"static/png/boss{i:02d}.png").convert_alpha() for i in range(15)] self.frame = 0 self.image = self.frames[self.frame] self.rect = self.image.get_rect(center=(screen_width // 2, -100)) self.last_update = pygame.time.get_ticks() self.frame_rate = 100 # 每100毫秒切换一帧 self.health = 100 # BOSS 的生命值 self.move_direction = 1 # 1 表示向右移动,-1 表示向左移动 self.move_speed = 2 # BOSS 的移动速度 self.shoot_delay = 1000 # 发射子弹的间隔时间(毫秒) self.last_shot = pygame.time.get_ticks() # 上一次发射子弹的时间 def update(self): # 移动 BOSS self.rect.y += 2 # BOSS 向下移动 if self.rect.top > 0: self.rect.x += self.move_speed * self.move_direction if self.rect.right > screen_width or self.rect.left < 0: self.move_direction *= -1 # 改变移动方向 # 更新动画帧 now = pygame.time.get_ticks() if now - self.last_update > self.frame_rate: self.last_update = now self.frame = (self.frame + 1) % len(self.frames) self.image = self.frames[self.frame] # 发射子弹 if now - self.last_shot > self.shoot_delay: self.last_shot = now self.shoot() def shoot(self): bullet = Bullet(self.rect.centerx, self.rect.bottom) bullets.add(bullet) # 使用 add 方法将子弹添加到组中
修改boss的类,再修改主循环,笑死了 这次出来 boss直接爆炸了,好本文到这里,大家可以持续关注和学习如何开发游戏欢迎给优雅草央千澈点赞收藏加关注,下篇我们完善下boss的打斗机制,主角机的打斗机制,背景画面,以及第一张关卡的内容,完成游戏开发目录专业分类。