[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,一经查实,立即删除!

相关文章

一年了

到温州出差一年了,一个项目做了一年啊,郁闷啊很想回家,回武汉

react学习(40)----react中的jsx简介

const name Josh Perez;const element <h1>Hello, {name}</h1>; ReactDOM.render(element,document.getElementById(root) ); jsx语法是个表达式 可以直接声明变量

将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…

react学习(41)----react中的jsx简介

JSX 特定属性你可以通过使用引号&#xff0c;来将属性值指定为字符串字面量&#xff1a;const element <div tabIndex"0"></div>;也可以使用大括号&#xff0c;来在属性值中插入一个 JavaScript 表达式&#xff1a;const element <img src{user.ava…

@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;两…

我喜欢的一首歌--《幸福的瞬间》

看了《薰衣草》就开始喜欢这首歌了&#xff0c;看的时候还会为了电视里男女主角痴情的爱情故事落泪&#xff0c;可见我还不成熟。今天正当我和下班人群一起在572上被挤得快变形的时候&#xff0c;车厢里放起了这首歌&#xff0c;我差点以为是我的手机响了。&#xff08;呵呵&am…

react学习(42)----react中的jsx表达对象

JSX 表示对象 Babel 会把 JSX 转译成一个名为 React.createElement() 函数调用。 以下两种示例代码完全等效&#xff1a; const element (<h1 className"greeting">Hello, world!</h1> ); const element React.createElement(h1,{className: greet…

react学习(43)----react中将一个元素渲染为 DOM

假设你的 HTML 文件某处有一个 <div>&#xff1a; <div id"root"></div> 我们将其称为“根” DOM 节点&#xff0c;因为该节点内的所有内容都将由 React DOM 管理。 仅使用 React 构建的应用通常只有单一的根 DOM 节点。如果你在将 React 集成进…

win7 IIS7.5配置伪静态

第一部: 从如下地址中下载URLRewriter组件组件&#xff1a;官方下载地址&#xff1a;http://download.microsoft.com/download/0/4/6/0463611e-a3f9-490d-a08c-877a83b797cf/MSDNURLRewriting.msi第二部&#xff1a;在网站项目中添加URLRewriter程序集的引用。第三部&#xff1…

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

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

学习计划

自己也算是一个老程序员了&#xff0c;但是毕业后一直没有系统的学习编程&#xff0c;自己感觉现在的技术乱七八糟、支离破碎的&#xff0c;因此决定从现在开始有计划地学习一些实用的技术&#xff1a;1、客户端&#xff1a;javascript、html、css、dhtml等&#xff1b;2、服务…

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

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

XForum 里用 Filter 编程实现安全访问控制

J2EE/EJB 论坛 / XForum 里用 Filter 编程实现安全访问控制cinc 2003.03.11&#xff0c; 15个回复&#xff0c; 1745次浏览在 J2ee 里&#xff0c;实现安全有两种&#xff1a; 用声明实现安全&#xff0c;就是在 web.xml 里实现安全限制。 用编程实现安全&#xff0c;自己写代码…

进制转换,写出一个程序,接受一个十六进制的数,输出该数值的十进制表示。 数据范围:保证结果在 1≤n≤2的31次方-1

题目&#xff1a;进制转换 写出一个程序&#xff0c;接受一个十六进制的数&#xff0c;输出该数值的十进制表示。 数据范围&#xff1a;保证结果在 1≤n≤2的31次方-1 代码实现&#xff1a; import java.util.Scanner;// 注意类名必须为 Main, 不要有任何 package xxx 信息 p…

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

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

react学习(45)----react组件

定义组件最简单的方式就是编写 JavaScript 函数&#xff1a; function Welcome(props) {return <h1>Hello, {props.name}</h1>; } 该函数是一个有效的 React 组件&#xff0c;因为它接收唯一带有数据的 “props”&#xff08;代表属性&#xff09;对象与并返回一…

Github | 线稿自动上色

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

react学习(46)----react渲染组件

const element <div />; 不过&#xff0c;React 元素也可以是用户自定义的组件&#xff1a; const element <Welcome name"Sara" />; 当 React 元素为用户自定义组件时&#xff0c;它会将 JSX 所接收的属性&#xff08;attributes&#xff09;以及子…