How to define that a child should only appear in one scene? - actionscript-3

We are making an space impact game. Here are 3 of our classes. Our problem is that when we create our InimigoNoite, they appear all over the game(menus, other levels, etc), instead of only appearing in the Scene that we want. How should we restrict the child to only appear in the CenárioCidade?
We've tried to use gotoandPlay, addChildAt, and also tried to create the Inimigo not in the Main class, but in the Inimigo class itself, but it doesnt appear at all. Please can someone help us? Thank you very much!
KEY.as
package {
import flash.display.Stage;
import flash.events.Event;
import flash.events.KeyboardEvent;
public class Key {
private static var initialized:Boolean = false;
private static var keysDown:Object = new Object();
public static function initialize(stage:Stage) {
if (!initialized) {
stage.addEventListener(KeyboardEvent.KEY_DOWN, keyPressed);
stage.addEventListener(KeyboardEvent.KEY_UP, keyReleased);
stage.addEventListener(Event.DEACTIVATE, clearKeys);
initialized = true;
}
}
public static function isDown(keyCode:uint):Boolean
{
return Boolean(keyCode in keysDown);
}
private static function keyPressed(event:KeyboardEvent):void {
keysDown[event.keyCode] = true;
}
private static function keyReleased(event:KeyboardEvent):void {
if (event.keyCode in keysDown) {
delete keysDown[event.keyCode];
}
}
private static function clearKeys(event:Event):void {
keysDown = new Object();
}
}
}
INIMIGO NOITE.as
package{
import flash.display.MovieClip;
import flash.events.Event;
import flash.utils.Timer;
public class InimigoNoite extends MovieClip{
var speed:Number;
static var list:Array = new Array();
var balaTimer: Timer;
function InimigoNoite(){
list.push(this);
this.x = 1160;
this.y = 150 + (450-150) * Math.random();
speed = Math.random()*5 + 5;
addEventListener("enterFrame", enterFrame);
var intervalo: Number = Math.random()*500 + 1000;
balaTimer = new Timer(intervalo);
balaTimer.addEventListener("timer", bala);
balaTimer.start();
}
function enterFrame (e:Event){
this.x -= speed;
if(this.x < -100){
matar();
return;
}
if(this.hitTestObject(SpaceImpact.navecnoite)){
matar();
}
}
function matar(){
var explosao = new ExplosaoNoite();
stage.addChild(explosao);
explosao.x = this.x;
explosao.y = this.y;
balaTimer.stop();
balaTimer.removeEventListener("timer",bala);
removeEventListener("enterFrame", enterFrame);
stage.removeChild(this);
for(var i in list){
if(list[i] == this){
delete list[i];
}
}
}
function bala(e:Event){
var b = new BalaInimigo();
b.x = this.x -50;
b.y = this.y;
stage.addChild(b);
}
}
}
MAIN.as
package{
import flash.display.MovieClip;
import flash.events.Event;
import flash.utils.Timer;
public class SpaceImpact extends MovieClip{
static var navecnoite:MovieClip;
var inimigoNoiteTimer:Timer;
function SpaceImpact(){
Key.initialize(stage);
inimigoNoiteTimer = new Timer(8000);
inimigoNoiteTimer.addEventListener("timer", criaInimigo);
inimigoNoiteTimer.start();
}
function criaInimigo(e:Event){
var inimigo = new InimigoNoite();
stage.addChild(inimigo);
addChildAt(inimigo, 3);
}
}
}

You never stop the timer. So your inimigo is created and added every 8seconds.
Stop the timer in criaInimigo and/or use the timerComplete Event
function SpaceImpact(){
Key.initialize(stage);
inimigoNoiteTimer = new Timer(8000,1);
inimigoNoiteTimer.addEventListener(TimerEvent.TIMER_COMPLETE, criaInimigo);
inimigoNoiteTimer.start();
}
function criaInimigo(e:Event){
//inimigoNoiteTimer.stop();//only needed if you use the 'timer'-Event
var inimigo = new InimigoNoite();
stage.addChild(inimigo);
addChildAt(inimigo, 3);
}

Right when you application starts, you are creating a new InimigoNoite every 8 seconds. Since you are adding them to the stage, they will appear over top anything you have on your timeline.
The issue (besides creating them when the application starts and never stopping your timer), is that when you through code use addChild, that child will stay on the screen until it's explicitly removed via removeChild (or one of it's parents are - but since the parent is stage that isn't going to happen).
I see that your have a hit test in the InimigoNoite class that can potentially remove it, but I don't see anywhere else where you remove it (so if the hit test never happens, it will never be removed from the stage regardless of scene).
It seem though that the solution to your problem is more advice on how to architect your application.
Don't use scenes.
Your best bet is to create a class file for each distinct state of your game. So something like this as a basic example:
Main Menu State
Game Play State(either 1 game state that encompasses all levels, or one state for each level - or both - depending on how much functionality changes between levels)
Game Over State
Make your game state class files extend Sprite or MovieClip, and if you want you can even create a new MovieClip in flash pro and attach the class to that (thereby being able to drop visual assets on the timeline).
So then your Main class would just be in charge of managing states (and any anything else that is global to the application)
package{
import flash.display.MovieClip;
import flash.events.Event;
public class SpaceImpact extends MovieClip {
private var menu:Menu; //Assumes you have a Menu.as class file
private var game:MainGame; //MainGame.as file
private var gameOver:GameOver; //GameOver.as file
public function SpaceImpact(){
Key.initialize(stage);
goMenu();
}
public function goMenu(e:Event = null):void {
removeAll();
menu = new Menu();
addChild(menu);
menu.addEventListener(Event.COMPLETE, startGame,false,0,true);
}
private function removeMenu():void {
if(menu){
if(menu.parent) removeChild(menu); //remove it from the screen
menu = null;
}
}
public function startGame(e:Event = null):void {
removeAll();
game = new MainGame();
addChild(game);
game.addEventListener(Event.COMPLETE, gameOver,false,0,true);
}
private function removeGame():void {
if(game){
if(game.parent) removeChild(game); //remove it from the screen
game = null;
}
}
public function gameOver(e:Event = null):void {
removeAll();
gameOver = new GameOver();
addChild(gameOver);
gameOver.addEventListener(Event.COMPLETE, goMenu,false,0,true);
}
private function removeGameOver():void {
if(gameOver){
if(gameOver.parent) removeChild(gameOver); //remove it from the screen
gameOver = null;
}
}
private function removeAll():void {
removeGameOver();
removeMenu();
removeGame();
}
}
}
then, your game state for example:
MainGame.as
package{
import flash.display.MovieClip;
import flash.events.Event;
import flash.utils.Timer;
public class MainGame extends MovieClip {
private var inimigoNoiteTimer:Timer;
public function MainGame() {
this.addEventListener(Event.ADDED_TO_STAGE, addedToStage, false, 0, true); //don't do anything until this object has been added to the screen
}
private function addedToStage(e:Event):void {
this.removeEventListener(Event.ADDED_TO_STAGE, addedToStage);
//start spawning
inimigoNoiteTimer = new Timer(8000);
inimigoNoiteTimer.addEventListener("timer", criaInimigo);
inimigoNoiteTimer.start();
}
function criaInimigo(e:Event){
var inimigo = new InimigoNoite();
addChild(inimigo);
}
//when whatever happens that makes your game finished
function gameComplete():void {
dispatchEvent(new Event(addEventListener.COMPLETE));
}
}
}

Related

Adding EventListener to Sprites in other classes does not work in AS3

I have my main class where I add EventLisitener to Sprites in other classes Like so:
public function Main() {
if (stage) init();
else addEventListener(Event.ADDED_TO_STAGE, init);
addChild(Menu.menuBackground);
addChild(Menu.startButton);
//Adds event Listener to Menu's Sprite startButton.
Menu.startButton.addEventListener(MouseEvent.CLICK, startGame);
}
private function init(e:Event = null):void {
removeEventListener(Event.ADDED_TO_STAGE, init);
}
This all works Fine and Dandy but later I try to do it again, the same way. But, clicking on the sprites does nothing. Here is the full Main Class code. Along with the code for the other three Sprite classes.
Full Main:
package {
//Other Files
import Menu;
import CrossHair;
import Birds;
import flash.display.Bitmap;
import flash.display.Sprite;
import flash.events.Event;
import flash.events.MouseEvent;
import flash.ui.Mouse;
public class Main extends Sprite {
//Game values
public static var gameWidth:int = 750;
public static var gameHeight:int = 750;
[Embed (source = "lib/background.png")]
public var backgroundClass:Class;
public var background:Bitmap = new backgroundClass();
public function Main() {
if (stage) init();
else addEventListener(Event.ADDED_TO_STAGE, init);
addChild(Menu.menuBackground);
addChild(Menu.startButton);
Menu.startButton.addEventListener(MouseEvent.CLICK, startGame);
}
private function init(e:Event = null):void {
removeEventListener(Event.ADDED_TO_STAGE, init);
}
//Function starts game
public function startGame(Evt:Event):void {
Mouse.hide(); //Hides Mouse
removeChild(Menu.startButton); //Get rid of startButton
Menu.startButton.removeEventListener(MouseEvent.CLICK, startGame);
reRender();
//Add eventListiners
addEventListener(Event.ENTER_FRAME, update);
Birds.bird.addEventListener(MouseEvent.CLICK, Birds.shot);
EnterShopButton.shopButton.addEventListener(MouseEvent.CLICK, enterShop);
}
public function reRender():void {
addChild(background); //Add background
addChild(Birds.bird); //Add birds.
addChild(EnterShopButton.shopButton); //Add UpgradeMenuButton
addChild(CrossHair.crossHair); //Add crosshair
}
public function enterShop():void {
stage.removeChildren(); //Removes all children from stage.
}
public function update(evt:Event):void {
Birds.update();
CrossHair.crossHair.x = mouseX - (CrossHair.crossHairImg.width / 2);
CrossHair.crossHair.y = mouseY - (CrossHair.crossHairImg.height / 2);
}
}
}
Event Lisitners:
package {
//Other files
import flash.events.Event;
import Main;
import flash.display.Sprite;
import flash.display.Bitmap;
public class Menu extends Sprite {
//create menbu background Bitmap
[Embed (source = "lib/menubackground.png")]
public static var menuBackgroundClass:Class;
public static var menuBackground:Bitmap = new menuBackgroundClass();
//create startButton Bitmap
[Embed (source = "lib/menustartbutton.png")]
public static var startButtonClass:Class;
public static var startButtonImg:Bitmap = new startButtonClass();
public static var startButton:Sprite = new Sprite();
//Set startButton's values
startButton.addChild(startButtonImg);
startButton.x = (Main.gameWidth / 2) - (startButtonImg.width / 2);
startButton.y = (Main.gameHeight / 2) - (startButtonImg.height / 2);
}
}
package {
//Other files
import Main;
import flash.display.Sprite;
import flash.display.Bitmap;
import flash.events.MouseEvent;
public class Birds extends Sprite {
public static var xSpeed:int = 10;
public static var ySpeed:int = 10;
public static var dead:Boolean = false;
//Create bird Sprite
[Embed (source = "lib/bird.png")]
public static var birdClass:Class;
[Embed (source = "lib/birdead.png")]
public static var deadBirdClass:Class;
public static var birdImg:Bitmap = new birdClass();
public static var deadBirdImg:Bitmap = new deadBirdClass();
public static var bird:Sprite = new Sprite();
//Sets Sprite's values
bird.addChild(birdImg);
bird.buttonMode = true;
bird.x = 0;
bird.y = 0;
public static function update():void {
bird.x += Math.random() * xSpeed;
bird.y += Math.random() * ySpeed;
if (!dead) {
if (bird.x >= (Main.gameWidth - birdImg.width) || bird.x <= 0) {
xSpeed = xSpeed * -1;
}
if (bird.y >= (Main.gameHeight - birdImg.height) || bird.y <= 0) {
ySpeed = ySpeed * -1;
}
} else {
if (bird.y > (Main.gameHeight - deadBirdImg.height)) {
resetBird();
}
}
}
public static function shot(evt:MouseEvent):void {
if (!dead) {
bird.removeChild(birdImg);
bird.addChild(deadBirdImg);
dead = true;
xSpeed = 0;
ySpeed = 50;
}
}
public static function resetBird():void {
bird.removeChild(deadBirdImg);
bird.addChild(birdImg);
dead = false;
bird.x = 0
bird.y = 0;
xSpeed = 10;
ySpeed = 10;
}
}
}
package {
//Other Files
import Main;
import flash.display.Sprite;
import flash.display.Bitmap;
import flash.events.Event;
import flash.events.MouseEvent;
public class EnterShopButton extends Sprite{
//Create crossHair
[Embed (source = "lib/shopbutton.png")]
public static var shopButtonClass:Class;
public static var shopButtonImg:Bitmap = new shopButtonClass();
public static var shopButton:Sprite = new Sprite();
//Set CrossHair's values
shopButton.addChild(shopButtonImg);
shopButton.buttonMode = true;
shopButton.x = Main.gameWidth - shopButtonImg.width;
shopButton.y = Main.gameHeight - shopButtonImg.height;
}
}
Same problem, same answer. Your previous question was answered the same way but you still persist on doing the exact same thing and getting into the exact same problem.
Stop trying to run code in static scope! addChild can't work in that scope and any other type of code.
Not sure why I was voted down. There's not much to answer here since the same problem with the same user was answered in another post.
This is really not difficult, user wants to run code at class definition scope. At class definition scope you can instantiate variable yes but that's all you can do. User wants to run code and logic at that scope and this is just completely ignored by the compiler. This was already pointed out to him in his previous question and he was even given the advice to stop trying to run code at that scope to avoid further problem. This is really simple to understand:
[Embed (source = "lib/menubackground.png")]
public static var menuBackgroundClass:Class;
public static var menuBackground:Bitmap = new menuBackgroundClass();
//instantiation is allowed at that scope and will work
//create startButton Bitmap
[Embed (source = "lib/menustartbutton.png")]
public static var startButtonClass:Class;
public static var startButtonImg:Bitmap = new startButtonClass();
//instantiation is allowed at that scope and will work
public static var startButton:Sprite = new Sprite();
//instantiation is allowed at that scope and will work
//COMPILER WILL IGNORE AT THAT SCOPE ANY CODE THAT IS NOT INSTANTIATION
//SO ALL FOLLOWING LINES ARE IGNORED AND PRODUCE NO RESULT
//EVEN TRACING WOULD NOT WORK HERE
// (Main.gameWidth / 2) WILL NOT BE CALCULATED AND DOES NOT PRODUCE ANY VALUE
// startButton.x WILL NOT BE SET AND WILL STAY AT DEFAULT VALUE 0
// FINALLY startButton WILL NOT addChild ANYTHING.
//ANY FORM OF CODE LOGIC IS IGNORED AT THAT SCOPE AND WILL NEVER PRODUCE ANY RESULT
startButton.addChild(startButtonImg);
startButton.x = (Main.gameWidth / 2) - (startButtonImg.width / 2);
startButton.y = (Main.gameHeight / 2) - (startButtonImg.height / 2);

How can I solve this error in Flash game?

I have a problem in Flash puzzle game. If I create the game in the first frame of my timeline it's working, but if the game has been created (for example) in 5th frame it does'nt work!
It send me this error:
TypeError: Error #1009: Cannot access a property or method of a null
object reference.
at Map() TypeError: Error #2007: Parameter hitTestObject must be non-null.
at flash.display::DisplayObject/_hitTest()
at flash.display::DisplayObject/hitTestObject()
at DragDrop/drop()
dragdrop class
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;
}
}
}
I think the problem is in var target! and I don't know how to solve it.
Map.as
enter code here package
{
import flash.display.*;
import flash.events.*;
public class Map extends MovieClip
{
var dragdrops:Array;
public function Map()
{
// constructor code
dragdrops = [tt1];
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
{
}
}
}
Edit:
There are multiple problems with the code. Too many to list, I'm afraid, but the biggest one is:
You're declaring a map, and trying to add your object to it, before your object exists. It doesn't exist until frame 5, so this won't work. I've re-written the code below, but honestly, there is so much wrong with the code that it's just not possible to fix without re-writing significant portions of it.
package
{
import flash.display.*;
import flash.events.*;
public class Map extends MovieClip
{
var dragdrops:Array;
public function Map()
{
// constructor code
dragdrops = new Array();
}
public function addElement(gamepiece:DragDrop):void {
dragdrops.push(gamepiece);
}
public function addChildElements():void {
var currentObject:Object;
for(var i:uint = 0; i < dragdrops.length; i++)
{
currentObject = dragdrops[i];
currentObject.test();
currentObject.target = (currentObject.name + "_target"); // this should work now, but doesn't. Why?
currentObject.target.test();
}
}
public function match():void
{
}
}
}
Then, on frame one, I added:
var map:Map = new Map();
Then, on frame five, I added:
map.addElement(tt1);
map.addChildElements();
This got tt1 added to map, at least, but that's as far as I got. Your problem now is;
currentObject.target = (currentObject.name + "_target");
It's the correct name, now, but it won't add it to target. That's as much as I can do.
It's because your hitTestObject method isn't correctly invoked. This method must be invoked in a Display Object instance to test if another instance of a Display Object hits it:
if (myDisplayObject.hitTestObject(anotherDisplayObject))
{
// do stuff
}
Adobe help about hitTestObject method.
Edit
So you should write you class like that:
package
{
import flash.display.*;
import flash.events.*;
public class DragDrop extends Sprite
{
var origX:Number;
var origY:Number;
var target:DisplayObject;
public function DragDrop()
{
addEventListener(Event.ADDED_TO_STAGE, init);
}
private function init(e:Event):void {
origX = x;
origY = y;
stage.addEventListener(MouseEvent.MOUSE_DOWN, drag);
buttonMode = true;
}
private function drag(evt:MouseEvent):void
{
stage.addEventListener(MouseEvent.MOUSE_UP, drop);
startDrag();
parent.addChild(this);
}
private function drop(evt:MouseEvent):void
{
target = (evt.target as DisplayObject);
stage.removeEventListener(MouseEvent.MOUSE_UP, drop);
stopDrag();
if(target.hitTestObject(target))
{
visible = false;
target.alpha = 1;
Object(parent).match();
}
x = origX;
y = origY;
}
}
}
Remark
You shouldn't call your variable target, because its the name of a Flash native variable. Rename it targ for example.

Multitouch as3 problems

I have a little problem with multitouch in as3.
Recently started a project in connection with my student practice.
This is to be a small game for android.
Are used to control two virtual joysticks and that's the problem with them.
As long as I use one of them or the other separately all works very well. However, when I try to use two at the same time, one of them is blocked and the object which moves begin to move in a random way and I can not control it.
Here is my code:
joystick.as:
package com.controls {
import flash.events.TouchEvent;
import flash.ui.Multitouch;
import flash.ui.MultitouchInputMode;
import flash.display.Sprite;
import flash.events.Event;
import flash.display.MovieClip;
import flash.geom.Rectangle;
import com.controls.JoystickKnob;
import com.Hero;
import com.Fire;
import com.greensock.*;
import com.greensock.easing.*;
public class Joystick extends MovieClip {
Multitouch.inputMode = MultitouchInputMode.TOUCH_POINT;
private var my_x:Number;
private var my_y:Number;
private var knob:JoystickKnob;
private var hero:Hero;
private var fire:Fire;
private var knob_tween:TweenLite;
public function Joystick(margin_left, margin_bottom, hero_mc) {
var circle:Sprite = new Sprite();
circle.graphics.beginFill(0x696969);
circle.graphics.drawCircle(50, 50, 60);
circle.graphics.endFill();
addChild(circle);
my_x = margin_left;
my_y = margin_bottom;
hero = hero_mc;
if (stage) {
init();
} else {
addEventListener(Event.ADDED_TO_STAGE,init);
}
}
private function init(e:Event = null):void {
if (hasEventListener(Event.ADDED_TO_STAGE)) {
removeEventListener(Event.ADDED_TO_STAGE,init);
}
this.x = my_x + this.width / 2;
this.y = stage.stageHeight - my_y - this.height / 2;
knob = new JoystickKnob();
knob.x = 0;
knob.y = 0;
knob.origin_x = 0;
knob.origin_y = 0;
addChild(knob);
this.addEventListener(TouchEvent.TOUCH_BEGIN, onTouchBegin, true);
knob.addEventListener(TouchEvent.TOUCH_MOVE, onTouchMove, true);
stage.addEventListener(TouchEvent.TOUCH_END, onTouchEnd, true);
knob.buttonMode = true;
}
private function onTouchBegin(event:TouchEvent):void {
knob.x = this.mouseX;
knob.y = this.mouseY;
onTouchMove(null);
}
private function onTouchMove(event:TouchEvent):void {
if (knob_tween) {
knob_tween.kill();
}
this.addEventListener(Event.ENTER_FRAME, knobMoved);
knob.startDrag(false, new Rectangle( - this.width /2, - this.height /2, this.width, this.height));
}
private function knobMoved(event:Event):void {
// LEFT OR RIGHT
if (knob.x > 15) {
hero.move_right = true;
hero.move_left = false;
} else if (knob.x < -15) {
hero.move_right = false;
hero.move_left = true;
} else {
hero.move_right = false;
hero.move_left = false;
}
// UP OR DOWN
if (knob.y > 15) {
hero.move_down = true;
hero.move_up = false;
} else if (knob.y < -15) {
hero.move_down = false;
hero.move_up = true;
} else {
hero.move_down = false;
hero.move_up = false;
}
}
private function onTouchEnd(event:TouchEvent):void {
knob.stopDrag();
hero.move_left = false;
hero.move_up = false;
hero.move_right = false;
hero.move_down = false;
if (this.hasEventListener(Event.ENTER_FRAME)) {
this.removeEventListener(Event.ENTER_FRAME, knobMoved);
}
mover();
}
private function mover():void {
knob_tween = new TweenLite(knob, 0.5, {x: knob.origin_x, y:knob.origin_y, ease:Bounce.easeOut});
}
}
}
joystickKnob.as:
package com.controls {
import flash.display.Sprite;
import flash.display.MovieClip;
public class JoystickKnob extends MovieClip {
private var _origin_x:Number;
private var _origin_y:Number;
private var knob:Class;
public function JoystickKnob() {
var circle:Sprite = new Sprite();
circle.graphics.beginFill(0x32CD32);
circle.graphics.drawCircle(50, 50, 35);
circle.graphics.endFill();
addChild(circle);
}
public function get origin_x():Number {
return _origin_x;
}
public function set origin_x(o_x:Number):void {
_origin_x = o_x;
}
public function get origin_y():Number {
return _origin_x;
}
public function set origin_y(o_y:Number):void {
_origin_y = o_y;
}
}
}
Second joystick code looks the same, except that it is stored in files joystick2.as, joystickKnob2.as.
This is the main class of my program:
package com {
import flash.events.TouchEvent;
import flash.display.MovieClip;
import flash.events.MouseEvent;
import com.controls.Joystick;
import com.controls.Joystick2;
import com.Hero;
import com.Fire;
public class MyApp extends MovieClip {
private var joystick:Joystick;
private var hero:Hero;
private var joystick2:Joystick2;
private var fire:Fire;
public function MyApp() {
hero = new Hero();
hero.x = stage.stageWidth/1.7;
hero.y = stage.stageHeight/1.7;
addChild(hero);
fire = new Fire();
fire.x = stage.stageWidth/1.7;
fire.y = stage.stageHeight/1.7;
addChild(fire);
joystick = new Joystick(-350, 100, hero);
addChild(joystick);
joystick2 = new Joystick2(600, 100, fire);
addChild(joystick2);
}
}
}
When using the two joysticks at the same time, the problem also occurs with the knob graphics - instead move in a specific area, one of them almost always moves to the other end of the screen, near the area of the second joystick.
Has anyone of you already encountered such a problem and knows how to remedy it?
Best regards and thank you in advance for your help
Multitouch.inputMode = MultitouchInputMode.TOUCH_POINT; does not support multiple fingers as written in de documentation:
For user interaction with multiple points of contact (such as several fingers moving across a touch screen at the same time) use the related GestureEvent, PressAndTapGestureEvent, and TransformGestureEvent classes. And, use the properties and methods of these classes to construct event handlers that respond to the user touching the device.
so you want Multitouch.inputMode = MultitouchInputMode.GESTURE;
This post shows up when searching for info on touch_point so I want to make sure it's correct.
TOUCH_POINT does support multiple touch points. Each touch is unique and given a unique id. You can have 100s of simultaneous touches.
TOUCH_POINT is what you use if you want to code your own touch handlers. GESTURE is TOUCH_POINTs handled for you. GESTURE decides if the touchpoints are swiping, tapping, etc. TOUCH_POINT is like a mouse event - the raw event.

AS3 MouseEvent.CLICK Interaction on Different Indexes

I'm currently working through a AS3 game tutorial on Lynda.com and am coming across a problem with the MouseEvent.CLICK and child indexes. The game is a simple point and shoot, where the player must shoot all of the approaching enemies before they get too close. It works initially, however the custom cursor I added displays behind the enemies. However when I try and adjust the index (I've used the addChildAt function and moving the addChild(cursor) line of code below the enemy container initializer) the on click interaction, which is supposed to remove the enemy when clicked on, doesn't work.
My document class:
package {
import flash.display.*;
import flash.utils.*;
import flash.events.*;
import flash.ui.*;
public class Game extends MovieClip {
public var cursor:Cursor;
public var enemy:Enemy;
public var numberOfEnemies:uint;
public var enemyContainer:MovieClip;
public var enemyTimer:Timer;
public function Game() {
addEventListener(Event.ADDED_TO_STAGE, init);
Mouse.hide();
}
public function init(event:Event):void {
cursor = new Cursor;
addChild(cursor);
stage.addEventListener(MouseEvent.MOUSE_MOVE, dragCursor);
numberOfEnemies = 10;
enemyTimer = new Timer(1000, numberOfEnemies);
enemyContainer = new MovieClip();
addChild(enemyContainer);
enemyTimer.addEventListener(TimerEvent.TIMER, createEnemies);
enemyTimer.start();
}
public function dragCursor(event:MouseEvent) {
cursor.x = this.mouseX;
cursor.y = this.mouseY;
}
public function createEnemies(event:TimerEvent):void {
enemy = new Enemy();
enemy.x = 25 + Math.random() * (stage.stageWidth - 75);
enemy.y = 25 + Math.random() * (stage.stageHeight - 75);
enemyContainer.addChild(enemy);
enemy.timerStart();
}
}
}
My enemy class:
package {
import flash.display.MovieClip;
import flash.utils.Timer;
import flash.ui.Mouse;
import flash.events.*;
public class Enemy extends MovieClip {
public var scaleObj:Number = 0.50;
public var growTimer:Timer;
public function Enemy() {
scaleX = scaleObj;
scaleY = scaleObj;
addEventListener(MouseEvent.CLICK, shootEnemy);
}
public function timerStart() {
growTimer = new Timer(50);
growTimer.addEventListener(TimerEvent.TIMER, objectGrow);
growTimer.start();
}
public function objectGrow(event:TimerEvent):void {
if(scaleObj <= 1.0) {
scaleObj += 0.01;
scaleX = scaleObj;
scaleY = scaleObj;
}
else {
killEnemy();
}
}
public function killEnemy():void {
this.parent.removeChild(this);
growTimer.stop();
}
public function shootEnemy(event:MouseEvent):void {
killEnemy();
}
}
}
There also is a cursor class, however there is no code beyond the package and class definers. Please let me know of any questions or comments you might have, thanks.
Most likely the Cursor object is intercepting the mouse click since it is above the Enemy object.
You can stop the Cursor from intercepting mouse events by setting in the cursor class:
this.mouseEnabled = false;
this.mouseChildren = false;
Also, you should ideally be using a native mouse cursor instead of manually creating your own. Check out this Adobe tutorial for an example.
Set your Cursor instance to not receive mouse events itself as it would block the click events from getting to the objects behind it. Code would be something like
cursor = new Cursor;
cursor.mouseEnabled = false;
cursor.mouseChildren = false;

AS3 - Error #2025: The supplied DisplayObject must be a child of the caller

After 2 days of trying and searching for an answer I still didn't found it. I keep getting Error #2025: The supplied DisplayObject must be a child of the caller. I'm making a game where if the user hits an enemy, the enemy get destroyed. The code:
My main class
package classes
{
import flash.display.MovieClip;
import flash.events.Event;
import flash.utils.Timer;
public class Main extends MovieClip
{
var enemyTimer:Timer;
public function Main()
{
var user:ship = new ship();
addChild(user);
user.name = "user";
user.initialize();
enemyTimer = new Timer(2000);
enemyTimer.addEventListener("timer", sendEnemy);
enemyTimer.start();
function sendEnemy(e:Event)
{
var badboy:enemy = new enemy();
addChild(badboy);
badboy.initialize();
}
}
}
}
the enemy class
package classes.enemy
{
import flash.display.MovieClip;
import flash.events.Event;
public class Enemy extends MovieClip
{
var speed:Number;
public function initialize()
{
addEventListener("enterFrame", enterFrame);
}
public function Enemy()
{
this.x = 700;
this.y = Math.random()*200 + 50;
speed = Math.random()*5 + 5;
}
function enterFrame(e:Event)
{
this.x -= speed;
if(this.hitTestObject(parent.getChildByName("user")))
{
kill();
}
}
function kill()
{
removeEventListener("enterFrame", enterFrame);
stage.removeChild(this);
}
}
}
The files are in different folders (classes > Main.as & classes.enemy.Enemy.as), don't know if that has anything to do with it.
Any help would be appreciated.
That's probably because you try to remove the Enemy MovieClip from stage, that it is not a (direct) child of.
I suggest you change this:
stage.removeChild(this);
to this:
this.parent.removeChild(this);
When you have a reference to a DisplayObject, like this in this case, you can always remove it from its parent, even if you don't know what that parent is. Or rather, you can remove it if you know it is on the display list, so you could also first check that it is, by doing:
if(this.parent) {
this.parent.removeChild(this);
}
I have got the solution: Just copy and paste the script and create few essentials symbols on stage, and in library; then, check it.
import flash.display.MovieClip;
var myArr:Array = [];
abc.startDrag(true);
var mymc:MovieClip = new MovieClip();
addChild(mymc);
init();
function init()
{
for (var i=0; i<25; i++)
{
var par:Particle = new Particle();
par.x = Math.random() * stage.stageWidth;
par.y = Math.random() * stage.stageHeight;
mymc.addChildAt(par,0);
myArr.push(par);
}
this.addEventListener(Event.ENTER_FRAME, hitTes);
}
function hitTes(e:Event):void
{
for (var j=0; j<myArr.length; j++)
{
if (abc.hitTestObject(myArr[j]))
{
if (myArr[j].parent)
{
myArr[j].parent.removeChild(myArr[j]);
}
}
}
}
I think you misplaced a method. See if this revision helps. (Also note that this does not include any cleanup of objects, which will eventually be a problem.)
package classes
{
import flash.display.MovieClip;
import flash.events.Event;
import flash.utils.Timer;
public class Main extends MovieClip
{
public var enemyTimer:Timer;
public var user:ship = new ship();
public var badboy:enemy = new enemy();
public function Main()
{
user = new ship();
addChild(user);
user.name = "user";
user.initialize();
enemyTimer = new Timer(2000);
enemyTimer.addEventListener("timer", sendEnemy);
enemyTimer.start();
}
// *** I moved this out of the constructor:
public function sendEnemy(e:Event):void
{
badboy = new enemy();
badboy.name = "badboy"; // you probably have to make this unique, though.
addChild(badboy);
badboy.initialize();
}
}
}