WAP之家:为您提供最全最新的WAP技术,CP.SP.3G等行业资讯。 WAP之家交流论坛全新开放 点击进入>>
WAP资讯 | 3G动态 | SP动态 | 运营商动态 | 内容商动态 | 制造商动态 | 论坛讨论>> 每次自动访问
WAP技术 | WAP源码 | 手机编程 | 手机源码 | 无线技术 | J2ME技术 | 手机软件 添加到收藏夹
IVR技术 | SP资料 | SMS MMS技术 | 商业方案 | IVR下载 | 书籍教程 | 工具软件 语言:繁體中文

WAP之家技术文章手机编程Symbian游戏开发在移动设备上使用M3G编程教程

在移动设备上使用M3G编程教程
作者:碧云天  来源:翻译  发布时间:2005-12-20 2:30:23
ra() {
        // Check controls
        if(key[LEFT])
        {
            camRot += 5.0f;
        }
        else if(key[RIGHT])
        {
            camRot -= 5.0f;
        }
       
        // Set rotation
        cam.setOrientation(camRot, 0.0f, 1.0f, 0.0f);
       
        // Calculate trigonometry for camera movement
        double rads = Math.toRadians(camRot);
        camSine = Math.sin(rads);
        camCosine = Math.cos(rads);

    正如你所看到的一样这个函数的一半是如此的简单,首先我们检查用户是否按下了左键或者右键,如果按下我们就是增加和减少摄像机的角度,个相当的简单。接下来的几行是相当有趣的,我们使得当用户按下左或右键时用户的头会转,我们沿着Y轴进行旋转,这就是说旋转的方向向量是0.0f,1.0f,0.0f。我们旋转摄像机以后我们计算新的正弦和余弦值,我们将根据这个结构来移动摄像机。接下来我们看一下接下来的代码:

if(key[UP])
        {
            // Move forward
            cam.translate(-0.1f * (float)camSine, 0.0f, -0.1f * (float)camCosine);
           
            // Bob head
            headDeg += 0.5f;
           
            // A simple way to "bob" the camera as the user moves
            cam.translate(0.0f, (float)Math.sin(headDeg) / 40.0f, 0.0f);
        }
        else if(key[DOWN])
        {
            // Move backward
            cam.translate(0.1f * (float)camSine, 0.0f, 0.1f * (float)camCosine);
           
            // Bob head
            headDeg -= 0.5f;
           
            // A simple way to "bob" the camera as the user moves
            cam.translate(0.0f, (float)Math.sin(headDeg) / 40.0f, 0.0f);
        }

        // If the user presses the FIRE key, let's quit
        if(key[FIRE])
            M3GMidlet.die();
    }

这里我们检查UP或DOWN。UP将移动摄像机向前而DOWN将移动摄像机向后。这里有一个简单的转化,我们马上就会解释的。摄像机总是从负Z轴的方向看过去的,所以我们向前移动只需要沿着Z轴的方向移动就可以了。然而,如果我们旋转了摄像机我们不能在只沿着Z轴方向移动,这样看上去是错误的。我们必须也沿着我们的方向在X轴移动。这样我们就用到了三角函数的方法。因为这个教程不是关于3D数学的,我们不能讨论更多的细节,如果你认为这是比较难的,那么在互联网上查找一个关于3D数学的教程将让你解决这些问题。

在完成所有的移动后,我们通过简单的头部抖动来移动我们的头部,我们只是通过一个简单的正弦函数实现沿着Y轴上下移动,以至于我们的看起来上下移动,他是通过增加或者减少headDeg这个变量来实现的。在最后我们检查了FIRE这个键,以至于用户可以在任何他想要退出的时候退出游戏。(我们也可以使用我们在Canvas建立的时候添加的退出命令菜单退出)。

综上所述,这就是我们摄像机的所有操作,现在所有剩下的操作就是使用World节点绘制了。

绘制多边型

我们在分析这段代码之前,我必须谈到的就是立即模式和保留模式的绘图。保留模式就是我们在现在的这个教程中使用的方式。当我们要绘制一个整个的包含摄像机、灯光、贴图灯的World节点时我们基本使用这种方式。这是一个绘制的简单的模式,但是这也使得我们对整个世界的控制变得最少。在立即模式下,我们绘制的时一个多边形的群,直接时简单的贴图和顶点数据。这将给我们更多的控制我们可以在绘制以前使用一个旋转矩阵对他进行旋转。我们在立即模式中,我们绘制一个World节点,通过使用一个旋转矩阵的方式来操作,但是我们将忽略所有的特效的效果,比如摄像机、背景、和其他。我们在以后的系列教程中将详细的讨论两个模式的细节问题。那么现在让我们看一下如何来绘制一个世界吧。

Graphics3D

JSR184中所有的绘制操作都是使用Graphics3D对象。我们甚至能够操作摄像机和灯光信息,如果使用的时立即模式绘图。既然我们已经决定在以后讨论,那么我们现在就不需要考虑这些问题。

为了使用Graphics3D对象绘图,我们必须绑定一个绘图设备上下文。一个绘图设备上下文的基本意思是一个Graphics对象要绘画的地方。如果我们想在一个图像上绘制我们的对象,那们它就是这个图像的对象,或者我们通过主Graphics对象中的getGraphics()获得的。通过主Graphics对象的方法获得的就是直接绘制在屏幕上,我们可以在上面做任何我们可以做的操作。对于得到一个Graphics3D对象是简单的,你只需要调用Graphics3D.getInstance()方法。你将得到每一个MIDlet唯一的Graphics3D对象,这就是我们只能使用getInstance()来得到它的原因了。通过bindTarget方法来实现绑定,这是一个很少用到的方法,这里是一个简单的例子。

//这是我们的 Graphics3D 对象
Graphics3D g3d = Graphics3D.getInstance();

// 绑定到一个图像文件
Image img = Image.createImage("myImage.png");
Graphics g = img.getGraphics();
g3d.bindTarget(g);

// 绑定主 Graphics 对象
g3d.bindTarget(getGraphics());

// We can also supply rendering hints. Remember those? I talked about them at the beginning.
// This is done by using the other form of the bindTarget method.
// It takes a Graphics object to begin with, as always, and then it needs a boolean
// and an integer mask of hints.
// The boolean simply tells the Graphics3D object if it should use a depth buffer
// and you'll probably always set it to 'true'. Here is how we'll use it to bind
// with our hints:
g3d.bindTarget(getGraphics(), true, RENDERING_HINTS); 

既然你知道了如何绑定你的目标了,你也必须知道这个目标必须在每个程序循环中释放。这意味着每当你要画其他的对象的时候,你必须释放这个目标。释放和绑定这个问题有时会出现。所以更多的人保持整个的游戏循环都在try、catch的异常处理的类中并且在异常的最后调用释放目标。在这个例子中我们就是这样做的。现在让我们来看一下绘图函数。为了绘制物体,我们需要使用一些绘制方法变量,在这一章里我们感兴趣的只有一个就是World的绘图方法。简单吗?当然,我们只需要提供你的世界节点,它将自动的绘制它。让我们看一看游戏的主循环是如何实现的。

/** 绘制到屏幕上
     */
    private void draw(Graphics g)
    {
        // Envelop all

上一页  [1] [2] [3] [4]  下一页

[] [返回上一页] [打 印]
文章评论

用户名: 查看更多评论

分 值:100分 85分 70分 55分 40分 25分 10分 0分

内 容:

         (注“”为必填内容。) 验证码: 验证码,看不清楚?请点击刷新验证码