Cocos2d-js 开发记录:自定义按钮
游戏开发总是有些特殊,一般的预制的UI无法满足要求。其实对于不复杂的功能,与其看文档还不如自己写一个。比如游戏中一个虚拟键盘,其中的按键在按下时会增长,变为原来的两倍高度,在原来高度上方显示按键的字如:
整体键盘:
一般来说按钮各个状态的各个大小都是一样的,一般可以直接使用cocos中的cc.MenuItemSprite或者cc.MenuItemImage来实现。而上述这个键盘按钮却是大小不同的。那么在两个状态的图片大小不同的时候,cc.MenuItemImage会怎么对齐呢?试了一下采取的是底端对齐,按钮的点击范围有正常状态下的图片大小确定,这两个情况其实和我们要实现的键盘按钮的要求是一致的。但是cc.MenuItemImage不能加入Label,更没有可用根据点击情况变化这个label位置的功能。
这些cc.MenuItemXxxx系列的类都直接或间接继承自cc.MenuItem,而cc.MenuItem继承自cc.Node(framework/cocos2d-html5/cocos2d/core/menus/CCMenuItem.js),来看下cc.MenuItem的源码:
/**
* Subclass cc.MenuItem (or any subclass) to create your custom cc.MenuItem objects.
* @class
* @extends cc.Node
* @param {function|String} callback
* @param {cc.Node} target
*/
cc.MenuItem = cc.Node.extend(/** @lends cc.MenuItem# */{
_enabled: false,
_target: null,
_callback: null,
_isSelected: false,
_className: "MenuItem", /**
* Constructor of cc.MenuItem
* @param {function|String} callback
* @param {cc.Node} target
*/
ctor: function (callback, target) {
var nodeP = cc.Node.prototype;
nodeP.ctor.call(this);
this._target = null;
this._callback = null;
this._isSelected = false;
this._enabled = false; nodeP.setAnchorPoint.call(this, 0.5, 0.5);
this._target = target || null;
this._callback = callback || null;
if (this._callback) {
this._enabled = true;
}
}, /**
* return whether MenuItem is selected
* @return {Boolean}
*/
isSelected: function () {
return this._isSelected;
},
/**
* only use for jsbinding
* @param value
*/
setOpacityModifyRGB: function (value) {
},
/**
* only use for jsbinding
* @returns {boolean}
*/
isOpacityModifyRGB: function () {
return false;
}, /**
* set the target/selector of the menu item
* @param {function|String} selector
* @param {cc.Node} rec
* @deprecated since v3.0
*/
setTarget: function (selector, rec) {
this._target = rec;
this._callback = selector;
}, /**
* return whether MenuItem is Enabled
* @return {Boolean}
*/
isEnabled: function () {
return this._enabled;
}, /**
* set enable value of MenuItem
* @param {Boolean} enable
*/
setEnabled: function (enable) {
this._enabled = enable;
}, /**
* initializes a cc.MenuItem with callback
* @param {function|String} callback
* @param {cc.Node} target
* @return {Boolean}
*/
initWithCallback: function (callback, target) {
this.anchorX = 0.5;
this.anchorY = 0.5;
this._target = target;
this._callback = callback;
this._enabled = true;
this._isSelected = false;
return true;
}, /**
* return rect value of cc.MenuItem
* @return {cc.Rect}
*/
rect: function () {
var locPosition = this._position, locContentSize = this._contentSize, locAnchorPoint = this._anchorPoint;
return cc.rect(locPosition.x - locContentSize.width * locAnchorPoint.x,
locPosition.y - locContentSize.height * locAnchorPoint.y,
locContentSize.width, locContentSize.height);
}, /**
* set the cc.MenuItem selected same as setIsSelected(true)
*/
selected: function () {
this._isSelected = true;
}, /**
* set the cc.MenuItem unselected same as setIsSelected(false)
*/
unselected: function () {
this._isSelected = false;
}, /**
* set the callback to the menu item
* @param {function|String} callback
* @param {cc.Node} target
*/
setCallback: function (callback, target) {
this._target = target;
this._callback = callback;
}, /**
* call the selector with target
*/
activate: function () {
if (this._enabled) {
var locTarget = this._target, locCallback = this._callback;
if (!locCallback)
return;
if (locTarget && cc.isString(locCallback)) {
locTarget[locCallback](this);
} else if (locTarget && cc.isFunction(locCallback)) {
locCallback.call(locTarget, this);
} else
locCallback(this);
}
}
});
cc.MenuItem对Node的selected,unselected, activate方法进行了重新,提供了回调函数设置设置,修改按钮锚点等功能,自定义的按钮从cc.MenuItem继承即可。根据需要复写一下方法:
- selected,被按下时调用(相当于pressed)
- unselected,按下后松开时调用(相当于released)
- activate,按下松开完成后调用(相当于click)
将要显示的内容元素如cc.Sprite通过this.addChild加入即可显示,在上述方法中通过控制这些元素的visible和位置属性可以实现自定义按钮的各种效果,还可以runAction。
下面给出自己的一个按钮示例:
/* implementation element(key button) used by keyboard */
var KeyMenuItem = cc.MenuItem.extend({
_label: null,
_normal_sprite: null,
_press_sprite: null,
FONT_EXTENDED_BOTTOM_PADDING_FACTOR: 0.75,
FONT_BOTTOM_PADDING_FACTOR: 0,
FONT_SIZE_FACTOR: 0.4, ctor: function(normal_img, press_img, text, callback, target) {
cc.MenuItem.prototype.ctor.call(this);
this.initWithCallback(callback, target); var normal_sprite = new cc.Sprite(normal_img);
var press_sprite = new cc.Sprite(press_img); this._normal_sprite = normal_sprite;
this._press_sprite = press_sprite; this.width = normal_sprite.width;
this.height= normal_sprite.height;var label = new cc.LabelTTF(text, "Arial", Math.ceil(normal_sprite.width * this.FONT_SIZE_FACTOR));
label.setColor(cc.color(0, 0, 0, 255));
this._label = label;
this.setNormal(); this.addChild(label, 2);
this.addChild(press_sprite, 0);
this.addChild(normal_sprite, 1); this.cascadeColor = true;
this.cascadeOpacity = true;
}, selected: function() {
cc.MenuItem.prototype.selected.call(this);
if (this._enabled) {
this.setPress();
cc.log("custom button selected");
}
cc.audioEngine.playMusic(res.button_press_mp3, false);
}, unselected: function() {
cc.MenuItem.prototype.unselected.call(this);
if (this._enabled) {
this.setNormal();
cc.log("custom button unselected");
}
}, setNormal: function() {
this.setLabelNormal();
this.setSpriteNormal();
}, setPress: function() {
this.setLabelPressed();
this.setSpritePressed();
}, setLabelNormal: function () {
var label = this._label;
var nsprite = this._normal_sprite;
label.setPosition(nsprite.width / 2.0, this.height * (0.5 + this.FONT_BOTTOM_PADDING_FACTOR));
}, setLabelPressed: function() {
var label = this._label;
var psprite = this._press_sprite;
var factor = this.FONT_EXTENDED_BOTTOM_PADDING_FACTOR;
label.setPosition(psprite.width / 2.0, psprite.height * factor);
}, setSpriteNormal: function () {
var nsprite = this._normal_sprite;
var psprite = this._press_sprite; psprite.visible = false;
nsprite.visible = true; nsprite.setPosition(this.width / 2.0, this.height / 2.0);
psprite.setPosition(psprite.width / 2.0, psprite.height / 2.0);
}, setSpritePressed: function() {
var nsprite = this._normal_sprite;
var psprite = this._press_sprite; psprite.visible = true;
nsprite.visible = false; psprite.setPosition(psprite.width / 2.0, psprite.height / 2.0);
nsprite.setPosition(this.width / 2.0, this.height / 2.0);
}, setEnabled: function(enabled) {
var nsprite = this._normal_sprite;
var psprite = this._press_sprite;
var label = this._label;
if (this._enabled != enabled) {
if (enabled == false) {
this.setOpacity(0);
} else {
this.setOpacity(255);
}
}
cc.MenuItem.prototype.setEnabled.call(this, enabled);
}, getString: function () {
return this._label.getString();
}
});
其中:
this.cascadeOpacity = true;
级联不透明度,可以使得对按钮设置透明度时整体透明度也一起变化
Cocos2d-js 开发记录:自定义按钮的更多相关文章
- wordpress优化之结合prism.js为编辑器自定义按钮转化代码
原文链接 http://ymblog.net/2016/07/24/wordpress-prism/ 继昨天花了一天一夜的时间匆匆写了主题Jiameil3.0之后,心中一直在想着优化加速,体验更好,插 ...
- JS开发中自定义调试信息开关
在开发过程中,可能随处留下几个console.log,或者alert语句,这些语句在开发过程中是很有价值的.但是项目一旦进入生产环境,过多的console.log可能影响到浏览器的运行效率,过多的al ...
- Dynamics CRM 客户端程序开发:自定义系统标准按钮的可用性
关注本人微信和易信公众号: 微软动态CRM专家罗勇 ,回复125或者20140414可方便获取本文,同时可以在第一时间得到我发布的最新的博文信息,follow me! 一般是新建一个解决方案用于客制化 ...
- iOS开发——UI进阶篇(十八)核心动画小例子,转盘(裁剪图片、自定义按钮、旋转)图片折叠、音量震动条、倒影、粒子效果
一.转盘(裁剪图片.自定义按钮.旋转) 1.裁剪图片 将一张大图片裁剪为多张 // CGImageCreateWithImageInRect:用来裁剪图片 // image:需要裁剪的图片 // re ...
- FineReport中JS如何自定义按钮导出
FineReport支持多种不同的导出方式,直接使用FineReport内置导出按钮可以非常快捷方便的来对各种格式的输出,但是我们在web页面集成中的时候,往往只想将报表内容嵌入到iframe中,而工 ...
- Dynamics CRM使用JS隐藏自定义按钮
在我们平时客制化开发的时候会经常遇到要制作自定义按钮的情况,而这个自定义按钮的功能又经常会有一些隐藏逻辑需要实现,所以每次通过获取控件查找这个按钮再隐藏比较麻烦,而且偶尔会出现代码没起作用的效果.下面 ...
- iOS开发之自定义导航栏返回按钮右滑返回手势失效的解决
我相信针对每一个iOS开发者来说~除了根视图控制器外~所有的界面通过导航栏push过去的界面都是可以通过右滑来返回上一个界面~其实~在很多应用和APP中~用户已经习惯了这个功能~然而~作为开发者的我们 ...
- Dynamics CRM2011中通过JS脚本方式显示和隐藏ribbon中的自定义按钮
首先该方法不能写在页面的onload中,因为当从子网格返回常规表单的时候ribbon区域会重新加载而常规表单所在的iframe区域是不会被刷新的,所以如果写在onload中的话就控制的不那么完全了,我 ...
- 【翻译】十大要避免的Ext JS开发方法
原文地址:http://www.sencha.com/blog/top-10-ext-js-development-practices-to-avoid/ 作者:Sean Lanktree Sean ...
随机推荐
- SLAM到底是什么?一文带你读懂SLAM
SLAM是Simultaneous localization and mapping缩写,意为“同步定位与建图”,主要用于解决机器人在未知环境运动时的定位与地图构建问题,为了让大家更多的了解SLAM, ...
- python获取函数参数默认值的两种方法
1.使用函数的__defaults__魔术方法 demo: # coding=utf-8 def f(a,b,c=1): pass f.__defaults__ 输出结果: (1,) 2.使用insp ...
- String Reduction问题分析
问题描述: Given a string consisting of a,b and c's, we can perform the following operation: Take any two ...
- angular-ui-select (系列二)远程搜索,页面方框显示的值跟传给后台的值不一样解决方案
三:下拉单选远程搜索: 一个重点是: 这个方法,就是让我们去远程搜索的 refresh="ctrl.refreshAddresses($select.search)" refres ...
- os模块与 sys模块
os模块是与操作系统交互的一个接口 ''' os.getcwd() 获取当前工作目录,即当前python脚本工作的目录路径 os.chdir("dirname") 改变当前脚本工作 ...
- wx.getLocation和show-location定位点不符
发现开发者工具未发现此类问题,到了真机上预览,观察到wx.getLocation的经纬度和show-location定位点的位置不符合.该怎么解决? 开发者工具上: 真机上: 解决方法: getLoc ...
- Web Worker 案例
什么是 Web Worker? 当在 HTML 页面中执行脚本时,页面的状态是不可响应的,直到脚本已完成. web worker 是运行在后台的 JavaScript,独立于其他脚本,不会影响页面的性 ...
- [转] Spring Boot特性
[From] http://blog.javachen.com/2015/03/13/some-spring-boot-features.html 1. SpringApplication Sprin ...
- Jsch初步
[From] http://xpenxpen.iteye.com/blog/2061869 上一篇文章我们成功搭建了sshd服务器,并通过3种方式登陆上了ssh.这一篇我们将用开源jar包jsch来登 ...
- css3 渐变色
Firefox可以使用角度来设定渐变的方向,而webkit只能使用x和y轴的坐标. 渐变可以创建类似于彩虹的效果,低版本的浏览器使用图片来实现,CSS3将会轻松实现网页渐变效果 粘贴代码 <di ...