[译]使用Game API创建2D动作游戏(二)

原创 2004年07月22日 11:03:00

(接上文)

游戏场景就像洋葱头

典型的2D动作游戏包括一个背景和一些活动的人物.尽管你可以自己来画这样的场景,Game API能让你用layers 来创建场景. 你可以用一个layer来做城市的背景,另一个来做一辆汽车. 将汽车层放到背景层上方就完成了整个的场景. 将汽车做为一个独立于背景和场景中的其它层的层会使对它的操作变得简单.

Game API 通过下面的四个类提供了灵活的对层的支持:

  • Layer 是所有层的抽象父类. 它定义了层的基本属性,包括位置,大小以及是否可见. 每个Layer 的子类必须定义paint() 方法用来在Graphics 上绘制该层. 它的两个具体的子类, TiledLayer Sprite, 应该会满足对2D游戏的需求.
  • TiledLayer 在创建背景图时会被用到. 你可以用一组小块儿的图片来高效地创建大幅的背景图.
  • Sprite 是会动的层. 你提供每个动作()的图片然后对它的活动进行完全的控制. Sprite 同时还提供对每个帧的镜像翻转和90°倍数旋转的功能.
  • LayerManager 是一个非常顺手的类,它记录你的场景中所有的层. 只需调用LayerManagerpaint() 方法就可以绘制它所包括的所有层.

使用 TiledLayer

TiledLayer 很简单, 尽管乍一看有些深入的地方不好理解. 最主要的思想就是一个图片源提供一组tiles (切片)用于组成一个大的场景. 例如, 下面的图片尺寸为64 x 48.


图片源

这个图片可以分为12个切片,每个大小为16 x 16 像素. TiledLayer 为每个切片分配一个编号, 从左上角开始为1. 图片源中的切片编号如下所示:


切片编号

编码来创建一个TiledLayer 是想当容易的. 你需要指定行数和列数, 图片源, 以及每个切片的大小. 这段代码说明了如何加载图片源并创建一个TiledLayer.

Image image = Image.createImage("/board.png");

TiledLayer tiledLayer = new TiledLayer(10, 10, image, 16, 16);



在例子中, 新创建的 TiledLayer 10 10 . 每个切片大小为16像素正方.

引人入胜的部分在于如何用这些切片创建场景. 要想为场景中的一个格分配一个切片,应使用setCell()方法. 你需要提供格的行和列位置以及切片的编号. 例如,你想将切片5分配给第2行第3列的格子,就应该使用setCell(2, 1, 5). 如果你看着这几个参数别扭,请注意切片编号从1开始,而格子的行和列编号从0开始. 新建的TiledLayer 中每个格的默认的切片编号为0, 这表明它们是空的.

下面的代码段演示了一种使用int数组创建TiledLayer的方法.在真正的游戏中, TiledLayers 应该由资源文件定义,这样可以更灵活地定义背景以及为游戏扩展新的地图或者级别等.

  private TiledLayer createBoard() {

    Image image = null;

    try { image = Image.createImage("/board.png"); }

    catch (IOException ioe) { return null; }

   

    TiledLayer tiledLayer = new TiledLayer(10, 10, image, 16, 16);

 

    int[] map = {

       1,  1,  1,  1, 11,  0,  0,  0,  0,  0,

       0,  0,  0,  0,  0,  0,  0,  0,  0,  0,

       0,  0,  0,  0,  0,  0,  0,  0,  0,  0,

       0,  0,  0,  0,  9,  0,  0,  0,  0,  0,

       0,  0,  0,  0,  1,  0,  0,  0,  0,  0,

       0,  0,  0,  7,  1,  0,  0,  0,  0,  0,

       1,  1,  1,  1,  6,  0,  0,  0,  0,  0,

       0,  0,  0,  0,  0,  0,  0,  7, 11,  0,

       0,  0,  0,  0,  0,  0,  7,  6,  0,  0,

       0,  0,  0,  0,  0,  7,  6,  0,  0,  0

    };

   

    for (int i = 0; i < map.length; i++) {

      int column = i % 10;

      int row = (i - column) / 10;

      tiledLayer.setCell(column, row, map[i]);

    }

   

    return tiledLayer;

  }



你需要在paint()方法中获得Graphics 对象来将这个TiledLayer 画在屏幕上.

TiledLayer 同样支持动态的切片,这使得按一定顺序变化一组切片变得很容易实现. 更多细节请参考 TiledLayerJavaDoc.

Sprites 实现人物动画

Game API 提供的Layer的另一个的子类是Sprite. 某种意义上来说, Sprite TileLayer概念上的反义词. TiledLayer 用图片源的一堆切片来构成一个场景, Sprite 是用一个图片源序列来实现动画.

创建一个Sprite 的所有工作需要提供一个图片源以及每一frame() 的图片大小. TiledLayer, 图片源是被分成相同大小的切片; Sprite, 每一个子图片则被称作一个帧. 下面的例子中, 图片源tank.png 被用来创建每帧大小32 x 32像素的Sprite.

  private MicroTankSprite createTank() {

    Image image = null;

    try { image = Image.createImage("/tank.png"); }

    catch (IOException ioe) { return null; }

 

    return new MicroTankSprite(image, 32, 32);

  }



图片源的每一个帧由一个编号,0开始依次编号. (这儿别晕; 切片编号从1开始.) Sprite 有一个frame sequence(帧序列) 用于决定每个帧按什么顺序来显示. 新建的 Sprite 默认帧序列为从0开始依次排列所有的帧.

在帧序列中前后变换应使用Sprite nextFrame() prevFrame() 方法. 这两个方法会自动判断边界处理. 比如, 如果Sprite 正显示它的帧序列中的最后一帧,调用 nextFrame() 则会显示帧序列的第一帧.

指定与默认的不同的序列,将新的序列表示为int数组并传递给setFrameSequence().

[不解] You can jump to a particular point in the current frame sequence by calling setFrame(). There is no way to jump to a specific frame number. You can only jump to a certain point in the frame sequence..

帧的变化只有在Sprite下次重绘的时候,也就是从Layer 类继承的paint()方法被调用的时候才可见.

Sprite 还可以对帧进行旋转变化. 每个帧可以旋转90°的倍数、进行镜像旋转, 或者两者的结合. Sprite 类里的常量列举了所有可能性. 可以通过这些常量使用setTransform()方法设置Sprite当前的旋转情况.下面的列子将当前帧以纵向中心为轴做镜面旋转并旋转90°(没看到过效果不知道翻译的对不对):

// Sprite sprite = ...

sprite.setTransform(Sprite.TRANS_MIRROR_ROT90);



图像旋转了但是Spritereference pixel(参考点) 并未移动. 默认地, Sprite 的参考点位于它的0,0,坐标也就是左上角. 当图像旋转时,参考点的位置也跟着转,但相对于图像来说参考点的位置还在原处(太蹩脚了,看不懂到底是什么意思).

你可以用defineReferencePixel() 方法改变参考点的位置. 在许多动画中你可能需要将参考点设在sprite的中心.

最后, Sprite 提供一些collidesWith() 方法用于与其它Sprites, TiledLayers, Images之间的碰撞检测. 你可以用矩形检测(方便但是不准)或者在像素这个级别上进行检测(麻烦但是准确). 这些方法之间的差别不是一句两句说得明白的,你还是去看JavaDoc.

clapton_xpAThotmailDOTcom

 

〔后面的懒得翻了,不如直接看代码喽〕

The muTank Example

The muTank example demonstrates the use of TiledLayer, Sprite, and LayerManager.

The important classes are MicroTankCanvas, which contains most of the code, and MicroTankSprite, which encapsulates the behavior of the tank.

MicroTankSprite makes extensive use of transformations. Using a source image with only three frames, MicroTankSprite can show the tank pointing in any of 16 different directions. Two exposed public methods, turn() and forward(), make the tank easy to control.

MicroTankCanvas is a GameCanvas subclass and contains an animation loop in run() that should look familiar to you. The tick() method checks to see if the tank has collided with the board. If so, its last movement is reversed using MicroTankSprite's undo() method. The input() method simply checks for key presses and adjusts the direction or position of the tank accordingly. The render() method uses a LayerManager to handle painting. The LayerManager contains two layers, one for the tank, one for the board.

The debug() method, called from the game loop, compares the elapsed time through the game loop with the desired loop time (80 milliseconds) and displays the percentage of time used on the screen. It is for diagnostic purposes only, and would be removed before the game was shipped to customers.

The timing of the game loop is more sophisticated than in the previous SimpleGameCanvas. To try to perform one iteration of the game loop every 80 milliseconds accurately, MicroTankCanvas measures the time it takes to perform tick(), input(), and render(). It then sleeps for the remainder of the 80-millisecond cycle, keeping the total time through each loop as close as possible to 80 milliseconds.

Summary

MIDP 2.0's Game API provides a framework that simplifies developing 2D action games. First, the GameCanvas class provides painting and input methods that make a tight game loop possible. Next, a framework of layers makes it possible to create complex scenes. TiledLayer assembles a large background or scene from a palette of source image tiles. Sprite is appropriate for animated characters and can detect collisions with other objects in the game. LayerManager is the glue that holds layers together. The muTank example provides a foundation of working code to demonstrate the Game API.

About the Author: Jonathan Knudsen [e-mail] [home page] is the author of several books, including Wireless Java (second edition), The Unofficial Guide to LEGO MINDSTORMS Robots, Learning Java (second edition), and Java 2D Graphics. Jonathan has written extensively about Java and Lego robots, including articles for JavaWorld, EXE, NZZ Folio, and the O'Reilly Network. Jonathan holds a degree in mechanical engineering from Princeton University.

 

 

clapton_xpAThotmailDOTcom

「Unity2D」使用Unity创建一个2D游戏系列-9

菜单选项 - 载入和重启游戏 本文由泰然教程组成员 betterdenger 翻译,原文请参阅「Menus - loading and restarting the game」 我们已经完...
  • s556699
  • s556699
  • 2017年02月15日 22:54
  • 919

[GDC 2015] Scroll Back - 2D 卷轴游戏的摄影机理论与实务

本文转载自:https://igdshare.org/content/gdc2015-2d-scrolling-itay-keren 直接開門見山地說,這場演講是我在 GDC 的獨立遊戲峰會(...
  • akof1314
  • akof1314
  • 2015年07月14日 19:42
  • 3014

Ubuntu 16.04安装星际译王

Ubuntu 16.04安装星际译王 1、sudo apt install stardict.安装星际译王IDE。 2、打开dash搜索星际译王,打开。但是默认现在你输入英文是无法翻译的,因为没有...
  • miaoqiucheng
  • miaoqiucheng
  • 2016年09月29日 14:48
  • 1483

关于iOS和OS X废弃的API

[译]关于iOS和OS X废弃的API你需要知道的一切 原文: Everything You Need to Know about iOS and OS X Deprecated APIs...
  • u010969412
  • u010969412
  • 2014年06月15日 11:16
  • 1724

2D动作游戏开发与实现(翻译) .

本文为 cping1982 主持翻译,如有转载,请严格按照如下方式显示标明译文作者及出处,以示尊重! 译者:cping1982 原文:http://blog.csdn.net/cping1982/...
  • kenkao
  • kenkao
  • 2013年09月26日 16:28
  • 1605

2D动作游戏开发与实现(翻译)

原文太长,所以将翻译与原文分成了两部分, 主要是讲2D游戏瓦片规则及不规则渲染与角色碰撞原理的。 因为单纯的2D游戏开发过于简单,所以本文尝试结合不同的2D平面游戏并将之归类,列出他们的优缺...
  • QQ276592716
  • QQ276592716
  • 2015年02月24日 14:05
  • 733

Quartz 2D之基本图形绘制

-(UIImage *)drawImageAtImageContext{ //获得一个位图图形上下文 CGSize size=CGSizeMake(300, 188);//画...
  • longshihua
  • longshihua
  • 2016年01月12日 16:35
  • 585

「Unity2D」使用Unity创建一个2D游戏系列-7

玩玩粒子效果 我们的发射的子弹,弹道是很飘逸,但是我们也该给它加点粒子效果来增强它们的视觉效果了。 粒子算是一种很小的sprite,它通过短时间的重复的生成和显示来生成一种酷炫的视觉效果。...
  • s556699
  • s556699
  • 2017年02月15日 22:51
  • 531

「Unity2D」使用Unity创建一个2D游戏系列-1

「Unity2D」使用Unity创建一个2D游戏系列-1 安装unity并且创建你的第一个场景 在第一章,你将会学习到一些非常基本的内容:首先是unity的下载和安装,其次...
  • s556699
  • s556699
  • 2017年02月14日 21:34
  • 1695

在Unity3D中使用Spine2D的骨骼动画

http://blog.csdn.net/huanran_li/article/details/41984001 调研资料 Spine下载地址: http://zh.es...
  • chenluwolf
  • chenluwolf
  • 2015年01月26日 10:40
  • 1605
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:[译]使用Game API创建2D动作游戏(二)
举报原因:
原因补充:

(最多只允许输入30个字)