分享
 
 
 

利用J2ME开发移动3D游戏之3D图形API

王朝java/jsp·作者佚名  2006-01-10
窄屏简体版  字體: |||超大  

作者:未知 文章来源:yesky

简述

现在,移动游戏和移动应用开发极为热门!游戏中需要有时髦漂亮的图形,其设计标准比以前任何时候都要高。本文将告诉你怎样用酷毙的移动3D图形API为J2ME设备开发3D图形游戏。

如果你在用MIDP1.0进行用户接口编程,那么有两条路你可以选择:使用高级的UI类或者一切由你自己从头开始。作为游戏开发者,第一种选择往往是不可能的;这是为什么游戏开发者不得不为他们的高级游戏开发自己的3D引擎的原因。无疑,这需要付出大量的时间和努力,而缺乏浮点数支持的CLDC 1.0(MIDP 1.0正是建于其上)对问题的解决没有多大帮助。

在MIDP 2.0中,有一个可选的叫移动3D图形API的软件包,或者叫JSR 184。该API是第一个基于Java标准开发的移动设备上的三维图形软件包。该API既有高级又有低级图形特征;其中,高级特征称为保留模式,低级特征称为立即模式。保留模式使得开发者有可能使用场景图形并使场景中的物体根据虚拟相机和灯光的位置进行自身的着色。立即模式能够允许应用程序直接进行物体绘制。如果需要,可以在同一个应用程序中使用这两种模式。

本文着重介绍立即模式(在第二篇文章中我们将分析保留模式)。

3D API

让我们以列举和解释该3D API中的类作为开始。除了这些API外,JSR 184还包含了一个场景图形结构和一个相应的文件格式以有效地管理和配置3D内容。该文件格式定义了一种m3g文件,这种文件典型地从3D建模文件应用程序中转换而来。

表1.3D API类

描述

AnimationController

控制动画顺序。

AnimationTrack

把一个KeyframeSequence同一个AnimationController相关联。

Appearance

定义一个网眼(Mesh)或一个Spring3D的着色属性的一组对象。

Background

定义视图是怎样被清除的。

Camera

一个场景图顶点,它定义了场景中观察者的位置以及从3D到2D的投影。

CompositingMode

一个Appearance类,它封装了每一个像素的合成属性。

Fog

一个Appearance类,它包含了雾化的有关属性。

Graphics3D

一个单独的3D图形上下文。所有的着色操作都是在该类中的render()方法中实现的。

Group

一个场景图形结点,它存储了一个无序的结点集作为它的子结点。

Image2D

一个二维图像,可用于纹理,背景,或者精灵图像。

IndexBuffer

该类定义了如何把顶点连接起来以形成一个几何体。

KeyframeSequence

封装了一系列的具有时间戳和矢量值的关键帧的动画数据。

Light

描述了不同类型的光源。

Loader

下载和反串行化图形结点及结点成分,以及整个场景图形。

Material

封装了进行光学计算的材质属性。

Mesh

描述了一个3D对象,它是用多边形面定义的。

MorphingMesh

描述了一个顶点-变形的多边形网眼。

Node

所有场景图形结点的抽象基类。其五个具体子类是:Camera,Mesh,Sprite3D,Light和Group。

Object3D

所有可以成为3D世界中组成部分的对象的抽象基类。

PolygonMode

封装了多边形级别属性。

RayIntersection

存储了对于分割的Mesh或Sprite3D的引用,以及有关分割点的信息。

SkinnedMesh

描述了一个框架动画的多边形网眼。

Sprite3D

用3D位置来描述一个2D图像。

Texture2D

封装了一个2D纹理图像和一个属性集合,这些属性指出该图像是如何应用到子网眼上的。

Transform

一个通用的4x4的浮点数矩阵,用来描述一个变换。

Transformable

Node和Texture2D类的抽象基类。

TriangleStripArray

定义了一个三角形带数组。

VertexArray

一个整型矢量数组,描述了顶点位置,法线,颜色或者纹理坐标。

VertexBuffer

存储对于VertexArrays的引用,它包含了一个顶点集的位置,颜色,法线,以及纹理坐标。

World

一个特别的Group结点,它作为场景图最顶层的容器。

举例

我们将开发一个简单的旋转一个多边形的3D应用程序为例。该多边形是一个立方体,它的纹理是一张旧汽车相片。列表1展示了例程midlet的主要类-应用程序的中心类。该类负责创建应用程序并建立起运行MyCanvas的计时器。

列表1. MIDletMain类

import javax.microedition.midlet.*;

import javax.microedition.lcdui.*;

import java.util.*;

public class MIDletMain extends MIDlet {

static MIDletMain midlet;

MyCanvas d = new MyCanvas();

Timer iTimer = new Timer();

public MIDletMain() {

this.midlet = this;

}

public void startApp() {

Display.getDisplay(this).setCurrent(d);

iTimer.schedule( new MyTimerTask(), 0, 40 );

}

public void pauseApp() {}

public void destroyApp(boolean unconditional) {}

public static void quitApp() {

midlet.destroyApp(true);

midlet.notifyDestroyed();

midlet = null;

}

class MyTimerTask extends TimerTask {

public void run() {

if( d != null ) {

d.repaint();

}

}

}

}

列表2显示了MyCanvas类,该类包含了应用程序的所有图形逻辑。init()方法负责结点的创建,纹理文件的装载并设置纹理,外观和背景也被一起设置。paint()方法负责着色并旋转立方体。图1展示了正在一个模拟器中运行的实际程序。

列表2. MyCanvas类

import javax.microedition.lcdui.*;

import javax.microedition.m3g.*;

public class MyCanvas extends Canvas {

private Graphics3D graphics3d;

private Camera camera;

private Light light;

private float angle = 0.0f;

private Transform transform = new Transform();

private Background background = new Background();

private VertexBuffer vbuffer;

private IndexBuffer indexbuffer;

private Appearance appearance;

private Material material = new Material();

private Image image;

public MyCanvas() {

// 创建Displayable对象以探听命令事件

setCommandListener(new CommandListener() {

public void commandAction(Command c, Displayable d) {

if (c.getCommandType() == Command.EXIT) {

MIDletMain.quitApp();}}

});

try { init();}

catch(Exception e) { e.printStackTrace();}

}

/**

* 组件的初始化

*/

private void init() throws Exception {

addCommand(new Command("Exit", Command.EXIT, 1));

graphics3d = Graphics3D.getInstance();

camera = new Camera();

camera.setPerspective( 60.0f,(float)getWidth()/ (float)getHeight(), 1.0f, 1000.0f );

light = new Light();

light.setColor(0xffffff);

light.setIntensity(1.25f);

short[] vert = {

5, 5, 5, -5, 5, 5, 5,-5, 5, -5,-5, 5,

-5, 5,-5, 5, 5,-5, -5,-5,-5, 5,-5,-5,

-5, 5, 5, -5, 5,-5, -5,-5, 5, -5,-5,-5,

5, 5,-5, 5, 5, 5, 5,-5,-5, 5,-5, 5,

5, 5,-5, -5, 5,-5, 5, 5, 5, -5, 5, 5,

5,-5, 5, -5,-5, 5, 5,-5,-5, -5,-5,-5 };

VertexArray vertArray = new VertexArray(vert.length / 3, 3, 2);

vertArray.set(0, vert.length/3, vert);

//立方体的各个结点法线

byte[] norm = {

0, 0, 127, 0, 0, 127, 0, 0, 127, 0, 0, 127,

0, 0,-127, 0, 0,-127, 0, 0,-127, 0, 0,-127,

-127, 0, 0, -127, 0, 0, -127, 0, 0, -127, 0, 0,

127, 0, 0, 127, 0, 0, 127, 0, 0, 127, 0, 0,

0, 127, 0, 0, 127, 0, 0, 127, 0, 0, 127, 0,

0,-127, 0, 0,-127, 0, 0,-127, 0, 0,-127, 0 };

VertexArray normArray = new VertexArray(norm.length / 3, 3, 1);

normArray.set(0, norm.length/3, norm);

//各个结点的纹理坐标

short[] tex = {

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

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

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

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

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

1, 0, 0, 0, 1, 1, 0, 1 };

VertexArray texArray = new VertexArray(tex.length / 2, 2, 2);

texArray.set(0, tex.length/2, tex);

int[] stripLen = { 4, 4, 4, 4, 4, 4 };

// 对象的VertexBuffer

VertexBuffer vb = vbuffer = new VertexBuffer();

vb.setPositions(vertArray, 1.0f, null);

vb.setNormals(normArray);

vb.setTexCoords(0, texArray, 1.0f, null);

indexbuffer = new TriangleStripArray( 0, stripLen );

//纹理图像

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

Image2D image2D = new Image2D( Image2D.RGB, image );

Texture2D texture = new Texture2D( image2D );

texture.setFiltering(Texture2D.FILTER_NEAREST,

Texture2D.FILTER_NEAREST);

texture.setWrapping(Texture2D.WRAP_CLAMP,Texture2D.WRAP_CLAMP);

texture.setBlending(Texture2D.FUNC_MODULATE);

// 创建外观(Appearance)对象

appearance = new Appearance();

appearance.setTexture(0, texture);

appearance.setMaterial(material);

material.setColor(Material.DIFFUSE, 0xFFFFFFFF);

material.setColor(Material.SPECULAR, 0xFFFFFFFF);

material.setShininess(100.0f);

background.setColor(0xffffcc);

}

protected void paint(Graphics g) {

graphics3d.bindTarget(g, true,

Graphics3D.DITHER |

Graphics3D.TRUE_COLOR);

graphics3d.clear(background);

//设置照相机

Transform transform = new Transform();

transform.postTranslate(0.0f, 0.0f, 30.0f);

graphics3d.setCamera(camera, transform);

//设置灯光

graphics3d.resetLights();

graphics3d.addLight(light, transform);

//设置旋转

angle += 1.0f;

transform.setIdentity();

transform.postRotate(angle, 1.0f, 1.0f, 1.0f);

graphics3d.render(vbuffer, indexbuffer, appearance, transform);

graphics3d.releaseTarget();

}

}

图1 正在一个模拟器中运行的应用程序

小结

JSR 184对于可以运行MIDP 2.0的设备来说,是一个节省时间和空间的可选的软件开发包。它允许开发者使用两种图形方式-保留模式和立即模式-来产生3D图形。本文集中讲述了立即模式,并给出一个例子程序来说明怎样使用3D API。

 
 
 
免责声明:本文为网络用户发布,其观点仅代表作者个人观点,与本站无关,本站仅提供信息存储服务。文中陈述内容未经本站证实,其真实性、完整性、及时性本站不作任何保证或承诺,请读者仅作参考,并请自行核实相关内容。
2023年上半年GDP全球前十五强
 百态   2023-10-24
美众议院议长启动对拜登的弹劾调查
 百态   2023-09-13
上海、济南、武汉等多地出现不明坠落物
 探索   2023-09-06
印度或要将国名改为“巴拉特”
 百态   2023-09-06
男子为女友送行,买票不登机被捕
 百态   2023-08-20
手机地震预警功能怎么开?
 干货   2023-08-06
女子4年卖2套房花700多万做美容:不但没变美脸,面部还出现变形
 百态   2023-08-04
住户一楼被水淹 还冲来8头猪
 百态   2023-07-31
女子体内爬出大量瓜子状活虫
 百态   2023-07-25
地球连续35年收到神秘规律性信号,网友:不要回答!
 探索   2023-07-21
全球镓价格本周大涨27%
 探索   2023-07-09
钱都流向了那些不缺钱的人,苦都留给了能吃苦的人
 探索   2023-07-02
倩女手游刀客魅者强控制(强混乱强眩晕强睡眠)和对应控制抗性的关系
 百态   2020-08-20
美国5月9日最新疫情:美国确诊人数突破131万
 百态   2020-05-09
荷兰政府宣布将集体辞职
 干货   2020-04-30
倩女幽魂手游师徒任务情义春秋猜成语答案逍遥观:鹏程万里
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案神机营:射石饮羽
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案昆仑山:拔刀相助
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案天工阁:鬼斧神工
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案丝路古道:单枪匹马
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案镇郊荒野:与虎谋皮
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案镇郊荒野:李代桃僵
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案镇郊荒野:指鹿为马
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案金陵:小鸟依人
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案金陵:千金买邻
 干货   2019-11-12
 
推荐阅读
 
 
 
>>返回首頁<<
 
靜靜地坐在廢墟上,四周的荒凉一望無際,忽然覺得,淒涼也很美
© 2005- 王朝網路 版權所有