nonClickable buttons after loading same FLA 2nd time - actionscript-3

Basically Im trying to make a FLA where if i click a button and close the FLA, next time I load the same FLA, the buttons that have been clicked before , now have an alpha of 0.5 and are nonClickable.
Currently i have only the logic for creating the buttons and saving the data:
private var savedData:SharedObject = SharedObject.getLocal("sharedStorage10");
private var buttonInfoArr:Array = [];
public function Main()
{
for (var i:int = 0; i < 4; i++)
{
var myImage_mc:MovieClip = new MovieClip();
myImage_mc.graphics.beginFill( 0xFFFFFF * Math.random() );
myImage_mc.graphics.drawRect(0,0,100,100);
myImage_mc.graphics.endFill();
myImage_mc.x = 50 + i * (myImage_mc.width + 10);
myImage_mc.y = 100;
myImage_mc.name = "myImage_mc" + i
this.addChild(myImage_mc);
myImage_mc.mouseEnabled = true;
myImage_mc.buttonMode = true;
myImage_mc.addEventListener(MouseEvent.CLICK, onClick);
}
}
private function onClick(ev:MouseEvent):void
{
var thisButton:MovieClip = ev.currentTarget as MovieClip
trace(thisButton.name)
thisButton.alpha = 0.5
thisButton.buttonMode = false;
thisButton.removeEventListener(MouseEvent.CLICK, onClick);
buttonInfoArr.push( thisButton.name );
savedData.data.myArray = buttonInfoArr;
}
But i dont know how to load/use the data and make the buttons (that have been clicked before) start with an alpha of 0.5 and without an EventListener(MouseEvent.CLICK, onClick)
PS:Could it be done without the use of Dictionary, cause i haven`t grasp my mind over it yet.
_EDIT__
to represent my problem in a more detailed way:
So im creating a game in which I collect objects that represent money.After I die in the game i get into the Shop Class in which i can buy different items depending on the money i have.
So lets say that after dying i have enough money to get item1 and item2. So i Click on button1 (representing item1) and button2 (representing item2) (when clicked their alpha gets to 0.5) and start the game again.Ok so now i have 1 life more and i get more money.But suddenly out of nowhere i feel something strange deep in me, something that i have never felt before -> HUNGER,
I shut down the PC (cause I love Earth )and run as fast as possible to the nearest shop.
lets say item1 is : +1life and item2 is : get more money from objects
After I had satisfied my primal needs I feel the strong urge to play that awesome game of mine again. But when i start the game I start to see some strange things: It seems that I havent got one life more and neither do i get more money and just to be sure that Im not hallucinating (or that i didnt rememer the lifes i had last time) I die on purpose so the Shop menu shows. So now what I see is making me sad -> button1 and button2 are active and have an alpha of 1( and that means that the game thinks that they were never bought/clicked, that i have never played this game before in my life)
So i go crazy (cause all that play before was for nothing and i have to start all over again).
After i calm down, I decide to change my life. 1st BIG change is adding some code into the game. To be more specific: a method that will save the items that i bougth, so when i close the game and start again the things i see will bring joy to my life - >: I still have the items that i bougth last time.
So long story short:
how do i make that when i click a button (it changes its alpha to 0.5)and close the FLA ,
whenever i open the same FLA, the button that i clicked before will be shown as clicked now(it alpha will be 0.5)

What is happening is normal. All variables are stored in RAM, which is temporary memory. Your button states are variables, too. Whenever any program closes, everything it has in RAM is deleted, thus the variables are cleared. This is true of all programs, in all programming languages. There are absolutely no exceptions.
Quite simply, you need to create a file that can store all this data long-term, on the hard drive (which is "permanent" memory).
If you're creating a game for the internet, you're going to need to store this data using SharedObjects (a.k.a. cookies).
If you're creating a game to be installed on the computer or mobile, you'll want to store data in a file. I recommend XML files, as they're the easiest to work with by far.
I am not going into either here, because those are lectures, not SO answers. See the above links to get started.

I didn't understand what exactly you're trying to do. But here is my simply approach would be that way.
// this is basically saved your latest clip we will control this if user click this button then we will be blocked
private var lastClickedButton:MovieClip;
private function onClick(ev:MouseEvent):void
{
var thisButton:MovieClip = ev.currentTarget as MovieClip
trace(thisButton.name)
thisButton.alpha = 0.5
thisButton.buttonMode = false;
thisButton.removeEventListener(MouseEvent.CLICK, onClick);
buttonInfoArr.push( thisButton.name );
savedData.data.myArray = buttonInfoArr;
// set the lastclicked button
lastClickedButton = thisButton;
// save this savedData sharedObject
savedData.data.lastClickedItem = lastClickedButton;
}
addEventListener(Event.ENTER_FRAME, loop)
{
if(savedData.data.lastClickedItem)
{
// do something here.
lastClickedButton.alpha = 0.5;
lastClickedButton.mouseEnabled=false;
// clear your sharedobject
savedData.flush();
}
}
I hope this will help you. good luck...

Related

AS3 tween object not working with .hitTestObject()

I am having a major problem in my new browser app.
Okay so I made game where different cubes (squares) spawn at the top of the screen and I use the Tween class to make them go down the screen and then disappear.
However I want to detect a collision when a cube hits the player (that is also a flying cube).
I tried everything, truly everything but it does not seem to work. The problematic thing is that when I remove the "Tween" function it does detect collision with the hitTestObject method but when I add the "Tween" line collision won't be detected anymore.
It looks like this:
function enemiesTimer (e:TimerEvent):void
{
newEnemy = new Enemy1();
layer2.addChild(newEnemy);
newEnemy.x = Math.random() * 700;
newEnemy.y = 10;
if (enemiesThere == 0)
{
enemiesThere = true;
player.addEventListener(Event.ENTER_FRAME, collisionDetection)
}
var Tween1:Tween = new Tween(newEnemy, "y", null, newEnemy.y, newEnemy.y+distance, movingTime, true);
}
And the collision detection part:
private function collisionDetection (e:Event):void
{
if (player.hitTestObject(newEnemy))
{
trace("aaa");
}
}
I am desperate for some information/help on the topic, it's been bugging me for days.
Thanks for your time, I would be very happy if someone could help me out^^
First, make sure the "newEnemy" instance and the "player" instance are within the same container. If they are not, their coordinate systems might not match up and could be the source of your problem.
Otherwise, you need to keep a reference to each enemy instance you create. It looks like you are only checking against a single "newEnemy" variable which is being overwritten every time you create a new enemy. This might be why you can successfully detect collision between the player and the most recent "enemy" instance.
So... you need a list of the enemies, you can use an Array for that.
private var enemyList:Array = [];
Every time you create an enemy, push it to the Array.
enemyList.push(newEnemy);
In your "collisionDetection" function, you need to loop through all of the enemies and check if the player is touching any of them.
for(var i:int = 0; i < enemyList.length; i++)
{
var enemy = enemies[i];
if (player.hitTestObject(enemy))
{
trace("Collision Detected!");
enemy.parent.removeChild(enemy); // remove the enemy from the stage
enemies.splice(i, 1); // remove the enemy from the list
}
}
I'd suggest that you move to TweenMax, it just might solve your problem, and in my experience it's much better in every possible way.
Scroll down the following page to see a few variations of this library, I myself use TweenNano, they're completely free of charge:
https://greensock.com/gsap-as
I think some plugins cost money, but I doubt you'll ever need them.

AS3/ AIR Alternative to PrevFrame() (too slow if big movieclip)

I'm having a problem with prevFrame(). In my previous projects, I never had a trouble with it (usage is pretty straightforward), but this one... I don't understand. Everything does what it needs to do, but when I try to go to the prevFrame of my "main movieclip", it takes ages.
Some context: I'm making a dictionary for an ancient language (non-latin alphabet). There are 6.000 glyphs so I had to find a way to make such a complex "keyboard".
var gArray: Array = [gEmpty, clavierUI.g1, clavierUI.g2, clavierUI.g3, (...)
clavierUI.g50
]; //array contaning the buttons for the keyboard (50 instances of the same
//movieclip. This movieclip is made of 6.000 frames, each containing a
//glyph), the fnClavier function makes each of the fifty instances go to its
//respective frame)
var myXML2: XML = new XML();
var XML_URL2: String = "assets/glyphs.xml";
var myXMLURL2: URLRequest = new URLRequest(XML_URL2);
var myLoader2: URLLoader = new URLLoader(myXMLURL2);
myLoader2.addEventListener("complete", xmlLoaded2);
//import the codename for each glyph
function xmlLoaded2(event: Event): void {
myXML2 = XML(myLoader2.data);
}
var xml2: XMLList = myXML2.glyph.code;
function fnClavier(e: Event): void { //transforms the keyboard
for each(var glyph: MovieClip in gArray) {
glyph.gotoAndStop(gArray.indexOf(glyph) + (50 * (clavierUI.currentFrame - 1)));
//the seconde half (50 * (...) -1))) can be explained like that :
//50 = 50 keys by keyboard "page".
// clavier.currentFrame - 1 = modifier, tells which set of the 6000 glyphs
//needs to appear (and later, correspond with the codename from xml)
}
}
clavierUI.nextPage.addEventListener(MouseEvent.CLICK, fnNextPage);
function fnNextPage(e: Event): void {
clavierUI.nextFrame(); //no problem here, goes fast.
fnClavier(null);
}
clavierUI.prevPage.addEventListener(MouseEvent.CLICK, fnPrevPage);
function fnPrevPage(e: Event): void {
clavierUI.prevFrame(); //takes about 20secondes to go back.
fnClavier(null);
}
My code is probably far from being perfect (i'm still learning), but I don't know why it wouldn't work. Jumping around the frames and going to the next works perfectly, so anyone know why going back one frame takes forever?
Thank you.
You'd better use containers instead of frames. Frames get constructed and deconstructed each time you move between keyframes, while you con construct all the containers once and then display them as needed, one container at a time. I expect that Flash has optimization somewhere that constructs the next frame prior to it being shown via nextFrame() while an abrupt calling of prevFrame() forces Flash to construct it at once, and if it's very complex, it can take a lot of time.
You have 6000 glyphs? That's a lot, but not too much. You can create a set of containers, each holding 120 glyphs, for example. To do that, you create an array of Sprites, each having a grid of glyphs 12x10, there will be 50 of these. Then, when you need another page, display another sprite from the array. Also, if your glyph is a static vector object, you should convert it to vector graphics, and add as library item (Shape descendant, these eat less memory). If it's raster, use Bitmap and underlying BitmapData classes to use them.

AS3 How to make an object shrink when it is not tapped

I have stumbled upon a problem that I do not seem to know how to solve. I have searched it up online but no answer has been found. It is that when you tap the Monster on the screen it grows, but when you don't tap it returns to its default size. I have managed to make it grow when tapped but I can not seem to make it so that when you release the tap it shrinks. An example of what I am talking about is on cookie clicker, that when you click the big cookie it grows but when you don't it goes to its original size. Here is my code so far:
var score:Number = 0;
var score_str:String;
var score_str_len:int;
Multitouch.inputMode = MultitouchInputMode.TOUCH_POINT;
Monster.addEventListener(TouchEvent.TOUCH_TAP, fl_TapHandler);
Monster.width = 363.5;
Monster.height = 344.9;
function fl_TapHandler(event:TouchEvent):void
{
Monster.width = 378.4;
Monster.height = 359;
score = score + 1;
score_str = score.toString();
score_str_len = score_str.length;
Taps_txt.text =
score_str_len > 3
? score_str.substr(0, score_str_len-3) + ',' + score_str.substr(score_str_len-3)
: score_str
;
}
Help will be greatly appreciated.
According to the actionscript reference, there are a lot of other touch events you can use, such as TouchEvent.TOUCH_OUT or TouchEvent.TOUCH_END.
I haven't used them so i can't tell you which one would be helpful to you but you can run some tests and see which of the event is fired when you remove your finger from the monster, just as you would do with mouse events.
So basically you would add another listener (best would be inside the fl_TapHandler function) for the release touchevent and put the monster variables back to their normal level.
If you want to have several monsters, the best way would be to create a class for it and call the functions that would be inside this class. Exemple:
Monster.addEventListener(TouchEvent.TOUCH_TAP, Monster.fl_TapHandler);
I hope this helps.
How about you store all monsters in an array?
var monsters:Vector.<Monster> = new Vector.<Monster>();
monsters.push(new Monster());
monsters.push(new Monster());
monsters.push(new Monster());
for(var monster : monsters) {
if(monster.isTapped){
monster.grow()
} else {
monster.shrink()
}
}

How to construct nested eventlisteners in AS3

Working a bit with AS3 and hit a wall on how to program through this situation. I have a class which represents a number say 103. I have a movieclip for each digit which I add to a holding movieclip and then add to the stage. I want to enable the ability to single click a digit like the zero in the number 103 and have it react since it is an individual movieclip and at the same time double click the entire number and have that react. Is there a way to cleanly do this wtihout confusing the code below is what I have thus far.
public function test()
{
numberimage = new MovieClip();
var images:Vector.<MovieClip> = generateNumericArray("");
for (var i:int = 0; i < String(value).length; i++) {
var temp:MovieClip = parsevalue(String(value).substr(i,1),images);
temp.x = i*50;
temp.addEventListener(MouseEvent.CLICK,click)
numberimage.addChild(temp);
}
numberimage.addEventListener(MouseEvent.MOUSE_DOWN,drag);
numberimage.addEventListener(MouseEvent.MOUSE_UP,drop);
numberimage.addEventListener(MouseEvent.MOUSE_OVER,doubleClick);
stage.addChild(numberimage);
}
any help on this would be much appreciated
Do, doubleclick on clip : stop listening to main movie, and listen now to sub clips. On click outside the main clip, listen back to the main movie and stop listening to its children.
Not sure if this is 100% what you are looking for: use the following, depending on what you are adding the listener to. You do have to enable double clicking first
numberimage.doubleClickEnabled = true;
numberimage.addEventListener(MouseEvent.DOUBLE_CLICK, click);

How to control sound/music playblack in AS3

I'm making a game with AS3. I would like to put a different music in each background.
So far, I've succeed to start the music when the player enters in a scene. But if he goes out, the music is still playing...(I want the music to stop when the players leave a scene).
I don't understand why the music is still playing.. Here's my code :
public function newBackground(thisBack:String):void{
var room = back.currentBack;
switch (thisBack){
case "maisonExt":
var mySound:Sound = new exterieur ();
mySound.play ();
My mp3 file is named "exterieur.mp3".
If you can think of anything it would be a great help.
Thanks !
You need to stop the music again. If you don't stop it, it will keep on playing :)
When you call .play it will return a SoundChannel which lets you control the playback -- changing position, stopping the playback, and accessing the SoundTransform which lets you control the volume. Here is some example code for you:
public var currentSoundChannel:SoundChannel;
public function newBackground(thisBack:String):void
{
var room = back.currentBack;
if (currentSoundChannel != null)
{
currentSoundChannel.stop()
}
var nextSong:Sound;
switch (thisBack){
case "maisonExt":
nextSong = new exterieur ();
break;
}
currentSoundChannel = nextSong.play();
}
If you want to learn more about sound, I would recommend this tutorial http://gamedev.michaeljameswilliams.com/2009/03/03/avoider-game-tutorial-9/. It's part of a larger tutorial which teaches you many aspects of game making, taking you from novice to capable of creating a game. You should really check that out.