Loop a function name in as3 - actionscript-3

How would I create a simple loop to create these functions:
function hello1(e:Event):void
{
trace("hi");
}
function hello2(e:Event):void
{
trace("hi");
}
The function name goes in order until it stops at
function hello10(e:Event):void
{
trace("hi");
}
I know I can just use one function but I am using this as an example for a larger project.

Functions are just like any other object is ActionScript 3, so you can pass them by reference.
Try something like this.
var functionList:Array = [];
var func:Function;
var numFunctions:int = 10;
for (var i:int = 0; i < numFunctions; i++)
{
func = function(num:Number):void
{
trace(num);
};
functionList.push(func);
}
for (var j:int = 0; j < functionList.length; j++)
{
func = functionList[j] as Function;
func(Math.random()* 100);
}

There are many way to accomplish this.
You could store all function in an array, then call Function pointers.
Or, maybe something like:
package
{
import flash.display.Sprite;
import flash.events.Event;
public class HelloLoop extends Sprite
{
public function hello1(event:Event):void
{
trace("hi - 1");
}
public function hello2(event:Event):void
{
trace("hi - 2");
}
public function hello3(event:Event):void
{
trace("hi - 3");
}
public function HelloLoop()
{
// not sure what event you are passing
var event:Event = new Event("unknown");
for (var i:uint = 1; i <= 3; i++)
{
this["hello" + i](event);
}
}
}
}

Related

Making a reset placed objects button in Flash (as3)

I have a drag and drop project where everytime I click on a movieclip a clone is made that can be dragged. I would like to know how to make a button that can reset/remove the clones when the button is pressed.
This is what I got so far:
import flash.display.MovieClip;
var latestClone:MovieClip;
plus.addEventListener(MouseEvent.MOUSE_DOWN, onPlusPressed);
function onPlusPressed(event:MouseEvent):void
{
latestClone = new Plus();
latestClone.x = event.stageX;
latestClone.y = event.stageY;
addChild(latestClone);
latestClone.startDrag();
latestClone.addEventListener(MouseEvent.MOUSE_DOWN, latestClone.startDrag);
}
stage.addEventListener(MouseEvent.MOUSE_UP, onStageReleased);
function onStageReleased(event:MouseEvent):void
{
if(latestClone != null){
latestClone.stopDrag();
}
}
Add all of your clones in an array, and loop over the array and do a removeChild on each item in the array. So:
var items:Array = new Array();
....
addChild(latestClone);
items.push(latestClone);
....
var resetButton:SimpleButton = new SimpleButton();
//set your button properties here
resetButton.addEventListener(MouseEvent.CLICK, onResetClicked);
addChild(resetButton);
function onResetClicked(e:MouseEvent):void
{
reset();
}
function reset():void
{
for (var i:uint = 0; i < items.length; i ++)
{
removeChild(items[i]);
items[i] = null;
}
items = new Array();
}
Hope this helps.
just declare container variable like so:
var clone_container:Sprite = new Sprite();
put all clones inside,than u can clear it up very easely:
while(clone_container.numChildren > 0){
clone_container.removeChildAt(0);
}
that's all..
I found the solution to my question by testing several possibilities with the code that was posted + searching other questions.
This is the code that worked:
import flash.display.MovieClip;
import flash.events.MouseEvent;
var latestClone:MovieClip;
plus.addEventListener(MouseEvent.MOUSE_DOWN, onPlusPressed);
function onPlusPressed(event:MouseEvent):void
{
latestClone = new Plus();
latestClone.x = event.stageX;
latestClone.y = event.stageY;
addChild(latestClone);
latestClone.startDrag();
latestClone.addEventListener(MouseEvent.MOUSE_DOWN,onClonedPlusPressed);
}
function onClonedPlusPressed(event:MouseEvent):void{
latestClone = MovieClip(event.currentTarget);
latestClone.startDrag();
}
stage.addEventListener(MouseEvent.MOUSE_UP, onStageReleased);
function onStageReleased(event:MouseEvent):void
{
if(latestClone != null){
latestClone.stopDrag();
items.push(latestClone);
}
}
resetButton.addEventListener(MouseEvent.CLICK, fl_MouseClickHandler);
function fl_MouseClickHandler(event:MouseEvent):void
{
}
var items:Array = new Array();
resetButton.addEventListener(MouseEvent.CLICK, onResetClicked);
addChild(resetButton);
function onResetClicked(e:MouseEvent):void
{
reset();
}
function reset():void
{
for (var i:uint = 0; i < items.length; i ++)
{ items[i].removeEventListener(MouseEvent.MOUSE_DOWN,onClonedPlusPressed);
if(items[i].parent) items[i].parent.removeChild(items[i]);
items[i] = null;
}
items = new Array()
}
you most add an array and push object into this,
your solution:
import flash.display.MovieClip;
import flash.events.Event;
var latestClone:MovieClip;
plus.addEventListener(MouseEvent.MOUSE_DOWN, onPlusPressed);
var plusArray:Array = new Array();
resetbtn.addEventListener(MouseEvent.CLICK,resetFunc);
function resetFunc(e:Event)
{
for (var i=0; i<plusArray.length; i++)
{
removeChild(plusArray[i]);
}
plusArray = new Array()
}
function onPlusPressed(event:MouseEvent):void
{
latestClone = new Plus();
latestClone.x = event.stageX;
latestClone.y = event.stageY;
plusArray.push(latestClone);
addChild(plusArray[plusArray.length-1]);
plusArray[plusArray.length - 1].startDrag();
plusArray[plusArray.length - 1].addEventListener(MouseEvent.MOUSE_DOWN, plusArray[plusArray.length-1].startDrag);
}
stage.addEventListener(MouseEvent.MOUSE_UP, onStageReleased);
function onStageReleased(event:MouseEvent):void
{
if (latestClone != null)
{
latestClone.stopDrag();
}
}
Good luck

Can I get some tips With My Inventory system for my game. I want to use an object in my inventory with another object (like a Key to a Door)

This is my Main Class:
package {
import flash.display.*;
public class InventoryDemo extends MovieClip {
var inventory:Inventory;
public function InventoryDemo() {
}
public function initialiseInventory():void
{
inventory = new Inventory(this);
inventory.makeInventoryItems([d1,d2]);
}
}
}
I used a sprite indicator to show that the items are inside the inventory.
And this is my child class:
package {
import flash.display.*;
import flash.events.*;
public class Inventory
{
var itemsInInventory:Array;
var inventorySprite:Sprite;
public function Inventory(parentMC:MovieClip)
{
itemsInInventory = new Array ;
inventorySprite = new Sprite ;
inventorySprite.x = 50;
inventorySprite.y = 360;
parentMC.addChild(inventorySprite);
}
function makeInventoryItems(arrayOfItems:Array)
{
for (var i:int = 0; i < arrayOfItems.length; i++)
{
arrayOfItems[i].addEventListener(MouseEvent.CLICK,getItem);
arrayOfItems[i].buttonMode = true;
}
}
function getItem(e:Event)
{
var item:MovieClip = MovieClip(e.currentTarget);
itemsInInventory.push(item);
inventorySprite.addChild(item);
item.x = itemsInInventory.length - 1 * 40;
item.y = 0;
item.removeEventListener(MouseEvent.CLICK,getItem);
item.addEventListener(MouseEvent.CLICK,useItem);
}
function useItem(e:Event)
{
var item:MovieClip = MovieClip(e.currentTarget);
trace(("Use Item:" + item.name));
}
}
}
Currently i can only click and trace the output, I was wondering how i can drag the sprite and use it to another object...like a key to unlock a door. Big thanks, btw im new in as3 and im trying to learn from stack overflow.
item.addEventListener(MouseEvent.CLICK,useItem);
var drag:Boolean;
function useItem(e:Event)
{
var item:MovieClip = MovieClip(e.currentTarget);
trace(("Use Item:" + item.name));
if(drag == false)
{
item.startDrag();
drag = true;
}else{
item.stopDrag();
drag = false;
findAction(e);
}
}
function findAction(e)
{
// Check the position of the key relative to the door.
}
Haven't really checked it but it'd probably work if you did something similar.

Trace is not working in Actionscript 3 Flash CS5

I am having an issue with using trace();
For example, at multiple points in my project (and other projects) I had trace statements, which functioned until recently. For some reason now, in the same projects where it worked before, trace no longer displays anything in the Output window.
I have checked and done the following:
Verified that the filter for Output is either None or Verbose
I'm publish previewing to Flash, not HTML
In the publish settings tab, "omit trace actions" is unchecked
Verified I have flash player debugger by double checking with right clicking on flashplayer window, and seeing the option "Debugger".
Reset workspace, just in case there was something funky going on.
Read 3 other posts in StackOverflow about same issue, tried each one's solution but yet to get it to work.
Does anyone have any ideas? I had added complete code.
package
{
//importing classes
import flash.display.Sprite;
import flash.events.MouseEvent;
import flash.events.TimerEvent;
import flash.utils.Timer;
import flash.events.Event;
//END importing classes
public class Main extends Sprite
{
//class level variables
private const FIELD_W:uint=9;
private const FIELD_H:uint=9;
private const NUM_MINES:uint=10;
private var mineField:Array=new Array();
private var game_container:Sprite=new Sprite();
private var tile:tile_movieclip;
private var timer:Timer=new Timer(1000);
private var toolbar:toolbar_mc;
private var gameOver:Boolean=false;
private var firstClick:Boolean=true;
private var remainingTiles:uint=FIELD_W*FIELD_H;
private var minesLeft:uint=NUM_MINES;
private var screenFrame:Screens;
//END class level variables
public function Main()
{
//Mine Field Creation
for (var i:uint=0; i<FIELD_H; i++)
{
mineField[i]=new Array();
for (var j:uint=0; j<FIELD_W; j++)
{
mineField[i].push(0);
}
}
trace("My dangerous mine field: "+mineField);
//END Mine Field Creation
addChild(game_container);
for (i=0; i<FIELD_H; i++)
{
for (j=0; j<FIELD_W; j++)
{
tile = new tile_movieclip();
game_container.addChild(tile);
tile.gotoAndStop(1);
tile.nrow=i;
tile.ncol=j;
tile.buttonMode=true;
tile.x=tile.width*j;
tile.y=tile.height*i;
tile.addEventListener(MouseEvent.CLICK,onTileClicked);
}
}
// end of tile creation
//time amangement and game over
toolbar = new toolbar_mc();
addChild(toolbar);
//var s_height:uint= stage.height;
toolbar.y=725;
timer.start();
timer.addEventListener(TimerEvent.TIMER,onTick);
//end of time management and game over
}//END Main function
private function onTick(e:TimerEvent):void
{
toolbar.message_text.text="Elapsed time: "+timer.currentCount+"s";
//trace("Elapsed time: "+timer.currentCount);
}
private function tileValue(row,col:uint):int
{
if (mineField[row]==undefined || mineField[row][col]==undefined)
{
return -1;
}
else
{
return mineField[row][col];
}
}
private function onTileClicked(e:MouseEvent):void
{
if (!gameOver && remainingTiles > 0)
{
var clicked_tile:tile_movieclip=e.currentTarget as tile_movieclip;
clicked_tile.removeEventListener(MouseEvent.CLICK,onTileClicked);
clicked_tile.buttonMode=false;
var clickedRow:uint=clicked_tile.nrow;
var clickedCol:uint=clicked_tile.ncol;
var clickedValue:uint=mineField[clickedRow][clickedCol];
if (firstClick)
{
firstClick=false;
//placing mines
var placedMines:uint=0;
var randomRow,randomCol:uint;
while (placedMines<NUM_MINES)
{
randomRow = Math.floor(Math.random()*FIELD_H);
randomCol = Math.floor(Math.random()*FIELD_W);
if (mineField[randomRow][randomCol] ==0)
{
if (randomRow!=clickedRow||randomCol!=clickedCol)
{
mineField[randomRow][randomCol] = 9;
placedMines++;
}
}
}//END placing Mines
// placing digits
for (var i:uint=0; i<FIELD_H; i++)
{
for (var j:uint=0; j<FIELD_W; j++)
{
if (mineField[i][j]==9)
{
for (var ii:int =-1; ii<=1; ii++)
{
for (var jj:int =-1; jj<=1; jj++)
{
if (ii!=0||jj!=0)
{
if (tileValue(i+ii,j+jj)!=9&&tileValue(i+ii,j+jj)!=-1)
{
mineField[i+ii][j+jj]++;
}
}
}
}
}
}
}
var debugString:String;
trace("My complete and formatted mine field: ");
for (i=0; i<FIELD_H; i++)
{
debugString="";
for (j=0; j<FIELD_W; j++)
{
debugString+=mineField[i][j]+" ";
}
trace(debugString);
}
// end of placing digits
// tile creation
}
if (e.shiftKey)
{
clicked_tile.gotoAndStop(5-clicked_tile.currentFrame);
remainingTiles--;
if (remainingTiles ==0)
{
timer.stop();
//Create a for loop involving string for number that appears on tiles
toolbar.message_text.text="WinBomb";
screenFrame = new Screens();
game_container.addChild(screenFrame);
screenFrame.gotoAndStop("win");
}
if (clickedValue ==9)
{
minesLeft--;
if (minesLeft==0)
{
timer.stop();
//Create a for loop involving string for number that appears on tiles
toolbar.message_text.text="Mine Free!!";
removeChild(toolbar);
screenFrame = new Screens();
game_container.addChild(screenFrame);
screenFrame.gotoAndStop("win");
}
}
}
else
{
//empty tile
if (clickedValue == 0)
{
floodFill(clickedRow,clickedCol);
}//END empty Tile
// numbered tile
if (clickedValue>0&&clickedValue<9)
{
clicked_tile.gotoAndStop(2);
clicked_tile.tile_text.text=clickedValue.toString();
remainingTiles--;
if (remainingTiles ==0)
{
toolbar.message_text.text="Mine Free!!";
removeChild(toolbar);
screenFrame = new Screens();
game_container.addChild(screenFrame);
screenFrame.gotoAndStop("win");
}
}// end of numbered tile
// mine
if (clickedValue==9)
{
clicked_tile.gotoAndStop(3);
timer.removeEventListener(TimerEvent.TIMER,onTick);
removeChild(toolbar);
screenFrame = new Screens();
game_container.addChild(screenFrame);
screenFrame.gotoAndStop("lose");
/*timer=new Timer(5000);
timer.start();
trace("Timer to End: "+timer.currentCount);
timer.addEventListener(TimerEvent.TIMER_COMPLETE, loseScreen); screenFrame = new Screens();
*/
}// end of mine
}
}
else if (remainingTiles == 0)
{
timer.stop();
toolbar.message_text.text="Mine Free!!";
removeChild(toolbar);
screenFrame = new Screens();
game_container.addChild(screenFrame);
screenFrame.gotoAndStop("win");
}
}//END onTileClicked function
private function floodFill(row,col:uint):void
{
var emptyTile:tile_movieclip;
emptyTile=game_container.getChildAt(row*FIELD_W+col) as tile_movieclip;
if (emptyTile.currentFrame==1)
{
emptyTile.removeEventListener(MouseEvent.CLICK,onTileClicked);
emptyTile.buttonMode=false;
emptyTile.gotoAndStop(2);
if (mineField[row][col]>0)
{
emptyTile.tile_text.text=mineField[row][col].toString();
remainingTiles--;
}
else
{
emptyTile.gotoAndStop(5);
remainingTiles--;
}
if (mineField[row][col]==0)
{
for (var ii:int =-1; ii<=1; ii++)
{
for (var jj:int =-1; jj<=1; jj++)
{
if (ii!=0||jj!=0)
{
if (tileValue(row+ii,col+jj)!=9)
{
if (tileValue(row+ii,col+jj)!=-1)
{
floodFill(row+ii,col+jj);
}
}
}
}
}
}
}
}//END floodFill
/* private function loseScreen(e:TimerEvent)
{
timer.removeEventListener(TimerEvent.TIMER_COMPLETE, loseScreen);
game_container.addChild(screenFrame);
screenFrame.gotoAndStop("lose");
}*/
}//END Main CLass
}//END package
Looking at the top part of your code, here's a slight re-arrangement. In this experiment I've taken the liberty of initializing your '_FIELD' variables. Try it. Does this solve your problem?
var mineField:Array = new Array;
var FIELD_H:int = 10;
var FIELD_W:int = 20;
for (var i:uint=0; i<FIELD_H; i++)
{
mineField[i]=new Array();
for (var j:uint=0; j<FIELD_W; j++)
{
mineField[i].push(0);
}
}
trace(mineField);
First
Your Main Class isn't correctly written. If it's imported, your compiler should output the following error message:
1114: The public attribute can only be used inside a package.
Because the general form of a Class is:
package myPackage
{
class MyClass
{
}
}
On the other hand
Specifically, this error message doesn't occur because you haven't probably imported your Main class:
File > ActionScript Settings > Document Class : Main

Flash events execution order

Check out the next code, tell me what do you expect to be printed. Then run it and check what is really happen.
package
{
import flash.display.Sprite;
import flash.events.Event;
public class TestFlashEvents extends Sprite
{
private static const DUMMY_EVENT:String = "DummyEvent";
private var dummyObjects:Vector.<DummyObject> = new Vector.<DummyObject>(100);
public function TestFlashEvents()
{
for(var i:int = 0; i < dummyObjects.length; i++){
dummyObjects[i] = new DummyObject(this);
addEventListener(DUMMY_EVENT, dummyObjects[i].listener);
}
removeEventListener(DUMMY_EVENT, dummyObjects[41].listener);
dispatchEvent(new Event(DUMMY_EVENT));
}
private var counter:int = 0;
public function onGettingEvent(dummyObject:DummyObject):void{
if(counter == 25){
for(var i:int = 0; i < 50; i++){
removeEventListener(DUMMY_EVENT, dummyObjects[i].listener);
trace("Removing", dummyObjects[i].id);
}
}
trace("Handeling event", counter, dummyObject.id);
counter++;
}
}
}
import flash.events.Event;
class DummyObject
{
private static var dummyObjectsCounter:int = 0;
public var id:String;
private var tester:TestFlashEvents;
public function DummyObject(tester:TestFlashEvents)
{
this.tester = tester;
id = "DummyObject " + dummyObjectsCounter;
dummyObjectsCounter++;
}
public function listener(event:Event):void{
tester.onGettingEvent(this);
}
}
The removeEventListener function is actually not working. Tell me what do you think about it. I also open a bug in adobe.
This code means Adobe caches event listener list prior to actually calling event listeners. It is an unusual behavior to have two listeners for one particular event over one single object, but if it happens, Adobe assumed that all listeners should be invoked prior to actually modifying this list. I was actually expecting all 99 listeners to get called. So, this behavior can even be by design, because re-rendering the event listener list while processing a single event will put a too heavy load on Flash, so that the lags will galore. No one wants lags.
This can easily be fixed by prioritizing you event listeners.
This is not a Flash bug, it is, like Vesper said caching of event listeners to prevent lag.
Here is the updated version of your code, mark the prioritizing on the addEventListener call.
package
{
import flash.display.Sprite;
import flash.events.Event;
public class TestFlashEvents extends Sprite
{
private var _this = this;
private static const DUMMY_EVENT:String = "DummyEvent";
private var dummyObjects:Vector.<DummyObject> = new Vector.<DummyObject>(100);
public function TestFlashEvents()
{
for(var i:int = 0; i < dummyObjects.length; i++)
{
dummyObjects[i] = new DummyObject(this);
addEventListener(DUMMY_EVENT, dummyObjects[i].listener, false, dummyObjects.length - i);
}
removeEventListener(DUMMY_EVENT, dummyObjects[41].listener);
dispatchEvent(new Event(DUMMY_EVENT));
}
private var counter:int = 0;
public function onGettingEvent(dummyObject:DummyObject):void
{
if (counter == 25)
{
for (var i:int = 0; i < 50; i++)
{
removeEventListener(DUMMY_EVENT, dummyObjects[i].listener);
trace("Removing", dummyObjects[i].id);
}
}
trace("Handeling event", counter, dummyObject.id);
counter++;
}
}
}
import flash.events.Event;
class DummyObject
{
private static var dummyObjectsCounter:int = 0;
public var id:String;
private var tester:TestFlashEvents;
public function DummyObject(tester:TestFlashEvents)
{
this.tester = tester;
id = "DummyObject " + dummyObjectsCounter;
dummyObjectsCounter++;
}
public function listener(event:Event):void{
tester.onGettingEvent(this);
}
}

How to make new bubbles stack in my Bubble Shooter game?

I'm making a Bubble Shooter game, and I'm trying to make the bubble I'm fireing to stack and then be at the right place in the column. The bubbles I've placed on the board looks like this:
000000000000000
000000000000000
000000000000000
000000000000000
There's 4 rows with 15 bubbles. This is the code I have written so far:
Main
package {
import flash.display.Sprite;
import flash.events.KeyboardEvent;
import flash.events.Event;
import flash.display.SpreadMethod;
public class Main extends Sprite {
private const ROT_SPEED:uint=2;
private const R:uint=18;
private const DEG_TO_RAD:Number=0.0174532925;
private const BUBBLE_SPEED:uint=10;
private var bubbleArr:Array=new Array();
private var loadArr:Array=new Array();
private var cannon:cannon_mc;
private var bubble:bubble_mc;
private var row:uint=0;
private var col:uint=0;
private var left:Boolean=false;
private var right:Boolean=false;
public var bubCont:Sprite;
private var loadCont:Sprite;
private var fire:Boolean=false;
private var vx,vy:Number;
public function Main() {
placeContainer();
placeCannon();
loadBubble();
stage.addEventListener(KeyboardEvent.KEY_DOWN,onKDown);
stage.addEventListener(KeyboardEvent.KEY_UP,onKUp);
addEventListener(Event.ENTER_FRAME,onEFrame);
trace("row= "+row+" , col= "+col);
}
private function placeCannon():void {
cannon=new cannon_mc();
addChild(cannon);
cannon.y=385.5;
cannon.x=320;
}
private function onKDown(e:KeyboardEvent):void {
switch(e.keyCode) {
case 37 :
left=true;
break;
case 39 :
right=true;
break;
case 38 :
if (! fire) {
fire=true;
var radians=(cannon.rotation-90)*DEG_TO_RAD;
vx=BUBBLE_SPEED*Math.cos(radians);
vy=BUBBLE_SPEED*Math.sin(radians);
}
break;
}
}
private function onKUp(e:KeyboardEvent):void {
switch(e.keyCode) {
case 37 :
left=false;
break;
case 39 :
right=false;
break;
}
}
private function onEFrame(e:Event):void {
if (left) {
cannon.rotation-=ROT_SPEED;
}
if (right) {
cannon.rotation+=ROT_SPEED;
}
if (fire) {
bubble.x+=vx;
bubble.y+=vy;
if (bubble.x<59) {
bubble.x=59;
vx*=-1;
}
if (bubble.x>(59+R*R)) {
bubble.x=59+R*R;
vx*=-1;
}
if (bubble.y<(40)) {
bubble.y=40;
}
}
}
public function placeContainer():void {
var iRow:Boolean=false;
bubCont=new Sprite();
addChild(bubCont);
for (var i:uint=0; i<4; i++) {
if (! iRow) {
for (var j:uint=0; j<15; j++) {
bubbleArr[i]=new Array();
bubbleArr[i][j]=Math.floor(Math.random()*6);
bubble = new bubble_mc(bubbleArr[i][j],i,j);
bubCont.addChild(bubble);
iRow=true;
row++;
col++;
}
} else {
for (j=0; j<15; j++) {
bubbleArr[i]=new Array();
bubbleArr[i][j]=Math.floor(Math.random()*6);
bubble = new bubble_mc(bubbleArr[i][j],i,j);
bubble.x=77+j*2*R;
bubCont.addChild(bubble);
iRow=false;
row++;
col++;
}
}
}
}
private function loadBubble():void {
addChild(bubble);
bubble.gotoAndStop(Math.floor(Math.random()*6))+1;
bubble.x=320;
bubble.y=410;
}
}
bubble_mc class:
package {
import flash.display.MovieClip;
public class bubble_mc extends MovieClip {
public function bubble_mc(val:uint,row:uint,col:uint) {
gotoAndStop(val+1);
name=row+"_"+col;
x=59+col*36;
y=40+row*32;
}
}
I have absolutley no idea how to make the bubbles stack together.. I have tried using hitTestObject-function and I have tried to write my own function that checks for collision and then calls a function that is supposed to place the bubble in the right place, but it doesn't work and I dont know why. I'm getting a error called TypeError: Error #1010.
Here is the collision function and the parkBubble function- which is supposed to place the bubbles in the right place:
private function parkBubble(bubble:bubble_mc,row:int,col:int):void {
var iRow:Boolean=false;
for (var j:uint=0; j<col; j++) {
trace("first for loop ");
for (var i:uint=row; i>0; i--) {
trace("second for loop ");
if (bubbleArr[i][j]!=null) {
trace("first if loop ");
if (! iRow) {
trace("second if loop ");
bubbleArr[i+1]=new Array();
bubbleArr[i+1][j]=Math.floor(Math.random()*6);
bubble = new bubble_mc(bubbleArr[i+1][j],(i+1),j);
bubCont.addChild(bubble);
iRow=true;
row++;
col++;
} else {
trace("first for loop after else ");
bubbleArr[i+1]=new Array();
bubbleArr[i+1][j]=Math.floor(Math.random()*6);
bubble = new bubble_mc(bubbleArr[i+1][j],(i+1),j);
bubble.x=77+j*2*R;
bubCont.addChild(bubble);
iRow=false;
row++;
col++;
}
}
}
}
removeChild(bubble);
fire=false;
loadBubble();
trace("slutet av parkBubble ");
}
private function collide(bub:bubble_mc):Boolean {
var dist_x:Number=bub.x-bubble.x;
var dist_y:Number=bub.y-bubble.y;
return Math.sqrt(dist_x*dist_x+dist_y*dist_y)<=2*R-4;
}
Was the TypeError on this line?
var placed_bubble:bubble_mc=new bubble_mc([row][col],row,col);
The [row] is an array, and [col] is an array. But the constructor expects an unsigned integer:
public function bubble_mc(val:uint,row:uint,col:uint) {
In order to copy the bubble to the bubble container, pass the frame number:
var placed_bubble:bubble_mc=new bubble_mc(bubble.currentFrame-1, row, col);
This might not be the only problem. TypeError often results from a variable not being defined, which could be from some other code that modifies the variable "bubble". For example, placeContainer assigns the bubbles in the container to the variable "bubble".
The function parkBubble always sets "iRow" to false, but if the bubble collides with a row above it that is odd you want iRow to be true.
var row:uint=Math.floor(bubble.y/(40+R*Math.sqrt(3)));
var iRow:Boolean= row % 2 == 1 ? true : false;
After it is at least compiling, you'll have less problems if you go back and simplify and optimize the math with some constant names. Then you'll more easily see the above code for calculating the row is not quite right. It should subtract the top margin (40). That is obvious with named constants:
private const Y_PER_ROW:int = int(R * Math.sqrt(3));
private const TOP:int = 40;
...
var row:uint = int((bubble.y - TOP) / Y_PER_ROW);
I would double-check your other calculations, too. Puzzle Bobble games usually set the odd rows to horizontally offset at radius, not at 2 radius (2 * R). So they fit together like hexagons.
The placeContainer function could be simplified. Most of the code in even or odd rows is the same, so could be taken out of the if block. And in this code you posted, I don't see why you need "row++" and "col++" in placeContainer. This is equivalent and easier to read:
for (var i:uint=0; i<4; i++) {
var xOffset:int = (i % 2) * 2 * R;
for (var j:uint=0; j<15; j++) {
bubbleArr[i] = new Array();
bubbleArr[i][j] = int(Math.random()*6);
bubble = new bubble_mc(bubbleArr[i][j], i, j);
bubble.x += xOffset;
bubCont.addChild(bubble);
row++;
col++;
}
}
Then, the collision detection code could be simplified and optimized to avoid calculations when the bubble is far away and avoid the expensive square-root calculation:
Circle Collision Detection HTML5 Canvas
http://cgp.wikidot.com/circle-to-circle-collision-detection