The terrain is just a graph. For any x position you just need a way to calculate a y.
A simple start would be y=sin(x)
Or to center it vertically and make the hills bigger you can do y=240+100*sin(x)
There are many ways to make the terrain more interesting than just a sine wave. You can use a noise plugin, or maybe add multiple sine waves together. Another idea is to just fill an array with random numbers and use cosp() to interpolate smoothly between the numbers.
So basically a function like this:
— i = int( x/100)
— t = x/100 -i
— return cosp(array.at(i),array.at(i+1),t)
Then you can move the player around in any way you like, and you can know if it hit the ground if player.y > function.call(“terrain”, player.x)
I don’t really want to fight with constructs collision system to somehow make it work with this, so instead you can do it manually. It’s also simple enough to do your own motion with a vx and vy variable.
— add 200*dt to player.vy
— add player.vx*dt to player.y
— add player.vy*dt to player.y
Set y0 to function.call(“terrain”, player.x)
Set y1 to function call(“terrain”, player.x + 0.001)
Set ang to angle(0,y0,0.001,y1)
Player.y > terrain(player.x)
— set player.y to y0
— set dot to player.vx*cos(ang)+player.vy*sin(ang)
— set player.vx to dot*cos(ang)
— set player.vy to dot*sin(ang)
So far so good. I guess I forgot to cover a way to draw the terrain. You could get away with only drawing what’s on screen.
Repeat 100 times
— create circle at (0,0)
— set x to lerp(leftScreen, rightscreen, loopindex/99)
— set y to function.call(“terrain”, self.x)
You could also stretch rectangle sprites between the circles to give a continuous line.
To fill the area below you could use all the circle locations along with the bottom two corners of the screen with a canvas fill function.
The gradients would require reasoning about how you’d want it to look and maybe drawing an offset polygon or placing blurred scaled sprites at key spots.