精华内容
下载资源
问答
  • Cocos2dx入门

    万次阅读 2019-04-18 15:09:46
    一.Cocos2d-x引擎特性 现代化的 C++ API 立足于 C++ 同时支持 JavaScript/Lua 作为开发语言 可以跨平台部署, 支持 iOS、Android、Windows、macOS 和 Linux 可以在 PC 端完成游戏的测试,最终发布到移动端 完善的游戏...

    一.Cocos2d-x引擎特性

    现代化的 C++ API
    立足于 C++ 同时支持 JavaScript/Lua 作为开发语言
    可以跨平台部署, 支持 iOS、Android、Windows、macOS 和 Linux
    可以在 PC 端完成游戏的测试,最终发布到移动端
    完善的游戏功能支持,包含精灵、动作、动画、粒子特效、场景转换、事件、文件 IO、数据持久化、骨骼动画、3D


    二.环境配置

    要求:
    Windows 7+,
    VS 2015+
    python2.7

    JDK
    SDK
    NDK(可选)


    三.cocos命令配置

    1.cocos命令配置

    Cocos2d-x 带有一个命令行工具:cocos 这是一个跨平台的工具,你可以用它创建项目、运行项目、发布项目。命令行工具适用于所有 Cocos2d-x 支持的平台,包括:iOS、Android、Mac、Linux、Windows、Web。不用 IDE,只用命令行,你就能完成所有的工作!

    1.行引擎源码根目录的 setup.py
    python setup.py

    2.测试

    cocos -v
    Python 2.7.10
    cocos2d-x-3.16
    Cocos Console 2.3

    2.cocos命令使用

    • 1.项目创建

    cocos new MyGame -p com.MyCompany.MyGame -l cpp -d ~/MyCompany

    • 2.项目编译(程序从源码到二进制程序,有一个编译环节)

    cocos compile . -p android -m release

    • 3.项目运行

    cocos run . -p android -m release

    • 4.项目发布

    cocos deploy -s c:\MyCompany\MyGame -p android -m release


    四.日志输出

    log("This would be outputted to the console");
    
    string s = "My variable";
    log("string is %s", s);
    
    double dd = 42;
    log("double is %f", dd);
    
    int i = 6;
    log("integer is %d", i);
    
    float f = 2.0f;
    log("float is %f", f);
    

    五.基本功能

    1.Director导演

    Cocos2d-x 使用导演的概念,Director 任务是控制场景替换和转换。
    Director是一个共享的单例对象,可以在代码中的任何地方调用。

    2.Scene场景

    场景(Scene) 是一个容器,容纳游戏中的各个元素,如精灵,标签,节点对象。它负责着游戏的运行逻辑,以帧为单位渲染内容。
    1.场景创建

    class MyScene : public cocos2d::Scene
    {
    public:
    	static cocos2d::Scene* createScene();
    	virtual bool init();
    
    	// 实现crete静态方法
    	CREATE_FUNC(StartScene);
    };
    
    //创建
    auto myScene = MyScene ::create();
    

    2.场景切换

    //加载第一个场景
    Director::getInstance()->runWithScene(myScene);
    
    //切换场景
    Director::getInstance()->replaceScene(myScene);
    
    //叠加场景
    Director::getInstance()->pushScene(myScene);
    
    //释放场景
    Director::getInstance()->popScene(myScene);
    

    场景图
    场景图(Scene Graph)是一种安排场景内对象的数据结构,它把场景内所有的 节点(Node) 都包含在一个 树(tree) 上。
    Cocos2d-x 使用 中序遍历,先遍历左子树,然后根节点,最后是右子树。中序遍历下图的节点,能得到 A, B, C, D, E, F, G, H, I 这样的序列。

    场景图

    3.Layer层

    Layer代表层,一般常做Scene的子容器,可以添加Sprite,相当于精灵的面板容器。

    4.Sprite精灵

    精灵是您在屏幕上移动的对象,它能被控制;

    可以使用一张图像来创建精灵,PNG, JPEG, TIFF, WebP, 这几个格式都可以。当然也可以是图集

    使用图片

    auto mySprite = Sprite::create("mysprite.png");
    

    使用图集

    1.创建图集
    Texture Packer工具创建并导出plist+png图集

    2.加载图集

    auto spritecache = SpriteFrameCache::getInstance();
    spritecache->addSpriteFramesWithFile("sprites.plist");
    

    3.创建精灵

    auto mysprite = Sprite::createWithSpriteFrameName("mysprite.png");
    

    精灵的控制

    1.锚点
    mySprite->setAnchorPoint(0.5, 0.5);
    2.位置
    mySprite->setPosition(Vec2(100, 200));
    3.旋转
    mySprite->setRotation(20.0f);
    4.缩放
    mySprite->setScale(2.0);
    mySprite->setScaleX(2.0);
    mySprite->setScaleY(2.0);
    5.倾斜
    mySprite->setSkewX(20.0f);//水平倾斜
    mySprite->setSkewY(20.0f);//数直倾斜
    6.颜色
    mySprite->setColor(Color3B::WHITE);
    mySprite->setColor(Color3B(255, 255, 255));
    7.透明度
    mySprite->setOpacity(30);
    

    5.Action动作

    动作(Action)通过改变一个 Node 对象的属性,让它表现出某种动作。动作对象能实时的改变 Node 的属性,任何一个对象只要它是 Node 的子类都能被改变。
    1.单一动作

    //从当前位置到目标位置
    auto moveTo = MoveTo::create(2, Vec2(50, 10));
    mySprite1->runAction(moveTo);
    //从目标位置到当前位置
    auto moveBy = MoveBy::create(2, Vec2(20,0));
    mySprite2->runAction(moveBy);
    

    2.动作序列和并列
    还可以创建一个动作 序列(Sequence) 和Swan(并列)

    auto mySprite = Node::create();
    
    auto moveTo1 = MoveTo::create(2, Vec2(50,10));
    auto moveBy1 = MoveBy::create(2, Vec2(100,10));
    auto moveTo2 = MoveTo::create(2, Vec2(150,10));
    
    mySprite->runAction(Sequence::create(moveTo1, moveBy1,moveTo2, nullptr));
    //或者
    mySprite->runAction(Spawn::create(moveTo1, moveBy1, moveTo2, nullptr));
    

    六.UI组件

    UI 代表用户界面,是 User Interface 的缩写,界面组件有标签,按钮,菜单,滑动条等

    1.标签(Label)

    //BMFont
    auto myLabel = Label::createWithBMFont("bitmapRed.fnt", "Your Text");
    //TTF
    auto myLabel = Label::createWithTTF("Your Text", "Marker Felt.ttf", 24);
    //SystemFont
    auto myLabel = Label::createWithSystemFont("My Label Text", "Arial", 16);
    //阴影效果
    myLabel->enableShadow();
    //描边效果
    myLabel->enableOutline(Color4B::WHITE, 1));
    //发光效果
    myLabel->enableGlow(Color4B::YELLOW);
    

    2.菜单(Menu)

    //图片菜单
    auto closeItem = MenuItemImage::create("CloseNormal.png", "CloseSelected.png",
    CC_CALLBACK_1(HelloWorld::menuCloseCallback, this));
    
    //文字菜单
    auto startItem = MenuItemText::create("StartGame",
    CC_CALLBACK_1(HelloWorld::menuCloseCallback, this));
    
    //menu总菜单
    auto menu = Menu::create(startItem, closeItem, NULL);
    this->addChild(menu, 1);
    
    //Lambda写法
    auto closeItem = MenuItemImage::create("CloseNormal.png", "CloseSelected.png",
    [&](Ref* sender){
        // your code here
    });
    

    3.按钮(Button)

    #include "ui/CocosGUI.h"。
    auto button = Button::create("normal_image.png", "selected_image.png", "disabled_image.png");
    button->setTitleText("Button Text");
    button->addTouchEventListener([&](Ref* sender, Widget::TouchEventType type){
            switch (type)
            {
                    case ui::Widget::TouchEventType::BEGAN:
                            break;
                    case ui::Widget::TouchEventType::ENDED:
                            std::cout << "Button 1 clicked" << std::endl;
                            break;
                    default:
                            break;
            }
    });
    

    4.复选框(CheckBox)(Toggle开关)

    #include "ui/CocosGUI.h"
    
    auto checkbox = CheckBox::create("check_box_normal.png",
                                     "check_box_normal_press.png",
                                     "check_box_active.png",
                                     "check_box_normal_disable.png",
                                     "check_box_active_disable.png");
    
    checkbox->addTouchEventListener([&](Ref* sender, Widget::TouchEventType type){
            switch (type)
            {
                    case ui::Widget::TouchEventType::BEGAN:
                            break;
                    case ui::Widget::TouchEventType::ENDED:
                            std::cout << "checkbox 1 clicked" << std::endl;
                            break;
                    default:
                            break;
            }
    });
    
    this->addChild(checkbox);
    

    5.进度条(LoadingBar)

    #include "ui/CocosGUI.h"
    //创建进度条
    auto loadingBar = LoadingBar::create("LoadingBarFile.png");
    loadingBar->setDirection(LoadingBar::Direction::RIGHT);
    //设置进度
    loadingBar->setPercent(25);
    //add节点
    this->addChild(loadingBar);
    

    6.文本框(TextField)

    #include "ui/CocosGUI.h"
    
    auto textField = TextField::create("","Arial",30);
    textField->addTouchEventListener([&](Ref* sender, Widget::TouchEventType type){
         std::cout << "editing a TextField" << std::endl;
    });
    
    this->addChild(textField);
    

    七.监听事件

    1.五种类型

    EventListenerTouch - 响应触摸事件
    
    EventListenerKeyboard - 响应键盘事件
    
    EventListenerAcceleration - 响应加速度事件
    
    EventListenMouse - 响应鼠标事件
    
    EventListenerCustom - 响应自定义事件
    

    2.事件的吞没(可做遮罩)

    listener1->setSwallowTouches(true);
    listener1->onTouchBegan = [](Touch* touch, Event* event){
        // your code
        return true;
    };
    

    3.触摸事件

    让我们先了解一下什么是触摸事件,当你触摸移动设备的屏幕时,设备感受到被触摸,了解到被触摸的位置,同时取得触摸到的内容,然后你的触摸被回答。 这就是触摸事件。

    //创建触摸
    auto listener1 = EventListenerTouchOneByOne::create();
    // 触摸开始
    listener1->onTouchBegan = [](Touch* touch, Event* event){
        // your code
        Vec2 point = touch->getLocation();//获取点击位置
        return true; // if you are consuming it
    };
    // 触摸滑动
    listener1->onTouchMoved = [](Touch* touch, Event* event){
        // your code
    };
    // 触摸结束
    listener1->onTouchEnded = [=](Touch* touch, Event* event){
        // your code
    };
    // 添加监听(最重要的一步)
    _eventDispatcher->addEventListenerWithSceneGraphPriority(listener1, this);
    

    4.鼠标事件

    创建鼠标事件监听器:

    //创建事件
    _mouseListener = EventListenerMouse::create();
    //设置不同监听
    _mouseListener->onMouseMove = CC_CALLBACK_1(MouseTest::onMouseMove, this);
    _mouseListener->onMouseUp = CC_CALLBACK_1(MouseTest::onMouseUp, this);
    _mouseListener->onMouseDown = CC_CALLBACK_1(MouseTest::onMouseDown, this);
    
    //绑定监听(最重要一步)
    _eventDispatcher->addEventListenerWithSceneGraphPriority(_mouseListener, this);
    
    //回调函数实现(也可以用匿名函数/Lambda)
    void MouseTest::onMouseDown(Event *event){
    	EventMouse* em = (EventMouse*)event;
    	em->getLocation();//获取鼠标位置
    }
    void MouseTest::onMouseUp(Event *event){}
    void MouseTest::onMouseMove(Event *event){}
    
    

    5.键盘事件

    对于桌面游戏,一般需要通过键盘做一些游戏内的控制,这时你就需要监听键盘事件。

    //创建事件
    auto listener = EventListenerKeyboard::create();
    listener->onKeyPressed = CC_CALLBACK_2(KeyboardTest::onKeyPressed, this);
    listener->onKeyReleased = CC_CALLBACK_2(KeyboardTest::onKeyReleased, this);
    //添加监听
    _eventDispatcher->addEventListenerWithSceneGraphPriority(listener, this);
    
    //实现回调函数
    void KeyboardTest::onKeyPressed(EventKeyboard::KeyCode keyCode, Event* event){}
    
    void KeyboardTest::onKeyReleased(EventKeyboard::KeyCode keyCode, Event* event){}
    

    6.Update事件

    如果需要持续的处理某个事件,那么可以开启一个update

    //开启update
    this->scheduleUpdate();
    void Test::update(float delta)
    {}
    

    八.物理引擎

    当你的需求很简单时,就不要使用物理引擎。比如只需要确定两个对象是否有碰撞,结合使用节点对象的 update 函数和 Rect 对象的 containsPoint(),intersectsRect() 方法可能就足够了。例如:

    void update(float dt)
    {
      auto p = touch->getLocation();
      auto rect1 = this->getBoundingBox();
      auto rect2 = this->getBoundingBox();
      if(rect1.containsPoint(p))
      {
          // do something, intersection
      }
      if(rect1.intersectsRect(rect2))
      {
          // do something, intersection
      }
    }
    

    1.刚体碰撞

    如你要开发一个游戏,一个场景有 100 个精灵对象,需要判断它们互相是否有碰撞,如果使用上诉方法那将非常复杂,同时性能消耗还会严重影响 CPU 的使用率和游戏运行的帧率,这游戏根本没法玩。
    这个时候就需要物理引擎了。

    /*创建物理场景*/
    auto scene = Scene::createWithPhysics();
    //显示物理引擎调试界面 --- 有红框
    scene->getPhysicsWorld()->setDebugDrawMask(PhysicsWorld::DEBUGDRAW_ALL);
    //可把自己的类定义为Layer
    auto layer = MyScene::create();
    scene->addChild(layer);
    
    
    /*创建边框测试*/
    //创建一个物理世界, 大小和屏幕的尺寸相同, 使用默认材质, debug框的宽度为3个像素
    auto body = PhysicsBody::createEdgeBox(visibleSize, PHYSICSBODY_MATERIAL_DEFAULT, 3);
    auto edgeShape = Node::create();//创建一个碰撞图形
    edgeShape->setPhysicsBody(body);//将图形和刚刚创建的世界绑定
    edgeShape->setPosition(visibleSize.width / 2, visibleSize.height / 2);//设置图形的位置在屏幕正中间
    this->addChild(edgeShape);
    
    
    /*创建静态刚体精灵*/
    auto sprite = Sprite::create("HelloWorld.png");
    sprite->setPosition(center);
    this->addChild(sprite);
    //添加静态的刚体
    auto physicsBody = PhysicsBody::createBox(sprite->getContentSize(),
    PhysicsMaterial(0.1f, 1.0f, 0.0f));
    physicsBody->setDynamic(false);
    //设置碰撞层
    physicsBody->setCategoryBitmask(8);//种类
    physicsBody->setCollisionBitmask(16);//碰撞
    physicsBody->setContactTestBitmask(16);//接触
    //把刚体赋给精灵
    sprite->addComponent(physicsBody);
    
    
    /*创建动态刚体精灵*/
    auto sprite = Sprite::create("HelloWorld.png");
    sprite->setPosition(center);
    this->addChild(sprite);
    //添加静态的刚体
    auto physicsBody = PhysicsBody::createBox(sprite->getContentSize(),
    PhysicsMaterial(0.1f, 1.0f, 0.0f));
    physicsBody->setGravityEnable(false);
    //设置碰撞层
    physicsBody->setCategoryBitmask(16);//种类
    physicsBody->setCollisionBitmask(8);//碰撞
    physicsBody->setContactTestBitmask(8);//接触
    //把刚体赋给精灵
    sprite->addComponent(physicsBody);
    
    
    /*添加碰撞事件*/
    auto contactListener = EventListenerPhysicsContact::create();
    contactListener->onContactBegin = [](PhysicsContact& contact) {
    	log("OnCollision");
    	//auto nodeA = contact.getShapeA()->getBody()->getNode();
    	//auto nodeB = contact.getShapeB()->getBody()->getNode();
    	return true;
    };
    //绑定监听事件
    _eventDispatcher->addEventListenerWithSceneGraphPriority(contactListener, this);
    

    2.查询

    • 1.点查询
    • 2.射线查询

    九.音乐和音效

    你的游戏肯定会需要音乐和音效!Cocos2d-x 提供了一个 SimpleAudioEngine 类支持游戏内的音乐和音效。它可以被用来增加背景音乐,控制游戏音效。
    SimpleAudioEngine 是一个共享的单例对象,

    #include "SimpleAudioEngine.h"
    using namespace CocosDenshion;
    
    // 播放背景音乐
    auto audio = SimpleAudioEngine::getInstance();
    audio->playBackgroundMusic("mymusic.mp3", loop);
    // 暂停/停止/恢复 背景音乐
    audio->pauseBackgroundMusic();
    audio->stopBackgroundMusic();
    audio->resumeBackgroundMusic();
    
    //播放音效
    audio->playEffect("myEffect.mp3", false, 1.0f, 1.0f, 1.0f);
    // 暂停/停止/恢复 音效
    audio->pauseEffect();audio->stopEffect();audio->resumeEffect();
    // 暂停/停止/恢复 所有音效
    audio->pauseAllEffects();audio->stopAllEffects();audio->resumeAllEffects();
    
    展开全文
  • cocos2dx入门

    2015-01-22 16:02:48
    在生硬的啃了几天python和lua之后,今天终于要开启cocos2dx入门之路了,只想说一句,finally,接下来就让这博客见证我的成长吧。 站在巨人的肩膀上,才能取得更高的成就,所以,首先要做的事情,就是多读读前人的...

    在生硬的啃了几天python和lua之后,今天终于要开启cocos2dx的入门之路了,只想说一句,finally,接下来就让这博客见证我的成长吧。

    站在巨人的肩膀上,才能取得更高的成就,所以,首先要做的事情,就是多读读前人的经验笔记,给这个任务号号脉,我首先翻阅的是一个博客,博主自学完成了超级玛丽的游戏设计,而这正是我的一个入门构思游戏,接下来几天,我将跟随博主来对cocos的旅程有个大概的了解。


    屏幕适配问题

    我在写超级玛丽的时候没有考虑到屏幕适配的问题,当我在最后把代码编译到安卓平台上的时候才发现屏幕适配应该在最开始定下来,所以后来把代码做了移植。这个游戏原定的分辨率就是480*320,所有的资源都是以这个分辨率设计的大小,最后再屏幕适配过程中只需要一行代码,就搞定了不同屏幕的适配问题,不过这个方法解决的不彻底,引擎提供的这个方法本来就是有缺陷的,但不影响游戏的运行与体验。”

    博主提到了屏幕适配的问题,不过却并没有讲明引擎提供的方法的缺陷在何处,也没有给出解决方案。于是自行去搜索了相应的文章来对此作出了解。

    原来,屏幕适配的作用是为了使得相同的游戏在不同的屏幕上都能得到同样的体验,而cocos早期的版本对于此功能的支持却做的不是很好,但是从2.0-x-2.0.4开始,团队开始对此问题作出回应,他们的回应方法是这样的,根据用户的屏幕和资源的尺寸的比例,对资源进行相应的缩放,而缩放的方式也是可以选择的,如拉伸,填充等,通过这些设置,可以实现,相同的资源可以填满不同分辨率尺寸的屏幕,当然,在长宽比例不一致的时候还会发生相应的形变就是了,详情参见这里

    角色定义

    对于游戏中出现的人物,其实就是一个对象,有着自己的特性,包括特征及动作。而一般反面的角色,大多是通过继承来完成(龙套没有地位)

    注:游戏中的主角类或是怪物类等一般有两种继承方式,要么是继承引擎里的CCSprite;要么是继承引擎里的CCNode,类里面再维护一个CCSprite*变量这两种处理方式都可以。不过在游戏中作者用的是后一种方式,这样子,马里奥在接受碰撞处理时表现的是CCNode的性质,在状态之间切换的时候私有变量CCSprite*可以做到马里奥的状态切换(就是换一张图片显示),播放各种动画(这个后序详述)。

    层的概念

    在游戏中,有了地图跟人物,还需要使得人物在地图上活动,那么就需要定义分层了,不然人物也没有办法知道地图上哪里是平地,哪里是高山,哪里可以行走,哪里会有怪物。

    在背景的设置上,有三个重要的概念,分别是锚点和局部坐标系(添加函数为addChild(CCNode*),CCNode是引擎里所有能够展示的内容的基类)

    游戏里的大多数逻辑都是在层里完成的,其继承于引擎中的CCLayer,完成这些设置之后,就能看到屏幕上一张地图,而马里奥就停留在某一点上。


    展开全文
  • Cocos2dx入门初级教程

    2018-09-28 16:45:24
    Cocos2dx入门初级教程,初学者可以用于学习cocos2d,可以带领初学者入门
  • Cocos2dx入门初级教程,方便想学习Cocos2dx的入门初学者,也方便入门者回头的复习用书。
  • cocos2dx入门小游戏

    2014-03-13 17:17:14
    一个简单的cocos2dx入门小游戏,简单易懂!
  • 几个重要概念在cocos2d引擎中,有几个概念,分别是导演,场景,布景和人物角色。导演(CCDirector)在cocos2d-x引擎中,导演类是游戏的组织者和领导者,导演制定规则让游戏内的场景,布景,和人物角色有序的运行摄像机...

    几个重要概念

    在cocos2d引擎中,有几个概念,分别是导演,场景,布景和人物角色。

    导演(CCDirector)在cocos2d-x引擎中,导演类是游戏的组织者和领导者,导演制定规则让游戏内的场景,布景,和人物角色有序的运行

    摄像机(CCCamera),每个节点都需要使用摄像机,当节点发生缩放,旋转,和位置变化时,都需要覆盖摄像机,让这个节点通过摄像机重新渲染。

    场景(CCScene)在游戏里,场景就是关卡,关卡有人物和背景构成

    布景(CCLayer)从概念上说,布景就是场景里的背景,其实就是层次的概念,这种概念在kjava时代就有,就是手动的把游戏中的场景分层(也有靠地图编辑器实现这一功能的)

    人物(CCSprite),这就很明显了,当然包括主角和敌人,和npc,以我个人的理解,也包括游戏中的动态大图素及机关等

    动作(CCAction),就是人物(CCSprite)拥有的动作

    在AppDelegate除了构建函数和析构函数之外,就是处理暂停和重新开始的函数,initInstance函数处理不同平台的问题,在applicationDidFinishLaunching中就是处理导演类和场景开始

    HelloWorld::init() 为程序启动前进行初始化函数.布置启动界面.

    如何加入一个精灵,然后通过点击屏幕使其动起来.

    点击屏幕,切换背景图像.

    场景类CCScene, 布景层类CCLayer, 人物精灵类CCSprite, 菜单类CCMenu

    一个场景中有多个精灵,如果想通过只管理一个精灵就能够同时控制全部精灵(如位置,旋转,缩放):

    创建一个节点,该节点什么都没有,无显示.将其他精灵全部addchild到该节点下.那么以后只要操作该子节点即可.

    切换场景动画的使用步骤如下:1) 新建场景。2) 根据需要的新建场景的切换动画选择CCTransitionScene子类, 通过create将之前建

    的场景传入其中, 并设置其他参数。3) 调用CCDirector::sharedDirector()->replaceScene(第2步中定义的CCTransitionScene的子类) 替换新场景。

    疑问, 目前知道如何在界面中呈现一张场景,场景是可以直接设置一张图像的。 目前想知道的是如何进行鼠标/触屏交互,做出一些改变。如点击一下切换图片,拖动图片,通过键盘或者是拖动,来移动一个东西。教程中都是各种类的介绍说明,以及使用规则,我现在想知道的是,如何在工程中使用这些类?在哪里写代码?如何通过代码控制精灵?如何把自己写的代码放入在工程中?

    瞬间动作 CCActionInstant

    延时动作 CCActionInterval

    程序运行时期,由mainLoop方法维持运行着游戏之内的各个逻辑,当在弹出最后一个场景,或者直接调用CCDirector::end();方法后,触发游戏的清理工作,执行purgeDirector方法,从而结束了 CCEGLView(不同平台不同封装,PC使用OpenGl封装,移动终端封装的为 OpenGl ES) 的运行,调用其end()方法,从而直接执行exit(0);退出程序进程,从而结束了整个程序的运行。(Android 平台的 end() 方法内部通过Jni 方法 terminateProcessJNI(); 调用 Java 实现的功能,其功能一样,直接结束了当前运行的进程)

    helloword是一个图层。

    大概明白是什么个意思了,scene为场景,layer为布景,比如在游戏开始界面就是一个场景,在游戏进行时就是一个场景。

    在游戏开始的场景中加入 ‘开始游戏’按钮(menuitem),然后设置按钮回调函数,然后在回调函数中进行:

    auto scene = GameScene::createScene();

    // run

    CCDirector::sharedDirector()->replaceScene(scene);

    这样就进行切换到第二个场景中去了。现在就相当于进入了游戏场景中,我们可以在游戏的场景中添加精灵了!

    目前知道这样的切换关系了。可以对自己新建立的场景 进行布置了。

    假如我现在假如一个坦克精灵。那么我应该如何通过键盘/鼠标进行点击控制它运动呢?

    展开全文
  • Cocos2dx 入门小游戏实例

    千次阅读 2014-03-17 22:44:45
    cocos2dx 入门小游戏实例

    从图书馆借了本木头的书籍,以下实例来自书籍,写在这里仅作笔记。。


    游戏内容大概如下:

    1.一个Sprite在地图上一直在跑,Sprite可以跳跃(其实是地图不断向左滚动)

    2.途中有金币,Sprite吃金币,左上方的Score会++,并且会有+15的字样出现



    1.创建实体类Entity,这是一个基类,主要用来绑定一个精灵,返回一个精灵

    #ifndef Entity_H
    #define Entity_H
    
    #include "cocos2d.h"
    using namespace cocos2d;
    
    class Entity:public CCNode
    {
    public:
    	Entity();
    
    	~Entity();
    
    	CCSprite* getSprite();
    
    	void bindSprite(CCSprite* sprite);
    
    private:
    	CCSprite* m_sprite;
    };
    #endif

    #include "Entity.h"
    
    Entity::Entity()
    {
    	m_sprite=NULL;
    }
    Entity::~Entity()
    {
    
    };
    
    CCSprite* Entity::getSprite()
    {
    	return this->m_sprite;
    }
    void Entity::bindSprite(CCSprite* sprite){
    	this->m_sprite=sprite;
    	this->addChild(m_sprite);
    }



    2.创建一个玩家主角类,可以jump,吃金币等

    #ifndef _Player_H
    #define _Player_H
    
    #include "cocos2d.h"
    #include "Entity.h"
    
    
    using namespace cocos2d;
    
    #define JUMP_ACTION_TAG 1;
    
    class Player:public Entity
    {
    public:
    	Player();
    	~Player();
    	CREATE_FUNC(Player);
    	virtual bool init();
    public:
    	void jump();
    	void jumpEnd();
    	void hit();//主角和怪物撞击(玩家受伤害)
    	int getMoney();
    	CCRect getBoundingBox();/*获取碰撞范围*/
    	void resetData();
    	void actionEnd();
    private:
    	bool m_isJumping;
    	int m_money;/*金钱*/
    
    };
    #endif
    #include "Player.h"
    #include "FlowWord.h"
    
    Player::Player()
    {
    	m_isJumping=false;
    	m_money=0;/*初始金钱为0*/
    }
    Player::~Player()
    {
    
    }
    bool Player::init()
    {
    	return true;
    }
    
    void Player::jump()
    {
    	if(!getSprite())
    	{
    		return;
    	}
    	if(m_isJumping)/*如果主角还在跳跃中,则不重复跳跃*/
    	{
    		return;
    	}
    
    	m_isJumping=true;
    
    	/*创建动作,2s,原地跳跃(即落地的地点相对于起跳地点x偏移0,y偏移0),高度250,弹跳次数1*/
    	CCJumpBy* jump=CCJumpBy::create(1.5f,ccp(0,0),200,1);
    	/*callFunc也是一个动作,作用是调用一个函数*/
    	CCCallFunc* callFunc = CCCallFunc::create(this, callfunc_selector(Player::jumpEnd));
    	/*组合动作*/
    	CCActionInterval* jumpActions=CCSequence::create(jump,callFunc,NULL);
    	
    	runAction(jumpActions);
    }
    
    void Player::jumpEnd()
    {
    	m_isJumping=false;
    }
    void Player::hit()
    {
    	if(getSprite()==NULL)
    	{
    		return;
    	}
    	/*加钱特效提示*/
    	FlowWord* flowword=FlowWord::create();
    	this->addChild(flowword);
    	flowword->showWord("+15",getSprite()->getPosition());
    	
    	m_money+=15;
    
    	/*创建4种动作对象*/
    	CCMoveBy* backMove=CCMoveBy::create(0.1f,ccp(-20,0));
    	CCMoveBy* forwardMove=CCMoveBy::create(0.1f,ccp(20,0));
    	CCRotateBy* backRotate=CCRotateBy::create(0.1f,-5,0);
    	CCRotateBy* forwardRotate=CCRotateBy::create(0.1f,5,0);
    
    	/*分别组合成两种动作(同时执行)*/
    	CCSpawn* backActions=CCSpawn::create(backMove,backRotate,NULL);
    	CCSpawn* forwardActions=CCSpawn::create(forwardMove,forwardRotate,NULL);
    
    	CCCallFunc* callFunc=CCCallFunc::create(this,callfunc_selector(Player::actionEnd));
    
    	CCActionInterval* actions=CCSequence::create(backActions,forwardActions,callFunc,NULL);
    	
    	//this->stopAllActions();
    	//resetData();
    
    	this->runAction(actions);
    
    
    }
    void Player::resetData()
    {
    	if(m_isJumping)
    	{
    		m_isJumping=false;
    	}
    	this->setPosition(ccp(200,500/4));
    	this->setScale(1.0f);
    	setRotation(0);
    }
    int Player::getMoney()
    {
    	return m_money;
    }
    CCRect Player::getBoundingBox()
    {
    	if(getSprite()==NULL){
    		return CCRectMake(0,0,0,0);
    	}
    	/*由于Sprite是放在Player上的,所以要检测Player的碰撞范围*/
    	CCSize spriteSize=getSprite()->getContentSize();
    	CCPoint entityPos=this->getPosition();//获取player中心点
    
    	//获取Player左下角的坐标值
    	int x=entityPos.x-spriteSize.width/2;
    	int y=entityPos.y-spriteSize.height/2;
    
    	return CCRectMake(x,y,spriteSize.width,spriteSize.height);
    }
    
    void Player::actionEnd()
    {
    	this->setScale(1.0f);
    	setRotation(0);
    }




    3.创建怪物类(金币),继承于实体类
    --

    #ifndef _Monster_H_
    #define _Monster_H_
    
    #include "Entity.h"
    #include "cocos2d.h"
    #include "Player.h"
    #include "ccMacros.h"
    
    USING_NS_CC;
    
    class Monster:public Entity
    {
    public:
    	Monster();
    	~Monster();
    	CREATE_FUNC(Monster);
    	virtual bool init();
    	
    public:
    	void show();
    	void hide();
    	void reset();//重置怪物数据
    	bool isAlive();//是否活动状态
    
    	bool isCollideWithPlayer(Player* player);//检测是否碰撞
    private:
    	bool m_isAlive;
    };
    #endif
    #include "Monster.h"
    
    Monster::Monster()
    {
    }
    Monster::~Monster()
    {
    }
    bool Monster::init()
    {
    	return true;
    }
    void Monster::show()
    {
    	if(getSprite()!=NULL)
    	{
    		this->setVisible(true);
    		m_isAlive=true;/*标记为活动状态*/
    	}
    }
    void Monster::hide()
    {
    	if(getSprite()!=NULL)
    	{
    		this->setVisible(false);
    		reset();
    		m_isAlive=false;/*标记为活动状态*/
    	}
    }
    void Monster::reset()
    {
    	if(getSprite()!=NULL)
    	{
    		/*初始化怪物坐标,宽度(800-2800),高度(100-200)*/
    		this->setPosition(ccp(800+CCRANDOM_0_1()*2000,200-CCRANDOM_0_1()*100));
    	}
    }
    bool Monster::isAlive()
    {
    	return m_isAlive;
    }
    bool Monster::isCollideWithPlayer(Player* player)
    {
    	CCRect playerRect=player->getBoundingBox();
    	CCPoint monsterPos=getPosition();
    
    	/*判断是否有交集*/
    	return playerRect.containsPoint(monsterPos);
    }



    4.创建怪物管理器类(MonsterManger),用来管理怪物的显示和隐藏


    #ifndef __MonsterManger_H__
    #define __MonsterManger_H__
    
    #include "cocos2d.h"
    #include "Player.h"
    USING_NS_CC;
    
    #define MAX_MONSTER_NUM 10
    
    class MonsterManger:public CCNode
    {
    public:
    	MonsterManger();
    	~MonsterManger();
    	CREATE_FUNC(MonsterManger);
    	virtual bool init();                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      	virtual void update(float dt);/*重写update函数*/
    	void bindPlayer(Player* player);
    private:
    	void createMonsters();/*创建Monster对象*/
    private:
    	CCArray* m_monsterArr;/*存放怪物数组*/
    	Player* m_player;
    };
    
    #endif

    #include "MonsterManger.h"
    #include "Monster.h"
    
    MonsterManger::MonsterManger(){}
    
    MonsterManger::~MonsterManger(){}
    
    bool MonsterManger::init()
    {
    	bool bRet=false;
    	do 
    	{
    		createMonsters();/*创建怪物*/
    		this->scheduleUpdate();/*启用update*/
    		bRet=true;
    	} while (0);
    	return bRet;
    	
    }
    
    
    void MonsterManger::createMonsters()
    {
    	m_monsterArr=CCArray::create();
    	m_monsterArr->retain();/*防止数组被释放*/
    
    	Monster* monster=NULL;
    	CCSprite* sprite=NULL;
    
    	for(int i=0;i<MAX_MONSTER_NUM; i++)
    	{
    		monster=Monster::create();
    		monster->bindSprite(CCSprite::create("monster.png"));
    		monster->reset();
    
    		this->addChild(monster);  /*将怪物添加到管理器(CCNode)中*/
    		m_monsterArr->addObject(monster);/*添加到数组中,便于管理*/
    	}
    }
    
    void MonsterManger::update(float dt)
    {
    	CCObject* obj=NULL;
    	Monster* monster=NULL;
    	
    	CCARRAY_FOREACH(m_monsterArr,obj)/*循环遍历怪物数组,重复出现在屏幕上*/
    	{
    		monster=(Monster*) obj;
    		if(monster->isAlive())/*活动状态*/
    		{
    			monster->setPositionX(monster->getPositionX()-3);//左移
    			if(monster->getPositionX()<0)
    			{
    				monster->hide();
    
    			}else if(monster->isCollideWithPlayer(m_player)){
    				m_player->hit();
    				monster->hide();
    			}
    		
    		}else/*非活动状态*/
    		{
    			monster->show();//
    		}
    	}
    }
    void MonsterManger::bindPlayer(Player* player)
    {
    	this->m_player=player;
    	this->m_player->retain();//引用计数 +1
    }



    5.创建文字飘动效果,(在主角身上显示"+15"特效)

    #ifndef __FlowWord_H__
    #define __FlowWord_H__
    
    #include "cocos2d.h"
    USING_NS_CC;
    
    class FlowWord:public CCNode
    {
    public:
    	FlowWord();
    	~FlowWord();
    	CREATE_FUNC(FlowWord);
    	virtual bool init();
    public:
    	void showWord(const char* text, CCPoint pos);
    	void flowEnd();
    private:
    	CCLabelTTF* m_textLab;
    };
    
    #endif


    #include "FlowWord.h"
    
    FlowWord::FlowWord(){}
    
    FlowWord::~FlowWord(){}
    
    bool FlowWord::init()
    {
    	m_textLab=CCLabelTTF::create("","Arial",30);
    	m_textLab->setColor(ccc3(255,0,0));
    	m_textLab->setVisible(false);
    
    	this->addChild(m_textLab);
    
    	return true;
    }
    
    void FlowWord::showWord(const char* str,CCPoint pos)
    {
    	m_textLab->setString(str);
    	m_textLab->setPosition(pos);
    	m_textLab->setAnchorPoint(ccp(1,0));
    	m_textLab->setVisible(true);
    
    	//先放大后缩小
    	CCActionInterval* scaleLarge=CCScaleTo::create(0.3f,2.5f,2.5f);
    	CCActionInterval* scaleSmall=CCScaleTo::create(0.4f,0.5f,0.5f);
    	//回调动作,移除效果
    	CCCallFunc* callFunc=CCCallFunc::create(this,callfunc_selector(FlowWord::flowEnd));
    
    	CCActionInterval* actions=CCSequence::create(scaleLarge,scaleSmall,callFunc,NULL);
    
    	m_textLab->runAction(actions);
    }
    
    void FlowWord::flowEnd()
    {
    	m_textLab->setVisible(false);
    	/*true: 从父节点移除,并移除节点的动作和回调函数*/
    	m_textLab->removeFromParentAndCleanup(true);
    }

    6.创建游戏场景类,所有游戏的效果都在这上面展示

    #ifndef __TollgateScene_H__
    #define __TollgateScene_H__
    
    #include "cocos2d.h"
    #include "cocos-ext.h"
    #include "Player.h"
    using namespace cocos2d;
    using namespace cocos2d::extension;
    
    
    class TollgateScene : public CCLayer {
    public:
    	static CCScene* scene();
    	virtual bool init();
    	CREATE_FUNC(TollgateScene);
    
    	virtual void update(float delta);
    
    private:
    	void initBG();  /* 初始化关卡背景 */
    	void createJumpBtn();/*创建跳跃按钮*/
    	void jumpEvent(CCObject* pSender,CCControlEvent event);/*响应按钮点击事件*/
    
    	void createScoreLab();/*创建分数标签*/
    	void createTimeSlider();/*创建时间条*/
    private:
    	CCSprite* m_bgSprite1;
    	CCSprite* m_bgSprite2;
    
    	Player* m_player;
    
    	CCLabelTTF* m_scoreLab;//分数标签
    	CCControlSlider* m_TimeSlider;//时间条
    
    	int m_score;	/*得分*/
    	int m_curTime; /*当前时间*/
    };
    
    #endif

    #include "TollgateScene.h"
    #include "MonsterManger.h"
    
    CCScene* TollgateScene::scene() {
    	CCScene* scene = NULL;
    	do 
    	{
    		scene = CCScene::create();
    		CC_BREAK_IF(!scene);
    
    		TollgateScene* layer = TollgateScene::create();
    		CC_BREAK_IF(!layer);
    
    		scene->addChild(layer, 1);
    	} while (0);
    
    	return scene;
    }
    
    bool TollgateScene::init() {
    	bool bRet = false;
    
    	do 
    	{
    		CCSize visibleSize = CCDirector::sharedDirector()->getVisibleSize();
    
    		/*游戏标题图片*/
    // 		CCSprite* titleSprite = CCSprite::create("title.png");
    // 		titleSprite->setPosition(ccp(visibleSize.width / 2, visibleSize.height - 50));
    // 		this->addChild(titleSprite, 2);
    
    		/*创建猪脚*/
    		CCSprite* sprite = CCSprite::create("sprite.png");
    		//sprite->setFlipX(true);
    		m_player = Player::create();
    		m_player->bindSprite(sprite);
    		m_player->setPosition(ccp(200, visibleSize.height / 4));
    		
    		this->addChild(m_player,1);
    		
    		/*初始化背景图片*/
    		initBG();
    
    		/*创建按钮*/
    		createJumpBtn();
    
    		/*设置启用CCNode的update()函数,游戏会在每一帧调用update()函数*/
    		this->scheduleUpdate();
    
    		/*创建怪物管理器(管理器里面放了很多怪物)*/
    		MonsterManger* monsterManger=MonsterManger::create();
    		monsterManger->bindPlayer(m_player);
    		this->addChild(monsterManger,4);
    
    		/*创建分数标签*/
    		createScoreLab();
    		/*创建时间条*/
    		createTimeSlider();
    
    		bRet = true;
    	} while (0);
    
    	return bRet;
    }
    
    void TollgateScene::initBG() {
    	CCSize visibleSize = CCDirector::sharedDirector()->getVisibleSize();
    
    	m_bgSprite1 = CCSprite::create("tollgateBG.jpg");
    	m_bgSprite1->setPosition(ccp(visibleSize.width / 2, visibleSize.height / 2));
    	this->addChild(m_bgSprite1, 0);
    
    	m_bgSprite2 = CCSprite::create("tollgateBG.jpg");
    	m_bgSprite2->setPosition(ccp(visibleSize.width + visibleSize.width / 2, visibleSize.height / 2));
    	m_bgSprite2->setFlipX(true);
    	this->addChild(m_bgSprite2, 0);
    }
    
    void TollgateScene::update(float delta)
    {
    	CCSize mapSize=m_bgSprite1->getContentSize();//地图大小
    
    	int posX1=m_bgSprite1->getPositionX();  //地图1的x坐标
    	int posX2=m_bgSprite2->getPositionX();	//地图2的x坐标
    
    	int iSpeed = 2;	//地图滚动的速度
    
    	posX1-=iSpeed;	//两张地图一起向左滚动
    	posX2-=iSpeed;
    
    	//创建无限循环
    	if(posX1<=-mapSize.width/2)
    	{
    		posX1=mapSize.width+mapSize.width/2;
    		posX2=mapSize.width/2;
    	}
    	if(posX2<=-mapSize.width/2)
    	{
    		posX1=mapSize.width/2;
    		posX2=mapSize.width+mapSize.width/2;
    	}
    
    	m_bgSprite1->setPositionX(posX1);
    	m_bgSprite2->setPositionX(posX2);
    
    	/*分数增加*/
    	m_score=m_player->getMoney();
    	m_scoreLab->setString(CCString::createWithFormat("Score:%d",m_score)->getCString());
    
    	m_TimeSlider->setValue(--m_curTime);
    	
    }
    void TollgateScene::createJumpBtn()
    {
    	CCSize visibleSize=CCDirector::sharedDirector()->getVisibleSize();
    
    	/*按钮标题*/
    	CCLabelTTF* jumpLabel=CCLabelTTF::create("Jump","Arial",35);
    
    	/*按钮状态图片*/
    	CCScale9Sprite* jumpNorBG=CCScale9Sprite::create("button.png");
    	CCScale9Sprite* jumpLightBG=CCScale9Sprite::create("buttonHighlighted.png");
    	
    	/*创建按钮*/
    	CCControlButton* jumpBtn=CCControlButton::create(jumpLabel,jumpNorBG);
    	jumpBtn->setPosition(ccp(visibleSize.width-80,50));
    	jumpBtn->setBackgroundSpriteForState(jumpLightBG,CCControlStateHighlighted);
    	
    	/*添加事件*/
    	jumpBtn->addTargetWithActionForControlEvents(this,
    		cccontrol_selector(TollgateScene::jumpEvent),
    		CCControlEventTouchDown);
    
    	this->addChild(jumpBtn);
    }
    
    void TollgateScene::jumpEvent(CCObject* pSender,CCControlEvent event)
    {
    	m_player->jump();
    }
    
    void TollgateScene::createScoreLab()
    {
    	m_score=m_player->getMoney();
    	CCSize visibleSize=CCDirector::sharedDirector()->getVisibleSize();
    	m_scoreLab=CCLabelTTF::create("Score:"+m_score,"Arial",35);
    	m_scoreLab->setAnchorPoint(ccp(0,1));
    	m_scoreLab->setPosition(ccp(0,visibleSize.height));
    	this->addChild(m_scoreLab);
    
    }
    
    void TollgateScene::createTimeSlider()
    {
    	CCSize visibleSize=CCDirector::sharedDirector()->getVisibleSize();
    	m_curTime=10000;
    	m_TimeSlider=CCControlSlider::create(
    		CCSprite::create("background.png"),
    		CCSprite::create("progress.png"),
    		CCSprite::create("sliderThumb.png")
    		);
    	m_TimeSlider->setPosition(ccp(
    		m_TimeSlider->getContentSize().width/2,
    		visibleSize.height-m_TimeSlider->getContentSize().height-m_scoreLab->getContentSize().height
    		));
    	m_TimeSlider->setTouchEnabled(false);
    	m_TimeSlider->setMaximumValue(10000);
    	m_TimeSlider->setMinimumValue(0);
    	m_TimeSlider->setValue(m_curTime);
    	this->addChild(m_TimeSlider,3);
    }



    运行效果如下




    源码

    展开全文
  • cocos2dx入门资料及学习资源 分类: cocos2dx_3.x2014-07-25 09:22 1030人阅读 评论(0) 收藏 举报 cocos2dx学习资料 目录(?)[+] 1. 书籍学习 (1)《cocos2dx游戏开发之旅 》 (2...
  • 一个Sprite在地图上一直在跑,Sprite可以跳跃(其实是地图不断向左滚动)2.途中有金币,Sprite吃金币,左上方的Score会++,并且会有+15的字样出现1.创建实体类Entity,这是一个基类,主要用来绑定一个精灵,返回一个...
  • Cocos2dx 入门学习准备

    2020-03-10 11:37:54
    1.掌握语言: 2.使用平台:video studio 3.需要下载的工具包:Cocos2dx开发包,Python2.7
  • cocos2dx入门篇(一)

    2020-05-13 00:26:17
    我使用的cocos2dx环境配置如下: 1、cocos2dx 2.2.6 2、python 2.7.18 3、visual studio 2010 如果懒得去找这些资源,也可通过下方链接下载 链接: https://pan.baidu.com/s/1ClxLq8Qb0PT9RcYYnHja1g 提取码: 7...
  • cocos2dx入门学习第一天

    千次阅读 2014-04-07 17:53:06
    一、cocos2d的种类有好几种,比如cocos2d javascrip,cocos2d html5,cocos2d和cocos2dx,其中cocos2dx是用c++写的跨平台的库,而cocos2d是用objc编写的,只在iphone上用。 二、到cocos2dx官方网站下载压缩包,然后...
  • Cocos2dx入门全程记录

    千次阅读 2013-09-11 15:13:36
    本篇博客记录我刚开始学习cocos2dx的历程 问题一:vs2012打开cocos2d-win32.vc2012.sln突然出问题了,弹窗如下图,cocos所有的项目都显示未加载 解决方法: 参考http://bbs.csdn.net/topics/390514959 下载...
  • Cocos2d-x 来源于 Cocos2d-iPhone,因此无论是代码风格还是文件结构,很多方面都沿袭了 Cocos2d-iPhone 的使用习惯。以后文章中,将详细介绍 Cocos2d-x 的代码风格与文件结构。   打开"AppDelegate.cpp",我们...
  • Cocos-JS对基本只有java基础的我来说学起来比较简单,但是鉴于手头能拿到公司的源码基本上都是C++所以还是打算入门C++ 然后就是看到前辈用的是visual studio和cocos studio 所以抱着兴趣的目的开始尝试一下~诶嘿!...
  • cocos2dx入门需要了解的工具

    千次阅读 2017-06-02 18:59:40
    官网 Cocos2d-x - World’s #1 Open-Source Game ...Download Cocos2d-x, Cocos Creator and Cocos | Cocos2d-x Windows Setup - Cocos Documentation Asset Our editors and tools 目前有三种方法来创建cocos项目
  • 1.cocos2dx对于win10有部分不兼容,当前时间(2020-4-20)不建议使用。 2.cocos2dx的3.X版本不一定对ubuntu18兼容,不过都对16版本兼容 3.cmake和python的版本一定要搞清楚 4.运行测试文件是遇见file too short ...
  • cocos2dx入门二之游戏循环

    千次阅读 2012-12-22 19:22:55
    Cocos2dxRenderer.onDrawFrame()->Cocos2dxRenderer.nativeRender()->Java_org_cocos2dx_lib_Cocos2dxRenderer.cpp.Java_org_cocos2dx_lib_Cocos2dxRenderer_nativeRender()-> CCDisplayLinkDirector.main
  • #ifndef __HELLOWORLD_SCENE_H__ #define __HELLOWORLD_SCENE_H__ ...#include "cocos2d.h" #include "SimpleAudioEngine.h" #include "cocos-ext.h" using namespace cocos2d; using namespace cocos2d::extension;
  • 1、CCTileMapAtlas: //创建一个CCTileMapAtlas: CCTileMapAtlas* map = CCTileMapAtlas::create...cocos2dx为了兼容性,所以保留了,现在cocos2dx不推荐使用此种方式拼图了... 2、CCTMXTiledMap //创建一个CCTMXTiledMa
  • Cocos2dxRenderer.onSurfaceCreated()-> Cocos2dxRenderer.nativeInit()->main.cpp.Java_org_cocos2dx_lib_Cocos2dxRenderer_nativeInit()->CCApplication.run()->AppDelegate.applicationDidFinishLaunc
  • cocos2dx 入门练习杂记

    2013-12-08 13:39:00
    # cocos2dx 代码中调用的图片文件,默认路径为工程同级目录 的[ Resources ]文件夹中,而不是工程目录内 # VS运行,中文乱码 因为Cocos2d-x使用的是UTF-8编码,VS默认GB2312 转换函数网上有很多,这里保留一...

空空如也

空空如也

1 2 3 4 5 ... 13
收藏数 255
精华内容 102
关键字:

cocos2dx入门