本期继续介绍python游戏编程,仍然是基于pgzero。关于该软件包的基础使用技巧可参考本人专栏文章:
老娄:python游戏编程之pgzero使用介绍zhuanlan.zhihu.com思考
本项目要实现的玩法是用下面的反弹板去接球,然后让球反弹上去,碰撞到砖块,砖块消失。这里有几个功能点要考虑:
- 移动最下方的反弹板,这是键盘方向键控制的动作,需要 "on_key_down" 事件,但通过前面几个游戏的练习,我们已经知道如果将角色的移动写到 "on_key_down" 事件的话,那就只是按一次鼠标,产生一次移动,如果需要持续移动,则应该写到 update 方法中。所以你看,过往的经历都是有积累滴。
- 需要处理“碰撞”, 官网上有一个方法“ methods like .colliderect() which can be used to test whether two actors have collided...“
- 球的移动是重点
- 球反弹,有一定的物理角度控制(已知角色有一个angle的属性表示方向的朝向);而且碰撞不同的对象,反弹角度的设置有所不同
- 碰到下底部,游戏结束
代码全文
import pgzrun
import pgzero
from random import randint
import math
WIDTH = 800 + 5 * 10
HEIGHT = 500
BRICK_WIDTH = 80
BRICK_HEIGHT = 20
global FINISH
FINISH = False
global SUCCESS
SUCCESS = False
global direction
direction = None
#初始化,设置游戏场景,添加三排砖块
global bricks
bricks = []
for i in range(0,4):
for j in range(0,10):
brick = Actor("brick")
brick.topleft = (j * BRICK_WIDTH + j * 5, i * BRICK_HEIGHT + i * 5)
bricks.append(brick)
#添加一个反弹板
bounce_pad = Actor("bounce")
bounce_pad.midbottom = (int(WIDTH/2), HEIGHT)
#添加球
ball = Actor("flying_ball")
ball.midbottom = (int(WIDTH/2),HEIGHT-BRICK_HEIGHT)
#给它一个初始的方向 和 移动步长
# ball.angle = 60
ball.dx = 3
# ball.dy = math.tan(ball.angle) * (-1) * ball.dx
ball.dy = -3
#设置一个击中砖块的逻辑
global HIT_BRICK
HIT_BRICK = False
global HIT_PAD
HIT_PAD = False
def update():
global bricks
global FINISH
global SUCCESS
global HIT_BRICK
global HIT_PAD
check_finish()
ball_collide_brick()
ball_collide_pad()
if FINISH:
return
if not FINISH and len(bricks) == 0:
SUCCESS = True
#最下方反弹板的移动
if direction == "left" and bounce_pad.x >= 0:
bounce_pad.x -= 3
elif direction == "right" and bounce_pad.x <= WIDTH:
bounce_pad.x += 3
#球碰撞左、右两侧
if ball.left <= 0 or ball.right >= WIDTH:
ball.dx = (-1) * ball.dx
#碰撞顶层的砖块、碰撞下面的反弹板,运动轨迹的改变是相同的
if HIT_BRICK or HIT_PAD:
# ball.angle = (-1) * ball.angle
ball.dy = (-1) * ball.dy
HIT_BRICK = False
HIT_PAD = False
#小球的移动
# ball.dy = math.tan(ball.angle) * (-1) * ball.dx
ball.x += ball.dx
ball.y += ball.dy
def draw():
screen.fill((255,255,255))
if FINISH:
screen.draw.text("GAME OVER!", (100, 100), color="green", fontsize=150)
return
if SUCCESS:
screen.draw.text("YOU WIN!", (100, 100), color="green", fontsize=150)
return
bounce_pad.draw()
ball.draw()
for b in bricks:
b.draw()
def on_key_down(key):
global direction
if key == keys.LEFT:
direction = "left"
elif key == keys.RIGHT:
direction = "right"
else:
return
def check_finish():
global FINISH
if ball.bottom >= HEIGHT:
FINISH = True
def ball_collide_brick():
global bricks
global HIT_BRICK
#当小球碰到砖块时,砖块消失,小球反弹
for b in bricks:
if ball.colliderect(b):
bricks.remove(b)
HIT_BRICK = True
break
def ball_collide_pad():
global HIT_PAD
if ball.colliderect(bounce_pad):
HIT_PAD = True
pgzrun.go()
游戏效果
详见下方视频:
知乎视频www.zhihu.com