Make MC visible depending on how make key presses AS3 - actionscript-3

Probably another easy one, but after hours of searching and trying I still cant get this working.
I have a keypad with 10 buttons (0 - 9) - I want to create a variable that stores the number of key presses on the keypad and displays each MC accordingly in sequence depending on how many presses have been made.
For example, if only 1 key has been pressed, then only the first MC displays (and increments the variable to '1'), if 2 keys have been pressed then the first and second MC's are displayed - and so on until all 4 of my MC's are displayed and the MC progresses to frame #33.
I am getting different errors depending on how I structure this (mainly "expecting identifier before greaterthan")
My code for button '0' is below, can anyone assist please?
kpad.b0.addEventListener(MouseEvent.MOUSE_DOWN, onMouseDown0);
var clickCount:int = 0;
function onMouseDown0(e:MouseEvent):int {
clickCount++();
if (clickCount <= 0)
as1.visible = true;
if (clickCount == 1)
as1.visible = true;
if (clickCount == 2)
as1.visible = true;
as2.visible = true;
if (clickCount == 3)
as1.visible = true;
as2.visible = true;
as3.visible = true;
if (clickCount == 4)
as1.visible = true;
as2.visible = true;
as3.visible = true;
as4.visible = true;
if (clickCount => 4)
this.gotoAndPlay (33)
}

Related

OpenFL - can someone explain __combinedVisible property of flash.display.Bitmap

Im using a Bitmap for a button in OpenFL. What im seeing when I set myBitmap.visible = true is that the bitmap does not become visible.
It seems I need to call myBitmap.__CombinedVisible = true as well for it to be drawn. I can't find any documentation for this property on how to use it properly.
I'm also noticing the first time I switch between 2 bitmaps that the bitmap made visible does not appear right away, but the one made invisible disappears right away. Any time after that it behaves properly and the switch happens instantly.
Could this have something to do with __CombinedVisible?
You can see the bitmap switching code below inside of my button.
private function update() : Void {
if( state == ButtonState.OVER ){
this.over.visible = this.over.__combinedVisible = true;
this.up.visible = this.down.visible = false;
}else if( state == ButtonState.UP ){
this.up.visible = this.up.__combinedVisible = true;
this.down.visible = this.over.visible = false;
} else if( state == ButtonState.DOWN ){
this.down.visible = this.down.__combinedVisible = true;
this.up.visible = this.over.visible = false;
}else if( state == ButtonState.CLICK ) {
this.up.visible = this.up.__combinedVisible = true;
this.over.visible = this.down.visible = false;
this.enabled = false;
dispatchEvent(new Event("CLICK"));
}
}
So after a bunch of testing I'v narrowed it down to this: If I set visible to false prior to assigning the BitmapData this __combinedVisible member seems to need to be used. If I do it right after setting the BitmapData it still needs this.
If I let the bitmap draw for 1 frame then set visible to false. visible = true works after this happens and I can now see the bitmap.
But if it doesn't draw once then visible = true does not show the bitmap.
Can I not create an empty bitmap this way and assign the BitmapData later? It works on the up state as I never set visible = false prior to it being drawn the first time.
Okay so after tons of testing and trying to get this to work it just won't.
There is a bug here where if visible is set to false before drawing the bitmap to the canvas it won't draw it until __combinedVisible is set to true. This always causes a flash when drawing the bitmap for the first time as well, so its not feasible to use.
I went and used alpha instead of visible. This works properly and as expected.
If someone can get this working with visible I will accept that answer.
private function update() : Void {
if( state == ButtonState.OVER ){
this.over.alpha = 1;
this.up.alpha = this.down.alpha = 0;
}else if( state == ButtonState.UP ){
this.up.alpha = 1;
this.down.alpha = this.over.alpha = 0;
} else if( state == ButtonState.DOWN ){
this.down.alpha = 1;
this.up.alpha = this.over.alpha = 0;
}else if( state == ButtonState.CLICK ) {
this.up.alpha = 1;
this.over.alpha = this.down.alpha = 0;
this.enabled = false;
dispatchEvent(new Event("CLICK"));
}
}

How can I graph a series of scores?

I am trying to make a score graph. I have last seven scores of the game. I could use the graphics.lineTo function but it takes so long.
Is there an easy way to do this ?
Example graph.
Here is what I tried so far. I made 20-40-60-80 lines movieclip and duplicate and change their name of each level.
if(score1 == 40 && score2 == 20 && makeline == true){
line20.x = 184;
line20.y = 411;
yirmiasah2 = true;//yirmi asa
}
if(score1 == 40 && score2 == 40 && makeline == true){
line40.x = 184;
line40.y = 411;
}
if(score1 == 40 && score2 == 60 && makeline == true){
line60.x = 183;
line60.y = 366;
}
if(score1 == 40 && score2 == 80 && makeline == true){
line80.x = 172;
line80.y = 384;
}
The question is not clear but you can try something like this.
Somewhere in your code you undoubtedly have a variable holding the score of the current game. You haven't shown that, so I'll call that current score from the last game currentScore of type int. First this variable is declared outside of any functions.
var currentScore:int;
Then, while the game is being played, this value goes up whenever the player earns a point. In my example, he gets a point when Sprite A touches Sprite B
if (spriteA.hitTestObject(spriteB)){
newScore++; // adds one to the newScore variable
}
Make an array to hold your scores in. Put this outside of any functions. Putting it at the same place you put the currentScore variable makes sense.
var scoreArray:Array = new Array();
As each score is made final (at the end of a game), add that score to the array:
if (gameOver == true){
// make a new variable to add to the array and give it the same value as the score of the last game
var newScore:int = currentScore;
// add the new variable to the array
scoreArray.push(newScore);
// this adds the newScore variable to the array.
// after 7 games, you'll have 7 values in the array.
}
Then to draw the graph:
var scoreGraph:Sprite = new Sprite();
addChild(scoreGraph);
scoreGraph.graphics.moveTo(0,100);
scoreGraph.graphics.lineStyle(1);
for (var i:int = 0; i < scoreArray.length; i++){
scoreGraph.graphics.lineTo(i*10,100-scoreArray[i]);
// this will space out along the x axis by 10 pixels and put the x axis at 100 pixels down.
}

How to loop through frame number and if true then ignore that frame number?

Hey guys so I am struggling the best way to approach this situation.
So I have 5 frames in my ovenScreen.mcChar movie clip. Each is a character that the player can unlock. If the player has enough coins then they can go to the prize screen to get a random unlockable character.
Here is how it is setup so far:
private function getPrizeHandler(e:MouseEvent):void
{
//Check if prize is locked or unlocked then unlock item/ loop through random number frames
frameLoop = randomNumber(1, 5);
ovenScreen.mcChar.gotoAndStop(frameLoop);
if (frameLoop == 1 && !sharedObjectCharacters.data.sharedHotDog)
{
sharedHotDog = true;
sharedObjectCharacters.data.sharedHotDog = sharedHotDog;
sharedObjectCharacters.flush ();
}else
if (frameLoop == 2 && !sharedObjectCharacters.data.sharedTaco)
{
sharedTaco = true;
sharedObjectCharacters.data.sharedTaco = sharedTaco;
sharedObjectCharacters.flush ();
}else
if (frameLoop == 3 && !sharedObjectCharacters.data.sharedDonut)
{
sharedDonut = true;
sharedObjectCharacters.data.sharedDonut = sharedDonut;
sharedObjectCharacters.flush ();
}else
if (frameLoop == 4 && !sharedObjectCharacters.data.sharedCoffee)
{
sharedCoffee = true;
sharedObjectCharacters.data.sharedCoffee = sharedCoffee;
sharedObjectCharacters.flush ();
}else
if (frameLoop == 5 && !sharedObjectCharacters.data.sharedPancakes)
{
sharedPancakes = true;
sharedObjectCharacters.data.sharedPancakes = sharedPancakes;
sharedObjectCharacters.flush ();
}
////////////////////////////////////////
ovenScreen.gotoAndPlay(2); //play animations
TweenLite.delayedCall(3.5, prizeConfettie);
ovenScreen.removeEventListener(MouseEvent.CLICK, getPrizeHandler);
}
As you can see I have the var frameLoop which is a random number from 1 - 5. So the character unlocked will be random and show the random unlocked character. I use the if statements to check if the random number lands on that certain frame and its not the case that it is unlocked then unlock it and save the data.
Now this all works fine but How could I go about fixing it to where if the Item is already unlocked to sort through a different frame number. So if the frameLoop lands on 2 and that character is already unlocked then repeat the random frame number until it lands on a locked character. I was thinking of setting up an array of numbers maybe that approach might be a logical one but not sure how to go about doing so.
Any help would be appreciated thanks.
Additional Info on the shared object Booleans:
private function allSharedObjectBooleans():void
{
sharedObjectCharacters = SharedObject.getLocal("Characters");
sharedHotDog = sharedObjectCharacters.data.sharedHotDog != null ? sharedObjectCharacters.data.sharedHotDog : false;
sharedTaco = sharedObjectCharacters.data.sharedTaco != null ? sharedObjectCharacters.data.sharedTaco : false;
sharedDonut = sharedObjectCharacters.data.sharedDonut != null ? sharedObjectCharacters.data.sharedDonut : false;
sharedCoffee = sharedObjectCharacters.data.sharedCoffee != null ? sharedObjectCharacters.data.sharedCoffee : false;
sharedPancakes = sharedObjectCharacters.data.sharedPancakes != null ? sharedObjectCharacters.data.sharedPancakes : false;
}
and I create them like so:
//shared Booleans
private var sharedHotDog:Boolean;
private var sharedTaco:Boolean;
private var sharedDonut:Boolean;
private var sharedCoffee:Boolean;
private var sharedPancakes:Boolean;
If the character is already unlocked, you increment the variable. If it's overboard (greater than the number of unlockable entities), set it to 1. If it looped through all characters and they all are already unlocked, do something else. And you already have an array of sorts for this, it's just located in sharedObjectCharacters.data and its indexes are string, not int. But this can be remedied by providing a map from int to string, and using this[string] syntax to check for properties. An example:
const strUnlockables:Array=["Noone","sharedHotDog","sharedTaco","sharedDonut","sharedCoffee","sharedPancakes"];
const unlockables:int=5;
private function getPrizeHandler(e:MouseEvent):void {
var f:int=randomNumber(1,5); //frameLoop
for (var i:int=0;i<unlockables;i++) { // check all unlockables, starting with f'th
if (sharedObjectCharacters.data[strUnlockables[f]]===false) {
// this "f" is the one to unlock
sharedObjectCharacters.data[strUnlockables[f]]=true;
sharedObjectCharacters.flush();
ovenScreen.mcChar.gotoAndStop(f);
ovenScreen.gotoAndPlay(2); //play animations
TweenLite.delayedCall(3.5, prizeConfettie);
break;
}
f++;
if (f>unlockables) f=1; // loop around
}
// if we're here, we either did a break, or have all characters unlocked
ovenScreen.removeEventListener(MouseEvent.CLICK, getPrizeHandler); // clean up
}

Making layers invisible with mouse click

Is it possible to make it so that when you click on a button the first time, a specific layer will become invisible... and then once you click on the button a second time, a different layer would become invisible, and so on? If so could I see an example? Thanks!
What I've tried :
/************************* RESET BUTTON **************************/
reset_btn.addEventListener(MouseEvent.CLICK,reset);
function reset(e:Event) : void
{
eraserClip.graphics.clear();
initEraser();
erasableBitmapData.fillRect(erasableBitmapData.rect, 0xFFFFFFFF);
penny.visible = true;
maskee4.visible = true;
card.visible = false;
greencard.visible = true;
}
The idea is, once I hit the reset button once, the layer named card, will disappear. Underneath that a layer will be there, which is titled greencard. Once I hit the reset button a second time I want the greencard to disappear. As you see above, I was just doing (property name).visible = false;. This works for the first card but not any after because they would not appear.
If I understand you correctly, you could try something like this below :
reset_btn.addEventListener(MouseEvent.CLICK, reset);
var clickCount : int = 0; //# start with zero since no clicks yet
card.visible = true;
greencard.visible = true;
function reset(e:Event) : void
{
clickCount += 1; //# adds +1 to current count of clicks
eraserClip.graphics.clear();
initEraser();
erasableBitmapData.fillRect(erasableBitmapData.rect, 0xFFFFFFFF);
penny.visible = maskee4.visible = true; //# if same value (true) you can chain them like this
if ( clickCount == 1) //if now 1 click
{
card.visible = false;
}
if ( clickCount == 2) //if now 2 clicks
{
greencard.visible = false;
}
}

What code in as-3 to use to allow seekbar to be moved by user?

I'm creating a simple music player which will play just one song. Stage timeline has got just one frame. There is main graphic for player which is movieClip_1 (it has 4 frames in it's own timeline) and that works ok. I've got button (button_2) which starts and pauses the song and the movieClip_1 (works ok). And i also have got a graphic (it's called tube - i have changed it to movie clip, it has got one frame inside it's timeline) as a seekbar component which I just want it to move correspondingly to channel.position of this song on the x axis which it does but gives me triple error of:
TypeError: Error #1009: Cannot access a property or method of a null object reference.
Debug points at this line:
tube.x = (chan.position/song.length) * 83;
I would really appreciate a tip regarding error and also what method to use in order for user to be able to navigate (with mouse) through song by moving tube on x axis and going to different part of song. I read about .startDrag and .stopDrag would that be good idea with my present code?
My code so far:
movieClip_1.stop();
var itsstoped:Boolean;
var youpausedit:Boolean;
var counter:Timer = new Timer(100);
var chan:SoundChannel;
var song:Sound = new Sound();
song.load(new URLRequest("wmc2.mp3"));
song.addEventListener(Event.COMPLETE, soundloaded);
function soundloaded(event:Event)
{
trace("Song has been loaded.");
}
counter.addEventListener(TimerEvent.TIMER,countcounter);
itsstoped = true;
youpausedit = false;
button_2.addEventListener(MouseEvent.CLICK, presser);
function presser(event:MouseEvent):void
{
if(itsstoped == true && youpausedit == true)
{
movieClip_1.gotoAndPlay(1);
chan = song.play(chan.position);
itsstoped = false;
}
else if(itsstoped == false)
{
movieClip_1.gotoAndStop(1);
chan.stop();
itsstoped = true;
youpausedit = true;
}
else if(itsstoped == true && youpausedit == false)
{
movieClip_1.gotoAndPlay(1);
chan = song.play();
counter.start();
itsstoped = false;
}
}
function countcounter(e:TimerEvent):void
{
trace(chan.position/song.length);
var percentage:uint = 100 * (chan.position / song.length);
trace(percentage);
if(percentage == 100)
{
movieClip_1.gotoAndStop(1);
itsstoped = true;
youpausedit = false;
counter.stop();
}
}
tube.buttonMode = true;
tube.useHandCursor = true;
addEventListener(Event.ENTER_FRAME, movewhenplay);
function movewhenplay(e:Event):void
{
tube.x = (chan.position/song.length) * 83;
}
Regarding the error, you're accessing an object that has yet to be instantiated, i.e. there is no data to fetch as it does not exist.
As for the searchbar, I'm guessing you're using some kind of mask for the search bar, as you're using its x position to display the song position. I would suggest you instead use its width parameter, and set the center point to the far left.
To be able to then search through the song, you can add a copy of this searchbar, place it on top of the first one. Set its alpha to 0, to make it invisible, but still clickable. Add mouseEvent listeners to that, and when the user clicks it, you can set the song to play from the position which you can calculate using mouseX relevant to the invisible search bar.
I.e. if you want the clicked position in percents
percent = (mouseX - invisiSearchBar.x) / invisiSearchbar.width