Make movieclip arrays not overlap to each other - actionscript-3

I'm currently working on a game with AS3, wherein the player needs to avoid falling random objects by tilting the phone. These objects uses timer for delay to make them fall one time per row. So I'm working now on the level where there are two objects falling randomly on the screen, which are movieclips "mercury" with class name of planet1 and "venus" with class name of "planet2". The problem is, sometimes they overlapped with each other when falling. I want the two movieclips to not overlap with each other when they start to fall. I had look for scripts and tried it but it doesn't work. I'm beginner in AS3.
Here is the script:
var mercury:planet1;
var mercuryArray:Array = new Array();
var mercuryClock = new Timer(5000, 0);
mercuryClock.addEventListener(TimerEvent.TIMER, spawnMercury);
var venus:planet2;
var venusArray:Array = new Array();
var venusClock = new Timer(2000, 0);
venusClock.addEventListener(TimerEvent.TIMER, spawnVenus);
addEventListener(Event.ENTER_FRAME, onMyEnterFrame);
function onMyEnterFrame(e:Event)
{
galawMercury();
galawVenus();
checkCollision();
}
/*==================PLANET 1=====================*/
function spawnMercury(e:Event)
{
gawaMercury();
}
function gawaMercury()
{
var mercury:planet1 = new planet1();
mercury.x = Math.random() * 400;
mercury.y = 0;
addChild(mercury);
mercuryArray.push(mercury);
}
function galawMercury()
{
for(var ee:int = mercuryArray.length - 1; ee >= 0; ee--)
{
mercuryArray[ee].y += 13;
if(mercuryArray[ee].y > stage.stageHeight)
{
mercuryArray[ee].parent.removeChild(mercuryArray[ee]);
mercuryArray.splice(ee, 1);
}
}
}
/*==================PLANET 2=====================*/
function spawnVenus(e:Event)
{
gawaVenus();
}
function gawaVenus()
{
var venus:planet2 = new planet2();
venus.x = Math.random() * 400;
venus.y = 0;
venus.width = 126;
venus.height = 200;
addChild(venus);
venusArray.push(venus);
}
function galawVenus()
{
for(var yy:int = venusArray.length - 1; yy >= 0; yy--)
{
venusArray[yy].y += 12;
if(venusArray[yy].y > stage.stageHeight)
{
venusArray[yy].parent.removeChild(venusArray[yy]);
venusArray.splice(yy, 1);
}
}
}
function checkCollision()
{
for(var oo:int = mercuryArray.length - 1; oo >= 0; oo --)
{
if(stella.hitStella.hitTestObject(mercuryArray[oo]))
{
keme();
}
}
for(var uu:int = venusArray.length - 1; uu >= 0; uu --)
{
if(stella.hitStella.hitTestObject(venusArray[uu]))
{
keme();
}
}
}
function keme()
{
soundtrackChannel.stop();
soundtrackChannel = stellaDead.play();
removeEventListener(Event.ENTER_FRAME, onMyEnterFrame);
mercuryClock.stop();
venusClock.stop();
score.stop();
stella.play();
blah.text = lbl_iskor.text;
removeObjects();
}
function removeObjects()
{
for each (var mercury:planet1 in mercuryArray)
{
mercuryArray.splice(mercury, 0);
removeChild(mercury);
}
for each (var venus:planet2 in venusArray)
{
venusArray.splice(venus, 0);
removeChild(venus);
}
}

Related

Shoot in different directions in as3

I'm having some troubles with the game I'm making. My character shoots bullets, but when it comes to shooting them in different directions it does not work properly. When it shoots the bullets follow the character's direction. Below I post the code.
var Bulli:Array = new Array();
var ShootTimer:Timer = new Timer(0);
stage.addEventListener(MouseEvent.MOUSE_DOWN, startShootTimer);
stage.addEventListener(MouseEvent.MOUSE_UP, stopShootTimer);
ShootTimer.addEventListener(TimerEvent.TIMER, shootBullo);
stage.addEventListener(Event.ENTER_FRAME, mainLoop);
function startShootTimer(e:MouseEvent):void
{
ShootTimer.start();
}
function stopShootTimer(e:MouseEvent):void
{
ShootTimer.stop();
}
function shootBullo(e:TimerEvent):void
{
var bullo:Bullo = new Bullo();
bullo.x = Jumbo.x;
bullo.y = Jumbo.y - 50;
if(destra)
{
bullo.dir = destra;
}
else
{
bullo.dir = sinistra;
}
addChild(bullo);
Bulli.push(bullo);
}
function mainLoop (e:Event):void
{
for (var b:int = 0; b < Bulli.length; b++)
{
if (Bulli[b].dir == destra)
{
Bulli[b].x += 10;
}
else
{
Bulli[b].x -= 10;
}
}
}
Don't add that listener to Stage, instead add it to each unique bullo...
//# not to Stage...
//stage.addEventListener(Event.ENTER_FRAME, mainLoop);
Try this (untested but may be useful for some ideas):
function shootBullo(e:TimerEvent):void
{
var bullo:Bullo = new Bullo();
bullo.x = Jumbo.x;
bullo.y = Jumbo.y - 50;
if(destra) { bullo.dir = destra; }
else { bullo.dir = sinistra; }
bullo.addEventListener(Event.ENTER_FRAME, mainLoop);
}
function mainLoop (e:Event):void //the "e" of this function parameter is each unique "Bullo"
{
//# currentTarget is whichever "bullo" is talking to this Event (via Listener).
if (e.currentTarget.dir == destra)
{ e.currentTarget.x += 10; }
else { e.currentTarget.x -= 10; }
}

ActionScript 3 - Error #1010: A term is undefined and has no properties

When testing my project, I got this error :
TypeError: Error #1010: A term is undefined and has no properties. firegame.as:115]
at firegame/checkhitammo()[..\Desktop\Flash\firegame.as:115
at firegame/mainloop()[..Desktop\Flash\firegame.as:77
I don't understand why and if I change the if statement to something simple it's all work fine.
This is my code :
package {
import flash.display.*;
import flash.events.KeyboardEvent;
import flash.events.MouseEvent;
import flash.utils.Timer;
import flash.events.TimerEvent;
import flash.events.Event;
public class firegame extends MovieClip {
var tiger:Tiger = new Tiger();
var enemys:Array = new Array();
var scorea:Number = 0;
var ammoleft:Number = 0;
var ammo:Array = new Array();
var setint:Timer = new Timer(110);
var setenemy:Timer = new Timer(980);
var newenemy:Number;
var hitcheck:Array = new Array();
var totallength:Number;
public function firegame() {
startgame();
}
public function startgame() {
addplayer();
stage.addEventListener(MouseEvent.MOUSE_MOVE, moveplayer);
stage.addEventListener(MouseEvent.MOUSE_DOWN, shotfire);
stage.addEventListener(MouseEvent.MOUSE_UP, shotfirestop);
setint.addEventListener(TimerEvent.TIMER, shotfirestart);
setenemy.addEventListener(TimerEvent.TIMER, addenemy);
stage.addEventListener(Event.ENTER_FRAME, mainloop);
setenemy.start();
}
public function addplayer():void {
tiger.y = 200;
tiger.x = 507;
addChild(tiger);
}
public function moveplayer(e:MouseEvent):void {
tiger.y = mouseY;
tiger.x = 507;
}
public function shotfire(e:MouseEvent):void {
setint.start();
}
public function shotfirestop(e:MouseEvent):void {
setint.stop();
}
public function shotfirestart(e:TimerEvent):void {
var fire:Fire = new Fire();
fire.x = 460;
fire.y = mouseY;
addChild(fire);
ammoleft -= 1;
ammo.push(fire);
}
public function addenemy(e:TimerEvent):void {
var enemy:Enemy = new Enemy();
enemy.x = 0;
enemy.y = Math.floor(Math.random() * (370 - 30) + 30);
addChild(enemy);
enemys.push(enemy);
}
public function mainloop(e:Event):void {
setscoreandammo();
moveammo();
moveenemy();
checkhitammo();
}
public function moveammo():void {
for (var i:int = 0; i < ammo.length; i++) {
ammo[i].x -= 15;
if (ammo[i].x < -30) {
removeChild(ammo[i]);
ammo[i] = null;
ammo.splice(i, 1);
}
}
}
public function moveenemy():void {
for (var b:int = 0; b < enemys.length; b++) {
enemys[b].x += 5;
if (enemys[b].x > 590) {
removeChild(enemys[b]);
enemys[b] = null;
enemys.splice(b, 1);
}
}
}
public function setscoreandammo():void {
score.text = String(scorea);
leftammo.text = String(ammoleft);
}
public function checkhitammo():void {
for (var i:int = ammo.length; i >= 0; i--) {
for (var b:int = enemys.length; b >= 0; b--) {
if (ammo[i].hitTestObject(enemys[b])) { // <--- this is the line where the error is fired
removeChild(ammo[i]);
ammo[i] = null;
ammo.splice(i, 1);
removeChild(enemys[b]);
enemys[b] = null;
enemys.splice(b, 1);
scorea += 50;
break;
}
}
}
}
}
}
Your specific problem is right here...
public function checkhitammo():void {
for (var i:int = ammo.length; i >= 0; i--) {
for (var b:int = enemys.length; b >= 0; b--) {
...you are starting the counters i and b with the length of the array, instead of the position of the last index. It should read...
public function checkhitammo():void {
for (var i:int = ammo.length - 1; i >= 0; i--) {
for (var b:int = enemys.length - 1; b >= 0; b--) {
That is, the length is 1-based, and positions are 0-based
first of all, all your for loops only has increment by 1 you may want to use like this
for (var i in ammo) {
for (var b in enemys) {
you just have to loop through array until something happens and break out of loop to make sure it doesn't check twice.
in this line
if (ammo[i].hitTestObject(enemys[b])) {
the error says program cannot find object in the array list, since it's just array it does not throw error like null pointer exception
if you swap ammo with enemys you will see that hitTestObject is trying to access a null object
and you don't really need to call this
ammo[i] = null;
since its already being removed

Remove timer event listener

so I need to remove a timer event. But the problem is, It's in another function so I can't access it.
Here's how my code goes:
-There is a Boss
-It generates bomb
-Bomb lasts for a couple of seconds before exploding (no error)
-Bomb can be removed by clicking. (generates error)
If the bomb was removed via clicking, there will be error because the time event wasn't remove. But like I said, I can't remove it because it's in another function. Help!
import flash.events.Event;
import flash.display.MovieClip;
var boss:MovieClip = new darklord();
this.addChild(boss);
boss.x = stage.stageWidth / 2;
boss.y = stage.stageHeight / 2;
var lives:int = 3;
var maxHP:int = 2000;
var currentHP:int = maxHP;
var percentHP:Number = currentHP / maxHP;
var bombcontainer:Array = [];
var timecontainer:Array = [];
function updateHealthBar():void
{
percentHP = currentHP / maxHP;
healthBar.barColor.scaleX = percentHP;
}
boss.addEventListener(MouseEvent.CLICK, TapBoss);
boss.addEventListener(Event.ENTER_FRAME, MoveBoss);
function TapBoss(e:MouseEvent):void
{
currentHP -= 10;
if (currentHP <= 0)
{
currentHP = 0;
trace("You win!");
}
updateHealthBar();
}
var timerBoss:Timer = new Timer(1000,60);
timerBoss.addEventListener(TimerEvent.TIMER, bosstimerhandler);
timerBoss.start();
var secondsBoss:Number = 0;
function bosstimerhandler(event:TimerEvent)
{
//trace("Seconds elapsed: " + seconds);
//SpawnNote(null);
if (secondsBoss%5==0)
{
RandomCoord(null);
BossAttack(null);
}
secondsBoss++;
}
var HighH:int = stage.stageHeight;
var HighW:int = stage.stageWidth;
var LowH:int = 0;
var LowW:int = 0;
var destinationX:int;
var destinationY:int;
function RandomCoord(event:Event):void
{
destinationX=Math.floor(Math.random()*(1+HighW-LowW))+LowW;
destinationY=Math.floor(Math.random()*(1+HighH-LowH))+LowH;
if (destinationX <= 50)
{
destinationX += 50;
}
if (destinationY <= 50)
{
destinationY += 50;
}
if (destinationX + 50 >= stage.stageWidth)
{
destinationX -= 50;
}
if (destinationY + 50 >= stage.stageHeight)
{
destinationY -= 50;
}
trace("X is: ", destinationX);
trace("Y is: ", destinationY);
}
function MoveBoss(event:Event):void
{
if (boss.x < destinationX)
{
boss.x += 1;
}
else if (boss.x > destinationX)
{
boss.x -= 1;
}
if (boss.y < destinationY)
{
boss.y += 1;
}
else if (boss.y > destinationY)
{
boss.y -= 1;
}
}
function BossAttack(event:Event):void
{
var boom:MovieClip = new Bomb();
this.addChild(boom);
bombcontainer.push(boom);
boom.x = boss.x;
boom.y = boss.y;
BombCoord(null);
boom.addEventListener(Event.ENTER_FRAME, MoveBomb);
boom.addEventListener(MouseEvent.CLICK, TapBomb(boom));
BombTimer(boom);
}
function BombTimer(boom:MovieClip):void
{
var time:Timer = new Timer(1000,30);
timecontainer.push(time);
time.addEventListener(TimerEvent.TIMER, TimeHandler);
time.start();
var t:Number = 1;
function TimeHandler(event:TimerEvent):void
{
trace("Seconds elapsed: " + t);
t++;
if (t==12)
{
lives--;
trace("You lost a life!");
time.removeEventListener(TimerEvent.TIMER, TimeHandler);
RemoveBomb(boom, 0);
}
}
}
function RemoveBomb(boom:DisplayObject, bid:int):void
{
boom.removeEventListener(Event.ENTER_FRAME, MoveBomb);
//boom.removeEventListener(MouseEvent.CLICK, TapBomb(boom));
bombcontainer.splice(bid, 1);
trace("Bomb # :" +bid+" is popped.");
this.removeChild(boom);
}
var BombX:int;
var BombY:int;
function BombCoord(event:Event):void
{
BombX=Math.floor(Math.random()*(1+HighW-LowW))+LowW;
BombY=Math.floor(Math.random()*(1+HighH-LowH))+LowH;
if (BombX <= 50)
{
BombX += 50;
}
if (BombY <= 50)
{
BombY += 50;
}
if (BombX + 50 >= stage.stageWidth)
{
BombX -= 50;
}
if (BombY + 50 >= stage.stageHeight)
{
BombY -= 50;
}
}
function MoveBomb(event:Event):void
{
var boom:DisplayObject = event.target as DisplayObject;
var fl_TimerInstance:Timer = new Timer(1000,6);
fl_TimerInstance.addEventListener(TimerEvent.TIMER, fl_TimerHandler);
fl_TimerInstance.start();
var fl_SecondsElapsed:Number = 1;
function fl_TimerHandler(event:TimerEvent):void
{
//trace("Seconds elapsed: " + fl_SecondsElapsed);
fl_SecondsElapsed++;
if (fl_SecondsElapsed==4)
{
boom.removeEventListener(Event.ENTER_FRAME, MoveBomb);
}
}
if (boom.x < BombX)
{
boom.x += 5;
//boom.x +=5;
}
else if (boom.x > BombX)
{
boom.x -= 5;
}//boom.x -=5;
if (boom.y < BombY)
{
boom.y += 5;
//boom.x +=5;
}
else if (boom.y > BombY)
{
boom.y -= 5;
}
if (boom.x == BombX)
{
if (boom.y == BombY)
{
boom.removeEventListener(Event.ENTER_FRAME, MoveBomb);
}
}
if (boom.y == BombY)
{
if (boom.x == BombX)
{
boom.removeEventListener(Event.ENTER_FRAME, MoveBomb);
}
}
}
function TapBomb(boom:MovieClip):Function
{
return function(e:MouseEvent):void {
var BombIndex:int = bombcontainer.indexOf(boom);
trace("You clicked the bomb at index " + BombIndex);
RemoveBomb(boom, BombIndex);
}
}
It's not that bad having a frame event listener on each bomb, unless perhaps you have hundreds of bombs at the same time.
You can solve the issue by making the Bomb a separate class that has its own handlers and timer. Something like this (not tested):
package {
import flash.display.*;
import flash.net.*;
import flash.utils.Timer;
public class Bomb extends MovieClip {
private var myTimer:Timer;
public function Bomb() {
myTimer = new Timer(1000,30);
myTimer.addEventListener(TimerEvent.TIMER, TimeHandler);
myTimer.start();
}
private function TimeHandler(event:TimerEvent):void {
// check the time
}
public function stopTicking():void {
this.myTimer.stop();
}
}
}
You can then create all the bombs you want and kill their timers by calling their method:
// create a bomb movieclip and add it to the displaylist
var myBomb = new Bomb();
bombContainer.addChild(myBomb);
// use the displaylist to keep track of nonexploded bombs
var someBomb = bombContainer.getChildAt(0);
// stop the timer on this bomb
someBomb.stopTicking();

Odd numbers of object extraction from an array

I'm trying to get 2 objects at a time form the array for now. but soon I will be using odd number of length and splicing items.
This works out perfectly so far with Even numbers in the Array, but I am not sure how to make it work with odd numbers. The way I think it may work is ask it to check the objects coming up next and if it is less than 2 than change the counters to 1. but I am not even sure how to put that in code specifically. I posted my code so far be
import flash.events.MouseEvent;
import flash.net.Socket;
var socket_Array_current_position = 0;
var socket_counter = 2;
var socket_Array: Array = new Array ();
socket_Array.push(socket_one, socket_two,socket_three, socket_four, socket_five, socket_six);
go_next_left.addEventListener(MouseEvent.CLICK, go_left);
go_next_right.addEventListener(MouseEvent.CLICK, go_right);
function go_left(going_left:MouseEvent)
{
if (socket_Array_current_position > 0)
{
socket_remove();
socket_Array_current_position -= socket_counter;
socket_x_position = 125;
socket_display();
}
}
function go_right(going_right:MouseEvent)
{
if (socket_Array_current_position < socket_Array.length-socket_counter)
{
socket_remove();
socket_Array_current_position += socket_counter;
socket_x_position = 125;
socket_display();
}
}
socket_display();
function socket_display()
{
var s = 0;
for (s; s < socket_counter; s++)
{
addChild(socket_Array[socket_Array_current_position + s]);
socket_Array[socket_Array_current_position + s].x = socket_x_position;
socket_Array[socket_Array_current_position + s].y = socket_y_position;
//socket_Array[s].addEventListener(MouseEvent.CLICK, picked);
socket_x_position = socket_x_position + 275;
}
}
function socket_remove()
{
var s = 0;
for (s; s < socket_counter; s++)
{
removeChild(socket_Array[socket_Array_current_position+s]);
}
}
I suppose that you want display X objects (in this case two) at a time from an array. Whatever length. I'm using Math lib. Consider that I didn't try the code below with sdk or Flash.
const X_START_POS:int = 125;
const COLUMN_WIDTH:int = 275;
const QTY_SCREEN:int = 2;
var socket_Array:Array = new Array();
var socket_Array_pos:int = 0;
var socket_Array_target:int = 0; // target is always right
var socket_Array_on_screen:Array = new Array();
// socket_Array.length must be >= QTY_SCREEN, always.
socket_Array.push(socket_one, socket_two, socket_three, socket_four, socket_five, socket_six);
go_next_left.addEventListener(MouseEvent.CLICK, go_left);
go_next_right.addEventListener(MouseEvent.CLICK, go_right);
socket_display();
function go_left(going_left:MouseEvent) {
socket_Array_target = Math.max(socket_Array_pos - QTY_SCREEN, 0);
socket_display();
}
function go_right(going_right:MouseEvent) {
socket_Array_target = Math.min(socket_Array_pos + QTY_SCREEN, socket_Array.length - QTY_SCREEN);
socket_display();
}
function socket_display() {
socket_remove();
socket_x_position = X_START_POS;
var limit:int = socket_Array_target + QTY_SCREEN;
for (var i = socket_Array_target; i < limit; i++) {
show_socket(socket_Array[i]);
socket_x_position += COLUMN_WIDTH;
}
socket_Array_pos = socket_Array_target;
}
function show_socket(asocket:DisplayObject) {
addChild(asocket);
asocket.x = socket_x_position;
asocket.y = socket_y_position;
socket_Array_on_screen.push(asocket); // remember me
}
function socket_remove() {
var qty:int = socket_Array_on_screen.length;
for (var s = 0; s < qty; s++) {
removeChild(socket_Array_on_screen.pop());
}
}

AS3 Flash: Spawning 2 same objects from 1 class?

I am creating a game in AS3, and in the class file for an enemy's bullet, I have this code.
public class enemy2Bullet extends MovieClip
{
public function enemy2Bullet()
{
stop();
//Setup an event listener to see if the bullet is added to the stage.
addEventListener(Event.ADDED_TO_STAGE, onAdd);
}
private function onAdd(e:Event):void
{
removeEventListener(Event.ADDED_TO_STAGE, onAdd);
//Now that our object is on the stage, run our custom code.
init();
}
private function init():void
{
if (Math.random() <= 0.5)
{
addEventListener(Event.ENTER_FRAME, bullet2Loop)
}
else
{
addEventListener(Event.ENTER_FRAME, bullet2Loop2)
}
}
private function bullet2Loop(e:Event):void
{
if (currentLabel != "destroyed")
{
this.x += 8;
}
if (currentLabel == "destroyedComplete")
{
destroyEnemy2Bullet();
}
}
private function bullet2Loop2(e:Event):void
{
if (currentLabel != "destroyed")
{
this.x -= 8;
}
if (currentLabel == "destroyedComplete")
{
destroyEnemy2Bullet();
}
}
public function destroyEnemy2Bullet():void
{
{
//Remove the object from stage
stage.removeChild(this);
//Remove any event listeners
removeEventListener(Event.ENTER_FRAME, bullet2Loop);
}
}
}
After compiling, the game runs, but the bullet only shoots in 1 direction.
How can I make it such that the bullets are shot from both left and right, and stay in that direction?
Here's my enemy2 function.
private function enemy2Control():void
{
if (getTimer() - lastSpawnTime2 > 3000 && aEnemy2Array.length < 3)
{
var newEnemy2:MovieClip = new mcEnemy2;
newEnemy2.x = Math.random() * 800;
newEnemy2.y = 0;
aEnemy2Array.push(newEnemy2);
stage.addChild(newEnemy2);
lastSpawnTime2 = getTimer();
}
//Control enemy's bullets
for (var i:int = aEnemy2Array.length - 1; i >= 0; i--)
{
if (enemy2LastFire + 750 / (aEnemy2Array.length) < getTimer())
{
var currentEnemy2:mcEnemy2 = aEnemy2Array[i];
if (Math.random() < 0.06)
{
var newEnemy2Bullet:enemy2Bullet = new enemy2Bullet();
newEnemy2Bullet.x = currentEnemy2.x;
newEnemy2Bullet.y = currentEnemy2.y;
enemy2BulletArray.push(newEnemy2Bullet);
stage.addChild(newEnemy2Bullet);
enemy2LastFire = getTimer();
}
}
for (var j:int = enemy2BulletArray.length - 1; j >= 0; j--)
{
var currentEnemy2Bullet:enemy2Bullet = enemy2BulletArray[j];
if (currentEnemy2Bullet.y >= stage.stageHeight)
{
enemy2BulletArray.splice(j, 1);
currentEnemy2Bullet.destroyEnemy2Bullet();
}
if (currentEnemy2Bullet.hitTestObject(playerCore))
{
playerHP -= 1;
currentEnemy2Bullet.gotoAndPlay(2);
enemy2BulletArray.splice(j, 1);
}
}
}
}
Any help would be appreciated.
A few things:
• You can replace currentEnemy2Bullet with j and just delete the whole var currentEnemy2Bullet:enemy2Bullet = enemy2BulletArray[j]; statement.
• init() is never called. But it's best if you do the direction calculation and use newEnemy2Bullet.addEventListener(Event.ENTER_FRAME, whatever) within the actual initialization of newEnemy2Bullet.
• Truth to be told, your code is fairly messy and can be simplified. For example, you can just determine the direction of the bullet by giving the class a variable, give it a value on initialization, and have the loop update its position based on that variable.