Welcome, Guest. Please login or register.

Login with username, password and session length

 
Advanced search

1411469 Posts in 69368 Topics- by 58422 Members - Latest Member: daffodil_dev

April 23, 2024, 04:47:49 AM

Need hosting? Check out Digital Ocean
(more details in this thread)
TIGSource ForumsDeveloperTechnical (Moderator: ThemsAllTook)implimenting a procedurally generated height map
Pages: [1]
Print
Author Topic: implimenting a procedurally generated height map  (Read 2125 times)
Codestar
Level 1
*

One man, one game


View Profile WWW
« on: March 06, 2015, 10:33:15 AM »



Here's a current screenshot of my game, "Mine to the sky". My game builds levels using 32 x 32 tile templates and compiles them into a 2D array that is 128 x 128, like the image attached below. This array holds values of 0(air) and 1(dirt).


Really want to add different harder to break types of dirt blocks to the existing generated levels, but I'm having some trouble with trying to generate a height map from an existing 2D Array. I'm not sure how I could generate a height map with the existing 2D array "Mask".

I'd like to figure out how to do something like this with the dirt blocks, but figuring out how to do it with an array that's already been generated is a big headache.


Basically lets say I have a map like this, but with a more randomized pattern.
[
    [0, 0, 0, 0, 0, 0, 0, 0, 0],
    [0, 1, 1, 1, 1, 1, 1, 1, 0],
    [0, 1, 1, 1, 1, 1, 1, 1, 0],
    [0, 1, 1, 1, 1, 1, 1, 1, 0],
    [0, 1, 1, 1, 1, 1, 1, 1, 0],
    [0, 1, 1, 1, 1, 1, 1, 1, 0],
    [0, 1, 1, 1, 1, 1, 1, 1, 0],
    [0, 0, 0, 0, 0, 0, 0, 0, 0]
]

How would I make it so it had a "peak" in it's data that gradually sloped down until it hit "air"?
Something like this, but with a more randomized pattern.

[
    [0, 0, 0, 0, 0, 0, 0, 0, 0],
    [0, 1, 1, 1, 1, 1, 1, 1, 0],
    [0, 1, 2, 2, 2, 2, 2, 2, 0],
    [0, 1, 2, 3, 3, 3, 3, 2, 0],
    [0, 1, 2, 3, 3, 3, 3, 2, 0],
    [0, 1, 2, 2, 2, 2, 2, 2, 0],
    [0, 1, 1, 1, 1, 1, 1, 1, 0],
    [0, 0, 0, 0, 0, 0, 0, 0, 0]
]

If anyone has any suggestions I would really appreciate it.

Logged



Check out my current game project:
Mine to the sky
Layl
Level 3
***

professional jerkface


View Profile WWW
« Reply #1 on: March 06, 2015, 10:44:21 AM »

I would use perlin or simplex noise for this, example in C#-alike pseudocode:

Code:
var multiplier = 5;

foreach(tile in tiles)
{
    var noise = perlin.GetValue(tile.X, tile.Y, 0.5f); // often perlin noise libraries only give you GetValue(x, y, z)
    var normalizedRaw = (noise + 1.0f) * 0.5; // perlin is in a range of -1 -> 1 usually BUT NOT ALWAYS, we need a 0-1 range here
    var normalized = Math.Range(, 0.0f, 1.0f); // Math.Range does not actually exist but you can see sort of what it does
    tile.Value = tile.Value * noise * multiplier;
}

If you want to make it slope down until it hits air, you also need to clamp or multiply the eventual value depending on the distance from the nearest air block.
Logged
surt
Level 7
**


Meat by-product.


View Profile
« Reply #2 on: March 06, 2015, 11:23:54 AM »

You'll want to do a distance transform of your mask to get the blended transition, then multiply it by your pattern to add the detailing.
Logged

Real life would be so much better with permadeath.
PJ Gallery - OGA Gallery - CC0 Scraps
Codestar
Level 1
*

One man, one game


View Profile WWW
« Reply #3 on: March 06, 2015, 12:11:37 PM »

You'll want to do a distance transform of your mask to get the blended transition, then multiply it by your pattern to add the detailing.

How would I pick what parts of my 2D array are the "peaks" that it could blend down from? or would I even need "peaks" if I used a euclidean distance transform?
« Last Edit: March 06, 2015, 12:26:50 PM by Codestar » Logged



Check out my current game project:
Mine to the sky
oodavid
Level 8
***


Discombobulate!


View Profile WWW
« Reply #4 on: March 06, 2015, 12:26:40 PM »

If you are starting with a 2d array as mentioned, why not loop and run something like this:

X = own value
N = sum of all neighbours
A = Math.floor(N/4)
if(X<=A){
  X++
}

Which is essentially a variation of Pascale's triangle.
Logged


Button up! - Out on Android and iOS

latest release: 13th March 2015
BorisTheBrave
Level 10
*****


View Profile WWW
« Reply #5 on: March 06, 2015, 01:23:38 PM »

Computing the distance transform for the manhattan distance metric. Here's an algorithm (essentially Dijkstra's, just simplified for you):

Code:
construct a new 2d array to store distance, and initialize every cell with zero
for each empty tile, t:
  set each adjacent solid tile's distance to 1
d = 1
repeat indefinitely:
  for each solid tile with distance d:
    set each adjacent solid tile with distance 0 to d + 1
  if no tiles were updated, exit loop
  d += 1

The easy way to loop over solid tiles with distance d is to just loop over all tiles and ignore those you don't want. Somewhat faster would be to record the set of tiles updated in each loop, and then loop over those next time round.

Note in your case you can probably terminate the loop after 10 iterations as anything more than 10 tiles from empty air is unlikely to be on the screen, so needn't have any variation.
« Last Edit: March 06, 2015, 02:57:53 PM by BorisTheBrave » Logged
surt
Level 7
**


Meat by-product.


View Profile
« Reply #6 on: March 06, 2015, 01:56:55 PM »

How would I pick what parts of my 2D array are the "peaks" that it could blend down from? or would I even need "peaks" if I used a euclidean distance transform?
You don't pick the peaks, the distance transform does. They will be the areas furthest from an edge.

EDIT:
Interactive demo of a rather sexy constant time distance transform method. Maths is way over my head though.  Waaagh!
« Last Edit: March 07, 2015, 04:06:09 AM by surt » Logged

Real life would be so much better with permadeath.
PJ Gallery - OGA Gallery - CC0 Scraps
Codestar
Level 1
*

One man, one game


View Profile WWW
« Reply #7 on: March 09, 2015, 07:21:25 AM »

Thanks a lot guys, I was able to implement the distance transform algorithm and it worked perfectly!

Logged



Check out my current game project:
Mine to the sky
BorisTheBrave
Level 10
*****


View Profile WWW
« Reply #8 on: March 09, 2015, 10:59:03 AM »

I'm glad you've got something you are happy with, but I can clearly see there are bugs in your implementation. The interior squares are somtimes only a single brick from the edge, sometimes many bricks. The point was to get a uniform distance!
Logged
Layl
Level 3
***

professional jerkface


View Profile WWW
« Reply #9 on: March 09, 2015, 11:06:54 AM »

I'm glad you've got something you are happy with, but I can clearly see there are bugs in your implementation. The interior squares are somtimes only a single brick from the edge, sometimes many bricks. The point was to get a uniform distance!

Nope, in the original post he asked for a bit of a randomized system, which is why I suggested perlin noise.
Logged
BorisTheBrave
Level 10
*****


View Profile WWW
« Reply #10 on: March 09, 2015, 11:27:23 AM »

Ah, I expect you are right.
Logged
Codestar
Level 1
*

One man, one game


View Profile WWW
« Reply #11 on: March 09, 2015, 02:59:18 PM »

I'm glad you've got something you are happy with, but I can clearly see there are bugs in your implementation. The interior squares are somtimes only a single brick from the edge, sometimes many bricks. The point was to get a uniform distance!

You're actually quite right, there were a few bugs in my first implementation that I ironed them out after posting that screenshot. Now I have uniform distance working. You have a keen eye my friend.  Gentleman

Logged



Check out my current game project:
Mine to the sky
Pages: [1]
Print
Jump to:  

Theme orange-lt created by panic