下面来实现蛇的移动,我们在initArrows()里面初始化方向按钮时对点击事件做了处理,记录点击的方向作为蛇的移动方向self.direction
function SnakeGame:doMove()
-- 蛇的移动
if not self.is_failed then
-- 蛇有头部(self.snakes[1]) 和身体组成,它又很多个“节点”组成的
-- 蛇的移动可以看着头部的移动,然后身体尾随头部移动而已
for i = #self.snakes, 1, -1 do
if i > 1 then
-- 当前身体“节点”部分的坐标设置为它的前一个“节点”的坐标
self.snakes[i]:setPosition(self.snakes[i - 1]:getPosition())
self.snakes[i].index = self.snakes[i - 1].index
else
-- 头部的坐标依据移动方向来设定!
if self.direction == SnakeGame.Dir.LEFT then
self.snakes[i]:setPosition(self.snakes[i]:getPositionX() - self.cell_width, self.snakes[i]:getPositionY())
self.snakes[i].index = self.snakes[i].index - 1
elseif self.direction == SnakeGame.Dir.RIGHT then
self.snakes[i]:setPosition(self.snakes[i]:getPositionX() + self.cell_width, self.snakes[i]:getPositionY())
self.snakes[i].index = self.snakes[i].index + 1
elseif self.direction == SnakeGame.Dir.DOWN then
self.snakes[i]:setPosition(self.snakes[i]:getPositionX(), self.snakes[i]:getPositionY() - self.cell_width)
self.snakes[i].index = self.snakes[i].index - self.column_num
elseif self.direction == SnakeGame.Dir.UP then
self.snakes[i]:setPosition(self.snakes[i]:getPositionX(), self.snakes[i]:getPositionY() + self.cell_width)
self.snakes[i].index = self.snakes[i].index + self.column_num
end
end
end
end
end
检测蛇是否死亡,头部到达边界或者与身体有碰撞则认为死亡!
function SnakeGame:checkBoundary()
local head_x = self.snakes[1]:getPositionX()
local head_y = self.snakes[1]:getPositionY()
if head_x >= self.column_num * self.cell_width or head_y >= self.row_num * self.cell_width or head_x < 0 or head_y < 0 then
self.tipsLabel:setString(string.format("failed! eated : %d", #self.snakes - self.start_body_length))
self.is_failed = true
return
end
for k, v in ipairs(self.snakes) do
if k > 2 then
if head_x == v:getPositionX() and head_y == v:getPositionY() then
self.tipsLabel:setString(string.format("failed! eated : %d", #self.snakes - self.start_body_length))
self.is_failed = true
break
end
end
end
end
检测目标物是否可以吞噬,判断头部在移动方向上是否可以通过下一步移动来到达目标
function SnakeGame:checkSwallow()
local head_x = self.snakes[1]:getPositionX()
local head_y = self.snakes[1]:getPositionY()
local body_pos = self.cells[self.tail.index]
local b = false
if self.direction == SnakeGame.Dir.LEFT then
b = head_x == body_pos.x + self.cell_width and head_y == body_pos.y
elseif self.direction == SnakeGame.Dir.RIGHT then
b = head_x == body_pos.x - self.cell_width and head_y == body_pos.y
elseif self.direction == SnakeGame.Dir.DOWN then
b = head_x == body_pos.x and head_y == body_pos.y + self.cell_width
elseif self.direction == SnakeGame.Dir.UP then
b = head_x == body_pos.x and head_y == body_pos.y - self.cell_width
end
if b then
local body = self:generateSnake(self.tail.index)
-- 吞噬后的目标作为新的头部,放在数组的第一个位置
table.insert(self.snakes, 1, body)
-- 重新生成目标物
self:generateBody()
self.tipsLabel:setString(string.format("eated: %d", #self.snakes - self.start_body_length))
return true
end
end
修改doMove里面增加判断让碰撞到边界不再做移动,实现吞噬时当前也不移动(因为吞噬时将目标已经加入到了snakes的头部)
function SnakeGame:doMove()
if self:checkSwallow() then
return
end
self:checkBoundary()
if not self.is_failed then
for i = #self.snakes, 1, -1 do
if i > 1 then
self.snakes[i]:setPosition(self.snakes[i - 1]:getPosition())
self.snakes[i].index = self.snakes[i - 1].index
else
if self.direction == SnakeGame.Dir.LEFT then
self.snakes[i]:setPosition(self.snakes[i]:getPositionX() - self.cell_width, self.snakes[i]:getPositionY())
self.snakes[i].index = self.snakes[i].index - 1
elseif self.direction == SnakeGame.Dir.RIGHT then
self.snakes[i]:setPosition(self.snakes[i]:getPositionX() + self.cell_width, self.snakes[i]:getPositionY())
self.snakes[i].index = self.snakes[i].index + 1
elseif self.direction == SnakeGame.Dir.DOWN then
self.snakes[i]:setPosition(self.snakes[i]:getPositionX(), self.snakes[i]:getPositionY() - self.cell_width)
self.snakes[i].index = self.snakes[i].index - self.column_num
elseif self.direction == SnakeGame.Dir.UP then
self.snakes[i]:setPosition(self.snakes[i]:getPositionX(), self.snakes[i]:getPositionY() + self.cell_width)
self.snakes[i].index = self.snakes[i].index + self.column_num
end
end
end
end
end
让蛇自己移动起来! 每调用一次doMove函数蛇就沿direction方向移动一格
在onEnter函数的update里面做处理
function SnakeGame:onEnter()
-- 从c++那边导出的一个取得当前毫秒的函数(lua中我不知道哪个函数可以实现这个)
local time1 = tsixi.THelper:currentMilliseconds()
local update = function(dt)
-- 没有死亡则下一步
if not self.is_failed then
local now = tsixi.THelper:currentMilliseconds()
-- 每500ms移动一次或者点了方向按钮立即做一次移动
if not self.parse and (now - time1 >= 500 or self.must) then
self.must = false
time1 = now
self:doMove()
end
end
end
self:scheduleUpdateWithPriorityLua(update, 0)
end
基本上传统的贪吃蛇就完成了!
用到的图片
接下来准备用A*算法来写一个贪吃蛇的自动寻路,有点意思