Creating Enemy Cone of vision - artificial-intelligence

I am trying to create a cone of vision for my enemy class. Right now it checks to see if the player is within a radius before moving towards them and will move around randomly if they are not. I want to give it vision so the enemy does not always rotate towards the player.
Enemy Class
package
{
import flash.automation.ActionGenerator;
import flash.events.Event;
import flash.geom.Point;
public class Enemy extends GameObject
{
var isDead:Boolean = false;
var speed:Number = 3;
var originalValue:Number = 50;
var changeDirection:Number = originalValue;
var checkDirection:Number = 49;
var numberGen:Number;
//var startTime:int = getTimer();
//var $timer = getTimer();
//var myTimer:int = getTimer();
//var moveTimer:int = timer - $timer;
public function Enemy()
{
super();
target = target_mc;
}
override public function update():void
{
movement();
}
private function movement():void
{
if (changeDirection >= 0)
{
if (changeDirection > checkDirection)
{
numberGen = (Math.random() * 360) / 180 * Math.PI;
}
var velocity:Point = new Point();
var $list:Vector.<GameObject > = getType(Player);
var $currentDistance:Number = Number.MAX_VALUE;
for (var i:int = 0; i < $list.length; i++)
{
var currentPlayer:GameObject = $list[i];
if (MathUtil.isWithinRange(currentPlayer.width,currentPlayer.x,currentPlayer.y,width,x,y))
{
var $delta:Point = new Point ;
$delta.x = currentPlayer.x - x;
$delta.y = currentPlayer.y - y;
if ($currentDistance > $delta.length)
{
$currentDistance = $delta.length;
velocity = $delta;
velocity.normalize(speed);
}
}
}
if(velocity.length == 0)
{
velocity = Point.polar(2, numberGen);
}
changeDirection--;
if (changeDirection == 0)
{
changeDirection = originalValue;
}
}
velocity.x = Math.floor(velocity.x * 10) * .1;
velocity.y = Math.floor(velocity.y * 10) * .1;
moveBy([Wall, Door], velocity.x, velocity.y, collides_mc);
var $collides:GameObject = collision([Player]);
if ($collides != null)
{
destroy();
}
if ($collides == null)
{
$collides = collision([Player],this);
if ($collides != null)
{
$collides.destroy();
}
}
rotation = (Math.atan2(velocity.y, velocity.x) * 180 / Math.PI);
collides_mc.rotation = -rotation;
trace($collides);
}
override public function onCollideX($collision:GameObject):void
{
}
override public function onCollideY($collision:GameObject):void
{
}
}
}
GameObject Class, which contains all the functions and Enemy extends it
package
{
import flash.display.DisplayObject;
import flash.events.Event;
import flash.ui.Keyboard;
import flash.events.KeyboardEvent;
import flash.display.MovieClip;
import flash.display.Sprite;
import flash.sensors.Accelerometer;
import flashx.textLayout.elements.ListElement;
public class GameObject extends MovieClip
{
static public var list:Vector.<GameObject> = new Vector.<GameObject>;
protected var hitBox:Sprite;
public var target:MovieClip;
public function GameObject()
{
target=this;
list.push(this);
}
public function update():void
{
}
public function collision(typesColliding:Array, $target:DisplayObject = null):GameObject
{
if($target == null)
$target = target;
for (var i:int = list.length - 1; i >= 0; i--)
{
var item:GameObject = list[i], found:Boolean = false;
for (var f:int = typesColliding.length - 1; f >= 0; f--)
{
if (item is typesColliding[f])
{
found = true;
break;
}
}
if (found && $target.hitTestObject(item.target) && this != item)
{
return item;
}
}
return null;
}
public function moveBy(typesColliding:Array, $x:Number = 0, $y:Number = 0, $target:DisplayObject = null):void
{
var $collision:GameObject;
x += $x;
if (($collision = collision(typesColliding, $target)) != null)
{
x -= $x;
onCollideX($collision);
}
y += $y;
if (($collision = collision(typesColliding, $target)) != null)
{
y -= $y;
onCollideY($collision);
}
}
public function onCollideX($collision:GameObject):void
{
}
public function onCollideY($collision:GameObject):void
{
}
public function getType($class:Class):Vector.<GameObject>
{
var $list:Vector.<GameObject> = new Vector.<GameObject>;
for (var i:int = 0; i < list.length; i++)
{
if (list[i] is $class)
{
$list.push(list[i]);
}
}
return $list;
}
public function destroy():void
{
var indexOf:int = list.indexOf(this);
if (indexOf > -1)
list.splice(indexOf, 1);
if (parent)
parent.removeChild(this);
trace("removing item: "+this+" list: " + list.length + ": " + list);
}
}
}
Any help would be appreciated, thank you.

Changing radius of vision to the cone of vision simply requires computing (after checking the distance) the angle between the direction enemy is facing and the player. If this angle is smaller then some T, then it is in the cone of vision of angle 2T (due to symmetry).
This obviously ignores any walls/obstacles that should limit vision, but it should give you the general idea.

Related

Error #1009: Cannot access a property or method of a null object for loop()

I have a problem: I have tested the single pong game, and then I found an error when the game live reached 0 and moved to a Game Over screen for a single pong game.
TypeError: Error #1009: Cannot access a property or method of a null object reference.
at BlowfishPong_fla::MainTimeline/loop()
Can you check this code?
Here is my code for the single pong game:
import flash.events.MouseEvent;
import flash.utils.Dictionary;
import flash.media.Sound;
import flash.media.SoundChannel;
import flash.media.SoundMixer;
import flash.display.MovieClip;
import flash.text.TextField;
import flash.net.SharedObject;
import flash.events.Event;
stop();
var sound: Sound
var sound_channel: SoundChannel;
var gameMiss: Miss = new Miss();
var gameBounce: BounceWall = new BounceWall();
var gameHit: Hit = new Hit();
var ballSpeedX: int = -3;
var ballSpeedY: int = -2;
var gameScore = 0;
var gameLives = 3;
var plzStop: Boolean = false;
helpContent.visible = false;
reset_btn.addEventListener(MouseEvent.CLICK, scoreReset);
function scoreReset(event: MouseEvent): void {
gameScore = 0;
gameLives = 3;
updateTextFields();
}
pause_btn.addEventListener(MouseEvent.CLICK, goPause);
function goPause(event: MouseEvent): void {
if (plzStop == true) {
plzStop = false;
} else {
plzStop = true;
}
}
home_btn.addEventListener(MouseEvent.CLICK, goHome);
function goHome(event: MouseEvent): void {
plzStop = true;
gotoAndStop("startScreen");
}
help_btn2.addEventListener(MouseEvent.CLICK, goHelp2);
function goHelp2(event: MouseEvent): void {
if (plzStop == true) {
helpContent.visible = false;
plzStop = false;
} else {
helpContent.visible = true;
plzStop = true;
}
}
function init(): void {
score_txt.text = gameScore;
lives_txt.text = gameLives;
stage.addEventListener(Event.ENTER_FRAME, loop);
}
function updateTextFields(): void {
score_txt.text = gameScore;
lives_txt.text = gameLives;
}
function calculateBallAngle(paddleY: Number, ballY: Number): Number {
var ySpeed: Number = 5 * ((ballY - paddleY) / 25);
return ySpeed;
}
function loop(e: Event): void {
if (plzStop == false) {
characterPaddle.y = mouseY;
blowfishPong.x += ballSpeedX;
blowfishPong.y += ballSpeedY;
if (blowfishPong.x <= blowfishPong.width / 2) {
blowfishPong.x = blowfishPong.width / 2;
ballSpeedX *= -1;
gameBounce.play();
}
else if (blowfishPong.x >= stage.stageWidth - blowfishPong.width / 2) {
blowfishPong.x = stage.stageWidth - blowfishPong.width / 2;
ballSpeedX *= -1;
gameMiss.play();
gameLives--;
lives_txt.text = gameLives;
if(gameLives == 0){
stage.removeEventListener(Event.ENTER_FRAME,loop);
gotoAndStop("gameover_Single");
SoundMixer.stopAll();
}
}
if (blowfishPong.y <= blowfishPong.height / 2) {
blowfishPong.y = blowfishPong.height / 2;
ballSpeedY *= -1;
gameBounce.play();
}
else if (blowfishPong.y >= stage.stageHeight - blowfishPong.height / 2) {
blowfishPong.y = stage.stageHeight - blowfishPong.height / 2;
ballSpeedY *= -1;
gameBounce.play();
}
if (characterPaddle.y - characterPaddle.height / 3 < 0) {
characterPaddle.y = characterPaddle.height / 3;
}
else if (characterPaddle.y + characterPaddle.height / 3 > stage.stageHeight) {
characterPaddle.y = stage.stageHeight - characterPaddle.height / 3;
}
if (characterPaddle.hitTestObject(blowfishPong) == true) {
if (ballSpeedX > 0) {
ballSpeedX *= -1;
ballSpeedY = calculateBallAngle(characterPaddle.y, blowfishPong.y);
gameScore++;
updateTextFields();
gameHit.play();
}
}
}
}
init();
Then, for the PlayerSkin function, there are some errors to fix:
character.addEventListener(Event.ENTER_FRAME, playerSkin);
TypeError: Error #1009: Cannot access a property or method of a null object reference.
at BlowfishPong_fla::MainTimeline/goHome3()[BlowfishPong_fla.MainTimeline::frame28:55]
TypeError: Error #1009: Cannot access a property or method of a null object reference.
at BlowfishPong_fla::MainTimeline/playerSkin()[BlowfishPong_fla.MainTimeline::frame28:268]

Trouble creating multiple objects (Arrays) in Flash

I'm making a basic Galaga type game in Flash and have been running into issues. This is my first time really messing with ActionScript.
I created an Array for my Enemies and would like to know how I would go about having them spawn in their own respective locations, like in Galaga and then have them move uniformly form left to right while descending once reaching the edge of the stage.
Game
package
{
import flash.display.MovieClip;
import flash.events.Event;
import flash.utils.Timer;
import flash.events.TimerEvent;
import flash.events.KeyboardEvent;
import flash.ui.Keyboard;
public class SpaceVigilanteGame extends MovieClip
{
public var army:Array;
public var avatar:Avatar;
public var gameTimer:Timer;
public var useMouseControl:Boolean;
public var rightKeyIsBeingPressed:Boolean;
public var leftKeyIsBeingPressed:Boolean;
var gameWidth:int = 0;
var gameHeight:int = 0;
public function SpaceVigilanteGame()
{ useMouseControl = false;
leftKeyIsBeingPressed = false;
rightKeyIsBeingPressed = false;
army = new Array();
var newEnemy = new Enemy( 60, 30 );
army.push( newEnemy );
addChild( newEnemy );
avatar = new Avatar();
addChild( avatar );
if ( useMouseControl )
{
avatar.x = mouseX;
avatar.y = mouseY;
}
else
{
avatar.x = 50;
avatar.y = 400;
}
gameWidth = stage.stageWidth;
gameHeight = stage.stageHeight;
gameTimer = new Timer( 25 );
gameTimer.addEventListener( TimerEvent.TIMER, moveEnemy );
gameTimer.addEventListener( TimerEvent.TIMER, moveAvatar );
gameTimer.start();
stage.addEventListener( KeyboardEvent.KEY_DOWN, onKeyPress );
stage.addEventListener( KeyboardEvent.KEY_UP, onKeyRelease );
function onKeyPress( keyboardEvent:KeyboardEvent ):void
{
if ( keyboardEvent.keyCode == Keyboard.RIGHT )
{
rightKeyIsBeingPressed = true;
}
else if ( keyboardEvent.keyCode == Keyboard.LEFT )
{
leftKeyIsBeingPressed = true;
}
}
function onKeyRelease( keyboardEvent:KeyboardEvent ):void
{
if ( keyboardEvent.keyCode == Keyboard.RIGHT )
{
rightKeyIsBeingPressed = false;
}
else if (keyboardEvent.keyCode ==Keyboard.LEFT )
{
leftKeyIsBeingPressed = false;
}
}
}
public function moveEnemy( timerEvent:TimerEvent ):void
{
for each ( var enemy:Enemy in army )
{
}
//enemy.moveDownABit();
if(enemy.x+enemy.width+2<=gameWidth)
{
enemy.moveRight();
}
else if(enemy.y+enemy.height+2<=gameHeight)
{
enemy.moveDown();
}
else if(enemy.x-2>=0)
{
enemy.moveLeft();
}
else if(enemy.y-2>=0)
{
enemy.moveUp();
}
}
public function moveAvatar( timerEvent:TimerEvent ):void
{
if ( useMouseControl )
{
avatar.x = mouseX;
avatar.y = mouseY;
}
else if ( rightKeyIsBeingPressed )
{
avatar.moveRight();
}
else if ( leftKeyIsBeingPressed )
{
avatar.moveLeft();
}
}
}
}
Enemy Class
package
{
import flash.display.MovieClip;
public class Enemy extends MovieClip
{
public function Enemy( startX:Number, startY:Number )
{
x = startX;
y = startY;
}
public function moveRight():void
{
x = x + 2;
}
public function moveDown():void
{
y = y + 2;
}
public function moveLeft():void
{
x = x - 2;
}
public function moveUp():void
{
y = y - 2;
}
}
}
I would suggest that during the enemy instantiation (of which there seems to be only one), you should be setting the locations respective of one another.
as an example:
your code currently does this:
var newEnemy = new Enemy( 60, 30 );
army.push( newEnemy );
addChild( newEnemy );
Perhaps it should do something like this:
for(var x:int = 0; x< ARMY_WIDTH; x++)
{
for(var y:int = 0; y < ARMY_HEIGHT; y++)
{
army.push(new Enemy(60 + x * X_GAP, 30 + y *Y_GAP));
this.addChild(army[army.length-1]);
}
}
Now, I've made a lot of assumptions in the above code; I've invented constants that you may not have, and I've only solved your immediate problem. Ideally you're going to need to look at more advanced solutions for your issue, something like a factory class that creates your enemies for you, or recycles them from a pool of enemies.
However, you're just starting out and you will figure a lot of this stuff out in time. Good luck in your project and I hope you keep up developing your skills :)

TypeError: Error #1010: A term is undefined and has no properties. Problems with successfully removing objects

I am trying to make a game involving a dragon burning little knights, fairly simple but I am new to AS3 and can't seem to solve this problem, sometimes when I kill a knight it returns an output error saying:
TypeError: Error #1010: A term is undefined and has no properties.
at drogtor/onTick()
I can't find any relevant solutions elsewhere on this website so I am submitting a question myself.
Here is (what I think to be) the relevant code.
package
{
import flash.display.MovieClip;
import flash.events.Event;
import flash.events.KeyboardEvent;
import global;
import flash.display.DisplayObject;
public class drogtor extends MovieClip
{
private var updown:Boolean=true;
private var fArray:Array;
private var eArray:Array;
var wpressed:Boolean = false;
var apressed:Boolean = false;
var dpressed:Boolean = false;
var spressed:Boolean = false;
var kspawn:Number = 5;
public function drogtor()
{
addEventListener(Event.ENTER_FRAME, onTick);
stage.addEventListener(KeyboardEvent.KEY_DOWN, fliy);
stage.addEventListener(KeyboardEvent.KEY_UP, fliy);
fArray = new Array();
eArray = new Array();
}
public function onTick(e:Event):void
{
var fcount:int=0;
var sdargon:int=10;
var rdargon:int=6;
var Angle:Number = (2 * Math.PI * (dargon.rotation/360));
var dy:Number = sdargon * Math.cos(Angle);
var dx:Number = sdargon * Math.sin(Angle);
HitBox.x = dargon.x;
HitBox.y = dargon.y;
HitBox.rotation = dargon.rotation;
//Flame Spewer
if (global.count==9)
{
var fAngle:Number = (2 * Math.PI * (dargon.rotation/360));
var fdy:Number = 10 * Math.cos(fAngle);
var fdx:Number = 10 * Math.sin(fAngle);
var ftemp:Flame=new Flame;
ftemp.x=dargon.x + (10 * fdx);
ftemp.y=dargon.y - (10 * fdy);
ftemp.rotation=dargon.rotation + Math.random() * (15-(-15)) + (-15);
fArray.push(ftemp);
addChildAt(ftemp, 0);
}
var kgen:int = Math.floor((Math.random() * 3)+1);
var stageside:int = Math.floor((Math.random() * 4)+1)
if (kgen == 1)
{
if (Math.floor((Math.random() * 100) + 1) <= kspawn)
{
var ktemp:keniget = new keniget;
if (stageside == 1)
{
ktemp.x = Math.random() * stage.stageWidth;
ktemp.y = 0
}
else if (stageside == 2)
{
ktemp.x = Math.random() * stage.stageWidth;
ktemp.y = stage.stageHeight;
}
else if (stageside == 3)
{
ktemp.x = 0;
ktemp.y = Math.random() * stage.stageHeight;
}
else if (stageside == 4)
{
ktemp.x = stage.stageWidth;
ktemp.y = Math.random() * stage.stageHeight;
}
eArray.push(ktemp);
addChildAt(ktemp, 0);
}
}
for (var iKl:int = eArray.length-1; iKl >= 0; iKl --)
{
var krotation:Number = (Math.atan2(eArray[iKl].y-dargon.y, eArray[iKl].x-dargon.x) * 180/Math.PI) - 90;
eArray[iKl].rotation = krotation
var kangle:Number = (2 * Math.PI * (eArray[iKl].rotation/360));
var edx:Number = 3 * Math.sin(kangle);
var edy:Number = 3 * Math.cos(kangle);
eArray[iKl].x += edx;
eArray[iKl].y -= edy;
if (eArray[iKl].hitTestObject(HitBox))
{
removeChild(eArray[iKl]);
eArray.splice(iKl, 1);
}
for (var iF:int=fArray.length-1; iF>=0; iF--)
{
if (eArray[iKl].hitTestObject(fArray[iF]))
{
removeChild(eArray[iKl]);
eArray.splice(iKl, 1);
kspawn += 0.5
}
}
}
for(var iFl:int=fArray.length-1; iFl>=0; iFl--)
{
if(fArray[iFl].currentFrame==fArray[iFl].totalFrames)
{
removeChild(fArray[iFl]);
fArray[iFl]=null;
fArray.splice(iFl, 1);
}
}
if(updown)
{
dargon.rotationX-=1;
if(dargon.rotationX == -10)
{
updown = false;
}
}
if(!updown)
{
dargon.rotationX+=1;
if(dargon.rotationX == 10)
{
updown = true;
}
}
//Movement
if(wpressed)
{
dargon.x += dx;
dargon.y -= dy;
}
if(apressed)
{
dargon.rotation -= rdargon;
}
if(dpressed)
{
dargon.rotation += rdargon;
}
if(spressed)
{
dargon.x -= ((1/4) * dx);
dargon.y += ((1/4) * dy)
}
}
public function fliy(ke:KeyboardEvent):void
{
if(ke.type == "keyDown")
{
//key=A
if(ke.keyCode==87)
{
wpressed=true;
}
//Key=A
if(ke.keyCode==65)
{
apressed=true;
}
//Key=D
if(ke.keyCode==68)
{
dpressed=true;
}
if(ke.keyCode==83)
{
spressed=true;
}
}
if(ke.type == "keyUp")
{
//key=A
if(ke.keyCode==87)
{
wpressed=false;
}
//Key=A
if(ke.keyCode==65)
{
apressed=false;
}
//Key=D
if(ke.keyCode==68)
{
dpressed=false;
}
if(ke.keyCode==83)
{
spressed=false;
}
}
}
}
}
The problem is, that even though you removed the knight from the display list, the code is still running in the onTick function, and you are trying to access something that is not existing, I suggest you to check whether your knight's reference is null or not, if not, then run the code, else skip it.
EDIT:
Whenever you null an instance (myInstance = null), you can no longer access to it's properties, functions etc.. and if you try, then you get that error above. To avoid it, check whether your object is null or not.
if(myInstance != null) {
//do your stuff with your instance
}

How do i get Object index in an array

I have seen many threads about this but my problem doesn't solved. This may be a simple way but i have no idea...
I'm trying to get Objects indices in an array like so :
var test:Array = new Array();
for (var row:Number = 0; row < 2; row++) {
test[row] = [];
for (var column:Number = 0; column < 3; column++) {
test[row][column].addEventListener(MouseEvent.CLICK, objClicked);
test[row][column] = new ballShape(column, column, row);
addChild(test[row][column]);
}
}
function objClicked(evt:MouseEvent):void {
// Here must return Object index in array
}
P.S :
I can get items index in int array, but i don't know about objects.
Any ideas would be appreciated.
Edit :
ballShape.as
package {
import flash.display.Graphics;
import flash.display.Sprite;
import flash.events.MouseEvent;
import fl.motion.Color;
public class ballShape extends Sprite {
private var shapeId:uint;
private var currentPosition:uint;
private var arrayPosition:uint;
private var color:Number;
public function ballShape(Id:uint, currPos:uint, arrPos:uint) {
setId(Id);
setArrayPos(arrPos);
setCurrentPos(currPos);
//trace("Array : " + arrPos);
//trace("Curr : " + currPos);
if (arrPos == 0) {
var posX:uint = 60;
} else {
var posX:uint = (arrPos + 1) * 60;
}
if (currPos == 0) {
var posY:uint = 42;
} else {
var posY:uint = (currPos + 1) * 42;
}
if (arrPos == 0) {
color = 0xFF0000;
} else {
color = 0x00FF00;
}
graphics.beginFill(color, 1.0);
graphics.drawCircle(posX, posY, 20);
graphics.endFill();
this.addEventListener(MouseEvent.CLICK, Clicked);
}
public function setId(Id:uint):void {
shapeId = Id;
}
public function getId():uint {
return shapeId;
}
public function Clicked(evt:MouseEvent):void {
//return getId();
trace("Ball id is " + getId());
trace("Array id is " + getArrayPos());
trace("PositionInArray id is " + getCurrentPos());
//return arrayPosition;
}
public function setCurrentPos(Pos:uint):void {
currentPosition = Pos;
}
public function getCurrentPos():uint {
return currentPosition;
trace(currentPosition);
}
public function setArrayPos(arrayPos:uint):void {
arrayPosition = arrayPos;
}
public function getArrayPos():uint {
return arrayPosition;
trace(arrayPosition);
}
public function addBead(arrayId, currPos):void {
}
}
}
I would suggest adding row and column as public variables in your ballShape class.
That way you can get them like this:
function objClicked(evt:MouseEvent):void {
trace(ballShape(evt.target).getCurrentPos(), ballShape(evt.target).getArrayPos());
}
Maybe turn this two lines around:
test[row][column].addEventListener(MouseEvent.CLICK, objClicked);
test[row][column] = new ballShape(column, column, row);
to be :
test[row][column] = new ballShape(column, column, row);
test[row][column].addEventListener(MouseEvent.CLICK, objClicked);
Try something like:
protected function objClicked(e:MouseEvent):void {
for (var row: int=0; row < test.length; row++) {
var column:int = (test[row] as Array).indexOf(e.currentTarget);//use currentTarget so you don't try to match on internal Interactive Objects!
if (column>-1) {
trace(row, column);
return;//or break, if you need to do something else below this loop
}
}
}

Positioning a movieclip onto another movieclip

I'm creating a game where if you hit a zombie the zombie dies and his head is sent back in the direction you hit. I have two movieclips the zombie and the zombie head. Once the zombie is hit it will play its dying animation and remove itself and at the same time the zombie head will be added to the dying zombie and be blown back. I have done the code for the hittest and the zombie dying and respawning but I can't seem to position and add the head to the dying zombie when it is hit. How can I do this. I thought it will be like this, I added this in the PlayDeathAnimation function in the zombie class but did not work:
for (var i=0; i < MovieClip(parent).zombies.length; ++i)
{
var zh = new ZombieHead();
zh.x = MovieClip(parent).zombies[i].x;
zh.y = MovieClip(parent).zombies[i].y;
zh.rotation = MovieClip(parent).zombies[i].rotation;
addChild(zh);
}
I have 4 classes
Player
package
{
import flash.display.MovieClip;
import flash.events.Event;
import flash.events.KeyboardEvent;
import flash.events.MouseEvent;
import flash.ui.Keyboard;
import flash.display.Graphics;
import flash.utils.setTimeout;
public class Player extends MovieClip
{
//Player Setting
var walkSpeed:Number = 4;
var walkRight:Boolean = false;
var walkLeft:Boolean = false;
var walkUp:Boolean = false;
var walkDown:Boolean = false;
var attacking:Boolean = false;
var attackRange:int = 100;
var attackAngle:int = 30;
public function Player()
{
stage.addEventListener(KeyboardEvent.KEY_DOWN,walk);
addEventListener(Event.ENTER_FRAME,Update);
stage.addEventListener(KeyboardEvent.KEY_UP,stopWalk);
stage.addEventListener(MouseEvent.CLICK,attack);
// The lines below draw a preview of your attack area
graphics.beginFill(0x00ff00, 0.2);
graphics.lineTo(attackRange*Math.cos((rotation-attackAngle)/180*Math.PI),attackRange*Math.sin((rotation-attackAngle)/180*Math.PI));
graphics.lineTo(attackRange*Math.cos((rotation+attackAngle)/180*Math.PI),attackRange*Math.sin((rotation+attackAngle)/180*Math.PI));
graphics.endFill();
}
function walk(event:KeyboardEvent)
{
//When Key is Down
if (event.keyCode == 68)
{
walkRight = true;
}
if (event.keyCode == 87)
{
walkUp = true;
}
if (event.keyCode == 65)
{
walkLeft = true;
}
if (event.keyCode == 83)
{
walkDown = true;
}
}
function Update(event:Event)
{
//if attacking is true then key moves are false;
if ((attacking == true))
{
walkRight = false;
walkLeft = false;
walkUp = false;
walkDown = false;
// see if the zombie is in the cone
for (var i:int=MovieClip(parent).zombies.length-1; i>=0; i--)
{
if (inAttackCone(MovieClip(parent).zombies[i]))
{
if (hitTestObject(MovieClip(parent).zombies[i]))
{
//attacking = true;
MovieClip(parent).zombies[i].zombieDead = true;
}
}
}
}
else if ((attacking == false))
{
//Else if attacking is false then move and rotate to mouse;
var dx = parent.mouseX - x;
var dy = parent.mouseY - y;
var angle = Math.atan2(dy,dx) / Math.PI * 180;
rotation = angle;
if ((walkRight == true))
{
x += walkSpeed;
gotoAndStop(2);
}
if ((walkUp == true))
{
y -= walkSpeed;
gotoAndStop(2);
}
if ((walkLeft == true))
{
x -= walkSpeed;
gotoAndStop(2);
}
if ((walkDown == true))
{
y += walkSpeed;
gotoAndStop(2);
}
}
}
//Calculate the distance between the two
public function distanceBetween(player:MovieClip,zombies:MovieClip):Number
{
for (var i:int=MovieClip(parent).zombies.length-1; i>=0; i--)
{
var dx:Number = x - MovieClip(parent).zombies[i].x;
var dy:Number = y - MovieClip(parent).zombies[i].y;
}
return Math.sqrt(((dx * dx) + dy * dy));
}
public function angleDifference(a:Object, b:Object):Number
{
var dx:Number = b.x - a.x;
var dy:Number = b.y - a.y;
var ang:Number = (a.rotation/180*Math.PI)-Math.atan2(dy, dx);
while (ang>Math.PI)
{
ang -= 2 * Math.PI;
}
while (ang<-Math.PI)
{
ang += 2 * Math.PI;
}
return Math.abs(ang*180/Math.PI);
}
function inAttackCone(enemy:MovieClip):Boolean
{
var distance:Number = distanceBetween(this,enemy);
distance -= enemy.width / 2;// account for the enemy's size
if (distance < attackRange)
{
// In range, check angle
if (angleDifference(this,enemy)<attackAngle)
{
return true;
}
}
return false;
}
function stopWalk(event:KeyboardEvent)
{
if ((attacking == false))
{
if (event.keyCode == 68)
{
event.keyCode = 0;
walkRight = false;
gotoAndStop(1);
}
if (event.keyCode == 87)
{
event.keyCode = 0;
walkUp = false;
gotoAndStop(1);
}
if (event.keyCode == 65)
{
event.keyCode = 0;
walkLeft = false;
gotoAndStop(1);
}
if (event.keyCode == 83)
{
event.keyCode = 0;
walkDown = false;
gotoAndStop(1);
}
}
}
function attack(event:MouseEvent)
{
if ((attacking == false))
{
attacking = true;
gotoAndStop(3);
}
}
}
}
Zombies
package
{
import flash.display.MovieClip;
import flash.events.Event;
import flash.geom.Point;
public class Zombie extends MovieClip
{
var walkSpeed:Number = 2;
var target:Point;
public var zombieDead:Boolean = false;
public function Zombie()
{
//set target location of Zombie
target = new Point(Math.random() * 500,Math.random() * 500);
}
function loop()
{
if (zombieDead == true)
{
playDeathAnimation();
}
else if (zombieDead == false)
{
gotoAndStop(1);
//Point Zombie at its target
var dx = MovieClip(root).Player01.x - x;
var dy = MovieClip(root).Player01.y - y;
var angle = Math.atan2(dy,dx) / Math.PI * 180;
rotation = angle;
//Move in the direction the zombie is facing
x = x+Math.cos(rotation/180*Math.PI)*walkSpeed;
y = y+Math.sin(rotation/180*Math.PI)*walkSpeed;
//Calculate the distance to target
var hyp = Math.sqrt((dx*dx)+(dy*dy));
if (hyp<5)
{
target.x = Math.random() * 500;
target.y = Math.random() * 500;
}
}
}
public function playDeathAnimation()
{
gotoAndStop(2);
}
public function deathAnimationFinishedCallback()
{
for (var i=0; i < MovieClip(parent).zombies.length; ++i)
{
if (MovieClip(parent).zombies[i] == this)
{
MovieClip(parent).zombies.splice(i, 1);
break;
}
}
MovieClip(parent).removeChild(this);
}
}
}
Document Class
package
{
import flash.display.MovieClip;
import flash.events.Event;
public class Game extends MovieClip
{
public var zombies:Array;
public function Game()
{
addEventListener(Event.ENTER_FRAME, update);
zombies = new Array();
}
public function update(e:Event)
{
//Only spawn a Zombie if there are less than number
if (numChildren < 4)
{
//Make a new instance of the Zombie.
var Z = new Zombie();
addChild(Z);
//Position and rotate the zombie
Z.x = Math.random() * stage.stageWidth;
Z.y = Math.random() * stage.stageHeight;
Z.rotation = Math.random() * 360;
zombies.push(Z);
}
for (var count = 0; count<zombies.length; count ++)
{
zombies[count].loop();
}
}
}
}
Zombie Head
package
{
import flash.display.MovieClip;
import flash.events.Event;
public class ZombieHead extends MovieClip
{
var headSpeed:Number = -30;
var friction:Number = 0.9;
public function ZombieHead()
{
// constructor code
addEventListener(Event.ENTER_FRAME,Update);
}
function Update(event:Event)
{
x = x+Math.cos(rotation/180*Math.PI)*headSpeed;
y = y+Math.sin(rotation/180*Math.PI)*headSpeed;
headSpeed *= friction;
if (headSpeed > -0.00001)
{
removeEventListener(Event.ENTER_FRAME,Update);
parent.removeChild(this);
}
else if (x<0 || x > 550 || y < 0 || y > 400)
{
removeEventListener(Event.ENTER_FRAME,Update);
parent.removeChild(this);
}
}
}
}

Resources