How to match a button to an image? - actionscript-3

I'm creating a image matching program which randomly displays an image at the top. The user needs to choose a matching image from a list of choices, and upon a good match it displays a message, and on a bad match it ends the game.
How can I determine if Elegir1 button is a match to the persoanje 1?
Screenshot:
Code:
DiabloB.addEventListener(MouseEvent.CLICK,Elegir1)
this.addEventListener(Event.ENTER_FRAME, Caida)
function Caida(e: Event) {
T++
if (T == 10) {
T = (Math.random() * 4 + 1)
//this is the random IMG "Personaje 1, Personaje 2 , Personaje 3 , Personaje 4"
refClass = getDefinitionByName("Personaje " + T) as Class;
ref = new refClass()
ref.y = -250
addChild(ref)
T = -500
enemigos.push(ref)
trace(enemigos.length)
setTimeout(function () {
removeChild(ref);
}, 20500);
}
}
// this is the button
function Elegir1(e: MouseEvent) {
}

The MouseEvent gives you access to the currentTarget. The target is a DisplayObject with a name. Create a conditional on click where you compare the two. Then, run your respective functions for each result.

Related

Flash drop and catch game

I am doing a flash mini game that a character need to catch item drop down from top.
The problems i am facing are using timer for those 6 items in an array randomly chose and drop down with random x-axis.
var PointFood:Array = [Melon1,Honey1,Worm1,Clock1,Poison1,Sling1];
//this is the array of items to drop
time = new Timer(60);
//No idea the timer is with frame or second
time.addEventListener(TimerEvent.TIMER,GenerateItem);
time.start();
function GenerateItem(event:TimerEvent):void
{
axis = Math.round(Math.random()*709.7)+44.45;
//this is the random x axis with my scene width
PointFood[i].x = axis;
PointFood[i].y = 0;
if(PointFood[i].y < 600.95)
{
PointFood[i].y += 10;
}
}
//here assign the x and y axis
function ItemType(e:Event):Number
{
i = Math.round(Math.random()*5);
return i;
}
//this is the random for item in array
However the x-axis will be keep changing once the calculation done. Even the items that already exist on screen, their x-axis will also keep changing with the calculation.
Any Solution for this?
There are different ways of dealing with this.
I assume Melon1, Honey1, ... are instances of your own classes.
Add a public property positioned to each of them, like:
public var positioned:Boolean=false;
At the moment your ItemType function just returns a random integer based on the number of objects inside the PointFood array.
Let's integrate a check if the random object is already positioned using it's freshly added positioned property:
function ItemType(e:Event):Number
{
var found:Boolean;
do
{
found = true;
i = Math.round(Math.random() * 5);
if (PointFood[i].positioned)
{
found = false;
}
} while (!found);
return i;
}
Finally modify the GenerateItem function to take the positioned property into account - thus just randomize the position if it's false:
function GenerateItem(event:TimerEvent):void
{
if (PointFood[i].positioned == false)
{
axis = Math.round(Math.random() * 709.7) + 44.45;
//this is the random x axis with my scene width
PointFood[i].positioned = true;
PointFood[i].x = axis;
PointFood[i].y = 0;
}
if (PointFood[i].y < 600.95)
{
PointFood[i].y += 10;
}
}
As a side note:
time = new Timer(60);
means your timer fires every 60 milliseconds - is that the expected behaviour?
Also there might be a little logic problem with your code. As the name GenerateItem implies, I guess this function should just spawn a new object and initialize it's position. Unfortunately it looks like you're abusing this function to do your main game loop as well. I'd recommend splitting this up into two separate functions.

How to create a sequence of clicks in ActionScript?

I am creating a puzzle in which the player have to click on the buttons on the right order or sequence to go to the next level (Scene 2 for example). I don't know how to do it. If any one have any idea to how to achieve this in Action Script.
Thank you
Scene 1:
enter image description here
each number is a button. Now the player has to click in the right order or sequence (1 2 3 4 5 6 7 8) to open the next level (Scene 2)
var checkString:String = "";
//Create event listeners and their functions.
btn1.addEventListener(Mouse.CLICK, oneClick);
btn2.addEventListener(Mouse.CLICK, twoClick);
btn3.addEventListener(Mouse.CLICK, threeClick);
btn4.addEventListener(Mouse.CLICK, fourClick);
btn5.addEventListener(Mouse.CLICK, fiveClick);
btn6.addEventListener(Mouse.CLICK, sixClick);
btn7.addEventListener(Mouse.CLICK, sevenClick);
btn8.addEventListener(Mouse.CLICK, eightClick);
function oneClick(evt:Event):void
{
//In each event listener function, add a letter or
//string to the checkString variable.
checkString += "on";
//Then, see if the string matches or not.
check();
}
function twoClick(evt:Event):void
{
checkString += "tw";
check();
}
function threeClick(evt:Event):void
{
checkString += "th";
check();
}
function fourClick(evt:Event):void
{
checkString += "fo";
check();
}
function fiveClick(evt:Event):void
{
checkString += "fi";
check();
}
function sixClick(evt:Event):void
{
checkString += "si";
check();
}
function sevenClick(evt:Event):void
{
checkString += "se";
check();
}
function eightClick(evt:Event):void
{
checkString += "ei";
check();
}
//If the proper sequence is one, two, three, four, five, six, seven, eight the string would read "ontwthfofisiseei".
function check():void
{
if(checkString == "ontwthfofisiseei")
{
//Clear the checkString for convenience before going on.
clearString();
//CODE TO GO TO NEW FRAME
gotoAndPlay(1, "Scene 3");
}
}
function clearString():void
{
//You will want to have a function for clearing the string.
//This is especially useful if you have a button for "start over."
checkString = "";
}
this the code i used before but it show error in the listener and it doesn't. work
To answer your updated question:
Your error is likely that Mouse.CLICK should be MouseEvent.CLICK.
Your other error is telling you that there is no scene called "Scene 3"
Let's assume you have 8 MovieClips (or buttons) that are on a timeline in Flash/Animate.
One (of many) ways to accomplish this would be the following:
Give each of those buttons an instance name. To make for less code, lets give them the name btn + their respective correct order number - so btn1, btn2, btn3 etc.
You'll need to add a click listener to each button, so they can have something happen when they are clicked.
You could do this 8 times (one for each button): btn1.addEventListener(MouseEvent.CLICK, buttonClick); but to make things simpler, you can just iterate through all the objects on the timeline and add the listener to each object whose name starts with "btn":
var totalBtns:int = 0; //create a var to store how many buttons there are
//loop through each child of the current timeline
var i:int = numChildren;
while(i--){
//if the child's name starts with 'btn'
if(getChildAt(i).name.indexOf("btn") == 0){
//add the click listener
getChildAt(i).addEventListener(MouseEvent.CLICK, buttonClick,false,0,true);
totalBtns++; //increase the total buttons variable by 1
}
}
This also means less work later if you add/remove buttons
You need a way to track when a button was clicked. To accomplish this, we'll use an array.
var clickArray:Array = []; //this creates a new array
//When a button is clicked, you add it to this array
lets create the function that is called when a button is clicked:
function buttonClick(e:Event):void {
//add the item that was just clicked (represented by the event's currentTarget property) to the array
//so if btn1 was just clicked, btn1 would be e.currentTarget
clickArray.push(e.currentTarget);
//now disable the button so it can't be clicked anymore
SimpleButton(e.currentTarget).enabled = false;
//check if all button have been clicked
if(clickArray.length == totalBtns){
//lets go through every item in the array, and see if it's in the right order
var ctr:int = 0; //a counter to keep track of the expected next number var i:int = 0; //iterator for the for loops
for(i=0;i<clickArray.length;i++){
//lets convert everything after the 3rd character of the name to a number - so for btn1, that would be 1
if(parseInt(clickArray[i].name.substring(3)) == ctr + 1){
ctr++; //increment the counter to the next expected number
}else{
break; //leave the for loop early since a click was out of place
}
}
//if the correct order was achieved
if(ctr == totalBtns){
nextScene(); //or however you continue
}else{
//the correct order was NOT acheived
//make all the buttons clickable again
for(i=0;i<clickArray.length;i++){
SimpleButton(clickArray[i]).enabled = true;
}
//reset the array
clickArray = [];
//probably want to tell the user to try again
}
}
}

Actionscript to make movie clip invisible before another is opened

I have a basic flash document that is showing football fixtures spread over several weeks. I have buttons for each week e.g. 'Gameweek 1', 'Gameweek 2' etc.
When the button is pressed, a movie clip is displayed below the buttons which shows the fixtures. The fixtures movie clip is always there but the button changes it to visible.
My problem is...if I have gameweek 1 fixtures showing and then i click on the 'Gameweek 2' button, both sets of fixtures are displayed because the gameweek 1 fixtures are still visible.
When I press a button to display new fixtures, I would like the previously visible movie clip to now be invisible so that just the new fixtures are visible.
Here is my actionscript:
stop();
btn_game1.addEventListener(MouseEvent.CLICK,openGame1);
function openGame1(evt:MouseEvent) {
if (game1.visible){
game1.visible = false;
}else {
game1.visible = true;
}
}
btn_game2.addEventListener(MouseEvent.CLICK,openGame2);
function openGame2(evt:MouseEvent) {
if (game2.visible){
game2.visible = false;
}else {
game2.visible = true;
}
}
I would like to propose a re-factored approach that cuts down on the amount of code and number of event handlers.
You only really need one button handler for all of your buttons. You'll also want to keep track of all of the clips that you're showing/hiding. They can be stored in an array.
You can "connect" a button to a clip by giving them similar names (btn_game1 and game1).
The following code assumes that your buttons are all named btn_gameN and your clips are named gameN (where N is a number):
var clips:Array = [game1, game2, game3, game4];
btn_game1.addEventListener(MouseEvent.CLICK, onGameButtonClicked);
btn_game2.addEventListener(MouseEvent.CLICK, onGameButtonClicked);
btn_game3.addEventListener(MouseEvent.CLICK, onGameButtonClicked);
btn_game4.addEventListener(MouseEvent.CLICK, onGameButtonClicked);
function onGameButtonClicked(e:MouseEvent):void
{
// figure out which button was just clicked by looking at its name
var clipNum:String = e.currentTarget.name.substr("btn_game".length);
// loop through all of your clips ...
for each(var clip:MovieClip in clips)
{
if(clip.name.substr("game".length) == clipNum)
{
// if the name matches, toggle the visibility
clip.visible = !clip.visible;
}
else
{
// if the name doesn't match, set visibility to false
clip.visible = false;
}
}
}
When you show game1 you must hide game2. Likewise for game2.
function openGame1(evt:MouseEvent) {
if (game1.visible) {
game1.visible = false;
}else {
game1.visible = true;
game2.visible = false;
}
}

How to apply drag and drop function to all frames in movie clip? Actionscript3

Each frame contain 1 text field. I apply the code on timeline.
But it only gets applied to the last object, which means that I can only drag and drop the last object. Why?
How can I improve this so that I can drag and drop all objects?
for(var j:uint=0; j<3; j++)
{
var q:Ans = new Ans();
q.stop();
q.x = j * 300+50;// set position
q.y = 500;
var r:uint = Math.floor(Math.random() * q_list.length);
q.qface = q_list[r];// assign face to card
q_list.splice(r,1);// remove face from list;
q.gotoAndStop(q.qface+1);
q.addEventListener(MouseEvent.MOUSE_DOWN, startAnsDrag);
q.addEventListener(MouseEvent.MOUSE_UP, stopAnsDrag);
q.addEventListener(Event.ENTER_FRAME, dragAns);
addChild(q);// show the card
}
//----------------------------drag
// offset between sprite location and click
var clickOffset:Point = null;
// user clicked
function startAnsDrag(event:MouseEvent) :void
{
clickOffset = new Point(event.localX, event.localY);
}
// user released
function stopAnsDrag(event:MouseEvent) :void
{
clickOffset = null;
}
// run every frame
function dragAns(event:Event) :void
{
if (clickOffset != null)
{ // must be dragging
q.x = clickOffset.x+mouseX+135;
q.y = clickOffset.y+mouseY;
}
}
Make a new layer in the timeline just for your drag-and-drop code, which you can remove from your other actionscript. Put the code on the first frame in that layer. Now click on and select the last frame on that layer in which you want the code to be effective (probably the last frame of the MovieClip). Press F5 to draw-out the range of frames which will be affected by the code. Voila!

Resetting score in AS3

I am creating a "dice spinner" game by using Flash action script 3, The rules are if the player rolls a 7 or 11 on first throw then they win but if the user rolls a 2,3 or 12 on the first throw then they lose. If the first throw is 4,5,6,8,9 or 10 then that sum becomes the point and that user has to make a point by rolling again until they make the point (they win) or they throw a 7 (they lose)
I have succesfully created the functions for it to spin, generate a random between 1-6 on each "dice" and to add the points up from total but my problem is if the user wins or lose. I can't figure out on how to reset the points back to zero when the user rerolls from last attempt
The code is blow.
import flash.events.MouseEvent;
spinner_mc.stop();
spinner2_mc.stop();
roll_btn.addEventListener(MouseEvent.CLICK, startspin);
stop_btn.addEventListener(MouseEvent.CLICK, stopspin);
spinner_mc.addEventListener(Event.ENTER_FRAME, spin);
spinner2_mc.addEventListener(Event.ENTER_FRAME, spin)
var spinning = false
function spin(evt){
if(spinning){
spinner_mc.rotation += 5
spinner2_mc.rotation += 5
}
} //end spin function
function startspin(mEvt:MouseEvent){
spinning = true
} //end startspin function
var points:int = 0;
function stopspin (mEvt){
if (spinning){
spinning = false
var nextVal = newVal()
var nextVal2 = newVal2()
var addPoints = nextVal + nextVal2
points += nextVal + nextVal2
spinner_mc.gotoAndStop(nextVal)
spinner_mc.rotation = 0
spinner2_mc.gotoAndStop(nextVal2)
spinner2_mc.rotation = 0
value_txt.text = "point = " + points + ", new value " + addPoints
}
if ((points == 0) && (addPoints == 7) || (addPoints == 11))
{
info_txt.text = "You win!! You rolled a 7 or 11 on first throw!"
}
if ((points == 0) && (addPoints == 2) || (addPoints == 3) || (addPoints == 12))
{
info_txt.text ="You lose! You rolled a 2, 3 or 12 on first throw!"
}
} // end stopspin function
function newVal(){
var temp:int;
temp = Math.random() * 6 + 1;
return temp;
}
function newVal2(){
var temp:int
temp = Math.random() * 6 + 1;
return temp;
}
You need to check for points and addPoints before you add points to the player, while your code has check for points outside the if (spinning) block. This makes your checks go awry even if points is yet zero. So, you first get the spin values, then check, then assign values.
function stopspin(evt:MouseEvent):void {
if (!spinning) return; // this is shorter than wrapping the entire function
// body into a single "if (spinning)" block. If we don't spin, get out
spinning=false;
var nextVal1:int=newVal();
var nextVal2:int=newVal(); // no need of two functions doing the same :)
var addPoints:int=nextVal1+nextVal2;
spinner_mc.gotoAndStop(nextVal1);
spinner_mc.rotation = 0;
spinner2_mc.gotoAndStop(nextVal2);
spinner2_mc.rotation = 0; // give values to spinners
// now check phase
if (points==0) {
// this means first throw.
if ((addPoints==7) || (addPoints==11)) {
// player wins, insert win code
} else if((addPoints==2)||(addPoints==3)||(addPoints==12)) {
// player loses, insert lose code
} else {
points=addPoints; // otherwise making the player do second throw
// add other code, say inform the player that he has to throw again
}
} else {
// not a first throw. We have the "point" in "points" variable right now
if (addPoints==points) {
// player wins with second throw, add win code
points=0; // okay, back to first throw
} else if (addPoints==7) {
// player loses second throw, add relevant code
points=0; // again, back to first throw
} else {
// else no match, oh well.
}
}
}
Also, you should know better how to use event listeners if you want several objects to listen with a single function (in your case, spin). See, right now you have your spin function to update both spinners, and you have it being called twice per frame, so your spinners are spinning at twice the desired speed. You can get the actively listening movie clip using the Event class object passed into the listener, you need to get its target property. So, your listener can be rewritten like this:
function spin(evt:Event):void {
var mc:DisplayObject=evt.target; // the object that's listening
mc.rotation+=5; // now turn it.
}
And last, please place semicolons at the end of each line. Even if AS3 compiler does not strictly require this, it can save you from some really weird mistakes.