Generate Worms Style Terrain, Perlin Noise in XNA
Have been testing what Microsofts XNA framework can do and am toying with the idea of making some sort of Worms style game. Spent a few minutes today googling on how one can generate the terrain for such a game and found a few pages which explained parts of it but no place really contained any good working examples.
So after spending a few hours with the examples I could find I came up with an algorithm which works pretty well.
Here is an example of what the code generates:
This is example terrain was generated in about 2 second.
Here is the code:
using System;
using System.Collections.Generic;
using Microsoft.Xna.Framework.Graphics;
using Microsoft.Xna.Framework;
namespace TankersTD.Tankers.Tools
{
class TerrainGenerator
{
private double initFrequency, initAmplitude, persistance;
private int octaves, seed;
public Texture2D generateTerrain(GraphicsDevice gd,
int width, int height, double ammountofearth,
double initFrequency, double initAmplitude, double persistance, int octaves )
{
this.initFrequency = initFrequency;
this.initAmplitude = initAmplitude;
this.persistance = persistance;
this.octaves = octaves;
seed = System.DateTime.Now.Millisecond;
Texture2D result = new Texture2D(gd, width, height);
Color[] cData = new Color[width * height];
int t_he = 1, t_wi = 1;
for (int x = 1; x < width*height; x++)
{
if (t_wi > width)
{
t_he++;
t_wi = 1;
}
double val = Function2D((double)t_wi, (double)t_he);
if (val > (ammountofearth*-1))
cData[x] = Color.Black;
t_wi++;
}
result.SetData(cData);
return result;
}
// returns the Perlin Noise value for the given coordinate
private double Function2D(double x, double y)
{
double frequency = initFrequency;
double amplitude = initAmplitude;
double sum = 0;
for ( int i = 0; i < octaves; i++ )
{
sum += SmoothedNoise( x * frequency, y * frequency ) * amplitude;
frequency *= 2;
amplitude *= persistance;
}
return sum;
}
private double Noise( int x, int y )
{
int n = x + y * 57;
n = ( n << 13 ) ^ n ;
return (1.0 - ((n * (n * n * (15731 + seed) + 789221- seed) + 1376312589) &amp;amp; 0x7fffffff) / 1073741824.0);
}
private double SmoothedNoise( double x, double y )
{
int xInt = (int) x;
int yInt = (int) y;
double xFrac = x - xInt;
double yFrac = y - yInt;
double x0y0 = Noise( xInt , yInt );
double x1y0 = Noise( xInt + 1, yInt );
double x0y1 = Noise( xInt , yInt + 1 );
double x1y1 = Noise( xInt + 1, yInt + 1) ;
double v1 = CosineInterpolate( x0y0, x1y0, xFrac );
double v2 = CosineInterpolate( x0y1, x1y1, xFrac );
return CosineInterpolate( v1, v2, yFrac );
}
private double CosineInterpolate( double x1, double x2, double a )
{
double f = ( 1 - Math.Cos( a * Math.PI ) ) * 0.5;
return x1 * ( 1 - f ) + x2 * f;
}
}
}
The code is used like this (the picture above was generated using these input variables):
TerrainGenerator terraingenerator = new TerrainGenerator();
Texture2D ter = terraingenerator.generateTerrain(
graphics.GraphicsDevice, 2048, 1024, -0.1, 0.0225, .5, 0.05, 1);
Here are a couple of related pages that may interest you:
- Project: Blinky – Sound Level Warning
My office recently moved from a building in which the rooms were were quite small and only...
2 Responses to Generate Worms Style Terrain, Perlin Noise in XNA
Leave a Reply Cancel reply
Tags
550d ads Audi backburner Billboard BMW C# competition Computers/Servers contract Dragster EXSi false advertisement gaining knowledge gallery haldex helsingborg Hobbies hobby Hovercraft Java kraken Lundalogik marketing Motorsports overview photo photos Programming Programs Racing RC recreation rendering machine sailing server servers systeam Thesis thesis search Trainee Veidec Virtualization VMWare Work







I’m also looking for somtehing like this for a upcomming “project”, have yout thought about just generating random circles to make the terrain? Wouldent that be faster?
The thought actually crossed my mind for the exact reason you mention, performance, but after testing it a bit I still went for the Perlin Noise method. When I tried it I actually used ellipses instead of circles and placed them randomly on the texture. Every second ellipse i placed generated terrain and the other removed whatever terrain was under it. It dident look very natural though and you could very much see that it was a bunch of ellipses added and subtracted to get the result.
This method may take a bit longer but I think its worth it.