AS3: is it possibile to set the cursor x and y? - actionscript-3

is it possibile to set the position of the mouse cursor? This is what I would like to do: when the user presses the mouse button over a movieclip, the movieclip starts dragging and on enterframe the cursor is positioned in the middle of the movieclip (don't tell me about lockcenter because I can't use it this way since my movieclip registration point is set at its top left corner). Basically, I would like to be able to force the cursor to reach the center of the movieclip when the user clicks it. Is this possible?

I don't have proof, but I think that you are not allowed to take control of the cursor like that.
An alternative would be to hide the actual mouse cursor, and add a custom cursor instead that you could positioned relative to the real cursor position, or in the center of your drag target if that would be easier. The problem would be that you have no way of knowing the exact appearance of the user's cursor.

In other words you're looking for this functionality: SetCursorPos.
You cannot control the cursor with Flash. You'll have to solve it otherwise - what about setting your movieclip's registration point to the center?!

I don't think that's possible. The mouse coordinates are read only.
However I would suggest any of these instead :
Hide the mouse using Mouse.hide();.
Make your own pointer in the location of the mouse.
Control this pointer as per your wish.
or
When the mouse button is pressed, move the movieclip itself, if
possible.

Expanding on loxxy's response:
Instead of moving the mouse cursor to the center of the object with lockCenter, you can manually move the object to be centered about the mouse cursor when the MouseEvent.MOUSE_DOWN event is fired on the object (just before you call startDrag on the object)
Here's a simple example:
package {
import flash.display.Sprite;
import flash.events.MouseEvent;
public class Main extends Sprite{
public function Main() {
var drag_object:Sprite = new Sprite()
drag_object.graphics.beginFill(0xFF0000, .5);
drag_object.graphics.drawRect(0, 0, 50, 50);
drag_object.graphics.endFill();
drag_object.addEventListener(MouseEvent.MOUSE_DOWN, onMouseDown);
drag_object.addEventListener(MouseEvent.MOUSE_UP, onMouseUp);
drag_object.x = 200;
drag_object.y = 300;
addChild(drag_object);
}
private function onMouseDown(e:MouseEvent):void {
var obj:Sprite = e.target as Sprite;
obj.x = e.stageX - (obj.width * .5);
obj.y = e.stageY - (obj.height * .5);
obj.startDrag();
}
private function onMouseUp(e:MouseEvent):void {
var obj:Sprite = e.target as Sprite;
obj.stopDrag();
}
}
}

Related

How do you handle mouseover events with overlapping TextFields?

I have a horizontal stack of buttons that represent tabs, and each button has a TextField inside of it that is larger than the dimensions of the button so that they overlap. Like this (the dotted line is a TextField and the red box is the area where mousing over does not work due to the overlap):
Each of these buttons is an instance of a TabButton, which has a class definition like this:
package src
{
import flash.display.MovieClip;
import flash.events.Event;
import flash.events.MouseEvent;
import flash.text.TextField;
public class TabButton extends MovieClip
{
// Stage Instances
public var mcHitZone:MovieClip;
public var mcText:TextField;
public function TabButton()
{
super();
addEventListener(Event.ADDED_TO_STAGE, onAddedToStage, false, 0, true);
}
private function onAddedToStage(e:Event):void
{
removeEventListener(Event.ADDED_TO_STAGE, onAddedToStage);
// Disable mouse input on everything except for the hit zone since that's where mouse handling should be done.
mcText.mouseEnabled = false;
mcHitZone.addEventListener(MouseEvent.ROLL_OVER, onMouse, false, 0, true);
}
private function onMouse(e:MouseEvent):void
{
trace("Mouse event: " + name + " " + e.type);
}
}
}
Each TabButton has a mcHitZone that I'm attaching the mouse handler to, which is the black area on the above image. Since the TextField is much larger than the button itself, it needs to be completely ignored for mouse input handling so I'm turning it off with mcText.mouseEnabled = false;, which seems to work when mousing within a single button, but when mousing over the overlap area (the red box) the TextField will block mouse input from the other button.
Is there any way to make this work so that the TextField does not block mouse input on anything that it overlaps with?
I've uploaded the FLA and AS that I've been testing this with here. If you run it, it will trace when you roll over a particular button. If you try to mouse over the red area of the leftmost button then it won't work.
Your button have three movieClips, mcHitZone, mcText, and TabButton itself.
So when you place two buttons close, the up tabButton(not it's Child mcText) will affect the under tabButton.
I advise your tabButton not extends movieClip, just use the mcHitZone as Button's skin, then add it to your stage.
Just as the comment say, you can also make the tabButton's mouseEnabled false. I mixed up mouseEnabled and mouseChildren.

AS3 parallax effect in Flash banner preventing Movieclip buttons from functioning

I'm building a rich media Flash banner ad. I have 3 to 4 round MovieClip buttons that move around with an AS3 parallax effect. It looks like an EnterFrame loop creates the effect in AS3. But the individual Movieclip buttons won't function when I assign MouseEvent Click events. I want the parallax movement to stop and playhead advance to a specific label on main timeline when the MC's are clicked.
I'm sure this can be done but I lack the expertise. Here is the code:
//add an event listener to trigger every frame
addEventListener(Event.ENTER_FRAME, onFrame);
//set a constant that marks the centre of the stage
//the stage is 600 x 400, so we halve that
const stageCentre:Point=new Point(180,300);
//set an easing constant
const ease:Number=0.2;
function onFrame(e:Event) {
//create a point to store the distances the mouse is from the centre
var mouseOffset:Vector3D=new Vector3D(stageCentre.x-mouseX,stageCentre.y-mouse Y, 0);
//move each background layer by a different percentage of offset
//the easing constant is used here to create smoother results
//foreground moves the most; 75% of the mouse offset
clip1_mc.x+=(stageCentre.x+mouseOffset.x*0.70 - clip1_mc.x)*ease;
clip1_mc.y+=(stageCentre.y+mouseOffset.y*0.50 - clip1_mc.y)*ease;
//mid-ground moves a medium amount; 50% of the mouse offset
clip2_mc.x+=(stageCentre.x+mouseOffset.x*1.00 - clip2_mc.x)*ease;
clip2_mc.y+=(stageCentre.y+mouseOffset.y*1.00 - clip2_mc.y)*ease;
//background moves the least; 25% of mouse offset
clip3_mc.x+=(stageCentre.x+mouseOffset.x*1.75 - clip3_mc.x)*ease;
clip3_mc.y+=(stageCentre.y+mouseOffset.y*1.00 - clip3_mc.y)*ease;
}
//Click on button to go to and Play "kelsey" label (this does NOT work)
clip1_mc.kelsey_btn.addEventListener(MouseEvent.CLICK, fl_MouseClickHandler);
function fl_MouseClickHandler(event:MouseEvent):void
{
MovieClip(root).gotoAndStop("kelsey");
}
Make sure the clip1_mc is on the top most layer, it is probably overlapped by other clips that are catching up the mouse click events.
If you have buttons in all layers you will need to disable mouse events for everything except the buttons. For example, if you have a "button" and a "background" in each movieclip and you want to only keep the buttons clickable, do something like this inside of that movieclip:
background.mouseEnabled = false;
background.mouseChildren = false;
This way the background will not listen for any mouse interactions
add removeEventlistener when the mouse clicks the movieclip
clip1_mc.kelsey_btn.addEventListener(MouseEvent.CLICK, fl_MouseClickHandler);
function fl_MouseClickHandler(event:MouseEvent):void
{
this.removeEventListener(Event.ENTER_FRAME, onFrame);
MovieClip(root).gotoAndStop("kelsey");
}

Clicking on a movieclip inside another movieclip on AS3

Alright, what i need it's simple but its driving me crazy, i want to know if AS3 detects my mouse inside a movieclip.
For example, i have a movieclip instanced "BEframes" which is inside movieclip "BE1" and i want to put him inside a new movieclip instanced "roll". So the order would be roll > BE1 > BEframes.
I want to know if flash will only detect "roll" or he will detect all movieclips, thank you,
for(i=1;i<=77;i++){
var str:String =("BE" + i);
this[str].BEframes.gotoAndStop(i);
this[str].addEventListener(MouseEvent.CLICK, clique);
this[str].addEventListener(MouseEvent.ROLL_OVER, over);
this[str].addEventListener(MouseEvent.ROLL_OUT, out);
}
function clique(evt:MouseEvent):void{
var botao:String = evt.currentTarget.name.toString();
var num:String = botao.replace("BE", "");
parede_esquerda.gotoAndStop(num);
}
function out(evt:MouseEvent):void {
evt.currentTarget.gotoAndPlay("out");
}`enter code here`
function over(evt:MouseEvent):void {
evt.currentTarget.gotoAndPlay("over");
}
*
Probably, you should use MOUSE_OVER and MOUSE_OUT instead of ROLL_OVER and ROLL_OUT.
this[str].addEventListener(MouseEvent.MOUSE_OVER, over);
this[str].addEventListener(MouseEvent.MOUSE_OUT, out);
To avoid receiving mouseEvent for movieClips set mouseEnabled to false, i.e if you don't want clip roll's mouse event setroll.mouseEnabled = false so that the object below will receive mouseEvent

how to check, whether user is dragging the object rightside or leftside in actionscript 3

I am creating a flash based application, where user can change a rectangle shapes, width and height using mouse drag. here is a quick prototype image.
let me explain briefly: In the image you can see, i am having a tiny red rectangle, which one now sitting is starting position and user can drag that only 100px to right side. The idea is when, user is dragging that to right, i want to rectangle also expand right side with that, like a flexible box. if he is dragging back then it will return with that.
so, the doubt is: how will check, whether user is dragging right side or left side. so based on that we can update the rectangle width.
Here is the code :
import flash.geom.Rectangle;
import flash.events.MouseEvent;
var horizRect:Rectangle = new Rectangle(scrollPathHoriz.x, scrollPathHoriz.y, 100, 0);
var horizCount:Number;
//event listener for the anchor point.
scrollHoriz.addEventListener(MouseEvent.MOUSE_DOWN, dragScroller);
stage.addEventListener(MouseEvent.MOUSE_UP, dropScroller);
//mouse down and mouse up event handler.
function dragScroller(evt:MouseEvent):void {
horizCount= scrollHoriz.x;
scrollHoriz.startDrag(false, horizRect);
scrollHoriz.addEventListener(MouseEvent.MOUSE_MOVE, calculateHorizPixel);
}
function dropScroller(evt:MouseEvent):void {
scrollHoriz.stopDrag();
scrollHoriz.removeEventListener(MouseEvent.MOUSE_MOVE, calculateHorizPixel);
}
function calculateHorizPixel(evt:MouseEvent):void {
horizCount ++;
trace(horizCount);
}
Since you are already saving the starting x position,
You simply need the difference between starting position & current position :
function calculateHorizPixel(evt:MouseEvent):void {
var dx = scrollHoriz.x - horizCount;
trace(dx);
}
A negative value of dx indicates that scrollHoriz moved left, else right.
Or try this:
import flash.events.MouseEvent;
stage.addEventListener(MouseEvent.MOUSE_MOVE, moveMouse);
function moveMouse(event:MouseEvent):void
{
var dx:Number = mouseX - stage.stageWidth/2;
trace(dx);
}

AS3 collision dectection mouse movement

I am making a game which uses collision detection with the mouse.
The player is a custom mouse cursor when the mouse collies with an object the mouse is moved to the coordinates X0,Y0. The code I have used to achieve this is below. However when the mouse is moved to X0,Y0 after a collision when the mouse is moved it starts back where the collision took place rather than moving from the top of the screen.
import flash.events.Event;
var cursor:MovieClip;
function initializeMovie ():void {
cursor = new Cursor();
addChild (cursor);
cursor.enabled = false;
Mouse.hide ();
stage.addEventListener (MouseEvent.MOUSE_MOVE, dragCursor);
}
function dragCursor (event:MouseEvent):void{
cursor.x = this.mouseX;
cursor.y = this.mouseY;
}
initializeMovie ();
this.addEventListener( Event.ENTER_FRAME, handleCollision)
function handleCollision( e:Event ):void{
if(cursor.hitTestObject( wall )){
cursor.x = 0
cursor.y = 0
}
}
Create a button at the 0, 0 coord that is required to click to continue again. Then your user will have to move the mouse to to that spot where you can continue to have the custom cursor track your mouse.
When you reset the position of cursor object you aren't moving the actual mouse position, I don't believe you can actual do what you're trying to (that is write to the mouse position to move the users cursor, I believe this would require system specific code, like C# or I believe Objective C and Cocoa or Carbon on the Mac side).
http://www.kirupa.com/forum/showthread.php?354641-Possible-to-set-mouse-position-in-flash
Here's a way you would do it on Mac apparently
https://developer.apple.com/library/mac/documentation/GraphicsImaging/Reference/Quartz_Services_Ref/Reference/reference.html#//apple_ref/c/func/CGWarpMouseCursorPosition
And a way on Windows
Set Mouseposition in WPF
And a way on Linux (Although this only has AIR support up to 2.6)
How to set the mouse position under X11 (linux desktop)?
So if you implemented both of those solutions and are packaging as an AIR app you could make this work, but otherwise I'm pretty sure it's impossible.