【Cocos2D-X 学习笔记】为精灵添加单点触控

  由于Cocos2d-x处于新学的阶段,因此最近也无法进行系统地更新,只会选择一些典型的Demo贴上来,一来是与大家分享,而来也可以作为以后回顾时的参考。

今天介绍一下Cocos2d-x的触摸事件处理,了解Android开发的朋友们知道,Android里会用一个OnClickListener()进行事件监听,而在J2SE中也会有Event类实现专门的监听处理。在Cocos2d-x中,因为是游戏引擎,用户在玩游戏时总是要通过屏幕与游戏进行交互,可想而知触摸事件是主要处理的事件。这里主要讲一下如何为精灵添加触控事件,最终的效果是做一个可以拖动的小球,内容很简单。

cocos2d-x提供的CCSprite (或者Sprite)类并没有添加触控监听接口,这就要求我们需要自己创建一个类继承CCSprite并且添加单点触控接口CCTargetedTouchDelegate (多点触控同理),并且实现三个虚方法bool  ccTouchBegan()    ccTouchMoved()  ccTouchEnded()  , 然后需要响应触摸事件还需要把该对象添加进CCTouchDispatcher中。

  下面是具体的代码:

  首先是Ball类的声明:

ball.h

#include "cocos2d.h"

USING_NS_CC;     //using namespace cocos2d

class Ball: public CCSprite,public CCTargetedTouchDelegate{

public:
    virtual void onEnter();
    //新创建一个Ball对象并显示时就会调用onEnter方法,在onEnter中把该对象添加进CCTouchDispatcher(触摸事件管理器)中

    virtual void onExit();
    //该对象终结时会调用onExit方法,在该方法中,把该对象从CCTouchDispatcher中删除

    static Ball* create(char *imageName);
    //重写了父类的create()方法,使得可以喝CCSprite一样通过create方法创建一个Ball精灵

public:
    virtual bool isPointInside(CCPoint point);
    //判断当前触摸到的点是否刚好在精灵上

    //触摸事件必须要实现的三个接口
public:
    virtual bool ccTouchBegan(CCTouch *touch,CCEvent *pevent);
    virtual void ccTouchMoved(CCTouch *touch,CCEvent *pevent);
    virtual void ccTouchEnded(CCTouch *touch,CCEvent *pevent);

};

然后是各个虚函数的具体实现部分

ball.cpp

#include "cocos2d.h"
#include "ball.h"

USING_NS_CC;

//在类声明里面出现的静态成员必须在定义的时候进行外部引用声明!!

void Ball::onEnter(){
    CCDirector *director=CCDirector::sharedDirector();
    director->getTouchDispatcher()->addTargetedDelegate(this,0,true);         //将该对象添加进事件处理序列
    CCSprite::onEnter();     //调用其父类的构造方法保证精灵能够正常初始化
    CCLog("On Enter!");

}

void Ball::onExit(){
    CCDirector *director=CCDirector::sharedDirector();
    director->getTouchDispatcher()->removeDelegate(this);                      //将该对象从事件处理序列中移除
    CCSprite::onExit();
    CCLog("On Exit!");
}

Ball* Ball::create(char *imageName){
    Ball *ball=new Ball();              //采用new方法创建一个对象,并设置自动释放
    ball->autorelease();
    ball->initWithTexture(CCTextureCache::sharedTextureCache()->addImage(imageName));                                            //CCTextureCache是一个单例模式,同CCDirector类似,addImage()方法回返回一个Texture2D对象供精灵初始化使用
                                          //addIamge方法回返回一个设定图像的Texture2D对象
    return ball;
}

bool Ball::ccTouchBegan(CCTouch *touch,CCEvent *pEvent){
    CCPoint point=touch->getLocation();
    if(!isPointInside(point))
        return false;            //ccTouchBegan返回false时表示不再执行ccTouchMoved 和ccTouchEnded函数,否则返回true时会执行上述两个方法
    return true;

}

void Ball::ccTouchMoved(CCTouch *touch,CCEvent *pEvent){
    CCPoint point=touch->getLocation();
    this->setPosition(point);
}

void Ball::ccTouchEnded(CCTouch *touch,CCEvent *pEvent){

}

//因为使用了new 方法,所以必须把所有的虚函数都实现,这是C++自身的语法
bool Ball::isPointInside(CCPoint point){
    CCPoint nodePoint=this->convertToNodeSpace(point);
    CCSize size=this->getContentSize();
    if(nodePoint.x>size.width ||nodePoint.x<0 ||nodePoint.y>size.height ||nodePoint.y<0 )
        return false;
    else
        return true;
}

然后在CCLayer中像添加一个普通精灵一个添加即可,create()创建对象,设置位置,通过addChild()添加进图层即可:

#include "HelloWorldScene.h"
#include "ball.h"

using namespace cocos2d;

CCScene* HelloWorld::scene()
{
    CCScene * scene = NULL;
    do
    {
        // ‘scene‘ is an autorelease object
        scene = CCScene::create();
        CC_BREAK_IF(! scene);

        // ‘layer‘ is an autorelease object
        HelloWorld *layer = HelloWorld::create();
        CC_BREAK_IF(! layer);

        // add layer as a child to scene
        scene->addChild(layer);
    } while (0);

    // return the scene
    return scene;
}

// on "init" you need to initialize your instance
bool HelloWorld::init()
{
    bool bRet = false;
    do
    {
        //////////////////////////////////////////////////////////////////////////
        // super init first
        //////////////////////////////////////////////////////////////////////////

        CC_BREAK_IF(! CCLayer::init());

        //////////////////////////////////////////////////////////////////////////
        // add your codes below...
        //////////////////////////////////////////////////////////////////////////

        // 1. Add a menu item with "X" image, which is clicked to quit the program.

        // Create a "close" menu item with close icon, it‘s an auto release object.
        CCMenuItemImage *pCloseItem = CCMenuItemImage::create(
            "CloseNormal.png",
            "CloseSelected.png",
            this,
            menu_selector(HelloWorld::menuCloseCallback));
        CC_BREAK_IF(! pCloseItem);

        // Place the menu item bottom-right conner.
        pCloseItem->setPosition(ccp(CCDirector::sharedDirector()->getWinSize().width - 20, 20));

        // Create a menu with the "close" menu item, it‘s an auto release object.
        CCMenu* pMenu = CCMenu::create(pCloseItem, NULL);
        pMenu->setPosition(CCPointZero);
        CC_BREAK_IF(! pMenu);

        // Add the menu to HelloWorld layer as a child layer.
        this->addChild(pMenu, 1);

        Ball *ball=Ball::create("ball.png");
        ball->setPosition(ccp(100,100));
        this->addChild(ball);

        bRet = true;
    } while (0);

    return bRet;
}

void HelloWorld::menuCloseCallback(CCObject* pSender)
{
    // "close" menu item clicked
    CCDirector::sharedDirector()->end();
}

关于资源文件配置,cocos2d-x引擎生命周期等不再详述。

【Cocos2D-X 学习笔记】为精灵添加单点触控,布布扣,bubuko.com

时间: 2024-12-20 01:08:49

【Cocos2D-X 学习笔记】为精灵添加单点触控的相关文章

Android学习笔记四:添加Source

问题描述 Source not foundThe JAR file D:\.....\sdk\platforms\android-20\android.jar has no source attachment. 问题原因及解决办法 1. 使用SDK Manager下载最新版本的Sources for Android SDK 一般文件下载目录默认在SDK下的sources文件中即 \adt-bundle-windows-x86_64-20130522\sdk\sources\android-20

【事件】封装touch触摸事件 --- DOM2级、单点触控

//封装touch触摸事件 --- DOM2级.单点触控 if (!Object.prototype.addTouchEvents) { Object.defineProperty(Object.prototype, 'addTouchEvents', { value: function(Obj) { var noop = function() {}; var defaults = { start: noop, //开始 move: noop, //移动 end: noop, //结束 left

Android学习笔记(九)——布局和控件的自定义

//此系列博文是<第一行Android代码>的学习笔记,如有错漏,欢迎指正! View是 Android中一种最基本的 UI组件,它可以在屏幕上绘制一块矩形区域,并能响应这块区域的各种事件,因此,我们使用的各种控件其实就是在 View的基础之上又添加了各自特有的功能.而ViewGroup 则是一种特殊的 View,它可以包含很多的子 View和子 ViewGroup,是一个用于放置控件和布局的容器.系统默认的所有控件都是直接或间接继承自 View 的,所用的所有布局都是直接或间接继承自 Vie

Dynamic CRM 2013学习笔记(八)过滤查找控件 (类似省市联动)

我们经常要实现类似省市联动一样的功能,常见的就是二个查找控件,一个选择了省后,另一个市的查找控件就自动过滤了,只显示当前省下的市,而不是所有的市.当然这是最简单的,实际工作中还有更复杂的功能要通过过滤查找控件来实现.本文主要介绍基本的查找控件过滤.多表关联的复杂过滤以及子表里实现查找控件的过滤.   一.简单的过滤 先看下需求: 按"Special GL Indicator" 来过滤 Posting 查找控件增加了preSearch事件.它发生在查找控件显示对话框供用户查找记录之前,与

【WPF学习】第十八章 多点触控输入

多点触控(multi-touch)是通过触摸屏幕与应用程序进行交互的一种方式.多点触控输入和更传统的基于笔(pen-based)的输入的区别是多点触控识别手势(gesture)——用户可移动多根手指以执行常见操作的特殊方式.例如,在触摸屏上放置两根手指并同时移动他们,这通常意味着“放大",而以一根手指为支点转动另一根手指意味着"旋转".并且因为用户直接在应用程序窗口中进行这些手势,所以每个手势自然会被连接到某个特定的对象.例如,简单的具有多点触控功能的应用程序,可能会在虚拟桌

FastReport.NET 学习笔记--子分组添加事件无效的问题

这个报表控件最吸引我的就是可以定义事件,于是尝试着改这个Groups模版,添加一个以名字前两个字母作为分组的子分组. 参考原有分组添加子分组.添加子分组统计 将“[Products.ProductName].Substring(0,1)”改为“[Products.ProductName].Substring(0,2)”,复制表达式之后点击取消.然后粘贴到Group Expert弹窗的文本框中,点击添加. 这样一个子分组就添加好了. 然后像图中一样复制对应的GroupHeader和GroupFoo

HTML&amp;CSS基础学习笔记1.10—添加链接

我们可以设置链接的目标,使我们点击后可以跳转到我们想要去的地方. <a>标签的 href 属性用于指定超链接目标的 URL. 在页面中添加的<a>标签,浏览器会用特殊效果显示,这样用户就会知道它是一个可以链接到其他文档的超链接. 看一段代码: <!DOCTYPE html><html lang="en"><head> <meta charset="UTF-8"> <title><

js 学习笔记【随时添加】

1.js正则表达式中/=\s*\".*?\"/g \s 匹配任何空白字符,包括空格.制表符.换页符等等.等价于 [ \f\n\r\t\v].\s*匹配0-n个空白,\"匹配双引号,.*?匹配任意个字符,这个正则就是匹配带双引号的内容,比如:“a”."sdafsas"这些 2.splice splice() 方法向/从数组中添加/删除项目,然后返回被删除的项目.注释:该方法会改变原始数组.splice() 方法与 slice() 方法的作用是不同的,spli

Linux学习笔记-Ubuntu添加右键菜单打开终端

1.进入个人目录(如/home/batsing,下文缩写成 ~ ):设置显示隐藏文件,或使用命令行:2.进入 ~/.gnome2/nautilus-scripts 文件夹,新建一个文件,名为 terminal :3.用文本编辑器(如Vim,gedit)打开,输入如下内容(Shell脚本)并保存退出: #!/bin/bash cd "dirname $NAUTILUS_SCRIPT_CURRENT_URI" exec gnome-terminal 4.把刚才的文本文件添加可执行属性,命令