transform a mouse event (drag) to a touch screen event - actionscript-3

I'm trying to transform my mouse event to a swipe event (for touch screen), but after hours and hours, I can't figure out how to do it.
Here's my code :
public function DraggedItem(stageRef:Stage, grabbedItem:Object){
this.stageRef = stageRef;
toolbar = Engine.toolbar;
usableItems = Engine.usableItems;
inv = Engine.inv;
puzzle = Engine.puzzle;
player = Engine.player;
linesData = Engine.linesData;
inv.draggingItem = true;
Mouse.hide();
itemRef = getDefinitionByName(grabbedItem.displayName.toLowerCase()+"Proper");
draggedItem = new itemRef;
stageRef.addChild(draggedItem);
draggedItem.displayName = grabbedItem.displayName;
if (grabbedItem.lookTag)
draggedItem.lookTag = grabbedItem.lookTag;
draggedItem.x = mouseX + x;
draggedItem.y = mouseY + y;
draggedItem.scaleX = itemScale;
draggedItem.scaleY = itemScale;
stageRef.addEventListener(MouseEvent.MOUSE_MOVE, dragItem, false, 0, true);
stageRef.addEventListener(Event.ENTER_FRAME, itemHitTest, false, 0, true);
draggedItem.addEventListener(MouseEvent.CLICK, itemClick, false, 0, true);
}
private function dragItem(e:MouseEvent):void{
draggedItem.x = mouseX + x;
draggedItem.y = mouseY + y;
}
On my computer, when I click on my inventory and the select a item, I can drag it where I want on the screen (the item become the mouse, and the mouse is hide).
So I'm trying to transform it for touch screen.
I've tried to using "event.stageX" instead of "mouseX", but it didn't work.
I've tried to replace mouseEvent by TransformGestureEvent, but it didn't work.
And When I click on my item in the inventory, the item stay stuck in the middle corner of the screen and I can't move it. (it's happening just when I'm exporting with adobe Air for Android, if I'm exporting in swf it's working just fine).
Do you know how I can do it ?
Here's a video of the problem : uploaded.net/file/lkwqsgm7
Thank you very much !

You can try using the built in gestures of flash.
Multitouch.inputMode = MultitouchInputMode.GESTURE; //you need to enable gestures
stageRef.addEventListener(TransformGestureEvent.GESTURE_SWIPE , onSwipe);
function onSwipe (e:TransformGestureEvent):void{
if (e.offsetX == 1) {
//swiped right
draggedItem.x += someValue;
}else{
//swiped left
draggedItem.x -= someValue;
}
}
Keep in mind, the swipe event is only for general swiping, if you're actually just dragging an object from position A to position B, this is not a swipe, but well...a drag. I'm not clear on what you're actually trying to accomplish.
If you do want to do multitouch, just change your MouseEvents to TouchEvents. Mouse_Down is equivalent to TOUCH_BEGIN and mouse up is equivalent to TOUCH_END.

Related

Video scrubber not stopping after scrubbing

I've created a custom scrub bar which means the scrub handle is being drug along a specific axis. I can drag the handle just fine, but when I start dragging and move the mouse off the handle and release, the handle does not stop. I have to be over the actual handle when I stop dragging in order for it to stop.
That wouldn't be an issue, but the handle is pretty small so it would be nice if I could figure out a way to stop dragging the handle when the mouse is on or off.
A good example is Youtube. You can start dragging the handle and while moving the handle move your mouse off and release. The handle stops even though you're not releasing directly over it.
bottom_bar.scrubber.handle.addEventListener(MouseEvent.MOUSE_DOWN, scrubberDown);
bottom_bar.scrubber.handle.addEventListener(MouseEvent.MOUSE_UP, scrubberUp);
function scrubberDown(e:Event):void
{
flvPlayback.pause();
var object = e.target;
var bounds:Rectangle = new Rectangle();
bounds.x = e.currentTarget.width - bottom_bar.scrubber.handle.width;
bounds.y = e.currentTarget.y;
bounds.width = bottom_bar.scrubber.width - (bottom_bar.scrubber.handle.width);
bounds.height = bottom_bar.scrubber.height - bottom_bar.scrubber.handle.height;
object.startDrag(false, bounds);
}
function scrubberUp(e:Event):void
{
var _math:Number =((bottom_bar.scrubber.handle.x) / (960) * flvPlayback.totalTime);
var object = e.target;
object.stopDrag();
flvPlayback.seek(_math);
flvPlayback.play();
}
Register MouseEvent.MOUSE_UP in scrubberDown handler, and for the stage, so user can stop dragging in any position.
bottom_bar.scrubber.handle.addEventListener(MouseEvent.MOUSE_DOWN, scrubberDown);
//bottom_bar.scrubber.handle.addEventListener(MouseEvent.MOUSE_UP, scrubberUp);
function scrubberDown(e:Event):void {
stage.addEventListener(MouseEvent.MOUSE_UP, scrubberUp);
//Your current code
}
function scrubberUp(e:Event):void {
stage.removeEventListener(MouseEvent.MOUSE_UP, scrubberUp);
var _math:Number =((bottom_bar.scrubber.handle.x) / (960) * flvPlayback.totalTime);
bottom_bar.scrubber.handle.stopDrag();
flvPlayback.seek(_math);
flvPlayback.play();
}

Double Click - Fullscreen

I'm working on a video player and I though that it could be usefull to include the fullscreen's function when the user double click on the stage.
I've done some research but I'm stuck right now because of this line:
player.display.mouseChildren = false;
I read somewhere that I have to include this before those:
player.display.doubleClickEnabled = true;
player.display.addEventListener(MouseEvent.DOUBLE_CLICK, doubleClickFS, false, 0, true);
However, if mouseChildren is false, the children are not working ^^'.
Do you have an idea to fix this ?
Thank you,
Lea.
Here is a cheat solution.
You just make a full size sprite over all layers, and set it to alpha 0.
Add double click listener to the sprite and set mouseChildren to false, this won't effect your player.
I just screwed up the event flow in AS3. Here is also a cheat solution.
Make your own DOUBLE_CLICK event use CLICK event.
var lastClickTime:Number = 0;
mc.addEventListener(MouseEvent.CLICK, function(e:MouseEvent):void
{
var curTime:Number = getTimer();
if( curTime - lastClickTime < 300 )
{
trace("Double Click");
}
else
{
trace("Single Click");
}
lastClickTime = curTime;
});

Actionscript Image with clickable spots

Can any one help in suggesting a solution for the following:
i have a large image, consider it as a map, i want to put this image in a viewer that is smaller than the image and i have to be able to scroll the image by clicking and dragging it.
and i want to put in this image a clickable spots in a specified x and y coordinated, and be able to click the spots.
when clicking any spot in the image, the image will be changed with a new spots.. and so on..
can you help in suggesting what is the best object to load the image in and be able to do all the mentioned points.
Thanks in advance.
This is easier than you think. You have a few goals to consider:
"i want to put this image in a viewer that is smaller than the image": You dont need anything special to do this. The concept of this is simply that you have a mask overlay where you want the large image visible.
var viewer:Sprite = new Sprite; //200x200
var imageMask:Sprite = new Sprite; //200x200
var imageContainer:Sprite = new Sprite; //400x500
imageContainer.mask = imageMask;
viewer.addChild(imageContainer);
//this will allow you to visibly see only 200x200 of the
//imageContainer at any time
"i have to be able to scroll the image by clicking and dragging it": This is a little more logic as the imageContainer will have to move in the -(negative) direction of the mouse. Add some listeners to check for mouse actions, and drag as required.
var allowDrag:Boolean = false;
imageContainer.addEventListener(MouseEvent.MOUSE_DOWN, onMouseDown);
imageContainer.addEventListener(MouseEvent.MOUSE_UP, onMouseUp);
imageContainer.addEventListener(MouseEvent.MOUSE_MOVE, onMouseMove);
function onMouseDown(e:Event):void{
allowDrag = true;
}
function onMouseUp(e:Event):void{
allowDrag = false;
}
function onMouseMove(e:Event):void{
//return if not dragging
if(!allowDrag) return;
//move the imageContainer in a -(negative) direction of the mouse
//use an index relative to the size of the viewer and imageContainer
var speed:Number = 0.5;
imageContainer.x -= (viewer.width/imageContainer.width)*speed;
imageContainer.y -= (viewer.height/imageContainer.height)*speed;
//clean the positions so the image remains within the viewer
if(imageContainer.x > 0) imageContainer.x = 0;
if(imageContainer.x < -viewer.width) imageContainer.x = -viewer.width;
if(imageContainer.y > 0) imageContainer.y = 0;
if(imageContainer.y < -viewer.height) imageContainer.y = -viewer.height;
}
"i want to put in this image a clickable spots in a specified x and y coordinated, and be able to click the spots": This also requires a little more thinking. In this case what you want to do is create [hotspots] on the image that are clickable, when clicked = do actions.
//USAGE
//define the click area coords
var clickCoords:Rectangle = new Rectangle();
clickCoords.x = 10; //starts at x 10
clickCoords.y = 10; //starts at y 10
clickCoords.width = 100; //100 wide
clickCoords.height = 100; //100 tall
//add the click listener
var clickArea:Sprite = hotSpot(imageContainer,clickCoords);
clickArea.addEventListener(MouseEvent.CLICK, onHotSoptClick);
//hot spot factory
function hotSpot(target:Sprite,coords:Rectangle):Sprite{
//create the hotspot
var hs:Sprite = new Sprite;
hs.graphics.beginFill(0,0);
hs.graphics.drawRect(0,0,coords.width,coords.height);
hs.graphics.endFill();
//add the hotspot to the target
hs.x = coords.x;
hs.y = coords.y;
target.addChild(hs);
}
function onHotSoptClick(e:MouseEvent):void{
//do something
}
IMPORTANT:
You may want to keep a list of hot spots you create so you can do garbage cleanup, and you plan on dynamically generating hotspots per image... then YOU MUST keep an active list of hot spots and remove when not in use.
You can catch the events MouseDown, MouseUp, MouseMove, MouseOut, on your viewing window, this way you can control exactly what do you want to do.
Here is the pseudo-code:
reset()
{
isDown=false;
downPointX=0;
downPointY=0;
distanceX=0;
distanceY=0;
}
onMouseDown()
{
isDown=true;
downPointX=mouseX;
downPointY=mouseY;
}
onMouseUp()
{
if(distanceX+distanceY==0 and isDown)
click(downPointX,downPointY);
reset();
}
onMouseMove()
{
if isDown then
distanceX=mouseX-downPointX;
distanceY=mouseY-downPointY;
drag(distanceX,distanceY);
endif;
}
onMouseOut()
{
reset();
}
drag(distanceX,distanceY)
{
change your map coordinates
}
click(downPointX,downPointY)
{
if(inSpot(downPointX,downPointY)==true)
changeMap();
endif;
}
changeMap()
{
change your maps and spots
}
avoid implementing any event for your spots sprites or you can get unexpected results.
You can check these for more information
http://help.adobe.com/en_US/FlashPlatform/reference/actionscript/3/flash/display/Sprite.html#eventSummary

Drag finger on X axis of mc, changes value - AS3

I have a rectangle mc. When the user swipes his finger slowly right on the mc, a value needs to increase, If moved left, it will decrease. 1 to 100 is the limit. How do I do that? i don't want a visible slider. It should not matter where the finger is on the mc, only which direction the finger is moving.
EDIT: I am currently looking into the touchEvent and am researching the web for solutions.
You'll want to keep track of whether or not a swipe is happening and, if so, where it started.
var dragging:Boolean = false;
var startX:Number = 0.0;
Then you'll use simple event listeners to keep track of this bool.
mc.addEventListener(MouseEvent.MOUSE_DOWN, mouseDown);
mc.addEventListener(MouseEvent.MOUSE_UP, mouseReleased);
function mouseDown(event:MouseEvent):void
{
dragging = true;
startX = event.localX;
}
function mouseReleased(event:MouseEvent):void
{
dragging = false;
}
Then you're MOUSE_MOVE touch event can handle all the logic:
stage.addEventListener(MouseEvent.MOUSE_MOVE, mouseMove); // Notice this event is on stage, not mc.
function mouseMove(event.MouseEvent):void
{
value += event.localX - startX;
if (value < 0) value = 0;
if (value > 100) value = 100;
}
Happy Holidays!

AS3 CS5 How can I refresh the stage after a SOUND_COMPLETE?

I have an educational game where children hear a sound and then have to choose the correct image out of 3 images.
When they want to hear the sound again they can press a speaker button.
The 3 images are movieclips (named card1, card2 and card3) dynamically added to the stage, with the buttonMode = true.
Whenever they press the speaker to hear the sound again or get feedback if they press the wrong image, I remove the mouse_events from the cards for the duration of the sound. I also set the buttonMode = false, so the children know they won't be able to click while the sound is playing.
On SOUND_COMPLETE I add the eventListeners again. Now the buttonMode = true again as well.
I want to do a refresh of the screen like event.updateAfterEvent(); so the cursor changes to a hand, should they have placed it on one of the cards. BUT the event.updateAfterEvent() can't be attached to a SOUND_COMPLETE, you can only use it after an interaction event like MOUSE or GESTURE.
tldr; How can I refresh my stage so the cursor changes back to a hand after the SOUND_COMPLETE ?
HereĀ“s some of the code:
function speakerClick(event:MouseEvent):void
{
remLst();
SoundMixer.stopAll();
cardCnl = gameSnd.play();
cardCnl.addEventListener(Event.SOUND_COMPLETE, sndComplete);
}
function sndComplete(event:Event):void
{
cardCnl.removeEventListener(Event.SOUND_COMPLETE, sndComplete);
addLst();
}
function addLst():void
{
for (var i:int = 1; i < 4; i++)
{
var card:Card = getChildByName("card" + i) as Card;
card.addEventListener(MouseEvent.CLICK, fnClick);
card.addEventListener(MouseEvent.MOUSE_OVER, fnOver);
card.addEventListener(MouseEvent.MOUSE_OUT, fnOut);
card.buttonMode = true;
}
}
In your addLst function, when cycling through the 4 cards, you could check for the current mouse position, and check if it is inside the boundaries of one of the cards.
It could work like this:
if ( mouseX > card.x && mouseX < (card.x + card.width)
mouseY > card.y && mouseY < (card.y + card.height))
{
Mouse.cursor = MouseCursor.BUTTON;
}
I am not 100% sure though if buttonMode changes it back to Arrow when the mouse leaves the object. I usually don't use buttonMode.