This is a carry-over post from my last blog and is ages old.

This application was created from scratch (without any 3rd party libraries) for a speed ActionScript 3 programming challenge. At the time, I have used AS2 but wanted to write this to see how well AS3 can utilize
advanced class constructs and other methods found in today’s mature OOP languages.

It was great fun to write, and it truly illustrates the speed boost AS3 delivers!

Version 0.85:

* Separation between NPC class and document class more defined
* +25% Speed increase
* NPCs now have sprite animations depending on the current state.

AS3 Demo – SWF
Modified: June 27, 2007: 3:10pm

[kml_flashembed movie="http://www.jadbox.com/wp-content/uploads/2008/07/jd_as3demo.swf" height="400" width="550" /]

MainAI.as
Modified: June 27, 2007: 3:10pm

// Demonstration (c) to Jonathan A Dunlap

// jonathanadunlap@gmail.com

package {

import flash.display.*;

import flash.text.TextField;

import flash.events.*;

import flash.utils.*;

public class MainAI extends MovieClip { // Main game initialization

public var group:Array = new Array();

public var game:Sprite = new Sprite();

public function MainAI():void {

game.blendMode = BlendMode.MULTIPLY;

this.stop();addChild(game); // General starters

for (var i:int=0; i < 20; i++) create_npc();

addEventListener(Event.ENTER_FRAME, ai_handler);

setInterval(create_npc, 1050);

}

public function create_npc():void {group.push(new npc(this.game));}

public function ai_handler(evt:Event):void { // Handle NPC movement and collision

for(var i:int=0;i<group.length-1;i++){

if (group[i]!=null && !group[i].is_saying_hello()) {

group[i].action();

for(var o:int=i+1;o<group.length;o++)

if (group[o]!=null && o != i && group[i].distanceToNpc(group[o])<=65 )

if(group[i].hitTestObject(group[o])) {

group[i].revert();group[o].revert();

group[i].actionMoveAway(group[o]);

group[o].actionMoveAway(group[i]);

group[i].actionSayHi();

}

if(group[i].alpha <= 0) { // Delete NPCs will several collisions

group[i].del();

group[group.indexOf(group[i])]=null; // Remove reference to object to clean memory

group.splice(group.lastIndexOf(null),1); // Clean up array

}

}

}

}

}

}

npc.as
Modified: June 27, 2007: 3:10pm

// See MainAI.as for notes.

//

// Tip: NPC stands for Non-Player Character

//

package {

import flash.display.*;

import flash.text.TextField;

import flash.events.TimerEvent;

import flash.utils.*;

public class npc extends MovieClip { // Initialize NPC unit

private var toy:int, tox:int,oldx:int,oldy:int,targetTimer:Timer,myparent:DisplayObjectContainer;

public const stateWonder:int=0;public const stateSayHi:int=1;

public function npc(aparent:DisplayObjectContainer):void {

myparent = aparent;

myparent.addChild(this);

this.blendMode = BlendMode.DARKEN;

this.posx = rand(this.poswidth,stage.stageWidth-this.poswidth);

this.posy = rand(this.posheight,stage.stageHeight-this.posheight);

targetTimer = new Timer(1800, 0);

targetTimer.addEventListener("timer", findtarget);

targetTimer.start();

}

public function action():void {

this.followWavePoint();

}

private function followWavePoint():void {

var oldx:int = this.posx;

this.posx -=point_axis_dist(this.x, this.tox, 5);

if(oldx==this.x) this.posy -= point_axis_dist(this.y, this.toy, 5);

}

private function point_axis_dist(axis1:int,axis2:int,distance:int):int
{ // Find if NPC is roughly on the correct traveling path

var subaxis:int = axis1-axis2;

var absaxis:int = Math.abs(subaxis);

if(absaxis >= distance) {if(absaxis==subaxis) return 1; else return -1;}

return 0;

}

public function del():void {

this.targetTimer.stop();

this.myparent.removeChild(this);

}

public function get poswidth():int {

return this.width/2;

}

public function get posheight():int {

return this.height/2;

}

public function findtarget(event:TimerEvent):void { // Find a new random location to travel to

this.tox = rand(this.poswidth,stage.stageWidth-this.poswidth);

this.toy = rand(this.posheight,stage.stageHeight-this.posheight);

}

public function actionSayHi():void {

this.alpha -= 0.25;

this.bump_say();

}

public function actionMoveAway(offender:npc):void {

if(Math.random() < 0.5) {

if(this.x >= offender.x) this.tox += this.width*2;

else if(this.x < offender.x) this.tox -= this.width*2;

} else {

if(this.y >= offender.y) this.toy += this.height*2;

else if(this.y < offender.y) this.toy -= this.height*2;

}

}

public function revert():void {

this.posx = this.oldx;this.posy=this.oldy;

}

public function set posx(x:int):void{

if(x > stage.stageWidth-this.poswidth) x = stage.stageWidth-this.poswidth;

else if(x < this.poswidth) x = this.poswidth;

else if(x < this.x) this.walk_left();

else if(x > this.x) this.walk_right();

this.oldx = this.x;

this.x = x;

}

public function set posy(y:int):void{

if(y > stage.stageHeight-this.posheight) y = stage.stageHeight-this.posheight;

else if(y < this.posheight) y = this.posheight;

else if(y < this.y) this.walk_up();

else if(y > this.y) this.walk_down();

this.oldy = this.y;

this.y = y;

}

public function get posx():int{return this.x;}

public function get posy():int{return this.y;}

private function walk_left():void{ // NPC animation trigger states

if(this.currentFrame < 24 || this.currentFrame > 34) this.gotoAndPlay(24);

}

private function walk_right():void{

if(this.currentFrame < 35 || this.currentFrame > 45) this.gotoAndPlay(35);

}

private function walk_down():void{

if(this.currentFrame > 12) this.gotoAndPlay(1);

}

private function walk_up():void{

if(this.currentFrame < 13 || this.currentFrame > 23) this.gotoAndPlay(13);

}

private function bump_say():void{

this.gotoAndPlay(46)

}

public function is_saying_hello():Boolean{

if(this.currentFrame > 45 && this.currentFrame < 57) return true;

return false;

}

public function distanceToNpc(other:npc):int {

return Math.abs(this.x-other.x)+Math.abs(this.y-other.y);

}

private function rand(min:int, max:int):int

{

return min + Math.floor(Math.random() * (max - min + 1));

}

private namespace npcNS;

}

}

Author: Jonathan Dunlap
Jonathan is a veteran software architect, author of IsoHill, humanitarian, and has worked with Bigpoint Inc, CrowdStar, ePrize, and Microsoft.
Be Sociable, Share!

Tags: ,