zoukankan      html  css  js  c++  java
  • 五毛的cocos2d-x学习笔记03-控件

    VS2013快捷键:注释,Ctrl+K+C;取消注释Ctrl+K+U。都是单行。要实现多行注释与取消注释,就选中多行。
    run方法调用了AppDelegate的applicationDidFinishLaunching方法
    要调整窗体的大小的话,在AppDelegate.cpp的

    auto director = Director::getInstance();
    auto glview = director->getOpenGLView();
    if(!glview) {
    glview = GLViewImpl::create("My Game");
    director->setOpenGLView(glview);
    }


    下面添加一行:

    glview->setFrameSize(320,480);


    效果如图:

    director->setDisplayStats(true);//显示帧频
    director->setAnimationInterval(1.0/60);//设置动画间隔。设置帧频大小,设置每一帧时间的间隔。1.0/60表示现在的帧频是60帧。

    在讲今天的内容之前,需要了解几个概念:Director, Scene, Layer, Sprite, 本地坐标VS世界坐标,锚点,Z轴顺序。

    游戏中基本上所有的类都派生自节点类(Node),如图

      

    •   Director是整个cocos2dx引擎的核心,是整个游戏的导航仪,游戏中的一些常用操作就是由Director来控制的,比如OpenGL ES的初始化,场景的转换,游戏暂停继续的控制,世界坐标和GL坐标之间的切换,对节点(游戏元素)的控制等,还有一些游戏数据的保存调用,屏幕尺寸的获取等都要由Director类来管理控制的。

           1、获取Director实例:auto director = Director::getInstance();

             2、Director控制场景的常用方法:用的栈的思想

        • runWithScene(Scene *scene)
        • replaceScene(Scene *scene)
    •   场景(Scene)是层的容器。一般创建Scene的子类,在子类的初始化中载入游戏资源,为场景添加层,启动音乐播放等等。
    •   层(Layer)通常包含的是直接在屏幕上呈现的内容,并且可以接受用户的输入事件,包括触摸,加速度计和键盘输入等。
    •   精灵(Sprite)和其他游戏引擎中的精灵相似,它可以移动,旋转,缩放,执行动画,并接受其他转换。

    笛卡尔坐标系、笛卡尔右手系、屏幕坐标系、cocos2d坐标系:

    •   笛卡尔坐标系中定义右手系原点在左下角,x向右,y向上,z向外,OpenGL坐标系为笛卡尔右手系。
    •   Cocos2d坐标系和OpenGL坐标系一样,原点为屏幕左下角,x向右,y向上。
    •   iOS, Android, Windows Phone等在开发应用时使用的是标准屏幕坐标系,原点为屏幕左上角,x向右,y向下。
    •   世界坐标系也叫绝对坐标系,“世界”指的是游戏世界。本地坐标系也叫相对坐标系,和节点关联,随节点移动。

    锚点(Anchor Point):

    •   两个参数在(0,1)之间。
    •   Layer的Anchor Point默认值为(0,0),其他Node的默认值为(0.5,0.5)。
    •   将一个节点添加到父节点里面时,需要设置其在父节点上的位置,本质上是设置节点的锚点在父节点坐标上的位置。
    •   Layer添加子节点默认在(0,0),除非子节点用setPosition方法修改。setPosition默认参数为(0, 0)(相对坐标系)。
    •   个人认为,锚点就是中心变化点。

    VertexZ, PositionZ, Zorder:

    •   positionZ = VertexZ。
    •   positionZ:全局渲染顺序,即在根节点上的渲染顺序。
    •   zOrder: 局部渲染顺序,即在其父节点上的渲染顺序,与Node的层级有关。
    •   当同时设置了positionZ和zOrder, 则positionZ生效。
    •   个人理解:positionZ比zOrder优先级更大。

    Sprite:

      (Sprite)精灵只是很简单的表现,可以理解为图片对象,仅用于图像表现。所以包含攻击力、血量、速度等一系列属性的飞机不是Sprite。飞机包含了精灵对象,是组合。
      Sprite的create方法有4个重载。
      我们要把图片img.jpg放在项目的Resources目录下。然后在VS2013中,展开我们的项目,右键resource——>添加——>添加现有项(快捷键Alt+Shift+A)。找到Resources目录下的img.jpg,添加进来。
      注释掉HelloWorldScene.cpp的init()方法中其他语句,只保留

    bool HelloWorld::init()
    if ( !Layer::init() )
    {
    return false;
    }
    //我们的代码从这里开始
    return true;
    }

      从我标注的地方添加代码:

    auto s = Sprite::create("img.jpg");
    this->addChild(s);

      Shift+F5,运行项目,结果如图。

      咦?和我们想象的不一样。图片只显示了右上角1/4。因为Sprite对象默认的锚点是(0.5, 0.5)。我们调整锚点为(0, 0)。

    s->setAnchorPoint(Vec2(0, 0));//方法的参数是一个二维向量


      这样,图片整个都出来了。

    Director、Layer、Scene:
      Director: 功能是切换Scene。只有在第一次呈现场景时用runWithScene,有场景存在的情况下,用replaceScene。
      为了演示Scene是怎么操作的,我们注释掉AppDelegate.cpp的applicationDidFinishLaunching方法中的这条语句:auto scene = HelloWorld::createScene();
      并在下面添加如下代码:

    Scene *scene = Scene::create();
    Layer *layer = Layer::create();
    scene->addChild(layer);
    Sprite *s = Sprite::create("img.jpg");
    s->setAnchorPoint(Vec2(0, 0));
    layer->addChild(s);

      运行效果和原来一样。

     

    注:以下代码无特殊说明,都写在HelloWorldScene.cpp的init方法中。
    Log:

      Log只能在调试(快捷键F5)时才能看到。
      

    log("Hello cocos2d-x log");
    log("Hello int %d",5);

    MessageBox(对话框):
    创建方法:MessageBox("消息内容", "消息标题");
    效果如图:

    LabelTTF(文本标签):

    //获得屏幕可见区域的大小
    Size visibleSize = Director::getInstance()->getVisibleSize();
    
    LabelTTF *label = LabelTTF::create();
    label->setString("Hello cocos2d-x");
    label->setFontSize(36);
    //setPosition放置的是label的锚点,而label的锚点默认是(0.5, 0.5),在label的正中间
    //下面这条语句将label放在屏幕的正中间
    label->setPosition(visibleSize.width/2, visibleSize.height/2);
    this->addChild(label);

      运行结果:

     

    TextFieldTTF(输入文本):

    Size visibleSize = Director::getInstance()->getVisibleSize();
    TextFieldTTF *tf = TextFieldTTF::textFieldWithPlaceHolder("input here","宋体",20);
    tf->setPosition(visibleSize.width/2, visibleSize.height/2);
    this->addChild(tf);
    
    auto listener = EventListenerTouchOneByOne::create();
    listener->onTouchBegan = [](Touch *t, Event *e){
        log(">>>>>>>>");
        return false;
    };
    
    Director::getInstance()->getEventDispatcher()->addEventListenerWithSceneGraphPriority(listener,tf);

      以上代码,单击input here输入文本,有log输出,但是,单击屏幕其他地方,也有log输出,这就不是我们希望的结果了。

      修改代码如下:

    [](Touch *t, Event *e){
        if (tf->getBoundingBox().containsPoint(t->getLocation())){
            log(">>>>>>>>");
        }
        return false;
    };


      
    这段其实是函数闭包,我们在函数闭包里面是访问不到外面的变量的。要解决这个问题,在中括号里面写tf,即[tf]。
      最终代码如下:

    Size visibleSize = Director::getInstance()->getVisibleSize();
    TextFieldTTF *tf = TextFieldTTF::textFieldWithPlaceHolder("input here","宋体",20);
    tf->setPosition(visibleSize.width/2, visibleSize.height/2);
    this->addChild(tf);
    
    auto listener = EventListenerTouchOneByOne::create();
    listener->onTouchBegan = [tf](Touch *t, Event *e){
        if (tf->getBoundingBox().containsPoint(t->getLocation())){
            //log(">>>>>>>>");
            tf->attachWithIME();//连接到IME,就可以输入了
        }
        else{
            tf->detachWithIME();//断开连接
      }
    return false;
    };
    
    Director::getInstance()->getEventDispatcher()->addEventListenerWithSceneGraphPriority(listener,tf);

      效果如图:

    创建自定义类:
      cocos2d-x发展自cocos2d,cocos2d最开始是用OC开发的,所以cocos2d-x也保留了OC的语言习惯。

      VS2013,如果你直接在:解决方案资源管理器——>HelloCocos——>src——>添加——>新建项,创建自定义类,那么你在include进其他.cpp或.h文件的时候,会报“无法打开源文件”的错。因为项目的层级显示是虚拟文件夹,你的新建项在proj.win32目录下,不在Classes目录下,当然找不到。所以为了统一管理,在Classes目录下新建.cpp和.h文件,然后解决方案资源管理器——>HelloCocos——>src——>添加——>现有项。资源文件也是如此。

      自定义一个类,中间显示一个小球。ball.png放在HelloCocosResources目录下;Ball.h和Ball.cpp放在HelloCocosClasses目录下。

      Ball.h如下:

    #ifndef _HELLOCOCOS_BALL_
    #define _HELLOCOCOS_BALL_
    
    #include<iostream>
    #include "cocos2d.h"
    
    using namespace cocos2d;//因为Sprite在cocos2d的命名空间里
    
    class Ball : public Sprite{
    public:
        virtual bool init();
        /*static Ball* create(){
            Ball* b = new Ball();
            b->init();
            b->autorelease();
    
            return b;
        }*/
        CREATE_FUNC(Ball);
    };
    
    #endif

    Ball.cpp如下:

    #include "Ball.h"
    bool Ball::init(){
        initWithFile("ball.png");
        return true;
    }

    在HelloWorldScene.cpp的init方法中添加如下代码:

    Size visibleSize = Director::getInstance()->getVisibleSize();
    auto ball = Ball::create();
    ball->setPosition(visibleSize.width/2,visibleSize.height/2);
    this->addChild(ball);

      具体添加位置如图:

      运行结果:

    今天就这么多内容。明天加油!

  • 相关阅读:
    June. 26th 2018, Week 26th. Tuesday
    June. 25th 2018, Week 26th. Monday
    June. 24th 2018, Week 26th. Sunday
    June. 23rd 2018, Week 25th. Saturday
    June. 22 2018, Week 25th. Friday
    June. 21 2018, Week 25th. Thursday
    June. 20 2018, Week 25th. Wednesday
    【2018.10.11 C与C++基础】C Preprocessor的功能及缺陷(草稿)
    June.19 2018, Week 25th Tuesday
    June 18. 2018, Week 25th. Monday
  • 原文地址:https://www.cnblogs.com/rainmer/p/4678771.html
Copyright © 2011-2022 走看看