Trace is not working in Actionscript 3 Flash CS5 - actionscript-3

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

Related

Building Sokoban Game using Actionscript 3, and getting incorrect number of arguments

I've been doing this Sokoban game for the university, however, I'm stuck with something. Here's the code so far on AS3:
package
{
import flash.display.Sprite;
public class Main extends Sprite
{
private var levels:Array=new Array();
private var currentLevel:uint = 0;
private var tile:tiles_mc;
private var level_container:Sprite;
public function Main()
{
setupLevels();
drawLevel(currentLevel);
}
private function setupLevels():void
{
levels[0]=[[1,1,1,1,0,0,0,0],[1,0,0,1,1,1,1,1],[1,0,2,0,0,3,0,1],
[1,0,3,0,0,2,4,1],[1,1,1,0,0,1,1,1],[0,0,1,1,1,1,0,0]];
levels[1]=[[0,0,1,1,1,1,0,0],[0,0,1,0,0,1,0,0],[1,1,1,0,0,1,1,1],
[1,0,3,5,2,4,0,1],[1,0,0,0,0,0,0,1],[1,1,1,1,1,1,1,1]];
levels[2]=[[1,1,1,1,1,1,1,1],[1,0,0,1,0,0,0,1],[1,0,0,0,0,0,0,1],
[1,3,3,3,1,1,1,1],[1,6,2,0,2,1,0,0],[1,1,1,1,1,1,0,0]];
trace("My levels: "+levels);
}
private function drawLevel(level:uint):void
{
level_container = new Sprite();
addChild(level_container);
for (var i:uint=0; i<levels[currentLevel].length; i++)
{
for (var j:uint=0; j<levels[currentLevel][i].length; j++)
{
switch (levels[currentLevel][i][j])
{
case 0 :// floor
tile = new tiles_mc(1,i,j);
level_container.addChild(tile);
break;
case 1 :// wall
tile = new tiles_mc(1,i,j);
level_container.addChild(tile);
break;
case 2 :// crate goal
tile = new tiles_mc(1,i,j);
level_container.addChild(tile);
break;
}
}
}
}
}}
However, when I try to test, I get this error:
What's going on? Clearly AS recognises the arguments, as seen here:
What am I doing wrong?

I am creating an auto solve function for a sliding puzzle

I am new to actionscript and I am trying to make a "cheat" way of completing a sliding puzzle where when I click the [s] key it calls a solve puzzle function which makes a for loop put all the puzzle pieces in the correct location. This function must call a for loop, those were the instructions I was given. Could anyone help me understand the code that I need to make this happen. I have already made the function and it does properly call when I hit the s key but everything past that doesn't seem to make the code actually move the pieces. Thank you for any help I can get.
package {
import flash.display.*;
import flash.events.*;
import flash.net.URLRequest;
import flash.geom.*;
import flash.utils.Timer;
public class SlidingPuzzle extends MovieClip {
// space between pieces and offset
static const pieceSpace:Number = 2;
static const horizOffset:Number = 50;
static const vertOffset:Number = 50;
// number of pieces
static const numPiecesHoriz:int = 5;
static const numPiecesVert:int = 5;
// random shuffle steps
static const numShuffle:int = 200;
// animation steps and time
static const slideSteps:int = 10;
static const slideTime:int = 250;
// size of pieces
private var pieceWidth:Number;
private var pieceHeight:Number;
// game pieces
private var puzzleObjects:Array;
// tracking moves
private var blankPoint:Point;
private var slidingPiece:Object;
private var slideDirection:Point;
private var slideAnimation:Timer;
public function startSlidingPuzzle() {
// blank spot is the bottom right
blankPoint = new Point(numPiecesHoriz-1,numPiecesVert-1);
// load the bitmap
loadBitmap("oceanshore.jpg");
// event to complete the puzzle for you.
stage.addEventListener(KeyboardEvent.KEY_UP, solvePuzzle);
}
// get the bitmap from an external source
public function loadBitmap(bitmapFile:String) {
var loader:Loader = new Loader();
loader.contentLoaderInfo.addEventListener(Event.COMPLETE, loadingDone);
var request:URLRequest = new URLRequest(bitmapFile);
loader.load(request);
}
// bitmap done loading, cut into pieces
public function loadingDone(event:Event):void {
// create new image to hold loaded bitmap
var image:Bitmap = Bitmap(event.target.loader.content);
pieceWidth = image.width/numPiecesHoriz;
pieceHeight = image.height/numPiecesVert;
// cut into puzzle pieces
makePuzzlePieces(image.bitmapData);
// shuffle them
shufflePuzzlePieces();
}
// cut bitmap into pieces
public function makePuzzlePieces(bitmapData:BitmapData) {
puzzleObjects = new Array();
for(var x:uint=0;x<numPiecesHoriz;x++) {
for (var y:uint=0;y<numPiecesVert;y++) {
// skip blank spot
if (blankPoint.equals(new Point(x,y))) continue;
// create new puzzle piece bitmap and sprite
var newPuzzlePieceBitmap:Bitmap = new Bitmap(new BitmapData(pieceWidth,pieceHeight));
newPuzzlePieceBitmap.bitmapData.copyPixels(bitmapData,new Rectangle(x*pieceWidth,y*pieceHeight,pieceWidth,pieceHeight),new Point(0,0));
var newPuzzlePiece:Sprite = new Sprite();
newPuzzlePiece.addChild(newPuzzlePieceBitmap);
addChild(newPuzzlePiece);
// set location
newPuzzlePiece.x = x*(pieceWidth+pieceSpace) + horizOffset;
newPuzzlePiece.y = y*(pieceHeight+pieceSpace) + vertOffset;
// create object to store in array
var newPuzzleObject:Object = new Object();
newPuzzleObject.currentLoc = new Point(x,y);
newPuzzleObject.homeLoc = new Point(newPuzzlePiece.x,newPuzzlePiece.y);
newPuzzleObject.piece = newPuzzlePiece;
newPuzzlePiece.addEventListener(MouseEvent.CLICK,clickPuzzlePiece);
puzzleObjects.push(newPuzzleObject);
}
}
}
//make the puzzle solve itself
public function solvePuzzle(evt:KeyboardEvent)
{
if (evt.keyCode == 83)
{
for(var i:int = 0; i<puzzleObjects.length; i++)
{
}
}
}
// make a number of random moves
public function shufflePuzzlePieces() {
for(var i:int=0;i<numShuffle;i++) {
shuffleRandom();
}
}
// random move
public function shuffleRandom() {
// loop to find valid moves
var validPuzzleObjects:Array = new Array();
for(var i:uint=0;i<puzzleObjects.length;i++) {
if (validMove(puzzleObjects[i]) != "none") {
validPuzzleObjects.push(puzzleObjects[i]);
}
}
// pick a random move
var pick:uint = Math.floor(Math.random()*validPuzzleObjects.length);
movePiece(validPuzzleObjects[pick],false);
}
public function validMove(puzzleObject:Object): String {
// is the blank spot above
if ((puzzleObject.currentLoc.x == blankPoint.x) &&
(puzzleObject.currentLoc.y == blankPoint.y+1)) {
return "up";
}
// is the blank spot below
if ((puzzleObject.currentLoc.x == blankPoint.x) &&
(puzzleObject.currentLoc.y == blankPoint.y-1)) {
return "down";
}
// is the blank to the left
if ((puzzleObject.currentLoc.y == blankPoint.y) &&
(puzzleObject.currentLoc.x == blankPoint.x+1)) {
return "left";
}
// is the blank to the right
if ((puzzleObject.currentLoc.y == blankPoint.y) &&
(puzzleObject.currentLoc.x == blankPoint.x-1)) {
return "right";
}
// no valid moves
return "none";
}
// puzzle piece clicked
public function clickPuzzlePiece(event:MouseEvent) {
// find piece clicked and move it
for(var i:int=0;i<puzzleObjects.length;i++) {
if (puzzleObjects[i].piece == event.currentTarget) {
movePiece(puzzleObjects[i],true);
break;
}
}
}
// move a piece into the blank space
public function movePiece(puzzleObject:Object, slideEffect:Boolean) {
// get direction of blank space
switch (validMove(puzzleObject)) {
case "up":
movePieceInDirection(puzzleObject,0,-1,slideEffect);
break;
case "down":
movePieceInDirection(puzzleObject,0,1,slideEffect);
break;
case "left":
movePieceInDirection(puzzleObject,-1,0,slideEffect);
break;
case "right":
movePieceInDirection(puzzleObject,1,0,slideEffect);
break;
}
}
// move the piece into the blank spot
public function movePieceInDirection(puzzleObject:Object, dx,dy:int, slideEffect:Boolean) {
puzzleObject.currentLoc.x += dx;
puzzleObject.currentLoc.y += dy;
blankPoint.x -= dx;
blankPoint.y -= dy;
// animate or not
if (slideEffect) {
// start animation
startSlide(puzzleObject,dx*(pieceWidth+pieceSpace),dy*(pieceHeight+pieceSpace));
} else {
// no animation, just move
puzzleObject.piece.x = puzzleObject.currentLoc.x*(pieceWidth+pieceSpace) + horizOffset;
puzzleObject.piece.y = puzzleObject.currentLoc.y*(pieceHeight+pieceSpace) + vertOffset;
}
}
// set up a slide
public function startSlide(puzzleObject:Object, dx, dy:Number) {
if (slideAnimation != null) slideDone(null);
slidingPiece = puzzleObject;
slideDirection = new Point(dx,dy);
slideAnimation = new Timer(slideTime/slideSteps,slideSteps);
slideAnimation.addEventListener(TimerEvent.TIMER,slidePiece);
slideAnimation.addEventListener(TimerEvent.TIMER_COMPLETE,slideDone);
slideAnimation.start();
}
// move one step in slide
public function slidePiece(event:Event) {
slidingPiece.piece.x += slideDirection.x/slideSteps;
slidingPiece.piece.y += slideDirection.y/slideSteps;
}
// complete slide
public function slideDone(event:Event) {
slidingPiece.piece.x = slidingPiece.currentLoc.x*(pieceWidth+pieceSpace) + horizOffset;
slidingPiece.piece.y = slidingPiece.currentLoc.y*(pieceHeight+pieceSpace) + vertOffset;
slideAnimation.stop();
slideAnimation = null;
// check to see if puzzle is complete now
if (puzzleComplete()) {
clearPuzzle();
gotoAndStop("gameover");
}
}
// check to see if all pieces are in place
public function puzzleComplete():Boolean {
for(var i:int=0;i<puzzleObjects.length;i++) {
if (!puzzleObjects[i].currentLoc.equals(puzzleObjects[i].homeLoc)) {
return false;
}
}
return true;
}
// remove all puzzle pieces
public function clearPuzzle() {
for (var i in puzzleObjects) {
puzzleObjects[i].piece.removeEventListener(MouseEvent.CLICK,clickPuzzlePiece);
removeChild(puzzleObjects[i].piece);
}
puzzleObjects = null;
}
}
First, program must know where to place the objects, for them to placed correctly. And best way to do it, is to record piece's initial positions.
Before you set piece's new location, create the Object and take it's initial location.
newPuzzleObject.initialLoc = new Point(newPuzzlePiece.x,newPuzzlePiece.y);
Object creation must come before this part, before piece's initial position changed;
// set location
newPuzzlePiece.x = x*(pieceWidth+pieceSpace) + horizOffset;
newPuzzlePiece.y = y*(pieceHeight+pieceSpace) + vertOffset;
And at the solvePuzzle, place them all back to their initial location.
for(i:uint; i < puzzleObjects.length; i++)
{
puzzleObjects[i].x = puzzleObjects[i].initialLoc.x;
puzzleObjects[i].y = puzzleObjects[i].initialLoc.y;
}

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.

got Error #1009 in flash as3

i'm new in flash and as3 programming, and this is my first project. i found error on my project like this
TypeError: Error #1009: Cannot access a property or method of a null object reference.
at src.char::Enemy/Remove()
at src.screen::Gameplay/Collision()
at src.screen::Gameplay/Routine()
I think the error occurs because there is no function Remove () on the gameplay, but I'm not sure that's true. here's the enemy.as
import flash.display.MovieClip;
import flash.events.Event;
import flash.events.TimerEvent;
import flash.utils.Timer;
public class Enemy extends MovieClip {
private var timer:Timer = new Timer(25);
public function Enemy(xPos:Number, yPos:Number) {
x = xPos;
y = yPos;
timer.addEventListener(TimerEvent.TIMER, MoveDown);
timer.start();
}
private function MoveDown(e:TimerEvent):void {
y += 3;
if (y>400) {
Remove();
}
}
public function Remove():void {
timer.stop();
timer.removeEventListener(TimerEvent.TIMER, MoveDown);
parent.removeChild(this);
}
}
and here's the the gameplay.as
public class Gameplay extends MovieClip {
private var timer:Timer = new Timer(500);
private var player:Player;
public function Gameplay() {
addEventListener(Event.ADDED_TO_STAGE, InitKeyboard);
addEventListener(Event.ENTER_FRAME, Routine);
gameplayBack.addEventListener(MouseEvent.CLICK, GoToMap);
timer.addEventListener(TimerEvent.TIMER, OnTick);
timer.start();
InitPlayer();
InitLifePoint();
}
private function InitLifePoint():void {
lifePoint.gotoAndStop(1);
}
private function Routine(e:Event):void {
Collision();
}
private function Collision():void {
for (var i:int = 0; i < enemies.length; i++ ) {
if (player.hitTestObject(enemies[i])) {
PlayerHit();
enemies[i].Remove();
return;
}else {
for (var j:int = 0; j < bullets.length; j++ ) {
if (bullets[j].hitTestObject(enemies[i])) {
layerParticle.addChild(new Blast(bullets[j].x, bullets[j].y));
layerParticle.addChild(new Smoke(bullets[j].x, bullets[j].y));
bullets[j].Remove();
enemies[i].Remove();
scorePlay.text = int(scorePlay.text) + 10 + "";
trace(scorePlay.text);
return;
}
}
}
}
}
private var life:int = 1000;
private var currentLife:int = 1000;
private function PlayerHit():void {
currentLife -= 100;
if (currentLife <= 0) {
lifePoint.gotoAndStop(100);
GameOver();
}else {
lifePoint.gotoAndStop(100 - currentLife / life * 100);
}
}
private var result:Result = new Result();
private function GameOver():void {
result.youWin.alpha = 0;
result.ok.addEventListener(MouseEvent.CLICK, GoToMap);
result.x = 0;
result.y = 0;
addChild(result);
}
private function InitKeyboard(e:Event):void {
removeEventListener(Event.ADDED_TO_STAGE, InitKeyboard);
stage.addEventListener(KeyboardEvent.KEY_DOWN, KeyDown);
}
private function KeyDown(e:KeyboardEvent):void {
switch(e.keyCode) {
case Keyboard.LEFT: MoveLeft(); break;
case Keyboard.RIGHT: MoveRight(); break;
case Keyboard.SPACE: Fire(); break;
}
}
private var bullets:Array = new Array();
private function Fire():void {
var bullet:Bullet = new Bullet(player.x, player.y);
bullet.scaleX = 0.25;
bullet.scaleY = 0.25;
bullet.addEventListener(Event.REMOVED_FROM_STAGE, RemoveBulletArray);
layerParticle.addChild(bullet);
bullets.push(bullet);
}
private function RemoveBulletArray(e:Event):void {
removeEventListener(Event.REMOVED_FROM_STAGE, RemoveBulletArray);
var index:int = bullets.indexOf(Bullet(e.currentTarget), 0);
bullets.splice(index, 1);
}
private function MoveRight():void {
if (player.x < 550) {
player.x += 5;
}
}
private function MoveLeft():void {
if (player.x > 0) {
player.x -= 5;
}
}
private function InitPlayer():void {
player = new Player(550 * 0.5, 350);
layerChar.addChild(player);
}
private function OnTick(e:TimerEvent):void {
RandomEnemy();
}
private var enemies:Array = new Array();
private function RandomEnemy():void {
var enemy:Enemy = new Enemy(Math.random() * 550, 0);
enemy.addEventListener(Event.REMOVED_FROM_STAGE, RemoveFromArray);
layerChar.addChild(enemy);
enemies.push(enemy);
}
private var remaining:int = 10;
private function RemoveFromArray(e:Event):void {
removeEventListener(Event.REMOVED_FROM_STAGE, RemoveFromArray);
var index:int = enemies.indexOf(Enemy(e.currentTarget), 0);
enemies.slice(index, 1);
remaining--;
if (remaining == 0) GameWin();
}
private function GameWin():void {
result.youLose.alpha = 0;
result.score.text = scorePlay.text;
result.ok.addEventListener(MouseEvent.CLICK, GoToMap);
result.x = 0;
result.y = 0;
addChild(result);
}
private function GoToMap(e:MouseEvent):void {
dispatchEvent(new ScreenEvent(ScreenEvent.MAP));
}
}
Your problem is a NPE (Null Pointer Exception/Error) inside the Enemy.Remove() method:
public function Remove():void {
timer.stop();
timer.removeEventListener(TimerEvent.TIMER, MoveDown);
parent.removeChild(this);
}
Either your timer property is null (which I doubt, looking at your code) or the parent property are.
In a MovieClip the parent property are filled with a DisplayObject if your MovieClip is added to it, if not, this property is null.
Your problem probably is that you are removing (from its parent) this MovieClip more than once, or is trying to remove it without adding it first.
To make sure this is the problem, add a if statement to check the parent property first, like this:
if(parent != null)
{
parent.removeChild(this);
}
Note:
This may solve your NPE problem, but will not solve what is causing it, which may lead you into more and more inexplicable bugs.
Double check your logic to make sure you're removing a previously added MovieClip, or that you aren't removing it more than once.
Do you notice the flaw in the Collision function, if you observe like this:
for (var i:int = 0; i < enemies.length; i++) {
if (~) {
...
enemies[i].Remove();
...
} else {
for (~) {
if (~) {
...
enemies[i].Remove();
...
}
}
}
}
Apparently, in the second for loop you could be easily referencing the same Enemy Object.
And the problem comes after you call Remove function, because by doing parent.removeChild(this); you remove the only reference of the object to it's parent object.
You can try to do one of these:
Keep a reference to the parent object in the class, manually.
Keep a state variable in the class to check if it is to be a part of display list or not.
Move the enemies[i].Remove(); code into outermost loop.
If possile, recycle the object. Especially, when you are just
moving (x,y) the movieclip around.

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