如果到目前为止您仍然关注该系列,我们将在处理触摸,显示图像和移动它们方面广为人知。

但是,动态图像看起来很呆板,因为它看起来确实是假的和业余的。 为了给角色一些生活,我们将需要做更多的事情。 这就是动画的全部内容。 岩石是无生命的物体,即使被扔掉,它的形状也不会改变。 另一方面,人类非常活跃。 尝试扔一个,您会看到四肢抽搐,甚至在空中尖叫。

让我们仅依靠检查本身很复杂的步行即可。 想象一个人横穿您的道路(仅在2D模式下)。 您会注意到身体的不同显示。 左脚在前,右手在前,相反的四肢在后。 这种变化缓慢,因此左脚留在后面,而右脚则与身体一起前进。 但在某一点上,循环会重复。 如果你不闭上眼睛,你会看到这个人进展顺利。 如果您闭上眼睛并保持闭合状态再打开一次,则该人已经继续前进并且处于不同的位置。 尝试快速眨眼,您会看到类似黑白喜剧的东西。 那就是低帧率。 有关FPS的更多信息,请点击此处。

实际上,对于本教程,我们确实希望以较低的帧速率行走,就像这样。

上面介绍的行走有点狡猾,但这是猴子岛精灵的翻版。 她是Elaine Marley。这称为Sprite 。 它是简单的二维图像或动画。为了能够重新创建上述动画,我们需要步行周期中的每一帧。

它是一个150像素宽的图像,每帧为30像素宽。为了更好地说明它,请检查以下图像。

要在android(或iPhone或其他任何程序)中获得上述动画,我们需要将每一帧加载为单独的图像,并以规则的间隔依次显示它们。 或者,我们可以加载包含所有帧的大图像,并使用android提供的方法对它们进行切片和切块,并仅显示相关帧。做到这一点是微不足道的。 我们知道我们有5帧,每帧为30像素宽。 我们定义一个矩形(将是我们的选择),该矩形具有一帧的宽度和图像的高度。下图显示了如何裁剪前两帧。 其余的您应该填写。

了解所有这些之后,我们就可以创建项目了。 我们将使用前几章中的知识,尤其是有关游戏循环和有关图像显示的知识(在这里,我们设置了每帧触发图形项绘制的线程)。

我们将需要一个对象进行动画处理。 我们使用猴子岛的Elaine,所以我将使用类ElaineAnimated.java

public class ElaineAnimated {private static final String TAG = ElaineAnimated.class.getSimpleName();private Bitmap bitmap;     // the animation sequenceprivate Rect sourceRect;   // the rectangle to be drawn from the animation bitmapprivate int frameNr;      // number of frames in animationprivate int currentFrame;   // the current frameprivate long frameTicker;   // the time of the last frame updateprivate int framePeriod;    // milliseconds between each frame (1000/fps)private int spriteWidth;   // the width of the sprite to calculate the cut out rectangleprivate int spriteHeight;  // the height of the spriteprivate int x;               // the X coordinate of the object (top left of the image)private int y;             // the Y coordinate of the object (top left of the image)}

私有属性已注释,但值得一提。

  • 位图是包含所有帧的png文件。 本文的第二张图片。
  • sourceRect是选择矩形。 这是上图中的蓝色窗口。 矩形将每一帧移到下一帧。
  • frameTicker这是行走序列中最后一个帧更改的java时间戳。 请注意,这不是游戏FPS,而是步行FPS。 如果我们希望Elaine在1秒钟内执行完整的步行周期,则将步行的帧频设置为5,因为我们有5帧。 要获得真正流畅的动画,我们需要30帧,但这不是重点。
  • framePeriod是时间(以毫秒为单位),表示显示帧的时间段。 如果周期在1秒钟内完成,则意味着持续5帧,周期为0.2秒。 即,每帧将显示0.2秒。

构造函数如下:

public ElaineAnimated(Bitmap bitmap, int x, int y, int width, int height, int fps, int frameCount) {this.bitmap = bitmap;this.x = x;this.y = y;currentFrame = 0;frameNr = frameCount;spriteWidth = bitmap.getWidth() / frameCount;spriteHeight = bitmap.getHeight();sourceRect = new Rect(0, 0, spriteWidth, spriteHeight);framePeriod = 1000 / fps;frameTicker = 0l;}

我假设帧的宽度相同,所以我通过将图像的宽度除以帧数来计算矩形的宽度。 我还传递了fps ,这也是步行周期每秒的帧数而不是游戏FPS。

Elaine将拥有自己的更新方法,因为她是动画对象,并且她需要看起来很好并且负责拖动脚。 因为游戏更新周期的时间段和Elaine的周期可能不同(在这种情况下),所以我们将实际游戏时间作为变量传递,因此我们知道何时需要显示下一帧。例如,游戏运行非常快,每20毫秒调用一次更新,因此我们需要每200毫秒更新一次帧,然后每进行10次游戏更新就会发生一次帧的进行。

这是代码:

public void update(long gameTime) {if (gameTime > frameTicker + framePeriod) {frameTicker = gameTime;// increment the framecurrentFrame++;if (currentFrame >= frameNr) {currentFrame = 0;}}// define the rectangle to cut out spritethis.sourceRect.left = currentFrame * spriteWidth;this.sourceRect.right = this.sourceRect.left + spriteWidth;
}

从主游戏面板调用此更新(检查以前的输入如何工作)。 这是MainGamePanel类的更新方法。

public void update() {elaine.update(System.currentTimeMillis());
}

更新方法很简单(Elaine's)。 如果传入的时间(这是调用update方法的系统时间)大于上一次更新帧的时间(一个帧时间)加上下一次更新的时间,则它将递增帧。如果下一帧超出最后一帧,我们将重置循环。

将所有要从中剪切图像的区域定义为sourceRect 。而已。 现在让我们继续显示它。

public void draw(Canvas canvas) {// where to draw the spriteRect destRect = new Rect(getX(), getY(), getX() + spriteWidth, getY() + spriteHeight);canvas.drawBitmap(bitmap, sourceRect, destRect, null);}

就这些。 我们将目标矩形设置为在何处绘制剪切出的图像。 它位于Elaine的位置(在构造函数中设置了X和Y)。

canvas.drawBitmap(bitmap, sourceRect, destRect, null);

告诉android从位图包含的图像中切出sourceRect定义的图像,并将它绘制到destRect定义的画布上的矩形中。

从游戏循环触发的游戏面板的渲染方法中调用绘制(请检查先前的条目)。

MainGamePanel.java与前几章略有不同。 我摆脱了所有的机器人,只添加了伊莱恩。

private ElaineAnimated elaine;public MainGamePanel(Context context) {//* ... removed ... */// create Elaine and load bitmapelaine = new ElaineAnimated(BitmapFactory.decodeResource(getResources(), R.drawable.walk_elaine), 10, 50  // initial position, 30, 47 // width and height of sprite, 5, 5);   // FPS and number of frames in the animation// create the game loop threadthread = new MainThread(getHolder(), this);//* ... removed ... */}

Elaine在面板的构造函数中实例化,并且初始位置为(X = 10,Y = 50)。 我也传入了精灵的宽度和高度,但是无论如何都会忽略它,但是您可以修改代码。FPS非常重要,帧数也很重要。 FPS表示一秒钟要显示多少帧。 最后一个参数是循环中的帧数。

线程和活动类完全没有改变。 您可以在下载中找到它们,因为它们粘贴的时间很长。 该图像名为walk_elaine.png ,它已复制到/ res / drawable-mdpi /,因此android可以自动将其拾取。

如果运行该应用程序,您应该会发现Elaine在一个地方执行步行周期。 我们应该使用跳跃,因为可以在一个地方进行跳跃,但是您明白了。

伊莱恩步行

增强功能

为了进行一些巧妙的修改,请修改Elaine的draw方法,使其显示原始图像,其中包含从中提取帧的精灵。

public void draw(Canvas canvas) {// where to draw the spriteRect destRect = new Rect(getX(), getY(), getX() + spriteWidth, getY() + spriteHeight);canvas.drawBitmap(bitmap, sourceRect, destRect, null);canvas.drawBitmap(bitmap, 20, 150, null);Paint paint = new Paint();paint.setARGB(50, 0, 255, 0);canvas.drawRect(20 + (currentFrame * destRect.width()), 150, 20 + (currentFrame * destRect.width()) + destRect.width(), 150 + destRect.height(),  paint);
}

这仅显示(20,150)处的图像并创建一个新的绘画对象,因此我们可以在原始图像的当前帧上绘画。setARGB方法创建半透明的绿色涂料。 第一个值是50 ,表示其透明度为75%。 0是完全透明的,而255是完全不透明的。绘制完所有内容后,我们将一帧大小的矩形绘制到原始图像上,以便查看运动中正在显示的帧。

行走与当前画框

而已。 运行它,您将拥有第一个精灵动画。

在此处下载源代码(animation_walk.tar.gz)

参考:来自我们的JCG合作伙伴Tamas Jano的Android版Sprite动画,来自“ Against The Grain ”博客。

不要忘记查看我们的新Android游戏ArkDroid (以下屏幕截图) 。 您的反馈将大有帮助!

相关文章:
  • Android游戏开发教程简介
  • Android游戏开发–游戏创意
  • Android游戏开发–创建项目
  • Android游戏开发–基本游戏架构
  • Android游戏开发–基本游戏循环
  • Android游戏开发–使用Android显示图像
  • Android游戏开发–在屏幕上移动图像
  • Android游戏开发–游戏循环
  • Android游戏开发–测量FPS
  • Android游戏开发–粒子爆炸
  • Android游戏开发–设计游戏实体–策略模式
  • Android游戏开发–使用位图字体
  • Android游戏开发–从Canvas切换到OpenGL ES
  • Android游戏开发–使用OpenGL ES显示图形元素(原语)
  • Android游戏开发– OpenGL纹理映射
  • Android游戏开发–设计游戏实体–状态模式
  • Android游戏文章系列

翻译自: https://www.javacodegeeks.com/2011/07/android-game-development-sprite.html

Android游戏开发–雪碧动画相关推荐

  1. 雪碧图 游戏开发_Android游戏开发–雪碧动画

    雪碧图 游戏开发 如果到目前为止您仍然关注该系列 ,我们将在处理触摸,显示图像和移动它们方面广为人知. 但是,动态图像看起来很呆板,因为它看起来确实是假的和业余的. 为了给角色一些生活,我们将需要做更 ...

  2. Android游戏开发–粒子爆炸

    有没有想过爆炸是如何产生的? 让我们绕个弯路,尝试实现基本的粒子爆炸. 爆炸不过是一堆散布在屏幕上的,源自单个点的粒子(无论是像素,小形状还是图像). 为了方便起见,并非总是如此,而是为了简洁起见,我 ...

  3. Android游戏开发–游戏循环

    游戏循环是每个游戏的心跳. 到目前为止,我们仅使用了非常简单的一种(您可以在此处找到),无法控制我们更新游戏状态的速度或速度以及要渲染的帧. 概括地说,最基本的游戏循环是while循环,该循环一直执行 ...

  4. android游戏开发_Android游戏开发–游戏循环

    android游戏开发 游戏循环是每个游戏的心跳. 到目前为止,我们仅使用了非常简单的一种(您可以在此处找到),无法控制我们更新游戏状态的速度或速度以及要渲染的帧. 概括地说,最基本的游戏循环是whi ...

  5. 【Android游戏开发二十二】(图文详解)游戏中灵活实现动画播放!简述J2me的游戏类库与Android游戏开发!

    本站文章均为 李华明Himi 原创,转载务必在明显处注明:(作者新浪微博: @李华明Himi ) 转载自[黑米GameDev街区] 原文链接: http://www.himigame.com/andr ...

  6. 雪碧动画:吸血鬼凯蒂的生活

    我一直很喜欢网页游戏: 它们只是制作有趣,易于编码(大多数情况下),并且当用户只需要单击一个链接即可开始玩游戏时,游戏的可访问性就非常不错. Ajax和移动的dom元素带来了一些乐趣,但是限制了您可以 ...

  7. 动画版雪碧_雪碧动画:吸血鬼凯蒂的生活

    动画版雪碧 我一直很喜欢网页游戏: 它们只是制作有趣,易于编码(大多数情况下),并且当用户只需要单击一个链接即可开始玩游戏时,游戏的可访问性就非常不错. Ajax和移动的dom元素带来了一些乐趣,但是 ...

  8. Android 游戏开发必备的基础知识

    Android游戏开发: View类开发框架 SurfaceView开发框架 Graphics类开发框架 Paint与Color类介绍 Canvas介绍 几何图形绘制 字符串绘制 图像的绘制 图像的旋 ...

  9. Android 游戏开发入门

    Android 游戏开发入门 图书描述: Android系统已经红遍了大江南北,持有Android设备的人也在不断增长.看着大街上用手指划着手机玩游戏的人,你有没有一种自己做一个游戏的想法呢?然而,入 ...

最新文章

  1. Git忽略文件方法【转】
  2. 关于变量在循环内声明还是在循环外声明
  3. nginx+tomcat实现Windows系统下的负载均衡搭建教程
  4. 微服务访问安全设计方案全探索
  5. python把数据写入excel_Python向excel中写入数据的方法
  6. linux2.6驱动学习笔记之字符驱动
  7. pcap python 生成_python+pcap+dpkt 抓包小实例
  8. Spark团队开源新项目MLflow发布0.2版本,内置TensorFlow集成
  9. Element-UI学习笔记-安装
  10. Magisk升级Zygisk
  11. 对两个等长升序的序列查找中位数
  12. 高端风再起,小爱、小度、天猫精灵发新芽?
  13. escape JavaScript
  14. c语言程序设计迷宫问题,C语言迷宫问题
  15. Shiro教程 - 雁迟
  16. ybt1000:入门测试题目
  17. PhysicalDrive 只是Device\Harddisk%d\Partition0的符号连接,. 而Device\Harddisk0\Partition0是\Device\Harddisk0\D
  18. oracle 设置监听和服务,oracle服务端和客户端之间的网络监听设置
  19. mysql 获取上个月,这个月的第一天或最后一天
  20. 阿里云视频加解密VOD开发

热门文章

  1. java手动切换成独立显卡_教你MacBook如何实现一键切换显卡
  2. 智产易:商标被驳回,是重新申请比较好,还是驳回复审好?
  3. Linux-内网服务器通过代理服务器访问外网
  4. HTML行间距的设置方法与问题
  5. 离线计算七 辅助系统(flume、sqoop、oozie)
  6. 王哲在Facebook高管午餐会的访谈实录
  7. 2020年最好用的手机是哪一款_哪款手机最值得买 2020年最值得买的手机排行推荐...
  8. 英雄联盟 VS IT 段位等级,知道如何输出,人活着成就感很重要。
  9. Win10 10586 更新
  10. 淘宝电商api接口获取分类详情