PDA

View Full Version : Challenge - Randomized Tornado


madgett
01-10-2005, 12:12 AM
Ok flash gurus I think that we should bring this forum to life again...at least until our brains are all fried...lol.

Ok, here's my challenge:

Using only ActionScript in less than 75 lines of code ( {} and comments don't count) simulate a tornado using only actionscript. It must possess at least 1 randomized entity. I've given it a shot and from what I did you will most likely have more than 1 entity anyways to make it look like a tornado.

To view mine go to this url on my testing server http://www.flashtowns.com

Lets give this a 1 week timeframe, so until next Sunday, Jan 16th and we'll see what brain tangling code everyone comes up with. I will post my code for it after we get a few entrances. Enjoy!

splict
01-10-2005, 10:39 AM
cool stuff, madgett. i came in here to post a challenge (hadn't thought of one yet :rolleyes: ) and saw yours. looks good! :) you just put stuff on the front page of that site? :confused:

Laguana
01-11-2005, 12:08 AM
I've got one that somewhat mostly works ;) It doesn't quite look proper yet, i'm still trying to get a funnel look.
function MatrixMultiply(A, B) {
A = prepareMatrix(A);
subA = A[0].length
B = prepareMatrix(B);
subB = B[0].length
C = new Array();
for (i=0; i<A.length; i++) {
this["sub"+i] = new Array();
for (k=0; k<subB; k++) {
tmpc = 0;
for (l=0; l<B.length; l++) {
tmpa = B[l][k];
tmpb = A[i][l];
tmpc = (tmpc+(tmpa*tmpb))}
this["sub"+i].push(tmpc)}
C.push(this["sub"+i])}
return C}
function prepareMatrix(F) {
for (i=0; i<F.length; i++) {
tmpArry = F[i];
if (Number(tmpArry) == tmpArry) {
tmpfi = F[i];
F[i] = new Array();
F[i].push(tmpfi)}}
return F}
function makeRotMat() {
Q = new Array([1, 0, 0], [0, Math.cos(_root.axisoffset[0]*Math.PI/180), Math.sin(_root.axisoffset[0]*Math.PI/180)*-1], [0, Math.sin(_root.axisoffset[0]*Math.PI/180), Math.cos(_root.axisoffset[0]*Math.PI/180)]);
R = new Array([Math.cos(_root.axisoffset[1]*Math.PI/180), 0, Math.sin(_root.axisoffset[1]*Math.PI/180)*-1], [0, 1, 0], [Math.sin(_root.axisoffset[1]*Math.PI/180), 0, Math.cos(_root.axisoffset[1]*Math.PI/180)]);
S = new Array([Math.cos(_root.axisoffset[2]*Math.PI/180), Math.sin(_root.axisoffset[2]*Math.PI/180)*-1, 0], [Math.sin(_root.axisoffset[2]*Math.PI/180), Math.cos(_root.axisoffset[2]*Math.PI/180), 0], [0, 0, 1]);
_root.rotMat = MatrixMultiply(MatrixMultiply(R, S), Q)}
function drawPointsIn() {
_root.everything.removeMovieClip();
_root.createEmptyMovieClip("everything", 0);
for (count=0; count<_root.absPoints.length; count++) {
curMat = MatrixMultiply(_root.RotMat, _root.absPoints[count]);
x = _root.centrex + curMat[0][0]
y = /*_root.centrey*/Stage.height -50 - curMat[1][0]
z = curMat[2][0]
_root.everything.moveTo(x,y)
_root.everything.lineStyle(5 + z/20,0,100)
_root.everything.lineTo(x+1,y+1)}}
function twirl() {
_root.axisoffset[1]+= 30
makeRotMat()
_root.centrex += direction
direction = _root.centrex < 500?-1:1
direction = _root.centrex > 100?1:-1
//_root.centrey = (Stage.height/2) + (Stage.height/100 - Stage.height/200 * Math.random())
drawPointsIn()}
updateAfterEvent()
function init() {
_root.axisoffset = [int(Math.random() *30) + 330, 0,0]
range = 100
_root.absPoints = []
_root.centrex = 200
for (i = 0; i < 100;i++) {
xx = int(Math.random() * range)- (range/2)
_root.absPoints.push([xx,int(Math.random() * Stage.height/1.5) ,int(Math.random() * range)- (range/2)])}
twirlInt = setInterval(twirl,100)}
init()

I just happened to be trying to make a 3d engine at the time of this challange, so i decided to use all the stuff from the engine :P had to remove a bunch of error checking to make it fit though. I count 60 lines.

Laguana
01-11-2005, 03:57 AM
Ok, now it looks like a tornado :) Just needed a little help from a 3d graphing website to get the equation for the "plane with hole in it" look, as i call it.

function MatrixMultiply(A, B) {
A = prepareMatrix(A);
subA = A[0].length
B = prepareMatrix(B);
subB = B[0].length
C = new Array();
for (i=0; i<A.length; i++) {
this["sub"+i] = new Array();
for (k=0; k<subB; k++) {
tmpc = 0;
for (l=0; l<B.length; l++) {
tmpa = B[l][k];
tmpb = A[i][l];
tmpc = (tmpc+(tmpa*tmpb))}
this["sub"+i].push(tmpc)}
C.push(this["sub"+i])}
return C}
function prepareMatrix(F) {
for (i=0; i<F.length; i++) {
tmpArry = F[i];
if (Number(tmpArry) == tmpArry) {
tmpfi = F[i];
F[i] = new Array();
F[i].push(tmpfi)}}
return F}
function makeRotMat() {
Q = new Array([1, 0, 0], [0, Math.cos(_root.axisoffset[0]*Math.PI/180), Math.sin(_root.axisoffset[0]*Math.PI/180)*-1], [0, Math.sin(_root.axisoffset[0]*Math.PI/180), Math.cos(_root.axisoffset[0]*Math.PI/180)]);
R = new Array([Math.cos(_root.axisoffset[1]*Math.PI/180), 0, Math.sin(_root.axisoffset[1]*Math.PI/180)*-1], [0, 1, 0], [Math.sin(_root.axisoffset[1]*Math.PI/180), 0, Math.cos(_root.axisoffset[1]*Math.PI/180)]);
S = new Array([Math.cos(_root.axisoffset[2]*Math.PI/180), Math.sin(_root.axisoffset[2]*Math.PI/180)*-1, 0], [Math.sin(_root.axisoffset[2]*Math.PI/180), Math.cos(_root.axisoffset[2]*Math.PI/180), 0], [0, 0, 1]);
_root.rotMat = MatrixMultiply(MatrixMultiply(R, S), Q)}
function drawPointsIn() {
_root.everything.removeMovieClip();
_root.createEmptyMovieClip("everything", 0);
for (count=0; count<_root.absPoints.length; count++) {
curMat = MatrixMultiply(_root.RotMat, _root.absPoints[count]);
x = _root.centrex + curMat[0][0]
y = Stage.height -50 + curMat[1][0]
z = curMat[2][0]
_root.everything.moveTo(x,y)
_root.everything.lineStyle(5 + z/20,0,100)
_root.everything.lineTo(x+1,y+1)}}
function twirl() {
_root.axisoffset[1]+= 30
makeRotMat()
_root.centrex += direction * 10
if (_root.centrex >500) {
direction = -1}
else if (_root.centrex < 100) {
direction = 1}
drawPointsIn()}
updateAfterEvent()
function init() {
_root.axisoffset = [int(Math.random() *10) + 350, 0,0]
range = 100
_root.absPoints = []
_root.centrex = 200
direction = 1
for (i = 0; i < 200;i++) {
xx = int(Math.random() * range)- (range/2)
zz = int(Math.random() * range)- (range/2)
yy = (Stage.height * 100)/(Math.pow(Math.abs((zz)),2) + Math.pow(Math.abs((xx)),2)) - (Stage.height/1.1)
_root.absPoints.push([xx,yy,zz])}
twirlInt = setInterval(twirl,50)}
init()

Have a look at http://thor.prohosting.com/laguana/tornado.swf

tdoublea
01-12-2005, 02:09 AM
ahh geez... this has cut a chunk out of the time i should be working on my projects...
i'll post mine as soon as i can figure out how to cut nine lines.

just wanted to say, nice work Laguana and good idea madgett. wanna see what splict comes up with.

-t

tdoublea
01-15-2005, 08:05 PM
eh...

var stageHeight = 200;
var stageWidth = 300;

function addDot(mc:MovieClip, radius:Number, x:Number, y:Number){
mc.beginFill(0xffffff, 100);
mc.moveTo(x,y);
mc.curveTo(x + radius, y , x + radius, y - radius);
mc.curveTo(x + radius, y - (radius *2), x, y - (radius*2));
mc.curveTo(x - radius, y - (radius *2), x - radius, y - radius);
mc.curveTo(x - radius, y, x, y);
mc.endFill();
}

var eye = createEmptyMovieClip("eye", 10);
addDot(eye, 2, 0, 0);
eye._y = stageHeight;
eye.radius = 10;

var turbArray = new Array();
var partArray = new Array();
function setTurbs(amount:Number){
for(var i = 0; i < amount; i++){
var turb = createEmptyMovieClip("turb" + (i + 1000), (i + 1000));
turb._y = stageHeight - ((stageHeight - eye._height)/amount * (i+1));
turb.diameter = (eye.radius + eye._y - turb._y)/2;
turb.lag = (i+1)/10;
turb.spread = (Math.max(0, Math.round((i-5)/amount)));
turbArray[i] = turb;

partArray[i] = new Array();
var setBack = turb.diameter/2;
for(var j = 0; j < (i+2); j++){
var particle = turb.createEmptyMovieClip("particle" + j, j);
particle.angle = j + 180;
particle.radius = turb.diameter/2;
particle.speed = Math.random(2) * (100/(i + 1));
addDot(particle, random(3) + 2, 0, 0);
var spacer = turb.diameter/(i + 1);
particle._x = eye._x + setback;
setback -= spacer;
partArray[i][j] = particle;
}
}
}
setTurbs(20);

var tornadoXcenter = 2;
var tornadoZcenter = 50;
var tornadoSpeed = 30;
var angle = 0;
eye.onEnterFrame = setTornado;

function setTornado(){
var z = tornadoZcenter + eye.radius * Math.sin(angle * (Math.PI/180));
var x = eye.radius * Math.cos(angle * (Math.PI/180));
angle += tornadoSpeed;
var scale = 150/(150 + z);
eye._xscale = eye._yscale = scale*100;

if(angle > 359){
angle = -360;
}

if(eye._x > (stageWidth+ 20)){
tornadoXcenter = -tornadoXcenter;
}
if(eye._x < -20){
tornadoXcenter = -tornadoXcenter;
}

eye._x += tornadoXcenter + x;
for(var i = 0; i < turbArray.length; i++){
var theTurb = turbArray[i];
lastTurbX = theTurb._x;
theTurb._x = eye._x;
theTurb._x += (stageWidth/2 - theTurb._x)/(1/theTurb.lag + 1);
theTurb._rotation = -(theTurb._x - lastTurbX) + (turbArray.length - i);
for(var j = 0; j < partArray[i].length; j++){
var thePart = partArray[i][j];
var partradius = thePart.radius + (theTurb.spread/(turbArray.length - i));
maxspread = Math.max(45, (((i+5) - turbArray.length) * 10) + 40);
thePart.radius = Math.min(partradius, maxspread);

var partz = tornadoZcenter + thePart.radius * Math.sin(thePart.angle * (Math.PI/180));
var partx = thePart.radius * Math.cos(thePart.angle * (Math.PI/180));
var partscale = 150/(150 + z);
thePart._xscale = thePart._yscale = partscale * (100);
var partSpeed = thePart.speed * 100/thePart._xscale + i;
thePart._x = partx;
thePart.angle += partSpeed;

if(partangle >= 359){
partangle = -360;
}
}
}
}


::minus space-endbrackets, i count 75
made with stage at 300x200 and background color other than white

-t

Xeef
01-15-2005, 10:54 PM
DEG = 0;
P = [];
_root.onEnterFrame = function() {
Q = this.createEmptyMovieClip("Clip", 1);
DEG++;
Q.Radius = 150;
Q.W = Q.Y=0;
Q.A1 = 75;
for (a=DEG; a<2500+DEG; a) {
if (!P[Q.W]) {
Obj = {};
Obj.Radius = random(Q.A1)-(Q.A1/2);
Obj.a = random(15);
Obj.b = 0;
Obj.y = random(Q.A1)-(Q.A1/2);
P.push(Obj);
}
Obj = _root.P[Q.W++];
Obj.b += (random(3)-1)/2;
Obj.y += (random(3)-1)/2;
Obj.Radius += (random(3)-1)/2;
a += Obj.a;
Q.Y += 1;
Q.Radius -= .4;
Q.x = (Q.Radius+Obj.Radius)*Math.cos((a+Obj.b)*Math.PI/180);
Q.y = ((Q.Radius+Obj.Radius)/2)*Math.sin((a+Obj.b)*Math.PI/180);
Q.lineStyle(2, 0xFF00FF, 100);
Q.moveTo(Q.x+200, Q.y-.3+Q.Y+Obj.y);
Q.lineTo(Q.x+200, Q.y+Q.Y+Obj.y);
}
};


DEG = 0;
P = [];
T = 0;
X = 200;
_root.onEnterFrame = function() {
Q = this.createEmptyMovieClip("Clip", 1);
DEG++;
Q.Radius = 150;
Q.W = Q.Y=0;
Q.A1 = 75;
Q.WW = T++;
Q.WWW = 200;
if (!(random(10))) {
X += (random(3)-1)/2;
}
for (a=DEG; a<3000+DEG; a) {
WAVE = (Q.WWW--)*Math.cos((Q.WW)*Math.PI/180);
Q.WW += 5;
if (!P[Q.W]) {
Obj = {};
Obj.Radius = random(Q.A1)-(Q.A1/2);
Obj.a = random(30);
Obj.y = random(Q.A1)-(Q.A1/2);
P.push(Obj);
}
Obj = _root.P[Q.W++];
a += Obj.a;
Q.Y += 2;
Q.Radius -= .9;
Q.x = (Q.Radius+Obj.Radius)*Math.cos((a)*Math.PI/180);
Q.y = ((Q.Radius+Obj.Radius)/2)*Math.sin((a)*Math.PI/180);
Q.lineStyle(5, 0xFF00FF, 100);
Q.moveTo(Q.x+X+WAVE/2, Q.y-.3+Q.Y+Obj.y);
Q.lineTo(Q.x+X+WAVE/2, Q.y+Q.Y+Obj.y);
}
};

Laguana
01-16-2005, 02:05 AM
Hey, can someone either host a .swf of tdoublea's one, or translate it into plain ol' mx? 'cause i've only got mx and i'm interested in seeing what it looks like, and if i change it by my un-2004-educated self i'll probably mess it up. Thanks

tdoublea
01-16-2005, 03:31 AM
hey laguana,

sorry about that. if you take away the type identifiers (:Number, :MovieClip) in the functions it should work in MX.

attached are files in MX and MX2004.

-t

tdoublea
01-16-2005, 03:32 AM
forgot to attach files...

Laguana
01-16-2005, 05:00 AM
Thanks for that. That's a pretty cool tornado :)

tdoublea
01-16-2005, 10:50 PM
thanks man :) you have yourself a pretty cool tornado too.

Xeef
01-18-2005, 07:51 PM
_root.createEmptyMovieClip("_mc", 1);
_mc.onEnterFrame = function() {
Wave++;
if (!(random(25))) {
C(this);
}
};
Wave = 0;
Count = 0;
function C(Obj) {
O = Obj.createEmptyMovieClip("Courv"+_root.Count++, Obj.getNextHighestDepth());
O.Deg = 0;
O.Y = Y+random(5)-2;
O.DegPlus = random(20)+5;
O.y = -(random(O.DegPlus/5));
O.Radius = _root.Radius;
rgb = random(200)+55;
O.RGB = "0x"+rgb.toString(16)+rgb.toString(16)+rgb.toString(16 );
O.onEnterFrame = function() {
O = this.createEmptyMovieClip("Draw", 1);
with (O) {
_parent.Deg += 3;
_parent.Y -= .05;
_parent.Radius += (Radius*Radius)/(5000-Radius*10);
if (_parent.Deg>5000) {
trace("!");
_parent.Radius+=.1
}
lineStyle(1, _parent.RGB, 100);
Obj = _root.XY(_parent.Deg, _parent.Radius);
moveTo(_root.X+Obj.x+Obj.R, _parent.Y+Obj.y-.3);
Obj = _root.XY(_parent.Deg+_parent.DegPlus, _parent.Radius);
lineTo(_root.X+Obj.x+Obj.R, _parent.Y+Obj.y+_parent.y);
}
};
}
function XY(Deg, Radius) {
Obj = {};
Obj.R = (50)*Math.cos((Deg/25+Wave)*Math.PI/180);
Obj.x = (Radius)*Math.cos(Deg*Math.PI/180);
Obj.y = (Radius/2)*Math.sin(Deg*Math.PI/180);
return Obj;
}
X = 300;
Y = 400;
THeight = 7500;
Radius = 10;


one more (need a bit time to build up)

madgett
01-22-2005, 07:43 AM
Wow, there is some great code in here! I just got my comp back with the files on it, so here is my code:

var numParticles:Number = 200;
var angle:Number = 0;
// spin speed, scale 1 - 10
var spinSpeed:Number = 3;
var cond:Number = 500;
var stageLocation:Number = Stage.width/3;
var trackParticle:Array = new Array();
_root.createEmptyMovieClip("particle_mc", 0);
particle_mc.lineStyle(2, 0x131050, 60);
particle_mc.lineTo(0, .5);
trackParticle.push(particle_mc);
for (var i = 0; i<numParticles; ++i) {
var particle:MovieClip = _root.particle_mc.duplicateMovieClip("particle"+i, i+1);
particle.angle = (Math.round(Math.random()*3.14)+0);
particle.rotate = (Math.round(Math.random()*110)+10);
particle.yChange = (Math.round(Math.random()*7)+2);
particle.yPos = (Math.round(Math.random()*400)+0);
particle.yPos2 = (Math.round(Math.random()*400)+0);
particle.xChange = (Math.round(Math.random()*2)+1);
particle.xPos = (Math.round(Math.random()*50)+15);
particle.xPos2 = Stage.width/3;
particle_mc._visible = false;
trackParticle.push(particle);
}
var vChange:Number = 0;
_root.onEnterFrame = function() {
for (i=0; i<trackParticle.length; ++i) {
var particle:MovieClip = trackParticle[i];
if (particle.xPos2<_root._xmouse) {
particle.xPos2 += 1;
}
if (particle.xPos2>_root._xmouse) {
particle.xPos2 -= 1;
}
// randA is the spin velocity
var randA:Number = (Math.random()*(spinSpeed/10))+.1;
particle._x = (particle.rotate*Math.cos(particle.angle)/particle.xChange)+particle.xPos2;
particle._y = particle.rotate*Math.sin(particle.angle)/particle.yChange;
if (i%3 == 0) {
particle._y = particle.rotate*Math.sin(particle.angle)/particle.yChange;
}
if (i%2 == 0) {
if (particle.yPos<cond) {
if (i%6 == 0 && vChange%5 == 0) {
particle._y = (particle.rotate*Math.sin(particle.angle)/particle.yChange)+particle.yPos;
particle.yPos += Math.pow((Math.random()*.4+.05), 1.5);
} else if (i%8 == 0 && vChange%5 == 0) {
particle._y = (particle.rotate*Math.sin(particle.angle)/particle.yChange)+particle.yPos;
particle.yPos += Math.pow((Math.random()*.2+.3), .9);
} else {
particle._y = (particle.rotate*Math.sin(particle.angle)/particle.yChange)+particle.yPos;
particle.yPos += Math.pow((Math.random()*.3+.5), .5);
}
} else if (particle.yPos2>0) {
particle.yPos2 -= 1;
particle._y = (particle.rotate*Math.sin(particle.angle)/particle.yChange)+particle.yPos2;
}
if (particle.yPos2<=0) {
cond = 500;
particle.yPos = 0;
particle.yPos2 = 500;
}
}
particle.angle += randA;
if (particle.angle>2*Math.PI) {
particle.angle = 0;
}
}
++vChange;
if (vChange == 100) {
vChange = 0;
}
};