您的位置:首页 > 其它

libgdx游戏引擎教程(十一)演员类的复杂动画(二)(附源码)

2013-03-11 14:29 531 查看
转自:http://www.apkbus.com/android-60053-1-1.html

本讲源代码下载:


edu.nju.wsj.libgdx.rar(3.78
MB, 下载次数: 131)

2012-7-20 11:11 上传
点击文件名下载附件

下载积分: 下载豆 -2

复制代码
[align=left]我们在第十讲中给大家介绍了Action的用法,并且用一个MoveTo(继承自AnimationAction)给大家演示了一下一个Button的移动过程。但单单一个简单的移动太过于简单,我们也不会满足于仅仅用这么一个效果来作为我们Actor的动作。那么我们今天来看看AnimationAction中的其他几个方法,我们从RotateTo入手。[/align]

[align=left]我们看看官方文档中对RotateTo的介绍:[/align]



2012-7-20 10:47 上传
下载附件(34.42 KB)

[align=left]我们发现,RotateTo和我们在第十讲中介绍的MoveTo的方法是一模一样的,获取实例的方法也是一样的,都是调用静态方法并返回一个实例。那我们用第十讲中同样的方法来构造这么一个RotateTo对象,并且加入Actor的动作之中,看看有什么效果。[/align]

[align=left]我们将在第十讲后的源代码上进行修改,我们将第十讲中加入的MoveTo对象删除,添加RotateTo对象:[/align]

RotateTo rotate;

复制代码
[align=left]同样的,我们在show()函数中做出相应的修改:[/align]

rotate=RotateTo.$(60, 1f);

rotate.setInterpolator(AccelerateDecelerateInterpolator.$());

rotate.setCompletionListener(new OnActionCompleted(){

@Override

public void completed(Action arg0) {

// TODO Auto-generated method stub

System.out.println("RotateTo Complete!");

}

});

复制代码
[align=left]我们在这里设置了一个监听函数,在RotateTo这个Action结束的时候会打印一句话:[/align]

"RotateTo Complete!"

复制代码
[align=left]通知我们动作已经结束。[/align]

[align=left]最后别忘了将这个RotateTo和Button绑定起来:[/align]

button.action(rotate);

复制代码
[align=left]我们来运行一下,看看效果如何。[/align]
[align=left][/align]
[align=left][/align]
[align=left][/align]
[align=left]很奇怪,没有任何效果。我们看一看输出:[/align]



2012-7-20 10:47 上传
下载附件(42.49 KB)

[align=left]很奇怪,输出是有的,说明这个RotateTo成功执行结束了,那为什么我们没有看到旋转的效果呢?我们再回过头来看看Actor中的成员变量:[/align]



2012-7-20 10:47 上传
下载附件(33.89 KB)

[align=left]红色的部分告诉我们,Actor有一个成员为rotation,从名字可以看出它是表征Actor的转动角度的,那么我们现在就要利用这个rotation来看看我们这个RotateTo是否对我们的Actor有影响。我们在MyGame.java的render()函数中添加这样一段语句:[/align]

System.out.println(button.rotation);

复制代码
[align=left]即我们随时打印button的rotation值,检查是不是有什么变化。我们运行一下,来看看输出:[/align]



2012-7-20 10:47 上传
下载附件(90.73 KB)

[align=left]令人庆幸的是,确实存在着输出,也就是说Button(别忘了,这也是一个Actor)的rotation在不断的改变,说明RotateTo确实可以改变它所绑定的Actor的属性,但这里为什么不能直接在绘制中体现出来呢?[/align]

[align=left]那么我们在第十讲中的MoveTo为什么又能体现出效果?我们猜测,MoveTo应该和RotateTo的原理一样,也是改变了所绑定的Actor的x和y值,而且Button的draw()函数中(所有Actor都通过这个函数绘制,还记得我们自定义Actor时自己实现的draw()方法吗)应该是根据x,y绘制的,而并没有根据rotation这个值来绘制,因此虽然RotateTo改变了rotation的值,但我们并没有在绘制函数draw()函数中将其表现出来,因此我们就没有看到旋转的效果了。[/align]

[align=left]为了确认我们的观点,我们来看看libgdx中Button的源码。[/align]

[align=left]这里插一句话,我们在下载好的libgdx包中的sources文件夹下找到对应的源码,除了直接导入jar查看源码,我们还可以直接通过改后缀名将jar改成rar并直接解压缩得到不同的包中的源码。[/align]

[align=left]Button.java在com.badlogic.gdx.scenes.scene2d.ui.Button下。[/align]
[align=left][/align]
[align=left]找到Button的源代码,我们直接来看看Button的draw函数:[/align]

public void draw (SpriteBatch batch, float parentAlpha) {

float offsetX = 0, offsetY = 0;

if (isPressed) {

setBackground(style.down == null ? style.up : style.down);

offsetX = style.pressedOffsetX;

offsetY = style.pressedOffsetY;

} else {

if (style.checked == null)

setBackground(style.up);

else

setBackground(isChecked ? style.checked : style.up);

offsetX = style.unpressedOffsetX;

offsetY = style.unpressedOffsetY;

}

validate();

for (int i = 0; i < children.size(); i++) {

Actor child = children.get(i);

child.x += offsetX;

child.y += offsetY;

}

super.draw(batch, parentAlpha);

for (int i = 0; i < children.size(); i++) {

Actor child = children.get(i);

child.x -= offsetX;

child.y -= offsetY;

}

}

复制代码
[align=left]从中我们没有看到任何和rotation有关的地方。只有一语句可能含有rotation参数:[/align]

super.draw(batch, parentAlpha);

复制代码
这句语句是调用了父类的draw()函数,我们需要继续往上追溯。

[align=left]我们又知道,Button的继承树的最顶端(Actor除外,因为Actor是一个虚类,它的draw()函数是空的)是Group。[/align]



2012-7-20 10:47 上传
下载附件(28.97 KB)

[align=left]那么我们再来看看Group源码中的draw()函数:[/align]

public void draw (SpriteBatch batch, float parentAlpha) {

if (debug && debugTexture != null && parent != null)

batch.draw(debugTexture, x, y, originX, originY, width == 0 ? 200 : width, height == 0 ? 200 : height, scaleX, scaleY,rotation, 0, 0, debugTexture.getWidth(), debugTexture.getHeight(), false, false);

if (transform) applyTransform(batch);

drawChildren(batch, parentAlpha);

if (transform) resetTransform(batch);

}

复制代码
[align=left]其他地方我们并不需要过多的关注,我们找重点,其中有一段代码:[/align]

batch.draw(debugTexture, x, y, originX, originY, width == 0 ? 200 : width, height == 0 ? 200 : height, scaleX, scaleY,rotation, 0, 0, debugTexture.getWidth(), debugTexture.getHeight(), false, false);

复制代码
[align=left]即是将Group根据x,y来绘制出来。由此我们知道了RotateTo改变了Actor的rotation的值却不能在动画上体现出来了。也就是说Action只负责改变Actor的属性参数,但实际用这些参数绘制出动画,需要我们添加自己的代码(初看起来是很麻烦,但实际上是给了我们更多的空间,可以用少数的参数的变化绘制出多种多样的动画)。[/align]

[align=left]那如果我们要让Actor根据RotateTo修改后的rotation旋转我们该怎么办呢?我们可以修改源码,但是出于开源代码的习惯,我们一般不会直接修改源码,我们可以自己写一个Actor并在其中的draw()函数中将rotation参数在绘制中体现出来,这样就有转动的效果了。[/align]

[align=left]我们可以修改我们工程中的AnimalActor.java,让AnimalActor在绘制的时候根据转动角度rotation来绘制。AnimalActor原来的绘制代码是这样的:[/align]

//以(0,0)绘制为起点(左下角为0,0)画出动画,大小128*128

arg0.draw(currentFrame,0, 0,128*power,128*power);

复制代码
[align=left]我们改用另外一个方法,将rotation这个参数在绘制中体现出来:[/align]

arg0.draw(currentFrame, 0, 0, 64*power, 64*power, 128*power, 128*power, 1, 1, this.rotation, true);

复制代码
[align=left]第一个参数即是当前帧currentFrame,第二第三个参数是动画旋转的原点,这里要配合第四第五个参数起作用,第四个第五个参数是旋转点的x,y偏置,比如我们设置旋转原点为(0,0),偏置也设为(0,0),那么实际上的旋转点就是(0,0),即动画绕着屏幕左下角旋转,如果要绕着中心转该怎么办呢?我们就将原点设置为(0,0),并将偏置点设在动画的中心,这样实际的原点就在动画的中心了。我上面就是这么做的。[/align]

[align=left]第六第七个参数是绘制的区域,第八第九是缩放的倍数,我们这里设置成1,即不缩放。第十个参数就是我们要表现的参数了,Actor的旋转角度rotation。第十一个参数是按顺时针还是逆时针绘制(注意,不是指旋转方向的顺时针或者逆时针,旋转方向都是逆时针的,对物理学有一些了解的人都知道,物理中很多量都是以逆时针旋转为正的,true和false的区别大家可以自己修改尝试看看区别。)[/align]

[align=left]我们来修改代码,我们修改过AnimalActor后,我们先将MyGame.java内所有关于RotateTo的代码删除,然后我们在Progress.java(即游戏界面)中添加一个RotateTo:[/align]

RotateTo roll;

复制代码
[align=left]同样在show()函数中进行初始化和绑定,这里我们将roll这个动作绑定在animal上:[/align]

roll=RotateTo.$(360, 5f);

animal.action(roll);

复制代码

[align=left]我们运行一下看看效果:[/align]



2012-7-20 10:47 上传
下载附件(61.94 KB)

[align=left]为什么起初的AnimalActor是竖着的呢?这个其实想一下就能明白,顺时针和逆时针法来计算角度的起点是在我们适中的十二点方向,而且我们起初的角度是0,因此绘制出来就是竖着的。如果我们要让一开始绘制的时候动物是横着的,我们可以将Actor的rotation的初始值置为90.[/align]

[align=left]我们在接下来的教程中将进行复杂的动画搭配和混合,欢迎大家有不懂的问题和我交流交流。[/align]
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: 
相关文章推荐