gpt4 book ai didi

android - 生成图 block 的更好方法

转载 作者:行者123 更新时间:2023-11-30 04:53:03 25 4
gpt4 key购买 nike

首先我会说我是 OpenGL ES 的新手(我昨天开始 =),但我确实有一些 Java 和其他语言的经验。

我看了很多教程,当然是Nehe的,我的工作主要是基于那个。

作为测试,我开始创建一个“图 block 生成器”,以创建一个类似于塞尔达传说的小型游戏(只需在带纹理的正方形中移动一个家伙就很棒了:p)。

到目前为止,我已经实现了一个可用的图 block 生成器,我定义了一个 char map[][] 数组来存储图 block :

private char[][] map = {
{0, 0, 20, 11, 11, 11, 11, 4, 0, 0},
{0, 20, 16, 12, 12, 12, 12, 7, 4, 0},
{20, 16, 17, 13, 13, 13, 13, 9, 7, 4},
{21, 24, 18, 14, 14, 14, 14, 8, 5, 1},
{21, 22, 25, 15, 15, 15, 15, 6, 2, 1},
{21, 22, 23, 0, 0, 0, 0, 3, 2, 1},
{21, 22, 23, 0, 0, 0, 0, 3, 2, 1},
{26, 0, 0, 0, 0, 0, 0, 3, 2, 1},
{0, 0, 0, 0, 0, 0, 0, 0, 0, 1},
{0, 0, 0, 0, 0, 0, 0, 0, 0, 1}
};

它正在工作,但我对此并不满意,我相信有更好的方法来做这些事情:

1) 加载纹理:

我创建了一个丑陋的数组,其中包含我想在该 map 上使用的图 block :

private int[] textures = {
R.drawable.herbe, //0
R.drawable.murdroite_haut, //1
R.drawable.murdroite_milieu, //2
R.drawable.murdroite_bas, //3
R.drawable.angledroitehaut_haut, //4
R.drawable.angledroitehaut_milieu, //5
};

(我故意剪掉的,我目前加载了 27 个图 block )

所有这些都存放在drawable文件夹中,每一个都是一个16*16的tile。

然后我使用这个数组生成纹理并将它们存储在 HashMap 中供以后使用:

int[] tmp_tex = new int[textures.length]; 
gl.glGenTextures(textures.length, tmp_tex, 0);
texturesgen = tmp_tex; //Store the generated names in texturesgen
for(int i=0; i < textures.length; i++)
{
//Bitmap bmp = BitmapFactory.decodeResource(context.getResources(), textures[i]);
InputStream is = context.getResources().openRawResource(textures[i]);
Bitmap bitmap = null;
try {
//BitmapFactory is an Android graphics utility for images
bitmap = BitmapFactory.decodeStream(is);

} finally {
//Always clear and close
try {
is.close();
is = null;
} catch (IOException e) {
}
}
// Get a new texture name
// Load it up
this.textureMap.put(new Integer(textures[i]),new Integer(i));
int tex = tmp_tex[i];
gl.glBindTexture(GL10.GL_TEXTURE_2D, tex);
//Create Nearest Filtered Texture
gl.glTexParameterf(GL10.GL_TEXTURE_2D, GL10.GL_TEXTURE_MIN_FILTER, GL10.GL_NEAREST);
gl.glTexParameterf(GL10.GL_TEXTURE_2D, GL10.GL_TEXTURE_MAG_FILTER, GL10.GL_LINEAR);

//Different possible texture parameters, e.g. GL10.GL_CLAMP_TO_EDGE
gl.glTexParameterf(GL10.GL_TEXTURE_2D, GL10.GL_TEXTURE_WRAP_S, GL10.GL_REPEAT);
gl.glTexParameterf(GL10.GL_TEXTURE_2D, GL10.GL_TEXTURE_WRAP_T, GL10.GL_REPEAT);

//Use the Android GLUtils to specify a two-dimensional texture image from our bitmap
GLUtils.texImage2D(GL10.GL_TEXTURE_2D, 0, bitmap, 0);

bitmap.recycle();
}

我很确定有更好的方法来处理这个……我只是想不出来。如果有人有想法,我会洗耳恭听。

2) 绘制方 block

我所做的是创建一个正方形和一个纹理贴图:

/** The initial vertex definition */
private float vertices[] = {
-1.0f, -1.0f, 0.0f, //Bottom Left
1.0f, -1.0f, 0.0f, //Bottom Right
-1.0f, 1.0f, 0.0f, //Top Left
1.0f, 1.0f, 0.0f //Top Right
};

private float texture[] = {
//Mapping coordinates for the vertices
0.0f, 1.0f,
1.0f, 1.0f,
0.0f, 0.0f,
1.0f, 0.0f

};

然后,在我的绘制函数中,我遍历 map 以定义要使用的纹理(在指向并启用缓冲区之后):

for(int y = 0; y < Y; y++){
for(int x = 0; x < X; x++){
tile = map[y][x];
try
{
//Get the texture from the HashMap
int textureid = ((Integer) this.textureMap.get(new Integer(textures[tile]))).intValue();
gl.glBindTexture(GL10.GL_TEXTURE_2D, this.texturesgen[textureid]);
}
catch(Exception e)
{
return;
}

//Draw the vertices as triangle strip
gl.glDrawArrays(GL10.GL_TRIANGLE_STRIP, 0, vertices.length / 3);
gl.glTranslatef(2.0f, 0.0f, 0.0f); //A square takes 2x so I move +2x before drawing the next tile
}
gl.glTranslatef(-(float)(2*X), -2.0f, 0.0f); //Go back to the begining of the map X-wise and move 2y down before drawing the next line
}

这很好,因为我真的认为在 1000*1000 或更大的 map 上,它会非常滞后(作为提醒,这是一个典型的塞尔达世界地图:http://vgmaps.com/Atlas/SuperNES/LegendOfZelda-ALinkToThePast-LightWorld.png)。

我已经阅读了有关顶点缓冲区对象和显示列表的内容,但我找不到好的教程,而 nodoby 似乎可以确定哪个是最好的/具有更好的支持(T1 和 Nexus One 已经很久了)。

我想就是这样,我已经输入了很多代码,但我认为它有帮助。

提前致谢!

最佳答案

一些事情:

  1. 无需使用 HashMap ,只需使用向量/列表即可。
  2. 拥有一个包含所有图 block 的大纹理可能会更快/更容易。使用适当的纹理坐标来选择适当的图 block 。您可能需要注意此处的纹理过滤。听起来您正在玩 2D 游戏,在这种情况下,您可能希望对图 block 使用最近邻过滤并将相机固定在整数像素位置。
  3. 使用 GL_QUADS 会不会比使用 GL_TRIANGLE_STRIP 更容易。不确定您那里的代码 - 您似乎没有使用“纹理”数组。
  4. 只要您不绘制不在屏幕上的图 block , map 大小应该不会有任何区别。你的代码应该是这样的:

.

int minX = screenLeft / tileSize;
int minY = screenBottom / tileSize;
int maxX = screenRight / tileSize;
int maxY = screenTop / tilesSize;
for (int x = minX; x <= maxX; ++x)
{
for (int y = minY; y < maxY; ++y)
{
...

关于android - 生成图 block 的更好方法,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/2444411/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com