js小球与边框碰撞反弹_python游戏编程系列-反弹球

本文介绍如何使用Python的pgzero库制作一款反弹球游戏。玩家通过键盘控制反弹板接球,球碰撞砖块后消失。游戏涉及事件处理、碰撞检测及物理角度控制等编程技巧。
摘要由CSDN通过智能技术生成

5a254990a6bd9cfb0952222039404bf4.png

本期继续介绍python游戏编程,仍然是基于pgzero。关于该软件包的基础使用技巧可参考本人专栏文章:

老娄:python游戏编程之pgzero使用介绍​zhuanlan.zhihu.com
5ecda9abdfb8b9fe0e5aaf94df98aac1.png

思考

本项目要实现的玩法是用下面的反弹板去接球,然后让球反弹上去,碰撞到砖块,砖块消失。这里有几个功能点要考虑:

  • 移动最下方的反弹板,这是键盘方向键控制的动作,需要 "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
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值