2015.3.24--1.cocos认知

准备搞搞手机小游戏玩一下。。研究了一下u3d跟cocos 发现作为独立开发者cocos更有优势一些。 相对成本低吧 个人见解
OK,建立一下学习目标跟短期规划。
首先我想做一个双摇杆或者单点触控的休闲小游戏。那么在cocos里面我需要学习以下知识
1.先基于win32的版本 方便调试(主要是我熟悉一些)。
2.场景相关api 更新等
3.玩家对象相关api 以及动作机制 移动等手法 还有特效~
4.安卓部署
5.网络层搭建
6.简单与服务端通讯
7.以后再补充优化


1.下载cocos2dx-3.x版本 下载好后本身找了很多教程部署环境,结果发现最清晰的反而是跟代码一同的Readme.md。打开阅读 照做即可

How to start a new game
-----------------------

1. Download the code from [cocos2d download site][4]
2. Run `setup.py`
3. Run the `cocos` script

Example:

$ cd cocos2d-x
$ ./setup.py
$ source FILE_TO_SAVE_SYstem_VARIABLE
$ cocos new MyGame -p com.your_company.mygame -l cpp -d NEW_PROJECTS_DIR
$ cd NEW_PROJECTS_DIR/MyGame

### Build and run new project for Windows 8.1 and Windows Phone 8.1 ###

$ cocos new MyGame -p com.bar.foo -l cpp -d projects

OK 根据教程可以建立一个win平台的vs项目了。。不过。。。太麻烦了。。不利于学习。
我的做法是 直接打开cpptest.然后编译运行 我已经有了明确的目标 那么目标导向就是我要先知道怎么搞个舞台 然后把玩家对象放上去 控制 +动作 这是第一步

----------------------------上面都是废话-----------------------------
找了个简单的cpp直接改ClickAndMoveTest.h/ClickAndMoveTest.cpp
本身这个类是用来测试点击移动的。
那么必然的要素是有场景 以及最简单的移动。
打开.h发现有类class MainLayer : public Layer
查询一下资料 发现背景是layer的一种 一直不知道怎么用中文来翻译这个layer 类似于布局 层级之类的东西 不过用中文翻译之后总觉得意图有所丢失
OK 那么所有的背景都是要建立在一个舞台上吧
class ClickAndMoveTestScene : public TestScene
{
public:
virtual void runThistest();
};
看到这个 TestScene的定义是这样的class TestScene : public Scene
那么现在追述一下代码
看到runThisTest并非是cocos的api Test也不是 这个类以及函数都是为了做这个cpptest程序的业务层
看一下runThisTest代码
void ClickAndMoveTestScene::runThistest()
{
auto layer = new (std::nothrow) MainLayer();
layer->autorelease();

addChild(layer);
Director::getInstance()->replaceScene(this);
}

addChild(layer)
这一句代码基本证实了前面的假设
一个scene下面有多个layer,以孩子的形式存在 也许是map?暂时先不深究了
这里可以看到很多关键的信息。第一 autorelease,追述一下源码,发现他会把创建的对象丢到一个obj列表里面 在需要的时候会自动释放(java的既视感!) OK 好东西。那么可以想象我们需要自己做一个obj基类 然后做一个create,再构造私有,这样就能保证对象安全了。(实际上日记做到这里的时候 回头再看 这个方式 cocos已经帮我实现了0.0)
第二个关键信息 Director::getInstance()->replaceScene(this);
获得设备单例 回收场景? why? 因为这个舞台是上一层的 我们做游戏大多可能用不到。。不然回到主场景的时候又要创建出来?根据业务需要吧。 不过这里掌握了一个关键信息 就是渲染设备是个单例的 通过这个方式去拿 打开Director包含的.h 扫一下api都大约提供了哪些接口。这时候我有些迷惑了 这个Director又提供了动画 场景渲染 矩阵缩放等 字体等等。。ok 我们先看到例子上有个scene的用法。。先保留这一个观点 以后再看到同类型用法时再进行验证了


场景的创建以及layer的布局方式已经明确了 layer这里有个疑点就是如果只是简单地addchild那么对于之后的layer管理会变得异常困难了,看一下重载方式。。ok 发现有childID的指定 暂时不用 pass掉。

这里cpp的主要功能就是鼠标点击一个精灵移动
精灵的概念就不再描述了 基本上所有渲染引擎都有的东西。
我们更关心怎么监听鼠标移动的。发现代码
auto listenerTouch = EventListenerTouchOneByOne::create();
listenerTouch->onTouchBegan = CC_CALLBACK_2(MainLayer::onTouchBegan,this);
listenerTouch->onTouchEnded = CC_CALLBACK_2(MainLayer::onTouchEnded,this);
_eventdispatcher->addEventListenerWithSceneGraPHPriority(listenerTouch,this);
4行代码 前3行是绑定监听回调函数的 不过在C11里面可以有更高级的形式来直接处理(个人不喜而已)
最后一行是把两个对象加入监听列表,函数名这么长应该是有其他讲究的。 这里不再累赘描述了 跳到头文件 看到有类似接口 注释已经描述的很清楚两个接口的区别
这时候响应对应事件 OK搞定 鼠标控制get it.

问题来了。。在手机上的触控监听在pc上的键盘监听怎么搞?上面第一行代码获取监听器的时候 我们跳入到监听器的基类 发现有枚举
enum class Type
{
UNKNowN,
TOUCH_ONE_BY_ONE,
TOUCH_ALL_AT_ONCE,
KEYBOARD,
MOUSE,
FOCUS,
GAME_CONTROLLER,
CUSTOM
};
有枚举就so easy了 直接全文搜索(what 搜不到?其实是不明确)
EventListenerKeyboard 搜到了这个东西 不过 细心一点看注释 基类上面的注释有写了* For instance,you Could refer to EventListeneracceleration,EventListenerKeyboard,EventListenerTouchOneByOne,EventListenerCustom.

找到keyboard的类头文件 发现一些Keycode用来监听 ok 加上算法 控制小人移动大功告成


void MainLayer::onKeypressed( EventKeyboard::KeyCode keyCode,Event* pEvent )
{
if (keyCode == EventKeyboard::KeyCode::KEY_W)
{
m_sprite->m_moveDirspeed += Vec2(0.f,1.5f);
}
if (keyCode == EventKeyboard::KeyCode::KEY_A)
{
m_sprite->m_moveDirspeed += Vec2(-1.5f,0.f);
}
if (keyCode == EventKeyboard::KeyCode::KEY_S)
{
m_sprite->m_moveDirspeed += Vec2(0.f,-1.5f);
}
if (keyCode == EventKeyboard::KeyCode::KEY_D)
{
m_sprite->m_moveDirspeed += Vec2(1.5f,0.f);
}
m_sprite->m_isMoveCount++;
//m_sprite->setDirty(true);
}



void MainLayer::onkeyreleased( EventKeyboard::KeyCode keyCode,Event* pEvent )
{
m_sprite->m_isMoveCount--;
if (0 == m_sprite->m_isMoveCount)
{
m_sprite->m_moveDirspeed = Vec2::ZERO;
m_sprite->m_theMoveAddSpeed = 0;
}else
{
if (keyCode == EventKeyboard::KeyCode::KEY_W)
{
m_sprite->m_moveDirspeed -= Vec2(0.f,1.5f);
}
if (keyCode == EventKeyboard::KeyCode::KEY_A)
{
m_sprite->m_moveDirspeed -= Vec2(-1.5f,0.f);
}
if (keyCode == EventKeyboard::KeyCode::KEY_S)
{
m_sprite->m_moveDirspeed -= Vec2(0.f,-1.5f);
}
if (keyCode == EventKeyboard::KeyCode::KEY_D)
{
m_sprite->m_moveDirspeed -= Vec2(1.5f,0.f);
}
}
}

void Player::update( float delta )
{
if (0 != m_isMoveCount)
{
Vec2 SpeedVec;
if (m_moveDirspeed.x > 0)
{
SpeedVec.x = m_theMoveAddSpeed;
}else if(m_moveDirspeed.x < 0)
{
SpeedVec.x = -m_theMoveAddSpeed;
}

if (m_moveDirspeed.y > 0)
{
SpeedVec.y = m_theMoveAddSpeed;
}else if(m_moveDirspeed.y < 0)
{
SpeedVec.y = -m_theMoveAddSpeed;
}
Vec2 newPosition = getPosition() + m_moveDirspeed + SpeedVec;
if (newPosition.x >= 0 && newPosition.y >= 0 && newPosition.x < 1024 && newPosition.y < 768)
{
setPosition(newPosition);
if (m_theMoveAddSpeed <= 1.f)
{
m_theMoveAddSpeed += 0.02f;
}
}
//setDirty(true);
}
}

其实在这里是遇到几个问题的。
1.做过端游控制的朋友知道 按键的按下不会一直redarw 那么需要通过标记的形式去update 首先 如果一个对象想要update 那么第一步 override这个函数 第二部步 调用scheduleUpdate(); 开启Update事件传递 (这里其实是有优先级的 看到api要记得先去官网查询一下 或者仔细看注释)
2.精灵对象的创建以及runAction函数搞不太懂。太多调用方式了。不过可以确定的是Runaction是执行一个动作序列函数函数指针或者对象。


今天就这样 下班 明天目标就是研究action 以及控制人物移动时播放一个"移动 动画"

相关文章

    本文实践自 RayWenderlich、Ali Hafizji 的文章《...
Cocos-code-ide使用入门学习地点:杭州滨江邮箱:appdevzw@1...
第一次開始用手游引擎挺激动!!!进入正题。下载资源1:从C...
    Cocos2d-x是一款强大的基于OpenGLES的跨平台游戏开发...
1.  来源 QuickV3sample项目中的2048样例游戏,以及最近《...
   Cocos2d-x3.x已经支持使用CMake来进行构建了,这里尝试...