flash as3 platform game (I am noob) - actionscript-3

I am making a platform game in flash cs4 as3 and am having a lot of trouble getting my different classes to work right together. I have a bullet class, enemy class, and a bumper class which determines the boundaries for the enemy. When the bullet hits the enemy the enemies death animation plays and then both are removed from the game. When the last enemy on that level gets removed though, i get this error saying a term is undefined and has no properties. Also if I kill the enemies out of the order they are called things don't work properly my codes must have some errors. Here is my code between the bullet and enemy classes:
if (enemyList.length>0) {
for (var i:int = 0; i < enemyList.length; i++) {
if (bulletList.length>0) {
for (var j:int = 0; j < bulletList.length; j++) {
if (enemyList[i].hitTestObject(bulletList[j])) {
trace("Bullet and Enemy are colliding");
enemyList[i].gotoAndPlay("dead");
bulletList[j].removeSelf();
enemyList[i].xSpeedConst=0;
enemyList[i].isDead = true;
} else {
enemyList[i].isDead = false;
}
}
}
}
}
}
and also between the player and enemy and bumper and enemy.
if (enemyList[k].isDead == false && enemyList.length>0) {
for (var k:int = 0; k < enemyList.length; k++) {
if (enemyList[k].isDead == false && bumperList.length>0) {
for (var h:int = 0; h < bumperList.length; h++) {
if (enemyList[k].hitTestObject(bumperList[h])) {
enemyList[k].changeDirection();
}
}
}
}
}
if (enemyList[m].isDead == false && enemyList.length>0) {
for (var m:int = 0; m < enemyList.length; m++) {
if (enemyList[m].hitTestObject(player)) {
trace("player collided with enemy");
currentHP-=5;
if (currentHP<=0) {
currentHP=0;
trace("you died");
gotoAndStop(1);
}
updateHealthBar();
}
}
}
Sorry it's kinda long I just feel like Im missing something obvious in here or maybe all my code is just poorly structured. Either way any help would be greatly appreciated thanks!

Don't you need to remove the bullet and enemy from the lists once a bullet hit an enemy? Because you do
bulletList[j].removeSelf();
which will probably remove the bullet from the display list, but the bullet reference will still stay in the bulletList and will be checked against on the next iteration.
Also your very first check should be
if (enemyList.length != 0 && bulletList.length != 0)
There is no point to loop trough all enemies if there are no bullets and vice versa :)

Related

Having some trouble with collision using Arrays and Childs

So, i was working on a game and i got some trouble at the part where i was coding the collision detection between my character and an item. When both collide, the item should dissapear, but it crashes the game. I'm coding using Flashdevelop and Starling. Here's my code:
private function collision(object1:DisplayObject, object2:Sprite):Boolean
{
var area1:Rectangle = object1.getBounds(stage);
var area2:Rectangle = object2.getBounds(stage);
if (area1.intersects(area2)) {
return true;
}
return false;
}
private function collisionPlayerItem(object:Player):void
{
for (var i:int = 0; i < itemArray.length; i++) {
if (collision(object.areaBody(), itemArray[i])) {
if(stage.contains(itemArray[i])){
map.removeChild(itemArray[i]);
life -= 1;
}
}
}
itemArray is where all the items are stocked in.
areaBody is the hitbox of my character.
The moment my character touch an item, the game crashes.
In flashdevelop there is no hitTestObject also.
Someone knows whats happening?

Flash as3 platform game Error 1009

Im making a platform game with patrolling enemies with an enemy class and a bumper class which changes the direction of the enemies when they collide. Once you open the door and call on the nextLevel function I need the enemies and bumpers to be removed. This is the code for the nextLevel function:
function nextLevel():void {
currentLevel++;
trace("Next Level: " + currentLevel);
if (enemyList.length>0) {
for (var i:int = 0; i < enemyList.length; i++) {
trace("enemyRemoved");
enemyList[i].removeSelf();
}
}
if (bumperList.length>0) {
for (var b:int = 0; b < bumperList.length; b++) {
trace("bumperRemoved");
bumperList[b].removeSelf();
}
}
if (currentLevel==2) {
gotoLevel2();
addEnemiesToLevel2();
addBumpersToLevel2();
}
}
if (currentLevel==3) {
gotoLevel3();
addEnemiesToLevel3();
addBumpersToLevel3();
trace("gotoLevel3");
}
which works fine for going to level 2. But somehow when I go to level 3, I get error 1009 cannot access a property of a null object reference when removing the bumpers. I don't understand why it would work for level 2 but not 3 and also the enemies get removed just fine which is almost identical to the remove bumper code. Here is my removeSelf function in the bumper class
public function removeSelf():void {
trace("remove bumper");
removeEventListener(Event.ENTER_FRAME, bumperloop);
this.parent.removeChild(this);
Also my function for pressing the down arrow key while on the open door to call the nextLevel function
} else if (e.keyCode == Keyboard.DOWN) {
downPressed=true;
if (doorOpen&&player.hitTestObject(back.other.lockedDoor)) {
nextLevel();
}
Anyone know what could be the problem here? I would be very grateful to anyone who could answer Iv'e been working at this for days. It gives me an error on the bumperList[b].removeSelf(); line on the nextLevel function and this.parent.removeChild(this); in the bumper class and on the nextLevel(); line in my keydown code

Remove bullet when hit a wall

I'm making an AS3 platform game where the player can shoot some bullets.
When the bullet is touching an enemy, the enemy die and the bullet is removed.
I've succeed do to that but now I'd like to remove the bullet if it hit a wall and I can't figure out how to do so.
So far, here's my code for removing the bullet when touching an enemy :
public function checkCollisions() {
// enemies
for(var i:int=enemies.length-1;i>=0;i--) {
if (hero.mc.hitTestObject(enemies[i].mc)) {
// is the hero jumping down onto the enemy?
if (hero.inAir && (hero.dy > 0)) {
enemyDie(i);
} else {
heroDie();
}
}
for (var j:int = 0; j < bulletList.length; j++) // for each bullet in the bulletList
{
if (enemies[i].mc.hitTestObject(bulletList[j]) )
{
trace("Bullet and Enemy are colliding");
enemyDie(i)
bulletList[j].removeSelf();
}
}
}
I've defined my wall and floor like this :
public function examineLevel() {
fixedObjects = new Array();
otherObjects = new Array();
for(var i:int=0;i<this.gamelevel.numChildren;i++) {
var mc = this.gamelevel.getChildAt(i);
// add floors and walls to fixedObjects
if ((mc is Floor) || (mc is Wall)) {
var floorObject:Object = new Object();
floorObject.mc = mc;
floorObject.leftside = mc.x;
floorObject.rightside = mc.x+mc.width;
floorObject.topside = mc.y;
floorObject.bottomside = mc.y+mc.height;
fixedObjects.push(floorObject);
}
}
I've tried to put this in my checkCollisions function but it's not working :
for(var k:int=0;k<fixedObjects.length;k++)
{
if (fixedObjects[k].hitTestObject(bulletList[j]) ){
trace("hit wall");
}
Do you know what do I have to put in order to remove the bullet when it's touching a wall (or floor) ?
Thx
The array fixedObjects holds references to Object instances. However, hitTestObject(obj) is a public function of the DisplayObject class, and the obj parameter needs to be an instance of DisplayObject.
If the code snippet you provided is exactly the same as what you used in your game, there should be runtime error messages generated.
Could you please verify whether this is the cause of failing to detect collision?

I added animation to the timeline of my movie clip, now its no longer colliding with objects as it did before

I'm working on a platform game in AS3 for Flash. There is of course a player character and enemies for him to interact with. I first made a simple placeholder graphic for the enemy while I worked on the code. I got the enemy to move back and forth between two bumpers with code. He also collides with the player, sending them back to the start screen. Now that I got the code working, I wanted to add some animations to the enemies so they walk instead of just skate across the ground. I added the animations to the timeline of the enemy movie clip. Now when I test the game, the animations play fine and the enemy begins to move, but he passes through the first bumper and doesn't collide with the player at all. If I force the movie clip to stop and not play the collision starts to work again. What would be causing this?
This is the code within the main timeline of the .fla file.
addEnemiesToLevel1();
addBumpersToLevel1();
function addEnemiesToLevel1():void
{
addEnemy(700, -54);
addEnemy(1341, -54);
addEnemy(2187, -54);
}
function addBumpersToLevel1():void
{
addBumper(900, -80);
addBumper(644, -80);
addBumper(1135, -90);
addBumper(1380, -90);
addBumper(2053, -90);
addBumper(2226, -90);
}
function addEnemy(xLocation:int, yLocation:int):void
{
var enemy:Enemy = new Enemy(xLocation, yLocation);
back.addChild(enemy);
enemy.addEventListener(Event.REMOVED, enemyRemoved);
enemyList.push(enemy);
}
function addBumper(xLocation:int, yLocation:int):void
{
var bumper:Bumper = new Bumper(xLocation, yLocation);
back.addChild(bumper);
bumper.visible = false;
bumperList.push(bumper);
}
//corralling the bad guys with bumpers
if (enemyList.length > 0){ //enemies left in the enemyList?
for (var k:int = 0; k < enemyList.length; k++){ // for each enemy in the enemyList
if (bumperList.length > 0){
for (var h:int = 0; h < bumperList.length; h++){ // for each bumper in the List
if ( enemyList[k].hitTestObject(bumperList[h]) ){
enemyList[k].changeDirection();
}
}
}
}
}
//player and enemy collisions
if (enemyList.length > 0){ //enemies left?
for (var m:int = 0; m < enemyList.length; m++){ // for each enemy in the enemyList
if ( enemyList[m].hitTestObject(player) ){
trace("player collided with enemy");
gotoAndStop(4);
enemyList[m].removeSelf();
}
}
}
}
This is the enemy class file.
package {
import flash.display.MovieClip;
import flash.events.Event;public class Enemy extends MovieClip {
private var xSpeedConst:int = 2;
private var flip:int = 1;
public function Enemy(xLocation:int, yLocation:int) {
// constructor code
x = xLocation;
y = yLocation;
addEventListener(Event.ENTER_FRAME, loop);
}
public function loop(e:Event):void {
if ((flip%2) == 1){
x += xSpeedConst;
} else if((flip%2) == 0){
x += (-xSpeedConst);
}
}
public function removeSelf():void {
trace("remove enemy");
removeEventListener(Event.ENTER_FRAME, loop);
this.parent.removeChild(this);
}
public function changeDirection():void{
trace("x ="+x);
flip++;
this.scaleX *= -1;
}
}
}
I had a problem that was very similar to this:
2D Platform Game using hitTestPoint:glitches
My problem was that my character's hitTestPoint wouldn't work after I animated the character. However, it wasn't because of the animation, it was because of my turning code for the character. I was using scaleX to flip the character. However, this flipped the points nested within the character as well (which were used to handle my collisions). I notice that you also flipped the character's scale:
public function changeDirection():void{
trace("x ="+x);
flip++;
this.scaleX *= -1;
}
Perhaps you are having the same problem as I did. If so, try removing this line of code for now:
this.scaleX *= -1;
...and see what happens...We can figure out what to do next from there
Drake Swartzy

AS3: How to remove a MovieClip created and placed on stage through an array?

I'm making a game in flash and am using arrays to dynamically create items and place them inventory. LongSword is a MovieClip. I place the movieclip in the array like so:
function buyitem1(e:Event):void
{
if(Store.itemslot.length < 6 && Store.currentMenu == 1 &&score >= 450)
{
Store.itemslot.push(new LongSword);
}
}
Now I'm trying to remove the movieclip from the stage when the LongSword is "sold". How can i remove this longsword? I've tried:
for(var i:int = 0; i < Store.itemslot.length; i++)
{
if(Store.itemslot[i] == LongSword)
{
stage.removeChild(Store.itemslot[0]);
}
}
Ive also tried:
for(var i:int = 0; i < Store.itemslot.length; i++)
{
if(Store.itemslot[i] == new LongSword)
{
stage.removeChild(Store.itemslot);
}
}
and several variations. any ideas?
Try something like:
for each(var i:MovieClip in Store.itemslot)
{
if(i is Longsword)
{
var n:int = Store.itemslot.indexOf(i);
Store.itemslot.splice(n, 1);
if(i.parent) i.parent.removeChild(i);
break; // Only remove one Longsword.
}
}
If there are multiple instances of Longsword in the array, you may want to keep a reference to each instance somewhere for better comparison.