Execute code only when mic activity level value changes - actionscript-3

I'm animating a mouth with microphone input. I'm using the microphone activity level, which delivers numbers from about 0-10. Each number corresponds to the frames in a "mouth" movie clip, so the louder the signal, the wider the mouth opens.
The mic activity level returns a value constantly (probably works out to once every frame). So even when the level stays the same for a while (particularly at 0 when there's no noise), it keeps executing the code to go to that frame.
I want to have the code execute only when the number changes.
import flash.display.BitmapData;
import flash.display.Shape;
var myMic:Microphone = Microphone.getMicrophone();
//Security.showSettings(SecurityPanel.MICROPHONE);
myMic.setLoopBack(true);
myMic.setUseEchoSuppression(true);
stage.addEventListener(Event.ENTER_FRAME, stage_EnterFrame);
function stage_EnterFrame(e:Event){
var num:Number = myMic.activityLevel * 1;
trace(num);
if (num == 0){
mouth.gotoAndStop(1);
} else if (num == 1){
mouth.gotoAndStop(2);
} else if (num == 2){
mouth.gotoAndStop(3);
} else if (num == 3){
mouth.gotoAndStop(4);
} else if (num == 4){
mouth.gotoAndStop(5);
} else if (num == 5){
mouth.gotoAndStop(6);
} else if (num == 6){
mouth.gotoAndStop(7);
} else if (num == 7){
mouth.gotoAndStop(8);
} else if (num == 8){
mouth.gotoAndStop(9);
} else if (num == 9){
mouth.gotoAndStop(10);
} else if (num == 10){
mouth.gotoAndStop(11);
}
}

So only exicute if it changes? Maybe something like
newNum=mic.activityLevel
If newNum != oldNum{
Gotoandstop (frame)
}
oldNum=newNum

Related

Character jumping but not returning to ground platform game AS3

I am making a platform game where the main character moves right and left and jumps however my character jumps and does not return to the ground but stays on top of the stage.My characters movie-clip symbol is called 'naruto' and my ground symbol is called 'ground'.
Here is my code:
import flash.events.KeyboardEvent;
import flash.ui.Keyboard;
import flash.display.MovieClip;
import flash.events.Event;
import flash.display.Stage;
naruto.gotoAndStop("stance");
var rightPressed:Boolean = new Boolean(false);
var leftPressed:Boolean = new Boolean(false);
var upPressed:Boolean = new Boolean(false);
var downPressed:Boolean = new Boolean(false);
var narutoSpeed:Number = 10;
stage.addEventListener(KeyboardEvent.KEY_DOWN,keyDownHandler);
stage.addEventListener(KeyboardEvent.KEY_UP,keyUpHandler);
stage.addEventListener(Event.ENTER_FRAME,gameLoop);
function keyDownHandler(keyEvent:KeyboardEvent):void
{
if (keyEvent.keyCode == Keyboard.RIGHT)
{
rightPressed = true;
}
else if(keyEvent.keyCode == Keyboard.LEFT)
{
leftPressed = true;
}
else if(keyEvent.keyCode == Keyboard.UP)
{
upPressed = true;
}else if(keyEvent.keyCode == Keyboard.DOWN)
{
downPressed = true;
}
}
function keyUpHandler(keyEvent:KeyboardEvent):void
{
if (keyEvent.keyCode == Keyboard.RIGHT)
{
rightPressed = false;
naruto.gotoAndStop("standright")
}
else if(keyEvent.keyCode == Keyboard.LEFT)
{
leftPressed = false;
naruto.gotoAndStop("standleft")
}
else if(keyEvent.keyCode == Keyboard.UP)
{
upPressed = false;
naruto.gotoAndStop("stance")
}else if(keyEvent.keyCode == Keyboard.DOWN)
{
downPressed = false;
naruto.gotoAndStop("stance")
}
}
function gameLoop(loopEvent: Event): void {
//If the right key is pressed, and the left key is NOT pressed
if (rightPressed && !leftPressed) {
naruto.x += narutoSpeed;
naruto.gotoAndStop("right");
}
if(leftPressed && !rightPressed) {
naruto.x -= narutoSpeed;
naruto.gotoAndStop("left");
}
var jumpHeight =0;
var defaultJumpSpeed = 20;
var jumpSpeed = 20;
if(upPressed && naruto.hitTestObject(ground))
{
trace("HELLO!");
naruto.y -= jumpSpeed;
jumpSpeed-= 4;
}
if(upPressed)
{
trace("HELLO!");
jumpHeight++;
naruto.y -= jumpSpeed;
if(jumpHeight>10)
jumpSpeed -= 4;
}
if(naruto.hitTestObject(ground))
{
trace("HELLO!");
jumpHeight =0;
jumpSpeed = defaultJumpSpeed;
}
}
Here is the link for my work: https://www.mediafire.com/?8d5opy49fuqmup5
Here is the problem:
The main issue, is in your current code, the player can only possible be in 3 positions:
Whatever the ground position is
16 (up is pressed and the character was not touching the ground
12 (up is pressed and the character was touching the ground)
Please see the code comments next to your original code to explain what is happening:
//you have this var inside the game loop, so every loop it resets to 20
var jumpSpeed = 20;
//so here, if up is pressed and the character is touching the ground
//you initiate a jump
if(upPressed && naruto.hitTestObject(ground))
{
trace("HELLO!");
naruto.y -= jumpSpeed;
jumpSpeed-= 4; //since you reset jumpSpeed to 20 every loop, this value will always just be 16
}
if(upPressed)
{
trace("HELLO!");
jumpHeight++;
//if naruto is touching the ground
//you are subtracting jumpSpeed above and right here again.
//so now the y position is 12 if touching the ground (or 16 if not touching the ground)
//since you reset jumpSpeed to 20 every loop, it always be one of those two values
naruto.y -= jumpSpeed;
if(jumpHeight>10)
jumpSpeed -= 4; //this serves no purpose, as your not using the value again and it gets reset to 20 next time the game loop runs
}
//this hit test will succeed in addition to the first one above when your jump starts.
if(naruto.hitTestObject(ground))
{
trace("HELLO!");
jumpHeight =0;
jumpSpeed = defaultJumpSpeed;
}
To remedy your jumping, you'll need to do something along these lines:
//initialize these vars outside of the game-loop for efficient and proper scoping (so their values don't reset every frame)
var isJumping:Boolean = false; //a flag to know if a jump is in progress
var jumpSpeed:Number = 0; //the current velocity of the jump
var defaultJumpSpeed:Number = 20; //the initial force (speed) of a jump
var jumpGravity:Number = 2; //subtract this from the speed every frame to slow the jump over time and fall
var onGround:Boolean = false; //a helper var for efficiency
function gameLoop(loopEvent: Event): void {
//If the right key is pressed, and the left key is NOT pressed
if (rightPressed && !leftPressed) {
naruto.x += narutoSpeed;
naruto.gotoAndStop("right");
}
if (leftPressed && !rightPressed) {
naruto.x -= narutoSpeed;
naruto.gotoAndStop("left");
}
//only do the hit test once per frame for efficiency (store the result)
onGround = naruto.hitTestObject(ground);
if (upPressed && onGround) {
trace("START JUMP");
isJumping = true;
jumpSpeed = defaultJumpSpeed; //set the initial jump velocity
}
if(isJumping){ //if jumping
naruto.y -= jumpSpeed; //move the player based off the current jump velocity
jumpSpeed -= jumpGravity; //slow the jump every frame (eventually causing it to be negative making the player fall)
}
//touching the ground and the up key is not pressed
//it's very important to put !upPressed so this doesn't run at the time as the initial jump above
if (!upPressed && onGround) {
//stop any jump motion
jumpSpeed = 0;
isJumping = false;
//you probably also want to snap the player to the ground
naruto.y = ground.y - naruto.height + 2; //the plus 2 ensures that the ground and the player touch so the hit test succeeds
}
}

ActionScript 3 Scoring/Math

I've been attempting to implement a score inside of a game that I'm creating in AS3. So far, I've managed to create a score system that adds/subtracts points based on actions in-game. I've decided that it'd be simpler to have the scoring system just add points instead of subtract them and on reaching a certain number, end the game.
The problem I'm having is that on the one hand, the game is performing checks to see if the pieces are in the right place. If they are, the player wins. On the other, the counter needs to count and reach a certain number (10) before deciding the player loses. At the moment there's some weird behaviour going on where I'm able to drag the pieces around without putting them in their right place and the counter still goes over 10. I've tried a few variations of changing the math so that it totals differently, but the functionality is the same. What would I have to change so that it would behave as first described?
stop();
//Create the score counter
import flash.text.TextField;
var score = 0;
scorecounter.text = score;
function init(): void
{
score = 0;
scorecounter.text = "SCORE:" + score.toString();
}
function updateScore(): void
{
scorecounter.text = ++score;
}
function evaluateScore(): void //this is meant to stop the score going below 0
{
scorecounter.text = --score;
if(score < 0) {
score -= score;
}
}
/*Omitted some functions and var's for object positions and events*/
function stopDragging(e:MouseEvent):void {
e.currentTarget.stopDrag();
switch (e.currentTarget){
case apple:
if (apple.x < appleEndX - offset || apple.x > appleEndX + offset ||
apple.y < appleEndY - offset || apple.y > appleEndY + offset) {
apple.x = appleStartX;
apple.y = appleStartY;
soundOne();
updateScore();
} else {
apple.x = appleEndX;
apple.y = appleEndY;
soundTwo();
updateScore();
checkGame();
}
break;
//Lots of other cases, using the same method
//The end of the game - here, I've been trying to set it to
//check whether the player will win or lose
}
}
function checkGame(): void {
if (apple.x == appleEndX && apple.y == appleEndY && pear.x == pearEndX &&
pear.y == pearEndY && guava.x == guavaEndX && guava.y == guavaEndY &&
pineapple.x == pineappleEndX && pineapple.y == pineappleEndY &&
plum.x == plumEndX && plum.y == plumEndY &&
purple.x == purpleEndX && purple.y == purpleEndY)
{
trace("You win!");
gotoAndStop(149);
soundFive();
} else if (score == 10) {
gotoAndStop(150);
soundSix();
trace("You lose.");
}
}
I think that the logic is a little confusing, but as I understand it from your code, the idea is to move a drag-gable item to the correct x,y position, with a tolerance of "offset"? The aim is to to this with the lowest possible "score" (or number of moves) and if the number of moves (score) is greater than 10 then you lose the game?
Currently the only place that checks to see if you have made 10 moves is "checkGame" and this method is only called if your "apple" is correctly positioned. If it is incorrectly positioned then the number of moves is incremented, but the score is not checked. So when you finally get to "checkGame" but correctly positioning the "apple" the score could already be greater than 10. So your "score == 10" check will fail also.
So what you need is to check the game on every move with something like this:
function stopDragging(e:MouseEvent):void {
...
switch (e.currentTarget){
case apple:
if (apple.x < appleEndX - offset || apple.x > appleEndX + offset ||
apple.y < appleEndY - offset || apple.y > appleEndY + offset) {
apple.x = appleStartX;
apple.y = appleStartY;
soundOne();
} else {
apple.x = appleEndX;
apple.y = appleEndY;
soundTwo();
}
break;
...
}
//Check the game on every turn.
checkGame();
}
function checkGame(){
//Update the score
score++;
if (apple.x == appleEndX && apple.y == appleEndY && pear.x == pearEndX &&
pear.y == pearEndY && guava.x == guavaEndX && guava.y == guavaEndY &&
pineapple.x == pineappleEndX && pineapple.y == pineappleEndY &&
plum.x == plumEndX && plum.y == plumEndY &&
purple.x == purpleEndX && purple.y == purpleEndY)
{
//Do the game win.
}
else if (score>=10)
{
//Else if you have a score greater then or equal to 10 do the game lose.
}
}

how to add timer in as3

I am doing a game that will count number of clicks then add scores. What i want is to add a timer, for example: the timer is 10 secs and the click done is 25 and your score is 35 points if the timer stopped the button(the one used to count the num of clicks) cannot be clicked and it will pause for a while, plan to make a little animation before it moves to another frame.
Want to make this simple as possible since design is more important than the codes, because it is a design base class.
Please no hitTestObject or classes, and i want to avoid arrays too :( last time a used them is a disaster...
Sorry for being noob
And thank you for advance
Here is the cODE:
var power:Number = 0;
var myTimer : Timer = new Timer(10 * 1000, 0);
myTimer.addEventListener(TimerEvent.TIMER_COMPLETE, function( e:TimerEvent ):void
{
myTimer.start();
trace("time up");
bgBack.gotoAndPlay("hit");
if (power == 5)
{
bgBack.gotoAndPlay("mini");
}
else if (power == 15)
{
bgBack.gotoAndPlay("mini");
}
else if (power == 25){
bgBack.gotoAndPlay("belowAve");
}
else if (power == 35){
bgBack.gotoAndPlay("ave");
}
else if (power == 50){
bgBack.gotoAndPlay("ave");
}
else if (power == 65){
bgBack.gotoAndPlay("highAve");
}
else if (power == 80){
bgBack.gotoAndPlay("magni");
}
});
pressBtn.addEventListener( MouseEvent.CLICK, function( e:MouseEvent ):void
{
power++;
if (power == 5)
{
gauge.gotoAndPlay("one");
}
else if (power == 15)
{
gauge.gotoAndPlay("two");
}
else if (power == 25){
gauge.gotoAndPlay("three");
}
else if (power == 35){
gauge.gotoAndPlay("four");
}
else if (power == 50){
gauge.gotoAndPlay("five");
}
else if (power == 65){
gauge.gotoAndPlay("six");
}
else if (power == 80){
gauge.gotoAndPlay("seven");
}
var myTimer : Timer = new Timer( 10 * 1000, 0 );
myTimer.addEventListener( TimerEvent.TIMER_COMPLETE, function( e:TimerEvent ):void
{
//here the timer ends and you can do stuff with the clicks.
//the ,0 means it will repeat this over and over and over. 10 seconds * 1000 milliseconds because its kept in milliseconds.
});
myTimer.start();
and also
var myClicks : Number = 0;
stage.addEventListener( MouseEvent.CLICK, function( e:MouseEvent ):void
{
myClicks++;
});

fluidly dealing with multiple keypresses in ActionScript3

I'm currently building an engine for a platformer game at the moment, but I've noticed that ActionScript3 is having difficulty in keeping fluid when multiple keypresses are in use. For example;
function onKeyDown(event:KeyboardEvent):void {
if (event.keyCode == Keyboard.UP || event.keyCode == Keyboard.W || event.keyCode == Keyboard.SPACE) {
if (isTouchingGround()) {
isJumping = true;
yv = -100;
}
} else if (event.keyCode == Keyboard.DOWN || event.keyCode == Keyboard.D) {
if (xv == 0) {
player.gotoAndPlay(275);
}
} else if (event.keyCode == Keyboard.LEFT || event.keyCode == Keyboard.A) {
if (xv == 0) {
xv = -24;
} else if (xv != -120) {
xv-=2;
}
} else if (event.keyCode == Keyboard.RIGHT || event.keyCode == Keyboard.D) {
if (xv == 0) {
xv = 24;
} else if (xv != 120) {
xv+=2;
}
}
}
So, as listed above, using the UP (or W, or Space) key triggers the player to jump (seperate onframe event handler handles gravity etc). Using the RIGHT (or D..) key triggers increases the player acceleration, which is again applied to the player in a seperate onframe event handler.
Everything works fine by itself - but the problem arises when multiple keystrokes are used. If a player starts to move to the right, and hits jump, he will cease accelerating. At the same time, he will not decelerate, as instructed in the Keyboard.UP method. Instead, he will maintain constant at his current rate, until the RIGHT key is hit again.
In short, it is as though Actionscript begins ignoring both the keyboard.down and keyboard.up methods for the RIGHT or LEFT movement keys, until they are no longer being pressed. This obviously causes for some very rigid gameplay - is there any solution anyone would be willing to share with me on this?
Your problem lies in the fact that your if conditionals are followed by if else conditionals. Drop the else and just have the if conditionals. Basically if the user holds down space then none of the other if conditionals are going to be tested since space is being held down and it's the first if statement. So just drop the else off of the if's. Just remove the if else conditionals that are testing keystrokes, not the conditionals inside of the if statements that deal with keystrokes.
Here is what your code should look like:
function onKeyDown(event:KeyboardEvent):void {
if (event.keyCode == Keyboard.UP || event.keyCode == Keyboard.W || event.keyCode == Keyboard.SPACE) {
if (isTouchingGround()) {
isJumping = true;
yv = -100;
}
}
if (event.keyCode == Keyboard.DOWN || event.keyCode == Keyboard.D) {
if (xv == 0) {
player.gotoAndPlay(275);
}
}
if (event.keyCode == Keyboard.LEFT || event.keyCode == Keyboard.A) {
if (xv == 0) {
xv = -24;
} else if (xv != -120) {
xv-=2;
}
}
if (event.keyCode == Keyboard.RIGHT || event.keyCode == Keyboard.D) {
if (xv == 0) {
xv = 24;
} else if (xv != 120) {
xv+=2;
}
}
}
Something else you may notice is that when the UP key and RIGHT key are both being held down, the computer seems to freeze keyboard input, however when the W key and D key are being held down you can still press other keys and the computer will register their input. The answer to that question is here.
Update:
For the fluid part, instead of triggering something when a keystroke takes place, it is better to have a boolean variable such as keyUP or UP that holds a true if the key is down or false when the key is up. Then have a function onEnterFrame(event:Event):void {} that performs an action when keyUP is true. Like so:
import flash.events.*;
public class keyEvents extends MovieClip {
private var keyRIGHT:Boolean = false;
public function keyEvents():void
{
this.addEventListener(KeyboardEvent.KEY_DOWN, onKeyDown);
this.addEventListener(KeyboardEvent.KEY_UP, onKeyUp);
this.addEventListener(Event.ENTER_FRAME, onEnterFrame);
}
function onKeyDown(event:KeyboardEvent):void
{
if(event.keyCode == Keyboard.RIGHT) {
this.keyRIGHT = true;
}
}
function onKeyUp(event:KeyboardEvent):void
{
if(event.keyCode == Keyboard.RIGHT) {
this.keyRIGHT = false;
}
}
function onEnterFrame(event:Event):void
{
if(this.keyRIGHT) {
// This code is executed while the RIGHT arrow key is down.
}
}
}
If the above code does not work I think that your problem lies with your keyboard, not that it's broken or anything but the way it was made might be messing things up.
Let me know if this didn't help and I'll continue trying.

AS3 Animation won't play

Fairly new to programming, slowly getting the hang of it. I've come across a problem I've spend hours on trying to fix but can't seem to get the result I'm looking for. I have made running animation for my character. He runs left, up, down, right, upRight, downRight BUT upLeft and downLeft the animations do not play. He moves in the correct direction but the animations that are being played are upRight and downRight. I've changed the animations for upLeft and downLeft to my "idle" animation and it works. I'm unsure as to why this is happening if all the other animations work correctly.
Here is my code for my player animation. Any help or advice would be great. Thanks in advance
package {
import flash.display.MovieClip;
import flash.display.*;
import flash.events.*;
public class PlayableCharacter extends Character
{
private var dx:int;
private var dy:int;
var ready:Boolean;
public function PlayableCharacter(x:int=0, y:int=0, dx:int = 3, dy:int = 3)
{
// constructor code
this.x = x;
this.y = y;
this.dx = dx;
this.dy = dy;
ready = true;
gotoAndStop("Idle");
addEventListener(Event.ENTER_FRAME,onEnter);
addEventListener(Event.ADDED_TO_STAGE, onStage);
}
private function onEnter(e:Event)
{
//doing animation stuff
if(!leftPressed && !rightPressed && !downPressed && !upPressed)
{
gotoAndStop("Idle");
}
//Go Left
if(leftPressed && !upPressed && !downPressed && !rightPressed)
{
//do something left
goDown(-dx)
gotoAndStop("Run");
}
//Go Right
if(rightPressed && !upPressed && !downPressed && !leftPressed)
{
//do something right
goDown(dx)
gotoAndStop("Run");
}
//Go Up
if(upPressed && !leftPressed && !rightPressed && !downPressed)
{
goUp(-dy)
gotoAndStop("RunUp");
}
//Go Down
if(downPressed && !upPressed && !rightPressed && !leftPressed)
{
goUp(dy)
gotoAndStop("RunDown");
}
//Go UpRight
if(rightPressed && upPressed && !leftPressed && !downPressed)
{
goDown(dx)
goUp(-dy)
gotoAndStop("UpRight");
}
//Go DownRight
if(rightPressed && downPressed && !leftPressed && !upPressed)
{
goDown(dx)
goUp(dy)
gotoAndStop("DownRight");
}
//Go UpLeft
if(leftPressed && upPressed && !rightPressed && !downPressed)
{
goDown(-dx)
goUp(-dy)
gotoAndStop("UpLeft");
}
// Go Downleft
if(leftPressed && downPressed && !rightPressed && !upPressed)
{
goDown(-dx)
goUp(dy)
gotoAndStop("DownLeft");
}
if (x > stage.stageWidth)
x = stage.stageWidth;
else if (x < 0)
x = 0;
if (y > stage.stageHeight)
y = stage.stageHeight;
else if (y < 0)
y = 0;
}
public function onStage(e:Event)
{
}
public function goUp(dy:int=0)
{
y += dy;
if(scaleY > 0 && dy < 0)
{
scaleY *= 1;
}
else if(scaleY < 0 && dy > 0)
{
scaleY *= -1;
}
}
public function goDown(dx:int =0)
{
x += dx;
if(scaleX > 0 && dx < 0)
{
scaleX *= -1;
}
else if(scaleX< 0 && dx > 0)
{
scaleX *= -1;
}
}
}
}
At first glance I dont see anything wrong with your code. I always woud advise against using labels for frames but using their numbers instead.
The names of functions "goUp" and "goDown" are hinting in a wrong direction, I'd change them to "goVertical" and "goHorizontal". How are the leftPressed, rightPressed, ... variables set? Have you tried putting a trace inside each "if" to see if the problem is that the wrong if-block is executed or the animation is addressed wrongly? Have you double-checked the names of the frames and maybe tried it using their respective numbers?