前文章节列表:

使用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

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

  1. [libGDX游戏开发教程]使用LibGDX进行游戏开发(1)-游戏设计

    声明:本章是一个系列的开始,英文原文是<Learning libGDX Game Development>,大家请周知. [libgdx游戏开发教程]使用Libgdx进行游戏开发(2)-游 ...

  2. 视频教程-微信小程序开发教程(第1篇)-微信开发

    微信小程序开发教程(第1篇) 微信企业号星级会员.10多年软件从业经历,国家级软件项目负责人,主要从事软件研发.软件企业员工技能培训.已经取得计算机技术与软件资格考试(软考)--"信息系统项 ...

  3. STM32F103C8T6基础开发教程(HAL库)—开发环境配置

    STM32F103C8T6基础开发教程目录 STM32F103C8T6基础开发教程(HAL库)-开发环境配置 STM32F103C8T6基础开发教程(HAL库)-Keil添加注释的快捷键 STM32F ...

  4. python网络游戏开发教程_python 网游开发教程 | python做的游戏有哪些

    python游戏开发是做什么的 现在很多的线下培训,质量参差不而且线下的培都十分高昂,加上你的线下生活费的话,学一个技术没有三万是学不下来的,你可以考虑线上的教育,只培训费就会给你省一大笔,学习时间还 ...

  5. python简单小游戏代码教程,Python简单小游戏代码

    球球各位大神怎么用python写一个猜词小游戏的代码? key = input('请输入一个单词:')description = input('输入单词描述:')chance = 5mark = 5p ...

  6. Libusb开发教程三 USB设备程序开发

    首先,需要指出本篇博客的基础仍然是基于 libusb V1.0 以下.主要考虑到保持与之前博客的连贯性,在上一篇博客中介绍了老版本中可以被调用的 API 以及功能介绍,对于库中 API 接口函数的使用 ...

  7. Kendo UI开发教程 2 准备Kendo UI开发环境

    分享一下我老师大神的人工智能教程!零基础,通俗易懂!http://blog.csdn.net/jiangjunshow 也欢迎大家转载本篇文章.分享知识,造福人民,实现我们中华民族伟大复兴! 首先你需 ...

  8. [Minecraft]基于Forge的1.8.9MOD开发教程——第一讲:搭建开发环境

    (第一次写教程,有点小紧张呢..) 作者的话 我一开始学习MOD开发时,也曾在各大网站搜索过一些教程,感觉国内的MOD开发教程是真心的少:CSDN没找到,优酷.爱奇艺.腾讯.B站也几乎没有(除了优酷的 ...

  9. Conflux 开发教程 | 使用 IDE 在 Conflux 开发 DApp 的实战操作指南

    Conflux DApp 开发教程 对本教程有任何疑问或建议可以在 GitHub 给我们留言. 简介 Conflux DApp 开发教程将使用 Conflux Studio 在 Oceanus 网络下 ...

最新文章

  1. 我的linux Mint之路(三)
  2. mysql中Table is read only 的解决方法小结
  3. 关于JavaScript的数组随机排序
  4. 对于原始轨迹的噪声过滤方法和曲率计算方法
  5. centos7 如何安装部署k8s_架构运维篇(五):Centos7/Linux中安装部署RocketMQ
  6. 维基百科文件解析成中文遇到的变量类型、编码问题
  7. python大佬养成计划----Web框架(Flask)
  8. 认识JQuery的三天--看视频得到的一些小知识点
  9. java排序_Java实现九种排序算法3:插入排序之希尔排序
  10. SQL必知必会数据库数据
  11. echarts3D地球
  12. python爬取和平精英皮肤_Python——LOL官方商城皮肤信息爬取(一次练手)
  13. BUUCTF WEB exec+lovesql
  14. 还搞不懂负数怎么用二进制表示?看完这一篇就懂了
  15. [转]NodeJS初探
  16. 投影仪排行,三款家用投影仪品牌,极米坚果大眼橙你选哪一款?
  17. 程序员画图利器——Visio
  18. 使用Python计算化学式的相对分子质量
  19. 费用型采购订单(科目分配类别=K)向成本中心计入费用
  20. 新浪股票java接口,「股票历史数据接口」搜狐股票历史数据接口

热门文章

  1. 在oracle中处理日期大全
  2. C# 使用WinApi操作剪切板Clipboard
  3. Spark 键值对RDD操作
  4. 瑞立视:厚积薄发且具有“工匠精神”的中国品牌
  5. 程序员的春天来了,赏花去!说走就走
  6. Linux运维:现状、入门和未来之路
  7. zabbix通过JMX监控Tomcat及一些报错
  8. LVS之一:基本命令和调度方法
  9. shell 产生随机数的多种方法
  10. [转载]如何将Putty生成的PrivateKey转换为SecureCRT所需的PublicKey