继续介绍python游戏编程,仍然是基于pgzero。关于该软件包的基础使用技巧可参考本人专栏文章:
老娄:python游戏编程之pgzero使用介绍zhuanlan.zhihu.com![a1eb432295a94e5ef91ada677664244e.png](https://i-blog.csdnimg.cn/blog_migrate/3f008959fd335b93beae6c1e4d769c60.jpeg)
本篇咱们来实现经典小游戏——飞机大战,要求战机在移动过程中摧毁敌方战机。
思考
- 关于移动。根据此前本系列中练习过的技能,咱们对于常规的角色移动就可以通过x,y这样的坐标变化来实现。但通常游戏中的角色如果能够实现移动中的“缓动”——速度会有变化,可以从快到慢或者由慢到快,轨迹也可以是直线或曲线,那么视觉效果会更好。pgzero提供了一个animate()来实现这样的效果。
代码
import pgzrun
import pgzero
import random
import math
WIDTH = 800
HEIGHT = 800
background0 = Actor("earth_background")
background0.topleft = (0,0)
background1 = Actor("earth_background")
background1.midbottom = background0.midtop
backgrounds = []
backgrounds.append(background0)
backgrounds.append(background1)
plane = Actor("plane")
plane.midbottom = (int(WIDTH/2),HEIGHT)
plane.power = False
bullets = [] #子弹列表
enemy_planes = [] #敌机列表
power_bags = [] #增强包
global FINISH
FINISH = False
global SCORE
SCORE = 0
#缓动效果
tweens = ["linear","accelerate","decelerate","accel_decel",
"in_elastic","out_elastic","in_out_elastic","bounce_end",
"bounce_start","bounce_start_end"]
def create_enemy_plane():
enemy_pics = ["enemyplane0","enemyplane1"]
enemy_plane = Actor(random.choice(enemy_pics))
enemy_plane.topleft = (random.randint(0,WIDTH),0)
enemy_planes.append(enemy_plane)
animate(enemy_plane,
tween = random.choice(tweens),
duration = random.randint(5,15),
topleft = (random.randint(0,WIDTH), HEIGHT)
)
clock.schedule_interval(create_enemy_plane, 1.5)
def update():
if FINISH:
clock.unschedule(create_enemy_plane)
update_background()
update_plane()
update_power_bag()
update_bullet()
update_enemy_plane()
def draw():
# screen.fill((255, 255, 255))
screen.draw.text("SCORE: %d" % SCORE, topleft = (20, 100), color="green", fontsize=60)
if FINISH:
screen.draw.text("GAME OVER!", (20, 300), color="red", fontsize=80)
return
for b in backgrounds:
b.draw()
plane.draw()
for p in power_bags:
p.draw()
for b in bullets:
b.draw()
for e in enemy_planes:
e.draw()
def update_plane():
global FINISH
speed = 3
if keyboard.LEFT:
plane.x -= speed
elif keyboard.RIGHT:
plane.x += speed
elif keyboard.UP:
plane.y -= speed
elif keyboard.DOWN:
plane.y += speed
else:
pass
if plane.left < 0:
plane.left = 0
if plane.right > WIDTH:
plane.right = WIDTH
if plane.bottom > HEIGHT:
plane.bottom = HEIGHT
if plane.top < 0:
plane.top = 0
#当按下空格键时,增加一枚子弹
if keyboard.SPACE:
clock.schedule_unique(shoot,0.1)
for e in enemy_planes:
if e.colliderect(plane):
FINISH = True
return
def shoot():
bullet = Actor("bullet")
bullet.midbottom = plane.midtop
bullets.append(bullet)
#如果获得了增强包,额外增加两排子弹
if plane.power:
leftbullet = Actor("bullet")
leftbullet.midbottom = plane.midtop
leftbullet.angle = 15
bullets.append(leftbullet)
rightbullet = Actor("bullet")
rightbullet.midbottom = plane.midtop
rightbullet.angle = -15
bullets.append(rightbullet)
def update_bullet():
for b in bullets:
theta = math.radians(b.angle) + 90
b.x += 10*math.cos(theta)
b.y -= 10*math.sin(theta)
if b.bottom < 0:
bullets.remove(b)
def update_background():
for b in backgrounds:
b.y += 1
if b.top > HEIGHT:
b.bottom = 0
def update_enemy_plane():
global SCORE
if FINISH:
return
if len(enemy_planes) == 0:
return
for e in enemy_planes:
if e.top > HEIGHT:
enemy_planes.remove(e)
continue
n = e.collidelist(bullets)
if n != -1:
enemy_planes.remove(e)
SCORE += 100
def update_power_bag():
for p in power_bags:
p.y += 2
if p.bottom > HEIGHT:
power_bags.remove(p)
if p.colliderect(plane):
plane.power = True
power_bags.remove(p)
clock.schedule(power_down,5.0)
if random.randint(0,800) < 5:
power_bag = Actor('warplanes_powerup')
power_bag.topleft = (random.randint(0,WIDTH),100)
power_bags.append(power_bag)
def power_down():
plane.power = False
pgzrun.go()
效果
知乎视频www.zhihu.com参考资料
《趣学python游戏编程》何青 著