Error #1034, with a MouseEvent - actionscript-3

I am making a basic point n' click game and I came upon this error:
TypeError: Error #1034: Type Coercion failed: cannot convert 3 to cem.mouvement.
Here's my script:
package cem {
import flash.events.Event;
import flash.display.MovieClip;
import cem.microjeux.events.InfoJeuEvent;
import cem.mouvement;
import flash.events.MouseEvent;
public class monterJeu extends MovieClip
{
private static var pType:String = "type";
private static var pNom:String = "testNom";
private static var pCourriel:String = "test#hotmail.com";
private static var pDifficulte:int = 0;
private static var pLangue:int = 0;
private static var pTitre:String = "Veuillez sortir";
private static var pVersion:String = "1.5";
private static var pCoordonnees:Number;
private var environnementJeu:environnement = new environnement();
private var personnageJeu:personnage = new personnage();
public function monterJeu():void
{
jouer(pNom,pDifficulte,pLangue);
dispatchEvent(new InfoJeuEvent(pType,pNom,pCourriel,pTitre,pVersion));
stage.addEventListener(MouseEvent.CLICK, test);
}
public function jouer(PNom:String,PDifficulte:int,PLangue:int):void
{
addChild(environnementJeu);
addChild(personnageJeu);
}
function test(e:MouseEvent){
pCoordonnees = stage.mouseX;
trace(pCoordonnees);
mouvement(3);
}
}
}
And on mouvement();
package cem
{
public class mouvement {
public function mouvement(blabla) {
trace(blabla);
}
}
}
I searched everywhere I could, and didn't find anything. I have no instances on the stage. Everything is imported on the first frame. I am kind of a beginner (let's say i'm no good at programming), so you can notify at the same time if you something that needs to be corrected. (BTW, the strange words are in french ;D)
Thanks!

The error is due to you trying to cast 3 to mouvement.
I think what you want is something like
function test(e:MouseEvent){
pCoordonnees = stage.mouseX;
trace(pCoordonnees);
var mouve:mouvement = new mouvement(3);
}
Notice that you have to have new in order to create a new instance of a class.
On another note, you should capitilize classes so they stand out better. So I would name the class Mouvement.

You are trying to cast 3 to the class mouvement into the test function:
function test(e:MouseEvent){
pCoordonnees = stage.mouseX;
trace(pCoordonnees);
new mouvement().mouvement(3); // <-- here your error
}
If you have only a function into your class you don't need to create a class but you can put on the function alone:
package cem
{
public function mouvement(blabla):void {
trace(blabla);
}
}
and now you can call the mpuvement function normally into you test function:
function test(e:MouseEvent){
pCoordonnees = stage.mouseX;
trace(pCoordonnees);
mouvement(3);
}

Related

Actionscript 3: Access movieclips from array with for-loop

I am having some trouble with accessing the movieclips I've added as childs. From what I've read, a way to solve this is to add every new movieclip to an array, and then loop through this array when I want to change something about all the movieclips.
In my case I want to scale them.
This is how I've tried to implement this function:
package
{
import flash.display.MovieClip;
import flash.utils.Dictionary;
import flash.events.MouseEvent;
import Airport;
public class Main extends Sprite
{
public var tile:MovieClip
public var bg_image:Sprite;
public var airport:Airport;
public static var airportDict:Dictionary = new Dictionary();
public static var collectedAirportArray:Array = new Array();
public function Main()
{
addEventListener(Event.ADDED_TO_STAGE, init);
}
public function init(e:Event):void
{
removeEventListener(Event.ADDED_TO_STAGE, init);
// airportDict is being filled up here.. but that's not really relevant for my problem
bg_image = new Image();
addChild(bg_image);
bg_image.addEventListener(MouseEvent.CLICK, testfunction);
for (var k:Object in airportDict)
{
var airport:Airport = new Airport(k,airportDict[k]["x"], airportDict[k]["y"]);
collectedAirportArray.push(collectedAirportArray);
bg_image.addChild(airport);
}
}
private function testfunction(evt:MouseEvent):void
{
for each (tile in collectedAirportArray)
{
tile.scaleY = 2 * tile.scaleY;
}
}
}
}
This give me the error message TypeError: Error #1034: Type Coercion failed: cannot convert []#30977eb1 to flash.display.MovieClip.
at Main/testfunction() when clicking on the bg_image
You have an error in where you are making the array. You have there collectedAirportArray.push(collectedAirportArray); - you're basically pushing an array into itself. Nice snakey, they said. You should instead push the newly created airport in there:
collectedAirportArray.push(airport);
If your airport is any kind of DisplayObject your code should work.
What AirPort class is extending? If it extends MovieClip then try type casting like so:
private function testfunction(evt:MouseEvent):void
{
for each (tile in collectedAirportArray)
{
var myTile:MovieClip = MovieClip(tile);
myTile.scaleY = 2 * myTile.scaleY;
}
}

AS3 - Having trouble with a basic game class

So I am creating a space shooter game. My document class is Engine and it looks like this:
package Classes
{
import flash.display.MovieClip;
import flash.display.Stage;
import flash.events.Event;
import flash.events.MouseEvent;
public class Engine extends MovieClip
{
private var startMenu:StartMenu;
private var numberOfStars:int = 80;
public static var enemyList:Array = new Array();
private var spaceShip:Ship;
private var hud:HUD;
public function Engine()
{
startMenu = new StartMenu();
stage.addChild(startMenu);
startMenu.x = (stage.stageWidth / 2);
startMenu.y = (stage.stageHeight / 2);
}
private function startGame()
{
stage.removeChild(startMenu)
spaceShip = new Ship(stage);
stage.addChild(spaceShip);
spaceShip.x = (stage.stageWidth / 2);
spaceShip.y = (stage.stageHeight / 2);
spaceShip.addEventListener("hit", shipHit);
hud = new HUD(stage); //create the HUD
stage.addChild(hud); //and display it.
for (var i:int = 0; i < numberOfStars; i++)
{
stage.addChildAt(new Star(stage), 1);
}
addEventListener(Event.ENTER_FRAME, createFighter);
}
}
So as you can see I am calling on another class called StartMenu. This is where I am having trouble: Here is the code (Or lack there of)
package Classes
{
import flash.display.MovieClip;
import flash.display.Stage;
import flash.events.Event;
import flash.events.MouseEvent;
import flash.events.*;
public class StartMenu extends MovieClip
{
public function StartMenu()
{
button1.addEventListener(MouseEvent.CLICK, buttonClicked);
}
private function buttonClicked(e:MouseEvent)
{
}
}
}
(Ignore the indentation errors, it is correct in the real code)
Okay so imagine a button being displayed on the screen. This button is part of the StartMenu Class and is listening for a MouseEvent.CLICK.
Once the button is clicked I need to somehow travel back to the Engine class and call the function startGame() , but I can't just do Engine.startGame() , I have tried setting the function to a public function, and I have tried setting the function to a public static function. no luck. HELP PLEASE?? Any method will be fine, I just need a way for this class to go to the startGame function once the button is clicked!
Probably the quickest way to do this is to add an Engine variable into the StartMenu class and pass the engine through the start menu's constructor. Here's a short code sample:
StartMenu
public class StartMenu extends MovieClip
{
private var _engine:Engine // add a new variable to the start menu class
public function StartMenu(engine:Engine) // add a new parameter to the constructor
{
_engine = engine; // set the variable to the value passed through the constructor
button1.addEventListener(MouseEvent.CLICK, buttonClicked);
}
private function buttonClicked(e:MouseEvent)
{
_engine.startGame()
}
}
Engine
public function Engine()
{
startMenu = new StartMenu(this);
// pass through the current instance of engine using the this keyword
...
}
public function startGame() // change private to public
{
...
}
I hope that helps
In your Engine.as class, you can put :
public static var instance:Engine;
public static function getInstance():Engine
{
return instance as Engine;
}
and in constructor of engine class put :
instance = this;
now you can use instace of Engine class and all the public functions and variables anywhere in your project by :
Engine.getInstance().startGame();
It can help you.
There are two types of solving such a case. One is using parent reference or specific reference to call a certain function, as Ethan Worley andwered, the other is using a customizable public clicker setter like this:
public class StartMenu extends MovieClip
{
private var button1:MovieClip; // or whatever type your button is
private var startGameFunction:Function;
public function StartMenu()
{
// some initialization code if needed, including allocating button1
startGameFunction=null;
button1.addEventListener(MouseEvent.CLICK, buttonClicked);
}
public function set startGameClicked(value:Function):void {
if (value==startGameFunction) return; // nothing to set
startGameFunction=value;
}
private function buttonClicked(e:MouseEvent)
{
if (startGameFunction) startGameFunction(); // if there's a function assigned, call it
}
}
Engine class:
public function Engine()
{
startMenu = new StartMenu();
startMenu.startGameFunction=this.startGame;
// no "()" here, as we are giving a function reference
...
}
public function startGame() // change private to public
{
...
}
I am a bit surprised that no one mentioned an Events based approach yet. That's what I would have used for such a requirement, since I don't really find the idea of passing an entire class instance for just a function call to be that appealing (that would mean that I may be a bit biased towards this approach so please feel free to point out the drawbacks it has, if any).
Inside your Engine class:
public function Engine()
{
startMenu = new StartMenu();
startMenu.addEventListner('StartGame', startGame);
stage.addChild(startMenu);
..
}
private function startGame(e:Event)
{
startMenu.removeEventListner('StartGame', startGame);
..
}
Inside your StartMenu class:
private function buttonClicked(e:MouseEvent)
{
this.dispatchEvent(new Event('StartGame'));
..
}

How to create a Collisions var in the Back class

Edit: I have now included a Player.as and a addchild
I've been trying to understand how to do this all day and again learned a lot in doing so. But I've come to a point that i need help.
I know I have to do this: create a Collisions var in the Back1 class.
Because the background called Back1 is the movieclip that contains the Collisions image
I found a good site or 2 that does a good job of explaining variables and classes but i still don't get how i should solve this problem
Research after variables and classes:
http://www.republicofcode.com/tutorials/flash/as3variables/
http://www.photonstorm.com/archives/1136/flash-game-dev-tip-1-creating-a-cross-game-communications-structure
the above problem results in the folowing error but i believe it is caused by not creating a Collisions var in the Back1 class
ArgumentError: Error #1063: Argument count mismatch on Bumper(). expected: 2, value 0.
at flash.display::MovieClip/gotoAndStop() at
DocumentClass/onRequestStart()DocumentClass.as:64] at
flash.events::EventDispatcher/dispatchEventFunction() at
flash.events::EventDispatcher/dispatchEvent() at
MenuScreen/onClickStart()MenuScreen.as:18]
package
{
import flash.display.MovieClip;
import flash.events.*;
import flash.events.KeyboardEvent;
import flash.ui.Keyboard;
import flash.geom.Point;
import Bumper;
//import Back1;
public class Test extends MovieClip
{
public var leftBumping:Boolean = false;
public var rightBumping:Boolean = false;
public var upBumping:Boolean = false;
public var downBumping:Boolean = false;
public var leftBumpPoint:Point = new Point(-30,-55);
public var rightBumpPoint:Point = new Point(30,-55);
public var upBumpPoint:Point = new Point(0,-120);
public var downBumpPoint:Point = new Point(0,0);
public var scrollX:Number = 0;
public var scrollY:Number = 500;
public var xSpeed:Number = 0;
public var ySpeed:Number = 0;
public var speedConstant:Number = 4;
public var frictionConstant:Number = 0.9;
public var gravityConstant:Number = 1.8;
public var jumpConstant:Number = -35;
public var maxSpeedConstant:Number = 18;
public var doubleJumpReady:Boolean = false;
public var upReleasedInAir:Boolean = false;
public var keyCollected:Boolean = false;
public var doorOpen:Boolean = false;
public var currentLevel:int = 1;
public var animationState:String = "idle";
public var bulletList:Array = new Array();
public var enemyList:Array = new Array();
public var bumperList:Array = new Array();
public var back1:Back1;
public var collisions:Collisions;
//public var back1:Collisions = new Collisions ;
public var player:Player;
public function Test()
{
addEventListener(Event.ADDED_TO_STAGE, init);
}
public function init(e:Event):void
{
player = new Player(320, 360);
back1 = new Back1();
collisions = new Collisions();
//back1.collisions = new Collisons();
addBumpersToLevel1();
}
public function addBumpersToLevel1():void
{
addBumper(500, -115);
addBumper(740, -115);
}
public function addPlayerTolevel1():void
{
addPlayer(320, 360);
}
public function loop(e:Event):void
{
trace("back1.collisions "+back1.collisions);
trace("back1 "+back1);
trace("collisions "+collisions);
if (back1.collisions.hitTestPoint(player.x + leftBumpPoint.x,player.y + leftBumpPoint.y,true))
{
just in case i've added Bumper.as
package {
import flash.display.MovieClip;
import flash.events.Event;
public class Bumper extends MovieClip{
public function Bumper(xLocation:int, yLocation:int) {
// constructor code
x = xLocation;
y = yLocation;
addEventListener(Event.ENTER_FRAME, bumper);
}
public function bumper(e:Event):void{
//code here
}
}
}
Player.as
package {
import flash.display.MovieClip;
import flash.events.Event;
public class Player extends MovieClip {
public function Player(xLocation:int, yLocation:int) {
// constructor code
x = xLocation;
y = yLocation;
}
// public function removeSelf():void {
// trace("remove enemy");
// removeEventListener(Event.ENTER_FRAME, loop);
// this.parent.removeChild(this);
// }
}
}
the Back1.as file (note it's got to be instanced wrong)
package {
import flash.display.MovieClip;
public class Back1 extends MovieClip {
//public var collisions:Back1;
//what should i put here?
}
}
I am not sure I understand completely what you mean. The question is phrased strange.
I assume you want to achieve a collision between your background object (The Back class) and a player object? I can't see from the code you have posted what the player object is since there is no such variable in your Test class.
To test a collision check between two objects use the following code:
if(someObject.hitTestObject(anotherObject))
Or in your case when using hitTestPoint:
if(back1.hitTestPoint(player.x, player.y,true))
Then again I don't know from the code you have posted how the back1 class looks like. If it extends a MovieClip or Sprite and you have a Player class that does the same (OR any DisplayObject) this should work.
This:
Argument count mismatch on Bumper(). expected: 2, value 0.
The error you get seems to come from another place not shown in your code. I would assume you did not pass any parameters into the Bumper class' constructor.
Btw, is this a Flash IDE sample or some other program such as FlashDevelop or FlashBuilder? If you are using the Flash IDE and are trying to attach code to a movie clip instance placed out on the scene I don't think its possible to pass parameters to it. Sorry been a while since I've worked in the Flash IDE.
EDIT:
Here's some sample code:
//:: Change Back1 class to this
package {
import flash.display.MovieClip;
public class Back1 extends MovieClip {
public function Back1()
{
graphics.beginFill(0xFF0000);
graphics.drawRect(0, 0, 50, 50);
graphics.endFill();
}
}
}
//:: Then in your Main class (Or the Test class) add the following
var player:Player = new Player(25, 25);
var collidable:Back1 = new Back1();
addChild(player);
addChild(collidable);
//:: Goes in your loop/update
if (collidable.hitTestPoint(player.x, player.y, true))
{
trace("HIT PLAYER");
}
How you apply the graphics to the Back1 class is up to you, I just drew a simple box. It could be anything.
Set default parameters for Bumper class:
package {
import flash.display.MovieClip;
import flash.events.Event;
public class Bumper extends MovieClip{
public function Bumper(xLocation:int = 0, yLocation:int = 0) {
// constructor code
x = xLocation;
y = yLocation;
addEventListener(Event.ENTER_FRAME, bumper);
}
public function bumper(e:Event):void{
//code here
}
}
}

TypeError: Error #1010 in AS3 constructor code

I keep getting the TypeError: Error #1010 when trying to create the constructor code for a small game in AS3. The code that appears to be causing the issue is:
package {
import flash.display.MovieClip;
import flash.events.MouseEvent;
public class Main extends MovieClip {
var screen1:StartScreen;
var screen2:InstructionsScreen;
var screen3:SelectScreen;
var screen4:Game1Screen;
var screen5:Game2Screen;
var screen6:Game3Screen;
var screen7:FailScreen;
var screen8:CompleteScreen;
public function Main(){
screen1 = new StartScreen();
screen2 = new InstructionsScreen();
screen3 = new SelectScreen();
screen4 = new Game1Screen();
screen5 = new Game2Screen();
screen6 = new Game3Screen();
screen7 = new FailScreen();
screen8 = new CompleteScreen();
screen1.startBtn.addEventListener(MouseEvent.CLICK,gotoSelect);
screen1.instBtn.addEventListener(MouseEvent.CLICK,gotoInst);
screen2.startBtn.addEventListener(MouseEvent.CLICK,gotoSelect2);
screen3.game1Btn.addEventListener(MouseEvent.CLICK,gotoGame1);
screen3.game2Btn.addEventListener(MouseEvent.CLICK,gotoGame2);
screen3.game3Btn.addEventListener(MouseEvent.CLICK,gotoGame3);
screen4.failBtn.addEventListener(MouseEvent.CLICK,gotoFail1);
screen4.winBtn.addEventListener(MouseEvent.CLICK,gotoWin1);
screen5.failBtn.addEventListener(MouseEvent.CLICK,gotoFail2);
screen5.winBtn.addEventListener(MouseEvent.CLICK,gotoWin2);
screen6.failBtn.addEventListener(MouseEvent.CLICK,gotoFail3);
screen6.winBtn.addEventListener(MouseEvent.CLICK,gotoWin3);
addChild(screen1);
}
private function gotoSelect(evt:MouseEvent):void{
removeChild(screen1);
addChild(screen3);
}
private function gotoInst(evt:MouseEvent):void{
removeChild(screen1);
addChild(screen2);
}
private function gotoSelect2(evt:MouseEvent):void{
removeChild(screen2);
addChild(screen3);
}
private function gotoGame1(evt:MouseEvent):void{
removeChild(screen3);
addChild(screen4);
}
private function gotoGame2(evt:MouseEvent):void{
removeChild(screen3);
addChild(screen5);
}
private function gotoGame3(evt:MouseEvent):void{
removeChild(screen3);
addChild(screen6);
}
private function gotoFail1(evt:MouseEvent):void{
removeChild(screen4);
addChild(screen7);
}
private function gotoWin1(evt:MouseEvent):void{
removeChild(screen4);
addChild(screen8);
}
private function gotoFail2(evt:MouseEvent):void{
removeChild(screen5);
addChild(screen7);
}
private function gotoWin2(evt:MouseEvent):void{
removeChild(screen5);
addChild(screen8);
}
private function gotoFail3(evt:MouseEvent):void{
removeChild(screen6);
addChild(screen7);
}
private function gotoWin3(evt:MouseEvent):void{
removeChild(screen6);
addChild(screen8);
}
}
}
And the error message that appears when I try and run this is:
TypeError: Error #1010: A term is undefined and has no properties.
at Main()
I don't see anything wrong with the code itself. I'm guessing that one of the movieclips screen1 to screen6 don't have the named buttons defined, or the StartScreen etc classes don't exist or are accessible.

Initialize Assets after Preload

Whenever I export the .swf file of my Flash game, I am receiving "TypeError: Error #1009: Cannot access a property or method of a null object reference.", along with a Runtime Shared Library Preloading Warning for my preloader. I have my timeline organized so that the first and third frames are both empty along with a stop(); command in the Actions layer. The second frame contains a single MovieClip that contains all of my exported assets, which are going to be initialized in the third frame of the timeline. None of my assets, except for the preloader, are exported in the first frame. What changes should I make to my Document Class for it to initialize the assets in the third frame?
Document Class:
package com.gameEngine.documentClass
{
import flash.events.*;
import flash.display.*;
import flash.geom.Point;
import com.gameEngine.assetHolders.*;
import com.gameEngine.assetHolders.Levels.*;
public class Document extends MovieClip
{
private static var _document:Document;
private var preloader:Preloader;
public var mcMain:Player;
public var restartButton:RestartButton;
public var spawnArea:SpawnArea;
public var level_1:Level_1;
public var level_2:Level_2;
public var level_3:Level_3;
public function Document()
{
addEventListener(Event.ADDED_TO_STAGE, init);
_document = this;
preloader = new Preloader(390, this.loaderInfo);
this.addChild(preloader);
preloader.addEventListener("loadComplete", loadAssets);
preloader.addEventListener("preloaderFinished", showLogo);
mcMain = new Player(this);
restartButton = new RestartButton(this);
spawnArea = new SpawnArea();
level_1 = new Level_1(this);
level_2 = new Level_2(this);
level_3 = new Level_3(this);
this.addChild(restartButton);
this.addChild(spawnArea);
this.preloader.x = 400;
this.preloader.y = 250;
restartButton.x = 822.95;
restartButton.y = 19;
spawnArea.x = 400;
spawnArea.y = 250;
trace ("Document Class Initialized");
// constructor code
}
public static function getInstance():Document
{
return _document;
}
private function loadAssets(event:Event):void
{
this.play();
}
private function showLogo(event:Event):void
{
this.removeChild(preloader);
}
public function init(event:Event)
{
if (stage.contains(spawnArea))
{
addChild(mcMain);
}
mcMain.x = spawnArea.x;
mcMain.y = spawnArea.y;
}
}
}
Preloader Class:
package com.gameEngine.assetHolders
{
import com.gameEngine.documentClass.*;
import flash.display.*;
import flash.events.*;
public class Preloader extends MovieClip
{
private var fullWidth:Number;
public var loaderInfo:LoaderInfo;
public function Preloader(fullWidth:Number = 0, loaderInfo:LoaderInfo = null)
{
this.fullWidth = fullWidth;
this.loaderInfo = loaderInfo;
addEventListener(Event.ENTER_FRAME, checkLoad);
}
private function checkLoad (event:Event):void
{
if (loaderInfo.bytesLoaded == loaderInfo.bytesTotal && loaderInfo.bytesTotal != 0)
{
dispatchEvent(new Event("loadComplete"));
phaseOut();
}
updateLoader(loaderInfo.bytesLoaded / loaderInfo.bytesTotal);
}
private function updateLoader(num:Number):void
{
progressBar.width = num * fullWidth;
}
private function phaseOut():void
{
removeEventListener(Event.ENTER_FRAME, checkLoad);
progressBar.gotoAndPlay(2);
if (progressBar.currentFrame == progressBar.totalFrames)
{
phaseComplete();
}
}
private function phaseComplete() : void
{
dispatchEvent(new Event("preloaderFinished"));
}
}
}
You have a lot of race conditions going on here. Many of these events could occur at relatively random times in relation to one another . . . you have to think asynchronously. That is, there can be no assumption that any object exists. E.g., in Document.init(), you check is if the spawnArea exists, but it is almost guaranteed not to at that point, and you never check for it again.
Without making any specific changes, I can recommend a generic solution. For any object (objB) you want loaded after another object (objA) is loaded, have objB created in the objA's ADDED_TO_STAGE handler. A simple example would be:
var objA:Whatever;
var objB:WhateverElse;
[...]
objA = new Whatever();
objA.addEventListener(Event.ADDED_TO_STAGE, objAAddedHnd);
[...]
public function objAAddedHnd(event:Event)
{
// remove the event, if no longer needed:
objA.removeEventListener(Event.ADDED_TO_STAGE, objAAddedHnd);
objB = new WhateverElse();
objB.addEventListener(Event.ADDED_TO_STAGE, objBAddedHnd);
}
[...]
public function objBAddedHnd(event:Event)
{
// remove the event, if no longer needed:
objB.removeEventListener(Event.ADDED_TO_STAGE, objBAddedHnd);
// and so on . . .
}
At this point, it shows that you would need to plan the timeline of object creation.