I'm reading this tutorial and it's the first time I try something this new.
Here is my attempt:
import sys
import math
import pygame
import random
pygame.init()
windowwidth, windowheight = 900, 500
windowsurface = pygame.display.set_mode((windowwidth, windowheight), 0, 32)
clock = pygame.time.Clock()
fps = 30
MAX_INT = (1<<31) - 1
grey = (128, 128, 128)
def linear_interpolate(a, b, x):
return a*(1-x) + b*x
def int_noise(x):
# I'm pretty sure I can use random.uniform(-1, 1) as I need a value in the range (-1, 1)
# I just saw this function on SO that is said to be faster that the build-in.
x = int(x)
x = ((x << 13) & MAX_INT) ^ x
x = ( x * (x * x * 15731 + 789221) + 1376312589 ) & MAX_INT
return 1.0 - x / 1073741824.0
def smooth_noise(x):
return int_noise(x)/2 + int_noise(x-1)/4 + int_noise(x+1)/4
def noise_interpolate(x):
int_x = int(x)
fractional_x = x - int_x
v1 = smooth_noise(int_x)
v2 = smooth_noise(int_x+1)
return linear_interpolate(v1, v2, fractional_x)
def perlin_noise(x):
total = 0
persistence = 1/4
octaves = 10
for i in range(octaves):
frequency = pow(2, i)
amplitude = pow(persistence, i)
total = total + noise_interpolate(x*frequency) * amplitude
return total
#---------------------------------------------------------------------------
def mainloop():
scale = 50
points = [(i, perlin_noise(0.6*i) * scale)
for i in range(0, windowwidth, 10)]
points.append((900, perlin_noise(0.5)))
while True:
clock.tick(fps)
pygame.display.set_caption('fps: %.2f' % clock.get_fps())
# handle events
for event in pygame.event.get():
if event.type == pygame.QUIT:
pygame.quit()
sys.exit()
# update game state
# draw
for i in range(len(points) - 1):
pygame.draw.line(windowsurface, grey,
(points[i][0], 350+points[i][1]),
(points[i+1][0], 350+points[i+1][1]), 1)
pygame.display.update()
if __name__ == '__main__':
mainloop()
I know the design is awful, but I'm more concerned if it is the correct way to write all this. From interpolating function, to the smoothing function, all the way to perlin.
I have the feeling that this Perlin noise function is completely wrong and very misleading, regardless the fact that I draw the wave onto the screen.