使用Love2D引擎开发贪吃蛇游戏
今天來介紹博主近期搗騰的一個(gè)小游戲[貪吃蛇],貪吃蛇這個(gè)游戲相信大家都不會(huì)感到陌生吧。今天博主將通過Love2D這款游戲引擎來為大家實(shí)現(xiàn)一個(gè)簡單的貪吃蛇游戲,在本篇文章其中我們將會(huì)涉及到貪吃蛇的基本算法、Lua語言編程等主要的內(nèi)容,希望能夠?qū)Υ蠹议_發(fā)相似的游戲提供借鑒和思考,文章中如有不足之處,還希望大家能夠諒解,由于博主的游戲開發(fā)基本就是這樣慢慢摸索著學(xué)習(xí)。所以難免會(huì)有不足的地方。
游戲算法
我們首先來看看貪吃蛇是怎么移動(dòng)的?
通過這四張圖的演示,我們能夠發(fā)現(xiàn)這樣一個(gè)規(guī)律:
蛇的移動(dòng)事實(shí)上是將蛇身體的最后一個(gè)元素移動(dòng)到第一個(gè)元素的位置
那么完畢這樣一個(gè)工作須要兩個(gè)步驟:
1、將在蛇頭位置插入一個(gè)新的元素
2、移除蛇尾位置的最后一個(gè)元素
好了。了解了蛇的移動(dòng)后我們再來考慮一個(gè)問題,如何推斷蛇吃到了食物?思路和蛇的移動(dòng)相似,主要考慮在蛇頭插入的這個(gè)元素和食物的關(guān)系,假設(shè)這個(gè)元素的坐標(biāo)和食物的坐標(biāo)是同樣的,那么就能夠覺得蛇吃到了食物,此時(shí)蛇的身體應(yīng)該是變長的。所以僅僅要在蛇頭位置插入一個(gè)元素就能夠了。反之,假設(shè)蛇沒有吃到食物。那么蛇應(yīng)該是移動(dòng)的。所以就能夠依照移動(dòng)的方法來處理了。那么在蛇頭位置插入的這個(gè)元素該如何確定呢?我們來看以下這段程序:
--計(jì)算下一個(gè)目標(biāo)點(diǎn)
function getNextPoint()
--計(jì)算下一個(gè)目標(biāo)點(diǎn)
snake={}
if(dir==0) then
snake.x=snakes[1].x
snake.y=snakes[1].y-20
end
if(dir==1) then
snake.x=snakes[1].x
snake.y=snakes[1].y+20
end
if(dir==2) then
snake.x=snakes[1].x-20
snake.y=snakes[1].y
end
if(dir==3) then
snake.x=snakes[1].x+20
snake.y=snakes[1].y
end
return snake
end
這里定義了getNextPoint()的方法,目的是計(jì)算在蛇頭位置加入的下一個(gè)元素,這里我們注意到依據(jù)蛇的移動(dòng)方向(dir)的不同,其中0表示上、1表示下、2表示左、3表示右,計(jì)算出下一個(gè)元素的位置,由于在這個(gè)游戲中網(wǎng)格大小是20,所以這里能夠直接依據(jù)坐標(biāo)來計(jì)算一個(gè)元素的位置。
snakes是一個(gè)table,保存的是當(dāng)前的蛇的所有元素的坐標(biāo)。通過維護(hù)這個(gè)table,我們就能夠利用畫圖的函數(shù)繪制出蛇的身體,這樣蛇就能夠移動(dòng)起來了。
我們來看看蛇是如何移動(dòng)的:
--核心算法——蛇的移動(dòng)
function SnakeUpdate()
--獲取元素個(gè)數(shù)
local n=table.maxn(snakes)
if(table.maxn(snakes)>0) then
if(getNextPoint().x==foodX and getNextPoint().y==foodY) then
--將下一個(gè)目標(biāo)點(diǎn)的位置插入表中
table.insert(snakes, 1, getNextPoint())
--將食物狀態(tài)設(shè)置為BeEated
foodState="BeEated"
else
--將下一個(gè)目標(biāo)點(diǎn)的位置插入表中
table.insert(snakes, 1, getNextPoint())
--移除最后一個(gè)元素
table.remove(snakes,n+1)
end
end
end
在這里我們定義了一個(gè)foodState變量以保存食物的狀態(tài)。當(dāng)食物的狀態(tài)為BeEated的時(shí)候表示食物被蛇吃掉了,此時(shí)應(yīng)該又一次生成一個(gè)食物的坐標(biāo)。此時(shí)事物的狀態(tài)將變成WaitToEat。食物的坐標(biāo)保存在foodX和foodY這兩個(gè)變量中。大家能夠到完整的代碼中去查看。
我們知道蛇碰到四周墻壁的時(shí)候就會(huì)死亡,此時(shí)游戲結(jié)束。
這個(gè)比較簡單,僅僅要推斷蛇頭的坐標(biāo)和屏幕的關(guān)系就能夠了。
由于在這個(gè)游戲中屏幕的尺寸為640X640。所以推斷游戲是否結(jié)束的代碼能夠這樣寫:
--推斷游戲狀態(tài)
if(snakes[1].x<=0 or snakes[1].x>=640 or snakes[1].y<=0 or snakes[1].y>=640) then
gameState=0
else
gameState=1
end
這里gameState為0表示游戲結(jié)束。gameState為1表示游戲正常進(jìn)行。
在完畢了這些核心的算法以后,剩下的事情就交給Love2D引擎來繪制吧。最后給出完整的程序代碼:
--定義窗體寬度和高度
local w=640
local h=640
--定義網(wǎng)格單元大小
local unitSize=20;
--方塊的初始位置
local initX=320
local initY=320
--移動(dòng)方向
local dir=1
--貪吃蛇集合
local snakes={}
--食物狀態(tài)
--WaitToEat:繪制食物
--BeEated:隨機(jī)生成食物
local foodState="WaitToEat"
--游戲狀態(tài)
--0:游戲結(jié)束
--1:游戲正常
local gameState=1
--食物的位置
local foodX=0
local foodY=0
--Love2D載入事件
function love.load()
--設(shè)置窗體標(biāo)題
love.window.setTitle("Love2D-貪吃蛇游戲")
--設(shè)置窗體大小
love.window.setMode(w,h)
--定義字體
myFont=love.graphics.newFont(30)
--設(shè)置字體
love.graphics.setFont(myFont)
--設(shè)置背景色
love.graphics.setBackgroundColor(255,255,255,255)
--設(shè)置線條類型為平滑
love.graphics.setLineStyle("smooth")
--設(shè)置線寬
love.graphics.setLineWidth(0.1)
--蛇的初始化(蛇的長度為5)
for i=1,5 do
snake={}
snake.x=initX +(i-1) * 20
snake.y=initY
snakes[i]=snake
end
--食物初始化
foodX=love.math.random(32-1)*20
foodY=love.math.random(32-1)*20
end
--Love2D繪制事件
function love.draw()
--繪制豎線
love.graphics.setColor(0,0,0,255)
for i=0,w,unitSize do
love.graphics.line(0,i,h,i)
end
--繪制橫線
for j=0,h,unitSize do
love.graphics.line(j,0,j,w)
end
--繪制蛇
for i=1,table.maxn(snakes) do
love.graphics.setColor(0,0,255,255)
love.graphics.rectangle("fill",snakes[i].x,snakes[i].y,20,20)
end
--繪制食物
if(foodState=="WaitToEat") then
love.graphics.setColor(255,0,0,255)
love.graphics.rectangle("fill",foodX,foodY,20,20)
end
--假設(shè)游戲結(jié)束則顯示GameOver
if(gameState==0) then
love.graphics.setColor(255,0,0,255)
love.graphics.print("Game Over",250,300)
end
end
--
function love.update(dt)
--推斷游戲狀態(tài)
if(snakes[1].x<=0 or snakes[1].x>=640 or snakes[1].y<=0 or snakes[1].y>=640) then
gameState=0
else
gameState=1
end
--假設(shè)游戲狀態(tài)為正常
if(gameState==1) then
SnakeUpdate()
FoodUpdate()
end
end
--核心算法——蛇的移動(dòng)
function SnakeUpdate()
--獲取元素個(gè)數(shù)
local n=table.maxn(snakes)
if(table.maxn(snakes)>0) then
if(getNextPoint().x==foodX and getNextPoint().y==foodY) then
--將下一個(gè)目標(biāo)點(diǎn)的位置插入表中
table.insert(snakes, 1, getNextPoint())
--將食物狀態(tài)設(shè)置為BeEated
foodState="BeEated"
else
--將下一個(gè)目標(biāo)點(diǎn)的位置插入表中
table.insert(snakes, 1, getNextPoint())
--移除最后一個(gè)元素
table.remove(snakes,n+1)
end
end
end
--隨機(jī)生成食物
function FoodUpdate()
--假設(shè)食物被蛇吃掉則又一次生成食物
if(foodState=="BeEated") then
foodX=love.math.random(32-1)*20
foodY=love.math.random(32-1)*20
foodState="WaitToEat"
end
end
--依據(jù)玩家按下的鍵位定義不同的方向
function love.keypressed(key)
if(key=="a" and dir~=3) then
dir=2
end
if(key=="d" and dir~=2) then
dir=3
end
if(key=="w" and dir~=1) then
dir=0
end
if(key=="s" and dir~=0) then
dir=1
end
end
function getNextPoint()
--計(jì)算下一個(gè)目標(biāo)點(diǎn)
snake={}
if(dir==0) then
snake.x=snakes[1].x
snake.y=snakes[1].y-20
end
if(dir==1) then
snake.x=snakes[1].x
snake.y=snakes[1].y+20
end
if(dir==2) then
snake.x=snakes[1].x-20
snake.y=snakes[1].y
end
if(dir==3) then
snake.x=snakes[1].x+20
snake.y=snakes[1].y
end
return snake
end
將代碼壓縮成.love文件后就能夠執(zhí)行了,我們來看看終于的效果:
Github
總結(jié)
以上是生活随笔為你收集整理的使用Love2D引擎开发贪吃蛇游戏的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 阳光惠生活如何注销信用卡(阳光高清图片素
- 下一篇: 自动点击器怎么设置滑动