En este tutorial aprenderás a crear una Clase en Actionscript 3 que generará un juego de Pong totalmente adaptable.
Abre un nuevo documento de Actionscript y guardalo como Pong.as.
Ahora comenzaremos a programar la Clase.
Primero importamos los paquetes necesarios:
package
{
import flash.display.*;
import flash.ui.Mouse;
import flash.events.TimerEvent;
import flash.events.MouseEvent;
import flash.text.TextField;
import flash.text.TextFieldType;
import flash.text.TextFormat;
import flash.text.TextFieldAutoSize;
import flash.utils.Timer;
Para una descripción más detallada de lo que hace cada uno, puedes consultar la ayuda de Flash presionando F1.
Ahora nombramos la Clase, que será heredada de la Clase MovieClip para poder utilizar el método addChild().
public class Pong extends MovieClip
{
Procedemos a escribir la función constructora de la clase, que será la encargada de todo el proceso del juego.
public function Pong(bgColor:uint = 0x000000, playerColor:uint = 0xFFFFFF, enemyColor:uint = 0xFFFFFF, ballColor:uint = 0xFFFFFF, middleLineColor:uint = 0xFFFFFF, ballSpeed:int = 2, scoreColor:uint = 0xFFFFFF, msgColor:uint = 0xFFFFFF, msg:String = "Click here", scoreFont:String = "Arial", scoreSize:int = 30):void
{
Como puedes observar se han colocado varios parametros, que a su vez, han sido declarados como predeterminados, a continuación explicaré cada uno de ellos.
Todos los valores uint, son números Hexadecimales en formato 0x. Puedes utilizar cualquier color Hexadecimal.
- bgColor: Color del MovieClip que servirá como fondo del stage.
- playerColor: Color del jugador.
- enemyColor: Color del oponente.
- ballColor: Color de la bola.
- middleLineColor: Color de la linea que divide el stage.
- ballSpeed: Velocidad de la bola.
- scoreColor: El color de los marcadores.
- msgColor: Color del texto usado como mensaje para comenzar.
- msg: Mensaje para comenzar.
- scoreFont: La fuente que será utilizada en el marcador.
- scoreSize: Tamaño de la fuente de los marcadores.
Ocultamos el Context Menu y establecemos Constantes del tamaño del stage.
stage.showDefaultContextMenu = false;
const STAGE_WIDTH:int = stage.stageWidth;
const STAGE_HEIGHT:int = stage.stageHeight;
Ahora creamos el Fondo.
var bg:MovieClip = new MovieClip();
bg.graphics.beginFill(bgColor);
bg.graphics.drawRect(0, 0, STAGE_WIDTH, STAGE_HEIGHT);
bg.graphics.endFill();
addChild(bg);
Creamos el Jugador y al Oponente y los posicionamos.
var player:MovieClip = new MovieClip();
player.graphics.beginFill(playerColor);
player.graphics.drawRect(0, 0, 8, 50);
player.graphics.endFill();
player.x = player.width;
player.y = (STAGE_HEIGHT / 2) - (player.height / 2);
addChild(player);
var enemy:MovieClip = new MovieClip();
enemy.graphics.beginFill(enemyColor);
enemy.graphics.drawRect(0, 0, 8, 50);
enemy.graphics.endFill();
enemy.x = STAGE_WIDTH - enemy.width * 2;
enemy.y = (STAGE_HEIGHT / 2) - (enemy.height / 2);
addChild(enemy);
El siguiente código crea la bola y la posiciona.
var ball:MovieClip = new MovieClip();
ball.graphics.beginFill(ballColor);
ball.graphics.drawRect(0, 0, 10, 10);
ball.graphics.endFill();
ball.x = STAGE_WIDTH / 2 - ball.width / 2;
ball.y = STAGE_HEIGHT / 2 - ball.height / 2;
addChild(ball);
Ahora creamos la linea que divide el stage.
var middleLine:MovieClip = new MovieClip();
middleLine.graphics.lineStyle(2, middleLineColor);
middleLine.graphics.lineTo(0, STAGE_HEIGHT);
middleLine.x = STAGE_WIDTH / 2;
middleLine.y = 0;
addChild(middleLine);
Creamos una función que será ejecutada por un Evento Timer, ésta se encargará de que el Jugador sea manejado con el Mouse, además de establecer hasta donde se puede mover.
function playerMovement(event:TimerEvent):void
{
player.y = mouseY - player.height / 2;
if(player.y >= STAGE_HEIGHT - player.height)
{
player.y = STAGE_HEIGHT - player.height;
}
if(player.y <= 0) { player.y = 0;
}
}
La función siguiente se encarga de manejar al Oponente, también establece hasta donde se puede mover.
function enemyAI(event:TimerEvent):void
{
enemy.y = ball.y - enemy.height / 2;
if(enemy.y >= STAGE_HEIGHT - enemy.height)
{
enemy.y = STAGE_HEIGHT - enemy.height;
}
if(enemy.y <= 0) { enemy.y = 0;
}
}
Ahora creamos el código que manejará la Bola que será explicado con comentarios para una mejor comprensión.
ball.speed = ballSpeed; //Se establece la velocidad, tomada del Parámetro ballSpeed.
ball.dir = 0; //Se crea una variable que manejara la dirección de la Bola.
player.score = 0; //Estos son los marcadores al iniciar.
enemy.score = 0;
function ballMovement(event:TimerEvent):void
{
if(playin) //Se checa si el juego ha comenzado, esta variable será creada más adelante.
{
ball.x -= ball.speed; //Estos códigos mueven la Bola.
ball.y -= ball.dir;
}
if(ball.x <= player.x) //Si la Bola pasa por detras del Jugador
{ //o del Oponente, re reinicia la Bola.
enemy.score++;
restart();
}
if(ball.x >= enemy.x)
{
player.score++;
restart();
}
if(ball.y > (STAGE_HEIGHT - ball.height / 2)) //Estos códigos se encargan de hacer rebotar la Bola.
{
ball.dir *= -1;
}
if(ball.y < class="kw3">height / 2)
{
ball.dir *= -1;
}
}
Ahora checamos las colisiones, si la Bola colisiona con el Jugador o el Oponente, la velocidad será invertida para dirigirse hacia el lado contrario, y la dirección se generará aleatoriamente, si el número generado es positivo la dirección será hacia abajo y si es negativo hacia arriba.
function checkHit(event:TimerEvent):void
{
if(ball.hitTestObject(player) || ball.hitTestObject(enemy))
{
ball.speed *= -1;
ball.dir = (Math.random() * 1) + (Math.random() * -1);
}
}
El siguiente código crea los Marcadores y los posiciona, además de crear la función que se encargará de actualizarlos.
var scoreFormat:TextFormat = new TextFormat();
scoreFormat.color = scoreColor;
scoreFormat.font = scoreFont;
scoreFormat.size = scoreSize;
var playerScore:TextField = new TextField();
playerScore.autoSize = TextFieldAutoSize.CENTER;
playerScore.x = STAGE_WIDTH / 4;
playerScore.y = STAGE_HEIGHT / 10;
playerScore.selectable = false;
playerScore.defaultTextFormat = scoreFormat;
playerScore.type = TextFieldType.DYNAMIC;
addChild(playerScore);
var enemyScore:TextField = new TextField();
enemyScore.autoSize = TextFieldAutoSize.CENTER;
enemyScore.x = (STAGE_WIDTH) - (STAGE_WIDTH / 4)
enemyScore.y = STAGE_HEIGHT / 10;
enemyScore.selectable = false;
enemyScore.defaultTextFormat = scoreFormat;
enemyScore.type = TextFieldType.DYNAMIC;
addChild(enemyScore);
function scoreHandler(event:TimerEvent)
{
playerScore.text = player.score;
enemyScore.text = enemy.score;
}
Creamos el mensaje para comenzar, la variable que nos indicará si el juego ha comenzado y la función que se encargará de ocultar el Mouse, iniciar el Timer y borrar el mensaje de inicio.
var startMsg:TextField = new TextField();
var startFormat:TextFormat = new TextFormat();
startFormat.color = msgColor;
startFormat.bold = true;
startMsg.x = 0;
startMsg.y = (STAGE_HEIGHT) - (STAGE_HEIGHT / 12);
startMsg.selectable = false;
startMsg.type = TextFieldType.DYNAMIC;
startMsg.defaultTextFormat = startFormat;
startMsg.text = msg;
addChild(startMsg);
var playin:Boolean = false;
function startHandler(event:MouseEvent):void
{
Mouse.hide();
playin = true;
timer.start();
startMsg.text = "";
}
Ahora creamos la función de reinicio que se encargará de reestablecer valores cuando el Marcador se actualize.
function restart():void
{
ball.x = STAGE_WIDTH / 2 - ball.width / 2;
ball.y = STAGE_HEIGHT / 2 - ball.height / 2;
ball.speed = ballSpeed;
ball.dir = 0;
}
Por último, creamos el objeto Timer y añadimos los Listeners.
stage.addEventListener(MouseEvent.CLICK, startHandler);
var timer:Timer = new Timer(1, 0);
timer.addEventListener(TimerEvent.TIMER, playerMovement);
timer.addEventListener(TimerEvent.TIMER, enemyAI);
timer.addEventListener(TimerEvent.TIMER, ballMovement);
timer.addEventListener(TimerEvent.TIMER, checkHit);
timer.addEventListener(TimerEvent.TIMER, scoreHandler);
La Clase debe ser llamada por medio del cuadro de texto Document Class en el Panel de Propiedades de Flash, ya que el objeto stage no permite el uso de import en una Clase de este tipo.
Para modificar los Parámetros lo puedes hacer directamente desde la Clase.
Recuerda que el stage puede ser de cualquier tamaño, la Clase ajustará automáticamente los elementos.
0 comentarios: