Skip to content

Instantly share code, notes, and snippets.

@renyuanL
Created July 6, 2014 14:44
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save renyuanL/3c0aaa6467d5e2e71ab3 to your computer and use it in GitHub Desktop.
Save renyuanL/3c0aaa6467d5e2e71ab3 to your computer and use it in GitHub Desktop.
ryPong.py, 乒乓球 遊戲
'''
ryPong.py
乒乓球
呂仁園,2014/07/06
'''
import random
import tkinter
class 桌類:
def __init__(我,窗,
色= "black",
網色= "green",
寬= 600,
高= 400,
垂直網= True,
水平網= True):
我.寬= 寬
我.高= 高
我.色= 色
我.布= tkinter.Canvas(窗,
bg= 我.色,
height= 我.高,
width= 我.寬)
我.布.pack()
if(垂直網):
我.布.create_line(我.寬/2, 0, 我.寬/2, 我.高,
width= 2,
fill= 網色,
dash= (15, 23))
if(水平網):
我.布.create_line(0, 我.高/2, 我.寬, 我.高/2,
width= 2,
fill= 網色,
dash= (15, 23))
字型= ("times", 72)
我.記分板= 我.布.create_text(我.寬/2, 65,
font= 字型,
fill= "magenta")
def 畫方(我, 方):
x1= 方.位x
y1= 方.位y
x2= x1 + 方.寬
y2= y1 + 方.高
c= 方.色
return 我.布.create_rectangle(x1, y1, x2, y2, fill= c)
def 畫圓(我, 圓):
x1= 圓.位x
y1= 圓.位y
x2= x1 + 圓.寬
y2= y1 + 圓.高
c= 圓.色
return 我.布.create_oval(x1, y1, x2, y2, fill= c)
def 移項(我, 項, x1, y1, x2, y2):
我.布.coords(項, x1, y1, x2, y2)
def 刪項(我, 項):
我.布.delete(項)
def 改項色(我, 項, 色):
我.布.itemconfigure(項, fill= 色)
def 記分(我, 左, 右):
分= str(右) + " : " + str(左) # 這裡怪怪的!
我.布.itemconfigure(我.記分板, text= 分)
class 球類:
def __init__(我, 桌,
寬= 20,
高= 20,
色= "red",
速x= 10,
速y= 5,
位x= 0,
位y= 0):
我.寬= 寬
我.高= 高
我.位x= 位x
我.位y= 位y
我.色= 色
我.位x0= 位x
我.位y0= 位y
我.速x= 速x
我.速y= 速y
我.桌= 桌
我.圓= 我.桌.畫圓(我)
def 設初始位置(我):
我.位x= 我.位x0
我.位y= 我.位y0
def 發球(我, 速x, 速y):
我.速x= -速x if random.randint(0,1) else 速x
我.速y= -速y if random.randint(0,1) else 速y
我.設初始位置()
def 移位(我):
#
# 依速度,改變位置
#
我.位x += 我.速x
我.位y += 我.速y
狀態= ''
#
# 撞左牆:
#
if(我.位x <= 0):
我.位x = 0
我.速x *= -1
狀態= '撞左牆'
#
# 撞右牆:
#
if(我.位x >= 我.桌.寬):
我.位x = 我.桌.寬
我.速x *= -1
狀態= '撞右牆'
#
# 撞上牆:
#
if(我.位y <= 0):
我.位y= 0
我.速y *= -1
狀態= '撞上牆'
#
# 撞下牆:
#
if(我.位y >= 我.桌.高):
我.位y= 我.桌.高
我.速y *= -1
狀態= '撞下牆'
#
# 算出該移動的座標值
#
x1= 我.位x
y1= 我.位y
x2= x1 + 我.寬
y2= y1 + 我.高
#
# 以上數學都算好了,真正的移動指令在此:
#
我.桌.移項(我.圓, x1, y1, x2, y2)
return 狀態 # 把撞牆狀態傳出去
def 停球(我):
我.速x= 0
我.速y= 0
class 拍類:
def __init__(我, 桌,
寬= 20,
高= 100,
位x= 50,
位y= 50,
色= "green",
速x= 20,
速y= 20):
我.寬= 寬
我.高= 高
我.位x= 位x
我.位y= 位y
我.色= 色
我.位x0= 位x
我.位y0= 位y
我.速x= 速x
我.速y= 速y
我.桌= 桌
我.方= 我.桌.畫方(我)
def 偵測碰撞(我, 球):
'''
If the implementation is easy to explain,
it may be a good idea.
>>>拍.偵測碰撞(球)
'''
拍上= 我.位y
拍下= 我.位y + 我.高
拍左= 我.位x
拍右= 我.位x + 我.寬
球上= 球.位y
球下= 球.位y + 球.高
球左= 球.位x
球右= 球.位x + 球.寬
#
# 開始寫碰撞邏輯了
#
球左上撞拍= 球左下撞拍= 球右上撞拍= 球右下撞拍= False
球左上撞拍= ((拍左<球左<拍右) and (拍上<球上<拍下))
球左下撞拍= ((拍左<球左<拍右) and (拍上<球下<拍下))
球右上撞拍= ((拍左<球右<拍右) and (拍上<球上<拍下))
球右下撞拍= ((拍左<球右<拍右) and (拍上<球下<拍下))
碰撞= any([ 球左上撞拍, 球左下撞拍, 球右上撞拍, 球右下撞拍])
# 碰撞後,速度及方向有所變化,遊戲比較好玩。
if(碰撞):
球.速x *= -(1+random.random())
球.速y *= 1+random.random()
def 移上(我, 參數):
我.位y += -我.速y
if(我.位y <= 0):
我.位y = 0
x1 = 我.位x
x2 = 我.位x+我.寬
y1 = 我.位y
y2 = 我.位y+我.高
我.桌.移項(我.方, x1, y1, x2, y2)
def 移下(我, 參數):
我.位y += +我.速y
if(我.位y >= 我.桌.高 - 我.高):
我.位y = 我.桌.高 - 我.高
x1 = 我.位x
x2 = 我.位x+我.寬
y1 = 我.位y
y2 = 我.位y+我.高
我.桌.移項(我.方, x1, y1, x2, y2)
def 移左(我, 參數):
我.位x += -我.速x
if(我.位x <= 0):
我.位x = 0
x1 = 我.位x
x2 = 我.位x+我.寬
y1 = 我.位y
y2 = 我.位y+我.高
我.桌.移項(我.方, x1, y1, x2, y2)
def 移右(我, 參數):
我.位x += +我.速x
if(我.位x >= 我.桌.寬 - 我.寬):
我.位x = 我.桌.寬 - 我.寬
x1 = 我.位x
x2 = 我.位x+我.寬
y1 = 我.位y
y2 = 我.位y+我.高
我.桌.移項(我.方, x1, y1, x2, y2)
def 設初始位置(我):
我.位x= 我.位x0
我.位y= 我.位y0
#
# 設計 遊戲流程
#
def 遊戲流程():
global 暫停遊戲等待發球, 左分, 右分, 目標分
global 窗, 桌, 球, 左拍, 右拍
if(暫停遊戲等待發球 == True):
球.停球() # 其實是設其 速 = 0
#
# 球在動。。。
#
狀態= 球.移位()
左拍.偵測碰撞(球)
右拍.偵測碰撞(球)
if(狀態 in ['撞左牆', '撞右牆']):
球.停球()
球.設初始位置()
暫停遊戲等待發球= True
if(狀態=='撞左牆'):
左分 += 1
if(左分 >= 目標分): 左分, 右分 = "贏", "輸"
if(狀態=='撞右牆'):
右分 += 1
if(右分 >= 目標分): 右分, 左分= "贏", "輸"
桌.記分(左分, 右分)
延遲時間= 10 #延遲時間 (ms) 後,
#自己呼叫自己,這是無窮迴圈。
窗.after(延遲時間, 遊戲流程)
#
# 設計 重新遊戲 的機制
#
def 重新遊戲(參數):
global 暫停遊戲等待發球, 左分, 右分
global 窗, 桌, 球, 左拍, 右拍
球.設初始位置()
左拍.設初始位置()
右拍.設初始位置()
初速x= random.random()*2
初速y= random.random()*2
球.發球(速x= 初速x, 速y= 初速y)
if(左分 in ["贏","輸"]):
左分= 右分= 0
桌.記分(左分, 右分)
暫停遊戲等待發球= False
#
# 設計 控制介面
#
def 綁定控制介面():
global 窗, 桌, 球, 左拍, 右拍
#
# 綁定 按鍵 與 球拍動作(上下左右)
#
窗.bind('<Up>', 右拍.移上)
窗.bind('<Down>', 右拍.移下)
窗.bind('<Left>', 右拍.移左)
窗.bind('<Right>',右拍.移右)
窗.bind('s', 左拍.移上)
窗.bind('x', 左拍.移下)
窗.bind('z', 左拍.移左)
窗.bind('c', 左拍.移右)
#
# 綁定 按鍵 「空白」與 重新遊戲
#
窗.bind('<space>', 重新遊戲)
def 主程式():
global 暫停遊戲等待發球, 左分, 右分, 目標分
global 窗, 桌, 球, 左拍, 右拍
左分= 右分= 0 # 左右打者分數
目標分= 5 # 到達 目標分 即算 贏
暫停遊戲等待發球= True
#
# 從 tkinter 進口 Tk 物類,改名為 窗類
#
窗類= tkinter.Tk
#
# 從 窗類 生 1個 窗
#
窗= 窗類()
窗.title("桌球窗")
#
# 從 桌類 生 1個 桌,放在 窗 內
#
桌= 桌類(窗)
#
# 從 球類 生 1個 球,放在 桌 上
#
球= 球類(
桌= 桌,
色= "red",
寬= 20,
高= 20,
位x= 桌.寬/2,
位y= 桌.高/2
)
#
# 從 拍類 生 2個 拍,左拍、右拍,放在 桌 上。
#
左拍= 拍類(
桌= 桌,
色= "blue",
寬= 20,
高= 100,
位x= 0,
位y= 桌.高/2
)
右拍= 拍類(
桌= 桌,
色= "yellow",
寬= 20,
高= 100,
位x= -20+桌.寬,
位y= 桌.高/2
)
#
# 呼叫遊戲流程,正式開始遊戲。
#
綁定控制介面()
遊戲流程()
#
# 進入 窗 的 主迴圈
#
窗.mainloop()
if __name__=='__main__':
主程式()
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment