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

转自:http://www.apkbus.com/android-60053-1-1.html

 

本讲源代码下载:

  1. edu.nju.wsj.libgdx.rar(3.78 MB, 下载次数: 131)
    2012-7-20 11:11 上传
    点击文件名下载附件
    下载积分: 下载豆 -2
复制代码
我们在第十讲中给大家介绍了Action的用法,并且用一个MoveTo(继承自AnimationAction)给大家演示了一下一个Button的移动过程。但单单一个简单的移动太过于简单,我们也不会满足于仅仅用这么一个效果来作为我们Actor的动作。那么我们今天来看看AnimationAction中的其他几个方法,我们从RotateTo入手。



 

我们看看官方文档中对RotateTo的介绍:


1.PNG

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



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



 

我们将在第十讲后的源代码上进行修改,我们将第十讲中加入的MoveTo对象删除,添加RotateTo对象
  1. RotateTo rotate;
复制代码
同样的,我们在show()函数中做出相应的修改:
  1. rotate=RotateTo.$(60, 1f);
  2. rotate.setInterpolator(AccelerateDecelerateInterpolator.$());
  3. rotate.setCompletionListener(new OnActionCompleted(){

  4. @Override
  5. public void completed(Action arg0) {
  6. // TODO Auto-generated method stub
  7. System.out.println("RotateTo Complete!");
  8. }

  9. });
复制代码
我们在这里设置了一个监听函数,在RotateTo这个Action结束的时候会打印一句话:
  1. "RotateTo Complete!"
复制代码
通知我们动作已经结束。


 

最后别忘了将这个RotateToButton绑定起来:
  1. button.action(rotate);
复制代码
我们来运行一下,看看效果如何。
很奇怪,没有任何效果。我们看一看输出:


2.PNG

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




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


3.PNG

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




红色的部分告诉我们,Actor有一个成员为rotation,从名字可以看出它是表征Actor的转动角度的,那么我们现在就要利用这个rotation来看看我们这个RotateTo是否对我们的Actor有影响。我们在MyGame.javarender()函数中添加这样一段语句:
  1. System.out.println(button.rotation);
复制代码
即我们随时打印buttonrotation值,检查是不是有什么变化。我们运行一下,来看看输出:



4.PNG

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




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


 

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



 

为了确认我们的观点,我们来看看libgdxButton的源码。


 

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



 

Button.java在com.badlogic.gdx.scenes.scene2d.ui.Button下。
找到Button的源代码,我们直接来看看Button的draw函数:
  1. public void draw (SpriteBatch batch, float parentAlpha) {
  2. float offsetX = 0, offsetY = 0;
  3. if (isPressed) {
  4. setBackground(style.down == null ? style.up : style.down);
  5. offsetX = style.pressedOffsetX;
  6. offsetY = style.pressedOffsetY;
  7. } else {
  8. if (style.checked == null)
  9. setBackground(style.up);
  10. else
  11. setBackground(isChecked ? style.checked : style.up);
  12. offsetX = style.unpressedOffsetX;
  13. offsetY = style.unpressedOffsetY;
  14. }
  15. validate();
  16. for (int i = 0; i < children.size(); i++) {
  17. Actor child = children.get(i);
  18. child.x += offsetX;
  19. child.y += offsetY;
  20. }
  21. super.draw(batch, parentAlpha);
  22. for (int i = 0; i < children.size(); i++) {
  23. Actor child = children.get(i);
  24. child.x -= offsetX;
  25. child.y -= offsetY;
  26. }
  27. }
复制代码
从中我们没有看到任何和rotation有关的地方。只有一语句可能含有rotation参数
  1. super.draw(batch, parentAlpha);
复制代码
这句语句是调用了父类的draw()函数,我们需要继续往上追溯。


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


5.PNG

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



那么我们再来看看Group源码中的draw()函数:
  1. public void draw (SpriteBatch batch, float parentAlpha) {
  2. if (debug && debugTexture != null && parent != null)
  3. 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);
  4. if (transform) applyTransform(batch);
  5. drawChildren(batch, parentAlpha);
  6. if (transform) resetTransform(batch);
  7. }
复制代码
其他地方我们并不需要过多的关注,我们找重点,其中有一段代码:
  1. 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);
复制代码
即是将Group根据x,y来绘制出来。由此我们知道了RotateTo改变了Actorrotation的值却不能在动画上体现出来了。也就是说Action只负责改变Actor的属性参数,但实际用这些参数绘制出动画,需要我们添加自己的代码(初看起来是很麻烦,但实际上是给了我们更多的空间,可以用少数的参数的变化绘制出多种多样的动画)。



 

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



 

我们可以修改我们工程中的AnimalActor.java,让AnimalActor在绘制的时候根据转动角度rotation来绘制。AnimalActor原来的绘制代码是这样的
  1. //以(0,0)绘制为起点(左下角为0,0)画出动画,大小128*128
  2. arg0.draw(currentFrame,0, 0,128*power,128*power);
复制代码
我们改用另外一个方法,将rotation这个参数在绘制中体现出来
  1. arg0.draw(currentFrame, 0, 0, 64*power, 64*power, 128*power, 128*power, 1, 1, this.rotation, true);
复制代码
第一个参数即是当前帧currentFrame,第二第三个参数是动画旋转的原点,这里要配合第四第五个参数起作用,第四个第五个参数是旋转点的x,y偏置,比如我们设置旋转原点为(0,0),偏置也设为(0,0),那么实际上的旋转点就是(0,0),即动画绕着屏幕左下角旋转,如果要绕着中心转该怎么办呢?我们就将原点设置为(0,0),并将偏置点设在动画的中心,这样实际的原点就在动画的中心了。我上面就是这么做的。



 

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



 

我们来修改代码,我们修改过AnimalActor后,我们先将MyGame.java内所有关于RotateTo的代码删除,然后我们在Progress.java(即游戏界面)中添加一个RotateTo
  1. RotateTo roll;
复制代码
同样在show()函数中进行初始化和绑定,这里我们将roll这个动作绑定在animal :
  1. roll=RotateTo.$(360, 5f);
  2. animal.action(roll);
复制代码


 

我们运行一下看看效果:

6.gif

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





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



 

我们在接下来的教程中将进行复杂的动画搭配和混合,欢迎大家有不懂的问题和我交流交流。

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值