add MouseEvent.CLICK to starling image - actionscript-3

i have a container have many image with scroll , i add TouchEvent.TOUCH as event listener instead of MouseEvent.CLICK , because starling doesn't support MouseEvent .
the problem is when i navigate between images it will listener to TouchEvent while i don't need to this ? is there any solution instead of TouchEvenet ?
the code :
private function onComplete (event:flash.events.Event):void
{
bitmapData = Bitmap(LoaderInfo(event.target).content).bitmapData;
var newImage:Image = Image.fromBitmap(Bitmap(LoaderInfo(event.target).content));
newImage.height = 154;
newImage.width = 180;
addChild(newImage);
newImage.addEventListener(starling.events.TouchEvent.TOUCH,image_clickHandler);
}
private function image_clickHandler(event:starling.events.TouchEvent):void
{
var touch:Touch = event.getTouch(stage);
if (touch != null)
{
if (touch.phase == TouchPhase.BEGAN)
{
//some code
}
}
}

It's a good practice not to attach event listeners to every objects on scene . You should attach only one listener to stage and after that read touch event's target property.Here the example from "Inroducing Starling" book:
private function onClick(e:TouchEvent):void
{
var touches:Vector.<Touch> = e.getTouches(this);
var clicked:DisplayObject = e.currentTarget as DisplayObject;
if ( touches.length == 1 )
{
var touch:Touch = touches[0];
if ( touch.phase == TouchPhase.ENDED )
{
trace ( e.currentTarget, e.target );
}
}
}
Here , currentTarget is Stage , and target will be your image

Related

AS3 Works but I get a ReferenceError: Error #1069 Property startDrag not found

I am trying to make a simple project when you click a button a draggable MovieClip is added to the stag and when you click it releases the MovieClip to the X/Y where you clicked, you can then pickup the MovieClip and drag it into a bin (MovieClip) where it destroys itself. The code is working great I can make multiple Movieclips with the button and they are all destroyed when I drag them in the bin however I don't like having "Error Codes".
import flash.events.MouseEvent;
var rubbish:my_mc = new my_mc();
btntest.addEventListener(MouseEvent.CLICK, makeRubbish);
function makeRubbish (event:MouseEvent):void {
addChild(rubbish);
rubbish.x = mouseX - 10;
rubbish.y = mouseY - 10;
rubbish.width = 50;
this.addEventListener(MouseEvent.MOUSE_DOWN, startDragging);
rubbish.buttonMode = true;
}
function stopDragging (event:MouseEvent):void {
rubbish.stopDrag()
event.target.addEventListener(MouseEvent.CLICK, startDragging);
rubbish.buttonMode = true;
if (event.target.hitTestObject(bin))
{
trace("hit");
event.target.name = "rubbish";
removeChild(getChildByName("rubbish"));
}
}
function startDragging (event:MouseEvent):void {
event.target.startDrag();
this.addEventListener(MouseEvent.CLICK, stopDragging);
}
Some Pointers:
The target property of an Event is not always what it seems. It actually refers to the current phase in the event bubbling process. Try using the currentTarget property.
I would also recommend tying the stopDragging method to the stage, as sometimes your mouse won't be over the drag as you're clicking.
I would use the MOUSE_UP event as opposed to a CLICK for standard dragging behaviour.
When dragging, keep a global reference to the drag in order to call the stopDrag method on the correct object.
Try This:
import flash.events.MouseEvent;
var rubbish:my_mc = new my_mc();
var dragging:my_mc;
btntest.addEventListener(MouseEvent.CLICK, makeRubbish);
function makeRubbish (event:MouseEvent):void {
addChild(rubbish);
rubbish.x = mouseX - 10;
rubbish.y = mouseY - 10;
rubbish.width = 50;
rubbish.addEventListener(MouseEvent.MOUSE_DOWN, startDragging);
rubbish.buttonMode = true;
}
function stopDragging (event:MouseEvent):void {
this.stage.removeEventListener(MouseEvent.MOUSE_UP, stopDragging);
if(dragging !== null){
dragging.stopDrag();
if (event.currentTarget.hitTestObject(bin)){
removeChild(dragging);
}
dragging = null;
}
}
function startDragging (event:MouseEvent):void {
dragging = event.currentTarget as my_mc;
dragging.startDrag();
this.stage.addEventListener(MouseEvent.MOUSE_UP, stopDragging);
}

Trace x,y of movieclip that is animated through timeline

I am trying to trace the position of a movieclip(that contains a simple timeline animation inside) so that I can attach another movieclip to be able to follow it.
How can I do that?
empty = the movieclip that contains timeline animation
mc = the movieclip I want to follow the "empty" movieclip
empty.addEventListener(Event.ENTER_FRAME, onMove);
function onMove(event:Event):void {
var mc:MovieClip = new SmokeTween();
mc.x = empty.x;
mc.y = empty.y;
mc.rotation = Math.round(Math.random() * 70);
this.addChild(mc);
}
Actually I went into "empty" mc and and used this code and seems to work fine:
this.addEventListener ( Event.ENTER_FRAME, traceFrame );
function traceFrame ( e : Event ) : void
{
if (e.target.currentFrame > 0){
MovieClip(parent.parent).mc.x = e.target.x;
}
}
I imagine that empty doesn't animate, so you need to use the root's ENTER_FRAME event instead of empty's:
addEventListener(Event.ENTER_FRAME, onMove); // no "empty."
function onMove(event:Event):void {
var mc:MovieClip = new SmokeTween();
mc.x = empty.x;
mc.y = empty.y;
mc.rotation = Math.round(Math.random() * 70);
this.addChild(mc);
}
As your project gets bigger, you'll also find that recycling objects becomes important (especially in Flash). Keep an array of SmokeTweens and keep recycling them, instead of creating new ones and letting them delete themselves.
Actually I went into "empty" mc and and used this code and seems to work fine:
this.addEventListener ( Event.ENTER_FRAME, traceFrame );
function traceFrame ( e : Event ) : void
{
if (e.target.currentFrame > 0){
mc.x = e.target.x;
}
}

ActionScript 3 Mouse Move event not dispatching

Script problem is that every movieclip dispatch down and up mouse event but mouse move event is not dispatching by some movieclips, which is an unexpected behaviour while I have traced the down event and it trace successfully on every object
also recommend your feedback on my code, thanks.
private function loadPurchasedClip(){
var decorationItem:String;
var lastItemIndex:uint = this.getChildIndex(tree1);
var item:Sprite;
for(var a in purchasedItems){
for(var b in purchasedItems[a]){
if(purchasedItems[a][b].item=='shed'){
item = new shed();
} else {
var ClassDefinition:Class = loadedDecorationItem.purchaseItem(purchasedItems[a][b].item) as Class;
item = new ClassDefinition();
}
item.x = purchasedItems[a][b].posX;
item.y = purchasedItems[a][b].posY;
item.addEventListener(MouseEvent.MOUSE_DOWN,function(e:MouseEvent){
Mouse.cursor = "hand";
e.target.startDrag(false);
dusbin.visible = true;
item.addEventListener(MouseEvent.MOUSE_MOVE,trashMe);
});
item.addEventListener(MouseEvent.MOUSE_UP,function(e:MouseEvent){
Mouse.cursor = "auto";
e.target.stopDrag();
externalPhpCall(e);
dusbin.visible = false;
if(trashClip){
removeChild(trashClip);
trashClip = null;
}
});
item.mouseChildren = false;
// if item is fence or flowers then move them behind the tree
if(
String(purchasedItems[a][b].item).indexOf('fence')!=-1
||
String(purchasedItems[a][b].item).indexOf('flower')!=-1
){
addChildAt(item,lastItemIndex);
lastItemIndex++;
} else {
addChildAt(item,this.numChildren-2);
}
purchasedNameAr[getChildIndex(item)] = purchasedItems[a][b].item;
}
}
Can't be sure, but I think it's probably that you're expecting a clip to continue to dispatch MouseEvent.MOUSE_MOVE events even once the mouse has left the clip - this won't happen, it's only whilst the local mouse pointer co-ordinates (ie yourClip.mouseX/mouseY) intersect the graphics of the clip itself that it will fire - even when dragging a clip, it can't be guaranteed that it will dispatch a MOVE event.
Let's suppose your clips are all on the root, which means you have access to 'stage' - you could do this:
replace:
item.addEventListener(MouseEvent.MOUSE_MOVE,mouseMove);
with:
stage.addEventListener(MouseEvent.MOUSE_MOVE,mouseMove);
...but you should remember to remove that event when necessary (use stage again, in case mouse is not released over the clip):
stage.addEventListener(MouseEvent.MOUSE_UP,endMove);
//Don't use anon function as won't have stage reference:
function endMove(e:MouseEvent):void {
//The rest of your code, then:
stage.removeEventListener(MouseEvent.MOUSE_MOVE,mouseMove);
}
private function loadPurchasedClip(){
var decorationItem:String;
var lastItemIndex:uint = this.getChildIndex(tree1);
var item:Sprite;
var Move:Boolean
for(var a in purchasedItems){
for(var b in purchasedItems[a]){
if(purchasedItems[a][b].item=='shed'){
item = new shed();
} else {
var ClassDefinition:Class = loadedDecorationItem.purchaseItem(purchasedItems[a][b].item) as Class;
item = new ClassDefinition();
}
item.x = purchasedItems[a][b].posX;
item.y = purchasedItems[a][b].posY;
item.addEventListener(e:Event.ENTER_FRAME, onEnterFrame);
item.addEventListener(MouseEvent.MOUSE_DOWN,function(e:MouseEvent){
Mouse.cursor = "hand";
e.target.startDrag(false);
Move = true
dusbin.visible = true;
});
item.addEventListener(MouseEvent.MOUSE_UP,function(e:MouseEvent){
Mouse.cursor = "auto";
e.target.stopDrag();
externalPhpCall(e);
dusbin.visible = false;
if(trashClip){
removeChild(trashClip);
trashClip = null;
}
});
item.mouseChildren = false;
// if item is fence or flowers then move them behind the tree
if(
String(purchasedItems[a][b].item).indexOf('fence')!=-1
||
String(purchasedItems[a][b].item).indexOf('flower')!=-1
){
addChildAt(item,lastItemIndex);
lastItemIndex++;
} else {
addChildAt(item,this.numChildren-2);
}
purchasedNameAr[getChildIndex(item)] = purchasedItems[a][b].item;
}
function onEnterFrame(e:Event):void{
if(Move){
// what ever here
{
}

Flash AS3 hit test go to next frame

I have a object that can be dragged into another object. I have set up a hit test for the collision. When the collision occurs I would like to progress to the next frame however, I have to click on the draggable object for it to do so. I would like it to move to the next frame right away without clicking. Is there anyway to fix this?
I mean after I have dragged the objected to create the collision I need to click on the object again to progress to the next frame. I do not want to have to click on the object again I want it to go to the next frame as the collision occurs.
This is my code
bottle.buttonMode = true;
bottle.addEventListener(MouseEvent.MOUSE_DOWN, drag);
bottle.addEventListener(MouseEvent.MOUSE_UP, drop);
function collision():void{
if(bottle.hitTestObject(hit)){
nextFrame();
}
}
function drag(e:MouseEvent):void{
bottle.startDrag();
collision();
}
function drop(e:MouseEvent):void{
bottle.stopDrag();
}
You should be checking for collisions after the drop, not at the start of the drag:
function collision():void{
if(bottle.hitTestObject(hit)){
nextFrame();
}
}
function drag(e:MouseEvent):void{
bottle.startDrag();
}
function drop(e:MouseEvent):void{
bottle.stopDrag();
collision();
}
Change collision() into an event listener and attach it to bottle.
Try this one ( adapted from Gary Rosenzweig ) :
bottle.buttonMode = true;
bottle.addEventListener( MouseEvent.MOUSE_DOWN, startBottleDrag );
stage.addEventListener( MouseEvent.MOUSE_UP, stopBottleDrag );
function collision():void {
if( bottle.hitTestObject( hit ) ) {
stopBottleDrag();
nextFrame();
}
}
// to keep bottle location as it is when clicked
var clickOffset:Point = null;
function startBottleDrag( e:MouseEvent ) {
clickOffset = new Point( e.localX, e.localY );
bottle.addEventListener( Event.ENTER_FRAME, dragBottle );
}
function stopBottleDrag( e:MouseEvent = null ) {
clickOffset = null;
bottle.removeEventListener( Event.ENTER_FRAME, dragBottle );
}
function dragBottle( e:Event ) {
bottle.x = mouseX - clickOffset.x;
bottle.y = mouseY - clickOffset.y;
collision();
}

flash as3 - prevent object from being used as dropTarget

Is there a way to prevent a flash movieclip (or its children) from being used as a dropTarget? I have objects on the stage which are getting in the way of my determining the underlying stage object where a draggable item is being dropped.
There is no way to prevent a flash movieclip (or its children) from being used as a dropTarget.
You could control it from the other end:
function onMouseUp( e:MouseEvent ):void
{
var obj = evt.target;
var target = obj.dropTarget;
if( target != nonDropAreaMovieClip )
{
obj.stopDrag();
}
}
or if you want the obj to be actually dropped to the backgroundMovieClip, which is behind the nonDropAreaMovieClip, you could calculate the global/local coorinates and just do:
function onMouseUp( e:MouseEvent ):void
{
var obj = evt.target;
var target = obj.dropTarget;
if( target != nonDropAreaMovieClip )
{
obj.stopDrag();
obj.x = //calculated x
obj.y = //calculated y
backgroundMovieClip.addChild( obj );
}
}
I've worked around a similar issue by creating movieclips that are transparent and placing them over the drop regions, or by creating a layer with a transparent object as the topmost layer to prevent the children (in the movieclip) from becoming the dropTarget.