Disable stop the object when it is hit on the right position - actionscript-3

I want to be a drag and drop game.When I will to start drag my object be a small size to a drop position.It is performed correctly.But when drag object is touched hit point, it could not stop drag. Can I stop drag?Here is my code.....
drag_6.buttonMode = true;
drag_6.addEventListener(MouseEvent.MOUSE_UP, dropMe6);
drag_6.addEventListener(MouseEvent.MOUSE_DOWN, dragMe6);
var back_6X:Number = back_6.x;
var back_6Y:Number = back_6.y;
var hit_6X:Number = hit_6.x;
var hit_6Y:Number = hit_6.y;
var drop_6H:Number = drop_6.height;
var drop_6W:Number = drop_6.width
function dragMe6(event:MouseEvent)
{
drag_6.startDrag();
drag_6.height=drop_6H;
drag_6.width=drop_6W;
setChildIndex(drag_6, this.numChildren-1);
}
function dropMe6(event:MouseEvent)
{
drag_6.stopDrag();
if (drag_6.hitTestObject(drop_6))
{
TweenMax.to(drag_6, 0.5, {x:hit_6X, y:hit_6Y, ease:Cubic.easeOut});
drag_6.mouseEnabled = false;
SoundMixer.stopAll();
drag_6.alpha = 0 ;
hit_6.alpha = 1;
drag_6.buttonMode = false;
}
else
{
TweenMax.to(drag_6, 0.5, {x:back_6X, y:back_6Y, ease:Bounce.easeOut});
SoundMixer.stopAll();
}
}

The reason is the mouseup event is not firing at all. The best a simple way to add event listeners to stage. `
drag_6.buttonMode = true;
drag_6.addEventListener(MouseEvent.MOUSE_DOWN, dragMe6);
var back_6X:Number = back_6.x;
var back_6Y:Number = back_6.y;
var hit_6X:Number = hit_6.x;
var hit_6Y:Number = hit_6.y;
var drop_6H:Number = drop_6.height;
var drop_6W:Number = drop_6.width
function dragMe6(event:MouseEvent)
{
stage.addEventListener(MouseEvent.MOUSE_UP, dropMe6);
drag_6.startDrag();
drag_6.height=drop_6H;
drag_6.width=drop_6W;
setChildIndex(drag_6, this.numChildren-1);
}
function dropMe6(event:MouseEvent)
{
stage.removeEventListener(MouseEvent.MOUSE_UP, dropMe6);
drag_6.stopDrag();
if (drag_6.hitTestObject(drop_6))
{
TweenMax.to(drag_6, 0.5, {x:hit_6X, y:hit_6Y, ease:Cubic.easeOut});
drag_6.mouseEnabled = false;
SoundMixer.stopAll();
drag_6.alpha = 0 ;
hit_6.alpha = 1;
drag_6.buttonMode = false;
}
else
{
TweenMax.to(drag_6, 0.5, {x:back_6X, y:back_6Y, ease:Bounce.easeOut});
SoundMixer.stopAll();
}
}
Make sure the global stage object is accessible.

Related

Actionscript 3 drag and drop multiple objects to target with well done

The drag and drop works, however, I have no idea how to create an if statement that goes to the next scene when all movieclips have been placed on the target.
I've tried placing the instance names in an if statement with the hittestobject however, no luck.
import flash.events.TouchEvent;
import flash.ui.Multitouch;
import flash.ui.MultitouchInputMode;
import flash.display.MovieClip;
/* Touch and Drag Event
Allows the object to be moved by holding and dragging the object.
*/
var objectoriginalX:Number;
var objectoriginalY:Number;
Multitouch.inputMode = MultitouchInputMode.TOUCH_POINT;
var lemons:Array = [lemon1_mc, lemon2_mc, lemon3_mc, lemon4_mc, lemon5_mc];
for each(var lemonMC:MovieClip in lemons)
{
lemonMC.buttonMode = true;
lemonMC.addEventListener(TouchEvent.TOUCH_BEGIN, pickobject);
lemonMC.addEventListener(TouchEvent.TOUCH_END, dropobject);
lemonMC.startX = lemonMC.x;
lemonMC.startY = lemonMC.y;
}
var fl_DragBounds:Rectangle = new Rectangle(0, 0, stage.stageWidth, stage.stageHeight);
function pickobject(event:TouchEvent):void
{
event.target.startTouchDrag(event.touchPointID, false, fl_DragBounds);
event.target.parent.addChild(event.target);
objectoriginalX = event.target.x;
objectoriginalY = event.target.y;
}
function dropobject(event:TouchEvent):void
{
if(event.target.hitTestObject(target_mc)){
event.target.buttonMode = false;
event.target.x = target_mc.x;
event.target.y = target_mc.y;
event.target.visible = false;
} else {
event.target.x = event.target.startX;
event.target.y = event.target.startY;
event.target.buttonMode = true;
}
}
var melons:Array = [melon1_mc, melon2_mc, melon3_mc, melon4_mc, melon5_mc, melon6_mc, melon7_mc];
for each(var melonMC:MovieClip in melons)
{
melonMC.buttonMode = true;
melonMC.addEventListener(TouchEvent.TOUCH_BEGIN, pickobject2);
melonMC.addEventListener(TouchEvent.TOUCH_END, dropobject2);
melonMC.startX = melonMC.x;
melonMC.startY = melonMC.y;
}
var fl_DragBounds2:Rectangle = new Rectangle(0, 0, stage.stageWidth, stage.stageHeight);
function pickobject2(event:TouchEvent):void
{
event.target.startTouchDrag(event.touchPointID, false, fl_DragBounds2);
event.target.parent.addChild(event.target);
objectoriginalX = event.target.x;
objectoriginalY = event.target.y;
}
function dropobject2(event:TouchEvent):void
{
if(event.target.hitTestObject(target_null)){
event.target.buttonMode = false;
event.target.x = target_mc.x;
event.target.y = target_mc.y;
event.target.visible = false;
} else {
event.target.x = event.target.startX;
event.target.y = event.target.startY;
event.target.buttonMode = true;
}
}
How about adding a counter that is equal to number of objects to drag, then every time you drop object (and detect if it was on target) you decrements the counter and at the end of the function you check if it's 0?
An easy way to do this would be to remove your lemons/melons from their arrays when they pass the hit test. Then check if each array is empty and continue to the next scene should that be the case.
You can actually reduce redundant code and use the same function (dropobject) for both lemons and melons.
function dropobject(event:TouchEvent):void {
//Figure out which array this belongs to (is it a lemon or a melon)
var array:Array; //the array the dropped item belongs to
var hitMC:MovieClip; //the hit object for the lemon or melon
if(lemons.indexOf(event.currentTarget) > -1){ //if the lemon array contains the currentTarget
array = lemons;
hitMC = target_mc;
}else{
array = melons;
hitMC = target_null;
}
if(event.currentTarget.hitTestObject(hitMC)){
event.currentTarget.buttonMode = false;
event.currentTarget.x = hitMC.x;
event.currentTarget.y = hitMC.y;
event.currentTarget.visible = false;
//remove the item from it's array
array.removeAt(array.indexOf(event.currentTarget));
//check if there are any items left
if(lemons.length < 1 && melons.length < 1){
//both arrays are empty, so move on
play(); //or however you want to move on
}
}
}
Getting more advanced, a better way to do this would be to make a base class for your lemons, melons and anything else you want to drag in the future. Then you can add the dragging functionality into that base class and add properties for the hit target and an event for when it's hit it's target. This would give you one code base that can be easily applied to any library object.

Drag Game Puzzle with custom dispatch event

i'm creating a drag puzzle game, and i need to resolve an issue, two to be exact:
a) Make a check if all the objects from dragArray variable are in the same place as the ones from matchArray.
b) If so, then display a button and play a sound file. (The button is *play_btn* and it plays a sound file when clicked, but i also need the sound to be played once the puzzle is solved so to speak.)
Would add some visual aid, but the forums says I need reputation.
Looking forward for some assistance.
The game is based on this tutorial.
var dragArray:Array = [p1, p2, p3, p4, p5, p6, p7, p8, p9];
var matchArray:Array = [p1_n, p2_n, p3_n, p4_n, p5_n, p6_n, p7_n, p8_n, p9_n];
var currentClip:MovieClip;
var startX:Number;
var startY:Number;
for(var i:int = 0; i < dragArray.length; i++) {
dragArray[i].buttonMode = true;
dragArray[i].addEventListener(MouseEvent.MOUSE_DOWN, item_onMouseDown);
matchArray[i].alpha = 0.2;
}
function item_onMouseDown(event:MouseEvent):void {
currentClip = MovieClip(event.currentTarget);
startX = currentClip.x;
startY = currentClip.y;
addChild(currentClip); //bring to the front
currentClip.startDrag();
stage.addEventListener(MouseEvent.MOUSE_UP, stage_onMouseUp);
}
function stage_onMouseUp(event:MouseEvent):void {
stage.removeEventListener(MouseEvent.MOUSE_UP, stage_onMouseUp);
currentClip.stopDrag();
var index:int = dragArray.indexOf(currentClip);
var matchClip:MovieClip = MovieClip(matchArray[index]);
if(currentClip.hitTestObject(matchClip)) {
//a match was made! position the clip on the matching clip:
currentClip.x = matchClip.x;
currentClip.y = matchClip.y;
//make it not draggable anymore:
currentClip.removeEventListener(MouseEvent.MOUSE_DOWN, item_onMouseDown);
currentClip.buttonMode = false;
} else {
//match was not made, so send the clip back where it started:
currentClip.x = startX;
currentClip.y = startY;
}
}
var my_sound:Sound = new Sound();
my_sound.load(new URLRequest("sounds/song.mp3"));
var my_channel:SoundChannel = new SoundChannel();
play_btn.addEventListener(MouseEvent.CLICK, playSound);
function playSound(event:MouseEvent):void{
my_channel = my_sound.play();
}
You can use a validate function like this one. It will returns true if all drop items are on their targets, false otherwise
function validate(drags:Array, drops:Array):Boolean {
var found:uint = 0
for (var i:uint = 0;i<drags.length;i++ ) {
var drag:MovieClip = MovieClip(drags[i]);
var drop:MovieClip = MovieClip(drops[i]);
found += (drag.hitTestObject(drop)) ? 1 : 0
}
return found == drop.length
}
Then you can use it to check the global interaction :
var result:Boolean = validate(dragArray,matchArray);
if (result) {
// all ok
// play sound...
} else {
// errors
}

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
{
}

Turn this AS3 into an array and work with it

How can I turn this basic function method into an Array and call to easily. Pretty much I am just comparing if objects have become false and then do something...but this just seems like a lot of code for something so easy. any ideas?
var b:Boolean = true;
var i:Boolean = true;
var t:Boolean = true;
var a:Boolean = true;
var m:Boolean = true;
var ii:Boolean = true;
var n:Boolean = true;
var e:Boolean = true;
var s:Boolean = true;
level5_mc.let_b_mc.addEventListener(MouseEvent.CLICK, hitB);
level5_mc.let_i_mc.addEventListener(MouseEvent.CLICK, hitI);
level5_mc.let_t_mc.addEventListener(MouseEvent.CLICK, hitT);
level5_mc.let_a_mc.addEventListener(MouseEvent.CLICK, hitA);
level5_mc.let_m_mc.addEventListener(MouseEvent.CLICK, hitM);
level5_mc.let_ii_mc.addEventListener(MouseEvent.CLICK, hitII);
level5_mc.let_n_mc.addEventListener(MouseEvent.CLICK, hitN);
level5_mc.let_e_mc.addEventListener(MouseEvent.CLICK, hitE);
level5_mc.let_s_mc.addEventListener(MouseEvent.CLICK, hitS);
function hitB(event:MouseEvent){
b=false;
trace("good");
level5_mc.removeChild(level5_mc.let_b_mc);
}
function hitI(event:MouseEvent){
if (b==false){
i=false;
level5_mc.removeChild(level5_mc.let_i_mc);
}
else {
//decrease timer
i=true;
}
}
function hitT(event:MouseEvent){
if (b==false && i==false){
t=false;
level5_mc.removeChild(level5_mc.let_t_mc);
}
else {
//decrease timer
i=true;
}
}
and so forth... edited below
var b=level5_mc.let_b_mc;
var i=level5_mc.let_i_mc;
var t=level5_mc.let_b_mc;
var movieClips:Array = [b,i,t];
var movieClipFlags:Object = {
b:[],
i:[b],
t:[b,i]
};
for each(var mc:MovieClip in movieClips) {
mc.addEventListener(MouseEvent.CLICK,movieClipHit);
}
function movieClipHit(e:MouseEvent) {
var mc:MovieClip = e.target as MovieClip;
if(readyToRemove(mc))
level5_mc.removeChild(mc);
else
trace("Can't remove yet.");
}
function readyToRemove(mc:MovieClip):Boolean {
for each(var mc:MovieClip in movieClipFlags[mc]) {
//if it has parent, it isn't removed yet.
if(mc.parent)
return false;
}
return true;
}
Something like the following should give you some ideas. I haven't tested the code you migt need to make some adjustments depending on your needs.
//put other movies clips in this array too.
var movieClips:Array = [level5_mc.let_b_mc,level5_mc.let_i_mc];
var movieClipFlags:Object = {
level5_mc.let_b_mc:[],
level5_mc.let_i_mc:[level5_mc.let_b_mc],
level5_mc.let_t_mc:[level5_mc.let_b_mc,level5_mc.let_i_mc]
//put other movie clips here too with the movie clips that need to be removed in the array
};
foreach(var mc:MovieClip in movieClips) {
mc.addEventListener(MouseEvent.CLICK,movieClipHit);
}
private function movieClipHit(e:MouseEvent) {
var mc:MovieClip = e.target as MovieClip;
if(readyToRemove(mc))
level5_mc.removeChild(mc);
else
trace("Can't remove yet.");
}
private function readyToRemove(mc:MovieClip):Boolean {
foreach(var mc:MovieClip in movieClipFlags[mc]) {
//if it has parent, it isn't removed yet.
if(mc.parent)
return false;
}
return true;
}
Hope it helps.

Actionscript 3.0 Keyboard event listener error

I have two functions, rotate and unrotate, and I used a keyboard event listener to listen for key_Down A and B but i get and error:
1119: Access of possibly undefined property A through a reference with static type Class.
ti.border = true
ti.addEventListener(TextEvent.TEXT_INPUT, onInput);
function onInput(event:TextEvent):void {
if(ti.text.search('a')!=-1) load_image("http://i54.tinypic.com/anom5d.png", "ottefct");
else if(ti.text.search('b')!=-1) load_image("http://i53.tinypic.com/2dv7dao.png", "rnd");
else if(ti.text.search('c')!=-1) load_image("http://i51.tinypic.com/m8jp7m.png", "ssd");
}
var loaded_images:Dictionary = new Dictionary();
function load_image(url:String, id_name:String)
{
var loader:Loader = new Loader();
loader.name = id_name;
var url_req:URLRequest = new URLRequest(url);
loader.contentLoaderInfo.addEventListener(Event.COMPLETE, onLoadingComplete);
loader.load(url_req);
}
function onLoadingComplete(evt:Event):void
{
var img_name:String = evt.currentTarget.loader.name
var spr_box:Sprite = new Sprite();
spr_box.addChild(evt.currentTarget.loader);
spr_box.mouseChildren = false;
spr_box.doubleClickEnabled = true;
spr_box.addEventListener(MouseEvent.MOUSE_DOWN, drag);
spr_box.addEventListener(MouseEvent.MOUSE_UP, drop);
spr_box.addEventListener(KeyboardEvent.KEY_DOWN, rotate);
spr_box.addEventListener(KeyboardEvent.KEY_DOWN, unrotate);
spr_box.width = 124;
spr_box.height = 180;
spr_box.x = 430;
spr_box.y = 425;
this.addChild(spr_box);
loaded_images[img_name] = spr_box;
}
function drag(evt:MouseEvent):void
{
evt.currentTarget.startDrag()
}
function drop(evt:MouseEvent):void
{
evt.currentTarget.stopDrag()
}
function rotate(evt:KeyboardEvent):void
{
if (evt.keyCode==Keyboard.D) {
evt.currentTarget.rotation = 90
}
}
function unrotate(evt:KeyboardEvent):void
{
if (evt.keyCode==Keyboard.A) {
evt.currentTarget.rotation = 0
}
}
Well - you are only referencing prop A in one spot and its throwing an undefined error. So, either your not linking the Keyboard class properly... or...?
At any rate - you can also use numeric assignment to capture keystrokes. In this case:
function rotate(evt:KeyboardEvent):void
{
if (evt.keyCode == 68) { //"D"
evt.currentTarget.rotation = 90
}
}
function unrotate(evt:KeyboardEvent):void
{
if (evt.keyCode == 65) { //"A"
evt.currentTarget.rotation = 0
}
}
They are all laid out pretty clearly right here.