今天正好有些时间,就把前两天看到的一篇制作飞机大战的文章
https://blog.csdn.net/A757291228/article/details/116305295,按照步骤复现了一下,同时也改进了其中的一些内容,总结记录一下整个复现过程。
首先制作飞机大战用到的一个包pygame,这个包我之前没接触过,不过没关系,安装一个这个包,接着做。自己按照文章的内容敲一遍代码,然后大致了解了这个包的一些用法:
-
pygame制作的游戏的流程大致是这样的:
-
可以看出整体通过一个循环不断执行代码,直到游戏终止,所以每次循环体内都是游戏运行过程中发生的所有事件的处理方法,最后通过刷新界面显示处理后的结果。
-
主要用到pygame中的如下方法
函数 | 说明 |
---|---|
init | 初始化界面 |
imgae.load | 加载某个路径下的图片 |
display.set_mode | 设置界面的大小 |
screen.blit | 将加载的图片传到界面中的某个位置进行展示 |
event.get() | 捕获所有的事件,关于pygame中的事件其实和c#做winform窗体类似,有很多事件,捕获到事件后,然后对捕获的不同的事件设置不同的响应。 |
display.update() | 刷新界面,不刷新界面,是没有办法展现的。 |
- 由于制作的相对来说是比较简单的,所以大体上就用到了上述方法,所以主要的内容就是写处理事件响应代码。
- 另外,自己做出了一些小的改动,添加了一些新的事件,修改了一些事件的响应,比如:子弹打到敌机之后子弹和敌机同时消失、飞机按方向键松开后就停止移动。
完整代码如下:
关于代码中的素材,请点击下载
import math
import random
import pygame
bg = pygame.image.load(r'.\img\bg.png') # load加载图片,背景图
hero = pygame.image.load(r'.\img\hero1.png') # 主角图
enemy = pygame.image.load(r'.\img\enemy1.png') # 敌人图
enemy_boom = pygame.image.load(r'.\img\enemy1_down1.png') # 敌人爆炸图
bullet = pygame.image.load(r'.\img\bullet1.png') # 子弹图
heroX = 250
heroY = 680
stepX = 0
stepY = 0
bullets_pos = []
enemy_speed = 2
enemy_objs = []
pygame.init()
screen = pygame.display.set_mode((600, 800)) # 创建窗口,窗口的大小为(600, 800)
pygame.display.set_caption("这是一个飞机游戏") # 设置窗口的标题
def distance(bx, by, ex, ey):
a = bx - ex
b = by - ey
return math.sqrt(a * a + b * b)
def screen_border(X, Y):
# 左右屏幕
if X < 0:
X = 0
elif X > 500:
X = 500
# 上下屏幕
if Y < 0:
Y = 0
elif Y > 700:
Y = 700
return X, Y
def keydown_envent(event, stepX, stepY, hero_pos):
"""
按键事件控制目标移动
:param event: 事件
:param stepX: x方向移动距离
:param stepY: y方向移动距离
:return: 移动后的stepX和stepY
"""
bullet_pos = []
if event.key == pygame.K_RIGHT:
stepX = 2
elif event.key == pygame.K_LEFT:
stepX = -2
elif event.key == pygame.K_UP:
stepY = -2
elif event.key == pygame.K_DOWN:
stepY = 2
elif event.key == pygame.K_SPACE:
bullet_pos = [hero_pos[0], hero_pos[1]]
return stepX, stepY, bullet_pos
def enemy_show(enemy_objs, startY=-40):
"""
添加5个敌人,并令敌人移动5个单位
:param enemy_objs:
:param startY: 敌人出现的y坐标位置
:return: enemy_objs 返回敌人移动后的坐标
"""
if len(enemy_objs) < 5:
while len(enemy_objs) < 5:
enemy_X = random.randint(0, 500)
enemy_pos = [enemy_X, startY]
screen.blit(enemy, enemy_pos)
enemy_objs.append(enemy_pos)
else:
i = 0
for pos in enemy_objs:
if pos[1] >= 700:
pos[1] = 0
screen.blit(enemy, pos)
enemy_objs[i] = [pos[0], pos[1] + enemy_speed]
i = i + 1
return enemy_objs
while True:
bullet_pso = []
heroX += stepX
heroY += stepY
heroX, heroY = screen_border(heroX, heroY)
screen.blit(bg, (0, 0)) # blit在屏幕上画出加载的图片,第一个参数是图片参数,第二个参数是整个屏幕的x和y坐标,x越大越靠右,y越大越靠下
screen.blit(hero, (heroX, heroY))
enemy_objs = enemy_show(enemy_objs) # 增加敌机
i = 0
for v in bullets_pos:
if v[1] < 0:
pass
bullets_pos[i] = [v[0], v[1] - 5]
screen.blit(bullet, (bullets_pos[i][0] + 45, bullets_pos[i][1]))
distance_b = [bullets_pos[i][0], bullets_pos[i][1]]
ei = 0
for ep in enemy_objs:
if distance(distance_b[0], distance_b[1], ep[0], ep[1]) < 60:
screen.blit(enemy_boom, (ep[0], ep[1]))
bullets_pos[i][1] = -1
enemy_objs[ei] = [random.randint(0, 500), -50]
ei = ei + 1
i = i + 1
for event in pygame.event.get(): # get()将会获取玩家做的所有事情
if event.type == pygame.QUIT:
exit()
if event.type == pygame.KEYUP:
if event.key == pygame.K_SPACE:
pass
else:
stepX = stepY = 0
if event.type == pygame.KEYDOWN:
stepX, stepY, bullets_pos_ = keydown_envent(event, stepX, stepY, [heroX, heroY])
if len(bullets_pos_) > 0:
bullets_pos.append(bullets_pos_)
pygame.display.update() # 刷新界面