I am going to dump/show some snippets and codes in flash that i have laying around my PC for a while. They will be in no particular order.
0x00 - What programs i use.
To develop games in Flash you can use a whole bunch of different programs, some of them expensive some of them free. I prefer free programs so i use Flex for compiling my Flash source code into a playable swf. As my IDE i use FlashDevelop which already comes with Flex so you only have to install one program.
0x01 - Collision check between two circles
When creating a game you often want to check for a collision between two objects. The most simple way is to this with circles as this simply uses Pythagorean theorem (a² + b² = c²).
Main.as - The main code which does the checks and outputs some information. It checks the position of the mouse/player every frame and calculates the distance between the circles. The red line that is shown is the actual distance and once the circles collide the enemy changes its color.
Code:
package
{
import flash.display.Sprite;
import flash.events.Event;
import flash.events.KeyboardEvent;
import flash.events.MouseEvent;
import flash.text.TextField;
public class Main extends Sprite
{
private var player:Actor;
private var enemy:Actor;
private var info:TextField;
public function Main():void
{
// Setup player
player = new Actor(0xff0000);
player.x = 300;
player.y = 200;
addChild(player);
// Setup enemy
enymy = new Actor(0x0000ff);
enemy.x = 400;
enemy.y = 300;
addChild(enemy);
// Setup info text
info = new TextField();
info.width = 800;
info.height = 600;
info.selectable = false;
addChild(info);
// Start event listener
stage.addEventListener(Event.ENTER_FRAME, EnterFrameHandler);
}
private function EnterFrameHandler(e:Event):void
{
// Move player to mouse position
player.x = stage.mouseX;
player.y = stage.mouseY;
// Rotate enemy so it faces the player
enemy.rotation = Math.atan2(player.y - enemy.y, player.x - enemy.x) / Math.PI * 180;
// Calculate a, b and c
var xdif:Number = Math.round(enemy.x - player.x); // a
var ydif:Number = Math.round(enemy.y - player.y); // b
var dist:Number = Math.sqrt(Math.pow(xdif, 2) + Math.pow(ydif, 2)); // c
// Check for collision
if (dist < 30)
{
enemy.col = 0xff00ff;
}
else if (enemy.col != 0x0000ff)
{
enemy.col = 0x0000ff;
}
// Update info text
info.text = "Player X: " + player.x + "\nPlayer Y: " + player.y +
"\nEnemy X: " + enemy.x + "\nEnemy Y: " + enemy.y +
"\na (blue): " + xdif + "\nb (green): " + ydif + "\nc (red): " + dist +
"\nCollides: " + (dist < 30 ? "true" : "false") +
"\nRad: " + Math.atan2(player.y - enemy.y, player.x - enemy.x);
// Update info graphics
graphics.clear();
graphics.lineStyle(2, 0xff0000);
graphics.moveTo(player.x, player.y);
graphics.lineTo(enemy.x, enemy.y);
graphics.drawCircle( (player.x + xdif / 2), (player.y + ydif / 2), 1);
graphics.lineStyle(2, 0x00ff00);
graphics.moveTo(player.x, player.y);
graphics.lineTo(player.x, enemy.y);
graphics.lineStyle(2, 0x0000ff);
graphics.lineTo(enemy.x, enemy.y);
}
}
}
Actor.as - Simple class that represents the circles
Code:
package
{
import flash.display.Sprite;
public class Actor extends Sprite
{
private var _col:uint;
public function Actor(color:uint)
{
_col = color;
Draw();
}
private function Draw():void
{
graphics.clear();
graphics.beginFill(_col, 0.2);
graphics.lineStyle(1, _col, 0.5);
graphics.drawCircle( 0, 0, 15);
graphics.moveTo(0, 0);
graphics.lineTo(15, 0);
graphics.endFill();
}
public function set col(value:uint) : void
{
_col = value;
Draw();
}
public function get col():uint { return _col; }
}
Compiled SWF: http://www.mediafire.com/?14668zza2e14zws
0x02 - Top down world movement
In games where you look on the player from above you may want to have a world/level that is bigger then the screen. So at some point you want to scroll the background and everything else with the camera fixed at the player. With Flash this is actually not that hard as you can work with layers. At the edges of the map it actually moves the player otherwise the background gets moved so it looks like the camera follows the player.
So i use a Sprite which holds all map images and on top of that i add the actual player. Here is an example of how this could look like. Player and map would be sprites and speed, screen_height, screen_width would be numbers.
Code:
/** VARIABLES EXAMPLES **/
var player:Sprite = new Sprite();
var map:Sprite = new Sprite();
var speed = 5;
var screen_width = 800;
var screen_height = 600;
/** MOVING UP **/
// Player further than half the screen down. -> Move player up.
if (player.y > screen_height / 2)
{
player.y -= speed;
}
// Map top border not at the top border of the screen yet. -> Move map down.
else if (map.y != 0)
{
map.y += speed;
}
// Player not at top border of the map yer. -> Move player up.
else if (player.y - player.height / 2 > 0)
{
player.y -= speed;
}
/** MOVING DOWN **/
if (player.y < screen_height / 2)
{
player.y += speed;
}
else if (map.height > screen_height)
{
map.y -= speed;
}
else if (player.y + player.height / 2 < screen_height)
{
player.y += speed;
}
/** MOVING LEFT **/
if (player.x > screen_width / 2)
{
player.x -= speed;
}
else if (map.x != 0)
{
map.x += speed;
}
else if (player.x - player.width / 2 > 0)
{
player.x -= speed;
}
/** MOVING RIGHT **/
if (player.x < screen_width / 2)
{
player.x += speed;
}
else if (map.height > screen_width)
{
map.x -= speed;
}
else if (player.x + player.height / 2 < screen_width)
{
player.x += speed;
}
I uploaded an example of how this could look like. It has a bit more stuff build in like automatically removing unseen Sprites when leaving the screen. You can observe that in fullscreen mode, just walk over the grass field using WASD.
Compiled SWF: http://www.mediafire.com/?c1dr5d55pgradi6
0x03 - Mouse speed and circles.
Sometimes you might want to know how fast the player has moved the mouse. Calculating this in Flash is actually pretty easy. Flash is frame based and an swf usually has like 30 fps and on each frame you gonna get the mouse position. On the next frame you just calculate the difference between the X and Y position of the mouse to the previous position.
This can be done with a few lines of code, i made an example where a circle is drawn at the mouse position. The size of the circle is determined by the speed of the mouse. Originally i found something like that in a java example and converted it to flash.
Code:
package
{
import flash.display.Sprite;
import flash.events.Event;
import flash.ui.Mouse;
public class Main extends Sprite
{
private var pMouseX:Number = 0;
private var pMouseY:Number = 0;
private var speed:Number;
private var circles:Vector.<Sprite> = new Vector.<Sprite>;
public function Main():void
{
// Hide mouse
Mouse.hide();
// Set previous mouse positions.
pMouseX = mouseX;
pMouseY = mouseY;
addEventListener(Event.ENTER_FRAME, EnterFrame);
}
private function EnterFrame(e:Event):void
{
// Fade out circles
for (var i:uint = 0; i < circles.length; i++)
{
circles[i].alpha -= 0.001;
// Remove invisible circles
if (circles[i].alpha <= 0)
{
removeChild(circles[i]);
circles.splice(i, 1);
}
}
// Create a new circle
if (pMouseX != mouseX || pMouseY != mouseY)
{
// Calculate mouse "speed"
speed = (Math.abs(mouseX - pMouseX) + Math.abs(mouseY - pMouseY)) / 2;
// Set speed/size limit
speed = (speed < 5) ? 5 : speed;
speed = (speed > 50) ? 50 : speed;
// Create circle
var circle:Sprite = new Sprite();
circle.graphics.lineStyle(1, 0x000000, 1);
circle.graphics.beginFill(0xffffff, 1);
circle.graphics.drawCircle(0, 0, speed);
circle.x = mouseX;
circle.y = mouseY;
addChild(circle);
circles.push( circle );
// Set previous mouse positions.
pMouseX = stage.mouseX;
pMouseY = stage.mouseY;
}
}
}
}
Compiled SWF: http://www.mediafire.com/?b1fuoab9if0c4p5
Enhanced Version SWF: http://www.mediafire.com/?1sx1cfyte7494k0
0x04 - Input Management for Mouse and Keyboard.
Interacting with your Flash Application is rather easy as Flash already has some nice functions for this. You can create a function for every possible key that could be pressed. To make things even easier i use a simple class that handles all the Input. It stores all the pressed keys and if the mouse is pressed as well. This way you can check for pressed keys every frame in one funtion rather then adding a new event for every key that could be pushed down.
Many games you played probably use a similar class or technique to do this.
Input.as - The main input class
Code:
package
{
import flash.events.KeyboardEvent;
import flash.events.MouseEvent;
/**
* Input Manager
* @author ZuckeR
*/
public class Input
{
/**
* KEY CODES
* Unused should be uncommented for release version.
*/
static public const A:uint = 65;
//static public const B:uint = 66;
//static public const C:uint = 67;
static public const D:uint = 68;
//static public const E:uint = 69;
//static public const F:uint = 70;
//static public const G:uint = 71;
//static public const H:uint = 72;
//static public const I:uint = 73;
//static public const J:uint = 74;
//static public const K:uint = 75;
//static public const L:uint = 76;
//static public const M:uint = 77;
//static public const N:uint = 78;
//static public const O:uint = 79;
//static public const P:uint = 80;
//static public const Q:uint = 81;
//static public const R:uint = 82;
static public const S:uint = 83;
//static public const T:uint = 84;
//static public const U:uint = 85;
//static public const V:uint = 86;
static public const W:uint = 87;
//static public const X:uint = 88;
//static public const Y:uint = 89;
//static public const Z:uint = 90;
static public const LEFT:uint = 37;
static public const UP:uint = 38;
static public const RIGHT:uint = 39;
static public const DOWN:uint = 40;
//static public const N0:uint = 48;
//static public const N1:uint = 49;
//static public const N2:uint = 50;
//static public const N3:uint = 51;
//static public const N4:uint = 52;
//static public const N5:uint = 53;
//static public const N6:uint = 54;
//static public const N7:uint = 55;
//static public const N8:uint = 56;
//static public const N9:uint = 57;
//static public const SHIFT:uint = 16;
//static public const CTRL:uint = 17;
//static public const SPACE:uint = 32;
//private var keysDown:Array = [];
private var keysDown:Vector.<Boolean> = new Vector.<Boolean>(91);
public var mouseDown:Boolean = false;
public function Input():void
{
}
// Save pushed down keys
public function KeyDownHandler(e:KeyboardEvent):void
{
keysDown[e.keyCode] = true;
}
// Remove pushed down keys
public function KeyUpHandler(e:KeyboardEvent):void
{
keysDown[e.keyCode] = false;
}
// Check if key is pressed
public function KeyDown(key:uint):Boolean
{
return keysDown[key];
}
// Set mouse button to be pressed
public function MouseDownHandler(e:MouseEvent):void
{
mouseDown = true;
}
// Set mouse button to not be pressed
public function MouseUpHandler(e:MouseEvent):void
{
mouseDown = false;
}
}
}
Main.as - To be able to use the input you must register the EventHandlers. Then you could check the pressed keys with the Frame Handler and move your player or whatever accordingly.
Code:
package
{
import flash.display.Sprite;
import flash.events.Event;
import flash.events.KeyboardEvent;
import flash.events.MouseEvent;
import Input;
public class Main extends Sprite
{
public var input = new Input;
public function Main() : void
{
// Set Event handlers for input
stage.addEventListener(KeyboardEvent.KEY_DOWN, input.KeyDownHandler);
stage.addEventListener(KeyboardEvent.KEY_UP, input.KeyUpHandler);
addEventListener(MouseEvent.MOUSE_DOWN, input.MouseDownHandler);
addEventListener(MouseEvent.MOUSE_UP, input.MouseUpHandler);
// Frame handler
addEventListener(Event.ENTER_FRAME, EnterFrameListener);
}
private function EnterFrameListener(e:Event) : void
{
// A key check could look like this
if (input.KeyDown(Input.UP) || input.KeyDown(Input.W))
{
// Move player up
}
else if (input.KeyDown(Input.DOWN) || input.KeyDown(Input.S) )
{
// Move player down
}
// More code here...
}
}
}
It is pretty basic, just remember to uncomment keys in the input class that you want to use in the game. And register the EventHandlers for key input to stage so it will work everywhere. I had issues with this when using a simple "addEventListener()" rather than "stage.addEventListener()". That is pretty much it, it is reuseable and quite simple to add to an existing project. I have this whole class as a global library that gets included automatically by FlashDevelop if you want to use it.
No compiled swf, look at 0x03 which has this included for the player movement.
0x05 - A simple way to add pathfinding to your game.
I just found a link i had for a while about a class for pathfinding (http://www.dauntless.be/astar/). I just implemented it in an old project and now the enemy chases the player over the whole map. On the site you can find some code examples to try it out yourself and implement it in your own game in the future.
What it does is to actually split a map into several fields. You can choose how many that should be, thats quite easy with maps that use and place objects the same way. The example i uploaded shows this when you press T while in the "game". It uses solid objects which are 40x40 pixel and block the players movement.
The enemy now walks the given path until he finds the player, moving the player updates the path. It is a sloppy implementation and is not very organized, so now code this time just follow the instructions on the website.
Compiled SWF: http://www.mediafire.com/?cbi47bsnv2r2yya
More to come...