Do you like my tutorials?

Then consider supporting me on Ko-fi

Talking about Tiny Wings game, Actionscript 3, Box2D, Flash and Game development.

I want to show you an improved version of the Tiny Wings terrain you’ve already seen at Create a terrain like the one in Tiny Wings with Flash and Box2D – adding textures.

This time hills have more bumps and are more irregular, getting a little closer to the original look and feel.

I also placed a sphere you can drive with left and right arrow keys to move along the terrain, and my movieMonitor to show you the performance.

Move the ball with LEFT and RIGHT arrows.

This is the source code:

package {
	import flash.display.Sprite;
	import flash.events.Event;
	import flash.events.KeyboardEvent;
	import Box2D.Dynamics.*;
	import Box2D.Collision.*;
	import Box2D.Collision.Shapes.*;
	import Box2D.Common.Math.*;
	import Box2D.Dynamics.Joints.*;
	public class Main extends Sprite {
		private const degreesToRadians:Number=0.0174532925;
		private var world:b2World=new b2World(new b2Vec2(0,10),true);
		private var worldScale:int=30;
		private var left:Boolean=false;
		private var right:Boolean=false;
		private var nextHill:Number=240;
		private var realHeight:Number=240;
		private var realWidth:Number=0;
		private var buildNextHillAt:Number=0;
		var theSphere:b2Body;
		private var gameCanvas:Sprite=new Sprite();
		public function Main():void {
			var sphereShape:b2CircleShape=new b2CircleShape(12/worldScale);
			var sphereFixture:b2FixtureDef = new b2FixtureDef();
			sphereFixture.density=1;
			sphereFixture.friction=3;
			sphereFixture.restitution=0.1;
			sphereFixture.filter.groupIndex=-1;
			sphereFixture.shape=sphereShape;
			var sphereBodyDef:b2BodyDef = new b2BodyDef();
			sphereBodyDef.type=b2Body.b2_dynamicBody;
			sphereBodyDef.position.Set(320/worldScale,0);
			sphereBodyDef.userData=new Object();
			theSphere=world.CreateBody(sphereBodyDef);
			theSphere.CreateFixture(sphereFixture);
			addChild(gameCanvas);
			stage.addChild(new movieMonitor());
			debugDraw();
			while (realWidth<1280) {
				nextHill=drawHill(10,realWidth,nextHill);
			}
			addEventListener(Event.ENTER_FRAME,updateWorld);
			stage.addEventListener(KeyboardEvent.KEY_DOWN,keyPressed);
			stage.addEventListener(KeyboardEvent.KEY_UP,keyReleased);
		}
		private function drawHill(pixelStep:int,xOffset:Number,yOffset:Number):Number {
			var hillStartY:Number=yOffset;
			var hillWidth:Number=120+Math.ceil(Math.random()*26)*20;
			realWidth+=hillWidth;
			var numberOfSlices=hillWidth/pixelStep;
			var hillVector:Vector.;
			var randomHeight:Number;
			if (xOffset==0) {
				randomHeight=0;
			}
			else {
				do {
					randomHeight=Math.random()*hillWidth/7.5;
				} while (realHeight+randomHeight>600);
			}
			realHeight+=randomHeight;
			hillStartY-=randomHeight;
			for (var j:int=0; j();
				hillVector.push(new b2Vec2((j*pixelStep+xOffset)/worldScale,480/worldScale));
				hillVector.push(new b2Vec2((j*pixelStep+xOffset)/worldScale,(hillStartY+randomHeight*Math.cos(2*Math.PI/numberOfSlices*j))/worldScale));
				hillVector.push(new b2Vec2(((j+1)*pixelStep+xOffset)/worldScale,(hillStartY+randomHeight*Math.cos(2*Math.PI/numberOfSlices*(j+1)))/worldScale));
				hillVector.push(new b2Vec2(((j+1)*pixelStep+xOffset)/worldScale,480/worldScale));
				var sliceBody:b2BodyDef=new b2BodyDef  ;
				var centre:b2Vec2=findCentroid(hillVector,hillVector.length);
				sliceBody.position.Set(centre.x,centre.y);
				for (var z:int=0; z();
				hillVector.push(new b2Vec2((j*pixelStep+xOffset)/worldScale,480/worldScale));
				hillVector.push(new b2Vec2((j*pixelStep+xOffset)/worldScale,(hillStartY+randomHeight*Math.cos(2*Math.PI/numberOfSlices*j))/worldScale));
				hillVector.push(new b2Vec2(((j+1)*pixelStep+xOffset)/worldScale,(hillStartY+randomHeight*Math.cos(2*Math.PI/numberOfSlices*(j+1)))/worldScale));
				hillVector.push(new b2Vec2(((j+1)*pixelStep+xOffset)/worldScale,480/worldScale));
				sliceBody=new b2BodyDef  ;
				centre=findCentroid(hillVector,hillVector.length);
				sliceBody.position.Set(centre.x,centre.y);
				for (z=0; z, count:uint):b2Vec2 {
			var c:b2Vec2 = new b2Vec2();
			var area:Number=0.0;
			var p1X:Number=0.0;
			var p1Y:Number=0.0;
			var inv3:Number=1.0/3.0;
			for (var i:int = 0; i < count; ++i) {
				var p2:b2Vec2=vs[i];
				var p3:b2Vec2=i+1

No need to download anything, simply copy and paste in any Tiny Wings source code you'll find around the blog.

Net time, I'll try to texture the hills with something decent.

Never miss an update! Subscribe, and I will bother you by email only when a new game or full source code comes out.