我目前正在制作一个程序,用程序生成2d地形图,在尺寸定义的图像上使用不同的技术,如perlin噪声,单形,voronoi,分形噪声等,以便能够在我需要的游戏中使用它2d地形。
我遇到http://paulbourke.net/fractals/noise的“建模假行星”部分,我需要在2d纹理上制作它,而不是像解释的那样在3D世界上。
现在我正在尝试
这会以这种方式运作:
使用以下方法覆盖,
http://img35.imageshack.us/img35/24/islf.png
我利用我的高中数学能力来创建代码示例,但它并没有真正起作用......
问题:
Java文件: 如果我需要一个关于我将如何进行的例子,这里是:
package Generator;
import java.awt.Color;
import java.awt.Dimension;
import java.awt.Graphics;
import java.awt.image.BufferedImage;
import java.util.Random;
import VectorialStuffs.Vector2;
public class Linear
{
public static BufferedImage generateImage(Dimension dim, int iterations)
{
BufferedImage image = new BufferedImage(dim.width, dim.height, BufferedImage.TYPE_INT_ARGB);
//point X and point Y
Vector2 pointX;
Vector2 pointY;
//difference between those
Vector2 diff;
Vector2 side;
double slope;
//random
Random rand = new Random();
boolean direction; //the orientation of the dark zone. (left/right)
for (int i = 0; i < iterations; ++i)
{
pointX = new Vector2(0, 0);
pointY = new Vector2(0, 0);
direction = rand.nextBoolean();
System.out.println(direction);
side = new Vector2(0, 0); //there are 4 sides of the image.
while (side.x == side.y)
{
side.x = rand.nextInt(3); //0 - 1 - 2 - 3
side.y = rand.nextInt(3);
}
switch(side.x) //not the x coord, the X point! ;D
{
//x = random and y = 0
case 0:
pointX.x = rand.nextInt(dim.width);
pointX.y = 0;
break;
//x = max and y = random
case 2:
pointX.x = dim.width;
pointX.y = rand.nextInt(dim.height);
break;
//x = random and y = max
case 1:
pointX.x = rand.nextInt(dim.width);
pointX.y = dim.height;
break;
//x = 0 and y = random
case 3:
pointX.x = 0;
pointX.y = rand.nextInt(dim.height);
break;
}
switch(side.y) //not the y coord, the Y point! ;D
{
//x = random and y = 0
case 0:
pointY.x = rand.nextInt(dim.width);
pointY.y = 0;
break;
//x = max and y = random
case 2:
pointY.x = dim.width;
pointY.y = rand.nextInt(dim.height);
break;
//x = random and y = max
case 1:
pointY.x = rand.nextInt(dim.width);
pointY.y = dim.height;
break;
//x = 0 and y = random
case 3:
pointY.x = 0;
pointY.y = rand.nextInt(dim.height);
break;
}
diff = new Vector2((pointY.x - pointX.x), (pointY.y - pointX.y));
slope = diff.y / diff.x;
Graphics graph = image.getGraphics();
if (direction) //true = right | false = left
{
int start; //the start x coordinate, on the line then increases until reaching the end of the image
int end = dim.width;
graph.setColor(Color.red);
graph.fillRect(pointX.x - 8, pointX.y -8, 16, 16);
graph.setColor(Color.yellow);
graph.fillRect(pointY.x - 8, pointY.y -8, 16, 16);
for (int times = 0; times < dim.height; ++times) //horizontal drawer
{
System.out.println(times);
start = (int)((times-diff.y)/slope + diff.y); //this is where it goes wrong?
for (int value = start; value < end; ++value)
{
graph.setColor(new Color(rand.nextInt(255), rand.nextInt(255), rand.nextInt(255), 100));
graph.fillRect(value, times, 1, 1);
}
}
graph.dispose();
}
else
{
int start; //the start x coordinate, on the line then increases until reaching the end of the image
int end = dim.width;
graph.setColor(Color.red);
graph.fillRect(pointX.x - 8, pointX.y -8, 16, 16);
graph.setColor(Color.yellow);
graph.fillRect(pointY.x - 8, pointY.y -8, 16, 16);
for (int times = 0; times < dim.height; ++times) //horizontal drawer
{
System.out.println(times);
start = (int)((times-diff.y)/slope);
for (int value = end; value < start; --value)
{
graph.setColor(new Color(rand.nextInt(255), rand.nextInt(255), rand.nextInt(255), 100));
graph.fillRect(value, times, 1, 1);
}
}
graph.dispose();
}
}
return image;
}
}
注意: 在这种情况下,vector2只是一个带有X和Y的类,可以访问它(这可能是暂时的)。
启动部分,以避免您浪费时间:
terrainImage = Linear.generateImage(size, 1); //size being a Dimension. -> "new Dimension(256, 256)"
if (terrainImage != null)
{
Icon wIcon = new ImageIcon(terrainImage);
JOptionPane.showMessageDialog(null, "message", "title", JOptionPane.OK_OPTION, wIcon);
}
//修改 这是需要改进的代码:
if (direction) //true = right | false = left
{
int start; //the start x coordinate, on the line then increases until reaching the end of the image
int end = dim.width;
graph.setColor(Color.red);
graph.fillRect(pointX.x - 8, pointX.y -8, 16, 16);
graph.setColor(Color.yellow);
graph.fillRect(pointY.x - 8, pointY.y -8, 16, 16);
for (int times = 0; times < dim.height; ++times) //horizontal drawer
{
System.out.println(times);
start = (int)((times-diff.y)/slope + diff.y); //this is where it goes wrong?
for (int value = start; value < end; ++value)
{
graph.setColor(new Color(rand.nextInt(255), rand.nextInt(255), rand.nextInt(255), 100));
graph.fillRect(value, times, 1, 1);
}
}
graph.dispose();
}
else
{
int start; //the start x coordinate, on the line then increases until reaching the end of the image
int end = dim.width;
graph.setColor(Color.red);
graph.fillRect(pointX.x - 8, pointX.y -8, 16, 16);
graph.setColor(Color.yellow);
graph.fillRect(pointY.x - 8, pointY.y -8, 16, 16);
for (int times = 0; times < dim.height; ++times) //horizontal drawer
{
System.out.println(times);
start = (int)((times-diff.y)/slope);
for (int value = end; value < start; --value)
{
graph.setColor(new Color(rand.nextInt(255), rand.nextInt(255), rand.nextInt(255), 100));
graph.fillRect(value, times, 1, 1);
}
}
graph.dispose();
}
我不能像上面的图片中所示那样工作,它所做的一切都是没有,或偏离2点。 此外,有时它会无缘无故地冻结,所以如果我对此进行更多迭代会发生什么:/
答案 0 :(得分:1)
代码的模式生成元素应该只占用大约3行,包括旋转,颜色模式调制以及所有迭代的函数。
我会尽力明白:
你不需要一个条形图/直线来生成地图,你需要在一个/两个轴上的任何图案,这些图案从地图的一半周期开始,并且得到的地图越来越小或者更小而且时间较短。
图案:
一条线是圆的(x);或圆形(x + y)或圆形(sin(x + y +平移条)+条形宽度)&lt; - 中间不仅仅是侧面的真实条形// 你可以使用X和Y函数的加法和乘法来制作曲线和曲折线以及2D线。该函数基本上只是一行,您可以将其更改为X值以便旋转。
旋转:
而不是每次产生垂直线时的功能X,你需要使用正弦和共窦函数来产生X和Y值。
4例30;旋转是:圆形(X * 0.866+ Y * 0.5)
获取随机值的正弦和余弦,它将为您提供模式的随机旋转,方便的是您只需对循环迭代进行随机值并将其发送到符号余弦。
好的我会用伪代码写这个会更简单:
var pattern = 0; // black canvas
for(var i=1; i=100; i++)
{
pattern += round((sin (X*sin(pseudorand(i)) + Y*cos(pseudorand(i)) + translation) + roundshift )*strength;
}
上述循环将通过添加不同旋转的条形图来生成数千个地图模式。
Round =量化你的sin(XY)函数,因此它只是黑色和白色/红色灰色。
Sin(XY)=用作模式的变量函数,通过舍入到0/1值进行量化...乘以并将该值钳制在同一行中,使其不超过1或0
roundshift =圆形(sin)模式内的值,它将sin在圆值内向下或向上移动,从而导致每次迭代的黑/白比例更小或更大。它是i的倍数,因此它是i的函数,每个循环都会变小。
xsin(rnd i)ycos(rnd i)=旋转你的模式rnd's必须是相同的数字。
翻译值=当你+/-一个数字到一个Sin(x +翻译)。它向后/向前移动
最后你的模式值将等于maxiumum 100,所以偏差为100,因此对于256来说它是0-1或者多为2.56,并且使用颜色随机函数来生成模式值的RGB随机倍数。
对于每个像素x y,上面的循环显然需要运行一次。
我不知道如何在JS中使用canvas数组/纹理插件像素,应该很容易。
上面的代码会给你很好的模式和你的错误的视觉反馈,所以你应该能够很好地完善它,只考虑我错过了钳位到sin(-1 1)+轮回结果的0-1值。
所以一个圆形是圆形的(sin(xy)+平移),你可以使用许多xy添加的muptiplied sins的函数来将其他所有东西加在一起,而不是条形图形,图形圆形,正方形,摆动,椭圆形,矩形等。 / p>
有一个网站都是关于这种类型的模式,除了有序角度和说5-6次迭代,使用点条三角形等,他是加拿大人和异常艺术品,如果没有那么多TD模式生成我可以找到他的网站!
答案 1 :(得分:0)
这是一个网站,解释了“模式打桩”的过程,它在越来越小的迭代中覆盖了许多形状。
唯一的区别是他使用有序旋转来创建对称性,并且您希望随机旋转来创建混沌贴图。
在2d看到所有堆积模式的照片,他有许多关于异常艺术及其网站的例子,我从这个人那里学到了很多:
http://algorithmic-worlds.net/info/info.php?page=pilpat 这里是对称旋转中叠加越来越小的模式的更多工作: https://www.google.com/search?q=Samuel+Monnier&espv=210&es_sm=93&source=lnms&tbm=isch&sa=X&ei=It0AU9uTCOn20gXXv4G4Cw&ved=0CAkQ_AUoAQ&biw=1365&bih=911
与使用随机sin cos旋转相同。