gpt4 book ai didi

java - 渲染图 block Java Libgdx

转载 作者:行者123 更新时间:2023-12-02 05:30:35 25 4
gpt4 key购买 nike

我正在尝试渲染一个平铺 map ,每次游戏运行时都会生成随机图 block 。

我有一个数组,应该保存图 block 的所有值,然后随机更改:

int[][] map = {
{ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,},
{ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,},
{ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,},
{ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,},
{ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,},
{ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,},
{ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,},
{ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,},
{ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,},
};
for (int x = 0; x < map.length; x++) {
for (int y = 0; y < map[x].length; y++) {
if(map[x][y] == 0){
switch(MathUtils.random(2)){
case 0:
map[x][y] = 0;
break;
case 1:
map[x][y] = 1;
break;
case 2:
map[x][y] = 2;
break;
}
}
}
}

然后我根据图 block 的内容渲染它们:

public void render(float delta) {
Gdx.gl.glClear(GL20.GL_COLOR_BUFFER_BIT);
Gdx.gl.glClearColor(0f, 0f, 0f, 1f);
game.batch.begin();
for (int x = 0; x < map.length; x++) {
for (int y = 0; y < map[y].length; y++) {
if(map[x][y] == 1){
game.batch.draw(stone, x*120, y*120);
}
if(map[x][y] == 2){
game.batch.draw(grass, x*120, y*120);
}
if(map[x][y] == 0){
game.batch.draw(dirt, x*120, y*120);
}
}
}

问题:

  1. 所有渲染的图 block 都是污垢。
  2. 这确实会减慢一切。

最佳答案

2. It really slows everything down

这是由于您的 map 尺寸过大造成的:1920 x 1080 block 。如果每个图 block 均为 120 x 120 像素,则相当于 230,400 x 129,600 像素。渲染所有这些对于 OpenGL 来说不是问题,因为它会自动裁剪所有不可见的内容,并且 OpenGL 在确定可见性方面非常高效。但是在将其发送到批处理渲染器之前,您已经做了很多可以轻松避免的工作。

(以下代码片段可能不是正确的 Java。)

  1. 不要在内部绘图循环中使用if——甚至更好的switch。创建索引查找数组:

    Texture textures[] = { dirt, stone, grass };

    然后在循环内使用:

    game.batch.draw(textures[map[x][y]], x*120, y*120);
  2. 不要绘制整个 map 。计算当前视口(viewport)(屏幕上显示的 map 部分)并仅绘制它。
    维护一个坐标对 mapx,mapy 来保存屏幕上 map 的左上角坐标。移动该坐标对将使 map 在屏幕上移动。如果您希望“播放器”始终位于屏幕的正中央,可以像 mapx = (player_x - screen_width/2) 一样简单。请注意检查是否有超出范围的值。

    map 上可见的部分开始于

    int tile_xoffset = floor (mapx/120);
    int tile_yoffset = floor (mapy/120);

    向下舍入,因为如果 mapx119,您仍会看到 map[0][y] 的一像素 strip 。 (小注意:floor实际上是不必要的。当将浮点转换为整数时,Java会自动向下舍入。)

    120x120 map block 中可见部分的宽度(以及类似的高度)可以计算为

    screen_width/120

    但这只是可见的整个 map block 的数量。您还需要绘制仅部分可见的 block 的“边界”。

    更准确的计算应该是这样的(警告:未经测试!):

    int vis_width = (screen_width + (mapx % 120) + (120-(screen_width % 120)))/120;
  3. 一个好的通用原则是在内循环中进行尽可能少的计算。每个图 block 乘以 120 可以轻松地用加法代替。也没有必要对最内层循环内的xy都执行此操作。

  4. 完成上述所有计算后,检查 tile_xoffset 是否不小于 0,并且 tile_xoffset +visible_width 是否小于图 block map 的宽度;当然,y 部分也是如此。

<小时/>

将所有这些放在一起,您的 map 绘制代码应如下所示:

xp = (tile_xoffset*120) - mapx;
for (int x = 0; x < visible_width; x++)
{
yp = (tile_yoffset*120) - mapy;
for (int y = 0; y < visible_height; y++)
{
game.batch.draw(textures[map[x][y]], xp, yp);
yp += 120;
}
xp += 120;
}
<小时/>

要在此 map 上绘制字符,您可以将其坐标偏移-mapx,-mapy。如果您有很多额外的字符,则可以通过首先测试它们是否在可见边界内来获得另一个加速。

关于java - 渲染图 block Java Libgdx,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/25590777/

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