AS3 collision dectection mouse movement - actionscript-3

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.

Related

How to use event Dispatch in actionscript 3.0

I tried using the event dispatch but unable to get clear view of this one, so tell me if anyone know this.
This is Sample Code but i can't understand could you explain elaborate.
var ball:Shape = new Shape();
ball.graphics.beginFill(0xFF0000);
ball.graphics.drawCircle(0, 0, 30);
ball.graphics.endFill();
addChild(ball);
stage.addEventListener(MouseEvent.MOUSE_MOVE, mouseMoveListener);
addEventListener("myCustomEvent", myCustomEventListener);
function mouseMoveListener(event:MouseEvent):void
{
dispatchEvent(new Event("myCustomEvent"));
}
function myCustomEventListener(event:Event):void
{
ball.x = stage.mouseX;
ball.y = stage.mouseY;
}
Think about stage as a big box where magic happens. Stage knows when you resize it, when you press keyboard buttons or when you move mouse on top of it. It does extend EventDispatcher which means it can broadcast stuff (and it does!). You usually don't pay attention to it, but in this particular piece of code you have:
stage.addEventListener(MouseEvent.MOUSE_MOVE, mouseMoveListener);
function mouseMoveListener(event:MouseEvent):void
{
dispatchEvent(new Event("myCustomEvent"));
}
What's going on in here? You're curious about MOUSE_MOVE event and that's why you add listener. Now every time you move your mouse over the stage, stage is going to broadcast (dispatch) event (like : "HEY! Mouse just moved!"). And every time that happens your mouseMoveListener would be called. You can add trace(stage.mouseX, stage.mouseY); inside it and it would trace your mouse position as you move it. You could also move this code
ball.x = stage.mouseX;
ball.y = stage.mouseY;
to that function and your ball would follow mouse cursor.
However what you're doing is:
dispatchEvent(new Event("myCustomEvent"));
Which basically means that you're broadcasting (dispatching) an event now. What event? "myCustomEvent". Now anyone who is interested might listen for it. And somebody is indeed:
addEventListener("myCustomEvent", myCustomEventListener);
function myCustomEventListener(event:Event):void
{
ball.x = stage.mouseX;
ball.y = stage.mouseY;
}
So you're basically listening for this even in the same class and when this even it being dispatched you execute myCustomEventListener function.
Hope that's gonna make it a bit more clearer for you :)

Making multiple objects draggable

I have about 50 symbols that I want to make draggable. Nothing fancy, just the ability to click it and drag it to a different location.
I found as3 code for doing so but when I paste it into my file it gives me errors:
**Error** Scene=Scene 1, layer=Units, frame=1:Line 9: The class or interface 'MouseEvent' could not be loaded.
function mouseDownHandler(evt:MouseEvent):void {
That code is:
// Register mouse event functions
fighter_uk.addEventListener(MouseEvent.MOUSE_DOWN, mouseDownHandler);
fighter_uk.addEventListener(MouseEvent.MOUSE_UP, mouseUpHandler);
fighter_uk.addEventListener(MouseEvent.MOUSE_DOWN, mouseDownHandler);
fighter_uk.addEventListener(MouseEvent.MOUSE_UP, mouseUpHandler);
// Define a mouse down handler (user is dragging)
function mouseDownHandler(evt:MouseEvent):void {
var object = evt.target;
// we should limit dragging to the area inside the canvas
object.startDrag();
}
function mouseUpHandler(evt:MouseEvent):void {
var obj = evt.target;
obj.stopDrag();
}
I'm using flash pro 8, so I tried finding as2 code but couldn't find it.
Also, is there an 'easy' way to code all 50 objects?
I think you're trying to compile AS3 code with AS2 compiler. Try changing your compilation settings to target AS3.
Also you may need to include the class import at the top of your code:
import flash.events.MouseEvent;
To drag 50 objects, add them all on the same container sprite and add the listener to the container sprite only:
var holder:Sprite = new Sprite();
for ( var i:int = 0, l:int = 50; i < l; i++ ) {
var dragee:YOUR_CUSTOM_OBJECT = new YOUR_CUSTOM_OBJECT();
holder.addChild(dragee);
}
addChild(holder);
holder.addEventListener(MouseEvent.MOUSE_DOWN, mouseDownHandler);
holder.addEventListener(MouseEvent.MOUSE_UP, mouseUpHandler);
holder.addEventListener(Event.MOUSE_LEAVE, mouseUpHandler);
var currentDragee:YOUR_CUSTOM_OBJECT = null;
function mouseDownHandler(evt:MouseEvent):void {
currentDragee = evt.target as YOUR_CUSTOM_OBJECT;
if ( currentDragee !== null ) {
currentDragee.startDrag();
holder.addChild(currentDragee); // bring current to front position
}
}
function mouseUpHandler(evt:Event):void {
if ( currentDragee !== null ) currentDragee.stopDrag();
currentDragee = null;
}
YOUR_CUSTOM_OBJECT being the object class you need to drag. Hope it helps!
This page seems to have the answers you are looking for (AS2 drag and drop). If you've already seen it, you'll need to explain why it's not good enough for your needs.
If you want to drag/drop multiple instances in AS2, you can still add the code to the movieClip symbol, export it from the library and load the instances up using attachMovie (all 50 of them). If they are all different, then attach the code as necessary to the clips themselves, or to some function elsewhere that will capture all the clicks and decide what was clicked. This is all very doable in AS2.
Remember you can use your onClipEvent(load) function to set up a lot of the initial lifting.
Here's a sample I made in AS2 for making a node tree. It's all draggable (mouse drag) and zoomable (with mouse Wheel). You can add nodes by clicking on the little down arrow in the node box. Each node is listening for the mouse.
You'll want to look at this section for the most part:
// Enable drag on button press
on (press)
{
startDrag(this);
}
// Stop the drag on release of mouse button
on (release)
{
stopDrag();
}
Besides this, I'm not really sure how your setup looks, so I hope this helps get the ball rolling. (Check the link, there's lots of little gems in there).
Flash Professional 8 only supports ActionScript 2 & 1
You can follow this official URL and learn how to do that in ActionScript 2, but I extremely recommend you to work with ActionScript 3.

Why is my custom cursor slow?

I just made a custom cursor using this code:
function initializeGame():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;
}
initializeGame();
The anchor point is registered in the top left hand corner. The problem that I am having is that the cursor is very laggy. My custom cursor contains no animation, it is just a cross hair. Is there any way to make it move faster like a regular cursor?
There is. You should update the screen (make a redraw) upon every mouse move. Add this to your mouse move listener:
event.updateAfterEvent();
There is a much better way to use custom cursors, check this tutorial -
Working with native mouse cursors in Flash Player 10.2
try using Event.ENTER_FRAME instead of MouseEvent.MOUSE_MOVE if possible. I did it and it made speed much better

Long Touch event with Timer and Confirmation Box for iOS deployment in AS3

I have a project where I have a scrolling list. I would like for my user to be able to "long touch" an item on the list so that they can delete it.
I am developing in Air for iOS using Flash CS6 so I don't really know much about the appropriate MultiTouch gestures for iOS deployment.
In my mind, the animation steps I would like to go like so..
Previously invisible button called btn_delete inside the Item movieclip will appear when Long Touch starts + timer begins
Intermediate step: btn_delete will rotate 90 degrees using TweenMax Rotate (I have this covered)
Final step: when timer reaches it's conclusion, a dialog box / confirmation box will pop up and ask the user if they are sure if they want to delete the item.
So here is some generic code I've written quickly to give you an idea of my structure so far (I've omitted the interlinking listener functions):
function exampleFunction {
_item.addEventListener(TouchEvent.TOUCH_BEGIN, onTouchBegin);
}
//-- Long Press Listener Functions--//
function onTouchBegin(eBegin:TouchEvent) {
trace("start");
}
function onTouchRotate(eEnd:TouchEvent) {
trace("rotation of image");
}
function onTouchEnd(eEnd:TouchEvent) {
trace("end");
}
If anyone has a piece of code they've already written that roughly matches my criteria then please post it!
I would just use MouseEvent for this.
var timer:Timer = new Timer( 500 ); //ms
timer.addEventListener( TimerEvent.TIMER_COMPLETE, timerCompleteHandler );
listItem.addEventListener( MouseEvent.MOUSE_DOWN, mouseDownHandler );
function mouseDownHandler( e:MouseEvent ):void {
timer.start();
stage.addEventListener( MouseEvent.MOUSE_UP, mouseUpHandler );
}
function mouseUpHandler( e:MouseEvent ):void {
//just some clean up to reset the timer and remove the mouse up event listener from the stage
timer.reset();
stage.removeEventListener( MouseEvent.MOUSE_UP, mouseUpHandler );
}
function timerCompleteHandler( e:TimerEvent ):void {
timer.reset();
stage.removeEventListener( MouseEvent.MOUSE_UP, mouseUpHandler );
//do delete actions here
}
So on mouse down, you start your timer and listen for a mouse up event (on the stage and not the component. That is important. If you want to know why, try it on the component and experiment). On mouse up, you reset the timer so the next time you mouse down, it starts at 0 (reset() has the added benefit of stopping the timer). On timer complete, you do the same as in mouse up in addition to your delete code.
I'm using a MouseEvent here just because it behaves identical to TouchEvent (for the most part) in this instance and it could be used on the desktop (meaning you can test in the emulator and you could add this to other projects if you wanted)
UPDATE:
Just reread your question and realized I missed the rotate. For this, just add another timer with a separate complete handler that and in that function, ONLY do the rotation and reset that timer.

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

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