How to have different mouse cursor on MOUSE_DOWN in as3? - actionscript-3

I'm new to as3 and I need to do a very simple thing. I have following code and it works pretty well. But what I need and can't figure out how to do it is:
change mouse cursor when I hold mouse button (choose from symbols)
ability to move with it (normally it would disappear when I move with mouse)
import flash.display.Sprite;
import flash.events.Event;
import flash.events.MouseEvent;
import fl.motion.MotionEvent;
var CursorStill: Sprite;
var CursorAnim: Sprite;
function init() {
Mouse.hide();
CursorStill = new CursorStillClass();
CursorStill.mouseEnabled = false;
CursorStill.visible = false;
addChild(CursorStill);
stage.addEventListener(MouseEvent.MOUSE_MOVE, mouseMoveHandler);
stage.addEventListener(Event.MOUSE_LEAVE, mouseLeaveHandler);
stage.addEventListener(MouseEvent.MOUSE_DOWN, mouseDownHandler);
}
function mouseMoveHandler(evt: MouseEvent): void {
CursorStill.visible = true;
CursorStill.x = evt.stageX;
CursorStill.y = evt.stageY;
evt.updateAfterEvent();
}
function mouseLeaveHandler(evt: Event): void {
CursorStill.visible = false;
}
function mouseDownHandler (evt: MouseEvent): void {
CursorStill.visible = false;
}
init();

a friend of mine helped me and i figured it out. i hope it will help other newbies at least :)
import flash.events.Event;
import flash.events.MouseEvent;
import fl.motion.MotionEvent;
function init() {
Mouse.hide();
// this creates an instance of the library MovieClip with the
// name, "MyCursorClass". this contains your mouse cursor art
//
Cursor = new CursorClass();
Cursor.mouseEnabled = false;
Cursor.visible = false;
// you'll want to make sure the child is added above everything
// else, possibly in its own container
//
addChild(Cursor);
// respond to mouse move events
stage.addEventListener(MouseEvent.MOUSE_MOVE, mouseMoveHandler);
stage.addEventListener(Event.MOUSE_LEAVE, mouseLeaveHandler);
stage.addEventListener(MouseEvent.MOUSE_DOWN, mouseDownHandler);
stage.addEventListener(MouseEvent.MOUSE_UP, mouseUpHandler);
}
function mouseMoveHandler(evt: MouseEvent): void {
// whenever the mouse moves, place the cursor in the same spot
Cursor.visible = true;
Cursor.x = evt.stageX;
Cursor.y = evt.stageY;
// for smoother mouse pointer
evt.updateAfterEvent();
}
function mouseLeaveHandler(evt: Event): void {
Cursor.visible = false;
}
function mouseDownHandler(evt: MouseEvent): void {
Cursor.gotoAndStop(xx);
}
function mouseUpHandler(evt: MouseEvent): void {
Cursor.gotoAndStop(xx);
}
init();
most credits goes to this tutorial though
http://danielmclaren.com/2008/03/tips-for-using-custom-mouse-cursors-in-flash-as3

Related

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

custom mouse hiding behind objects as3

i have this here http://www.nzombie.eshost.es/ with a custom mouse. It works perfect, only that when it is behind another movie clip it "hides" itself. I don't know what's wrong. Any advice or help with be appreciated. Here's the mouse class:
package
{
import flash.display.MovieClip;
import flash.events.MouseEvent;
import flash.events.Event;
import flash.ui.Mouse;
public class myCursor extends MovieClip
{
public function myCursor(stage):void
{
stop();
Mouse.hide();
stage.addEventListener(MouseEvent.MOUSE_DOWN, onDown);
stage.addEventListener(MouseEvent.MOUSE_UP, onUp);
stage.addEventListener(MouseEvent.MOUSE_MOVE, onMove);
addEventListener(Event.REMOVED_FROM_STAGE, onRemove);
}
private function updateCoor(e:MouseEvent):void
{
x = e.stageX;
y = e.stageY;
e.updateAfterEvent();
}
private function onDown(e:MouseEvent):void
{
updateCoor(e);
gotoAndStop(2);
}
private function onUp(e:MouseEvent):void
{
updateCoor(e);
gotoAndStop(1);
}
private function onMove(e:MouseEvent):void
{
Mouse.hide();
updateCoor(e);
}
private function onRemove(e:Event):void
{
Mouse.show();
stage.removeEventListener(MouseEvent.MOUSE_DOWN, onDown);
stage.removeEventListener(MouseEvent.MOUSE_UP, onUp);
stage.removeEventListener(MouseEvent.MOUSE_MOVE, onMove);
removeEventListener(Event.REMOVED_FROM_STAGE, onRemove);
}
}
}
If you are adding multiple things to the stage at runtime it would be worth overriding addChild so that everything is added at index 1, leaving the cursor (at index 0) always on top.
Something like this:
override public function addChild(value:displayObject):void
{
var index:uint = 1;
if(value is myCursor){index = 0;}
addChildAt(value, index);
}
Or simply only ever add new display objects using addChildAt(displayObject, 1) and be sure to add your cursor class at 0;
I believe the issue lies not in this class, but in the class where you add myCursor object.
The buttons might have been added after the cursor & so the cursor lies behind the buttons in the display list. Try adding the myCursor after the buttons have been added to stage.

AS3: Live drawing?

I have one strange problem, if I use graphics.lineTo while moving the mouse (MOUSE_MOVE), the lines are created live. But if I change it to MOUSE_DOWN, the lines are straight, and unresponsive if the mouse is still being pressed.
Here's an example:
stage.addEventListener(MouseEvent.MOUSE_MOVE, follow);
stage.addEventListener(MouseEvent.MOUSE_DOWN, draw);
private function follow(e:MouseEvent){
trace(e.localY);
activeChalk.x = e.stageX;
activeChalk.y = e.stageY;
}
private function draw(e:MouseEvent){
trace(e.localY);
activeChalk.x = e.stageX;
activeChalk.y = e.stageY;
board.graphics.lineTo(e.stageX,e.stageY);
}
EDIT: I managed to make it to work using the following example:
http://www.foundation-flash.com/tutorials/as3drawingbymouse/
Your application is fundamentally flawed in a variety of ways.
Instead of going in to detail, here's a very simply implementation of drawing:
package
{
import flash.display.Graphics;
import flash.display.Sprite;
import flash.display.StageAlign;
import flash.display.StageScaleMode;
import flash.events.MouseEvent;
import flash.geom.Point;
[SWF(percentWidth = 100, percentHeight = 100, backgroundColor = 0xefefef, frameRate = 30)]
public class Chalk extends Sprite
{
protected var lastPoint:Point;
public function Chalk()
{
super();
stage.scaleMode = StageScaleMode.NO_SCALE;
stage.align = StageAlign.TOP_LEFT;
initializeDrawing();
}
protected function initializeDrawing():void
{
stage.addEventListener(MouseEvent.MOUSE_DOWN, mouseDownHandler);
}
protected function mouseDownHandler(event:MouseEvent):void
{
stage.removeEventListener(MouseEvent.MOUSE_DOWN, mouseDownHandler);
// mark mouse down location
lastPoint = new Point(mouseX, mouseY);
// listen for movement or up/out
stage.addEventListener(MouseEvent.MOUSE_MOVE, mouseMoveHandler);
stage.addEventListener(MouseEvent.MOUSE_UP, mouseUpHandler);
stage.addEventListener(MouseEvent.MOUSE_OUT, mouseUpHandler);
}
protected function mouseMoveHandler(event:MouseEvent):void
{
var g:Graphics = graphics;
g.lineStyle(1, 0x0000ff);
// draw line segment
g.moveTo(lastPoint.x, lastPoint.y);
g.lineTo(mouseX, mouseY);
// mark end of line segment
lastPoint = new Point(mouseX, mouseY);
}
protected function mouseUpHandler(event:MouseEvent):void
{
stage.removeEventListener(MouseEvent.MOUSE_MOVE, mouseMoveHandler);
stage.removeEventListener(MouseEvent.MOUSE_UP, mouseUpHandler);
stage.removeEventListener(MouseEvent.MOUSE_OUT, mouseUpHandler);
// prepare for next line
initializeDrawing();
}
}
}
Not really strange, a single MOUSE_DOWN event is dispatched when you click the mouse, thereafter MOUSE_MOVE events are dispatched.
You can simply trace your events to find out exactly what's happening.

AS3 How to find current location of mc?

Thanks for the startdrag() suggestions, but I'm trying to avoid that atm
I'm trying to create a drag motion by using mouse_down then the mc = mouseX. Here is an image of the situation
But when I click, the mc always jumps to its registration point, which is the top left corner atm.
I can't work my head around how to grab the current location of the mc. Note that the mc (all_mc) is wider than the stage.
Can someone please help me out?
this.addEventListener(MouseEvent.MOUSE_DOWN, mouseDownHandler);
function mouseDownHandler(e:MouseEvent) {
this.addEventListener(MouseEvent.MOUSE_MOVE, mouseMoveHandler);
}
function mouseMoveHandler(e:MouseEvent) {
all_mc.x = mouseX;
}
Edit:
Ok I kind of worked out the x location of the mouse in relation to the registration point of the mc (the registration is at the top left):
Math.abs(stage.x - all_mc.x) + mouseX
But how to I select that point of on the mc?
Modified Marty Wallace's answer to handle the difference between where you click and the registration point:
package {
import flash.display.Sprite;
import flash.events.Event;
import flash.events.MouseEvent;
public class DummyTest extends Sprite {
private var mDeltaX:Number = 0;
private var mDeltaY:Number = 0;
private var mGfx:Sprite;
public function DummyTest() {
mGfx = new Sprite();
with(mGfx.graphics) {
beginFill(0x00FF00);
drawRect(0, 0, 200, 200);
endFill();
}
addChild(mGfx);
addEventListener(MouseEvent.MOUSE_DOWN, onMouseDown);
}
private function onMouseDown(e:MouseEvent) : void {
mDeltaX = mGfx.x - mouseX;
mDeltaY = mGfx.y - mouseY;
addEventListener(Event.ENTER_FRAME, onEnterFrame);
addEventListener(MouseEvent.MOUSE_UP, onMouseUp);
}
private function onMouseUp(e:MouseEvent) : void {
removeEventListener(Event.ENTER_FRAME, onEnterFrame);
removeEventListener(MouseEvent.MOUSE_UP, onMouseUp);
}
private function onEnterFrame(e:Event) : void {
mGfx.x = parent.mouseX + mDeltaX;
mGfx.y = parent.mouseY + mDeltaY;
}
}
}
import flash.events.MouseEvent;
import flash.display.Sprite;
var mc:MovieClip;
var sprite:Sprite = new Sprite ;
sprite.graphics.beginFill(0x000000);
sprite.graphics.drawRect(0,0,100,100);
sprite.graphics.endFill();
this.addChild(sprite);
sprite.addEventListener(MouseEvent.MOUSE_DOWN,function(){
sprite.startDrag();}
);
sprite.addEventListener(MouseEvent.MOUSE_UP,function(){
sprite.stopDrag();}
);
startDrag() has a lockCenter argument which you could try playing with.
lockCenter:Boolean (default =
false) — Specifies whether the
draggable sprite is locked to the
center of the mouse position (true),
or locked to the point where the user
first clicked the sprite (false).
Without startDrag as per comment
Make this the base class of an object that you want to drag:
package
{
import flash.display.Sprite;
import flash.events.MouseEvent;
import flash.events.Event;
public class Draggable extends Sprite
{
// vars
private var _hx:Number = 0;
private var _hy:Number = 0;
/**
* Constructor
*/
public function Draggable()
{
addEventListener(MouseEvent.MOUSE_DOWN, _mouseDown);
}
/**
* MouseEvent.MOUSE_DOWN
*/
private function _mouseDown(e:MouseEvent):void
{
_hx = mouseX;
_hy = mouseY;
addEventListener(Event.ENTER_FRAME, _handle);
addEventListener(MouseEvent.MOUSE_UP, _mouseUp);
}
/**
* MouseEvent.MOUSE_UP
*/
private function _mouseUp(e:MouseEvent):void
{
removeEventListener(Event.ENTER_FRAME, _handle);
removeEventListener(MouseEvent.MOUSE_UP, _mouseUp);
}
/**
* Event.ENTER_FRAME
*/
private function _handle(e:Event):void
{
x = parent.mouseX - _hx;
y = parent.mouseY - _hy;
}
}
}
stage.addEventListener(MouseEvent.MOUSE_DOWN, mouseDownHandler);
var positionX:Number = 0;
var positionY:Number = 0;
function mouseDownHandler(e:MouseEvent) {
positionX = all_mc.mouseX;// save the x position for future reference
positionY = all_mc.mouseY;// save the y position for future reference
stage.addEventListener(MouseEvent.MOUSE_MOVE, mouseMoveHandler);
}
function mouseMoveHandler(e:MouseEvent) {
all_mc.x = stage.mouseX - positionX ;
all_mc.y = stage.mouseY - positionY ;
}
function mouseUpHandler(e:MouseEvent) {
stage.removeEventListener(MouseEvent.MOUSE_MOVE, mouseMoveHandler);
}

ActionScript - Mouse Logic Problem

dumb problem. embarrassed that i haven't found a solution. i'm tired.
a red square in on the stage. mouse-down + mouse-drag-up will move the red square downward (+y), while mouse-down + mouse-drag-down will move the red square upward (-y). this opposite motion is desired.
however, during a mouse drag the square must begin moving from it's current y position, regardless of how many mouse drags have changed it's initialized position. currently, the red square will always begin at stage 0, since my mouseDownOrigin variable is incorrect because my brain is asleep.
package
{
import flash.display.Sprite;
import flash.events.MouseEvent;
public class Test extends Sprite
{
private var sp:Sprite = new Sprite();
private var mouseDownOrigin:int;
public function Test()
{
sp.graphics.beginFill(0xFF0000);
sp.graphics.drawRect(0, 0, 100, 100);
sp.x = sp.y = 200;
addChild(sp);
stage.addEventListener(MouseEvent.MOUSE_DOWN, mouseDownEventHandler);
}
private function mouseDownEventHandler(evt:MouseEvent):void
{
mouseDownOrigin = evt.stageY;
stage.addEventListener(MouseEvent.MOUSE_MOVE, mouseMoveEventHandler);
stage.addEventListener(MouseEvent.MOUSE_UP, mouseUpEventHandler);
}
private function mouseMoveEventHandler(evt:MouseEvent):void
{
sp.y = mouseDownOrigin - evt.stageY;
}
private function mouseUpEventHandler(evt:MouseEvent):void
{
stage.removeEventListener(MouseEvent.MOUSE_MOVE, mouseMoveEventHandler);
stage.removeEventListener(MouseEvent.MOUSE_UP, mouseUpEventHandler);
}
}
}
You need to record the red square y position on the MouseUp event handler, practically recording the position you leave the square in.
private var currentPosition:int;
private function mouseUpEventHandler(evt:MouseEvent):void
{
currentPosition = sp.y;
stage.removeEventListener(MouseEvent.MOUSE_MOVE, mouseMoveEventHandler);
stage.removeEventListener(MouseEvent.MOUSE_UP, mouseUpEventHandler);
}
private function mouseMoveEventHandler(evt:MouseEvent):void
{
var n:int = event.stageY - mouseDownOrigin ;
sp.y = currentPosition - n;
}