cocos2d-x lua 贪吃蛇完整项目

cocos2d-x lua 贪吃蛇游戏 一步一步开发学习
本文地址: http://blog.csdn.net/qq_26437925/article/details/51842647

源代码:
https://github.com/doctording/cocos2dx_lua_snake

学习视频见慕课网

开发环境,项目编译运行

===

windows 直接下载windows版本最新的,网址如下(官网可能变化)
http://www.cocos.com/download/cocos2d-lua/
或者下载网盘里的:http://pan.baidu.com/s/1c2fwhKc

解压到某个目录下就行了,setup.py设置环境
这里写图片描述

切换到如下的目录,既可以创建lua项目
这里写图片描述

shift +鼠标右键,在该目录下打开cmd,输入

cocos.py new Snake -l lua -d d:\

可以在D:\下建立一个Snake 项目,这些都是可选的,自己随便玩

接着用vs2012 或者vs2013 打开如下的解决方案,并完成编译
这里写图片描述

最后可以运行出结果,可在如下的目录中运行,点击exe即可
这里写图片描述

这里写图片描述

有模拟器 和 日志两个窗口,在实际编程中需要多打日志 和 查看日志 分析问题,并解决。


Hello World

===

类似cocos2d-x win32 C++ 功能
程序从 E:\workspace\cocos_lua\Snake\runtime\win32\src\下的main.lua开发,包括了各种配置等(如config.lua的一些屏幕显示配置)

接着 src/app 目录下有个 MyApp.lua,加载了 src/app/scenes/下的MainScene

而Mainscene就是继承了Scene的一个场景了,可以看到有HelloWorld

参考 cocos2d-x lua tolua++ 面向对象
http://blog.csdn.net/qq_26437925/article/details/51842400

因为继承了场景类,所以需要重写一些方法

void onExitTransitionDidStart();//2,创建完layer的时候调用,也就是1调用完之后调用  
void onEnter();//1,创建时调用  
void onExit();//3,退出当前layer的时候调用,在这里都是做一些清除工作  
void onEnterTransitionDidFinish();//在3完成之后,调用该成员方法  

所以我们需要在 onEnter(); 中写各种东西,这样就可以显示Sprite, Button,Label等等了。


坐标转换

===

显示蛇,首先需要重定义坐标,认识屏幕的坐标系统

这里写图片描述

cGridSize 大小依据蛇身体图片的大小而定,自定义一个转换函数,方便用来设置Sprite的位置

local cGridSize = 33
local scaleRate = 1 / display.contentScaleFactor

-- 根据自定义的坐标得到实际应该显示的cocos2d-x坐标位置
function Grid2Pos(x,y)

    local visibleSize = cc.Director:getInstance():getVisibleSize() -- 获取整个手机可视屏幕尺寸

    local origin = cc.Director:getInstance():getVisibleOrigin() -- 获取手机可视屏原点的坐标,屏幕的左上角

    local finalX = origin.x + visibleSize.width / 2 + x * cGridSize * scaleRate
    local finalY = origin.y + visibleSize.height / 2 + y * cGridSize * scaleRate

    return finalX,finalY

end

蛇身

===

有了上面的基础,可以先显示蛇身了

src/app 目录下定义一个Body类,表示蛇身 , 有坐标,是否头部,其父节点等信息,当然完全看自己如何弄

local Body = class("Body")

-- node为cocos2dx-父节点
function Body:ctor(snake , x, y, node, isHead)

    self.snake = snake
    self.X = x
    self.Y = y

    if isHead then -- 根据是否是头部,用不同的图片创建 
        self.sp = cc.Sprite:create("head.png")
    else
        self.sp = cc.Sprite:create("body.png")
    end

    node:addChild(self.sp) -- 添加到父节点

    self:Update()

end

-- 更新自己的位置
function Body:Update()
    local posx,posy = Grid2Pos(self.X , self.Y)
    self.sp:setPosition(posx,posy)
end

return Body

MainScene.lua中

local cGridSize = 33
local scaleRate = 1 / display.contentScaleFactor

-- 根据自定义的坐标得到实际应该显示的cocos2d-x坐标位置
function Grid2Pos(x,y)

    local visibleSize = cc.Director:getInstance():getVisibleSize() -- 获取整个手机可视屏幕尺寸

    local origin = cc.Director:getInstance():getVisibleOrigin() -- 获取手机可视屏原点的坐标,屏幕的左上角

    local finalX = origin.x + visibleSize.width / 2 + x * cGridSize * scaleRate
    local finalY = origin.y + visibleSize.height / 2 + y * cGridSize * scaleRate

    return finalX,finalY

end

-- require相应的类
local Body = require("app.Body") 

local MainScene = class("MainScene", function()
    return display.newScene("MainScene")
end)

function MainScene:onEnter() -- MainScene 加载执行
    -- 测试body
    self.body1 = Body.new(nil,0,0,self,true)

    self.body2 = Body.new(nil,2,2,self,false)
end

return MainScene

显示如下,很预想的一样,就证明没有什么错误了

这里写图片描述


构造一条蛇

===

有了蛇身体,构造一条蛇就容易了
编写一个蛇Snake类,利用Body类

Snake.lua


local Snake = class("Snake")

local Body = require("app.Body")

local cInitLen = 3 -- 蛇初始长度

-- 构造函数
function Snake:ctor(node)

    self.BodyArray = {} -- Body对象数组
    self.node = node
    self.MoveDir = "left" -- 蛇的初始移动方向

    for i = 1,cInitLen do
        self:Grow(i == 1)
    end

end


--取出蛇尾
function Snake:GetTailGrid()
    if #self.BodyArray == 0 then -- 设置蛇头的位置为(0,0)
        return 0,0
    end

    local tail = self.BodyArray[#self.BodyArray]

    return tail.X,tail.Y

end

-- 蛇变长
function Snake:Grow(isHead)

    local tailX,tailY = self:GetTailGrid()
    local body = Body.new(self,tailX,tailY,self.node,isHead)

    table.insert(self.BodyArray,body)

end

-- 根据方向改变坐标
local function OffsetGridByDir(x,y,dir)
    if dir == "left" then
        return x - 1, y
    elseif dir == "right" then
        return x + 1, y
    elseif dir == "up" then
        return x, y + 1
    elseif dir == "down" then
        return x, y - 1
    end

    print("Unkown dir", dir)
    return x, y
end


-- 根据蛇的移动方向 更新蛇,就是BodyArray一个一个往前移动
function Snake:Update()

    if #self.BodyArray == 0 then
        return
    end

    for i = #self.BodyArray , 1 , -1 do

        local body = self.BodyArray[i]

        if i == 1 then -- 蛇头位置 与 方向,得到一个新的位置 存放蛇头
            body.X, body.Y = OffsetGridByDir(body.X, body.Y, self.MoveDir)
        else
            local front = self.BodyArray[i-1]
            body.X, body.Y = front.X, front.Y
        end

        body:Update()

    end

end


-- 取出蛇头
function Snake:GetHeadGrid()
    if #self.BodyArray == 0 then
        return nil
    end

    local head = self.BodyArray[1]

    return head.X, head.Y

end

-- 设置方向
function Snake:setDir(dir)
        self.MoveDir = dir
end

return Snake

响应的MainScene.lua中也要调整下


local cGridSize = 33
local scaleRate = 1 / display.contentScaleFactor

-- 根据自定义的坐标得到实际应该显示的cocos2d-x坐标位置
function Grid2Pos(x,y)

    local visibleSize = cc.Director:getInstance():getVisibleSize() -- 获取整个手机可视屏幕尺寸

    local origin = cc.Director:getInstance():getVisibleOrigin() -- 获取手机可视屏原点的坐标,屏幕的左上角

    local finalX = origin.x + visibleSize.width / 2 + x * cGridSize * scaleRate
    local finalY = origin.y + visibleSize.height / 2 + y * cGridSize * scaleRate

    return finalX,finalY

end

-- require相应的类
-- local Body = require("app.Body")
local Snake = require("app.Snake")

local MainScene = class("MainScene", function()
    return display.newScene("MainScene")
end)

function MainScene:onEnter() -- MainScene 加载执行
        self.snake = Snake.new(self) -- 创建一条蛇
end

return MainScene

最后显示如下,似乎看不到一条蛇,因为它们都重复了,我们需要是的蛇能够动起来

这里写图片描述


小蛇动起来

===

只需要设个定时器,刷新屏幕就行了,所以在上面的基础上,只需要加个定时器,更新小蛇就行了
修改MainScene.lua


local cGridSize = 33
local scaleRate = 1 / display.contentScaleFactor

-- 根据自定义的坐标得到实际应该显示的cocos2d-x坐标位置
function Grid2Pos(x,y)

    local visibleSize = cc.Director:getInstance():getVisibleSize() -- 获取整个手机可视屏幕尺寸

    local origin = cc.Director:getInstance():getVisibleOrigin() -- 获取手机可视屏原点的坐标,屏幕的左上角

    local finalX = origin.x + visibleSize.width / 2 + x * cGridSize * scaleRate
    local finalY = origin.y + visibleSize.height / 2 + y * cGridSize * scaleRate

    return finalX,finalY

end

-- require相应的类
-- local Body = require("app.Body")
local Snake = require("app.Snake")

local MainScene = class("MainScene", function()
    return display.newScene("MainScene")
end)

local cMoveSpeed = 0.3

function MainScene:onEnter() -- MainScene 加载执行
        self.snake = Snake.new(self) -- 创建一条蛇

        local tick = function()
            self.snake:Update() -- 更新蛇
        end -- end tick

        cc.Director:getInstance():getScheduler():scheduleScriptFunc(
             tick,cMoveSpeed,false)

end

return MainScene

定时器,就一句话
schedulerID = cc.Director:getInstance():getScheduler():scheduleScriptFunc(调用的function, 定时时间(秒), 是否暂停(true, false))

我们在更新函数中写了self.snake:Update()

function Snake:Update()

    if #self.BodyArray == 0 then
        return
    end

    for i = #self.BodyArray , 1 , -1 do

        local body = self.BodyArray[i]

        if i == 1 then -- 蛇头位置 与 方向,得到一个新的位置 存放蛇头
            body.X, body.Y = OffsetGridByDir(body.X, body.Y, self.MoveDir)
        else
            local front = self.BodyArray[i-1]
            body.X, body.Y = front.X, front.Y
        <
  • 29
    点赞
  • 57
    收藏
    觉得还不错? 一键收藏
  • 6
    评论
评论 6
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值