自己寫的貪吃蛇(1)
阿新 • • 發佈:2019-02-20
最近很多人在玩一個《貪吃蛇大作戰》的遊戲,以前小時候也經常在文曲星上玩貪吃蛇這個小遊戲,於是自己就試著寫一個傳統的貪吃蛇遊戲來玩玩,先寫了一個簡單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
這個就是貪吃蛇的初始化。先寫在這裡吧,下次接著寫蛇的移動及碰撞等