Jump to content
  • Advertisement
Sign in to follow this  
Master thief

Need advice/help with simple noise functions and 2D terrain gen

This topic is 801 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

If you intended to correct an error in the post then please contact us.

Recommended Posts

I'm following this article in order to understand noise algorithms, and I'm still only half way through it, so I'm still doing the simpler stuff. As I'm doing this I'm trying to translate what I learn into my intended application of it: terrain generation for a platformer (I can't find any useful tutorials for this...). However, I don't know if I'm doing this right, and there's also a few things I'm getting confused about.

I figured if I got the output values of the noise functions between 0 and 1, and then multiply that output by the height of the map (which is for now the same size as the screen (768px)), it could work. I can use that to know where each tile goes. I figured if I later have a bigger map I can lower this value to something sensible like, say, a 5th of the map's height.

Am I on the right track here? It does seem to work. Kind of...

The results from the red noise function are quite appealing (with 50 smoothing passes).

 

HAzBITS.jpg

But the results from the violet one always go near the top of the screen/map and I don't know if that's natural behavior or a flaw in what I'm doing. I figure it's the latter since I'm not being able to display them any lower by playing with the numbers.

The tiles at the bottom are actually wrapping around the top cells, which is why the red lines aren't connecting to them.

FxZH36v.jpg


I'm also confused about whether the output should include negative values (-1 to 1). The article author uses them here and there without even flinching. But I'm not sure how to account for that. I'm not using any, but the rough() function (below) naturally gives me some. If I converted those negative values to positive, I end up taming the violet function, but only slightly. And the tiles are still near the top.

Here are the functions as I made them (in python (pySFML)):
 

# In the Noise class...
# I stripped these functions of class specific stuff,
# like 'self.' and '@classmethod', for readability

def red(n, seed = 0, lmin = 0, lmax = 99, avg = 0.5, passes = 1):
    random.seed(seed)
    points = []

    for i in xrange(n):
        points.append(random.randint(lmin, lmax)*0.01)

    # smooths the values
    return smooth(points, avg, passes)


def violet(n, seed = 0, lmin = 0, lmax = 99, avg = 0.5, passes = 1):
    random.seed(seed)
    points = []

    for i in xrange(n):
        points.append(random.randint(lmin, lmax)*0.01)
    
    # roughs the values
    return rough(points, avg, passes)


def smooth(noise, avg, passes):
    if passes > 0:
        output = []

        for i in xrange(len(noise)):
            if i is not len(noise)-1:
                output.append( avg * (noise[i] + noise[i+1]) )
            else:
                # Average of the last value and the first
                output.append( avg * (noise[i] + noise[0]) )
        
        return smooth(output, avg, passes-1)
    else: return noise


def rough(noise, avg, passes):
    if passes > 0:
        output = []

        for i in xrange(len(noise)):
            if i is not len(noise)-1:
                output.append( avg * (noise[i] - noise[i+1]) )
            else:
                # Diference between the last value and the first
                output.append( avg * (noise[i] - noise[0]) )
        
        return s.rough(output, avg, passes-1)
    else: return noise    


# and in the World class
# I use 's.' instead of 'self.', by the way

def genNoise(s):
    numPoints = s.numCellsX*s.tsize                 # s.tsize = tile size (16px)
    s.points = Noise.red    (numPoints, 0, 0, 100, 0.5, 50)
    # s.points = Noise.violet(numPoints, 0,  0, 100, 0.5, 3)


def placeTiles(s):
    for i in xrange(len(s.points)):
        p = s.points[i]

        tileX = int(i%s.csize)                     # s.csize = cell size (16 tiles)
        tileY = int(((p*s.mh)/s.tsize)%s.csize)    # s.mw/s.mh = map width/height (1280x768)
        cellX = int((i%s.mw)/s.csize)              
        cellY = int(((p*s.mh)/s.tsize)/s.csize)
        
        s.cells[cellX][cellY].tiles[tileX][tileY].show()
        s.cells[cellX][cellY].hasTiles = True

Edited by Master Thief

Share this post


Link to post
Share on other sites
Advertisement
Sign in to follow this  

  • Advertisement
×

Important Information

By using GameDev.net, you agree to our community Guidelines, Terms of Use, and Privacy Policy.

We are the game development community.

Whether you are an indie, hobbyist, AAA developer, or just trying to learn, GameDev.net is the place for you to learn, share, and connect with the games industry. Learn more About Us or sign up!

Sign me up!