建议转至该处阅读 https://www.zybuluo.com/tangyikejun/note/21953

配置环境:win7+Cocos2d-x.2.0.3+VS2012
目标读者:已经了解Cocos2d-x中的坐标系统,精灵和图片的关系。并知道OOP中类和对象的关系。

 

目标

实现一个按键效果,按下去之前显示normal.png的图,按下去之后显示selected.png的图。selected.png尺寸大于normal.png。效果图如下:

 

正文

 

1、原始效果

笔者在这个问题上纠结了一天半,尝试了各种方法,一直以为是自己错误使用菜单类导致不能居中放大。之后查看了源码,源码用两个精灵保存前后两张图片,并设置其锚点为(0,0),因此按键前后的图片都是以左下角点为原点绘制,无法到达居中放大的效果。

 

2、类间关系

我们先罗列出绘制一个按键所涉及的类,CCMenu、CCMenuItemSprite、CCSprite。它们在结点树上依次是爷爷、父亲、儿子的关系,当然你也可以认为是外婆、母亲、女儿的关系,随便。上述三个类中,CCMenu和CCSprite的锚点坐标都是(0,0),CCMenuItemSprite的锚点为(0.5,0.5),不建议更改这一默认设置。默认设定CCMenuItemSprite的大小和CCSprite的大小一致。当你没有抚摸屏幕的时候界面是这样的:

;

在这个图中,只对CCMenuItemSprite的位置进行了设置,其他对象的位置都是默认值。可以看到CCMenu对象的默认位置(position)为(0,0)。CCSprite的位置与CCMenuItemSprite的位置一致,即CCSprite的位置默认也是(0,0)。

 

3、解决方案

接下来我们通过实际的例子来讨论,本例中一些类和对象的关系如下表:

对象 对应图片
CCSprite pNormalSprite normal.png
CCSprite pSelectedSprite selected.png
CCMenuItemSprite pCloseItem

现在我们只把注意力放在CCMenuItemSprite和CCSprite这两个类上。对于本例,pNormalSprite和pSelectedSprite两个对象的默认锚点和位置均为(0,0),也就是说均以pCloseItem的左下角点作为原点。为了达到中心放大的目的,只需要重新设置pSelectedSprite的位置即可,见下图伪代码:

 

4、实现

具体的代码如下,直接在HelloWorld工程中的HelloWorld::init()函数中修改即可查看效果(当然要先把图放进去!)。

//start//////////////////下面这些代码都是通用的///////////////

/*新建按键前后两个精灵*/
CCSprite *pNormalSprite = CCSprite::create("normal.png");
CC_BREAK_IF(!pNormalSprite); CCSprite *pSelectedSprite = CCSprite::create("selected.png");
CC_BREAK_IF(!pSelectedSprite); /*计算两张图片的dW,dH*/
float dW = pNormalSprite->getContentSize().width
- pSelectedSprite->getContentSize().width;
float dH = pNormalSprite->getContentSize().height
- pSelectedSprite->getContentSize().height; /*设置pSelectedSprite的位置*/
pSelectedSprite->setPosition(ccp(dW / 2.0f,dH / 2.0f)); /*把精灵添加到菜单项pCloseItem中*/
CCMenuItemSprite *pCloseItem = CCMenuItemSprite::create(pNormalSprite,pSelectedSprite,this,menu_selector(HelloWorld::menuCloseCallback));
CC_BREAK_IF(!pCloseItem);
//end//////////////////////////////////////////////////////// /*设置菜单项的位置。*/
pCloseItem->setPosition(ccp(,)); /*添加菜单项到菜单*/
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, );

5、更进一步

上述代码虽然解决了中心放大的问题,但是仍存在一些缺陷。Cocos2d-x引擎处理后,pCloseItem对象的尺寸(content size)与pNormalSprite的尺寸是一样大的。即pSelected的尺寸 大于 pCloseItem对象的尺寸。当我们需要根据菜单项的大小来确定位置的时候,上面这种设置就会出现问题,比如我想把菜单项放在屏幕的左下角,如果直接将位置设置为

pCloseItem->setPosition(ccp(w/,h/));//w,h分别是从pCloseItem获得的宽和高

那么菜单项被按下后selected图片会超出屏幕。
要解决这个问题需要两个步骤:
1、pSelectedSprite保持默认位置,而对pNormalSprite的位置进行设置。
2、将pCloseItem对象的尺寸设置为pSelectedSprite的尺寸。

例子:

CCSprite *pNormalSprite = CCSprite::create(path);       //path为图片路径
CCSprite *pSelectedSprite = CCSprite::create(path); //得到dW和dH
float dW = pSelectedSprite->getContentSize().width - pNormalSprite->getContentSize().width;
float dH = pSelectedSprite->getContentSize().height - pNormalSprite->getContentSize().height; //更改位置
pNormalSprite->setPosition(ccp(dW / 2.0f,dH / 2.0f)); //将菜单项的contentSize设置为selectedSprite对象的大小
CCMenuItemSprite *pItemSprite = CCMenuItemSprite::create(pNormalSprite,pSelectedSprite,this,menu_selector(MainScene::onMenuEnd)); CCSize size = pSelectedSprite->getContentSize();
pItemSprite->setContentSize(size);

本文疏漏错误之处,欢迎大家指正!从而对博文不断改进,更好地为大家服务!

转载请注明出处:

http://www.cnblogs.com/tangyikejun/p/3842000.html

https://www.zybuluo.com/tangyikejun/note/21953

Cocos2d-x 点击菜单按键居中放大(无需修改底层代码)的更多相关文章

  1. 基于jQuery点击图像居中放大插件Zoom

    分享一款基于jQuery点击图像居中放大插件Zoom是一款放大的时候会从原图像的位置以动画方式放大到画面中间,支持点击图像或者按ESC键来关闭效果.效果图如下: 在线预览   源码下载 实现的代码. ...

  2. 点击弹出 +1放大效果 -- jQuery插件

    20140110更新: <!doctype html> <html> <head> <meta charset="UTF-8"> & ...

  3. 微信公众号菜单openid 点击菜单即可打开并登录微站

    现在大部分微站都通过用户的微信openid来实现自动登录.在我之前的开发中,用户通过点击一个菜单,公众号返回一个图文,用户点击这个图文才可以自动登录微站.但是如果你拥有高级接口,就可以实现点击菜单,打 ...

  4. dialog弹出,点击back按键无法返回问题解决

    今天阅读队友代码,调试代码中,发现对话框弹出点击back按键无法返回问题解决. 代码如下: /** * 单个按钮没有标题的弹框 * * @param context * @param content内 ...

  5. Activity切换动画---点击哪里从哪放大

    emmmm,这次来梳理一下 Activity 切换动画的研究.首先,老规矩,看一下效果图: 效果图 这次要实现的动画效果就是类似于上图那样,点击某个 view,就从那个 view 展开下个 Activ ...

  6. 重写JS的鼠标右键点击菜单

    重写JS的鼠标右键点击菜单 该效果主要有三点,一是对重写的下拉菜单的隐藏和显示:二是屏蔽默认的鼠标右键事件:三是鼠标左键点击页面下拉菜单隐藏. 不多说,上html代码: 1 <ul id=&qu ...

  7. 点击菜单选项,右侧主体区新增子界面(Tab)的实现

    今天是2019年小年后一天,还有三天回家过年. 今天记录一下一种前端页面的效果的实现,这种效果很常见,一般用于网站后台系统的前端页面.一般后台系统会分为顶部导航栏,左边的菜单栏和右边的主体区.有一种效 ...

  8. ios点击输入框,界面放大解决方案

    当我们编写的input宽度没有占满屏幕宽度,而且又没有申明meta,就会出现点击输入框,界面放大这个问题. 下面我直接给出解决方案: <meta name="viewport" ...

  9. 实例讲解如何利用jQuery设置图片居中放大或者缩小

    大家有没有见过其他网站的图片只要鼠标放上去就能放大,移出去的时候就能缩小,而且一直保持居中显示!其实jQuery提供一个animate函数可以使图片放大和缩小,只要改变图片的长和高就OK啦!但是ani ...

随机推荐

  1. PC端、移动端页面适配方案

    前言 页面自适应PC端.移动端大体上可以分为两种: 1.在同一个页面进行自适应布局,通常使用CSS3 @media 媒体查询器实现 2.两套页面,在后端进行统一适配,根据不同的浏览器UA返回对应的页面 ...

  2. Lamada表达式小技巧介绍

    函数式编程 @FunctionalInterface interface Lf{ void dispaly(); } @FunctionalInterface为显示定义函数时编程接口,不符合函数式编程 ...

  3. Vue中使用iconfont

    学习博客:https://www.imooc.com/article/33597?block_id=tuijian_wz

  4. Linux之CentOS设置别名与屏蔽别名

    一.环境 CentOS6.8 二.设置别名 ◆别名功能:让grep符合的关键字高亮 1.临时生效 [root@localhost ~]#alias grep="grep --color=au ...

  5. Android Studio 中java 文件报错红色J

    用常用的方法清除Android Studio的缓存然后重启,"File" -> "Invalidate Cashes / Restart" -> & ...

  6. 2016/09/21 context.getConfiguration().get()

    查看api:http://hadoop.apache.org/docs/stable/api/ public String get(String name) Get the value of the ...

  7. 《Java基础知识》Java异常处理详解

    1. Java 中的异常 前言:Java 中的异常处理是处理程序运行错误时的强大机制之一,它可以保证应用程序的正常流程. 首先我们将了解java异常.异常的类型以及受查和非受查异常之间的区别. 1.1 ...

  8. ElasticSearch - 遐想

    众所周知,ElasticSearch 存在一个问题,无法查询最近 1s 的写入.近实时这个属性,限制了其在某些场景的应用.本文记录了我在日常工作中想到的,解决特定场景的一些方案.既然是记录,便会有好有 ...

  9. 现代“十二要素应用”与 Kubernetes

    "十二要素应用"为开发SaaS应用提供了方法上的指导,而Docker能够提供打包依赖,解耦后端服务等特性,使得两者非常吻合.这篇文章介绍了Docker特性怎样满足了开发" ...

  10. Graylog 环境搭建与使用

    graylog 官网地址: www.graylog.org graylog 简易架构图: graylog 生产架构图: graylog 有两个版本,1.企业版:2.开源版 下面使用开源版本搭建日志中心 ...