love2d 2. 自动寻路的贪吃蛇

可以看我这篇
https://blog.csdn.net/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
  1. 只是寻路,不一定是最短路径
  2. 我是以像素点为单位,分辨率小,效果会好;分辨率高,每次寻路都会卡很久
  3. 视频

CSDN练习

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值