Java学习者论坛

 找回密码
 立即注册

QQ登录

只需一步,快速开始

手机号码,快捷登录

恭喜Java学习者论坛(https://www.javaxxz.com)已经为数万Java学习者服务超过8年了!积累会员资料超过10000G+
成为本站VIP会员,下载本站10000G+会员资源,购买链接:点击进入购买VIP会员
JAVA高级面试进阶视频教程Java架构师系统进阶VIP课程

分布式高可用全栈开发微服务教程

Go语言视频零基础入门到精通

Java架构师3期(课件+源码)

Java开发全终端实战租房项目视频教程

SpringBoot2.X入门到高级使用教程

大数据培训第六期全套视频教程

深度学习(CNN RNN GAN)算法原理

Java亿级流量电商系统视频教程

互联网架构师视频教程

年薪50万Spark2.0从入门到精通

年薪50万!人工智能学习路线教程

年薪50万!大数据从入门到精通学习路线年薪50万!机器学习入门到精通视频教程
仿小米商城类app和小程序视频教程深度学习数据分析基础到实战最新黑马javaEE2.1就业课程从 0到JVM实战高手教程 MySQL入门到精通教程
查看: 550|回复: 0

Android 游戏教程(五) - Android学习

[复制链接]

该用户从未签到

发表于 2011-10-26 19:24:45 | 显示全部楼层 |阅读模式
       这个系列的第五部分将讲述如何创建一个3D的物体。本实例中是一个具有四个面的三角锥。

       为了使我们今后的开发更简单,需要做一些准备。我们需要能够动态地计算缓冲区大小和创建数组。

java代码:
private int _nrOfVertices = 0;



private void initTriangle() {

float[] coords = {

// 坐标

};

_nrOfVertices = coords.length;



float[] colors = {

// 颜色

};



short[] indices = new short[] {

// 索引

};



// float has 4 bytes, coordinate * 4 bytes

ByteBuffer vbb = ByteBuffer.allocateDirect(coords.length * 4);

vbb.order(ByteOrder.nativeOrder());

_vertexBuffer = vbb.asFloatBuffer();



// short has 2 bytes, indices * 2 bytes

ByteBuffer ibb = ByteBuffer.allocateDirect(indices.length * 2);

ibb.order(ByteOrder.nativeOrder());

_indexBuffer = ibb.aSSHortBuffer();



// float has 4 bytes, colors (RGBA) * 4 bytes

ByteBuffer cbb = ByteBuffer.allocateDirect(colors.length * 4);

cbb.order(ByteOrder.nativeOrder());

_colorBuffer = cbb.asFloatBuffer();



_vertexBuffer.put(coords);

_indexBuffer.put(indices);

_colorBuffer.put(colors);



_vertexBuffer.position(0);

_indexBuffer.position(0);

_colorBuffer.position(0);

}
复制代码
       为了更动态一些,我们需要改变一些变量:
       在第一行可以看到我们给_nrOfVertices的初值为0因为它的值取决于第七行坐标数组的大小。另外我们将成员变量_indiceArray改为局部变量,该局部变量叫做indices,在第十三行初始化。

       缓冲区的创建移到了坐标数组,颜色数组和索引数组下面,因为缓冲区的大小依赖于这些数组的大小。请阅读相关的第17~18行,第22~23行,第27~28行,在注释中我解释清楚了其中的数学表示含义。
这样修改的好处是,我们可以创建更多的顶点而不必手动来修改关于顶点数量,数组和缓冲区大小等值。

       下一步,你必须理解OpenGL是如何绘制我们所看到的图形的。OpenGL ES相比OpenGL的一个缺陷就是它只支持三角形。因此为了创建多边形我们必须由三角形来搭建。

       现在我们想要创建一个多彩的三角锥,首先需要使依赖我们触摸事件的glClearColor()函数不再工作。因此我们需要移除变量_red, _green, _blue以及setColor()函数。

       我们也要改变转动的方向,因此我们把旋转分解到x,y两个轴上。

java代码:
public class VortexRenderer implements GLSurfaceView.Renderer {

private static final String LOG_TAG = VortexRenderer.class.getSimpleName();



// 一个缓冲区来保存绘图顶点的索引值

private ShortBuffer _indexBuffer;



// 一个缓冲区来保存顶点坐标

private FloatBuffer _vertexBuffer;



// 一个缓冲区来存储颜色

private FloatBuffer _colorBuffer;



private int _nrOfVertices = 0;



private float _xAngle;

private float _yAngle;



@Override

public void onSurfaceCreated(GL10 gl, EGLConfig config) {

// code snipped

}



@Override

public void onSurfaceChanged(GL10 gl, int w, int h) {

gl.glViewport(0, 0, w, h);

}



public void setXAngle(float angle) {

_xAngle = angle;

}



public float getXAngle() {

return _xAngle;

}



public void setYAngle(float angle) {

_yAngle = angle;

}



public float getYAngle() {

return _yAngle;

}

// code snipped
复制代码
        确保你的工程中有与我在类的开始定义的相同名称的变量。这里有两个float型变量来记录角度,xAngle,和_yAngle以及它们相应的设置函数以及获取函数。

java代码:
// code snipped



private float _x = 0;

private float _y = 0;



// code snipped



public boolean onTouchEvent(final MotionEvent event) {

if (event.getAction() == MotionEvent.ACTION_DOWN) {

_x = event.getX();

_y = event.getY();

}

if (event.getAction() == MotionEvent.ACTION_MOVE) {

final float xdiff = (_x - event.getX());

final float ydiff = (_y - event.getY());

queueEvent(new Runnable() {

public void run() {

_renderer.setXAngle(_renderer.getXAngle() + ydiff);

_renderer.setYAngle(_renderer.getYAngle() + xdiff);

}

});

_x = event.getX();

_y = event.getY();

}

return true;

}
复制代码
        当ACTION_DOWN事件发生时我们会设置它们的值,所以一旦我们在屏幕上移动手指,当前坐标与之前坐标的差值会计算出来。之后把这个差值添加到我们对象的角度变量中。第18~19行,你可以想象到,如果我们打算在x方向移动手指时物体会转动,那么它应该是围绕y轴进行旋转。在y方向移动手指,那么它应该是围绕x轴进行旋转。

       如果我们将手指移动到最左边或最上边,xdiff或者ydiff的值会是负值因此旋转会是逆向的。到此为止我们已经可以轻松是想2个坐标轴的旋转了。

       下面是最有趣的部分:三角锥。
       正如我们上面引用的那一部分所提到的一样,围绕(winding)需要一些设置。一些可能是默认的,但是我们仍然对它们进行设置以保证每个方面都按我们设想的进行。

java代码:
@Override

public void onSurfaceCreated(GL10 gl, EGLConfig config) {

// preparation

// 保证多边形只有一面可以被观察到

gl.glEnable(GL10.GL_CULL_FACE);

// 决定可以被观察到的那一面的顶点的绘制顺序(逆时针)

gl.glFrontFace(GL10.GL_CCW);

// 哪一面不用被观察到

gl.glCullFace(GL10.GL_BACK);



gl.glEnableClientState(GL10.GL_VERTEX_ARRAY);

gl.glEnableClientState(GL10.GL_COLOR_ARRAY);



initTriangle();

}
复制代码
        在第5行我们使能culling face以便总是显示一个面。在第7行我们定义前面(front)的绘图顶点顺序。设置为GL_CCW就意味着逆时针顺序。在第9行,我们定义哪一面为cull face,即不可以被观察到。我们设置为GL10.GL_BACK,这样前面就可以显示出来。可能有些混乱,如果你尝试用GL_FRONT_AND_BACK就可以看到什么都不会显示出来。

java代码:
@Override

public void onDrawFrame(GL10 gl) {

// 定义背景颜色

gl.glClearColor(0f, 0f, 0f, 1.0f);



// 重置矩阵

gl.glLoadIdentity();



//清除颜色缓冲区

gl.glClear(GL10.GL_COLOR_BUFFER_BIT);



// 设置旋转

gl.glRotatef(_xAngle, 1f, 0f, 0f);

gl.glRotatef(_yAngle, 0f, 1f, 0f);



//gl.glColor4f(0.5f, 0f, 0f, 0.5f);

gl.glVertexPointer(3, GL10.GL_FLOAT, 0, _vertexBuffer);

gl.glColorPointer(4, GL10.GL_FLOAT, 0, _colorBuffer);

gl.glDrawElements(GL10.GL_TRIANGLES, _nrOfVertices, GL10.GL_UNSIGNED_SHORT, _indexBuffer);

}
复制代码
        在第4行你可以看到我们的背景颜色是黑色的。在第13~14行是实现旋转的部分。剩下的部分和之前的部分类似。

       最后一个需要改动就是initTriangle()函数中的颜色数组,坐标数组以及索引数组。我们的三角锥是这样的:




java代码:
private void initTriangle() {

float[] coords = {

-0.5f, -0.5f, 0.5f, // 0

0.5f, -0.5f, 0.5f, // 1

0f, -0.5f, -0.5f, // 2

0f, 0.5f, 0f, // 3

};

_nrOfVertices = coords.length;



float[] colors = {

1f, 0f, 0f, 1f, // point 0 red

0f, 1f, 0f, 1f, // point 1 green

0f, 0f, 1f, 1f, // point 2 blue

1f, 1f, 1f, 1f, // point 3 white

};



short[] indices = new short[] {

0, 1, 3, // rwg

0, 2, 1, // rbg

0, 3, 2, // rbw

1, 2, 3, // bwg

};



//code snipped

}
复制代码
系列之Android 游戏教程(一)的帖子链接http://www.eoeandroid.com/thread-102096-1-1.html
系列之Android 游戏教程(二)的帖子链接http://www.eoeandroid.com/thread-102097-1-1.html
系列之Android 游戏教程(三)的帖子链接http://www.eoeandroid.com/thread-102100-1-1.html
系列之Android 游戏教程(四)的帖子链接http://www.eoeandroid.com/thread-103115-1-1.html
系列之Android 游戏教程(六)的帖子链接http://www.eoeandroid.com/thread-103121-1-1.html
系列之Android 游戏教程(七)的帖子链接http://www.eoeandroid.com/thread-103125-1-1.html

本帖子中包含更多资源

您需要 登录 才可以下载或查看,没有帐号?立即注册

x
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

QQ|手机版|Java学习者论坛 ( 声明:本站资料整理自互联网,用于Java学习者交流学习使用,对资料版权不负任何法律责任,若有侵权请及时联系客服屏蔽删除 )

GMT+8, 2025-1-11 20:50 , Processed in 0.344961 second(s), 37 queries .

Powered by Discuz! X3.4

© 2001-2017 Comsenz Inc.

快速回复 返回顶部 返回列表