How to drag and drop multiple objects to specific targets? - actionscript-3

I am very new to AS3. Of course just ignore the reset button for now. I know my code is big and clunky but I don't mind that for now as it is easily understood by me.
I am trying to match a yellow ball with the yellow goal and green to green and so on.
However every time I try to drag a second object I just can't, the object is stuck, I hear that is the problem with AS3/Flash and the only simple way to solve it is to drag it off the screen which is something I don't want to do.
yellowBall.addEventListener(MouseEvent.MOUSE_DOWN, mouseDowny)
redBall.addEventListener(MouseEvent.MOUSE_DOWN, mouseDownr)
blueBall.addEventListener(MouseEvent.MOUSE_DOWN, mouseDownb)
greenBall.addEventListener(MouseEvent.MOUSE_DOWN, mouseDowng)
yellowBall.addEventListener(MouseEvent.MOUSE_UP, mouseUpy)
redBall.addEventListener(MouseEvent.MOUSE_UP, mouseUpr)
blueBall.addEventListener(MouseEvent.MOUSE_UP, mouseUpb)
greenBall.addEventListener(MouseEvent.MOUSE_UP, mouseUpg)
resetButton.addEventListener(MouseEvent.CLICK, reset);
addEventListener(Event.ENTER_FRAME,enterFrameHandlerr);
function mouseDowny(event:MouseEvent):void {
yellowBall.startDrag();
}
function mouseDownr(event:MouseEvent):void {
redBall.startDrag();
}
function mouseDownb(event:MouseEvent):void {
blueBall.startDrag();
}
function mouseDowng(event:MouseEvent):void {
greenBall.startDrag();
}
function mouseUpy(event:MouseEvent):void {
yellowBall.stopDrag();
}
function mouseUpr(event:MouseEvent):void {
redBall.stopDrag();
}
function mouseUpb(event:MouseEvent):void {
blueBall.stopDrag();
}
function mouseUpg(event:MouseEvent):void {
greenBall.stopDrag();
}
function enterFrameHandlerr(event:Event):void{
if(yellowBall.hitTestObject(yellowHome)){
yellowBall.stopDrag();
yellowBall.x = int(2000);
yellowBall.y = int(60);
}
if(redBall.hitTestObject(redHome)){
redBall.stopDrag();
redBall.x = int(425);
redBall.y = int(60);
}
if(blueBall.hitTestObject(blueHome)){
blueBall.stopDrag();
blueBall.x = int(425);
blueBall.y = int(275);
}
if(greenBall.hitTestObject(greenHome)){
greenBall.stopDrag();
greenBall.x = int(55);
greenBall.y = int(275);
}
}
function reset(event:MouseEvent):void
{
yellowBall.x = int(250);
yellowBall.y = int(250);
};

Related

how to apply condition on all frames?

I want to apply this condition on all frame of adobe flash cs 6:
if(pauseMusic.visible==true) {
playMusic.visible=false;
} else if(pauseMusic.visible==false) {
playMusic.visible=true;
}
But I don't want to copy it one by one of frame actions. What cant I do?
!
create a function in your first frame
if you have more than one frame in your time line, at the first frame insert it:
if(this._condition == null) {
this._condition = function():void {
if(pauseMusic.visible==true) {
playMusic.visible=false;
} else if(pauseMusic.visible==false) {
playMusic.visible=true;
}
}
}
and simply call it in other frames : this._condition();
I agree with #payamsbr but this is shorter...
_condition = function():void {
pauseMusic.visible = !pauseMusic.visible;
}
So you may avoid the if... else... check.
The initial Boolean should be defined to
true or false
So all You have to do is to call
_condition();
[EDIT]
OR in case of uint 1 ->-1 or -1 to 1:
var i:uint=1
function changeUint():void{
i = *=-1
}
changeUint();
-> 1 to -1 or -1 to 1
1 to -1 or -1 to 1...
[/EDIT]
But You want to check if the function exist as he said.
I used this function in first frame:
stage.addEventListener(Event.ENTER_FRAME, onFrameEnter);
function onFrameEnter(Event):void
{
if(pauseMusic.visible==true)
{
playMusic.visible=false;
}
else if(pauseMusic.visible==false)
{
playMusic.visible=true;
}
}

how does the "for each in" loop work?

for some reason this code does not work as intended, I've cut out most of my program but, all I think I need to tell you is that I have a tree array, and I am trying to make collisions with said trees so I thought that this would work:
function collisions(loopEvent:Event):void
{
for each (var a:tree in TreeArray)
{
if (brettMc.right1.hitTestObject(a.stump))
{
rightcoll = false;
}
else
{
rightcoll = true;
}
if (brettMc.left1.hitTestObject(a.stump))
{
leftcoll = false;
}
else
{
leftcoll = true;
}
if (brettMc.up1.hitTestObject(a.stump))
{
upcoll = false;
}
else
{
upcoll = true;
}
if (brettMc.down1.hitTestObject(a.stump))
{
downcoll = false;
}
else
{
downcoll = true;
}
}
}
I am pretty sure that the problem is just that the for each loop is messed up.
I don't see any issue with loop itself
EXCEPT
Is TreeArray actual name of variable? Or it's a Type?
If that's actual variable, can you trace the length of it before loop?

Actions Script 3.0 if else statements

need to do several things by it's click event. I'm a beginner to this, so is there any other way to write this code? by clicking this button, it goes to next frame and according to statement several buttons will be visible or not. I wrote the code this way and it says there are syntax error, but I couldn't find any. Hope you guys understand this and will help me. :) Thank you!
review_btn.addEventListener(MouseEvent.CLICK, review1)
function review1(event:MouseEvent):void{
if(rvw1 == "Correct"){
gotoAndStop(3627);
help1.visible = false
}
else{
gotoAndStop(3627);
help1.visible = true
}
}
review_btn.addEventListener(MouseEvent.CLICK, review2)
function review2(event:MouseEvent):void{
if(rvw2 == "Correct"){
gotoAndStop(3627);
help2.visible = false
}
else{
gotoAndStop(3627);
help2.visible = true
}
}
review_btn.addEventListener(MouseEvent.CLICK, review3)
function review3(event:MouseEvent):void{
if(rvw3 == "Correct"){
gotoAndStop(3627);
help3.visible = false
}
else{
gotoAndStop(3627);
help3.visible = true
}
}
review_btn.addEventListener(MouseEvent.CLICK, review4)
function review4(event:MouseEvent):void{
if(rvw4 == "Correct"){
gotoAndStop(3627);
help4.visible = false
}
else{
gotoAndStop(3627);
help4.visible = true
}
}
review_btn.addEventListener(MouseEvent.CLICK, review5)
function review5(event:MouseEvent):void{
if(rvw5 == "Correct"){
gotoAndStop(3627);
help5.visible = false
}
else{
gotoAndStop(3627);
help5.visible = true
}
}
I'll take an attempt at it. It looks like the only difference is that in each method you need to match up "helpX".visible with "rvwX" equals the string "Correct", where X is a number from 1-5. The gotoAndStop() frame is the same regardless. Also, that all five are meant to be off the same button. I'm going to take an assumption that the clips 'help' are movieclips defined on the stage else if they are from something else I would store them in an array for looping through instead of 'building' the name and finding the reference that way just for clarity.
function review(event:MouseEvent):void {
for(var counter:int = 1; counter < 6; counter++){
this["help" + counter].visible = (this["rvw" + counter] != "Correct");
}
this.gotoAndStop(3627);
}
review_btn.addEventListener(MouseEvent.CLICK, review);
I think you have to do a class with 2 fields: "help" and "rvw" (let me call it "Switcher"). Also it may contain a function of setting visibility (may, not must, this function can also be in your main class):
Switcher.as:
import flash.display.MovieClip;
public class Switcher {
private var help:MovieClip;
private var rvw:String;
public function setVisibility() {
help.visible = !(rvw == "Correct");
}
}
Then you have to make an array of Switcher's objects in your main class and to use only one "review" handler:
function review(event:MouseEvent):void {
for each(var sw:Switcher in switchersArray) {
sw.setVisibility();
}
this.gotoAndStop(3627);
}
The code from previous answer will work correctly, but IMHO, creating an Array (or Vector) of similar objects is better than doing lots of help1, help2, help3 etc variables.

Collecting and identifying functions within an array in actionscript

So, I want to do something where I collect functions to be invoked later when a certain condition is met. E.g.
function doSomething(someArg:Object):void {
if (conditionIsFalse){
operationsToDoWhenConditionIsTrue.push(function(){
doSomething(someArg);
});
}
}
function onConditionBecomingTrue():void {
while (operationsToDoWhenConditionIsTrue.length > 0){
operationsToDoWhenConditionIsTrue.shift()();
}
}
So far so good. However at some point I want to iterate over the operationsToDoWhenConditionIsTrue and identify and replace a function. In pseudo code inside the doSomething method it would be:
function doSomething(someArg:Object):void {
if (conditionIsFalse){
for (var i:int = 0; i<operationsToDoWhenConditionIsTrue; i++){
// pseudo code here
if (typeof operationsToDoWhenConditionIsTrue[i] == doSomething){
operationsToDoWhenConditionIsTrue[i] = doSomething(someArg);
}
}
}
}
Basically if doSomething is called twice, I only want operationsToDoWhenConditionIsTrue to hold the most recent invocation. Obviously since the invocations are wrapped in function(){} all the functions are the same. Is there any way I can accomplish what I want?
Create an identifier function that can identify the operations you want to detect as the same. Assign the ID as a property of the anonymous function that you add to the queue. When you iterate over the queue, record IDs in a collection. Don't execute the operation if it's already in the collection.
function doSomething(someArg:Object):void {
if (conditionIsFalse){
var operation = function(){
doSomething(someArg);
};
operation.operationID = objID(...);
operationsToDoWhenConditionIsTrue.push(operation);
}
}
function onConditionBecomingTrue():void {
var done = {}, f;
while (operationsToDoWhenConditionIsTrue.length > 0){
f = operationsToDoWhenConditionIsTrue.shift();
if (! f.operationID in done) {
done[f.operationID] = true;
f()
}
}
}
As a more efficient variant of this, you can index the queue by IDs, so that a function can be added only once to the queue. However, you will lose control over the order that operations are executed.
var operationsToDoWhenConditionIsTrue:Object = {};
function doSomething(someArg:Object):void {
if (conditionIsFalse){
operation.operationID = ...;
operationsToDoWhenConditionIsTrue[objID(...)] = function(){
doSomething(someArg);
};
}
}
function onConditionBecomingTrue():void {
for (id in operationsToDoWhenConditionIsTrue){
operationsToDoWhenConditionIsTrue[id]();
}
operationsToDoWhenConditionIsTrue = {};
}
If you need to preserve the sequence (so that operations are executed in order they were first added to the queue, or in the order they were last added), create a queue type that can be indexed by both ID and sequence, which you can do by storing mappings between the index types. Note: the following is untested.
class OperationQueue {
protected var queue:Array = [];
protected var idToSeq:Object = {};
public function push(op:Function):void {
/* Orders by last insertion. To order by first insertion,
simply return if the operation is already in the queue.
*/
if (op.id in this.idToSeq) {
var seq = this.idToSeq[op.id];
delete this.queue[seq];
}
this.queue.push(op);
this.idToSeq[op.id] = this.queue.length-1;
}
public function runAll():void {
var op;
while (this.queue.length > 0) {
if ((op = this.queue.shift())) {
delete this.idToSeq[op.id];
op();
}
}
}
}

Movieclips whack-a-mole different cords on moles

I have created a flash whack-a-mole game, and coded the 9 different x and y cordinates the 4 moles can come up on. But I can't code it so that the moles can never have the same x and y cordinates.
I have tried this code: (Barney and mulvarp is two moles. .flytt(); is the command that gives the mole a new place to be.
if( Barney.x == mulvarp.x ){
Barney.flytt();
}
Barney.addEventListener(MouseEvent.CLICK, flyttb);
function flyttb(evt:MouseEvent){
barneyAu.play();
//returnFourPositionsF();
Barney.flytt();
teller-=4;
score.text=teller+"p";
barneyTimer.reset();
barneyTimer.start();
}
mulvarp.addEventListener(MouseEvent.CLICK, flyttm);
function flyttm(evt:MouseEvent){
squishRiktig.play();
mulvarp.flytt();
teller+=1;
score.text=teller+"p";
mulvarpTimer.reset();
mulvarpTimer.start();
}
Kone.addEventListener(MouseEvent.CLICK, flyttmk);
function flyttmk(evt:MouseEvent){
squishRiktig.play();
Kone.flytt();
teller+=2;
score.text=teller+"p";
koneTimer.reset();
koneTimer.start();
}
Baby.addEventListener(MouseEvent.CLICK, flyttmb);
function flyttmb(evt:MouseEvent){
squishRiktig.play();
Baby.flytt();
teller+=3;
score.text=teller+"p";
babyTimer.reset();
babyTimer.start();
}
And this is the .flytt(); function I got inside all of the moles in a actionscript:
function flytt():void{
var flyttUt:int=Math.random() * 8;
if(flyttUt==0){
x=243,30;
y=171,65
}
if(flyttUt==1){
x=630,55;
y=170,25;
}
if(flyttUt==2){
x=999,85;
y=175,55;
}
if(flyttUt==3){
x=244,85;
y=363,85;
}
if(flyttUt==4){
x=632,75;
y=360,20;
}
if(flyttUt==5){
x=996,25;
y=359,50;
}
if(flyttUt==6){
x=228,45;
y=572,40;
}
if(flyttUt==7){
x=627,75;
y=570,95;
}
if(flyttUt==8){
x=650,60;
y=382,05;
}
}
I got an advice on maybe using this and call returnFourPositionsF(); but I am unsure on how to put all the moles into one, since they all have different timers, and I don't want them to change position even tho only one is changing.
var positionA:Array = [ [243.30,171.65],[630.55,170.25],[999.85,175.55],[244.85,363.85],[632.75,360.20],[996.25,359.50],[228.45,572.40],[627.75,57.95],[650.60,382.05] ];
function returnFourPositionsF():Array{
shuffle(positionA);
return [positionA[0],positionA[1],positionA[2],positionA[3]]
}
function shuffle(a:Array) {
var p:int;
var t:*;
var ivar:int;
for (ivar = a.length-1; ivar>=0; ivar--) {
p=Math.floor((ivar+1)*Math.random());
t = a[ivar];
a[ivar] = a[p];
a[p] = t;
}
}
Run your shuffled array through a Dictionary like so.
import flash.utils.Dictionary;
var ar:Array = [[200, 100], [600, 400], [200, 100], [479, 239]];
var dict:Dictionary = new Dictionary();
for(var i:int=0;i<ar.length;i++)
{
dict[ar[i]] = ar[i];
}
var temp:Array = [];
for(var item in dict)
{
temp.push(item);
}
Dictionaries can't have duplicate keys, so each duplicate key is removed. From there, you should be able to use this logic to avoid duplicate positions.