最近很多人在玩一个《贪吃蛇大作战》的游戏,以前小时候也经常在文曲星上玩贪吃蛇这个小游戏,于是自己就试着写一个传统的贪吃蛇游戏来玩玩,先写了一个简单demo。
我们知道小蛇是由一块块正方形的块组成的,于是首先需要的就是画出方格地图。我用的cocos2dx的lua版本来做这个小游戏的
SCREEN_WIDTH =(cc.Director:getInstance():getOpenGLView():getVisibleSize().width)
SCREEN_HEIGHT =(cc.Director:getInstance():getOpenGLView():getVisibleSize().height)
self.cell_width = 50 -- 方格的大小
self.column_num = math.floor(SCREEN_WIDTH / self.cell_width) -- 列
self.row_num = math.floor(SCREEN_HEIGHT / self.cell_width) -- 行
for i = 0, self.row_num do
local line = cc.DrawNode:create()
line:drawLine(cc.p(0, self.cell_width * i),
cc.p(SCREEN_WIDTH, self.cell_width * i), cc.c4f(0, 0, 0, 0.4))
self:addChild(line)
end
for i = 0, self.column_num do
local line = cc.DrawNode:create()
line:drawLine(cc.p(self.cell_width * i, 0),
cc.p(self.cell_width * i, SCREEN_HEIGHT), cc.c4f(0, 0, 0, 0.4))
self:addChild(line)
end
生成的方格如图所示
可以看见右边和上面有部分格子没有显示出来,主要是我们画线的时候设置的横线终点和竖线终点是屏幕大小,这样显然不对, 修改成这样:
横线终点是self.column_num * self.cell_width
竖线终点是self.row_num * self.cell_width
for i = 0, self.row_num do
local line = cc.DrawNode:create()
line:drawLine(cc.p(0, self.cell_width * i),
cc.p(self.column_num * self.cell_width, self.cell_width * i), cc.c4f(0, 0, 0, 0.4))
self:addChild(line)
end
for i = 0, self.column_num do
local line = cc.DrawNode:create()
line:drawLine(cc.p(self.cell_width * i, 0),
cc.p(self.cell_width * i, self.row_num * self.cell_width), cc.c4f(0, 0, 0, 0.4))
self:addChild(line)
end
改动后的效果
现在将方格设置我30大小 如图:
把所有方格坐标放入一个数组中以备后面用
self.cells = {}
for i = 0, self.row_num do
for j = 0, self.column_num do
if i * self.cell_width + self.cell_width <= SCREEN_HEIGHT and
j * self.cell_width + self.cell_width <= SCREEN_WIDTH then
table.insert(self.cells, cc.p(j * self.cell_width, i * self.cell_width))
end
end
end
定义的lua文件SnakeGame.lua
SCREEN_WIDTH =(cc.Director:getInstance():getOpenGLView():getVisibleSize().width)
SCREEN_HEIGHT =(cc.Director:getInstance():getOpenGLView():getVisibleSize().height)
local SnakeGame = class("SnakeGame", function() return ccui.Layout:create() end)
SnakeGame.Dir = {LEFT = 180, DOWN = 90, RIGHT = 0, UP = 270}
function SnakeGame:ctor()
self:setContentSize(cc.size(SCREEN_WIDTH, SCREEN_HEIGHT))
self:setBackGroundColorType(ccui.LayoutBackGroundColorType.solid)
self:setBackGroundColor(cc.c3b(0xff, 0xff, 0xff))
self:setBackGroundColorOpacity(240)
self.column_num = 0
self.row_num = 0
self.cell_width = 30
self.start_body_length = 5 -- 蛇初始长度
self.direction = SnakeGame.Dir.LEFT
self.snakes = {} --蛇的身体部分
self.tail = nil -- 蛇去吃的目标..
self:init()
self:registGlobaleEvt()
end
function SnakeGame:registGlobaleEvt()
local onEvent = function(evt)
if evt == "enter" then
self:onEnter()
elseif evt == "exit" then
self:onExit()
end
end
self:registerScriptHandler(onEvent)
end
function SnakeGame:onEnter()
local update = function(dt)
end
self:scheduleUpdateWithPriorityLua(update, 0)
end
function SnakeGame:onExit()
self:unscheduleUpdate()
end
function SnakeGame:init()
self.column_num = math.floor(SCREEN_WIDTH / self.cell_width)
self.row_num = math.floor(SCREEN_HEIGHT / self.cell_width)
-- tsixi.TButton就是cocos自己的button按钮,我简单封装了一下, 没得什么影响!
local closeBtn = tsixi.TButton:create("ui/common/btn_exit.png")
closeBtn:setPosition(SCREEN_WIDTH - 10, SCREEN_HEIGHT - 10)
closeBtn:setAnchorPoint(cc.p(1, 1))
closeBtn:addTouchEndListener(function(sender)
-- 暂停
self.parse = not self.parse
end)
self:addChild(closeBtn)
local refreshBtn = tsixi.TButton:create("ui/common/btn_refresh_big.png")
refreshBtn:setPosition(closeBtn:getPositionX() - closeBtn:getContentSize().width - 20, closeBtn:getPositionY())
refreshBtn:setAnchorPoint(closeBtn:getAnchorPoint())
refreshBtn:addTouchEndListener(function(sender) self:refresh() end)
self:addChild(refreshBtn)
--tsixi.TLabel也是简单封装的cocos的label函数,无影响
self.tipsLabel = tsixi.TLabel:create("", 16, cc.c3b(0xff, 0, 0))
self.tipsLabel:setPosition(SCREEN_WIDTH * 0.5, SCREEN_HEIGHT - 30)
self:addChild(self.tipsLabel)
-- 蛇会去吃的那个“点”
self.tail = cc.DrawNode:create()
self:addChild(self.tail)
self:initSquare()
end
function SnakeGame:initSquare()
-- 画方格
self.cells = {}
for i = 0, self.row_num do
local line = cc.DrawNode:create()
line:drawLine(cc.p(0, self.cell_width * i), cc.p(self.column_num * self.cell_width, self.cell_width * i), cc.c4f(0, 0, 0, 0.4))
self:addChild(line)
end
for i = 0, self.column_num do
local line = cc.DrawNode:create()
line:drawLine(cc.p(self.cell_width * i, 0), cc.p(self.cell_width * i, self.row_num * self.cell_width), cc.c4f(0, 0, 0, 0.4))
self:addChild(line)
end
for i = 0, self.row_num do
for j = 0, self.column_num do
if i * self.cell_width + self.cell_width <= SCREEN_HEIGHT and j * self.cell_width + self.cell_width <= SCREEN_WIDTH then
table.insert(self.cells, cc.p(j * self.cell_width, i * self.cell_width))
end
end
end
end
下一步增加一个操作的方向按键
function SnakeGame:initArrows()
self.rightArrow = tsixi.TButton:create("ui/common/btn_arrow.png")
self.rightArrow:setPosition(SCREEN_WIDTH - 30, 90)
self:addChild(self.rightArrow)
self.downArrow = tsixi.TButton:create("ui/common/btn_arrow.png")
self.downArrow:setPosition(SCREEN_WIDTH - 90, 30)
self.downArrow:setRotation(90)
self:addChild(self.downArrow)
self.upArrow = tsixi.TButton:create("ui/common/btn_arrow.png")
self.upArrow:setPosition(self.downArrow:getPositionX(), 150)
self.upArrow:setRotation(-90)
self:addChild(self.upArrow)
self.leftArrow = tsixi.TButton:create("ui/common/btn_arrow.png")
self.leftArrow:setPosition(SCREEN_WIDTH - 150, self.rightArrow:getPositionY())
self.leftArrow:setScaleX(-1)
self:addChild(self.leftArrow)
local arrowTouched = function(sender)
if sender == self.leftArrow then
self.direction = SnakeGame.Dir.LEFT
elseif sender == self.rightArrow then
self.direction = SnakeGame.Dir.RIGHT
elseif sender == self.downArrow then
self.direction = SnakeGame.Dir.DOWN
elseif sender == self.upArrow then
self.direction = SnakeGame.Dir.UP
end
self.must = true
end
self.rightArrow:addTouchEndListener(arrowTouched)
self.downArrow:addTouchEndListener(arrowTouched)
self.leftArrow:addTouchEndListener(arrowTouched)
self.upArrow:addTouchEndListener(arrowTouched)
end
生成初始蛇的身体及被吃的点
function SnakeGame:refresh()
self.direction = SnakeGame.Dir.LEFT -- 初始方向左
self.is_failed = false
self.find_index = -1
self.tipsLabel:setString("a snake game")
for k, v in ipairs(self.snakes) do
v:removeFromParent(true)
end
self.snakes = {}
local start_x = math.random(1, self.column_num - 10)
local start_y = math.random(1, self.row_num - 4)
for i = 1, self.start_body_length do
local body = self:generateSnake(i + start_x + start_y * self.column_num)
table.insert(self.snakes, body)
end
self:generateBody()
end
function SnakeGame:generateSnake(index)
local body = cc.Sprite:create("ui/common/bg_2.png")
body:setScale(self.cell_width / body:getContentSize().width)
body:setPosition(self.cells[index])
body:setAnchorPoint(0, 0)
body.index = index
self:addChild(body)
return body
end
function SnakeGame:generateBody()
self.tail:clear()
local index = math.random(0, #self.cells)
local x = self.cells[index]
local points = {x, cc.p(x.x + self.cell_width, x.y), cc.p(x.x + self.cell_width, x.y + self.cell_width), cc.p(x.x, x.y + self.cell_width)}
-- 画一个小方块作为蛇的追逐目标
self.tail:drawPolygon(points, #points, cc.c4f(1, 0, 0, 1), 1, cc.c4f(0, 0, 0, 0))
self.tail.index = index
end
这个就是贪吃蛇的初始化。先写在这里吧,下次接着写蛇的移动及碰撞等