Resolve Warning: 1082: Migration issue: Method gameThread will behave differently in ActionScript 3.0 - actionscript-3

Since I moved to using adobe flash 2017+, I've gotten warnings 1082/1083.
The warning is:
Warning: 1082: Migration issue: Method gameThread will behave differently in ActionScript 3.0 due to the change in scoping for the this keyword. See the entry for warning 1083 for additional information.
Although the only error which I am getting is for putting events inside classes, I cannot add mouse events or any events without having these warnings and I don't know how to fix...
People suggested to remove super() which is not the solution.
Example of event which I added to main code
error comes on line " addEventListener...."
package {
import flash.display.MovieClip;
import flash.events.Event;
import data.Player;
public class Game extends MovieClip {
private var players:Array = new Array();
public function Game() {
super();
resetPlayers();
addEventListener(Event.ENTER_FRAME, this.gameThread);
}
private function resetPlayers():void{
for (var i:int = 0; i < this.numChildren; i++){
if (getChildAt(i) is Player){
players.push(getChildAt(i));
}
}
}
protected function gameThread(event:Event):void{
for (var i:int = 0; i < this.players.length; i++){
players[i].fall();
}
}
}
}

You are be able to overcome this issue by simply removing the this keyword. It's not needed in this case.
addEventListener(Event.ENTER_FRAME, gameThread);
In AS3 methods are exectued in the context (your Game class) it's defined.
Same for the other uses of the this keyword.
players is a class variable of Game, resetPlayers() and gameThread() are methods of Game -> so it's all in the same context.

Related

TouchEvent.TOUCH_BEGIN, onTouchBegin Freezes after several Reloads

I am building an Adobe Air AS3 IOS and Android App, in which i have a movie clip in the center of the stage. When you start touching this movie clip, you can move it all around the stage.
This is how i'm doing so :
Multitouch.inputMode = MultitouchInputMode.TOUCH_POINT;
MC_M1.alpha = 1;
MC_M1.addEventListener(Event.ENTER_FRAME, ifHitAct);
MC_M1.addEventListener(TouchEvent.TOUCH_BEGIN, onTouchBegin);
MC_M1.x = 0.516 * gameIntro.stageWidthToUse;
MC_M1.y = 0.75 * gameIntro.stageHeightToUse;
MC_M1.height = 0.2 * gameIntro.stageHeightToUse;
MC_M1.width = MC_M1.height / 1.4;
gameIntro.STAGE.stage.addChildAt(MC_M1,1);
function onTouchBegin(event:TouchEvent)
{
trace("TouchBegin");
if (touchMoveID != 0)
{
trace("It Did Not");
return;
}
touchMoveID = event.touchPointID;
gameIntro.STAGE.stage.addEventListener(TouchEvent.TOUCH_MOVE, onTouchMove);
gameIntro.STAGE.stage.addEventListener(TouchEvent.TOUCH_END, onTouchEnd);
}
function onTouchMove(event:TouchEvent)
{
if (event.touchPointID != touchMoveID)
{
return;
}
//trace("Moving")
MC_M1.x = event.stageX;
MC_M1.y = event.stageY;
}
function onTouchEnd(event:TouchEvent)
{
if (event.touchPointID != touchMoveID)
{
return;
}
//trace("Ending");
touchMoveID = 0;
gameIntro.STAGE.stage.removeEventListener(TouchEvent.TOUCH_MOVE, onTouchMove);
gameIntro.STAGE.stage.removeEventListener(TouchEvent.TOUCH_END, onTouchEnd);
}
When the player actually looses the game, what i am actually doing is the following :
MC_M1.removeEventListener(Event.ENTER_FRAME , ifHitAct);
MC_M1.removeEventListener(TouchEvent.TOUCH_BEGIN , onTouchBegin);
gameIntro.STAGE.stage.removeChild(MC_M1);
MC_M1.alpha = 0;
isDead = 1;
replayButToUse.x = 0.127 * gameIntro.stageWidthToUse;
replayButToUse.y = 0.91 * gameIntro.stageHeightToUse;
replayButToUse.addEventListener(MouseEvent.CLICK, gotoIntro);
This is all happening in a class called : introClassToUse.
So when the users looses, he will get a replay button, and when he clicks it, he will go back to the same class and reload everything, using the following code :
function gotoIntro(event:MouseEvent):void
{
replayButToUse.removeEventListener(MouseEvent.CLICK, gotoIntro);
replayButToUse.alpha = 0;
replayButToUse.removeEventListener(MouseEvent.CLICK, gotoIntro);
stop();
var reload:introClassToUse = new introClassToUse();
}
And so everything loads back up and the game restarts. My problem is, i'm facing a very weird behavior when i tend to replay the game more than 2-3 times. The MC_M1 just stops listening to any touch event, but keeps on listening to ENTER_FRAME events, in which i keep touching the MC_M1 but it seems to not respond to it. I even debugged it remotely from my iPhone, for the first couple of replays, i can see the trace("TouchBegin"); with it's outcome, it was showing me TouchBegin, but after a few replays, the touch events just froze. What am i missing?
Any help is really appreciated, i'm new in AS3, i need to learn so i could manage more
Edit 1 :
I have no code on any frame, i just have lots of AS Classes.
The fla file is linked to an AS Class called gameIntro. In this class, i have linked the following :
- STAGE is an object of type Stage.
- gameIntro.STAGE = stage
Later on, when the user clicks a play button, i call the class introClassToUse. This class has all the game functionalities. All the code present above is in introClassToUse. When the user looses and clicks the replay button, he will go to "goToIntro" function, im which i recall the introClassToUse.
It's all working fine, with several other timers implemented and all, the only problem is that after several replays, the MC_M1 just freezes over
I am removing the MC_M1 each time the user looses and re-add them when i call back the introClassToUse, because i tried to use the .visible property, it didn't work at all ( this is why i am using the gameIntro.STAGE.stage.removeChild(MC_M1)
I know the question is old but maybe someone is still wondering what is going on here (like me).
There are lot of problems in you code but I thing the root of your problem starts here:
function gotoIntro(event:MouseEvent):void{
//...
var reload:introClassToUse = new introClassToUse();
}
It is usually unwanted behavior if simply creating an instance does more than nothing to your program and you don't even need to assign it to variable in this case.
You mentioned this code is located in your introClassToUse class. This basically means that you are creating new instance of your game inside old one and this seem to be completely awry.
You should consider using only instance properties in your class definition and create new introClassToUse() in external classes;
You didn't include many important details about your code like
How the whole class structures look like - for example you can't place line like MC_M1.addEventListener(Event.ENTER_FRAME, ifHitAct);in the scope of your class so obviously you have this in some function and we don't know when and from where it is called.
Where and how your variables are declared, and assigned. It's hard to tell if your MC_M1 is property of an instance or a class, is it internal/public/private/...
Do you link library symbols to your classes or acquire it from stage.
There could be many things that could give you such result. Based on what you wrote I've reproduced behavior similar to what you've describe but using mouse event and a dummy loose condition. This ends the game each time you drop the mc partially outside right edge of the sage, show restart button and starts again if you click it (basically it's mostly your code). It works fine for about 10s and than suddely you can't move the mc anymore. The frame event is still tracing out but touch/mouse is not.
How can it be? I suspect that you could remove only listeners somewhere and have invisible mc stuck on the new one. And this could be easy overlooked, especially if you using static properties. Again we don't even know where is your movie clip coming from so we can only guess what is happening whit your code but I've tried to take the example simple this is how I did it. The problem may lay in some completely different place but you can guess for all scenarios.
Document class of the project - GameIntro.as
package
{
import flash.display.Sprite;
public class GameIntro extends Sprite
{
//Document class. this need to be compiled with strict mode off.
public function GameIntro() {
GameIntro.STAGE = stage;
GameIntro.stageWidthToUse = stage.stageWidth;
GameIntro.stageHeightToUse = stage.stageHeight;
var intro:IntroClassToUse = new IntroClassToUse();
stage.addChild(intro);
}
}
}
IntroClassToUse.as
package
{
import flash.display.MovieClip;
import flash.events.Event;
import flash.events.MouseEvent;
import flash.events.TimerEvent;
import flash.utils.Timer;
/**
* You need to have library symbol linked to this class in .fla with two mcs -
* mcFromLibrarySymbol (dragable) and repButton (reapatButton)
*/
public class IntroClassToUse extends MovieClip
{
var t = 0; //timer ticks
var fc:uint = 0; //frames counter
var isDead = 0;
var mc;
static var repButton;
var logicContex:Timer = new Timer(30);
public function IntroClassToUse() {
trace("toUse", GameIntro.stageWidthToUse);
mc = mcFromLibrarySymbol;
if(!repButton) repButton = repButtonX;
logicContex.addEventListener(TimerEvent.TIMER, logicInterval);
logicContex.start();
init();
}
internal function init() {
trace("init");
mc.alpha = 1;
mc.addEventListener(Event.ENTER_FRAME, onFrame);
mc.addEventListener(MouseEvent.MOUSE_DOWN, onMDown);
mc.x = 0.516 * GameIntro.stageWidthToUse;
mc.y = 0.75 * GameIntro.stageHeightToUse;
mc.height = 0.2 * GameIntro.stageHeightToUse;
mc.width = mc.height / 1.4;
GameIntro.STAGE.stage.addChildAt(mc, 1);
}
internal function onLoose() {
trace("onLoose");
mc.removeEventListener(Event.ENTER_FRAME , onFrame);
mc.removeEventListener(MouseEvent.MOUSE_DOWN, onMDown);
GameIntro.STAGE.stage.removeChild(mc);
mc.alpha = 0;
isDead = 1;
repButton.x = 0.127 * GameIntro.stageWidthToUse;
repButton.y = 0.91 * GameIntro.stageHeightToUse;
repButton.addEventListener(MouseEvent.CLICK, onReplay);
repButton.alpha = 1;
}
internal function onReplay(e:MouseEvent):void {
trace("onReplay");
repButton.removeEventListener(MouseEvent.CLICK, onReplay);
repButton.alpha = 0;
stop();
new IntroClassToUse();
}
internal function onMDown(e:MouseEvent):void {
trace("mouseDow");
GameIntro.STAGE.stage.addEventListener(MouseEvent.MOUSE_MOVE, onMMove);
GameIntro.STAGE.stage.addEventListener(MouseEvent.MOUSE_UP, onMUp);
}
internal function onMMove(e:MouseEvent):void {
mc.x = e.stageX;
mc.y = e.stageY;
}
//you loose the game if you release you mc with part of it over rigth stage edge.
internal function onMUp(e:MouseEvent):void {
trace("mouseUp");
GameIntro.STAGE.stage.removeEventListener(MouseEvent.MOUSE_MOVE, onMMove);
GameIntro.STAGE.stage.removeEventListener(MouseEvent.MOUSE_UP, onMUp);
trace("Stage:", GameIntro.STAGE.numChildren);
if (mc.x + mc.width > GameIntro.STAGE.stageWidth) onLoose();
}
internal function onFrame(e:Event):void {
trace("frames", fc++);
}
internal function logicInterval(e:TimerEvent):void {
if (t++ < 300 || !isDead) return;
init();
mc.alpha = 0;
mc.removeEventListener(MouseEvent.MOUSE_DOWN, onMDown);
isDead = 0;
}
}
}

How to delay when my actionscript 3 code runs?

I am creating a drag and drop game that I followed through a Lynda tut. I kept getting an error for my game that I created because I noticed (after weeks of reviewing the code and having other people look at it to figure out what was wrong) that the tutorial that I followed did everything on frame one but I was making my game start at frame 3. So if I start my game at frame 1, it works perfectly and I wont get these errors:
This occurs when I test the movie, once I click continue I am able to see the movie -
TypeError: Error #1009: Cannot access a property or method of a null object reference.
at simpleSpring()[simpleSpring.as:21]
And this occurs when I drag my object -
TypeError: Error #2007: Parameter hitTestObject must be non-null.
at flash.display::DisplayObject/_hitTest()
at flash.display::DisplayObject/hitTestObject()
at DragDrop/drop()[DragDrop.as:33]
Since I know these errors won't appear unless I begin the game at frame 1, I want to know what code I can place so that I can begin the game at frames that are past the first frame.
The following is the code for DragDrop.as
package
{
import flash.display.*;
import flash.events.*;
public class DragDrop extends Sprite
{
var origX:Number;
var origY:Number;
var target:DisplayObject;
public function DragDrop()
{
// constructor code
origX = x;
origY = y;
addEventListener(MouseEvent.MOUSE_DOWN, drag);
buttonMode = true;
}
function drag(evt:MouseEvent):void
{
stage.addEventListener(MouseEvent.MOUSE_UP, drop);
startDrag();
parent.addChild(this);
}
function drop(evt:MouseEvent):void
{
stage.removeEventListener(MouseEvent.MOUSE_UP, drop);
stopDrag();
if(hitTestObject(target))
{
visible = false;
target.alpha = 1;
Object(parent).match();
}
x = origX;
y = origY;
}
}
}
And here is the simpleSpring.as
package
{
import flash.display.*;
import flash.events.*;
public class simpleSpring extends MovieClip
{
var dragdrops:Array;
public function simpleSpring()
{
// constructor code
dragdrops = [ladyone,ladytwo,ladythree,ladyfour,ladyfive,ladysix];
var currentObject:DragDrop;
for(var i:uint = 0; i < dragdrops.length; i++)
{
currentObject = dragdrops[i];
currentObject.target = getChildByName(currentObject.name + "_target");
}
}
public function match():void
{
}
}
}
I tried adding the code to a actions layer in the game document but that also does not seem to work correctly.
I am such a newbie when it comes to publishing things. I noticed I can add multiple swf files when I publish for android. This solves my issue of not being able to code at the beginning frame. If I have this game in a separate flash file saved in the same folder with the title movie calling to it with actionscript, the code will work and I am able to publish the whole thing as one file. Thanks again for those that tried to help me figure this out!

Actionscript 3.0, error with hitTestObject

I'm getting an error I can't seem to fix. I think I know kind of what is going on but I'm not sure enough to be able to fix it. I keep getting error
"TypeError: Error #2007: Parameter hitTestObject must be non-null.
at flash.display::DisplayObject/_hitTest()
at flash.display::DisplayObject/hitTestObject()"
Basically I fire an attack in my game. It hits an enemy and he is killed just fine. BUT, he has an animation as he dies that takes a couple seconds. It seems if I fire another attack during his animation, my attack IMMEDIATELY gives this error (before striking anything, that is). Once the animation is over, everything is fine again. Also, the game was working 100% fine before I put in this animation.
Here is my document class
package com.classes
{
import flash.display.MovieClip;
import flash.display.Stage;
import flash.events.Event;
public class DocumentClass extends MovieClip
{
// we need to keep track of our enemies.
public static var enemyList1:Array = new Array();
// moved stickobject1 to a class variable.
private var stickobject1:Stickman2;
public function DocumentClass() : void
{
//removed the var stickobject1:Stickman2 because we declared it above.
var bg1:background1 = new background1();
stage.addChild(bg1);
stickobject1 = new Stickman2(stage);
stage.addChild(stickobject1);
stickobject1.x=50;
stickobject1.y=300;
//running a loop now.... so we can keep creating enemies randomly.
addEventListener(Event.ENTER_FRAME, loop, false, 0, true);
}
//our loop function
private function loop(e:Event) : void
{
//run if condition is met.
if (Math.floor(Math.random() * 90) == 5)
{
//create our enemyObj1
var enemyObj1:Enemy1 = new Enemy1(stage, stickobject1);
//listen for enemyObj1 being removed from stage
enemyObj1.addEventListener(Event.REMOVED_FROM_STAGE, removeEnemyObj1, false, 0, true);
//add our enemyObj1 to the enemyList1
enemyList1.push(enemyObj1);
stage.addChild(enemyObj1);
}
}
private function removeEnemyObj1(e:Event)
{
enemyList1.splice(enemyList1.indexOf(e.currentTarget), 1);
}
}
}
And here is my attack1 class
package com.classes {
import flash.display.MovieClip;
import flash.display.Stage;
import com.senocular.utils.KeyObject;
import flash.ui.Keyboard;
import flash.events.Event;
public class attack1 extends MovieClip {
private var stageRef:Stage;
private var bulletSpeed:Number = 16;
public function attack1 (stageRef:Stage, x:Number, y:Number) : void
{
this.stageRef = stageRef;
this.x = x;
this.y = y;
addEventListener(Event.ENTER_FRAME, loop, false, 0, true);
}
private function loop(e:Event) : void
{
//move bullet up
x += bulletSpeed;
if (x > stageRef.stageWidth)
removeSelf();
for (var i:int = 0; i < DocumentClass.enemyList1.length; i++)
{
if (hitTestObject(DocumentClass.enemyList1[i].hit))
{
trace("hitEnemy");
removeSelf();
DocumentClass.enemyList1[i].takeHit();
}
}
}
private function removeSelf() : void
{
removeEventListener(Event.ENTER_FRAME, loop);
if (stageRef.contains(this))
stageRef.removeChild(this);
}
}
}
Don't think you should need any other of my classes to figure out what's going on, but let me know if you do! Thanks very much =)
You don't want to do a hit test against any object that may have been removed from the scene (or from the enemyList array). The extra condition added to attack1.loop's for loop should get rid of your error. A better fix is to splice out the items you remove, so they are never tested against in the loop.
The break line will make it stop trying to hit other enemies after the bullet is removed. If the line "DocumentClass.enemyList1[i].takeHit();" removes the item from the enemyList1, you need to make sure you use "i--;" at the bottom of the loop as well, if you plan on looping through the remainder of the enemies. "i--" or "break", you will probably need one of them in that loop.
Double check the order in which you are executing your removal methods. Sometimes it's better to flag the items for removal and remove them in a separate loop than to remove an item that may be needed later in the same loop.
for (var i:int = 0; i < DocumentClass.enemyList1.length; i++){
if(DocumentClass.enemyList1[i] && DocumentClass.enemyList1[i].hit){
if (hitTestObject(DocumentClass.enemyList1[i].hit)){
trace("hitEnemy");
removeSelf();
DocumentClass.enemyList1[i].takeHit();
break;
}
}
}
Not the correct solution in this question. You can always do != null in a conditional statement.
if(object!=null){
party.drink();
}

AS3 How to use addChild() in a separated as file

How can I add the MovieClip I have put into the array to the Stage?
The following code is a separated .as file and located at the same level with the main.fla
I have tried many times but I got the error message -
"ReferenceError: Error #1065: Variable stage is not defined. at Set1()
at main_fla::MainTimeline/frame1()"
How can I do? Thank for any help!!
package
{
import flash.display.MovieClip;
import flash.display.Stage;
public class Set1
{
private var map:Array=new Array();
public function Set1()
{
for (var i:Number=0; i<5; i++)
{
var cell_mc=new cell();
cell_mc.x = 50+ i*cell_mc.width;
cell_mc.y = 50;
cell_mc.className=i;
map[i] = cell_mc;
trace(map[i].className);
stage.addChild(map[i]);
}
}
}
}
You are a little mixed up. stage is not a magic variable, instead it is a property that is inherited from the DisplayObject base class. That property gets set internally when a display object is added to the stage. So in your case your class needs to either inherit from a DisplayObject– probably Sprite class. Or simply inject a reference to the Stage from the outside when you invoke your function
First you need to set the Main flash file class.You'll do that by clicking on stage in your fla. file and edit you class in properties(should look like this(class:Set1))
Code below should work fine
package
{
import flash.display.MovieClip;
import flash.display.Sprite;
public class Set1 extends Sprite
{
private var map:Array=new Array();
public function Set1()
{
for (var i:Number=0; i<5; i++)
{
var cell_mc=new cell();
cell_mc.x = 50+ i*cell_mc.width;
cell_mc.y = 50;
cell_mc.className=i;
map[i] = cell_mc;
trace(map[i].className);
addChild(map[i]);
}
}
}
}

AS3 - Adding an object to a MovieClip Container from a class

I'm kind of new to adding using classes in AS3, so far i've just been doing everything on frame1 of the movie. I figured I should eventually learn classes so here goes :) When I add objects onto the screen, I like to group them together in container objects for use later. So I have a board of Hex's that I'm building, and I'm trying to get them into a MovieClip named hexContainer that I have places on the stage. Now if I was doing this code like I normally would, I would just do hexContainer.addChild(tempHex). However, this is throwing me an error 1120.
My class code is as follows:
package
{
import flash.display.MovieClip
import Hex
import flash.display.Stage
public class Boards extends Hex
{
public function buildBoardOne()
{
for(var i:int = 1; i <= 5; i++)
{
var tempHex:Hex = new Hex();
tempHex.x = 100;
tempHex.y = 100;
hexContainer.addChild(tempHex);
}
}
}
}
I did in the beginning just have these added to the Stage and was getting an error when I did that, that's why the import statement is there. I had checked on google to figure out why and that's what they said to do.
Now, when I added these to the stage it worked fine. I could get my hex's and manipulate them and we partied and it was a great time. Now that I'm trying to put them into the container movie clip they are rather angry at me and I just can't appease them :p
Any help you guys could give me would be greatly appreciated.
Edited code to test out what okayGraphics suggested:
package
{
import flash.display.MovieClip
import Hex
import flash.display.Stage
public class Boards extends Hex
{
var hexContainer:MovieClip = new MovieClip();
stage.addChild(hexContainer);
public function buildBoardOne()
{
for(var i:int = 1; i <= 5; i++)
{
var tempHex:Hex = new Hex();
tempHex.x = 100;
tempHex.y = 100;
stage.addChild(tempHex);
}
}
}
}
You are getting an 1120 error because hexContainer is not defined in this package.
You either (1)need to declare var hexContainer = [your_reference_here] before you try to add children to it,
or
(2)you can just add the hexes as children to the Boards class, then add that to your hexContainer.
instead of hexContainer.addChild(TempHex); just put addChild(TempHex);
There's lots of other ways to do it too, but I think these two are the most straightforward approaches.