各位是否有玩過 Pong 這個經典遊戲?根據維基百科上的介紹,Pong 遊戲是 Atari 公司在 1972年11月推出的大型電玩遊戲。它是一款模擬桌球競賽的遊戲。玩家目的就是將球擊出,讓對手無法回擊而取分,最快取得七分者,即為贏家。
這個遊戲雖然畫面簡單,但藉由模擬乒乓球的動作,讓玩家們彼此勾心鬥角,想辦法用各種技巧,讓對手來不及反應而失誤。初學開發遊戲程式的學員也會用這個例子,練習幾個技巧:
今日,我們就來教大家如何做一個簡易型的類似Pong遊戲。
要讓初學者控制一個點在玩學機的畫面上移動,並非易事。原因有幾個,第一就是使用者往往不熟悉電腦動畫的基礎。早期電腦擅長的工作是純運算,後來逐漸加強繪圖能力。但繪圖並不是直接能做動畫。由於早期電腦的硬體限制,無法處理太大的動畫程式(需要的記憶體過多)。因此,聰明的程式設計師就想到利用人類視覺暫留的原理,利用在記憶體特定區域,繪製平面圖的像素點後,再快速抹除部份內容後重新繪製,再顯示圖像,形成物體會動的錯覺。
我們可以先用一個簡單的例子來說明,我們先在玩學機的左側產生一個紅色方塊,代表是一顆乒乓球。我們要讓它自動地向右邊移動,要怎麼做呢?
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引擎範例展示」與幾個經典遊戲。