一、英雄机的移动
想要移动飞机,无非就是改变飞机在屏幕上贴图的位置
先初始化飞机的位置, 定义两个变量来控制飞机的移动
1、编写移动逻辑
获取事件,pygame.event.get() 可以获取程序的所有事件
遍历事件,并判断事件的类型为按下键盘,然后改变hero_x 和 hero_y的值
右上角的坐标为(0, 0),向下y的值变大,向下y的值减小,向右x的值变大, 向左x的值减小
这里按一下移动10个单位的距离,可以根据需求调整数值
2、编写while循环实现移动
需要不断执行函数画图, 这样才能达到移动的目的
二、飞机发射子弹
想要达到发射子弹的效果,只需要让子弹再飞机的头部直线向上发射就可,就是沿着y轴的方向贴图,贴的位置要根据英雄机的位置来贴。
用一个列表来存放子弹发射的初始位置,这样能保证飞机移动的同时原来发射的子弹还能继续向前发射。
列表中存放字典,用字典记录子弹发射的初始位置,[{'x': 1, 'y': 1}], 不断遍历整个列表画子弹,最后让子弹的y轴变化即可实现子弹的发射。
三、生成敌机
这里是简易版的,一次只会生成一个敌机,我们先初始化一个列表, 列表中存一个敌机的位置
遍历列表绘制敌机,并不断改变敌机的y的值,就能实现移动了。
四、炸弹击中敌机
用一个全局变量staus来判断敌机是否还存活, 如果status='live'表示还活着,就绘制敌机,如果status='dead'表示敌机灭亡,就绘制爆炸效果,判断炸弹的位置是否在敌机位置范围内就可以判断炸弹是否击中敌机, 击中之后 ,将列表中的子弹和敌机都移除即可。
五、暂停游戏
定义全局变量pause存放状态,初始状态为False,表示不暂停,当按下空格键时,将pause值变为True, 当pause为True时暂停绘制值敌机即可,同时出现暂停提示,这样就能实现暂停游戏。
六、效果展示
七、代码
import pygame
import time
import sys
import random
pygame.init() # 初始化pygame, 确保包都导入了
# 控制位置变化, 初始化
hero_x = 300
hero_y = 470
# 弹夹, 每一颗子弹的位置用字典存储,{'x': 1, 'y': 2}
bullets = []
# 控制敌机的生成位置,初始化
enemies = [{'x': 300, 'y': 10}] # 存放敌机
status = 'live' # 判断敌机是否存活
# 爆炸效果
bomb1 = pygame.image.load('images/bz1.png')
bomb2 = pygame.image.load('images/bz2.png')
bombs = [bomb1, bomb2]
# 设置暂停
pause = False
# 英雄机
def hero_plane(screen, hero, bullet):
global hero_x, hero_y, pause # 定义成全局变量
screen.blit(hero, (hero_x, hero_y)) # 初始化英雄机的位置
# 获取事件
for event in pygame.event.get():
if event.type == pygame.QUIT: # 点击叉
print("退出游戏")
pygame.quit()
sys.exit() # 退出游戏
if event.type == pygame.KEYDOWN: # 按下键盘
if event.key == pygame.K_UP: # 上键
hero_y -= 20 # 向上移动十个单位,左上角是(0, 0)
elif event.key == pygame.K_DOWN: # 下键
hero_y += 20 # 向下移动十个单位
elif event.key == pygame.K_LEFT: # 左键
hero_x -= 20 # 向左移动十个单位
elif event.key == pygame.K_RIGHT: # 下键
hero_x += 20 # 向右移动十个单位
elif event.key == pygame.K_SPACE: # 空格键暂停
pause = not pause # 取非即可实现暂停和继续
elif event.key == pygame.K_s: # s键发射子弹
print("发射子弹")
bullets.append({'x': hero_x + 50, 'y': hero_y - 50}) # 初始化子弹的位置
# 子弹要持续的发射,画出子弹, 会持续遍历整个列表,实现飞机移动了,子弹还能再之前的位置动
for i in bullets:
# 绘制多个子弹,一排三个
screen.blit(bullet, (i['x'], i['y']))
screen.blit(bullet, (i['x'] + 20, i['y']))
screen.blit(bullet, (i['x'] - 20, i['y']))
i['y'] -= 20
# 敌机, 敌机是不能发射子弹的, 低级版,每次只生成一台
def enemy_plane(scree, enemy):
global status
if status == 'live':
if len(enemies) < 1:
enemy_x = random.randint(10, 600)
enemy_y = 10
enemies.append({'x': enemy_x, 'y': enemy_y})
for i in enemies:
scree.blit(enemy, (i['x'], i['y']))
i['y'] += 1
# 遍历子弹列表,判断子弹和敌机的位置
for bullet in bullets:
if enemies[0]['x'] - 50 < bullet['x'] < enemies[0]['x'] + 133 and enemies[0]['y'] - 75 < bullet['y'] < \
enemies[0]['y'] + 75:
print(enemies[0]['y'], bullet['y'])
bullets.remove(bullet) # 删除子弹
status = 'dead' # 状态变为dead
elif status == 'dead':
bomb_x = enemies[0]['x']
bomb_y = enemies[0]['y']
enemies.clear()
for bomb in bombs:
scree.blit(bomb, (bomb_x, bomb_y)) # 爆炸显示,在敌机的位置上
status = 'live' # 恢复状态
return
def main():
screen = pygame.display.set_mode((700, 600), 0, 30) # 设置屏幕
pygame.display.set_caption('飞机大战') # 标题
bgc_image = pygame.image.load('images/bg.jpg') # 获取背景图
hero = pygame.image.load('images/hero.png') # 英雄机的图
bullet = pygame.image.load('images/bullet.png') # 子弹
enemy = pygame.image.load('images/enemy.png') # 敌机
# 死循环,不断执行函数,不断画图
while True:
screen.blit(bgc_image, (0, 0)) # 贴图, 背景图
hero_plane(screen, hero, bullet) # 英雄机的逻辑实现
if not pause: # 暂停,就不能绘制敌机了
enemy_plane(screen, enemy) # 敌机的逻辑实现
if pause:
font = pygame.font.SysFont('arial', 50)
text = font.render("Pause", True, (255, 0, 0), (255, 255, 255))
text_rect = text.get_rect()
text_rect.center = (350, 300)
screen.blit(text, text_rect)
pygame.display.update() # 更新屏幕
time.sleep(0.05) # 一直显示,能看到效果
if __name__ == '__main__':
main()