Multitouch as3 problems - actionscript-3

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.

Related

AS3 - Space Shooter Enemy Shots

I'm very new to AS3 and programming in general and I've been developing a space shooter game in AS3 and have run into trouble regarding the enemy shots. The enemies fly vertically down from the top of the screen and should fire two shots (one going left and one going right) once their y coordinates equal that of the player. This works fine, except after anything from 30 seconds to 2 minutes, the following errors occur.
TypeError: Error #1009: Cannot access a property or method of a null object reference.
at EnemyShip2/fireWeapon()[G:\Games Related\1942\src\EnemyShip2.as:78]
at EnemyShip2/loop2()[G:\Games Related\1942\src\EnemyShip2.as:65]
TypeError: Error #1009: Cannot access a property or method of a null object reference.
at EnemyShot/removeSelf()[G:\Games Related\1942\src\EnemyShot.as:43]
at EnemyShot/loop()[G:\Games Related\1942\src\EnemyShot.as:36]
Below is the relevant code, for the enemy ship class as well as the enemy shot class.
Enemy Ship
package
{
import flash.display.Sprite;
import flash.display.Bitmap;
import flash.display.Stage;
import flash.events.Event;
import flash.events.TimerEvent;
import flash.utils.Timer;
/**
* ...
* #author D Nelson
*/
[Embed(source = "../assets/enemyship2.png")]
//This enemy moves relatively slowly and fires horizontal shots
public class EnemyShip2 extends Bitmap
{
private var vy:Number = 3;
//private var ay:Number = .2;
private var target:HeroShip;
private var enemyShip2:EnemyShip2;
private var enemyfireTimer:Timer;
private var enemycanFire:Boolean = true;
public function EnemyShip2(target:HeroShip):void
{
this.target = target;
scaleX = 0.3;
scaleY = 0.3;
x = Math.floor(Math.random() * 550);
y = -105;
addEventListener(Event.ENTER_FRAME, loop2, false, 0, true);
enemyfireTimer = new Timer(1000, 1);
enemyfireTimer.addEventListener(TimerEvent.TIMER, handleenemyfireTimer, false, 0, true);
}
private function handleenemyfireTimer(e:TimerEvent) : void
{
//the timer runs, so a shot can be fired again
enemycanFire = true;
}
private function removeSelf2():void
{
removeEventListener(Event.ENTER_FRAME, loop2);
if (stage.contains(this))
{
stage.removeChild(this);
}
}
private function loop2 (e:Event):void
{
//vy += ay;
y += vy;
if (y > stage.stageHeight)
{
removeSelf2();
}
if (y >= target.y && (enemycanFire))
{
fireWeapon();
enemycanFire = false;
enemyfireTimer.start();
}
if (this.x > 540 || this.x < 10)
{
removeSelf2();
}
}
private function fireWeapon():void
{
stage.addChild(new EnemyShot(target, x, y, -4));
stage.addChild(new EnemyShot(target, x, y, +4));
}
}
}
Enemy Shot
package
{
import flash.display.Sprite;
import flash.display.Bitmap;
import flash.events.Event;
import flash.display.Stage;
/**
* ...
* #author D Nelson
*/
[Embed(source="../assets/enemyshot.png")]
public class EnemyShot extends Bitmap
{
private var speed:Number;
private var target:HeroShip;
private var vx:Number;
public function EnemyShot(target:HeroShip, x:Number, y:Number, vx:Number)
{
this.target = target;
this.x = x;
this.y = y;
this.vx = vx;
scaleX = 0.3;
scaleY = 0.3;
addEventListener(Event.ENTER_FRAME, loop, false, 0, true);
}
private function loop(e:Event) : void
{
x += vx;
if (x >= 600 || x <= -50)
{
removeSelf();
}
}
private function removeSelf():void
{
removeEventListener(Event.ENTER_FRAME, loop);
if (stage.contains(this))
{
stage.removeChild(this);
}
}
}
}
Also provided is the main class, in case that is of any help.
package
{
import flash.display.Sprite;
import flash.display.MovieClip;
import flash.display.DisplayObject;
import flash.display.Stage;
import flash.events.*;
import flash.events.Event;
import flash.events.EventDispatcher;
import flash.events.KeyboardEvent;
import flash.events.TimerEvent;
import flash.ui.Mouse;
import flash.utils.*;
import flash.utils.ByteArray;
import flash.utils.Timer;
import flash.text.*;
import flash.media.Sound;
import flash.media.SoundChannel;
/**
* ...
* #author D Nelson
*/
public class Main extends MovieClip
{
[Embed(source = "snd/gamemusic2.mp3")]
private var MySound : Class;
private var mainsound : Sound;
private var shootsound: Sound = new ShootSound;
private var sndChannel:SoundChannel = new SoundChannel;
public var heroShip:HeroShip;
public var enemyShip1:EnemyShip1
public var enemyShip2:EnemyShip2
public var enemyShip3:EnemyShip3
public var enemyShip4:EnemyShip4
public var bossShip: BossShip
public var enemyShot: EnemyShot;
public var playerShot: PlayerShot;
private var background1:Background1;
private var background2:Background2;
public static const scrollspeed:Number = 2;
public var playerShotArray:Array = new Array()
public var enemyShotArray:Array = new Array()
public var enemies1Array:Array = new Array()
public var enemies2Array:Array = new Array()
private var fireTimer:Timer; //this creates a delay between each shot
private var canFire:Boolean = true; //this checks if a shot can be fired
public function Main():void
{
if (stage) init();
else addEventListener(Event.ADDED_TO_STAGE, init);
mainsound = (new MySound) as Sound;
shootsound = (new ShootSound) as Sound;
mainsound.play();
background1 = new Background1();
background2 = new Background2();
//setting the backgrounds one below another
background1.y = 0;
background2.y = background1.height;
//add background at the lowest depth level
stage.addChildAt(background1,0);
stage.addChildAt(background2, 0);
//sets up the timer and its listener
fireTimer = new Timer(250, 1);
fireTimer.addEventListener(TimerEvent.TIMER, handlefireTimer, false, 0, true);
stage.addEventListener(KeyboardEvent.KEY_DOWN, handleCharacterShoot);
//background scrolling effect
stage.addEventListener(Event.ENTER_FRAME, backgroundScroll);
//loop for enemy1 variety
stage.addEventListener(Event.ENTER_FRAME, loop1, false, 0, true);
//loop for enemy2 variety
stage.addEventListener(Event.ENTER_FRAME, loop2, false, 0, true);
//speed of player shots
setInterval(playerShootMovement, 10);
}
private function init(e:Event = null):void
{
removeEventListener(Event.ADDED_TO_STAGE, init);
//entry point
heroShip = new HeroShip();
stage.addChild(heroShip);
//test values for enemies
/*enemyShip1 = new EnemyShip1();
stage.addChildAt(enemyShip1, 2);
enemyShip1.y = stage.stageWidth * 0.3;
enemyShip1.x = 300;
enemyShip2 = new EnemyShip2();
stage.addChildAt(enemyShip2, 2);
enemyShip2.y = stage.stageWidth * 0.3;
enemyShip2.x = 200;
enemyShip3 = new EnemyShip3();
stage.addChildAt(enemyShip3, 2);
enemyShip3.y = stage.stageWidth * 0.3;
enemyShip3.x = 100;
enemyShip4 = new EnemyShip4();
stage.addChildAt(enemyShip4, 2);
enemyShip4.y = stage.stageWidth * 0.3;
enemyShip4.x = 400;
bossShip = new BossShip();
stage.addChildAt(bossShip, 1);
bossShip.y = 10;
bossShip.x = 130;*/
Mouse.hide();
}
private function handlefireTimer(e:TimerEvent) : void
{
//the timer runs, so a shot can be fired again
canFire = true;
}
public function playerShoot():void
{
//if canFire is true, allow a shot to be fired, then set canFire to false and start the timer again
//else, do nothing
if (canFire)
{
//Add new line to the array
playerShotArray.push(playerShot = new PlayerShot);
//Spawn missile in ship
playerShot.y = heroShip.y;
playerShot.x = heroShip.x+11;
addChild(playerShot);
canFire = false;
fireTimer.start();
sndChannel = shootsound.play();
}
}
public function playerShootMovement():void
{
//code adapted from the Pie Throw tutorial
for (var i:int = 0; i < playerShotArray.length; i++)
{
playerShotArray[i].y -= 10;
if (playerShotArray[i].y == 850)
{
playerShotArray.shift();
}
}
}
public function handleCharacterShoot(e:KeyboardEvent):void
{
/**
* SpaceBar = 32
*/
if (e.keyCode == 32)
{
playerShoot();
}
}
public function backgroundScroll (evt:Event):void
{
background1.y += scrollspeed;
background2.y += scrollspeed;
if (background1.y >= stage.stageHeight)
{
//the background is below the visible stage area, put it above the other background
background1.y = background2.y - background2.height;
}
else if (background2.y >= stage.stageHeight)
{
background2.y = background1.y - background2.height;
}
}
//EnemyShip 1 spawning
private function loop1(e:Event):void
{
//generates probability for the ship to spawn (lower number to increase odds, decrease it to decrease odds)
if (Math.floor(Math.random() * 55) == 5)
{
var enemyShip1:EnemyShip1 = new EnemyShip1(heroShip);
enemyShip1.addEventListener(Event.REMOVED_FROM_STAGE, removeEnemy1, false, 0, true);
enemies1Array.push(enemyShip1);
stage.addChild(enemyShip1);
}
}
private function removeEnemy1(e:Event):void
{
//removes the enemy that most recently left the screen from the array
enemies1Array.splice(enemies1Array.indexOf(e.currentTarget), 1);
}
//EnemyShip2 spawning
private function loop2(e:Event):void
{
if (Math.floor(Math.random() * 40) == 5)
{
var enemyShip2:EnemyShip2 = new EnemyShip2(heroShip);
enemyShip2.addEventListener(Event.REMOVED_FROM_STAGE, removeEnemy2, false, 0, true);
enemies2Array.push(enemyShip2);
stage.addChild(enemyShip2);
}
}
private function removeEnemy2(e:Event):void
{
enemies2Array.splice(enemies2Array.indexOf(e.currentTarget), 1);
}
}
}
Initially I thought it was to do with enemies firing shots while being too far to either side of the screen, but that doesn't seem to be the case. Any help would be greatly appreciated.
You need to make sure you remove the ENTER_FRAME listeners whenever you remove the object.
Actually, my advise is to not add ENTER_FRAME handlers throughout your game objects. This gets hard to manage and leads to bugs like you've encountered. Instead, add a single ENTER_FRAME as your core game loop, and update objects by calling an update() function on a list of game objects you maintain in your main game class. When you remove an object you simply won't call update() anymore. It also becomes easy to pause the game by just removing the ENTER_FRAME handler.
For example, here's a pattern I like to use for simple games:
interface IGameObject {
update():void;
}
class Enemy extends Sprite implements IGameObject {
public update():void {
// move, fire, etc
}
}
class Player extends Sprite implements IGameObject {
public update():void {
// move, fire, etc
}
}
class Bullet extends Bitmap implements IGameObject {
public update():void {
// move, collide, etc
}
}
class Main extends Sprite {
private objects:Vector.<IGameObject> = new <IGameObject>[];
public start():void {
addEventListener(Event.ENTER_FRAME, update);
}
public stopGame():void {
removeEventListener(Event.ENTER_FRAME, update);
}
private function update(e:Event):void {
for each (var object:IGameObject in objects) {
object.update();
}
}
public addObject(object:IGameObject):void {
objects.push(object);
addChild(object as DisplayObject);
}
public removeObject(object:IGameObject):void {
objects.splice(objects.indexOf(object), 1);
removeChild(object as DisplayObject);
}
}
Add and remove objects using addObject and removeObject. You can invoke them through a reference to Main or through event handlers you dispatch from your objects.

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 to define that a child should only appear in one scene?

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));
}
}
}

Actionscript 3: Error #1009: Cannot access a property or method of a null object reference. (parent)

This is a bit difficult to explain, but I will try.
In my Main() class, let's say I have the main movieclip (bg_image) being created, and also some lines that create an instance of another class. (look at the code below)
var route = Route(Airport.return_Route);
This route instance, is then purposed to dynamically add sprite-childs to the main background from the Main() class.
I have tried to to this with the following line:
new_flight = new Flight(coordinates)
Main.bg_image.addChild(new_flight);
This seem to work pretty fine. Let's switch focus to the new_flight instance. At the Flight class, this line trace(this.parent) would return "[object Image]".I would consider this successful so far since my intention is to add the new_flight as child to bg_image, which I guess is an "object image".
The problem, however, occurs when trying to delete the "new_flight"-instance. Obviously the ideal way of doing this would be through bg_image with removeChild.
But, when my script reaches this line: Main.bg_image.removeChild(this), my script stops and returns ArgumentError: Error #2025: The supplied DisplayObject must be a child of the caller., at that line. I have also tried replacing Main.bg_image.removeChild(this) with this.parent.removeChild(this), with no luck.
I think the solution may be to use some sort of "EventDispatching"-method. But I haven't fully understood this concept yet...
The code follows. Please help. I have no idea how to make this work...
Main class:
package
{
import flash.display.MovieClip;
import flash.utils.Dictionary;
import flash.events.MouseEvent;
import flash.display.Sprite;
import flash.text.TextField;
import fl.controls.Button;
import flash.display.DisplayObject;
import Airport;
public class Main extends Sprite
{
// ------------------------
// Buttons
public var create_new_route;
public var confirm_new_route;
// images
public static var bg_image:MovieClip;
public var airport:MovieClip;
//-------------------------------
public var routeArray:Array;
public static var airportDict:Dictionary = new Dictionary();
public static var collectedAirportArray:Array = new Array();
public function Main()
{
addEventListener(Event.ADDED_TO_STAGE, init);
create_new_route = new Button();
create_new_route.label = "Create new route";
create_new_route.x = 220;
create_new_route.y = 580;
this.addChild(create_new_route)
create_new_route.addEventListener(MouseEvent.CLICK, new_route)
confirm_new_route = new Button();
confirm_new_route.label = "Confirm route";
confirm_new_route.x = 220;
confirm_new_route.y = 610;
this.addChild(confirm_new_route)
confirm_new_route.addEventListener(MouseEvent.CLICK, confirm_route)
}
public function init(e:Event):void
{
removeEventListener(Event.ADDED_TO_STAGE, init);
bg_image = new Image();
addChild(bg_image);
S_USA["x"] = 180.7;
S_USA["y"] = 149.9;
S_USA["bynavn"] = "New York";
S_Norway["x"] = 423.7;
S_Norway["y"] = 76.4;
S_Norway["bynavn"] = "Oslo";
S_South_Africa["x"] = -26;
S_South_Africa["y"] = 146;
S_South_Africa["bynavn"] = "Cape Town";
S_Brazil["x"] = 226;
S_Brazil["y"] = 431.95;
S_Brazil["bynavn"] = "Rio de Janeiro";
S_France["x"] = 459.1;
S_France["y"] = 403.9;
S_France["bynavn"] = "Paris";
S_China["x"] = 716.2;
S_China["y"] = 143.3;
S_China["bynavn"] = "Beijing";
S_Australia["x"] = 809.35;
S_Australia["y"] = 414.95;
S_Australia["bynavn"] = "Sydney";
// ----------------------------------------------------
airportDict["USA"] = S_USA;
airportDict["Norway"] = S_Norway;
airportDict["South Africa"] = S_South_Africa;
airportDict["Brazil"] = S_Brazil;
airportDict["France"] = S_France;
airportDict["China"] = S_China;
airportDict["Australia"] = S_Australia;
for (var k:Object in airportDict)
{
var value = airportDict[k];
var key = k;
startList.addItem({label:key, data:key});
sluttList.addItem({label:key, data:key});
var airport:Airport = new Airport(key,airportDict[key]["bynavn"]);
airport.koordinater(airportDict[key]["x"], airportDict[key]["y"]);
collectedAirportArray.push(airport);
airport.scaleY = minScale;
airport.scaleX = minScale;
bg_image.addChild(airport);
}
// --------------------------------------------
// --------------------------------------------
// -----------------------------------------------
}
private function new_route(evt:MouseEvent):void
{
Airport.ROUTING = true;
}
public function confirm_route(evt:MouseEvent):void
{
Airport.ROUTING = false;
trace(Airport.return_ROUTE);
var route = new Route(Airport.return_ROUTE); // ***
this.addChild(route); // **
Airport.return_ROUTE = new Array();
}
}
}
Airport class:
package
{
import flash.display.MovieClip;
import flash.events.MouseEvent;
import flash.events.Event;
import flash.display.SimpleButton;
import flash.display.Stage;
import flash.text.TextField;
import flash.text.TextFormat;
import flashx.textLayout.formats.Float;
public class Airport extends MovieClip
{
public static var ROUTING = false;
public static var return_ROUTE:Array = new Array();
//-----------------------------------------------------------------------------
// ----------------------------------------------------------------------------
protected var navn:String;
protected var bynavn:String;
// ----------------------------------------------------------------------------
public function Airport(navninput, bynavninput)
{
this.bynavn = bynavninput;
this.navn = navninput;
this.addEventListener(MouseEvent.CLICK, clickHandler);
this.addEventListener(MouseEvent.MOUSE_OVER, hoverHandler);
}
public function zoomHandler():void
{
trace("testing complete");
}
public function koordinater(xc, yc)
{
this.x = (xc);
this.y = (yc);
}
private function clickHandler(evt:MouseEvent):void
{
trace(ROUTING)
if (ROUTING == true)
{
return_ROUTE.push([this.x, this.y])
}
}
private function hoverHandler(evt:MouseEvent):void
{
if (ROUTING == true)
{
this.alpha = 60;
this.width = 2*this.width;
this.height = 2*this.height;
this.addEventListener(MouseEvent.MOUSE_OUT, awayHandler);
}
}
private function awayHandler(evt:MouseEvent):void
{
this.width = 13;
this.height = 13;
}
}
}
Route class
package
{
import flash.events.TimerEvent;
import flash.utils.Timer;
import flash.display.MovieClip;
import Main;
public class Route
{
public var income:Number;
public var routePoints:Array;
private var routeTimer:Timer;
private var new_flight:Flight;
public function Route(route_array:Array)
{
this.routePoints = route_array
routeTimer = new Timer(2000);// 2 second
routeTimer.addEventListener(TimerEvent.TIMER, route_function);
routeTimer.start();
}
private function route_function(event:TimerEvent):void
{
for (var counter:uint = 0; counter < routePoints.length - 1; counter ++)
{
trace("Coords: ", routePoints[counter][0],routePoints[counter][1],routePoints[counter + 1][0],routePoints[counter + 1][1]);
new_flight = new Flight(routePoints[counter][0],routePoints[counter][1],routePoints[counter + 1][0],routePoints[counter + 1][1]);
Main.bg_image.addChild(new_flight);
var checkTimer:Timer = new Timer(15);// 1 second
checkTimer.addEventListener(TimerEvent.TIMER, check_function);
checkTimer.start();
function check_function(event:TimerEvent):void
{
if (new_flight.finished = true)
{
checkTimer.stop();
}
}
}
}
}
}
Flight class
package
{
import flash.display.MovieClip;
import flash.display.Sprite;
import flash.events.MouseEvent;
import flash.events.Event;
import flash.display.SimpleButton;
import flash.display.Stage;
import flash.events.TimerEvent;
import flash.utils.Timer;
import fl.controls.Button;
import flash.display.DisplayObject;
public class Flight extends MovieClip
{
public static var speed:uint = 1
public var finished:Boolean = false;
protected var absvector:Number;
protected var vector:Array;
protected var myTimer:Timer;
//protected var parentContainer:MovieClip;
protected var utgangspunkt_x;
protected var utgangspunkt_y;
protected var destinasjon_x;
protected var destinasjon_y;
protected var vector_x;
protected var vector_y;
public function Flight(utgangspunkt_x, utgangspunkt_y, destinasjon_x, destinasjon_y):void
{
addEventListener(Event.ADDED_TO_STAGE, init);
this.utgangspunkt_x = utgangspunkt_x;
this.utgangspunkt_y = utgangspunkt_y;
this.x = utgangspunkt_x;
this.y = utgangspunkt_y;
this.destinasjon_x = destinasjon_x + 10;
this.destinasjon_y = destinasjon_y + 10;
this.vector_x = Math.abs(this.destinasjon_x-this.utgangspunkt_x);
this.vector_y = Math.abs(this.destinasjon_y-this.utgangspunkt_y);
this.height = 20;
this.width = 20;
}
public function init(evt:Event):void
{
trace(this.parent)
if (utgangspunkt_x < destinasjon_x)
{
this.rotation = -(Math.atan((utgangspunkt_y-destinasjon_y)/(destinasjon_x-utgangspunkt_x)))/(Math.PI)*180;
}
else
{
this.rotation = 180-(Math.atan((utgangspunkt_y-destinasjon_y)/(destinasjon_x-utgangspunkt_x)))/(Math.PI)*180;
}
absvector = Math.sqrt(Math.pow((destinasjon_x - utgangspunkt_x),2) + Math.pow((utgangspunkt_y - destinasjon_y),2));
vector = [(destinasjon_x - utgangspunkt_x) / absvector,(utgangspunkt_y - destinasjon_y) / absvector];
stage.addEventListener(Event.ENTER_FRAME, movement)
}
private function movement(evt:Event):void
{
if (this.vector_x > this.vector_y)
{
if (destinasjon_x>utgangspunkt_x)
{
if (this.x < destinasjon_x)
{
this.x += speed*vector[0];
this.y -= speed*vector[1];
}
else
{
finished = true
Main.bg_image.removeChild(this)
}
}
else if (destinasjon_x<utgangspunkt_x)
{
if (this.x > destinasjon_x)
{
this.x += speed*vector[0];
this.y -= speed*vector[1];
}
else
{
finished = true
Main.bg_image.removeChild(this)
}
}
}
else
{
if (destinasjon_y>utgangspunkt_y)
{
if (this.y < destinasjon_y)
{
this.x += speed*vector[0];
this.y -= speed*vector[1];
}
else
{
finished = true
Main.bg_image.removeChild(this)
}
}
else if (destinasjon_y<utgangspunkt_y)
{
if (this.y > destinasjon_y)
{
this.x += speed*vector[0];
this.y -= speed*vector[1];
}
else
{
finished = true
Main.bg_image.removeChild(this)
}
}
}
}
}
}
I am confused what your asking and what your trying to do, but I will give it my best shot.
this.addchild(new_class2)
This line adds your object to the display list. Adding another object to the display is done the same way you added the first. Flash adds objects in the sequentially, so the objects you want in the back need to be declared and added first.
This is probably what you want:
var new_flight:Flight = new Flight();
this.addchild(new_flight);
Also you forgot your type declaration for Class2:
var new_class2:Class2 = new Class2();
Try replacing:
Main.bg_image.addChild(new_flight);
with
Main(this.parent).bg_image.addChild(new_flight);
... assuming the 'main' class you refer to is infact named 'Main' and it has a named instance called 'bg_image'
Please leave a comment if it works, I can explain in more detail what is actually happening here.
Why you are adding new_flight to bg_image?
Anyway, if you are adding new_flight to bg_image, then you have bg_image already declared as public static (which I do not recommend),
Try removing the flight in your Flight class it-self like so,
Main.bg_image.removeChild(this) // *
You can also use Event Dispatching instead of declaring bg_image as static.
If you want to remove flight then dispatch event from Flight class to Route class and there you again dispatch event to main class.
And, inside main class capture this event and access the MovieClip.

ActionScript 3: Zoom functions - drag does not show

I've included a zoom functionality similar to the one explained at this website: http://www.flashandmath.com/howtos/zoom/
Even though it does indeed work in terms of the possibility of moving the image on my stage, the drag-animation is not present, meaning there will be no "movement" of my image, just a sudden change in position.
The problem followed my attempt to change the concept from timeline-based to class-based.
Here is my Main class:
package
{
import flash.display.MovieClip;
import flash.utils.Dictionary;
import flash.display.Shape;
import fl.transitions.Fly;
import fl.motion.MatrixTransformer;
import flash.events.MouseEvent;
import flash.events.KeyboardEvent;
import flash.geom.Matrix;
import flash.geom.Point;
import flash.ui.Mouse;
public class Main extends Sprite
{
public static var scale:Number = 1;
private var _rootMC:MovieClip;
// ------------------------------
public var bg_image:Sprite;
public var spImage:Sprite;
public var mat:Matrix;
public var mcIn:MovieClip;
public var mcOut:MovieClip;
public var boardWidth:int = 980;
public var boardHeight:int = 661;
public var boardMask:Shape;
public var externalCenter:Point;
public var internalCenter:Point;
public static var scaleFactor:Number = 0.8;
public static var minScale:Number = 0.25;
public static var maxScale:Number = 10.0;
//-------------------------------
public function Main(rootMC:MovieClip)
{
_rootMC = rootMC;
bg_image = new image();
this.graphics.beginFill(0xB6DCF4);
this.graphics.drawRect(0,0,boardWidth,boardHeight);
this.graphics.endFill();
spImage = new Sprite();
this.addChild(spImage);
boardMask = new Shape();
boardMask.graphics.beginFill(0xDDDDDD);
boardMask.graphics.drawRect(0,0,boardWidth,boardHeight);
boardMask.graphics.endFill();
boardMask.x = 0;
boardMask.y = 0;
this.addChild(boardMask);
spImage.mask = boardMask;
minScale = boardWidth / bg_image.width;
mcIn = new InCursorClip();
mcOut = new OutCursorClip();
bg_image.addChild(mcIn);
bg_image.addChild(mcOut);
bg_image.scaleX = minScale;
bg_image.scaleY = minScale;
spImage.addChild(bg_image);
spImage.addChild(mcIn);
spImage.addChild(mcOut);
spImage.addEventListener(MouseEvent.MOUSE_DOWN, startDragging);
_rootMC.stage.addEventListener(MouseEvent.MOUSE_UP, stopDragging);
spImage.addEventListener(MouseEvent.CLICK, zoom);
_rootMC.stage.addEventListener(KeyboardEvent.KEY_DOWN, keyHandler);
_rootMC.stage.addEventListener(KeyboardEvent.KEY_UP, keyHandler);
}
private function startDragging(mev:MouseEvent):void
{
spImage.startDrag();
}
private function stopDragging(mev:MouseEvent):void
{
spImage.stopDrag();
}
private function zoom(mev:MouseEvent):void
{
if ((!mev.shiftKey)&&(!mev.ctrlKey))
{
return;
}
if ((mev.shiftKey)&&(mev.ctrlKey))
{
return;
}
externalCenter = new Point(spImage.mouseX,spImage.mouseY);
internalCenter = new Point(bg_image.mouseX,bg_image.mouseY);
if (mev.shiftKey)
{
bg_image.scaleX = Math.max(scaleFactor*bg_image.scaleX, minScale);
bg_image.scaleY = Math.max(scaleFactor*bg_image.scaleY, minScale);
}
if (mev.ctrlKey)
{
bg_image.scaleX = Math.min(1/scaleFactor*bg_image.scaleX, maxScale);
bg_image.scaleY = Math.min(1/scaleFactor*bg_image.scaleY, maxScale);
}
mat = this.transform.matrix.clone();
MatrixTransformer.matchInternalPointWithExternal(mat,internalCenter,externalCenter);
bg_image.transform.matrix = mat;
}
private function keyHandler(ke:KeyboardEvent):void
{
mcIn.x = spImage.mouseX;
mcIn.y = spImage.mouseY;
mcOut.x = spImage.mouseX;
mcOut.y = spImage.mouseY;
mcIn.visible = ke.ctrlKey;
mcOut.visible = ke.shiftKey;
if (ke.ctrlKey || ke.shiftKey)
{
Mouse.hide();
}
else
{
Mouse.show();
}
}
}
}
Here is my image class:
package {
import fl.motion.MatrixTransformer;
import flash.display.MovieClip;
import flash.utils.Dictionary;
import flash.display.Shape;
import fl.transitions.Fly;
import fl.motion.MatrixTransformer;
import flash.events.MouseEvent;
public class image extends MovieClip
{
public function image()
{
this.width = 980
this.height = 500
this.y = 0
this.x = 0
}
}
I know this is a lot of code, but I am really stuck :(
On your MOUSE_DOWN handler, you need to start listening to the MOUSE_MOVE event.
On your MOUSE_UP handler, you need to stop listening to the MOUSE_MOVE event.
Not sure if you are already doing this.
In your MOUSE_MOVE event handler, you need to update the x / y positions of the image, in a similar way to what you are probably doing on the MOUSE_UP handler.