iT邦幫忙

2023 iThome 鐵人賽

DAY 18
1
自我挑戰組

WiFiBoy Python 玩學機介紹系列 第 18

18. 經典遊戲(三) 吃豆子遊戲

  • 分享至 

  • xImage
  •  

經典的 Pong 遊戲

各位是否有玩過 Pong 這個經典遊戲?根據維基百科上的介紹,Pong 遊戲是 Atari 公司在 1972年11月推出的大型電玩遊戲。它是一款模擬桌球競賽的遊戲。玩家目的就是將球擊出,讓對手無法回擊而取分,最快取得七分者,即為贏家。

https://ithelp.ithome.com.tw/upload/images/20230919/20105707hqOmEpbCtj.jpg

https://ithelp.ithome.com.tw/upload/images/20230919/20105707ciMf8bwaNG.png

這個遊戲雖然畫面簡單,但藉由模擬乒乓球的動作,讓玩家們彼此勾心鬥角,想辦法用各種技巧,讓對手來不及反應而失誤。初學開發遊戲程式的學員也會用這個例子,練習幾個技巧:

  1. 畫面繪製
  2. 鍵盤按鍵控制
  3. 運動畫面繪製
  4. 碰撞模擬系統

今日,我們就來教大家如何做一個簡易型的類似Pong遊戲。

從控制一個點開始

要讓初學者控制一個點在玩學機的畫面上移動,並非易事。原因有幾個,第一就是使用者往往不熟悉電腦動畫的基礎。早期電腦擅長的工作是純運算,後來逐漸加強繪圖能力。但繪圖並不是直接能做動畫。由於早期電腦的硬體限制,無法處理太大的動畫程式(需要的記憶體過多)。因此,聰明的程式設計師就想到利用人類視覺暫留的原理,利用在記憶體特定區域,繪製平面圖的像素點後,再快速抹除部份內容後重新繪製,再顯示圖像,形成物體會動的錯覺。

我們可以先用一個簡單的例子來說明,我們先在玩學機的左側產生一個紅色方塊,代表是一顆乒乓球。我們要讓它自動地向右邊移動,要怎麼做呢?

  1. 先將開機畫面清除,讓背景變成黑色
  2. 在指定的位置(20, 30)先畫一個方塊
  3. 然後清除畫面
  4. 再到 (22, 30) 重新繪製一個方塊
  5. 以此類推,就會感到方塊好像在移動。
wb.cls()
while True:
    for x in range(100):
        wb.box(20+x, 30, 10, 10, wb.RED)
        wb.cls()
        time.sleep(0.01)

此時您會發現一個問題,就是螢幕閃動的很厲害,原因是畫面重繪是使用 wb.cls() 函數,是將整個畫面重新繪製,不僅速度慢,畫面全部更新,自然就會覺得畫面閃動大。此時我們可以用底下的程式來改善。

wb.cls()
while True:
    for x in range(100):
        wb.box(20+x, 30, 10, 10, wb.RED)
        time.sleep(0.01)
        wb.box(20+x, 30, 10, 10, wb.BLACK)

原來是直接針對原本的位置,用黑色再畫一次,即可讓原本的方塊消失。

來回碰撞的球

我們只要設定終點座標,讓座標值反向回數即可。

wb.cls()
while True:
    for x in range(100):
        wb.box(20+x, 30, 10, 10, wb.RED)
        time.sleep(0.01)
        wb.box(20+x, 30, 10, 10, wb.BLACK)
    for x in range(100):
        wb.box(120-x, 30, 10, 10, wb.RED)
        time.sleep(0.01)
        wb.box(120-x, 30, 10, 10, wb.BLACK)

隨機產生蘋果,看誰在時限內分數最高

感謝玩學運算科技提供一個「吃蘋果競賽」的好玩遊戲,讓大家可以更了解如何運用畫面重繪的技巧來實作這類遊戲。

# WiFiBoy OK:ESP32 Snake-Apple Example
# 2018.10.26, tklua@wifiboy.org
try: 
    if snd: snd.deinit()
except: pass
machine.Pin(17,3).value(1)
snd = machine.PWM(machine.Pin(25 ,3)); snd.duty(0)
def play(f, t): snd.freq(f);snd.duty(50);time.sleep(t);snd.duty(0)
ax = ay = score = dx = dy = 0; sx = sy = 3; f=[]
def update_screen():
    for i in range(320):
        if f[i]==2: wb.box(int(i%20)*8, int(i/20)*8, 8, 8, wb.BLACK); f[i]=0
        elif f[i]==1: wb.box(int(i%20)*8, int(i/20)*8, 8, 8, wb.WHITE)
        elif f[i]==3: wb.box(int(i%20)*8, int(i/20)*8, 8, 8, wb.RED)        
def new_apple(): ax=wb.rand(20); ay=wb.rand(15)+1; f[ay*20+ax]=3; return ax,ay
for i in range(320): f.append(0)  
f[sy*20+sx] = 1
ax,ay = new_apple()
wb.cls(); wb.colors(wb.YELLOW, wb.YELLOW)
while True:
    update_screen()
    f[sy*20+sx]=2
    if (wb.getkey()==4): dx = 1; dy = 0
    elif (wb.getkey()==8): dx = -1; dy = 0
    elif (wb.getkey()==16): dy = 1; dx = 0
    elif (wb.getkey()==32): dy = -1; dx = 0
    sx += dx
    if sx>19: sx = 0
    elif sx<0: sx = 19
    sy += dy
    if sy>15: sy = 1
    elif sy<1: sy = 15
    if sx == ax and sy == ay: # eating apple
        score += 1; play(980, 0.05); play(1180, 0.05)
        wb.box(5,10,20,10,0); wb.str(str(score), 5, 10, 1, 1)
        while sx == ax and sy == ay: ax,ay = new_apple()     
    f[sy*20+sx]=1
    time.sleep(0.05)

感謝大家的支持,明天我們將會介紹「Sprite引擎範例展示」與幾個經典遊戲。


上一篇
17. 經典遊戲(二) 井字遊戲
下一篇
19. 經典遊戲(四): Sprite引擎介紹與小精靈
系列文
WiFiBoy Python 玩學機介紹30
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言