Cocos2d-x 点击菜单按键居中放大(无需修改底层代码)
建议转至该处阅读 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 点击菜单按键居中放大(无需修改底层代码)的更多相关文章
- 基于jQuery点击图像居中放大插件Zoom
分享一款基于jQuery点击图像居中放大插件Zoom是一款放大的时候会从原图像的位置以动画方式放大到画面中间,支持点击图像或者按ESC键来关闭效果.效果图如下: 在线预览 源码下载 实现的代码. ...
- 点击弹出 +1放大效果 -- jQuery插件
20140110更新: <!doctype html> <html> <head> <meta charset="UTF-8"> & ...
- 微信公众号菜单openid 点击菜单即可打开并登录微站
现在大部分微站都通过用户的微信openid来实现自动登录.在我之前的开发中,用户通过点击一个菜单,公众号返回一个图文,用户点击这个图文才可以自动登录微站.但是如果你拥有高级接口,就可以实现点击菜单,打 ...
- dialog弹出,点击back按键无法返回问题解决
今天阅读队友代码,调试代码中,发现对话框弹出点击back按键无法返回问题解决. 代码如下: /** * 单个按钮没有标题的弹框 * * @param context * @param content内 ...
- Activity切换动画---点击哪里从哪放大
emmmm,这次来梳理一下 Activity 切换动画的研究.首先,老规矩,看一下效果图: 效果图 这次要实现的动画效果就是类似于上图那样,点击某个 view,就从那个 view 展开下个 Activ ...
- 重写JS的鼠标右键点击菜单
重写JS的鼠标右键点击菜单 该效果主要有三点,一是对重写的下拉菜单的隐藏和显示:二是屏蔽默认的鼠标右键事件:三是鼠标左键点击页面下拉菜单隐藏. 不多说,上html代码: 1 <ul id=&qu ...
- 点击菜单选项,右侧主体区新增子界面(Tab)的实现
今天是2019年小年后一天,还有三天回家过年. 今天记录一下一种前端页面的效果的实现,这种效果很常见,一般用于网站后台系统的前端页面.一般后台系统会分为顶部导航栏,左边的菜单栏和右边的主体区.有一种效 ...
- ios点击输入框,界面放大解决方案
当我们编写的input宽度没有占满屏幕宽度,而且又没有申明meta,就会出现点击输入框,界面放大这个问题. 下面我直接给出解决方案: <meta name="viewport" ...
- 实例讲解如何利用jQuery设置图片居中放大或者缩小
大家有没有见过其他网站的图片只要鼠标放上去就能放大,移出去的时候就能缩小,而且一直保持居中显示!其实jQuery提供一个animate函数可以使图片放大和缩小,只要改变图片的长和高就OK啦!但是ani ...
随机推荐
- Python3 数据结构之词频统计(英文)
import string path = r'C:\Users\Black\Desktop\Walden.txt' with open(path, 'r', encoding='utf-8') as ...
- DRF源码系列分析
DRF源码系列分析 DRF源码系列分析--版本 DRF源码系列分析--认证 DRF源码系列分析--权限 DRF源码系列分析--节流
- 这道Java基础题真的有坑!我求求你,认真思考后再回答。
本文目录 一.题是什么题? 二.阿里Java开发规范. 2.1 正例代码. 2.2 反例代码. 三.层层揭秘,为什么发生异常了呢? 3.1 第一层:异常信息解读. 3.2 第二层:抛出异常的条件解读. ...
- doGet()方法和doPost()方法有什么区别?
1. 一般上,get是从服务器上获取数据,post是向服务器传送数据. 2. get是把参数数据队列加到提交表单的ACTION属性所指的URL中,值和表单内各个字段一一对应,在URL中可以看到.pos ...
- Java集合类框架的最佳实践?
根据应用的需要选择合适的集合对性能是非常重要的.如果一个集合的元素数量是固定的,而且我们能够提前知道固定的数量,那么就可以使用数组,而不是ArrayList. 每个集合都可以设置初始容量,如果我们提前 ...
- 网络配置工具iproute2和net-tools的基本原理和基本使用方法
这是网络程序设计课程的第一次作业的博客,由于还是小白,分享的内容都是比较基础的东西,希望看到的各位同学可以提出指导意见,必将虚心听取. 这次分享的内容是网络配置工具iproute2和net-tools ...
- webpack学习_资源管理(loader)
webpack 最出色的功能之一就是,除了 JavaScript,还可以通过 loader 引入任何其他类型的文件 引入资源步骤 Step1:安装你需要的loader Step2:在 module配 ...
- 你不知道的JavaScript(上)this和对象原型(三)
第四章 混核对象“类” 1.理论 面向对象编程强调的是数据和操作数据的行为本质上是互相关联的.实例化,继承,多态性 javascript中只有对象,并不存在可以被实例化的“类”.一个对象并不会被复制 ...
- 线上服务器CPU彪高的调试方式
原文内容来自于LZ(楼主)的印象笔记,如出现排版异常或图片丢失等问题,可查看当前链接:https://app.yinxiang.com/shard/s17/nl/19391737/2fee7b91-f ...
- 在 .NET Core 中使用 Diagnostics (Diagnostic Source) 记录跟踪信息
前言 最新一直在忙着项目上的事情,很久没有写博客了,在这里对关注我的粉丝们说声抱歉,后面我可能更多的分享我们在微服务落地的过程中的一些经验.那么今天给大家讲一下在 .NET Core 2 中引入的全新 ...