[libGDX游戏开发教程]使用libGDX进行游戏开发(12)-Action动画

前文章节列表:

使用libGDX进行游戏开发(11)-高级编程技巧 
使用libGDX进行游戏开发(10)-音乐音效不求人,程序员也可以DIY 
使用libGDX进行游戏开发(9)-场景过渡
使用libGDX进行游戏开发(8)-没有美工的程序员,能够依赖的还有粒子系统 
使用libGDX进行游戏开发(7)-屏幕布局的最佳实践 
使用libGDX进行游戏开发(6)-添加主角和道具 
使用libGDX进行游戏开发(5)-关卡加载 
使用libGDX进行游戏开发(4)-素材管理 
使用libGDX进行游戏开发(3)-给游戏添加一些控制功能 
使用libGDX进行游戏开发(2)-游戏框架建设 
使用libGDX进行游戏开发(1)-游戏设计 

本章打包的素材:http://files.cnblogs.com/mignet/animate.7z

在这一章我们将通过动画来丰富我们的游戏效果。

使用action来操作actor:

很多同学应该都很清楚action是什么东东,所以这里仅仅举个最常见的例子。

moveTo (x, y);
moveTo (x, y, duration);
moveTo (x, y, duration, interpolation);
rotateTo (rotation);
rotateTo (rotation, duration);
rotateTo (rotation, duration, interpolation);

来个连续动作:

Actor actor = new Actor();
float x = 100.0f, y = 100.0f, rotation = 0.0f, duration = 1.0f;
actor.addAction(sequence(
moveTo(x, y),
rotateTo(rotation),
delay(duration),
parallel(moveBy(50.0f, 0.0f, 5.0f),
rotateBy(90.0f, 5.0f, Interpolation.swingOut))));

插值算法(Interpolation)和前文提到的一样。现在,发现actor+action的威力了吗,哈哈

Libgdx支持的action列表:

•add(): This adds an action to an actor.
•alpha(): This sets the alpha value of an actor's color.
•color(): This sets the color of an actor.
•fadeIn() and fadeOut(): These are convenience actions to set the alpha value of an actor's color to 1 or 0, respectively.
•hide(): This sets the visibility of an actor to false.
•layout(): This sets the actor's layout to enabled or disabled.
•moveBy() and moveTo(): These move an actor by a relative amount or to a specific location.
•removeActor(): This removes the actor to which this action is attached. Alternatively, another actor that is to be removed can be specified.
•rotateBy() and rotateTo(): These rotate an actor by a relative amount or to a specific angle of rotation.
•run(): This runs a Runnable (the code will be executed in a separate thread).
•scaleBy() and scaleTo(): These scale an actor by a relative amount or to a specific scale.
• show(): This sets the visibility of an actor to true.
• sizeBy() and sizeTo(): These resize an actor by a relative amount or to a specific size.
• touchable(): This sets the touchability of an actor(refer to Touchable enumerator).
• visible(): This sets the visibility of an actor.

控制执行的顺序和时间:

• after(): This waits for other actions of an actor to finish before its action is executed. Note that this action will only wait for other actions that were already added to an actor prior to this.
• delay(): This delays the execution of an action.
• forever(): This repeats an action forever.
• parallel():This executes a list of actions at the same time.
• repeat(): This repeats an action for a given number of times.
• sequence(): This executes a list of actions one after another.

让游戏菜单动起来

动画效果:首先金币和兔子头是看不见的,接着金币淡入和比例从0%提高到100%,这样看起来好像是跳出了水面到中心屏幕上一样,短暂的停顿之后,兔子头出现在右上角,兔子头移动,就好像它是跳跃到它前面的其他的岩石上。

首先,修改MenuScreen:

private Table buildObjectsLayer() {Table layer = new Table();// + CoinsimgCoins = new Image(skinCanyonBunny, "coins");layer.addActor(imgCoins);imgCoins.setOrigin(imgCoins.getWidth() / 2,imgCoins.getHeight() / 2);imgCoins.addAction(sequence(moveTo(135, -20),scaleTo(0, 0),fadeOut(0),delay(2.5f),parallel(moveBy(0, 100, 0.5f, Interpolation.swingOut),scaleTo(1.0f, 1.0f, 0.25f, Interpolation.linear),alpha(1.0f, 0.5f))));// + BunnyimgBunny = new Image(skinCanyonBunny, "bunny");layer.addActor(imgBunny);imgBunny.addAction(sequence(moveTo(655, 510),delay(4.0f),moveBy(-70, -100, 0.5f, Interpolation.fade),moveBy(-100, -50, 0.5f, Interpolation.fade),moveBy(-150, -300, 1.0f, Interpolation.elasticIn)));return layer;}

让menu和Option动起来

添加MenuScreen:

    private void showMenuButtons(boolean visible) {float moveDuration = 1.0f;Interpolation moveEasing = Interpolation.swing;float delayOptionsButton = 0.25f;float moveX = 300 * (visible ? -1 : 1);float moveY = 0 * (visible ? -1 : 1);final Touchable touchEnabled = visible ? Touchable.enabled: Touchable.disabled;btnMenuPlay.addAction(moveBy(moveX, moveY, moveDuration, moveEasing));btnMenuOptions.addAction(sequence(delay(delayOptionsButton),moveBy(moveX, moveY, moveDuration, moveEasing)));SequenceAction seq = sequence();if (visible)seq.addAction(delay(delayOptionsButton + moveDuration));seq.addAction(run(new Runnable() {public void run() {btnMenuPlay.setTouchable(touchEnabled);btnMenuOptions.setTouchable(touchEnabled);}}));stage.addAction(seq);}private void showOptionsWindow(boolean visible, boolean animated) {float alphaTo = visible ? 0.8f : 0.0f;float duration = animated ? 1.0f : 0.0f;Touchable touchEnabled = visible ? Touchable.enabled: Touchable.disabled;winOptions.addAction(sequence(touchable(touchEnabled),alpha(alphaTo, duration)));}

修改:

private Table buildOptionsWindowLayer () {
...
// Make options window slightly transparent
winOptions.setColor(1, 1, 1, 0.8f);
// Hide options window by default
showOptionsWindow(false, false);
if (debugEnabled) winOptions.debug();
// Let TableLayout recalculate widget sizes and positions
winOptions.pack();
// Move options window to bottom right corner
winOptions.setPosition(Constants.VIEWPORT_GUI_WIDTH
- winOptions.getWidth() - 50, 50);
return winOptions;
}
private void onOptionsClicked () {loadSettings();showMenuButtons(false);showOptionsWindow(true, true);
}
private void onCancelClicked () {showMenuButtons(true);showOptionsWindow(false, true);AudioManager.instance.onSettingsUpdated();
}

使用的图像序列动画:

用texture packer把序列图片打包。

Libgdx播放动画的不同模式:

• NORMAL: This plays the animation once (first frame to last)
• REVERSED: This plays the animation once (last frame to first)
• LOOP: This plays the animation in a loop (first frame to last)
• LOOP_REVERSED: This plays the animation in a loop (last frame to first)
• LOOP_PINGPONG: This plays the animation in a loop (first frame, to last,to first)
• LOOP_RANDOM: This plays the animation in a loop (random frames)

给游戏场景增加动画:

这三个动画将分别使用不同的模式:

1. The first animation animCopterTransform plays all frames once (play mode:NORMAL; frame progression: 01, 02, 03, 04, 05).
2. The second animation animCopterRotate plays the last two frames in a ping-pong loop(play mode: LOOP_PINGPONG; frame progression: 04, 05, 05,04, [restart at first frame]).

3. Lastly, the third animation animCopterTransformBack is simply the reverse of the first animation (play mode: REVERSED; frame progression: 05, 04, 03,02, 01).

首先,在Assets添加素材:

public class AssetGoldCoin {public final AtlasRegion goldCoin;public final Animation animGoldCoin;public AssetGoldCoin(TextureAtlas atlas) {goldCoin = atlas.findRegion("item_gold_coin");// Animation: Gold CoinArray<AtlasRegion> regions =atlas.findRegions("anim_gold_coin");AtlasRegion region = regions.first();for (int i = 0; i < 10; i++)regions.insert(0, region);animGoldCoin = new Animation(1.0f / 20.0f, regions,Animation.LOOP_PINGPONG);}}public class AssetBunny {public final AtlasRegion head;public final Animation animNormal;public final Animation animCopterTransform;public final Animation animCopterTransformBack;public final Animation animCopterRotate;public AssetBunny(TextureAtlas atlas) {head = atlas.findRegion("bunny_head");Array<AtlasRegion> regions = null;AtlasRegion region = null;// Animation: Bunny Normalregions = atlas.findRegions("anim_bunny_normal");animNormal = new Animation(1.0f / 10.0f, regions,Animation.LOOP_PINGPONG);// Animation: Bunny Copter - knot earsregions = atlas.findRegions("anim_bunny_copter");animCopterTransform = new Animation(1.0f / 10.0f, regions);// Animation: Bunny Copter - unknot earsregions = atlas.findRegions("anim_bunny_copter");animCopterTransformBack = new Animation(1.0f / 10.0f, regions,Animation.REVERSED);// Animation: Bunny Copter - rotate earsregions = new Array<AtlasRegion>();regions.add(atlas.findRegion("anim_bunny_copter", 4));regions.add(atlas.findRegion("anim_bunny_copter", 5));animCopterRotate = new Animation(1.0f / 15.0f, regions);}}

修改AbstractGameObject:

    public float stateTime;public Animation animation;public void setAnimation(Animation animation) {this.animation = animation;stateTime = 0;}
public void update (float deltaTime) {stateTime += deltaTime;
if (body == null) {updateMotionX(deltaTime);updateMotionY(deltaTime);// Move to new positionposition.x += velocity.x * deltaTime;position.y += velocity.y * deltaTime;
} else {position.set(body.getPosition());rotation = body.getAngle() * MathUtils.radiansToDegrees;}
}

修改GoldCoin:

    private void init() {dimension.set(0.5f, 0.5f);setAnimation(Assets.instance.goldCoin.animGoldCoin);stateTime = MathUtils.random(0.0f, 1.0f);// Set bounding box for collision detectionbounds.set(0, 0, dimension.x, dimension.y);collected = false;}public void render(SpriteBatch batch) {if (collected)return;TextureRegion reg = null;reg = animation.getKeyFrame(stateTime, true);batch.draw(reg.getTexture(), position.x, position.y, origin.x,origin.y, dimension.x, dimension.y, scale.x, scale.y, rotation,reg.getRegionX(), reg.getRegionY(), reg.getRegionWidth(),reg.getRegionHeight(), false, false);}

现在,给兔子头加动画,主要是螺旋桨飞行:

这里用到了状态机的概念,我们兔子头就是有限状态机,也就是说,它在任何时候一定处于有限状态的某种状态中,并且在合适的时候进行状态的切换。

我们来修改BunnyHead:

private Animation animNormal;
private Animation animCopterTransform;
private Animation animCopterTransformBack;
private Animation animCopterRotate;public void init () {
dimension.set(1, 1);
animNormal = Assets.instance.bunny.animNormal;
animCopterTransform = Assets.instance.bunny.animCopterTransform;
animCopterTransformBack =
Assets.instance.bunny.animCopterTransformBack;
animCopterRotate = Assets.instance.bunny.animCopterRotate;
setAnimation(animNormal);
// Center image on game object
origin.set(dimension.x / 2, dimension.y / 2);
...
}
@Overridepublic void update(float deltaTime) {super.update(deltaTime);if (velocity.x != 0) {viewDirection = velocity.x < 0 ? VIEW_DIRECTION.LEFT: VIEW_DIRECTION.RIGHT;}if (timeLeftFeatherPowerup > 0) {if (animation == animCopterTransformBack) {// Restart "Transform" animation if another feather power-up// was picked up during "TransformBack" animation. Otherwise,// the "TransformBack" animation would be stuck while the// power-up is still active.
                setAnimation(animCopterTransform);}timeLeftFeatherPowerup -= deltaTime;if (timeLeftFeatherPowerup < 0) {// disable power-uptimeLeftFeatherPowerup = 0;setFeatherPowerup(false);setAnimation(animCopterTransformBack);}}dustParticles.update(deltaTime);// Change animation state according to feather power-upif (hasFeatherPowerup) {if (animation == animNormal) {setAnimation(animCopterTransform);} else if (animation == animCopterTransform) {if (animation.isAnimationFinished(stateTime))setAnimation(animCopterRotate);}} else {if (animation == animCopterRotate) {if (animation.isAnimationFinished(stateTime))setAnimation(animCopterTransformBack);} else if (animation == animCopterTransformBack) {if (animation.isAnimationFinished(stateTime))setAnimation(animNormal);}}}
@Overridepublic void render(SpriteBatch batch) {TextureRegion reg = null;// Draw Particles
        dustParticles.draw(batch);// Apply Skin Color
        batch.setColor(CharacterSkin.values()[GamePreferences.instance.charSkin].getColor());float dimCorrectionX = 0;float dimCorrectionY = 0;if (animation != animNormal) {dimCorrectionX = 0.05f;dimCorrectionY = 0.2f;}// Draw imagereg = animation.getKeyFrame(stateTime, true);batch.draw(reg.getTexture(), position.x, position.y, origin.x,origin.y, dimension.x + dimCorrectionX, dimension.y+ dimCorrectionY, scale.x, scale.y, rotation,reg.getRegionX(), reg.getRegionY(), reg.getRegionWidth(),reg.getRegionHeight(), viewDirection == VIEW_DIRECTION.LEFT,false);// Reset color to whitebatch.setColor(1, 1, 1, 1);}

呼,终于忙完了。

至此12章全文结束,所有章节的源码都在qq群文件中,大家知悉。

转载于:https://www.cnblogs.com/mignet/p/libgdx_game_development_12.html

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/408371.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

将DataSet中的操作更新到Access数据库

代码如下&#xff1a;<%import Namespace Namespacesystem.data%><%import Namespace Namespacesystem.data.oledb%><script languagevb runatserver>Sub page_load()sub page_load() dim strConnection as string dim strSQL as string dim ob…

@synthesize obj=_obj的意义详解 @property和@synthesize

本文转载至&#xff1a;http://blog.csdn.net/showhilllee/article/details/8971159我们在进行iOS开发时&#xff0c;经常会在类的声明部分看见类似于synthesize window_window; 的语句&#xff0c;那么&#xff0c;这个window是什么&#xff0c;_ window又是什么&#xff0c;两…

Github项目推荐|可视化 GAN 的训练过程

点击上方“算法猿的成长“&#xff0c;关注公众号&#xff0c;选择加“星标“或“置顶”总第 137 篇文章&#xff0c;本文大约 1000 字&#xff0c;阅读大约需要 5 分钟今天介绍的一个开源的 github 项目&#xff0c;主要是实现了对 GAN 训练过程的可视化代码&#xff0c;项目链…

Github|类别不平衡学习资源(上)

点击上方“算法猿的成长“&#xff0c;关注公众号&#xff0c;选择加“星标“或“置顶”总第 138 篇文章&#xff0c;本文大约 5400 字&#xff0c;阅读大约需要 15 分钟今天推荐的是一个 github 项目&#xff0c;项目地址如下&#xff0c;主要是类别不平衡学习的论文、代码、框…

Github|类别不平衡学习资源(下)

点击上方“算法猿的成长“&#xff0c;关注公众号&#xff0c;选择加“星标“或“置顶”总第 139 篇文章&#xff0c;本文大约 3600 字&#xff0c;阅读大约需要 10 分钟继续介绍类别不平衡学习资源&#xff0c;github 地址&#xff1a;https://github.com/ZhiningLiu1998/awes…

Github | 线稿自动上色

点击上方“算法猿的成长“&#xff0c;关注公众号&#xff0c;选择加“星标“或“置顶”总第 140 篇文章&#xff0c;本文大约 1500 字&#xff0c;阅读大约需要 5 分钟今天要介绍的是一个 Github 项目&#xff0c;项目地址如下&#xff0c;它实现了对线稿的自动上色功能&#…

如何在图片上添加文本信息

点击上方“算法猿的成长“&#xff0c;关注公众号&#xff0c;选择加“星标“或“置顶”总第 141 篇文章&#xff0c;本文大约 1500 字&#xff0c;阅读大约需要 5 分钟前言给图片添加文本信息是非常常见的需求&#xff0c;通常需要添加的文本信息分为中文文字或者是非中文的文…

Github|基于 Jittor 的 GAN 模型库

点击上方“算法猿的成长“&#xff0c;关注公众号&#xff0c;选择加“星标“或“置顶”总第 142 篇文章&#xff0c;本文大约 1300 字&#xff0c;阅读大约需要 5 分钟前言今天介绍一个 Github 项目---集成了 27 种 GAN 模型的 Jittor-GAN&#xff0c;项目地址&#xff1a;htt…

mongoDB分页的两种方法

mongoDB的分页查询是通过limit(),skip(),sort()这三个函数组合进行分页查询的 下面这个是我的测试数据 db.test.find().sort({"age":1}); 第一种方法 查询第一页的数据&#xff1a;db.test.find().sort({"age":1}).limit(2); 查询第二页的数据&#xff1a;…

22 款设计和可视化神经网络的工具

点击上方“算法猿的成长“&#xff0c;关注公众号&#xff0c;选择加“星标“或“置顶”总第 143 篇文章&#xff0c;本文大约 3000 字&#xff0c;阅读大约需要 10 分钟前言深度学习领域&#xff0c;最常见的就是各种网络模型&#xff0c;那么在写论文或者文章&#xff0c;介绍…

计算机视觉研究生文献和复现哪个更重要?

点击上方“算法猿的成长“&#xff0c;关注公众号&#xff0c;选择加“星标“或“置顶”总第 144 篇文章&#xff0c;本文大约 6000 字&#xff0c;阅读大约需要 15 分钟前言这是来自知乎上的一个问题&#xff0c;但我觉得应该是对很多初入深度学习领域&#xff0c;不只是计算机…

Flex4 初始化过慢解决方法

昨天找了个免费.net空间&#xff0c;想测试一下做的一个简单Flex4 上传项目的效果。上传所有文件到网站之后&#xff0c;访问项目页面&#xff0c;进度条一点一点艰难的向前移动&#xff0c;到了100%后却不出现程序界面&#xff0c;等待一会儿还是没有出现&#xff0c;于是我去…

SRZoo--深度学习图像超分辨率工具

点击上方“算法猿的成长“&#xff0c;关注公众号&#xff0c;选择加“星标“或“置顶”总第 145 篇文章&#xff0c;本文大约 2100 字&#xff0c;阅读大约需要 7 分钟前言今天要介绍的是 Github 上一个基于深度学习的超分辨率工具--SRZoo&#xff0c;并且它还提供了多个预训练…

Scapy:局域网MAC地址扫描脚本

转载自&#xff1a;http://blog.sina.com.cn/s/blog_4b5039210100gn6k.html 未测试&#xff0c;回头研究研究。 用pythonscapy写的&#xff0c;只要双击.py文件即可&#xff0c;扫描当地局域网的主机MAC地址&#xff0c;并把结果写入文档保存。 代码如下&#xff1a;用到注册表…

基于 opencv 的图像处理入门教程

点击上方“算法猿的成长“&#xff0c;关注公众号&#xff0c;选择加“星标“或“置顶”总第 146 篇文章&#xff0c;本文大约 5000 字&#xff0c;阅读大约需要 20 分钟前言虽然计算机视觉领域目前基本是以深度学习算法为主&#xff0c;但实际上很多时候对图片的很多处理方法&…

新增两款Skin(clover与Valentine)

感谢沪江博客又为博客园提供两款漂亮的Skin。 clover: Valentine: 转载于:https://www.cnblogs.com/dudu/archive/2005/03/06/113853.html

同一页面引入多个JS文件的编码问题

原来只是觉得IE解析HTML文件的时候&#xff0c;需要知道其传输编码&#xff0c;才能正确处理&#xff0c;而从来没有在意过JavaScript文件的编码问题。结果今天发现同一页面中的多个JavaScript文件如果保存编码不同&#xff0c;也会有出错的问题。这个一般怎么会遇到呢&#xf…

简单盘点 CVPR2020 的图像合成论文

点击上方“算法猿的成长“&#xff0c;关注公众号&#xff0c;选择加“星标“或“置顶”总第 147 篇文章&#xff0c;本文大约 3500 字&#xff0c;阅读大约需要 10 分钟前言本文将简单盘点在 CVPR2020 上的图像合成方面的论文&#xff0c;然后给出下载地址以及开源代码 github…