1. 程式人生 > >自己寫的貪吃蛇(1)

自己寫的貪吃蛇(1)

最近很多人在玩一個《貪吃蛇大作戰》的遊戲,以前小時候也經常在文曲星上玩貪吃蛇這個小遊戲,於是自己就試著寫一個傳統的貪吃蛇遊戲來玩玩,先寫了一個簡單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

這裡寫圖片描述

這個就是貪吃蛇的初始化。先寫在這裡吧,下次接著寫蛇的移動及碰撞等