• 博客园logo
  • 会员
  • 周边
  • 新闻
  • 博问
  • 闪存
  • 赞助商
  • YouClaw
    • 搜索
      所有博客
    • 搜索
      当前博客
  • 写随笔 我的博客 短消息 简洁模式
    用户头像
    我的博客 我的园子 账号设置 会员中心 简洁模式 ... 退出登录
    注册 登录
指尖上的快乐
博客园    首页    新随笔    联系   管理    订阅  订阅

day02 坐标体系,游戏优化,定时器,Touch

Day02

1,坐标体系

OperGL坐标 以左下角为原点,向右是X,向上是Y,cocos2d-x默认坐标体系与之一样

 

屏幕坐标系  屏幕坐标系使用的是不同的坐标系统,原点在屏幕左上角,x轴向右,y轴向下,iOS的屏幕触摸事件CCTouch传入的位置信息使用的是该坐标系。因此在Cocos2D-x中对触摸事件做出响应前,需要首先把触摸点转化到OpenGL坐标系。

 

世界坐标  世界坐标系也叫作绝对坐标系,是游戏开发中建立的概念,因此,“世界”即是游戏世界. 世界坐标系和OpenGL坐标系方向一致,原点在屏幕左下角,x轴向右,y轴向上。

 

节点坐标  又名本地坐标,每个精灵都有这自己的本地坐标. 节点坐标系是和特定节点相关联的坐标系,每个节点都有独立的坐标系。当节点移动或者改变方向的时候,和该节点相关联的坐标系(子节点)会随之一起移动或改变方向。

 

坐标转换函数

CCPoint p1 = sprite2->convertToNodeSpace(sprite1->getPosition());

CCPoint p2 = sprite2->convertToWorldSpace(sprite1->getPosition());

 

p1就是sprite1锚点相对于sprite2原点来说在sprite2坐标系中的位置

p2就是sprite1锚点相对于sprite2原点来说在上图坐标系中的位置

 

本人的理解:

convertToNodeSpace是指以sprite2的原点作为坐标系原点,sprite1的锚点距离sprite2原点的坐标.

convertToWorldSpace就是sprite1锚点相对于sprite2原点来说在上图坐标系中的位置,这句话可以理解为 将sprite1锚点原来距离原点的坐标位置等同换成距离sprite2原点位置,通俗地讲,原来sprite1距离父节点(X, Y),那么现在就距离sprite2的原点(X, Y).再求出此时sprite1锚点的世界坐标位置

小技巧: 针对本地坐标系就用减法,针对世界坐标系就用加法

 

setTouchEnabled(true);打开触摸开关

setTouchMode(kCCTouchesOneByOne);选择触摸模式(此时为单点)

在layer的初始化中设置

 

setColor(ccRED);

setTextureRect(CCRectMake(0, 0, 250, 150));当精灵创建为空时,可画出一片大小为250,150的红色区域.

 

CCMoveBy *move1 = CCMoveBy::create(2, ccp(100, 0)); 移动,类似于CCJumpBy

CCSequence *sq = CCSequence::create(move1, move2, NULL); 作为动作队列

 

virtual bool ccTouchBegan(CCTouch *pTouch, CCEvent *pEvent);为setTouchEnabled(true)设置事件,参数二为IOS的兼容而保留的.

转换坐标体系:

pTouch->getLocation()         获取当前触摸的坐标,体系为operGL

pTouch->getLocationInView();   同上,不同的是体系为屏幕坐标

转换坐标系,由于是关联于整个屏幕,所有要由导演来转,代码如下

CCDirector::sharedDirector()->convertToUI(pGL);  //转成operGL

CCDirector::sharedDirector()->convertToUI(pUI);  //转成屏幕坐标

 

2.游戏的优化

 主要使用类CCSpriteBatchNode

操作步骤为

一.在layer的init()中,创建CCSpriteBatchNode的实例,并加截plist的大图片,一般格式为.png,

二.由层(layer)来addChild,然后就可以在ccTouchBegan创建大量小精灵,

三.由BatchNode来addChild大量精灵

它的原理为,当在触摸事件一次性创建大量小精灵时,可以减少渲染次数,由BatchNode统一渲染,估计低层的实现在BatchNode->addChild(spr),最后由layer来addChild已经渲染好的结果,即layer->addChild(BatchNode).另外,BatchNode与Sprite属于同一级别.

 

小宏函数CCRANDOM_0_1(),产生一个0~1之间的随机数

 

3.Schedule游戏定时器

主要流程模型如下图

applicationDifFinshLaunching()完成一开始精灵的放置,触摸开关,也就是自定义中init()里做的事,当applicationDifFinshLaunching()返回后,执行while(1)大循环,其中mainLoop里完成绘图功能,遍历节点,完成定时功能,内存清理工作.. mainLoop返回后再进行消息循环.

 

定时器有三种方式

 第一种, scheduleUpdate();最原始的计时器,每0.016秒执行一次相对应的执行函数为    void update(float t) override;该函数重写了父类函数

 

第二种, scheduleOnce

typedef void (CCObject::*SEL_SCHEDULE)(float);

scheduleOnce(SEL_SCHEDULE(&T06Schedule::myUpdate), 2);

这种方式只执行一次,延时2秒

其中第一个参数为回调函数(类型为SEL_SCHEDULE),第二个参数表示延时.代码含意为将T06Schedule::myUpdate类成员函数指针强转为CCObject::*SEL_SCHEDULE,类成员函数指针,该转换成功的前提是双方的参数相同(由于SEL_SCHEDULE类型包含一个参数float,所以, T06Schedule::myUpdate也应包含一float参数,参数传递的是延时的时间),只是所属的类不同.

 

第三种Schedule

该函数有以下几个重载函数

void CCNode::schedule(SEL_SCHEDULE selector)

void CCNode::schedule(SEL_SCHEDULE selector, float interval)

void CCNode::schedule(SEL_SCHEDULE selector, float interval, unsigned int repeat, float delay)

不管那一种,最后都是调用

m_pScheduler->scheduleSelector(selector, this, interval , repeat, delay, !m_bRunning);

参数说明

selector:回调函数,同

interval:时间间隔

repeat:重复次数, kCCRepeatForever永久重复

delay:从开始到第一次调用时的时间间隔.

 

Cocos2d-x里类成员函数里的小精灵相互传递方式

Spr-> setTag(xx) 将spr精灵挂在渲染树上,该渲染树为map模型(key-value),而xx对应key

CCSprite *spr = (CCSprite *)getChildByTag(xx); 取出该精灵,取出map模型里key为xx的value

getChildByTag返回的是CCNode *类型,注意类型转换

 

4.Touch

只有Layer及以下级别的才可以有触摸开关之类的操作函数

setTouchEnabled(true);               设置开关

setTouchMode(kCCTouchesOneByOne);  触摸模式

 

有四个父函数,分别表示不同触摸状态,

 virtual bool ccTouchBegan(CCTouch *pTouch, CCEvent *pEvent);

 virtual void ccTouchMoved(CCTouch *pTouch, CCEvent *pEvent);

 virtual void ccTouchEnded(CCTouch *pTouch, CCEvent *pEvent);

 virtual void ccTouchCancelled(CCTouch *pTouch, CCEvent *pEvent);

 

ccTouchBegan:鼠标按下(触摸开始),即被调用.返回表示消息是否向下传递.Shovel->boundingBox().containsPoint(pt), boundingBox()表示精灵缩放之后的大小,代码意思表示,Shovel 缩放后的大小是否包含(containsPoint)点pt. boundingBox()返回的是一个矩形,包含大小,及坐标. Shovel->getContentSize()获得实际大小,无视缩放.返回的是CCSize类型

ccTouchMoved:触摸滑动的时候触发,每一帧执行一次,一般用pTouch->getDelta()返回前后两帧的坐标差距,便于精灵移动.但注意移动边界限制.代码模版

 

 

ccTouchEnded:当手指离开屏幕时触发.

ccTouchCancelled:当触摸中断时触发,主要保存好游戏现状

 

参数说明

pTouch:用于获取点击或移动时的屏幕坐标, ,获取的坐标为世界坐标,属于OperGL坐标

pEvent:为苹果兼容而设定.目前用不上

 

5.touch优先级

CCTouchDispatcher* pDispatcher = CCDirector::sharedDirector()->getTouchDispatcher();

pDispatcher->addTargetedDelegate(this, m_nTouchPriority, true);

参数说明

This:当前层

m_nTouchPriority:优先级,数字越小,优先级越高

true:吞噬消息,不再往后传递

 

posted @ 2015-12-22 12:10  指尖上的快乐  阅读(139)  评论(0)    收藏  举报
刷新页面返回顶部
博客园  ©  2004-2026
浙公网安备 33010602011771号 浙ICP备2021040463号-3