真正的從零開始, 一段代碼一段代碼, 一個函數一個函數地從頭開始構思/編寫一個武俠練功遊戲框架
咱們這個遊戲以人物的狀態變化爲核心, 一切都從這個核心出發, 因此最早編寫的就是這我的物狀態原型.函數
首先定義一下角色的狀態欄:體力,內力,精力,智力,氣,血,寫個狀態類把它們表現出來. 代碼:動畫
-- 角色狀態類 Status = class() function Status:init() -- 體力,內力,精力,智力,氣,血 self.tili = 100 self.neili = 0 self.jingli = 100 self.zhili = 100 self.qi = 100 self.xue = 100 -- 申請一個 200* 300 的圖片, 用來繪製狀態 self.img = image(200, 300) end
爲方便調試,再寫一個繪製方法, 代碼以下:.net
function Status:drawUI() -- 把全部內容先繪製到 self.img 上 setContext(self.img) background(119, 121, 72, 255) fill(36, 112, 111, 255) rect(5,5,200-10,300-10) fill(70, 255, 0, 255) textAlign(LEFT) text("體力: "..self.tili,50,280) text("內力: "..self.neili,50,260) text("精力: "..self.jingli,50,240) text("智力: "..self.zhili,50,220) text("氣 : "..self.qi,50,200) text("血 : "..self.xue,50,180) setContext() sprite(self.img, 200,300) end
最後是一個主程序框架:調試
-- 主程序框架 function setup() displayMode(OVERLAY) myStatus = Status() end function draw() background(32, 29, 29, 255) myStatus:drawUI() end
把上述代碼合起來,就是一個基本的角色狀態了.code
角色的狀態不可能凝固不變,所以,咱們須要爲角色狀態類增長一個用來更新值的方法,原型調試階段,簡單實現最基本功能就能夠了:blog
function Status:update() -- 更新狀態:自我修煉,平常休息,戰鬥 self.neili = self.neili + 10 end
暫時用觸摸動做來觸發這個方法,在屏幕右半部分點擊一次就會調用一次,增長觸摸事件:遊戲
function touched(touch) -- 調試用: 點擊在屏幕右側, 會觸發 Status:update() , 刷新 self.neili 的值 if touch.x > WIDTH/2 and touch.state == ENDED then myStatus:update() end end
如今已經能夠初步跑起來了, 點擊會刷新狀態值.事件
咱們爲了更直觀地瞭解人物狀態的變化, 寫一個雷達圖繪製函數, 具體調試過程就不贅述了, 總之是先寫最簡單的骨架結構, 再一步步填充豐滿, 代碼以下:圖片
-- 角色技能雷達圖 function Status:raderGraph() setContext(self.img) pushMatrix() pushStyle() fill(60, 230, 30, 255) -- 中心座標,半徑,角度 local x0,y0,r,a,s = 150,230,40,360/6,4 -- 計算右上方斜線的座標 local x,y = r* math.cos(math.rad(30)), r* math.sin(math.rad(30)) p = {"體力","內力","精力","智力","氣","血"} axis = {t={vec2(0,r/s),vec2(0,r*2/s),vec2(0,r*3/s),vec2(0,r)}, n={vec2(-x/s,y/s),vec2(-x*2/s,y*2/s),vec2(-x*3/s,y*3/s),vec2(-x,y)}, j={vec2(-x/s,-y/s),vec2(-x*2/s,-y*2/s),vec2(-x*3/s,-y*3/s),vec2(-x,-y)}, z={vec2(0,-r/s),vec2(0,-r*2/s),vec2(0,-r*3/s),vec2(0,-r)}, q={vec2(x/s,-y/s),vec2(x*2/s,-y*2/s),vec2(x*3/s,-y*3/s),vec2(x,-y)}, x={vec2(x/s,y/s),vec2(x*2/s,y*2/s),vec2(x*3/s,y*3/s),vec2(x,y)}} -- 用於繪製圈線的函數 function lines(t,n,j,z,q,x) line(axis.n[n].x, axis.n[n].y, axis.t[t].x, axis.t[t].y) line(axis.n[n].x, axis.n[n].y, axis.j[j].x, axis.j[j].y) line(axis.x[x].x, axis.x[x].y, axis.t[t].x, axis.t[t].y) line(axis.z[z].x, axis.z[z].y, axis.j[j].x, axis.j[j].y) line(axis.x[x].x, axis.x[x].y, axis.q[q].x, axis.q[q].y) line(axis.z[z].x, axis.z[z].y, axis.q[q].x, axis.q[q].y) end -- 平移到中心 (x0,y0), 方便以此爲中心旋轉 translate(x0,y0) -- 圍繞中心點勻速旋轉 rotate(30+ElapsedTime*10) -- 繪製背景圓環 fill(57, 121, 189, 84) strokeWidth(0) ellipse(0,0,2*r/s) ellipse(0,0,4*r/s) ellipse(0,0,6*r/s) ellipse(0,0,r*2) strokeWidth(2) -- noSmooth() stroke(93, 227, 22, 255) fill(60, 230, 30, 255) -- 繪製雷達圖 for i=1,6 do text(p[i],0,45) line(0,0,0,r) rotate(a) end -- 繪製圈線 stroke(255, 0, 0, 102) strokeWidth(2) for i = 1,4 do lines(i,i,i,i,i,i) end end stroke(255, 32, 0, 255) strokeWidth(2) smooth() -- 設定當前各參數的值 print(values()) local t,n,j,z,q,x = 3,2,3,2,4,1 local t,n,j,z,q,x = values() lines(t,n,j,z,q,x) popStyle() popMatrix() setContext() end
基本的雷達圖代碼寫完了, 如今繪製出來的仍是一個靜態的雷達圖, 咱們但願能根據狀態值的刷新而實時更新雷達圖, 那麼就是把這段代碼修改一下, 由於這段代碼只是把 3,2,3,2,4,1
這些固定值賦給這幾個局部變量:
local t,n,j,z,q,x = 3,2,3,2,4,1 lines(t,n,j,z,q,x)
在函數 Status:raderGraph()
內部寫一個函數, 把這幾個局部變量 t,n,j,z,q,x
跟狀態類的各個屬性 self.tili
等關聯起來, 也就是作一個賦值:
-- 處理人物狀態值, 根據它的值大小將其縮減爲 1,2,3,4 並返回 function values() local t,n,j,z,q,x = self.tili, self.neili, self.jingli,self.zhili, self.qi, self.xue local f = math.floor return f(t/25),f((25+math.fmod(n,100))/25),f(j/25),f(z/25),f(q/25),f(x/25) end
把這條語句
local t,n,j,z,q,x = 3,2,3,2,4,1
換成下面這條:
local t,n,j,z,q,x = values()
很好, 如今咱們的雷達圖就能夠隨着狀態值的變化而變化了
不過這種變化仍是不太明顯, 咱們再增長一個旋轉效果, 增長以下語句到相應位置:
-- 圍繞中心點勻速旋轉 rotate(30+ElapsedTime*10)
這樣就會產生一個實時旋轉的效果了, 所有代碼以下:
-- 角色狀態類 Status = class() function Status:init() -- 體力,內力,精力,智力,氣,血 self.tili = 100 self.neili = 90 self.jingli = 70 self.zhili = 100 self.qi = 100 self.xue = 100 self.img = image(200, 300) end function Status:update() -- 更新狀態:自我修煉,平常休息,戰鬥 self.neili = self.neili + 1 end function Status:drawUI() setContext(self.img) background(119, 121, 72, 255) pushStyle() fill(36, 112, 111, 255) rect(5,5,200-10,300-10) fill(70, 255, 0, 255) textAlign(RIGHT) text("體力: "..self.tili,50,280) text("內力: "..self.neili,50,260) text("精力: "..self.jingli,50,240) text("智力: "..self.zhili,50,220) text("氣 : "..self.qi,50,200) text("血 : "..self.xue,50,180) sprite("Documents:B1", 100,90) popStyle() setContext() self:raderGraph() sprite(self.img, 400,300) end -- 角色技能雷達圖 function Status:raderGraph() setContext(self.img) pushMatrix() pushStyle() fill(60, 230, 30, 255) -- 中心座標,半徑,角度 local x0,y0,r,a,s = 150,230,40,360/6,4 -- 計算右上方斜線的座標 local x,y = r* math.cos(math.rad(30)), r* math.sin(math.rad(30)) p = {"體力","內力","精力","智力","氣","血"} axis = {t={vec2(0,r/s),vec2(0,r*2/s),vec2(0,r*3/s),vec2(0,r)}, n={vec2(-x/s,y/s),vec2(-x*2/s,y*2/s),vec2(-x*3/s,y*3/s),vec2(-x,y)}, j={vec2(-x/s,-y/s),vec2(-x*2/s,-y*2/s),vec2(-x*3/s,-y*3/s),vec2(-x,-y)}, z={vec2(0,-r/s),vec2(0,-r*2/s),vec2(0,-r*3/s),vec2(0,-r)}, q={vec2(x/s,-y/s),vec2(x*2/s,-y*2/s),vec2(x*3/s,-y*3/s),vec2(x,-y)}, x={vec2(x/s,y/s),vec2(x*2/s,y*2/s),vec2(x*3/s,y*3/s),vec2(x,y)}} -- 用於繪製圈線的函數 function lines(t,n,j,z,q,x) line(axis.n[n].x, axis.n[n].y, axis.t[t].x, axis.t[t].y) line(axis.n[n].x, axis.n[n].y, axis.j[j].x, axis.j[j].y) line(axis.x[x].x, axis.x[x].y, axis.t[t].x, axis.t[t].y) line(axis.z[z].x, axis.z[z].y, axis.j[j].x, axis.j[j].y) line(axis.x[x].x, axis.x[x].y, axis.q[q].x, axis.q[q].y) line(axis.z[z].x, axis.z[z].y, axis.q[q].x, axis.q[q].y) end -- 平移到中心 (x0,y0), 方便以此爲中心旋轉 translate(x0,y0) -- 圍繞中心點勻速旋轉 rotate(30+ElapsedTime*10) fill(57, 121, 189, 84) strokeWidth(0) ellipse(0,0,2*r/s) ellipse(0,0,4*r/s) ellipse(0,0,6*r/s) ellipse(0,0,r*2) strokeWidth(2) -- noSmooth() stroke(93, 227, 22, 255) fill(60, 230, 30, 255) -- 繪製雷達圖 for i=1,6 do text(p[i],0,45) line(0,0,0,r) rotate(a) end -- 繪製圈線 stroke(255, 0, 0, 102) strokeWidth(2) for i = 1,4 do lines(i,i,i,i,i,i) end function values() local t,n,j,z,q,x = self.tili, self.neili, self.jingli,self.zhili, self.qi, self.xue local f = math.floor return f(t/25),f((25+math.fmod(n,100))/25),f(j/25),f(z/25),f(q/25),f(x/25) end stroke(255, 32, 0, 255) strokeWidth(2) smooth() -- 設定當前各參數的值 print(values()) -- local t,n,j,z,q,x = 3,2,3,2,4,1 local t,n,j,z,q,x = values() lines(t,n,j,z,q,x) popStyle() popMatrix() setContext() end -- main 主程序框架 function setup() displayMode(OVERLAY) myStatus = Status() end function draw() background(32, 29, 29, 255) myStatus:drawUI() -- myStatus:raderGraph() fill(143, 255, 0, 255) rect(WIDTH/2,HEIGHT/2,200,200) fill(0, 55, 255, 255) text("修煉", WIDTH/2+100, HEIGHT/2+100) end function touched(touch) if touch.x > WIDTH/2 and touch.state == ENDED then myStatus:update() end end
把雷達圖函數加載, 運行無誤, 接下來能夠選擇的方向就多了--也意味着工做量和複雜度也大大增長了.
從零開始寫一個武俠練功遊戲-1-狀態原型
從零開始寫一個武俠練功遊戲-2-幀動畫
---本章結束