quick-quick cocos2dxx 能开发3d游戏吗

两小时学会用 cocos2d-lua 开发游戏
主题:用 cocos2d-lua 创建一个小游戏,掌握游戏开发基本概念。
cocos2d-x 里已经内置了一个 lua 版本,被称为 cocos2d-lua。而 quick 是 cocos2d-lua 的一个强化版本。现在 quick 团队已经接手了 cocos2d-lua 的开发和维护工作,所以未来 quick 和 cocos2d-lua 将完全合并起来。因此,我们今天的学习也是基于 quick 来讲。
从 cn.cocos2d-x.org 下载 quick 版本后,执行安装程序即可。需要注意的问题就是不要安装到根目录,或者带有空格或中文的路径里。
安装完成,双击桌面上的 player3 图标,可以看到 quick 自带的 welcome 界面。这个界面可以用来创建、打开、编译项目。这个 player 就是 quick 里自带的模拟器,可以用来运行游戏。
选择新建,选择项目放置在哪里,再输入项目的包名。这个包名有点类似域名的格式,只不过顺序相反。
接下来我们选择屏幕方向为 landscape,也就是横屏。
由于这次的学习不涉及到 C++ 部分,所以我们去掉 Copy Source Files 选项,可以加快项目创建速度。
点击 Create Project 按钮后,会出现一个终端窗口显示创建项目的结果。如果一切正常,我们就可以回到 player 里选择 Open Project 打开项目。最后关掉 welcome 界面。
现在模拟器里已经把我们的游戏跑起来了,大大的 Hello, World 如此耀眼。
在开始写代码之前,我们明确一下游戏的玩法:
游戏开始后,玩家有 5 个红心。
从屏幕周边不断出现各种小虫子,并往屏幕另一边爬行。
玩家要用手指戳死虫子。
虫子爬到屏幕外面时,就会扣掉玩家一个红心。
红心被扣完后,游戏结束。
游戏结束时,统计玩家干掉了多少虫子。
开始创建游戏
第一步我们创建主菜单场景。
在编辑器中打开 src 目录,可以看到如下目录结构。
其中 app 子目录里就是放置我们的游戏代码,而 app/scenes 则是游戏各个场景的代码。
创建主菜单场景
我们可以把场景想象为舞台。当游戏进行时,只有一个舞台可以被玩家看到,所以切换场景就相当于换一个舞台。
现在我们来创建游戏的主菜单场景。打开 app/scenes/MainScene.lua 文件:
修改内容为:
function MainScene:ctor()
display.newSprite(&img/cover.jpg&)
:pos(display.cx, display.cy)
:addTo(self)
按 F5 刷新一下模拟器,可以看到屏幕上的显示内容已经变了。
概念讲解:
app:游戏启动后就创建的全局对象,用于提供整个应用程序级别的功能
场景:定义一个舞台
app:run() 里将默认打开 MainScene 场景
什么是类和对象:把类想象为 word 的文档模板,而对象则是从模板创建出来的文档,又被称为实例。所以修改类后,基于这个类创建的对象也会具有不同的方法和属性。
如何定义一个类:从基础类继承、从函数创建对象
类的继承:子类会包含父类的方法和属性
调用父类方法: app 里 ctor() 方法就需要调用父类的 ctor() 方法,完成初始化工作。
回到 MainScene.lua,继续讲场景相关的概念:
坐标系:左下角原点、X/Y轴的数值变化,右上角坐标点
pos() 方法
addTo() 方法
屏幕分辨率:假定为 960x640,暂时不考虑多分辨率适配
在背景上放置一个虫子:
display.newSprite(&img/bug1_01.png&)
:pos(display.cx, display.cy)
:addTo(self)
层叠关系:后加入的 Sprite 会叠加在之前加入场景的 Sprite 之上
修改 ZOrder:修改对象的 ZOrder 可以改变这种行为
放置开始按钮:
使用 cc.ui.UIPushButton
cc.ui.UIPushButton.new(&img/play_button.png&)
:pos(display.cx, display.cy - 200)
:addTo(self)
增加点击事件处理:
onButtonClicked() 方法
cc.ui.UIPushButton.new(&img/play_button.png&)
:onButtonClicked(function()
print(&PLAY BUTTON CLICKED&)
:pos(display.cx, display.cy - 200)
:addTo(self)
创建游戏场景
创建 app/scenes/PlayScene.lua,并从 app/scenes/MainScene.lua 复制内容,修改为:
local PlayScene = class(&PlayScene&, function()
return display.newScene(&PlayScene&)
function PlayScene:ctor()
display.newSprite(&img/bg.jpg&)
:pos(display.cx, display.cy)
:addTo(self)
function PlayScene:onEnter()
function PlayScene:onExit()
return PlayScene
修改 MainScene,在点击 &Play& 按钮时切换到新场景:
:onButtonClicked(function()
app:enterScene(&PlayScene&)
增加一点切换效果:
:onButtonClicked(function()
app:enterScene(&PlayScene&, nil, &Random&, 1.0)
由于随机数问题,所以我们在 app 初始化时还要初始化一下随机数种子:
function MyApp:run()
math.newrandomseed()
添加更多元素:
cc.ui.UILabel.new({
text = &5&,
x = display.left + 90,
y = display.top - 50,
size = 32})
:addTo(self)
由于这个文字标签要根据玩家的 HP 来动态变化,所以我们给 PlayScene 对象定义两个新的属性:
self.stars_ = 5
self.starsLabel_ = cc.ui.UILabel.new({
text = self.stars_,
x = display.left + 90,
y = display.top - 50,
size = 32})
:addTo(self)
创建游戏的玩法逻辑模型
因为游戏有两种虫子,但它们都有一些共同的行为,例如移动、钻入洞里等,所以我们定义一个名为 BugBase 的基础类。
增加 app/models 文件夹,添加文件 BugBase.lua:
添加 Base 表示基础类,这是一种约定,可以方便团队协作
local BugBase = class(&BugBase&)
return BugBase
添加构造函数:
function BugBase:ctor()
self.position_ = cc.p(0, 0)
self.rotation_ = 0
self.type_ = 1
定义了虫子的初始位置、角度和类型。但我们不应该使用数字或字符串来直接定义类型,而是应该使用更容易阅读和维护的形式:
BugBase.BUG_TYPE_ANT = 1
BugBase.BUG_TYPE_SPIDER = 2
function BugBase:ctor()
self.position_ = cc.p(0, 0)
self.rotation_ = 0
self.type_ = BugBase.BUG_TYPE_ANT
添加两种虫子的类文件,并且在构造函数中指定虫子的类型。
讲解 import() 函数的用法
虫子是随机出现在屏幕四周,往屏幕中间的洞移动,所以我们需要一个方法来初始化虫子位置和方向。由于这个方法是两种虫子都需要的,所以定义在 BugBase 里:
function BugBase:setInitPosition(holePosition, rotation, dist)
-- 确定虫子从洞的哪个角度出现
local rotation = rotation or math.random(0, 360)
-- 转为弧度
local radians = rotation * math.pi / 180
-- 确定虫子与洞的初始距离
-- 这里偷懒确定初始距离总是比半个屏幕的宽度多一些,避免虫子一出来时就在屏幕上
-- 严格的算法应该是屏幕四周与指定角度射线的交点距离
local dist = dist or math.random(display.width / 2 + 200, display.width / 2 + 500)
-- 计算虫子的初始位置和角度
self.position_ = cc.p(holePosition.x + math.cos(radians) * dist,
holePosition.y - math.sin(radians) * dist)
-- 因为需要虫子的头对着洞,所以虫子的方向实际上要旋转 180 度
self.rotation_ = rotation - 180
return self
cocos2dx 里,0 度正对右方,所以虫子图片里虫子的头部也是正对右方
为什么要返回 self
试试看在场景里加入虫子。由于需要读取虫子对象的属性,所以还要为 BugBase 再添加一些读取属性的方法:
function BugBase:getPosition()
return self.position_.x, self.position_.y
function BugBase:getRotation()
return self.rotation_
function BugBase:getType()
return self.type_
function BugBase:getDist()
return self.dist_
function BugBase:setDistPosition(holePosition)
self.distPosition_ = clone(holePosition)
return self
修改 PlayScene:
local BugAnt = import(&..models.BugAnt&)
function PlayScene:ctor()
local bug = BugAnt.new()
bug:setInitPosition(cc.p(display.cx - 30, display.cy - 75), math.random(0, 360), 200)
display.newSprite(&img/bug1_01.png&)
:pos(bug:getPosition())
:rotation(bug:getRotation())
:addTo(self)
顺便讲解一下 import() 里多个 . 的意义
这里显示创建了虫子对象,然后创建图片,并按照虫子对象的属性来设置图片位置和方向。多刷新几次模拟器,看看虫子是否始终正对着洞。
这里可以看到传给 setInitPosition() 方法的洞位置是一个特定值,对于这种值也应该定义为更有意义的名字。
创建 app/models/Game.lua 文件,内容为:
local Game = class(&Game&)
Game.HOLE_POSITION = cc.p(display.cx - 30, display.cy - 75)
return Game
修改 PlayScene:
local Game = import(&..models.Game&)
bug:setInitPosition(Game.HOLE_POSITION, math.random(0, 360), 200)
实现虫子的移动:
添加更多属性和方法
function BugBase:ctor()
self.dist_ = 0
self.distPosition_ = cc.p(0, 0)
self.speed_ = 1
添加移动方法:
function BugBase:step()
-- 每执行一次,让虫子往目的地方向移动一点点
self.distPosition_ = self.distPosition_ - self.speed_
local radians = (self.rotation_ + 180) * math.pi / 180
self.position_ = cc.p(self.distPosition_.x + math.cos(radians) * self.dist_,
self.distPosition_.y - math.sin(radians) * self.dist_)
return self
可以看到 step() 方法和 setInitPosition() 方法里的计算是一样的,所以可以重构一下代码:
function BugBase:setInitPosition(holePosition, rotation, dist)
-- 确定虫子从洞的哪个角度出现
local rotation = rotation or math.random(0, 360)
-- 确定虫子与洞的初始距离
-- 这里偷懒确定初始距离总是比半个屏幕的宽度多一些,避免虫子一出来时就在屏幕上
-- 严格的算法应该是屏幕四周与指定角度射线的交点距离
self.dist_ = dist or math.random(display.width / 2 + 200, display.width / 2 + 500)
-- 计算虫子的初始位置和角度
self.position_ = self:calcPosition_(rotation, self.dist_, holePosition)
-- 因为需要虫子的头对着洞,所以虫子的方向实际上要旋转 180 度
self.rotation_ = rotation - 180
-- 设置目的地位置
self:setDistPosition(holePosition)
return self
function BugBase:step()
-- 每执行一次,让虫子往目的地方向移动一点点
self.dist_ = self.dist_ - self.speed_
self.position_ = self:calcPosition_(self.rotation_ + 180, self.dist_, self.distPosition_)
return self
function BugBase:calcPosition_(rotation, dist, distPosition)
local radians = rotation * math.pi / 180
return cc.p(distPosition.x + math.cos(radians) * dist,
distPosition.y - math.sin(radians) * dist)
注意在 setInitPosition() 里调用了 setDistPosition()
修改 PlayScene,执行一个循环,看看虫子的移动效果:
function PlayScene:ctor()
local bug = BugAnt.new()
bug:setInitPosition(Game.HOLE_POSITION, math.random(0, 360), 200)
local bugSprite = display.newSprite(&img/bug1_01.png&)
:pos(bug:getPosition())
:rotation(bug:getRotation())
:addTo(self)
self:schedule(function()
bug:step()
bugSprite:pos(bug:getPosition())
print(bug:getDist())
可以看到虫子在不断往洞靠近。
现在我们需要在场景里添加多个虫子,并且让这些虫子动起来。
在 Game 对象里处理所有虫子的移动和图像
阅读(...) 评论() &君,已阅读到文档的结尾了呢~~
游戏开发引擎—cocos2d-lua(quick-cocos2d-x)集成第三方sdk(三),lua sdk,lua sdk 下载,lua sdk home path,cocos2dx lua 接入sdk,cocos2dx lua sdk,lua5.1 sdk 下载,lua 第三方库,quick lua,quick cocos2dx lua
扫扫二维码,随身浏览文档
手机或平板扫扫即可继续访问
游戏开发引擎—cocos2d-lua(quick-cocos2d-x)集成第三方sdk(三)
举报该文档为侵权文档。
举报该文档含有违规或不良信息。
反馈该文档无法正常浏览。
举报该文档为重复文档。
推荐理由:
将文档分享至:
分享完整地址
文档地址:
粘贴到BBS或博客
flash地址:
支持嵌入FLASH地址的网站使用
html代码:
&embed src='/DocinViewer--144.swf' width='100%' height='600' type=application/x-shockwave-flash ALLOWFULLSCREEN='true' ALLOWSCRIPTACCESS='always'&&/embed&
450px*300px480px*400px650px*490px
支持嵌入HTML代码的网站使用
您的内容已经提交成功
您所提交的内容需要审核后才能发布,请您等待!
3秒自动关闭窗口在线时间0 小时
版本JLB39.0
积分 28, 距离下一级还需 22 积分
积分 28, 距离下一级还需 22 积分
机型小米手机2/2S
MIUI版本JLB39.0
来自网页版
如题 游戏基于quick-cocos2d-x研发的,经常闪退 小米sdk已经接入成功
在小米机器上运行,总莫名其妙闪退
其他设备都没什么问题
请问产品是否要对小米系统做什么兼容性的东西么
分享到微信朋友圈
打开微信,点击底部的“发现”,使用 “扫一扫” 即可将网页分享到我的朋友圈。
Copyright (C) 2016 MIUI
京ICP备号 | 京公网安备34号 | 京ICP证110507号quick-cocos2dx第一次实现热更新功能
一个as程序员到quickx程序员的转变过程,最大的感觉是这个过程中有太多太多的迷茫点,心里一直揪着。
从以一次接触quickx到实现热更新功能,为期2个月左右的时间,接触了太多东西,心中的石头终于平稳的落地。
简单总结下接触到的知识点:
第一:学习lua语言
第二:了解quickx原文件各个功能
第三:对工程目录结构的了解,会用player运行小程序,并且做简单修改
第四:(边开发边学习)开发过程中要用到:lua本身的类、quickx提供的cocos2dx的封装类、cocos2dx扩展类和cocos2dx类,所以认识这些基础要用到的类,并且能够比较熟练的找到这些类及源码
第五:(边开发边学习)学习c++基础 能够看懂cocos2dx
c++源码作简单修改并且知道怎么讲修改后的c++文件应用到工程中
第六:学会讲自定义的c++类导成能给lua直接调用的类
第七:五六过程中要学会配置windows或mac下开发环境 JDK SDK VS 了解tolua
第八:涉及到平台开发和服务器的请求,所以对跨平台性,资源目录路径和http请求了解
第九:涉及到面板 要会虚拟机安装苹果系统 在苹果系统下使用cocosbulider以及在lua中使用和控制面板
第十:在做链接服务器开发时,还专门花时间研究了git。从注册到能从本地上传更新文件,算是基本掌握。哈哈,以后自己做小应用可以考虑用git了。
以上这些过程对于一个从来没接触过手机开发的as程序员来说,步步艰辛啊。现在虽然实现了所有的功能,但接触都的东西还大多是基本的接触,掌握他们还要很久时间,以后做功能,上面提到的不会太接触,基本就是面板游戏逻辑和调消息。再花时间好好学习上面接触到的,如果全部掌握,基本做cocos2dx开发就可以了解于心了。
以上网友发言只代表其个人观点,不代表新浪网的观点或立场。quick cocos2dx 游戏数据存储
整理一下项目中经常用到的几种数据格式,推荐GameState
1:json数据格式
json->table
local str = json.encode({a=1,b=2,c={123}})
print(str)
{“a”:1,”c”:[123],”b”:”cc”}
table->json
local str2 = json.decode('{"a":1,"c":[123],"b":"cc"}')
dump(str2)
[LUA-print] - "" = {
[LUA-print] -
[LUA-print] -
"b" = "cc"
[LUA-print] -
[LUA-print] -
[LUA-print] -
[LUA-print] - }
2: UserDefault
- -支持c++ lua 语言
cc.UserDefault:getInstance():setIntegerForKey("Pass",1)
--Integer,Double,Bool,Float,String,
cc.UserDefault:getInstance():flush()
在writablePath路径下会生成UserDefault.xml文件
local user_integer = cc.UserDefault:getInstance():getIntegerForKey("Pass")
3 : GameState
只有在cocos2dx-Lua下使用,经常在项目中使用,可以进行加解密、格式化、存储table
(1)导入GameState
local GameState = import("framework.ui.utils.GameState")
GameState.init(function(param)
local returnValue = nil
if param.errorCode then
print("error code" .. param.errorCode)
if param.name == "save" then
local str = json.encode(param.values)
str = crypto.encryptXXTEA(str,"abcd")--使用XXT算法
returnValue = {data = str}
elseif param.name == "load" then
local str = crypto.decryptXXTEA(param.values.data,"abcd")
returnValue = json.decode(str)
return returnValue
end,"data.txt","abcd") --保存到writablePath下data.txt文件中,加密口令"abcd"
GameData = GameState.load() or {}
导出到文件
GameData.name = "uud"
GameData.age = 10
GameData.level = 15
GameState.save(GameData)
4:FileUtils
在 c++ 或者lua中使用
cc.FileUtils:getInstance():getString/ValueMap/IntegerFromFile(filePath)
cc.FileUtils:getInstance():writeToFile(tb,filePath)
filePath 一定是 cc.FileUtils:getInstance():getWritablePath()返回的路径}

我要回帖

更多关于 cocos2dx 3d开发指南 的文章

更多推荐

版权声明:文章内容来源于网络,版权归原作者所有,如有侵权请点击这里与我们联系,我们将及时删除。

点击添加站长微信