可以看我这篇
https://blog.youkuaiyun.com/ZRXSLYG/article/details/109464128
conf.lua
function love.conf(t)
t.window.width = 150
t.window.height = 150
end
main.lua
map_walk = {} --记录方向, 无方向为nil, 有方向为up right down left
map_cost = {} --记录成本, 初始成本为1, 蛇身成本为100000000
for i=1,love.graphics.getWidth(),1 do
map_walk[i] = {}
map_cost[i] = {}
for j=1,love.graphics.getHeight(),1 do
map_walk[i][j]=nil
map_cost[i][j]=1
end
end
--初始化蛇头、蛇尾位置
--snake_head = {x=math.floor(love.graphics.getWidth()/2),y=math.floor(love.graphics.getHeight()/2)}
snake_head = {x=math.floor(love.graphics.getWidth()/2),y=1}
snake_tail = {x=math.floor(love.graphics.getWidth()/2),y=math.floor(love.graphics.getHeight())}
--食物
food = {}
speed = 0.01
function love.load(arg)
init_snake()
init_food()
end
function love.update(dt)
speed = speed - dt
if speed > 0 then
return
end
speed = 0.01
--head------------------------------------------------
if map_walk[snake_head.x][snake_head.y] == 'up' then
snake_head.y = snake_head.y - 1
elseif map_walk[snake_head.x][snake_head.y] == 'down' then
snake_head.y = snake_head.y + 1
elseif map_walk[snake_head.x][snake_head.y] == 'left' then
snake_head.x = snake_head.x - 1
elseif map_walk[snake_head.x][snake_head.y] == 'right' then
snake_head.x = snake_head.x + 1
end
map_cost[snake_head.x][snake_head.y] = 100000000
--head------------------------------------------------
--tail------------------------------------------------
map_cost[snake_tail.x][snake_tail.y] = 1
if map_walk[snake_tail.x][snake_tail.y] == 'up' then
map_walk[snake_tail.x][snake_tail.y] = nil
snake_tail.y = snake_tail.y - 1
elseif map_walk[snake_tail.x][snake_tail.y] == 'down' then
map_walk[snake_tail.x][snake_tail.y] = nil
snake_tail.y = snake_tail.y + 1
elseif map_walk[snake_tail.x][snake_tail.y] == 'left' then
map_walk[snake_tail.x][snake_tail.y] = nil
snake_tail.x = snake_tail.x - 1
elseif map_walk[snake_tail.x][snake_tail.y] == 'right' then
map_walk[snake_tail.x][snake_tail.y] = nil
snake_tail.x = snake_tail.x + 1
end
--tail------------------------------------------------
if snake_head.x == food.x and snake_head.y == food.y then
init_food()
end
end
function love.draw(dt)
local point = {}
point.x = snake_tail.x
point.y = snake_tail.y
while(point.x ~=snake_head.x or point.y ~= snake_head.y)
do
if map_walk[point.x][point.y] == 'up' then
love.graphics.line(point.x,point.y,point.x,point.y-1)
point.y = point.y-1
elseif map_walk[point.x][point.y] == 'down' then
love.graphics.line(point.x,point.y,point.x,point.y+1)
point.y = point.y+1
elseif map_walk[point.x][point.y] == 'left' then
love.graphics.line(point.x,point.y,point.x-1,point.y)
point.x = point.x-1
elseif map_walk[point.x][point.y] == 'right' then
love.graphics.line(point.x,point.y,point.x+1,point.y)
point.x = point.x+1
end
end
love.graphics.points(food.x,food.y)
end
-------------------------------------------------------------
function init_snake()
local map_cost_total = {} --记录总成本
local map_walk_tmp = {} --记录方向
for i=1,love.graphics.getWidth(),1 do
map_cost_total[i] = {}
map_walk_tmp[i] = {}
for j=1,love.graphics.getHeight(),1 do
map_cost_total[i][j] = 0
map_walk_tmp[i][j] = nil
end
end
--从蛇头找向蛇尾
local queue = PriorityQueueCreate()
PriorityQueuePush(queue,snake_head,0)
map_walk_tmp[snake_head.x][snake_head.y] = 'yes' --随便
while(not PriorityQueueEmpty(queue))
do
local point = PriorityQueuePop(queue)
if point.x == snake_tail.x and point.y == snake_tail.y then
break
end
--up
if point.y-1>=1 then
local point_tmp = {}
point_tmp.x = point.x
point_tmp.y = point.y-1
if map_walk_tmp[point_tmp.x][point_tmp.y] == nil or map_cost_total[point_tmp.x][point_tmp.y]>map_cost_total[point.x][point.y]+map_cost[point_tmp.x][point_tmp.y] then
local cost = map_cost_total[point.x][point.y]+map_cost[point_tmp.x][point_tmp.y]
map_walk_tmp[point_tmp.x][point_tmp.y] = 'down'
map_cost_total[point_tmp.x][point_tmp.y] = cost
PriorityQueuePush(queue,point_tmp,cost+heuristic(point_tmp,snake_tail))
end
end
--down
if point.y+1<=love.graphics.getHeight() then
local point_tmp = {}
point_tmp.x = point.x
point_tmp.y = point.y+1
if map_walk_tmp[point_tmp.x][point_tmp.y] == nil or map_cost_total[point_tmp.x][point_tmp.y]>map_cost_total[point.x][point.y]+map_cost[point_tmp.x][point_tmp.y] then
local cost = map_cost_total[point.x][point.y]+map_cost[point_tmp.x][point_tmp.y]
map_walk_tmp[point_tmp.x][point_tmp.y] = 'up'
map_cost_total[point_tmp.x][point_tmp.y] = cost
PriorityQueuePush(queue,point_tmp,cost+heuristic(point_tmp,snake_tail))
end
end
--left
if point.x-1>=1 then
local point_tmp = {}
point_tmp.x = point.x-1
point_tmp.y = point.y
if map_walk_tmp[point_tmp.x][point_tmp.y] == nil or map_cost_total[point_tmp.x][point_tmp.y]>map_cost_total[point.x][point.y]+map_cost[point_tmp.x][point_tmp.y] then
local cost = map_cost_total[point.x][point.y]+map_cost[point_tmp.x][point_tmp.y]
map_walk_tmp[point_tmp.x][point_tmp.y] = 'right'
map_cost_total[point_tmp.x][point_tmp.y] = cost
PriorityQueuePush(queue,point_tmp,cost+heuristic(point_tmp,snake_tail))
end
end
--right
if point.x+1<=love.graphics.getWidth() then
local point_tmp = {}
point_tmp.x = point.x+1
point_tmp.y = point.y
if map_walk_tmp[point_tmp.x][point_tmp.y] == nil or map_cost_total[point_tmp.x][point_tmp.y]>map_cost_total[point.x][point.y]+map_cost[point_tmp.x][point_tmp.y] then
local cost = map_cost_total[point.x][point.y]+map_cost[point_tmp.x][point_tmp.y]
map_walk_tmp[point_tmp.x][point_tmp.y] = 'left'
map_cost_total[point_tmp.x][point_tmp.y] = cost
PriorityQueuePush(queue,point_tmp,cost+heuristic(point_tmp,snake_tail))
end
end
end
queue = {}
--将找到的路径, 写回map_cost和map_walk里
local point = {}
point.x = snake_tail.x
point.y = snake_tail.y
while(point.x ~=snake_head.x or point.y ~= snake_head.y)
do
map_cost[point.x][point.y] = 100000000 --更新成本
map_walk[point.x][point.y] = map_walk_tmp[point.x][point.y]
if map_walk_tmp[point.x][point.y] == 'up' then
point.y = point.y-1
elseif map_walk_tmp[point.x][point.y] == 'down' then
point.y = point.y+1
elseif map_walk_tmp[point.x][point.y] == 'left' then
point.x = point.x-1
elseif map_walk_tmp[point.x][point.y] == 'right' then
point.x = point.x+1
end
end
--map_cost[snake_head.x][snake_head.y] = 100000000 --更新成本
end
function init_food()
for i=0,10,1 do
--food.x = love.math.random(math.max(0,snake_head.x-100), math.min(love.graphics.getWidth(),snake_head.x+200))
--food.y = love.math.random(math.max(0,snake_head.y-100), math.min(love.graphics.getHeight(),snake_head.y+200))
food.x = love.math.random(1, love.graphics.getWidth())
food.y = love.math.random(1, love.graphics.getHeight())
if map_walk[food.x][food.y] == nil then
break
end
end
local map_cost_total = {} --记录总成本
local map_walk_tmp = {} --记录方向
for i=1,love.graphics.getWidth(),1 do
map_cost_total[i] = {}
map_walk_tmp[i] = {}
for j=1,love.graphics.getHeight(),1 do
map_cost_total[i][j] = 0
map_walk_tmp[i][j] = nil
end
end
--从食物找向蛇头
queue = PriorityQueueCreate()
PriorityQueuePush(queue,food,0)
map_walk_tmp[food.x][food.y] = 'yes' --随便
while(not PriorityQueueEmpty(queue))
do
local point = PriorityQueuePop(queue)
if point.x == snake_head.x and point.y == snake_head.y then
break
end
--up
if point.y-1>=1 then
local point_tmp = {}
point_tmp.x = point.x
point_tmp.y = point.y-1
if map_walk_tmp[point_tmp.x][point_tmp.y] == nil or map_cost_total[point_tmp.x][point_tmp.y]>map_cost_total[point.x][point.y]+map_cost[point_tmp.x][point_tmp.y] then
local cost = map_cost_total[point.x][point.y]+map_cost[point_tmp.x][point_tmp.y]
map_walk_tmp[point_tmp.x][point_tmp.y] = 'down'
map_cost_total[point_tmp.x][point_tmp.y] = cost
PriorityQueuePush(queue,point_tmp,cost+heuristic(point_tmp,snake_head))
end
end
--down
if point.y+1<=love.graphics.getHeight() then
local point_tmp = {}
point_tmp.x = point.x
point_tmp.y = point.y+1
if map_walk_tmp[point_tmp.x][point_tmp.y] == nil or map_cost_total[point_tmp.x][point_tmp.y]>map_cost_total[point.x][point.y]+map_cost[point_tmp.x][point_tmp.y] then
local cost = map_cost_total[point.x][point.y]+map_cost[point_tmp.x][point_tmp.y]
map_walk_tmp[point_tmp.x][point_tmp.y] = 'up'
map_cost_total[point_tmp.x][point_tmp.y] = cost
PriorityQueuePush(queue,point_tmp,cost+heuristic(point_tmp,snake_head))
end
end
--left
if point.x-1>=1 then
local point_tmp = {}
point_tmp.x = point.x-1
point_tmp.y = point.y
if map_walk_tmp[point_tmp.x][point_tmp.y] == nil or map_cost_total[point_tmp.x][point_tmp.y]>map_cost_total[point.x][point.y]+map_cost[point_tmp.x][point_tmp.y] then
local cost = map_cost_total[point.x][point.y]+map_cost[point_tmp.x][point_tmp.y]
map_walk_tmp[point_tmp.x][point_tmp.y] = 'right'
map_cost_total[point_tmp.x][point_tmp.y] = cost
PriorityQueuePush(queue,point_tmp,cost+heuristic(point_tmp,snake_head))
end
end
--right
if point.x+1<=love.graphics.getWidth() then
local point_tmp = {}
point_tmp.x = point.x+1
point_tmp.y = point.y
if map_walk_tmp[point_tmp.x][point_tmp.y] == nil or map_cost_total[point_tmp.x][point_tmp.y]>map_cost_total[point.x][point.y]+map_cost[point_tmp.x][point_tmp.y] then
local cost = map_cost_total[point.x][point.y]+map_cost[point_tmp.x][point_tmp.y]
map_walk_tmp[point_tmp.x][point_tmp.y] = 'left'
map_cost_total[point_tmp.x][point_tmp.y] = cost
PriorityQueuePush(queue,point_tmp,cost+heuristic(point_tmp,snake_head))
end
end
end
queue = {}
--将找到的路径, 写回map_walk里
local point = {}
point.x = snake_head.x
point.y = snake_head.y
while(point.x ~=food.x or point.y ~= food.y)
do
map_walk[point.x][point.y] = map_walk_tmp[point.x][point.y]
if map_walk_tmp[point.x][point.y] == 'up' then
point.y = point.y-1
elseif map_walk_tmp[point.x][point.y] == 'down' then
point.y = point.y+1
elseif map_walk_tmp[point.x][point.y] == 'left' then
point.x = point.x-1
elseif map_walk_tmp[point.x][point.y] == 'right' then
point.x = point.x+1
end
end
end
-------------------------------------------------------------
--优先级队列-----------------------------------------------------------
function PriorityQueueCreate()
return {head=nil,tail=nil}
end
function PriorityQueuePush(list, value, priority)
local node = {value=value,priority=priority,next=nil}
if list.tail == nil then
list.head = node
list.tail = node
return
end
local newhead = {next = list.head}
local node_tmp = newhead
while(node_tmp.next ~= nil)
do
if node.priority<node_tmp.next.priority then
break
end
node_tmp = node_tmp.next
end
node.next = node_tmp.next
node_tmp.next = node
list.head = newhead.next
if list.tail.next ~= nil then
list.tail = list.tail.next
end
end
function PriorityQueuePop(list)
if list.head == nil then
return nil
end
local value = list.head.value
list.head = list.head.next
if list.head == nil then
list.tail = nil
end
return value
end
function PriorityQueueEmpty(list)
if list.head == nil then
return true
else
return false
end
end
--优先级队列-----------------------------------------------------------
function heuristic(a, b)
return (math.abs(a.x - b.x) + math.abs(a.y - b.y))
end
- 只是寻路,不一定是最短路径
- 我是以像素点为单位,分辨率小,效果会好;分辨率高,每次寻路都会卡很久
- 视频
优快云练习