For now I have the player throwing pizzas at randomly spawned PacMan. The collision detection only works 40% of the time. Sometimes, the pizza goes straight through the PacMan or disappears half way through, and this error messages keeps showing up: TypeError: Error #1010: A term is undefined and has no properties. at PizzaDelivery/update(). Please help!
package
{
import flash.display.MovieClip;
import flash.events.Event;
import flash.events.KeyboardEvent;
public class PizzaDelivery extends MovieClip
{
var moveLeft:Boolean;
var moveRight:Boolean;
var moveDown:Boolean;
var moveUp:Boolean;
var playerSpeed = 10;
var numOfPizza = 0;
var genList:Array = [];
var genX:Array = [10,10,10,115,115,115];
var genY:Array = [10,115,215,10,115,215];
var pizzaList:Array = [];
var enemyList:Array = [];
var spawnTimeList:Array = [];
var timer = 0;
public function PizzaDelivery()
{
for(var s=0; s!=12; s++)
{
spawnTimeList[s] = Math.floor(Math.random()*480);
}
for(var a=0; a!=6; a++)
{
genList[a]= new pizzaGen();
stage.addChild(genList[a]);
genList[a].x = genX[a];
genList[a].y = genY[a];
genList[a].timer = 60;
}
stage.addEventListener(Event.ENTER_FRAME, update);
stage.addEventListener(KeyboardEvent.KEY_DOWN, movePlayer);
stage.addEventListener(KeyboardEvent.KEY_UP, ceasePlayer);
stackOfPizza.stop();
player.stop();
}
function update(event:Event):void
{
//spawning enemies
timer++;
for(var o=0; o<=spawnTimeList.length-1; o++)
{
if(timer==spawnTimeList[o])
{
addEnemy(new PacMan);
}
}
//pizza
if(pizzaList.length != 0)
{
for(var f = 0; f <= pizzaList.length - 1; f++)
{
if(pizzaList[f].x >= 1000)
{
if(pizzaList[f].parent)
{
pizzaList[f].parent.removeChild(pizzaList[f]);
pizzaList.splice(f,1);
}
}
if(enemyList.length != 0)
{
for(var e = 0; e != enemyList.length - 1; e++)
{
if(pizzaList[f].hitTestObject(enemyList[e]))
{
if(pizzaList[f].parent)
{
pizzaList[f].parent.removeChild(pizzaList[f]);
pizzaList.splice(f,1);
}
if(enemyList[e].parent)
{
enemyList[e].parent.removeChild(enemyList[e]);
enemyList.splice(f,1);
}
}
}
}
}
}
//pizza generators
for(var b=0;b!=6;b++)
{
if(player.hitTestObject(genList[b]))
{
if(genList[b].timer==60)
{
if(numOfPizza!=10)
{
genList[b].timer = 0;
genList[b].gotoAndStop(0);
genList[b].visible = false;
numOfPizza++;
stackOfPizza.gotoAndStop(numOfPizza+1);
}
}
}
if(genList[b].timer != 60)
{
genList[b].timer++;
} else
{
genList[b].visible = true;
genList[b].gotoAndStop(4);
}
}
//player movement
if(moveLeft==true)
{
player.play();
player.x -= playerSpeed;
stackOfPizza.x -= playerSpeed;
}
if(moveRight==true)
{
player.play();
player.x += playerSpeed;
stackOfPizza.x += playerSpeed;
}
if(moveUp==true)
{
player.play();
player.y -= playerSpeed;
stackOfPizza.y -= playerSpeed;
}
if(moveDown==true)
{
player.play();
player.y += playerSpeed;
stackOfPizza.y += playerSpeed;
}
}
function addEnemy(object:Object):void
{
enemyList.push(object);
stage.addChild(enemyList[enemyList.length-1]);
object.x = 1000;
object.y = Math.floor(Math.random() * (400-object.height));
}
You almost got it correct, but it needs couple tiny changes.
1. When pizzaList[f].x > 1000
, you remove that pizza, and you can't use it anymore to check collisions, as it's not there anymore. Easiest way is to have a separate loop for x-position checks before collision detection.
2. For loops: when you run an array loop and remove its elements inside the loop, you need to remember that when removing any element, you also change order for the rest of the elements in the array.
F.ex. if you remove 2nd element, then 3rd will become 2nd and so on. And at the same time your loop variable increases from 1 to 2, and the outcome is that when the next loop cycle uses array[2], it skips 2nd element (former 3rd element).
To avoid this, you have few different solutions.
break
ing the loop will do, but not always.3. When you get positive hitTestObject, you remove both the pizza and enemy. But as pizza is now removed, you can not continue the enemy loop with the same pizza, as it's not there anymore.
So, after a match, just break;
the inner loop and then outer loop continues with next element.
//pizza
var f:int;
if(pizzaList.length != 0){
for(f = pizzaList.length - 1; f > -1; f--){ // 1 & 2
if(pizzaList[f].x >= 1000){
if(pizzaList[f].parent){
pizzaList[f].parent.removeChild(pizzaList[f]);
pizzaList.splice(f,1);
}
}
}
if(enemyList.length != 0){
for(f = pizzaList.length - 1; f > -1; f--){ // 2
for(var e:int = enemyList.length - 1; e > -1; e--){ // 2
if(pizzaList[f].hitTestObject(enemyList[e])){
if(pizzaList[f].parent){
pizzaList[f].parent.removeChild(pizzaList[f]);
pizzaList.splice(f,1);
}
if(enemyList[e].parent){
enemyList[e].parent.removeChild(enemyList[e]);
enemyList.splice(f,1);
}
break; // 3
}
}
}
}
}
And actually you shouldn't need to check .parent
for pizzas nor enemies.
Edit:
My first point is not a must, as you could keep everything in same loop and just have else
block for the bottom part:
if(pizzaList[f].x >= 1000){
//removing pizza
}else{
if(enemyList.length != 0){
//check collisions
}
}
Just remember that you don't need another pizzaList loop inside this else-block, as you're already inside of one.