Need to move this Object in one direction - actionscript-3

I am trying to move this seatBelt object just on the horizontal plane. I have posted what I did so far. it's not really working out because it seems like once I press the button the seat belt is only able to move towards the right side and MOUSE_UP doesn't work. can somebody guide me on how to go about doing this?
seatBelt.addEventListener (MouseEvent.MOUSE_DOWN, prsing);
seatBelt.addEventListener (MouseEvent.MOUSE_UP, lfting);
seatBelt.addEventListener (MouseEvent.MOUSE_MOVE, mving);
function prsing (e:MouseEvent){
posX= seatBelt.x ;
posY = seatBelt.y ;
mouseclick = 1;
}
function mving (e:MouseEvent) {
if (mouseclick == 1) {
seatBelt.x = mouseX ;
}
}
function lfting (e:MouseEvent){
seatBelt.x = posX;
seatBelt.y = posY;
mouseclick =0;
}

So your intended functionality is to be able to drag the seatBelt along the x-axis and on release for it to go back to its original position?
You need to change the MOUSE_UP and MOUSE_MOVE to listen to the stage rather than the seatBelt. This is because it is possible for you to release the button when it is no longer over the seatBelt and so the function never gets called. The stage however will receive the event.
stage.addEventListener(MouseEvent.MOUSE_UP, lifting);
stage.addEventListener(MouseEvent.MOUSE_MOVE, moving);
I am not sure where you are declaring the mouseX variable but if you are after dragging functionality alter the listener to:
function moving (e:MouseEvent) {
if (mouseclick == 1) {
seatBelt.x = e.stageX;
}
}

What you have mostly looks okay code-wise, except what I think is happening is that you are "mousing up" on the stage/somewhere off the seatBelt object. I'm guessing this as to make the object move you have it reacting to mouse moving...to which I am guessing you are moving the mouse all over the stage and off the seatbelt object at which point you are then releasing the mouse.
To check if this is the case, try releasing the mouse over your seatBelt object to see if your MOUSE_UP event does get triggered.
I'm guessing the behaviour you want is that you want to have the object stop moving at any point regardless of where the mouse is released. To do this, try adding the MOUSE_UP event listener to the stage:
this.stage.addEventListener (MouseEvent.MOUSE_UP, lfting);
Though, since you may not always want this listener to be active, perhaps only add it when the mouse is pressed down over the object by adding and removing the listener only as needed.
I've edited your code a bit to show what I mean and taken out the "mouseclick" boolean as it wouldn't really be needed to keep track of the mouse down/up event anymore:
seatBelt.addEventListener(MouseEvent.MOUSE_DOWN, prsing);
function prsing(e:MouseEvent){
posX= seatBelt.x ;
posY = seatBelt.y ;
this.stage.addEventListener(MouseEvent.MOUSE_MOVE, mving);
this.stage.addEventListener(MouseEvent.MOUSE_UP, lfting);
}
function mving(e:MouseEvent) {
seatBelt.x = mouseX;
}
function lfting(e:MouseEvent){
seatBelt.x = posX;
seatBelt.y = posY;
this.stage.removeEventListener(MouseEvent.MOUSE_MOVE, mving);
this.stage.removeEventListener(MouseEvent.MOUSE_UP, lfting);
}

You can use the Sprite.startDrag method to do what you need. No MOUSE_MOVE listener is needed. Lookup the params if you need to: Sprite. I like to only have only one of the MOUSE_DOWN or MOUSE_UP listeners active at a time.
seatBelt.addEventListener (MouseEvent.MOUSE_DOWN, prsing);
function prsing (e:MouseEvent){
seatBelt.startDrag(false, new Rectangle(0,seatBelt.y,stage.width,seatBelt.y));
seatBelt.removeEventListener (MouseEvent.MOUSE_DOWN, prsing);
seatBelt.addEventListener (MouseEvent.MOUSE_UP, lfting);
}
function lfting (e:MouseEvent){
seatBelt.stopDrag();
seatBelt.addEventListener (MouseEvent.MOUSE_DOWN, prsing);
seatBelt.removeEventListener (MouseEvent.MOUSE_UP, lfting);
}

Related

Getting Mouse Position on Event

I have two events; mouse up and down. I get the initial position of the mouse when left button down. Then I plan to get the last position of the mouse when button released. So if there is a horizontal movement I can easily recognise. However it is problematic. Since I add listener to a movie clip, it obtain mouse x in bounds of that movie clip. What I mean is if you release button outside of the movie clip it does not work because event attached to it. Are there any turnarounds here?
m_c.addEventListener(MouseEvent.MOUSE_DOWN, StartPoint);
m_c.addEventListener(MouseEvent.MOUSE_UP, EndPoint);
function StartPoint(event:MouseEvent):void
{
initX = stage.mouseX;
}
function EndPoint(event:MouseEvent):void
{
lastX = stage.mouseX;
trace("drop ", lastX);
if(lastX < initX)
{
trace("goes left");
.
.
.
}
}
you need to addListener to stage, preferable in listener of MOUSE_DOWN
function StartPoint(event: MouseEvent) : void {
stage.addEventListener(MouseEvent.MOUSE_UP, EndPoint);
// another code
}

Actionscript 3 - How do I make new instances draggable?

I am attempting to build a drag and drop game where a user can build something using the images I provide. I will have images in a menu that the user can click and drag to the building area. The user will be able to add however many instances of that image as they want.
I was able to get part of it working. So far, I can click the image and drag it around, and create as many instances as I want. However, I cannot click and drag the image once I have placed it.
When I do a trace to see what the name is, it says that all the new instances are named hillChild1. I tried to make them named hillChild1, hillChild2, etc., but that doesn't seem to work either... not sure that is an issue, though.
Here's my code:
thesubmenu1.hill.addEventListener(MouseEvent.MOUSE_DOWN, onDown);
stage.addEventListener(MouseEvent.MOUSE_UP, onUp);
var myImage:Sprite = Sprite(new Hill_mc());
var i:Number=0; i++;
function onDown(e:MouseEvent):void {
var myImage:Sprite = Sprite(new Hill_mc());
myImage.name = "hillChild"+i;
addChild(myImage);
myImage.x = mouseX;
myImage.y = mouseY;
myImage.startDrag();
myImage.buttonMode = true;
}
function onUp(e:MouseEvent):void {
var myImage:Sprite = Sprite(new Hill_mc());
myImage.stopDrag();
myImage.name = "hillChild";
}
stage.addEventListener(MouseEvent.CLICK, traceName);
function traceName(event:MouseEvent):void { trace(event.target.name); }
myImage.getChild(myImage).addEventListener("mouseDown", mouseDownHandler);
stage.addEventListener("mouseUp", mouseUpHandler);
function mouseDownHandler (e:MouseEvent):void{
myImage.startDrag();
}
function mouseUpHandler (e:MouseEvent):void{
myImage.stopDrag();
}
I am new to StackOverflow and also Actionscript 3, if it isn't apparent.
Your issue is likely that you are creating a new instance on mouse up (when what you want is a reference to instance that was already created on mouse down). Also, you never add a click listener to you new objects. Add the mouse up listener to stage only after the mouse down (then remove the listener in the mouse up).
thesubmenu1.hill.addEventListener(MouseEvent.MOUSE_DOWN, createCopy);
var i:int=0;
var tmpImage:Sprite; //to store which image is being dragged currently
function createCopy(e:MouseEvent):void {
tmpImage = new Hill_mc();
tmpImage.name = "hillChild"+(i++); //increment every copy
addChild(tmpImage);
tmpImage.x = mouseX;
tmpImage.y = mouseY;
tmpImage.startDrag();
tmpImage.buttonMode = true;
tmpImage.addEventListener(MouseEvent.MOUSE_DOWN, onDown); //add the mouse down to this new object
stage.addEventListener(MouseEvent.MOUSE_UP, onUp); //since the mouse is currently down, we need to listen for mouse up to tell the current copy to stop dragging
}
//this will be called when click a copy
function onDown(e:MouseEvent):void {
tmpImage = Sprite(e.currentTarget); //get a reference to the one that was clicked, so we know which object to stop dragging on the global mouse up.
stage.addEventListener(MouseEvent.MOUSE_UP, onUp); //listen for the mouse up
tmpImage.startDrag();
}
function onUp(e:MouseEvent):void {
stage.removeEventListener(MouseEvent.MOUSE_UP,onUp); //now that the mouse is released, stop listening for mouse up
tmpImage.stopDrag(); //stop dragging the one that was clicked
}

AS3 remove tween before MOTION_FINISH via the movieclip

I've been fumbling with this issue for a bit. I've got a lovely little tooltip movieclip that follows the user's mouse for a few seconds before it removes itself. My problem is that if there is one already there I remove it, however, I cannot seem to remove the MOTION_FINISH event and it still fires and possibly deletes a new tooltip.
What I want is to essentially put in a line item such as var tween(smallhelp_panel).deleteAll();
I saw a tweenlight function killtweensof(mc); However I've used the tweens I've incorporated below throughout my 30k lines of AS3 code.
Here is my tooltip handler. I call it with a simple
Main_Warning("Please don't forget to save!",5);
My movieclip is a 'smallhelp_panel' and I check if it already exists and remove it. However, the alpha and MOTION_FINISH tweens still exist and cause issues with any new smallhelp_panels.
public function Main_Warning( the_text:String, myTimer:int = 4){
if(smallhelp_panel != null){
stage.removeChild( smallhelp_panel );
removeEventListener(Event.ENTER_FRAME, trackmouse);
smallhelp_panel = null;
}
smallhelp_panel = new small_help();
smallhelp_panel.name = "myWarning";
smallhelp_panel.x = mouseX - 50;
smallhelp_panel.y = mouseY + 15;
smallhelp_panel.helptext.text = the_text;
stage.addChild( smallhelp_panel );
addEventListener(Event.ENTER_FRAME, trackmouse);
var myTween:Tween;
myTween = new Tween(smallhelp_panel, "alpha", None.easeOut, 1, 0, myTimer, true);
tweenholder = myTween;
tweenArray.push(tweenholder);
myTween.addEventListener(TweenEvent.MOTION_FINISH, removeTween);
}
That is my Tooltip handler.
for reference purposes my tween remover is:
public function removeTween(e:TweenEvent = null):void{
e.target.removeEventListener(TweenEvent.MOTION_FINISH, removeTween);
if(smallhelp_panel != null){
removeEventListener(Event.ENTER_FRAME, trackmouse);
stage.removeChild( smallhelp_panel );
smallhelp_panel = null;
}
}
and my mouse tracker that moves the tooltip with the mouse is a simple:
public function trackmouse(e:Event):void{
smallhelp_panel.x = mouseX - 50;
smallhelp_panel.y = mouseY + 15;
}
That's because you've added your MOTION_FINISH event listener to the tween, not to the panel. You remove the panel, if one already exists, but the tween still exists in the tweenholder and tweenArray variables - and fires a MOTION_FINISH event, when its calculations are finished. Your event listener method doesn't know which tween the event came from, and correctly removes the help panel.
To fix this, either remove the tween and event listener along with the help panel in your Main_Warning function, or modify the removal block in your event listener method:
public function removeTween(e:TweenEvent = null):void{
e.target.removeEventListener(TweenEvent.MOTION_FINISH, removeTween);
// --- this will check if the Tween belongs to the panel on the stage!
if (smallhelp_panel && e.target.obj == smallhelp_panel ) {
// ---
removeEventListener(Event.ENTER_FRAME, trackmouse);
stage.removeChild( smallhelp_panel );
smallhelp_panel = null;
}
// --- NOW remove the tween from the array (all of them should be removed after use)
tweenArray.splice (tweenArray.indexOf (e.target), 1);
}
I don't understand exactly why you would need both a tweenholder and a tweenArray variable, though ;)
Your TweenEvent is still being listened for. You never remove the previous listener, so it will fire when the tween calculations are complete.
I assume tweenholder is declared somewhere global? (Like the other answer here, I'm confused as to your need of declaring a new tween, storing it in another reference and adding that reference to an array...) If so, try this:
public function Main_Warning( the_text:String, myTimer:int = 4){
tweenholder.removeEventListener(TweenEvent.MOTION_FINISH,removeTween);
if(smallhelp_panel != null){
...

mouse up event not working properly

can anyone please help me on this.
attached is the fla which has a part of code i am working on for a project.
with help of mouse you can draw a circle on the image, but for some reasons the mouse up event does not work. it works fine when the eventlisteners is attached to the stage, but does not work when its attached to the movieclip.
also how can i restrict the circle to be drawn only inside the movieclip which is a rectangle.
here is the code
const CANVAS:Sprite = new Sprite();
var _dragging:Boolean = false;
var _corner:Point;
var _corner2:Point;
menFront.addEventListener(MouseEvent.MOUSE_DOWN, setAnchor);
menFront.addEventListener(MouseEvent.MOUSE_UP, completeRect);
function setAnchor(e:MouseEvent):void{
trace("mouse down");
if(!_dragging){
CANVAS.graphics.clear();
_corner = new Point(e.stageX, e.stageY);
_dragging = true;
menFront.addEventListener(MouseEvent.MOUSE_MOVE, liveDrag);
}
}
function completeRect(e:MouseEvent):void{
trace("mouse up");
if(_dragging){
_dragging = false;
menFront.removeEventListener(MouseEvent.MOUSE_MOVE, liveDrag);
CANVAS.graphics.lineStyle(0, 0, 0);
CANVAS.graphics.beginFill(0x222222,.5)
_corner2 = new Point(e.stageX, e.stageY);
trace(Point.distance(_corner,_corner2).toFixed(2));
CANVAS.graphics.drawCircle(_corner.x, _corner.y, Point.distance(_corner,_corner2));
addChild(CANVAS);
}
}
function liveDrag(e:MouseEvent):void{
CANVAS.graphics.clear();
CANVAS.graphics.lineStyle(0, 0x999999);
_corner2 = new Point(e.stageX, e.stageY);
//trace(Point.distance(_corner,_corner2).toFixed(2));
CANVAS.graphics.drawCircle(_corner.x, _corner.y, Point.distance(_corner,_corner2));
addChild(CANVAS);
}
If you add the MouseEvent.MOUSE_UP to the object that you are dragging, the event will only fire if the item is underneath the mouse at the moment the MOUSE_UP happens, but since you're updating the item with MOUSE_MOVE, that's a race-condition between when the MOUSE_UP happens and when the MOUSE_MOVE happens.
To avoid such problems you want to guarantee that you receive the MOUSE_UP whenever MOUSE_UP fires, during your live-update cycle. To do that, add the event listener to the stage just when it's needed, something like this:
menFront.addEventListener(MouseEvent.MOUSE_DOWN, setAnchor);
function setAnchor(event:MouseEvent):void
{
stage.addEventListener(MouseEvent.MOUSE_UP, completeRect);
// your other functionality
}
function completeRect(event:MouseEvent):void
{
stage.removeEventListener(MouseEvent.MOUSE_UP, completeRect);
// your other functionality
}
so that your completeRect doesn't get called inadvertently if you're clicking elsewhere.
Hope This Helps

actionscript 3, removeEventListener not working properly

I've made this game with event listener (coordinates) on mouse position when a click occurs (to move the character).
I've another event listener for drag and drop (to combine items) that works pretty well.
function stageDown (event:MouseEvent):void
{
stage.removeEventListener(MouseEvent.CLICK, coordinates);
MovieClip(getChildByName(event.target.name).toString()).startDrag();
MovieClip(getChildByName(event.target.name).toString()).addEventListener(MouseEvent.MOUSE_UP,stageUp);
...stuff..
}
function stageUp(event:MouseEvent):void
{
stopDrag();
...stuff...
stage.addEventListener(MouseEvent.CLICK, coordinates);
}
In the function stageDown I remove the event listener for the movement(coordinates), than I add it again at the end of the function stageUp (when you release the mouse button and the drag is complete)
But is not working, when I release the drag the character start moving, can't understand why
I don't fully understand the why (something to do with how Click events are tracked I suppose) but it is the 'normal' behavior.
Here is how I've handled this in the past. Basically you can add a higher priority click listener to the object you are dragging and cancel the event there: (see code comments)
//Assuming you have something like this in your code/////////
stage.addEventListener(MouseEvent.CLICK, coordinates);
function coordinates(event:MouseEvent):void {
trace("STAGE CLICK"); //whatever you do here
} ///////////////////////////////////////////////////////////
//add your mouse down listener to your object
someObject.addEventListener(MouseEvent.MOUSE_DOWN, stageDown);
//ALSO add a click listener to your object, and add it with higher priority than your stage mouse click listener
someObject.addEventListener(MouseEvent.CLICK, itemClick, false, 999);
function itemClick(event:MouseEvent):void {
//stop the event from reaching the lower priority stage mouse click handler
event.stopImmediatePropagation();
trace("Item CLICK");
}
function stageDown (event:MouseEvent):void
{
Sprite(event.currentTarget).startDrag();
//listen for the mouse up on the stage as sometimes when dragging very fast there is slight delay and the object may not be under the mouse
stage.addEventListener(MouseEvent.MOUSE_UP,stageUp, true);
//if you don't care about mouse up on stage, then you can just forget the mouse up listener and handler altogether and just stop drag on the itemClick function.
}
function stageUp(event:MouseEvent):void
{
//remove the stage mouse up listener
stage.removeEventListener(MouseEvent.MOUSE_UP,stageUp, true);
trace("UP");
stopDrag();
}