- iOS/Objective-C 元类和类别
- objective-c - -1001 错误,当 NSURLSession 通过 httpproxy 和/etc/hosts
- java - 使用网络类获取 url 地址
- ios - 推送通知中不播放声音
我正在制作分形地形,但无论尝试什么,它总是看起来完全随机。我一直在遵循 Diamonds and Squares 算法,如解释的那样 here .我该怎么做才能解决这个问题?
这是我的地形类:
package game;
import java.util.Random;
public class Terrain {
Panel panel;
public Terrain(Panel panel) {
this.panel = panel;
generateTerrain();
}
private void generateTerrain() {
Random rand = new Random();
int seed = rand.nextInt(panel.colors.length);
int sideLength = panel.mapSize - 1;
int halfSideLength;
int average;
panel.map[0][0] = seed;
panel.map[panel.mapSize - 1][0] = seed;
panel.map[0][panel.mapSize - 1] = seed;
panel.map[panel.mapSize - 1][panel.mapSize - 1] = seed;
while (sideLength > 0) {
halfSideLength = sideLength / 2;
for (int x = 0; x < panel.mapSize - 1; x += sideLength) {
for (int y = 0; y < panel.mapSize - 1; y += sideLength) {
average = panel.map[x][y]
+ panel.map[x + sideLength][y]
+ panel.map[x][y + sideLength]
+ panel.map[x + sideLength][y + sideLength];
average /= 4;
average += rand.nextInt(8);
panel.map[x + halfSideLength][y + halfSideLength] = average;
}
}
for (int x = 0; x < panel.mapSize - 1; x += sideLength) {
for (int y = 0; y < panel.mapSize - 1; y += sideLength) {
average = panel.map[x][y]
+ panel.map[x + halfSideLength][y]
+ panel.map[x][y + sideLength]
+ panel.map[x + halfSideLength][y + halfSideLength];
average /= 4;
panel.map[x][y] = average;
if (x == 0) {
panel.map[panel.mapSize - 1][y] = average;
}
if (y == 0) {
panel.map[x][panel.mapSize - 1] = average;
}
}
}
sideLength /= 2;
}
}
}
这是我的面板类:
package game;
import javax.swing.*;
import java.awt.*;
import java.awt.event.*;
public class Panel extends JPanel implements ActionListener {
Terrain currentTerrain;
boolean upPressed = false;
boolean rightPressed = false;
boolean downPressed = false;
boolean leftPressed = false;
int tileSize = 1;
int mapSize = 1025;
int deltaX = 0;
int deltaY = 0;
int x = 0;
int y = 0;
int map[][] = new int[mapSize][mapSize];
Color[] colors = {
new Color(0, 0, 180),
new Color(0, 0, 255),
new Color(0, 150, 255),
new Color(255, 255, 180),
new Color(220, 220, 120),
new Color(200, 200, 60),
new Color(0, 200, 0),
new Color(0, 180, 0),
new Color(0, 160, 0),
new Color(0, 140, 0),
new Color(0, 120, 0),
new Color(0, 100, 0),
new Color(0, 80, 0),
new Color(0, 60, 0),
new Color(0, 40, 0),
new Color(40, 40, 40),
new Color(60, 60, 60),
new Color(80, 80, 80),
new Color(100, 100, 100),
new Color(120, 120, 120),
new Color(255, 255, 255)
};
public Panel(Main main) {
setPreferredSize(main.getSize());
setFocusable(true);
setBackground(Color.WHITE);
add(new KeyBindings(this));
currentTerrain = new Terrain(this);
new Timer(1000 / 120, this).start();
}
private void tick() {
if (upPressed) {
deltaY += 10;
} else if (downPressed) {
deltaY -= 10;
}
if (rightPressed) {
deltaX -= 10;
} else if (leftPressed) {
deltaX += 10;
}
repaint();
}
@Override
public void actionPerformed(ActionEvent e) {
tick();
}
@Override
public void paintComponent(Graphics g) {
super.paintComponent(g);
x = 0;
y = 0;
for (int[] rowData : map) {
for (int cellData : rowData) {
int v = cellData;
if(v < 0) {
v = 0;
} else if(v > colors.length - 1) {
v = colors.length - 1;
}
g.setColor(colors[v]);
g.fillRect(x + deltaX, y + deltaY, tileSize, tileSize);
x += tileSize;
if(x == mapSize * tileSize) {
x = 0;
y += tileSize;
}
}
}
}
}
最佳答案
您弄错了算法的钻石阶段。菱形的中心是正方形边的中点。它们最好在两个单独的循环中处理:一个用于垂直中点,第二个用于水平中点。在 map 的边缘,钻石的尖端会伸出 map 。您可以通过将它们“折叠”到 map 中来解决这个问题,例如在左边,右边的点会被考虑两次。
所以代码应该是:
function generateTerrain() {
int seed = rand.nextInt(colors.length);
int sideLength = mapSize - 1;
int halfSideLength;
int average;
int offset = 8;
map[0][0] = seed;
map[mapSize - 1][0] = seed;
map[0][mapSize - 1] = seed;
map[mapSize - 1][mapSize - 1] = seed;
while (sideLength > 0) {
halfSideLength /= 2;
for (int x = 0; x < mapSize - 1; x += sideLength) {
for (int y = 0; y < mapSize - 1; y += sideLength) {
average = map[x][y]
+ map[x + sideLength][y]
+ map[x][y + sideLength]
+ map[x + sideLength][y + sideLength];
average /= 4;
average += rand.nextInt(offset);
map[x + halfSideLength][y + halfSideLength] = average;
}
}
for (int x = 0; x < mapSize - 1; x += sideLength) {
for (int y = 0; y < mapSize; y += sideLength) {
int yTop = y - halfSideLength;
int yBottom = y + halfSideLength;
if (yTop < 0) yTop = y + halfSideLength;
if (yBottom > mapSize - 1) yBottom = y - halfSideLength;
average = map[x][y]
+ map[x + sideLength][y]
+ map[x + halfSideLength][yTop]
+ map[x + halfSideLength][yBottom];
average = /= 4;
map[x + halfSideLength][y] = average;
}
}
for (int x = 0; x < mapSize; x += sideLength) {
for (int y = 0; y < mapSize - 1; y += sideLength) {
int xLeft = x - halfSideLength;
int xRight = x + halfSideLength;
if (xLeft < 0) xLeft = x + halfSideLength;
if (xRight > mapSize - 1) xRight = x - halfSideLength;
average = map[x][y]
+ map[x][y + sideLength]
+ map[xRight][y + halfSideLength]
+ map[xRight][y + halfSideLength];
average /= 4;
map[x][y + halfSideLength] = average;
}
}
sideLength /= 2;
}
}
(注意:我已经从你的代码开始工作,但是将它转换成 Javascript 并转换回来,所以它可能仍然存在一些 Java 错误。但我认为这两个循环的想法很清楚。)
这会产生非常嘈杂的 map 。通常,每次将边长减半时,随机偏移量(代码中的 8)都会减少一个常数。 map 的平滑度可以通过这个参数来控制,玩起来很有趣。在您的例子中,参数是 1.0。逼真的 map 的一个很好的系数是 0.65 左右。
您的方法还有另一个问题:您始终使用窄整数。我在这里使用“窄”是指整数的粒度,即 1,等于 map 中的颜色变化。这并没有为一种颜色内的随机变化提供很大的范围。最好使用 float 或范围更广的整数来生成 map ,然后将这些值映射到您的颜色。
例如,假设您使用介于 0.0 和 1.0 之间的 float :然后您可以将低于 0.1 的值映射为深绿色,将低于 0.2 的值映射为浅绿色,依此类推,直到高于 0.9 的值变为白色。这将提供更平滑的带状外观,如您链接的文章部分下方的云图片。
另一件事是,您从拐角处的随机值开始,然后在打印 map 时将值限制在颜色范围内。您添加的随机偏移量始终为正,因此如果您从“高”颜色开始,您很可能会得到一张大部分为白色的图片。事实上,您不会得到任何低于起始值的颜色。您可以从中间颜色开始,并允许负随机偏移和正随机偏移来避免这种情况。或者,您可以在生成 map 后根据最低值和最高值对其进行归一化。
关于java - 菱形和正方形算法不起作用,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/30228244/
我试图使用 显示正方形(如元素符号正方形) .squares{ list-style-type: square; display:inline; } 但我希望它们是水
这是关于在作为 4 个 div 的一部分的 1 个 div 中嵌套 4 个 div(正方形)... 我在包装器中使用 display: flex 并用于包装的元素本身,否则它不会工作 对我来说,这感觉
这是图像,我想填充此矩形或正方形的边缘,以便可以使用轮廓对其进行裁剪。到目前为止,我所做的是我使用了canny边缘检测器来找到边缘,然后使用bitwise_or或将这个矩形填充了一点,但没有完全填充。
我希望能够在图片框内创建 X x Y 数量的框/圆圈/按钮。完全像 Windows 碎片整理工具。 我尝试创建一个布局并不断向其添加按钮或图片框,但速度非常慢,在添加 200 个左右的图片框后它崩溃,
我正在尝试从图像(肺部图像)中提取 3 个区域,这些区域在软组织中显示,每个区域都是具有特定高度和宽度的正方形,例如宽高各10mm,如下图, 如图所示,该区域也是均匀的,这意味着它只包含相同的颜色(在
在我左键单击它后,我试图让一个正方形跟随我的鼠标。当我右键单击时,方 block 应该停止跟随我的鼠标。 我的程序检测到我在方 block 内单击,但由于某种原因,它没有根据 Mouse.getDX/
已经花了几个小时在这上面了(因为我还在学习),所以也许你们可以帮忙。问题是我无法弄清楚如何将二维数组划分为所有可能的 nxn 正方形。 我正在随机化二维数组,可以说它是这样的: 1 0 1 0 2
使用 Graph API,我可以获得小型、大型、中型图片。或者我可以获得小方形图片。 但是我怎样才能得到大方形图片呢?有什么服务可以使用吗? 最佳答案 很简单,我刚发现这个。 例子, https://
我是 HTML 和 CSS 的新手。 尝试创建 3 x 3 正方形“图片”,使用 ,但无法找到将正方形放在页面中间的简单解决方案,例如中间有九个正方形。 如何把所有的方 block 都放在大边框的正方
我正在玩弄 CSS 动画以获得乐趣。我有限的经验阻碍了这一进程。 下面的脚本将圆形转换为三 Angular 形,再转换为正方形,然后反转。然而,圆形和三 Angular 形之间的动画有一个小错误。我希
我的标准布局(最小宽度 1024 像素)有 4 行。第一个和最后一个有 6 个正方形,中间有两个组合正方形。但是第三行的第一个方 block 不见了。我没有使用不同的 CSS 设置。我试过 clear
关闭。这个问题需要更多focused .它目前不接受答案。 想改进这个问题吗? 更新问题,使其只关注一个问题 editing this post . 关闭 7 年前。 Improve this q
我的网站上有 4 张图片,我试图对其进行定位,以便它们在我的 DIV 中形成一个相等的正方形,但它看起来像一条由 4 张图片组成的垂直线。我希望它看起来像 2 个图像的 2 条垂直线,彼此相邻,使其成
这是方 block 检测示例的输出我的问题是过滤这个方 block 第一个问题是它为同一区域绘制多条线; 第二个是我只需要检测对象而不是所有图像。 另一个问题是我必须只取除所有图像之外的最大对象。 检
我正在绘制一个带有移动立方体(正方形,因为它是 2d)算法的元球。一切都很好,但我想将其作为矢量对象获取。 到目前为止,我已经从每个事件方 block 中得到一两条矢量线,将它们保存在列表线中。换句话
实际上,我有一个适用于 Android 1.5 的应用程序,其中包含一个 GLSurfaceView 类,它在屏幕上显示一个简单的方形多边形。 我想学习如何添加一个新功能,即移动用手指触摸的方 blo
如果我有一个包含多个子组件的 JPanel,我该如何使 JPanel 保持正方形,而不管其父组件的大小如何调整?我尝试了以下代码的变体,但它不会导致子组件也变成正方形。 public void pai
我找到了 this answer ,它确保 ImageView 的宽高比得以保留。 我如何使用带有可绘制背景的 TextView 来做到这一点?我有这个 TextView: 这是我的背
这个问题在这里已经有了答案: Maintain aspect ratio of a div according to height [duplicate] (1 个回答) 关闭 8 年前。 是否可以
如何创建 div Logo ,如下图所示: 这是我在 JsFiddle 中创建的 主要问题是如何将两个形状如下图的盒子连接起来,有人可以提出建议吗? body,html { width: 100%
我是一名优秀的程序员,十分优秀!