从本篇起介绍一些cocos2d-x的新功能,包括CocosBuilder动画等功能,还包括从2.1版本添加的一些新特性,本篇文章就介绍一下2.1中我非常喜欢的一个新特性--可以根据一个模板切割图片的节点--CCClippingNode。这个类提供了一种不规则切割图片的方式,在这种方式以前,我们可以使用纹理类自带的setTextureRect函数来切割矩形区域,这种方式就像是J2me的setClip方法一样整块的切割图片,比如我们要实现一个血条的时候,就可以使用这种方式进行切割,切掉我们不想显示的部分,而新特性中提供的CCClippingNode最大的不同之处就是裁减将不仅仅局限于矩形,可以根据任何形状进行裁减,而你要做的只是给一个“裁减模板”,这就好比是我们用剪刀剪形状,需要一个模具类的东西,然后我们拿着模具和要被裁减的纸顺着模具的边缘用剪刀剪就可以剪出一个模具的样子一样,首先来看这个类的常用函数(需要说明的是,这里介绍的函数只是这个类独有的,这个类继承自CCNode节点类,因此节点类有的函数也就不做介绍了):
getStencil:返回一个节点对象,这个对象就是之前提到的“裁减模板”。
setStencil:设置“裁减模板”。
getAlphaThreshold::这种裁减是可以改变裁减的透明度的,修改这个透明度就是通过设置这个阈值。
setAlphaThreshold:获得这个透明度阈值。
isInverted:之前说过的剪刀剪形状的例子,剪完形状以后,是显示被剪掉的部分,还是显示剩余的部分呢,默认isInverted值是false,是显示被剪掉的部分,设置为true则是显示剩余的部分。这个函数获得这个值。
setInverted:设置isInverted值。
使用这个效果,一般的过程是这样的:
//创建“裁减模板”
CCNode*stencil = this->stencil();
stencil->setTag( kTagStencilNode);
stencil->setPosition( ccp(50,50) );
//创建裁减节点类
CCClippingNode*clipper = this->clipper();
clipper->setTag( kTagClipperNode);
clipper->setAnchorPoint(ccp(0.5,0.5));
clipper->setPosition( ccp(s.width / 2 -50, s.height/ 2 - 50) );
//为设置裁减节点类设置“裁减模板”
clipper->setStencil(stencil);
this->addChild(clipper);
//设置裁减节点类所放的内容
CCNode*content = this->content();
content->setPosition( ccp(50,50) );
clipper->addChild(content);
通过这个新特性可以实现出很多有意思的效果,首先来学习一下cocos2D-x中的testApp的使用实例首先是一个类似ScrollView的滚动效果,在这之前,介绍cocos2D-x的另一个新特性—CCDrawNode,这个类不是一个新的功能,而是对原来功能的封装,在这之前,如果我们需要绘制矩形,圆形,点等形状,需要重新写一个类继承自节点或布景层,然后重写draw函数,现在使用CCDrawNode,可以直接使用这个类来绘制相应图形,相关函数如下所示:
drawDot:绘制点,参数给出坐标位置。
drawSegment:绘制片断,给出起始点,结束点,半径等参数。
drawPolygon:绘制矩形,可以分别给出填充颜色和边框颜色,还可以设置边框宽度。
实现类似ScrollView的滚动效果的代码如下:
//创建裁减节点类
CCClippingNode *clipper= CCClippingNode::create();
clipper->setTag( kTagClipperNode);
clipper->setContentSize( CCSizeMake(200, 200) );
clipper->setAnchorPoint( ccp(0.5, 0.5) );
clipper->setPosition( ccp(this->getContentSize().width / 2, this->getContentSize().height/ 2) );
clipper->runAction(CCRepeatForever::create(CCRotateBy::create(1, 45)));
this->addChild(clipper);
/
public class XPermutation { private int _length; private int _number; private int[] _current; private bool _first; /// <summary> /// 排列组合数据 /// </summary> public int[] Current { get { return _current; } } /// <summary> /// 数据长度 /// </summary> public int Length { get { return _length; } } /// <summary> /// 数据个数 /// </summary> public int Number { get { return _number; } } /// <summary> /// 数据可以重复的排列组合 /// </summary> /// <param name="length">数据长度</param> /// <param name="number">数据个数</param> public XPermutation(int length,int number) { _length = length; _number = number; _current = new int[length]; Reset(); } public bool Next() { if (_first) { _first = false; return true; } for (int i = 0; i < _length; ++i) { ++_current[i]; if (_current[i] == _number) _current[i] = 0; else break; } for (int i = 0; i < _length; ++i) if (_current[i] != 0) return true; _first = true; return false; } /// <summary> /// 重新初始化 /// </summary> public void Reset() { for (int i = 0; i < _current.Length; ++i) _current[i] = 0; _first = true; } } public class Permutation { private int _length; private int[] _current; private bool _stop; /// <summary> /// 排列组合数据 /// </summary> public int[] Current { get { return _current; } } /// <summary> /// 数据长度 /// </summary> public int Length { get { return _length; } } /// <summary> /// 排列组合 /// </summary> /// <param name="length">数据长度</param> public Permutation(int length) { _length = length; _current = new int[length]; for (int i = 0; i < _current.Length; ++i) _current[i] = i; _stop = true; } /// <summary> /// 重新初始化 /// </summary> public void Reset() { for (int i = 0; i < _current.Length; ++i) _current[i] = i; _stop = true; } /// <summary> /// 获取一个排列组合的数据 /// </summary> /// <returns></returns> public bool Next() { if (_stop) { _stop = false; return true; } else { calc(0); _stop = false; if (_current[0] == _length) return false; return true; } } private void calc(int index) { if (index == _current.Length) { _stop = true; return; } if ((_current[index]!=-1) && ((index + 1) != _current.Length)) calc(index + 1); if (_stop) return; for (++_current[index]; _current[index] < _length; ++_current[index]) { int n = 0; for (; n < index; ++n) if (_current[n] == _current[index]) break; if (n == index) calc(index + 1); if (_stop) return; } if (index != 0) _current[index] = -1; } }
目的:动手做小程序
需求:这里有一组数:1、1、2、3、5、8、13、21、34、55......要求计算用这个递归算法,计算出这组数的第40个数是多少?
分析:分析这组数的规律,可以得知,每个数字是它之前两个数字之和(若该数前面不足两个数,则不足的数省为0)
实现:按照下图,在窗体中添加4个lable控件,用来显示文本和计算结果,1个button控件,1个textBox控件,控件的name属性和text属性值可以参考下面的图和源代码。
以下是可参考的程序源代码(C#):
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
namespace Arithmetic
{
public partial class frmMain : Form
{
public frmMain()
{
InitializeComponent();
}
private void btn_Cal_Click(object sender, EventArgs e)
{
int P_int_temp;//定义整型变量
if (int.TryParse(txt_value.Text, out P_int_temp))//为变量赋值
{
lb_result.Text =Get(P_int_temp).ToString();//输出计算结果
}
else
{
MessageBox.Show(//提示输入正确数值
"请输入正确的数值!", "提示!");
}
}
/// <summary>
/// 递归算法
/// </summary>
/// <param name="i">参与计算的数值</param>
/// <returns>计算结果</returns>
int Get(int i)
{
if (i <= 0) //判断数值是否小于0
return 0; //返回数值0
else if (i >= 0 && i <= 2) //判断位数是否大于等于0并且小于等于2
return 1; //返回数值1
else //如果不满足上述条件执行下面语句
return Get(i - 1) + Get(i - 2); //进行递归运算,返回指定位数前两位数的和
}
}
}