iis服务器助手广告广告
返回顶部
首页 > 资讯 > 精选 >如何使用Game API函数制作二维动作游戏
  • 575
分享到

如何使用Game API函数制作二维动作游戏

2023-06-03 06:06:35 575人浏览 独家记忆
摘要

小编给大家分享一下如何使用Game api函数制作二维动作游戏,相信大部分人都还不怎么了解,因此分享这篇文章给大家参考一下,希望大家阅读完这篇文章后大有收获,下面让我们一起去了解一下吧!MIDP 2.0里面包括一个用来简化编写二维游戏的AP

小编给大家分享一下如何使用Game api函数制作二维动作游戏,相信大部分人都还不怎么了解,因此分享这篇文章给大家参考一下,希望大家阅读完这篇文章后大有收获,下面让我们一起去了解一下吧!

MIDP 2.0里面包括一个用来简化编写二维游戏的API函数。这个API函数是非常简凑的,只包括javax.microedition.lcdui.game包里的五个类。这五个类主要提供了两个重要的功能:
 新的Gamecanvas类使得在一个游戏循环体内画一个screen和响应键盘输入成为可能,而不需要调用系统的paint和input线程
 功能强大而复杂的图层(layer)API函数可以轻松高效地建立复杂的场景。

screen.width-333)this.width=screen.width-333;">

muTank Example
利用GameCanvas类创建一个游戏循环(game loop)
GameCanvas类是附加了功能的Canvas类,它提供了立即重画和检查设备按键状态的方法。这些新的方法把一个游戏的所有函数(功能)封装在一个循环体内,并由一个单线程进行控制。为什么这样做就非常吸引人阿?先让我们考虑一下你是如何执行一个使用了Canvas类的典型游戏的:
public void MicroTankCanvas
extends Canvas
implements Runnable {
public void run() {
while (true) {
// Update the game state.
repaint();
// Delay one time step.
}
}

public void paint(Graphics g) {
// Painting code Goes here.
}
protected void keyPressed(int keyCode) {
// Respond to key presses here.
}
}

这不是一个美丽的画面 。运行在应用程序线程中的run()方法,每一个时间段都会刷新游戏。典型的任务是刷新小球或飞行物的位置,绘制人物或飞行器动画。每一次通过循环体,repaint()方法被用来刷新屏幕。系统把按键事件传送给KeyPressed(),它能适当地刷新游戏状态。
问题是,每样东西都在不同的线程里,游戏代码在以上三种不同方法里传递很容易混淆。当run()方法里的主动画循环体调用repaint()方法时,将没有办法确切知道系统什么时候调用paint()方法。当系统调用KeyPressed()时,也没有办法知道程序的另一部分正在进行什么。如果你KeyPressed()中的代码将要刷新游戏的状态,而同一时刻paint()方法将表现屏幕,这时屏幕将会持续非常奇怪的状态。如果表现屏幕所用时间超过一个单时间段,动画会看起来颠簸不定或是很奇怪。
GameCanvas类允许你避开常用绘画(painting)和按键消息(key-event)机制,所以所有的游戏逻辑都可以被包括在一个单循环中。首先,GameCanvas类允许你用getGraphics()方法直接访问Graphics对象。对于所返回的Graphics对象的任何表现(rendering)都可以通过屏幕外缓冲区(offscreen buffer)来实现。你可以用flushGraphics()复制缓冲区到屏幕上,直到屏幕被刷新才会返回。这种方式给你提供比调用repaint()方法更完善的控制。Repaint()方法会立即返回值,以至于你的应用程序不能确定系统什么时候会调用paint()来刷新屏幕。
GameCanvas类也包含一个用来获得设备按键当前状态的方法,即所谓得polling技术。你可以通过调用GameCanvas类的geTKEyStates()方法,马上确定哪一个按键被按下,从而取代了等待系统调用KeyPressed()方法。
下面是一个使用GameCanvas类的典型的游戏循环体:
public void MicroTankCanvas
extends GameCanvas
implements Runnable {
public void run() {
Graphics g = getGraphics();
while (true) {
// Update the game state.
int keyState = getKeyStates();
// Respond to key presses here.
// Painting code goes here.
flushGraphics();
// Delay one time step.
}
}
}

接下来的例子描述了一个基本的游戏循环体。它向你展现了一个旋转的“X”,你可以用方向键在屏幕上移动它。这里的Run()方法特别的瘦小,这要多亏了GameCanvas。
import javax.microedition.lcdui.*;
import javax.microedition.lcdui.game.*;

public class SimpleGameCanvas
extends GameCanvas
implements Runnable {
private boolean mTrucking;
private long mFrameDelay;

private int mX, mY;
private int mState;

public SimpleGameCanvas() {
super(true);
mX = getWidth() / 2;
mY = getHeight() / 2;
mState = 0;
mFrameDelay = 20;
}

public void start() {
mTrucking = true;
Thread t = new Thread(this);
t.start();
}

public void stop() { mTrucking = false; }

public void run() {
Graphics g = getGraphics();

while (mTrucking == true) {
tick();
input();
render(g);
try { Thread.sleep(mFrameDelay); }
catch (InterruptedException ie) {}
}
}

private void tick() {
mState = (mState + 1) % 20;
}

private void input() {
int keyStates = getKeyStates();
if ((keyStates & LEFT_PRESSED) != 0)
mX = Math.max(0, mX - 1);
if ((keyStates & RIGHT_PRESSED) != 0)
mX = Math.min(getWidth(), mX + 1);
if ((keyStates & UP_PRESSED) != 0)
mY = Math.max(0, mY - 1);
if ((keyStates & DOWN_PRESSED) != 0)
mY = Math.min(getHeight(), mY + 1);
}

private void render(Graphics g) {
g.setColor(0xffffff);
g.fillRect(0, 0, getWidth(), getHeight());

g.setColor(0x0000ff);
g.drawLine(mX, mY, mX - 10 + mState, mY - 10);
g.drawLine(mX, mY, mX + 10, mY - 10 + mState);
g.drawLine(mX, mY, mX + 10 - mState, mY + 10);
g.drawLine(mX, mY, mX - 10, mY + 10 - mState);

flushGraphics();
}
}

本文所举示例的代码包括一个使用了这个canvas的MIDlet。你可以尝试着运行SimpleGameMIDlet这个小程序,看看它是怎样工作的。你将会看到一个像正在做健身操的海星的东西(或许它正在寻找自己失掉的腿)。


如何使用Game API函数制作二维动作游戏


screen.width-333)this.width=screen.width-333;">

SimpleGameMIDlet Screen Shot

游戏场景就像是洋葱(有层次)
典型的二维动作游戏常包含一个背景和若干动画人物。尽管你可以自己来描绘出这种场景,不过Game API函数使你能够用图层来建立场景。你可以做一个城市的背景图层,另外再做一个含有一辆小汽车的图层。将小汽车图层放在背景上,你就创造出了一个完整的场景。把小汽车放在一个单独的图层中,可以很容易的熟练操控它,而不受背景和其他图层的影响。

Game API函数使用以下四个类为图层提供灵活的支持

 Layer类是所有图层类对象的抽象基类。它定义了一个图层的基本属性,包括位置,尺寸,和此图层是否可见。Layer类的每个子类必须定义一个paint()方法,用来把这个图层表现在一个图象上,这个图象将会被描画到屏幕表面上。两个确切的子类TiledLayer和Sprite应该能满足你的二维游戏的需要了。
 TiledLayer类用来建立背景图像。你可以用一个小的源图像贴的集合来高效的制作大的图像。
 Sprite类是一个动画层。你提供源帧就可以对整个动画进行完全的控制。Sprite类也提供镜像,并可对源帧作90度旋转。
 LayerManager类是一个非常有用的类,用来保存你的场景中的所有图层的动作轨迹。LayerManager类 paint()方法的一个简单调用就足以控制所包含的所有图层。

使用TiledLayer类
尽管包含一些不是显而易见的微妙不同,TiledLayer类还是很容易理解。这个类的基本思想就是,用一个源图像提供一组图像贴片,这些贴片可以组合成一幅大的场景。例如,下面的图像是64*48像素的。


如何使用Game API函数制作二维动作游戏


screen.width-333)this.width=screen.width-333;">

Source Image
这个图像被分成了12块16*16的图像贴片。TiledLayer类分配给每个图像贴片编号,左上角的图片规定为1,以此类推。上面源图像的各个贴片如下编号:


如何使用Game API函数制作二维动作游戏


screen.width-333)this.width=screen.width-333;">

Tile Numbering
用代码创建一个TiledLayer类是非常简单的。你需要确定行数和列数,源图像以及这个源图像里每个贴片的像素大小。下面的代码片断告诉你如何装载图像和创建TiledLayer类。
Image image = Image.createImage("/board.png");
TiledLayer tiledLayer = new TiledLayer(10, 10, image, 16, 16);
在例子中,新的TiledLayer类有10行,10列。这些来自image的图像贴片大小是16*16像素。
有趣的部分还是用这些图像贴片来创建一幕场景。利用setCell()方法可以把一个图像贴片分配到一个数组元胞里。你需要提供这个数组元胞所在行列数以及图像贴片的编号。例如,你可以通过调用setCelll(2,1,5)方法把编号为5的图像贴片分配到第2行中的第3个数组元胞里。如果你觉得这些参数看起来不对,请注意,图像贴片编号是从1开始计数,而行和列的编号是从0开始的。参数缺省情况下,新的TiledLayer类对象中的所有数组元胞的图像贴片标号为0,这就意味着它们是空的。

下面的代码片断向你说明一种使用整数数组来填充TiledLayer类对象。在实际图像中,TiledLayer类可以从资源文件里定义,这就使得定义背景时可以有更多的灵活性,并能提供新的背景和级别来增强游戏的可玩性。
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;
}
为了把这个TiledLayer类对象显示在屏幕上,你需要调用一个Graphics对象的paint()方法。
TiledLayer类还支持动画图像帖子,这样就使得通过一系列贴片来移动元胞集合很容易了。若想得到更详细的说明,参看TiledLayer类相关的API文档。

使用Sprite类实现人物动画
Game API函数里提供的另一个具体的Layer类是Sprite类。一方面,Sprite类是TileLayer类的概念化的逆转.TiledLayer类使用源图像贴片的调色板来创建一幅大场景,而Sprite类则使用一系列源图像帧来产生动画。

你创建一个Sprite类所需要的只是源图像和每个帧的尺寸。在TiledLayer类里,源图像被分为相同大小的图像贴片;在Sprite类里,子图像被称为帧。在下面的例子里,源图像tank.png用来创建帧大小为32*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类有一个帧序列,它决定了帧显示的顺序。一个新Sprite类对象的缺省帧序列简单地依照可用帧,从0开始累加。
使用Sprite类的nextFrame()方法和prevFrame()方法,可以把帧在帧序列中向前或向后移动。这些方法把帧序列的头尾连接起来了。例如,如果Sprite类对象已经把位于帧序列末尾的帧显示出来了,若在调用nextFrame()方法将会显示帧序列的头帧。
调用setFrameSequence()方法,可以通过整型数组所指定的序列来确定不同于缺省时的帧序列。
你还可以调用setFrame()方法跳至当前帧序列中的某一帧。你不能跳至特定的帧编号处,只能跳至帧序列的特定点。
利用从Layer类继承下来的paint()方法时,只有在Sprite类在下一个时间段内被表现的时候,帧的变化才真正实现。
Sprite类还可以变换源帧。可以把帧旋转90度,或做镜像变换,或两者皆有。在Sprite类里的常数枚举了这些可能性。Sprite类的当前变换方式可以通过向setTransfORM()方法传递这些常数之一进行设定。下面的例子是当前帧绕垂直中心做镜像变换,并旋转90度:
// Sprite sprite = ...
sprite.setTransform(Sprite.TRANS_MIRROR_ROT90);
应用了变换方式,从而使得Sprite类的参考像素并没有移动。缺省下,Sprite类的参考像素位于Sprite类坐标系里的(0,0)点处,即左上角。当应用了变换方式,参考像素的位置也变换了。Sprite类的位置被调整了,从而参考像素仍然在原位置上。
你可以通过调用defineReferencePixel()方法来改变参考像素点的位置。对于大多数类型的动画,你可以把参考像素点定义在sprite的中心上。
最后,Sprite类提供几个collidesWith()方法来检测与其他Sprites,ItledLayers,或Images类对象的碰撞。你可以使用检测矩形(快但粗糙)或者像素级别(慢但精确)来检测碰撞。这些方法的微妙不同是难以描述的;若详细资料,可参看API 文档。
MuTank例子
MuTank例子向你说明TiledLayer,Sprite和LayerManager类的用法。
最重要的类是包含大部分代码的MicroTankCanvas类和封装了坦克行为的MicroTankSprite类。
MicroTankSprite类制作了大量的变换方式。它使用了一个只含3帧的源图像来显示指向16种方向的坦克。Turn()和forward()两个公用方法使得坦克很容易控制。
MicroTankCanvas类是GameCanvas类的子类,它在run()方法里包含一个你应该很熟悉的动画循环体.Tick()方法用来检测坦克是否碰到隔板上了。如果碰到了,就调用MicroTankCanvas类的undo()方法使它最近一次的运动倒退。Input()方法简单地检测按键是否被按下,并同时调整坦克的方向或位置。Render()方法使用一个LayerManager类对象来对绘画进行处理。LayerManager类包含两个图层,坦克图层和隔板图层。
从游戏循环体中调用的Debug()方法,用来比较通过游戏循环体所用时间和期望的循环时间(80毫秒),并在屏幕上显示时间的百分比。它仅仅是用作调试诊断目的的,在游戏被发送给用户之前将会被删除。
游戏循环体的计时比前面的SimpleGameCanvas类更加复杂。为了更精确的每80毫秒就重复一次游戏循环体,MicroTankCanvas类对tick(),input()和render()方法所花费时间进行测量。然后停下来花费完80毫秒中的剩余时间,以使得通过每次循环所用的总共时间尽可能的接近于80毫秒。

以上是“如何使用Game API函数制作二维动作游戏”这篇文章的所有内容,感谢各位的阅读!相信大家都有了一定的了解,希望分享的内容对大家有所帮助,如果还想学习更多知识,欢迎关注编程网精选频道!

--结束END--

本文标题: 如何使用Game API函数制作二维动作游戏

本文链接: https://www.lsjlt.com/news/233185.html(转载时请注明来源链接)

有问题或投稿请发送至: 邮箱/279061341@qq.com    QQ/279061341

本篇文章演示代码以及资料文档资料下载

下载Word文档到电脑,方便收藏和打印~

下载Word文档
猜你喜欢
  • 如何使用Game API函数制作二维动作游戏
    小编给大家分享一下如何使用Game API函数制作二维动作游戏,相信大部分人都还不怎么了解,因此分享这篇文章给大家参考一下,希望大家阅读完这篇文章后大有收获,下面让我们一起去了解一下吧!MIDP 2.0里面包括一个用来简化编写二维游戏的AP...
    99+
    2023-06-03
  • 如何使用Java制作飞机大战游戏
    这篇文章给大家分享的是有关如何使用Java制作飞机大战游戏的内容。小编觉得挺实用的,因此分享给大家做个参考,一起跟随小编过来看看吧。一、代码实现创建窗口首先创建一个游戏窗体类GameFrame,继承至JFrame,用来显示在屏幕上(wind...
    99+
    2023-06-15
  • 如何使用Matlab制作大富翁小游戏
    这篇文章主要介绍“如何使用Matlab制作大富翁小游戏”,在日常操作中,相信很多人在如何使用Matlab制作大富翁小游戏问题上存在疑惑,小编查阅了各式资料,整理出简单好用的操作方法,希望对大家解答”如何使用Matlab制作大富翁小游戏”的疑...
    99+
    2023-06-29
  • python如何使用MyQR和qrcode来制作二维码
    这篇文章将为大家详细讲解有关python如何使用MyQR和qrcode来制作二维码,小编觉得挺实用的,因此分享给大家做个参考,希望大家阅读完这篇文章后可以有所收获。Python的优点有哪些1、简单易用,与C/C++、Java、C# 等传统语...
    99+
    2023-06-15
  • 如何使用h5制作的网页版扫雷游戏
    小编给大家分享一下如何使用h5制作的网页版扫雷游戏,相信大部分人都还不怎么了解,因此分享这篇文章给大家参考一下,希望大家阅读完这篇文章后大有收获,下面让我们一起去了解一下吧!示例代码如下:<!DOCT...
    99+
    2022-10-19
  • “如何在PHP和Git中使用NPM制作二维码?”
    如何在PHP和Git中使用NPM制作二维码? 二维码的应用越来越广泛,不论是商家在广告中使用二维码来提供更多信息,还是个人在社交媒体上分享自己的联系方式。在本文中,我们将介绍如何使用NPM在PHP和Git中制作二维码。 NPM是一个包管理器...
    99+
    2023-09-07
    git 二维码 npm
  • 如何在 Windows 操作系统中使用 Go 编写二维码函数?
    随着移动支付的普及,二维码技术已经成为了现代生活中不可或缺的一部分。在编写应用程序时,我们也经常需要使用二维码来实现某些功能。如果你是一名使用 Go 语言进行开发的开发者,那么你可能会想知道如何在 Windows 操作系统中使用 Go 编...
    99+
    2023-10-03
    windows 二维码 函数
  • 二维码生成器:如何使用Java API和Linux操作系统?
    二维码已经成为了一种非常流行的信息分享方式。在现代数字化时代,人们越来越需要快速、方便的方式来分享和传递信息,而二维码正是这样的一种方式。在本文中,我们将介绍如何使用Java API和Linux操作系统来生成二维码。 一、什么是二维码? 二...
    99+
    2023-06-15
    api linux 二维码
  • 如何使用Matlab制作简易版八分音符酱游戏
    这篇文章主要介绍“如何使用Matlab制作简易版八分音符酱游戏”的相关知识,小编通过实际案例向大家展示操作过程,操作方法简单快捷,实用性强,希望这篇“如何使用Matlab制作简易版八分音符酱游戏”文章能帮助大家解决问题。效果游戏方式给电脑插...
    99+
    2023-06-29
  • 如何使用React Native制作一个简单的游戏引擎
    这篇文章将为大家详细讲解有关如何使用React Native制作一个简单的游戏引擎,小编觉得挺实用的,因此分享给大家做个参考,希望大家阅读完这篇文章后可以有所收获。开始吧要制作任何游戏,我们需要一个循环,在我们玩的时候更新我们的游戏。这个循...
    99+
    2023-06-15
软考高级职称资格查询
编程网,编程工程师的家园,是目前国内优秀的开源技术社区之一,形成了由开源软件库、代码分享、资讯、协作翻译、讨论区和博客等几大频道内容,为IT开发者提供了一个发现、使用、并交流开源技术的平台。
  • 官方手机版

  • 微信公众号

  • 商务合作