Categories
Flash

Circuito de carreras con coche en Flash AS2 & AS3

outrun lego

Después de escribir este post mi buen amigo Iván aportó una grandísima idea, un diseño y me dió más tareas para el tren, mi lado friki sentía cosquillas por hacerlo con la API de dibujo de Flash, pero para variar un poco en esta ocasión lo he hecho en ActionScript 2.0 y en ActionScript 3.0 que realmente no es tan distinto para los que ya programan en AS2.

INTRODUCCIÓN

La idea es poner un coche en el circuito que ya hicimos en el anterior post, así que simplemente con rectángulos lo vamos a hacer. Para esto haremos uso de la API de dibujo de Flash en AS2 y AS3, las diferencias son pequeñas y en ocasiones grandes, pero con un poco de imaginación haremos que se parezcan más, :P.

DESARROLLO

ActionScript 3.0

En ActionScript 3.0 utilizaremos los métodos beginFill y drawRect de la clase Graphics.

ActionScript 2.0

En ActionScript 2.0 no tenemos una clase Graphics y menos aún el método drawRect, pero la solución es fácil, hacemos una función o método que haga lo mismo y listo :D.

function drawRect(_mc:MovieClip, _nX:Number, _nY:Number, _nW:Number, _nH:Number):Void
{
	_mc.moveTo(_nX, _nY);
	_mc.lineTo(_nX + _nW, _nY);
	_mc.lineTo(_nX + _nW, _nY + _nH);
	_mc.lineTo(_nX, _nY + _nH);
	_mc.lineTo(_nX, _nY);
}

CÓDIGO COMPLETO

A continuación el código en ActionScript 3.0:

package
{
	import flash.display.MovieClip;
	import flash.display.Shape;
	import flash.display.Sprite;
	import flash.events.Event;

	public class Car extends MovieClip
	{
		private var car:Sprite;

		private var lights:Shape;
		private var bar:Shape;
		private var structure:Shape;
		private var wheels:Shape;

		private var nCounter:uint;

		public function Car():void
		{
			this.drawCar();

			this.nCounter = 0;

			this.addEventListener(Event.ENTER_FRAME, doOnEnterFrame);
		}

		private function drawCar():void
		{
			this.car = new Sprite();

			this.lights = new Shape();
			this.bar = new Shape();
			this.structure = new Shape();
			this.wheels = new Shape();

			//Chasis
			this.wheels.graphics.beginFill(0x1E1E1E);
			this.wheels.graphics.drawRect(38, 146, 316, 28);

			this.wheels.graphics.beginFill(0x1E1E1E);
			this.wheels.graphics.drawRect(157, 172, 78, 6);

			//Llanta izquierda
			this.wheels.graphics.beginFill(0x333333);
			this.wheels.graphics.drawRect(28, 132, 45, 68);

			//Llanta derecha
			this.wheels.graphics.beginFill(0x333333);
			this.wheels.graphics.drawRect(318, 132, 45, 68);

			//Carrosería
			this.structure.graphics.beginFill(0xFF0000);
			this.structure.graphics.drawRect(42, 0, 308, 166);

			//Cristal trasero
			this.structure.graphics.beginFill(0x70A9FE);
			this.structure.graphics.drawRect(49, 7, 293, 68);

			//Retrovisor izquierdo
			this.structure.graphics.beginFill(0xFF0000);
			this.structure.graphics.drawRect(0, 65, 42, 21);

			this.structure.graphics.beginFill(0x70A9FE);
			this.structure.graphics.drawRect(3, 68, 35, 15);

			//Retrovisor derecho
			this.structure.graphics.beginFill(0xFF0000);
			this.structure.graphics.drawRect(350, 65, 42, 21);

			this.structure.graphics.beginFill(0x70A9FE);
			this.structure.graphics.drawRect(353, 68, 35, 15);

			//Luz izquierda
			this.lights.graphics.beginFill(0xFF9900);
			this.lights.graphics.drawRect(46, 100, 34, 18);

			//Luz derecha
			this.lights.graphics.beginFill(0xFF9900);
			this.lights.graphics.drawRect(312, 100, 34, 18);

			//Defensa
			this.bar.graphics.beginFill(0x808080);
			this.bar.graphics.drawRect(38, 124, 316, 28);

			//Matrícula
			this.bar.graphics.beginFill(0xFFFFFF);
			this.bar.graphics.drawRect(157, 128, 78, 20);

			this.car.addChild(this.wheels);
			this.car.addChild(this.structure);
			this.car.addChild(this.bar);
			this.car.addChild(this.lights);

			this.car.scaleX = 0.5;
			this.car.scaleY = 0.5;

			this.addChild(this.car);
		}

		private function doOnEnterFrame(_oEvent:Event):void
		{
			this.nCounter++;
			if(this.nCounter % 4 == 0)
			{
				this.lights.y = (this.lights.y == 0) ? 3: 0;
				this.structure.y = (this.structure.y == 0) ? -3: 0;
				this.bar.y = (this.bar.y == 0) ? 2: 0;
			}
		}
	}
}

Y a continuación el código en ActionScript 2.0:

import gs.TweenLite;

var nColor1:Number = 0xFFFFFF;
var nColor2:Number = 0xCCCCCC;
var nColor3:Number = 0xFF0000;
var nColor4:Number = 0xFFFFFF;

var nColorSky:Number = 0x0066FF;
var nColorGrass:Number = 0x65FF00;

var nWidthSky:Number = Stage.width;
var nHeigthSky:Number = 80;

var nWidthGrass:Number = Stage.width;
var nHeigthGrass:Number = 170;

var nWidthBorderLine:Number = 30;
var nWidthMiddleLine:Number = 8;
var nWidthCenterLine:Number = 140;
var nHeigthLine:Number = 2.5;

var nTotalLines:Number = 68;

var nCounter:Number = 0;
var nFramesToUpdateCircuit:Number = 3;
var nFramesToUpdateCar:Number = 5;

var mcSky:MovieClip;
var mcGrass:MovieClip;
var mcCircuit:MovieClip;

var mcCar:MovieClip;

var mclights:MovieClip;
var mcBar:MovieClip;
var mcStructure:MovieClip;
var mcWheels:MovieClip;

this.create();

function create():Void
{
	Key.addListener(this);

	this.mcSky = this.createEmptyMovieClip("mcSky", 1);
	this.mcGrass = this.createEmptyMovieClip("mcGrass", 2);
	this.mcCircuit = this.createEmptyMovieClip("mcCircuit", 3);

	this.mcSky.beginFill(this.nColorSky, 100);
	this.drawBox(this.mcSky, this.nWidthSky, this.nHeigthSky);
	this.mcSky.endFill();

	this.mcGrass.beginFill(this.nColorGrass, 100);
	this.drawBox(this.mcGrass, this.nWidthGrass, this.nHeigthGrass);
	this.mcGrass.endFill();

	this.mcGrass._y = this.nHeigthSky;
	this.mcCircuit._y = this.nHeigthSky;

	for (var i:Number = 0; i < this.nTotalLines; i++)
	{
		var nType:Number = ((i % 2) == 0) ? 1: 0;
		var mc:MovieClip = this.createLine(nType);
		mc._xscale = 100 + (i * 2);
		mc._x = Math.round((Stage.width - mc._width) / 2)
		mc._y = i * this.nHeigthLine;
		mc.nPosOriX = mc._x;
	}

	this.drawCar();
	this.mcCar._xscale = 40;
	this.mcCar._yscale = 40;
	this.mcCar._x = (Stage.width - this.mcCar._width ) / 2;
	this.mcCar._y = 100;
	this.mcCar.nPosOriX = this.mcCar._x;
	this.mcCar.nPosOriY = this.mcCar._y;

	this.mcInstructions.swapDepths(this.getNextHighestDepth());
}

function createLine(_nType:Number):MovieClip
{
	var nDepth:Number = this.mcCircuit.getNextHighestDepth();
	var mcLine:MovieClip = this.mcCircuit.createEmptyMovieClip("mcLine_" + String(nDepth), nDepth);
	var mcLine1:MovieClip = mcLine.createEmptyMovieClip("mcLine1", 1);
	var mcLine2:MovieClip = mcLine.createEmptyMovieClip("mcLine2", 2);

	this.contructLine(mcLine1, _nType);
	this.contructLine(mcLine2, _nType + 1);

	mcLine2._visible = false;

	return mcLine;
}

function contructLine(_mc:MovieClip, _nType:Number):Void
{
	var mcBox1:MovieClip = _mc.createEmptyMovieClip("mcBox1", 1);
	var mcBox2:MovieClip = _mc.createEmptyMovieClip("mcBox2", 2);
	var mcBox3:MovieClip = _mc.createEmptyMovieClip("mcBox3", 3);

	var nColor:Number = (_nType == 1) ? this.nColor1: this.nColor3;

	mcBox1.beginFill(nColor, 100);
	this.drawBox(mcBox1, this.nWidthBorderLine, this.nHeigthLine);
	mcBox1.endFill();

	mcBox2.beginFill(this.nColor2, 100);
	this.drawBox(mcBox2, this.nWidthCenterLine, this.nHeigthLine);
	mcBox2.endFill();

	mcBox3.beginFill(nColor, 100);
	this.drawBox(mcBox3, this.nWidthBorderLine, this.nHeigthLine);
	mcBox3.endFill();

	mcBox2._x = this.nWidthBorderLine;
	mcBox3._x = this.nWidthBorderLine + this.nWidthCenterLine;

	if(_nType == 1)
	{
		var mcBox4:MovieClip = _mc.createEmptyMovieClip("mcBox4", 4);
		mcBox4.beginFill(nColor, 100);
		this.drawBox(mcBox4, this.nWidthMiddleLine, this.nHeigthLine);
		mcBox4.endFill();

		mcBox4._x = (_mc._width - mcBox4._width) / 2;
	}
}

function drawBox(_mc:MovieClip, _nWidth:Number, _nHeigth:Number):Void
{
	_mc.lineTo(_nWidth, 0);
	_mc.lineTo(_nWidth, _nHeigth);
	_mc.lineTo(0, _nHeigth);
	_mc.lineTo(0, 0);
}

function onEnterFrame(_mc:MovieClip):Void
{
	this.nCounter++
	if(this.nCounter % this.nFramesToUpdateCircuit == 0)
	{
		for (var i:Number = 0; i < this.nTotalLines; i++)
		{
			var mcLine:MovieClip = this.mcCircuit["mcLine_" + String(i)];
			mcLine.mcLine1._visible = !mcLine.mcLine1._visible;
			mcLine.mcLine2._visible = !mcLine.mcLine2._visible;
		}
	}

	if(this.nCounter % this.nFramesToUpdateCar == 0)
	{
		this.mcLights._y = (this.mcLights._y == 0) ? 3: 0;
		this.mcStructure._y = (this.mcStructure._y == 0) ? -3: 0;
		this.mcBar._y = (this.mcBar._y == 0) ? 2: 0;
	}
}

function moveLeft():Void
{
	var r:Number = 1.5;
	for (var i:Number = 0; i < this.nTotalLines; i++)
	{
		var mc:MovieClip = this.mcCircuit["mcLine_" + String(i)];
		TweenLite.to(mc, 1, { _x:mc.nPosOriX - (this.nTotalLines - i) * r } );
		r -= 0.01;
	}
	TweenLite.to(this.mcCar, 1, { _x:this.mcCar.nPosOriX - 40, _y:this.mcCar.nPosOriY + 10 } );
}

function moveRight():Void
{
	var r:Number = 1.5;
	for (var i:Number = 0; i < this.nTotalLines; i++)
	{
		var mc:MovieClip = this.mcCircuit["mcLine_" + String(i)];
		TweenLite.to(mc, 1, { _x:mc.nPosOriX + (this.nTotalLines - i) * r } );
		r -= 0.01;
	}
	TweenLite.to(this.mcCar, 1, { _x:this.mcCar.nPosOriX + 40, _y:this.mcCar.nPosOriY + 10 } );
}

function returnCenter():Void
{
	for (var i:Number = 0; i < this.nTotalLines; i++)
	{
		var mc:MovieClip = this.mcCircuit["mcLine_" + String(i)];
		TweenLite.to(mc, 1, { _x:mc.nPosOriX } );
	}
	TweenLite.to(this.mcCar, 1, { _x:this.mcCar.nPosOriX, _y:this.mcCar.nPosOriY } );
}

function onKeyDown():Void
{
	if(Key.isDown(Key.LEFT))
	{
		this.moveLeft();
	}
	else if(Key.isDown(Key.RIGHT))
	{
		this.moveRight();
	}
	else if(Key.isDown(Key.UP))
	{
		this.returnCenter();
	}
}

function drawCar():Void
{
	this.mcCar = this.createEmptyMovieClip("mcCar", 4);

	this.mcLights = this.mcCar.createEmptyMovieClip("mcLights", 4);
	this.mcBar = this.mcCar.createEmptyMovieClip("mcBar", 3);
	this.mcStructure = this.mcCar.createEmptyMovieClip("mcStructure", 2);
	this.mcWheels = this.mcCar.createEmptyMovieClip("mcWheels", 1);

	//Chasis
	this.mcWheels.beginFill(0x1E1E1E);
	this.drawRect(this.mcWheels, 38, 146, 316, 28);

	this.mcWheels.beginFill(0x1E1E1E);
	this.drawRect(this.mcWheels, 157, 172, 78, 6);

	//Llanta izquierda
	this.mcWheels.beginFill(0x333333);
	this.drawRect(this.mcWheels, 28, 132, 45, 68);

	//Llanta derecha
	this.mcWheels.beginFill(0x333333);
	this.drawRect(this.mcWheels, 318, 132, 45, 68);

	//Carrosería
	this.mcStructure.beginFill(0xFF0000);
	this.drawRect(this.mcStructure, 42, 0, 308, 166);

	//Cristal trasero
	this.mcStructure.beginFill(0x70A9FE);
	this.drawRect(this.mcStructure, 49, 7, 293, 68);

	//Retrovisor izquierdo
	this.mcStructure.beginFill(0xFF0000);
	this.drawRect(this.mcStructure, 0, 65, 42, 21);

	this.mcStructure.beginFill(0x70A9FE);
	this.drawRect(this.mcStructure, 3, 68, 35, 15);

	//Retrovisor derecho
	this.mcStructure.beginFill(0xFF0000);
	this.drawRect(this.mcStructure, 350, 65, 42, 21);

	this.mcStructure.beginFill(0x70A9FE);
	this.drawRect(this.mcStructure, 353, 68, 35, 15);

	//Luz izquierda
	this.mcLights.beginFill(0xFF9900);
	this.drawRect(this.mcLights, 46, 100, 34, 18);

	//Luz derecha
	this.mcLights.beginFill(0xFF9900);
	this.drawRect(this.mcLights, 312, 100, 34, 18);

	//Defensa
	this.mcBar.beginFill(0x808080);
	this.drawRect(this.mcBar, 38, 124, 316, 28);

	//Matrícula
	this.mcBar.beginFill(0xFFFFFF);
	this.drawRect(this.mcBar, 157, 128, 78, 20);
}

function drawRect(_mc:MovieClip, _nX:Number, _nY:Number, _nW:Number, _nH:Number):Void
{
	_mc.moveTo(_nX, _nY);
	_mc.lineTo(_nX + _nW, _nY);
	_mc.lineTo(_nX + _nW, _nY + _nH);
	_mc.lineTo(_nX, _nY + _nH);
	_mc.lineTo(_nX, _nY);
}

RESULTADO

El resultado final es una bonita carretera con su césped, su cielo y un coche que da saltitos, jejeje 😀

Circuito con coche en ActionScript 2.0

El resultado en ActionScript 3.0 para generar el coche es el siguiente:

Coche programado con ActionScript 3.0

DESCARGAS

Tenemos los ficheros para la versión en ActionScript 2.0 y para los de ActionScript 3.0:

Entradas relacionadas:

Saludos

Categories
Flash

Circuito de carreras en Flash con ActionScript

Out Run

En un proyecto que participé hace poco tuvimos que hacer un circuito de carreras  y aunque parece increíble no encontré algo por ahí que me sirviera de base, así que al final me lo tuve que cocinar.

Dentro de los requisitos técnicos tenía que ser para Flash Player 7, con lo cual no podía utilizar la Clase BitmapData de AS2 y muchísimo menos utilizar AS3, así que la cosa se ponía más chunga, pero bueno, sino donde queda la gracia. 😛

Teníamos en la mente el mítico juego Out Run y queríamos conseguir algo como eso. Aunque durante la investigación vimos las maravillas de AS3 o las posibilidades al utilizar la Clase BitmapData con el motor del modo 7, pero nada, donde manda capitán no manda marinero, así que a buscarse la vida.

El resultado fué el siguiente, bueno, este realmente no es, esta es una versión lite que programé en mis mañanas de tren, jejeje. Mi lado friki me obligó a hacerlo todo con programación, así que el código se puede copiar, pegar y compilar sin problema.

NOTA:

Utilizo la TweenLite así que no funciona tal cual, hace falta tener la librería TweenLite. 😛

CÓDIGO

import gs.TweenLite;

var nColor1:Number = 0xFFFFFF;
var nColor2:Number = 0xCCCCCC;
var nColor3:Number = 0xFF0000;
var nColor4:Number = 0xFFFFFF;

var nColorSky:Number = 0x0066FF;
var nColorGrass:Number = 0x65FF00;

var nWidthSky:Number = Stage.width;
var nHeigthSky:Number = 80;

var nWidthGrass:Number = Stage.width;
var nHeigthGrass:Number = 170;

var nWidthBorderLine:Number = 30;
var nWidthMiddleLine:Number = 8;
var nWidthCenterLine:Number = 140;
var nHeigthLine:Number = 2.5;

var nTotalLines:Number = 68;

var nCounter:Number = 0;
var nFramesToUpdate:Number = 3;

var mcSky:MovieClip;
var mcGrass:MovieClip;
var mcCircuit:MovieClip;

this.create();

function create():Void
{
	Key.addListener(this);

	this.mcSky = this.createEmptyMovieClip("mcSky", 1);
	this.mcGrass = this.createEmptyMovieClip("mcGrass", 2);
	this.mcCircuit = this.createEmptyMovieClip("mcCircuit", 3);

	this.mcSky.beginFill(this.nColorSky, 100);
	this.drawBox(this.mcSky, this.nWidthSky, this.nHeigthSky);
	this.mcSky.endFill();

	this.mcGrass.beginFill(this.nColorGrass, 100);
	this.drawBox(this.mcGrass, this.nWidthGrass, this.nHeigthGrass);
	this.mcGrass.endFill();

	this.mcGrass._y = this.nHeigthSky;
	this.mcCircuit._y = this.nHeigthSky;

	for (var i:Number = 0; i < this.nTotalLines; i++)
	{
		var nType:Number = ((i % 2) == 0) ? 1: 0;
		var mc:MovieClip = this.createLine(nType);
		mc._xscale = 100 + (i * 2);
		mc._x = Math.round((Stage.width - mc._width) / 2)
		mc._y = i * this.nHeigthLine;
		mc.nPosOriX = mc._x;
	}
}

function createLine(_nType:Number):MovieClip
{
	var nDepth:Number = this.mcCircuit.getNextHighestDepth();
	var mcLine:MovieClip = this.mcCircuit.createEmptyMovieClip("mcLine_" + String(nDepth), nDepth);
	var mcLine1:MovieClip = mcLine.createEmptyMovieClip("mcLine1", 1);
	var mcLine2:MovieClip = mcLine.createEmptyMovieClip("mcLine2", 2);

	this.contructLine(mcLine1, _nType);
	this.contructLine(mcLine2, _nType + 1);

	mcLine2._visible = false;

	return mcLine;
}

function contructLine(_mc:MovieClip, _nType:Number):Void
{
	var mcBox1:MovieClip = _mc.createEmptyMovieClip("mcBox1", 1);
	var mcBox2:MovieClip = _mc.createEmptyMovieClip("mcBox2", 2);
	var mcBox3:MovieClip = _mc.createEmptyMovieClip("mcBox3", 3);

	var nColor:Number = (_nType == 1) ? this.nColor1: this.nColor3;

	mcBox1.beginFill(nColor, 100);
	this.drawBox(mcBox1, this.nWidthBorderLine, this.nHeigthLine);
	mcBox1.endFill();

	mcBox2.beginFill(this.nColor2, 100);
	this.drawBox(mcBox2, this.nWidthCenterLine, this.nHeigthLine);
	mcBox2.endFill();

	mcBox3.beginFill(nColor, 100);
	this.drawBox(mcBox3, this.nWidthBorderLine, this.nHeigthLine);
	mcBox3.endFill();

	mcBox2._x = this.nWidthBorderLine;
	mcBox3._x = this.nWidthBorderLine + this.nWidthCenterLine;

	if(_nType == 1)
	{
		var mcBox4:MovieClip = _mc.createEmptyMovieClip("mcBox4", 4);
		mcBox4.beginFill(nColor, 100);
		this.drawBox(mcBox4, this.nWidthMiddleLine, this.nHeigthLine);
		mcBox4.endFill();

		mcBox4._x = (_mc._width - mcBox4._width) / 2;
	}
}

function drawBox(_mc:MovieClip, _nWidth:Number, _nHeigth:Number):Void
{
	_mc.lineTo(_nWidth, 0);
	_mc.lineTo(_nWidth, _nHeigth);
	_mc.lineTo(0, _nHeigth);
	_mc.lineTo(0, 0);
}

function onEnterFrame(_mc:MovieClip):Void
{
	this.nCounter++
	if(this.nCounter % this.nFramesToUpdate == 0)
	{
		for (var i:Number = 0; i < this.nTotalLines; i++)
		{
			var mcLine:MovieClip = this.mcCircuit["mcLine_" + String(i)];
			mcLine.mcLine1._visible = !mcLine.mcLine1._visible;
			mcLine.mcLine2._visible = !mcLine.mcLine2._visible;
		}
	}
}

function moveLeft():Void
{
	var r:Number = 1.5;
	for (var i:Number = 0; i < this.nTotalLines; i++)
	{
		var mc:MovieClip = this.mcCircuit["mcLine_" + String(i)];
		TweenLite.to(mc, 1, { _x:mc.nPosOriX - (this.nTotalLines - i) * r } );
		r -= 0.01;
	}
}

function moveRight():Void
{
	var r:Number = 1.5;
	for (var i:Number = 0; i < this.nTotalLines; i++)
	{
		var mc:MovieClip = this.mcCircuit["mcLine_" + String(i)];
		TweenLite.to(mc, 1, { _x:mc.nPosOriX + (this.nTotalLines - i) * r } );
		r -= 0.01;
	}
}

function returnCenter():Void
{
	for (var i:Number = 0; i < this.nTotalLines; i++)
	{
		var mc:MovieClip = this.mcCircuit["mcLine_" + String(i)];
		TweenLite.to(mc, 1, { _x:mc.nPosOriX } );
	}
}

function onKeyDown():Void
{
	if(Key.isDown(Key.LEFT))
	{
		this.moveLeft();
	}
	else if(Key.isDown(Key.RIGHT))
	{
		this.moveRight();
	}
	else if(Key.isDown(Key.UP))
	{
		this.returnCenter();
	}
}

RESULTADO

Circuito de carreras en Flash con ActionScript

DESCARGAS

Para el que quiera el fla aquí está.

Saludos!!!

Entradas relacionadas: