海纳百客

海纳百客

用 micro:bit 玩乒乓球无线对战

吃瓜阿阳

友情提示点击顶部放大镜 可以使用站内搜索 记住我们的地址 www.hainabaike.com

我想尝试用 Python 编写一个无线乒乓球游戏,我用一个 micro:bit 控制游戏和决定谁得到一分,玩家B是“从机”,只把它的左右移动发给到游戏者A,然后镜显示在玩家A的屏幕上。

怎样玩

使用 Mu 将玩家A的程序写到一个 micro:bit 中,而玩家B使用另外一个 micro:bit 程序。在micro:bit上你可以选择连接耳机或蜂鸣器到micro:bit的引脚0和1获得声音反馈(在newbit上可以直接使用,甚至可以连接震动马达进行力度反馈)。

玩家B先上电 – 它会等待来自玩家A 的消息,然后玩家A上电。接着开始发球,球是屏幕中间移动的LED点。使用A和B按钮左右移动你的球拍,如果挡住球会随机反向反弹,如果没有击中球,对手将得到一分(分数没有显示在屏幕),先得到5分的玩家获胜。开始下一局需要按复位按钮。

工作原理

玩家B比较容易解释。它在一个循环中不断轮询消息和按键。如果你按A键就向左移动,按B向右移动,它会发送一条包含球拍新位置的信息。它也接收来自对手的消息。它们以不同的代码字母开头:
P + A 是玩家A的位置。
X和Y的信息是球的当前位置,然后调用bat_map用字典查表。
a和b消息给出A和B各自的分数。

如果玩家B得到5分,它将退出循环并播放一首快乐的乐曲(Nyan cat)。如果玩家A赢得比赛将播放一首悲伤的歌(葬礼进行曲)。

玩家A做主控端。它为球选择一个随机方向开始移动,如果球碰到任何一个边,它就会反弹。如果它击中了顶部或底部,而玩家没有挡住球,对手就得到一分。我通过delay和计数器计时 – 每达到1000就移动球(我没有找出在microbit上使用MicroPython定时器的方法)。如果一个玩家用球拍击球,速度会加快一点。它发送(如上所述)的球的位置、得分和玩家A球拍位置给给玩家B。游戏的结束方式和玩家B的代码相同,除了玩家A获胜是高兴曲子和玩家B获胜时放悲伤的曲调。

如何修改

通过将延迟参数变小,可以使游戏更快。你也可以通过增加winning_score使游戏时间变长。
一个很好的扩展是添加更多的声音(例如,当你击中球),每当有人赢了一场比赛,等级越高游戏速度就越快。
让我知道你想如何去改进 — 球弹跳的物理方面是我可以帮助的一个领域!

源代码

玩家A所用的代码如下:

# Pongo by @blogmywiki
# player A code - with points

import radio
import random
from microbit import *
from music import play, POWER_UP, JUMP_DOWN, NYAN, FUNERAL

a_bat = 2              # starting position of player A bat
b_bat = 2              # starting position of player B bat
bat_map = {0: 4, 1: 3, 2: 2, 3: 1, 4: 0}
ball_x = 2             # starting position of ball
ball_y = 2
directions = [1, -1]   # pick a random direction for ball at start
x_direction = random.choice(directions)
y_direction = random.choice(directions)
delay = 1000           # used as a crude timer
counter = 0            # used as a crude timer
a_points = 0
b_points = 0
winning_score = 5
game_over = False

def move_ball():
    global ball_x, ball_y, x_direction, y_direction, counter, a_bat, b_bat, a_points, b_points, delay
    display.set_pixel(ball_x, ball_y, 0)
    ball_x = ball_x + x_direction
    ball_y = ball_y + y_direction
    if ball_x < 0:							# bounce if hit left wall
        ball_x = 0
        x_direction = 1
    if ball_x > 4:							# bounce if hit right wall
        ball_x = 4
        x_direction = -1
    if ball_y == 0:
        if ball_x == b_bat:					# bounce if player B hit ball
            ball_y = 0
            y_direction = 1
            delay -= 50						# speed up after bat hits
        else:
            play(POWER_UP, wait=False)      # A gets point if B missed ball
            a_points += 1
            ball_y = 0
            y_direction = 1
            radio.send('a'+str(a_points))			# transmit points

    if ball_y == 4:							# bounce if player A hits ball
        if ball_x == a_bat:
            ball_y = 4
            y_direction = -1
            delay -= 50						# speed up after bat hits
        else:
            play(JUMP_DOWN, wait=False)     # player B gets point if A misses
            b_points += 1
            ball_y = 4
            y_direction = -1
            radio.send('b'+str(b_points))
    counter = 0
    radio.send('x'+str(ball_x))				# transmit ball position
    radio.send('y'+str(ball_y))

radio.on()    # like the roadrunner

while not game_over:
    counter += 1
    display.set_pixel(a_bat, 4, 6)        # draw bats
    display.set_pixel(b_bat, 0, 6)
    display.set_pixel(ball_x, ball_y, 9)  # draw ball
    if button_a.was_pressed():
        display.set_pixel(a_bat, 4, 0)
        a_bat = a_bat - 1
        if a_bat < 0:
            a_bat = 0
        radio.send('p'+str(a_bat))
    if button_b.was_pressed():
        display.set_pixel(a_bat, 4, 0)
        a_bat = a_bat + 1
        if a_bat > 4:
            a_bat = 4
        radio.send('p'+str(a_bat))
    incoming = radio.receive()
    if incoming:
        display.set_pixel(b_bat, 0, 0)
        b_bat = bat_map[int(incoming)]
    if counter == delay:
        move_ball()
    if a_points == winning_score or b_points == winning_score:
        game_over = True

if a_points > b_points:
    play(NYAN, wait=False)
    display.scroll('A wins!')
else:
    play(FUNERAL, wait=False)
    display.scroll('B wins!')

display.scroll('Press reset to play again')

玩家B所用的代码如下:

# Pongo by @blogmywiki
# player B code

import radio
from microbit import *
from music import play, POWER_UP, JUMP_DOWN, NYAN, FUNERAL

a_bat = 2              # starting position of player A bat
b_bat = 2              # starting position of player B bat
bat_map = {0: 4, 1: 3, 2: 2, 3: 1, 4: 0}
ball_x = 2             # starting position of ball
ball_y = 2
a_points = 0
b_points = 0
winning_score = 5
game_over = False
radio.on()     # like the roadrunner

def parse_message():
    global a_bat, incoming, bat_map, ball_x, ball_y, a_points, b_points
    msg_type = incoming[:1]    # find out what kind of message we have received
    msg = incoming[1:]         # strip initial letter from message
    if msg_type == 'p':
        display.set_pixel(a_bat, 0, 0)
        their_bat = int(msg)     # mirror their bat position
        a_bat = bat_map[their_bat]
    if msg_type == 'x':
        display.set_pixel(ball_x, ball_y, 0)
        ball_x = bat_map[int(msg)]
    if msg_type == 'y':
        display.set_pixel(ball_x, ball_y, 0)
        ball_y = bat_map[int(msg)]
    if msg_type == 'a':
        a_points = int(msg)
        play(JUMP_DOWN, wait=False)
    if msg_type == 'b':
        b_points = int(msg)
        play(POWER_UP, wait=False)

while not game_over:
    display.set_pixel(b_bat, 4, 6)
    display.set_pixel(a_bat, 0, 6)
    display.set_pixel(ball_x, ball_y, 9)  # draw ball
    if button_a.was_pressed():
        display.set_pixel(b_bat, 4, 0)
        b_bat = b_bat - 1
        if b_bat < 0:
            b_bat = 0
        radio.send(str(b_bat))
    if button_b.was_pressed():
        display.set_pixel(b_bat, 4, 0)
        b_bat = b_bat + 1
        if b_bat > 4:
            b_bat = 4
        radio.send(str(b_bat))
    incoming = radio.receive()
    if incoming:
        parse_message()
    if a_points == winning_score or b_points == winning_score:
        game_over = True

if a_points < b_points:
    play(NYAN, wait=False)
    display.scroll('B wins!')
else:
    play(FUNERAL, wait=False)
    display.scroll('A wins!')

https://github.com/blogmywiki/pongo

    标签:

    发布评论 条评论)

    评论列表