PDA

View Full Version : Rollercoaster


icio
12-28-2006, 09:24 AM
Some (productive?) hours of boredom.

Version 2

Draw with your mouse, this will become the track.
Make sure to start off going downwards or gravity can't take effect on your cart!

Play (http://img146.imageshack.us/img146/5518/rollercoaster2nu6.swf)
import flash.geom.Point;

Stage.scaleMode = "noScale";
Stage.align = "TL";
Stage.showMenu = false;

var track:MovieClip;
var section:MovieClip;
var length:Number = 60;

var ball;
var friction = 0.9999;
var gravity = 0.5;

var points:Array;
var p:Point;
var drawing:Boolean = false;

var lines:Array;

function onMouseDown() {
points = [];
lines = [];

drawing = true;

track.clear();
_root.clear();
if (ball) ball.removeMovieClip();

section = _root.createEmptyMovieClip("_section", 2);
section._x = _xmouse;
section._y = _ymouse;
section.onMouseMove = function() {
this.clear();
this.lineStyle(1, 0x666666);
this.lineTo(this._xmouse, this._ymouse);
updateAfterEvent();
}
section.onMouseMove();

p = new Point(_xmouse, _ymouse);
points.push(p);

_root.lineStyle(1, 0xCCCCCC);
_root.moveTo(0, _ymouse);
_root.lineTo(2000, _ymouse);
_root.moveTo(_xmouse, _ymouse);
}

function onMouseUp() {
points.push(new Point(_xmouse, _ymouse));
_root.lineTo(_xmouse, _ymouse);

drawing = false;
section.removeMovieClip();

if (!track) {
track = _root.createEmptyMovieClip("_track", 1);
}

var p1:Point, p2:Point, p3:Point, mid1:Point, mid2:Point;
var p1:Point = linearBezierPoint([points[0], points[1]], 0.5);

track.lineStyle(0, 0x000000);
track.moveTo(points[0].x, points[0].y);
track.lineTo(p1.x, p1.y);

lines.push({x: points[0].x, y: points[0].y});

for (var i:Number=0; i<points.length-2; i++) {
p1 = points[i];
p2 = points[i+1];
p3 = points[i+2];
mid1 = linearBezierPoint([p1, p2], 0.5);
mid2 = linearBezierPoint([p2, p3], 0.5);

lines = lines.concat(track.bezier([mid1, p2, mid2], 20));
}

lines.push({x: p3.x, y: p3.y});
track.lineTo(p3.x, p3.y);

for (i=0; i<lines.length; i++) {
var a = lines[i];
var b = lines[i+1];
a.dx = b.x - a.x;
a.dy = b.y - a.y;
a.a = Math.atan2(a.dy, a.dx);
}

lines.pop();

ball = track.attachMovie("ball", "_ball", 1);
ball._x = lines[0].x;
ball._y = lines[0].y;
ball._rotation = 180*lines[0].a/Math.PI;
ball.v = 0;
ball.line = 0;

_root.onEnterFrame = function() {
var l = lines[ball.line];
ball.v += Math.sin(l.a)*gravity;
ball.v *= friction;
run(ball.v);
ball._rotation = 180/Math.PI*lines[ball.line].a;
};
}

function onMouseMove() {
if (!drawing) return;

var dx:Number = _xmouse - p.x;
var dy:Number = _ymouse - p.y;
var d:Number = Math.sqrt(dx*dx+dy*dy);

if (d >= length) {
var a:Number = Math.atan2(dy, dx);
p = new Point(p.x+length*Math.cos(a), p.y+length*Math.sin(a));
points.push(p);

section._x = p.x;
section._y = p.y;
section.onMouseMove();

_root.lineTo(p.x, p.y);

onMouseMove();
}
}

function run(distance) {
var l = lines[ball.line];
if (ball.v == 0) return;

var ex:Number = l.x, ey:Number = l.y;
if (ball.v >= 0) {
ex += l.dx;
ey += l.dy;
}

var dx:Number = ex - ball._x, dy:Number = ey - ball._y;
var d:Number = Math.sqrt(dx*dx + dy*dy);

if (d < Math.abs(distance)) {
ball._x = ex;
ball._y = ey;
ball.line += ball.v > 0 ? 1 : -1;
if (ball.line == -1 || ball.line == lines.length) {
ball.line -= ball.v > 0 ? 1 : -1;
ball.v *= -0.3;
} else {
run((Math.abs(distance) - d)*Math.abs(distance)/distance);
}
} else {
ball._x += distance*Math.cos(l.a);
ball._y += distance*Math.sin(l.a);
}
}

MovieClip.prototype.linearBezierPoint = function(p:Array, t:Number):Point {
if (t < 0 || t > 1 || p.length != 2) return null;

return new Point(
p[0].x+(p[1].x-p[0].x)*t,
p[0].y+(p[1].y-p[0].y)*t
);
};

MovieClip.prototype.quadraticBezierPoint = function(p:Array, t:Number):Point {
if (t < 0 || t > 1 || p.length != 3) return null;

var ax:Number, bx:Number;
bx = 2*(p[1].x-p[0].x);
ax = p[2].x - p[0].x - bx;

var ay:Number, by:Number;
by = 2*(p[1].y - p[0].y);
ay = p[2].y - p[0].y - by;

var t2:Number = t*t;

return new Point(
ax*t2 + bx*t + p[0].x,
ay*t2 + by*t + p[0].y
);
};

MovieClip.prototype.bezier = function (p:Array, segments:Number):Array {
if (segments < 1) return;

var func:Function;
if (p.length < 2) {
return;
} else if (p.length == 2) {
func = this.linearBezierPoint;
} else if (p.length == 3) {
func = this.quadraticBezierPoint;
} else if (p.length == 4) {
func = this.cubicBezierPoint;
} else {
return;
}

var pr:Array = [];

var dt:Number = 1/segments;
var s:Point = func(p, 0);
this.moveTo(s.x, s.y);

for (var i:Number=1; i<=segments; i++) {
s = func(p, i*dt);
pr.push({x: s.x, y: s.y});
this.lineTo(s.x, s.y);
}

return pr;
}


Version 1

Draw with your mouse, this will become the track.
You can create sections of track that will boost your cart.
Holding one of the following keys will create boost sections:
Up: Boost no matter of the direction of your cart
Left: Boost when the cart is moving backwards
Right: Boost when the cart is moving forwards

Play (http://img99.imageshack.us/img99/5032/rollercoasterux4.swf)

Stage.scaleMode = "noScale";
Stage.align = "TL";

// The previous position of the mouse whilst drawing
var m:Object = {
x: 0,
y: 0
};

var friction:Number = 1; //0.999; // Friction whilst not being boosted
var gravity:Number = 0.5; // Gravitational force in effect whilst not being boosted
var boost:Number = 0.1; // Acceleration whilst being boosted

var ball:MovieClip; // Actually the rollercoaster's cart
var lines:Array = []; // The track

var drawing:Boolean = false;// Not drawing

/********************
* CREATELINE
* Creates the track in the `lines` array as the user draws
*******************/
function createLine(dx, dy) {
// The line object
var line:Object = {
x: m.x, /* Starting X of the line */
y: m.y, /* Starting Y of the line */
dx: dx, /* Change in X over course of line */
dy: dy, /* Change in Y over course of line */
a: Math.atan2(dy, dx), /* Angle of line */
boostB: Key.isDown(Key.UP), /* Boost in both directions */
boostL: Key.isDown(Key.LEFT), /* Boost when going left */
boostR: Key.isDown(Key.RIGHT) /* Boost when going right */
};

// Select which colour to draw in
var color:Number = 0;
if (line.boostB) {
color = 0xFF0000;
} else if (line.boostL) {
color = 0x00FF00;
} else if (line.boostR) {
color = 0x0000FF;
}

// Update the previous mouse position variable
m.x += dx;
m.y += dy;

// Draw the line
lines.push(line);
track.lineStyle(1, color);
track.lineTo(line.x+line.dx, line.y+line.dy);
}

function onMouseDown() {
// If we're drawing for a second time then `track` will exist;
// in which case we want to reset everything
if (track) {
track.removeMovieClip();
delete onEnterFrame;
lines = [];
}

// Set off the drawing
drawing = true;
m.x = _xmouse;
m.y = _ymouse;

// Set up our track
_root.createEmptyMovieClip("track", 1);

track.lineStyle(1, 0xCCCCCC);
track.moveTo(0, _ymouse);
track.lineTo(2000, _ymouse);

track.moveTo(m.x, m.y);

}
function onMouseUp() {
// No longer drawing, finish the last line
drawing = false;
createLine(_xmouse - m.x, _ymouse - m.y);

// Create the cart
ball = track.attachMovie("ball", "ball", 1);
ball._x = lines[0].x;
ball._y = lines[0].y;
ball.v = 0.2;
ball.line = 0;

// Set the main loop
_root.onEnterFrame = function() {
// How the cart should react to it's environment:
// BoostB [Boost in both directions]
// BoostL [Boost when going left]
// BoostR [Boost when going right]
// Otherwise [Apply gravity and friction]
var l = lines[ball.line];
if (l.boostB) {
ball.v += boost*Math.abs(ball.v)/ball.v;
} else if (l.boostL && ball.v <= 0) {
ball.v -= boost;
} else if (l.boostR && ball.v >= 0) {
ball.v += boost;
} else {
ball.v += Math.sin(l.a)*gravity;
ball.v *= friction;
}

// Run the line processing for the cart then update rotation
run(ball.v);
ball._rotation = 180/Math.PI*lines[ball.line].a;

};
}

function onMouseMove() {
if (!drawing) return;

// distance moved
var dx:Number = _xmouse - m.x, dy:Number = _ymouse - m.y;
var d:Number = Math.sqrt(dx*dx + dy*dy);

// Keep the lines less than 10 units long
// (I can't remember why I put it in, but I'm going to leave it.)
if (d >= 10) {
var a = Math.atan2(dy, dx);
dx = 10*Math.cos(a);
dy = 10*Math.sin(a);
createLine(dx, dy);
onMouseMove();
} else {
createLine(_xmouse-m.x, _ymouse-m.y);
}
}

function run(distance) {
// The line the ball is on.
var l = lines[ball.line];
// If the ball is not moving then don't both continuing (unlikely)
if (ball.v == 0) return;

// Calculate the coordinates of the end the cart is heading to on it's current line
var ex:Number = l.x, ey:Number = l.y;
if (ball.v >= 0) {
ex += l.dx;
ey += l.dy;
}

// Distace to the calculated end
var dx:Number = ex - ball._x, dy:Number = ey - ball._y;
var d:Number = Math.sqrt(dx*dx + dy*dy);

// If we get to the end of the line before we have travelled the desired distance then we need to move onto the next line
if (d < Math.abs(distance)) {
// Move to the end of the line
ball._x = ex;
ball._y = ey;
// Move onto the next line
ball.line += ball.v > 0 ? 1 : -1;
// If we've reached either end of the track
if (ball.line == -1 || ball.line == lines.length) {
// Rebound
ball.line -= ball.v > 0 ? 1 : -1;
ball.v *= -0.3;
// Otherwise
} else {
// Run again on the next line with the distance we have to travel minus the distance we just travelled
run((Math.abs(distance) - d)*Math.abs(distance)/distance);
}
// Or if we can move the desired distance on our current line
} else {
// Do so
ball._x += distance*Math.cos(l.a);
ball._y += distance*Math.sin(l.a);
}
}

Hope you enjoy :thumb:
Oh, 2.9k posts

Seb Hughes
12-28-2006, 10:04 AM
Sweeet, thats pretty cool.

SimplyArun
12-28-2006, 10:41 AM
wow man that's pretty nifty!
if there's some way you could smoothen out the lines drawn then it would be all the more better

bombsledder
12-28-2006, 11:35 AM
its kind of like linerider

final_end
12-28-2006, 11:38 AM
hehe. fun stuff.

.soulty
12-28-2006, 11:47 AM
oh man this is very cool, wonder if there is a way to save our paths so we can share our track creations.

nice work:thumb:

gonzolo
12-28-2006, 11:53 AM
very neat

icio
12-29-2006, 12:40 PM
Thanks for the comments guys.

I know what you mean about the lines. Line-smoothing would be nice. All it would require is a custom curveTo that uses straight lines to achieve a similar effect.

rugget
12-29-2006, 01:53 PM
Yes! my track is quite impressive, only if I could show you.

mprzybylski
12-29-2006, 03:21 PM
very slick. nice work

icio
12-29-2006, 04:29 PM
Yes! my track is quite impressive, only if I could show you.
Screenshot, lol?

I'm working on the track smoothing :)

Tocksiq
12-29-2006, 04:43 PM
ahhahahaahaaa mines the best....

CriTiCeRz
12-29-2006, 05:00 PM
Wow that's freaking sweet. :)

smartie.on.comp
12-29-2006, 06:00 PM
if only it could jump or even fly off the tracks when it reaches the end lol :P

icio
12-29-2006, 08:23 PM
big update line smoothing added.

chrisclick
12-30-2006, 11:21 PM
afre you going to think about the cart flying off the track...?

REEF·
12-30-2006, 11:28 PM
this is just like linerider. except, your line smoothing is...amazing!

finally, I was waiting for someone to make their own version. I want these options (for now):

save, load, delete tracks.
erasing and smoothing

I want them now! Lol, just kidding. But they would be nice! :love:

smartie.on.comp
12-31-2006, 04:07 AM
Beautiful! this is just 100% amazing!

good work

RonH
12-31-2006, 04:28 AM
This has to be the most mind boggling thing I ever have seen from a flash movie... I will definitly be learning from that flash file... I feel like such a noob...

By the way... I didn't know IMAGEshack could host .swfs... is that a hack?

robson_jerome
12-31-2006, 08:07 AM
wow. better than linerider any day.

_this
01-09-2007, 07:05 AM
Game about it ...
http://www.miniclip.com/games/deep-freeze/en/

Great idea!

phorte
01-09-2007, 08:16 AM
yeah a save function would be really awsome so we could trade. even if it was only just in raw variables for the time being. might have a look at that on the weekend.

darkmotion
01-09-2007, 09:14 AM
man thats great! maybe add a chain of carts to it and passengers that fall out :P

lewi-p
01-09-2007, 12:43 PM
hahaha passengers that fall out would be SO sweet!

darkmotion
01-10-2007, 05:09 AM
oh yeah you should account for friction as well

Dark Angel
01-10-2007, 07:44 PM
Wow, much better then linerider. This is amazing.

icio
01-10-2007, 08:13 PM
oh yeah you should account for friction as wellFriction has been accounted for...

Glad you all like it - I've been thinking about the multiple carts thing. I might go and have a quick look at it.

darkmotion
01-11-2007, 03:01 AM
Friction has been accounted for...

Glad you all like it - I've been thinking about the multiple carts thing. I might go and have a quick look at it.
Me thinks you should add more, because it is so fluid, it can make it up any incline (as long as no parts of the track go higher than the origin)

ø
01-11-2007, 09:50 AM
Awesome:D

CriTiCeRz
01-11-2007, 05:29 PM
Wow that's freaking awesome...

tedc
01-12-2007, 01:48 PM
yeah haha this is amazing! I see a lot of future, imagine, flying people, high points for the more people that fly out of the cart, people jumping on quickly at the end of the line, cart flying off and getting points for air time, I would be at it all day long and on top of that being able to trade lines haha wow...

danulf
01-12-2007, 03:07 PM
reminds me of http://www.linerider.org/ :)

can't get it to load :(

mlk
01-14-2007, 01:06 PM
the cart could fall of when the angles are too sharp

Smily
01-14-2007, 03:34 PM
Heh, quite a long time since I last posted. Anyways, shall I try to reconstruct/improve upon it in Flash 9/Actionscript 3? :D

squishy
01-14-2007, 06:26 PM
I can't open it.:hurt:

vini
01-16-2007, 12:10 PM
Ahem ...This is Funny

fattony
01-26-2007, 01:35 PM
*Applause* this will keep me interested in it for at least a few hours, it is really cool

pips
01-27-2007, 04:39 AM
very nice work!

darkmotion
01-27-2007, 04:43 AM
Heh, quite a long time since I last posted. Anyways, shall I try to reconstruct/improve upon it in Flash 9/Actionscript 3? :DSmiiiiiiiiily! Sup!? ya dude go for it!!! I wanna see!

protonxp
01-30-2007, 01:01 AM
could someone moddify the code for flash 5? ... pls? :angel:

iwiniquit
02-11-2007, 10:34 PM
i found this little glitch.

http://www.iwiniquit.com/rndm/coasterglitch.jpg

the cart just trails off into nowhere.