利用J2ME开发移动3D游戏之3D图形API
来源:互联网 发布:java 源码保护 编辑:程序博客网 时间:2024/06/15 06:36
简述
(转自:http://lixinye0123.javaeye.com/blog/318288)
现在,移动游戏和移动应用开发极为热门!游戏中需要有时髦漂亮的图形,其设计标准比以前任何时候都要高。本文将告诉你怎样用酷毙的移动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类
举例
我们将开发一个简单的旋转一个多边形的3D应用程序为例。该多边形是一个立方体,它的纹理是一张旧汽车相片。列表1展示了例程midlet的主要类-应用程序的中心类。该类负责创建应用程序并建立起运行MyCanvas的计时器。
列表1. MIDletMain类
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.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。
- 利用J2ME开发移动3D游戏之3D图形API
- 利用J2ME开发移动3D游戏之3D图形API
- 利用J2ME开发移动3D游戏之3D图形API
- 利用J2ME开发移动3D游戏之3D图形API
- 为J2ME开发移动3D游戏之立即模式
- 为J2ME开发移动3D游戏之保留模式
- 为基于J2ME的手机开发移动3D游戏
- 基于J2ME的手机开发移动3D游戏
- 为基于J2ME的手机开发移动3D游戏
- 为基于J2ME的手机开发移动3D游戏
- [转载]为J2ME开发移动3D游戏之保留模式
- 3D数学基础图形与游戏开发之 坐标系
- 3D数学基础图形与游戏开发之坐标系
- J2ME移动2D图形开发快速入门
- J2ME 2D游戏开发中的图形旋转问题
- 使用irrlicht开发3D移动游戏
- J2ME移动2D图形快速入门
- 使用Game API开发J2ME 2D游戏
- [转载]关于struct device_driver结构中的probe探测函数的调用
- Wince unicode
- C#中Get,Set的详细说明
- Android如何解析Intent
- 启动tomcat的时候报Exception starting filter struts2的解决办法
- 利用J2ME开发移动3D游戏之3D图形API
- Port and CMF
- dedecms用webservice添加天气预报
- 我是IT界的一只小小鸟,天空是我的极限!
- Ogre-天龙八部粒子插件的实现(1)
- PC-Lint软件使用方法
- GDB STL vector打印
- 获取下拉菜单的项文本 text
- vc win32 gdi+ 怎么显示PNG图片