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.
}
}
Related
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
I'm trying to develop a simple snake game with libgdx. My problem is that everytime I want to spawn some apples(texture, 20px width X 20px height) it always overlaps the body of the snake.
I'm trying to avoid this but it keeps occuring during the game.
The snake is compiled of parts - every part is a texture of 20px width X 20px height(The screen width is 480px width X 800px height)
Here is what I have tried so far:
public void addApple() {
accomplishedSnake = false;
accomplishedApples = false;
while (!accomplishedSnake && !accomplishedApples) {
xApple = 20 * MathUtils.random(0, 23);
yApple = 20 * MathUtils.random(20, 36);
if (!accomplishedSnake) {
for (int i = 0; i < snake.getSize(); i++) {
if (snake.getPart(i).getX() <= xApple
&& snake.getPart(i).getX() + 20 >= xApple
&& yApple >= snake.getPart(i).getY()
&& yApple <= snake.getPart(i).getY() + 20)
break;
if (i == snake.getSize() - 1) {
accomplishedSnake = true;
break;
}
}
}
if (!accomplishedApples) {
for (int i = 0; i < apples.size; i++) {
if (apples.get(i).getX() <= xApple && apples.get(i).getX()+20 >= xApple
&& yApple >= apples.get(i).getY() && yApple <= apples.get(i).getY()+20)
break;
if (i == apples.size - 1) {
accomplishedApples = true;
break;
}
}
}
}
apples.add(new Apple(xApple, yApple));
}
The code is pretty self-explanatory. In every moment I have 3 different apples on the screen. This code tries to raffle x-y coordinates to the new apple but before the apple is added to the screen and rendered, I want to make sure that it doesn't overlaps the body of the snake or the other apples.
I just can't see what's wrong with this code.
P.S I tried to use the overlaps method in the Rectangle class but it doesn't work.
You test conditions are too simple. Each item snake body part/apple has size, you need to consider their locus. So [snake.X,snake.X+20] and [snake.Y,snake.Y+20] is occupied by each body part, you need to ensure both apple.X and apple.X+20 aren't in range, the same for apple.Y
try this ..
if (snake.getPart(i).getX() >= xApple
&& snake.getPart(i).getX() + 20 <= xApple
&& snake.getPart(i).getX() >= xApple+20
&& snake.getPart(i).getX() + 20 <= xApple+20
&& snake.getPart(i).getY() >= yApple
&& snake.getPart(i).getY() + 20 <= yApple
&& snake.getPart(i).getY() >= yApple +20
&& snake.getPart(i).getY() + 20 <= yApple +20)
break;
also you need to ensure accomplishedApple and accomplishedSnake are set to false both before entering the while loop and after each calculation of random coordinates.
you also need to mimic this logic when establishing accomplishedApple further down your code.
This game should be tile-based.
This means, that the game is organized as a grid, where every cell has the same size.
This is done by using a camera:
OrthographicCamera cam = new OrthographicCamera(viewportWidth, viewportHeight)
The viewportWidth and viewportHeight define how many cells there should be in x and y.
As you are using a resolution of 480*800px and pictures with a size of 20*20px, the viewportWidth should be 480/20=24 and the viewportHeight should be 800/20 = 40.
Note, that the cameras P(0/0) is in the middle of the screen and you see objects from -12 to 12 (x) and -20 to 20 (y). Just set the position of the camera to P(12/20) and the P(0/0) is the lower left corner, as usual.
Now the spawning would be easy:
I use a int[][] world, where i store, if there is a:
Snakepart at P(x,y) (world[x][y] == 1)
Apple at P(x,y) (world[x][y] == 2)
Nothing at P(x,y) (world[x][y] == 0)
This means, that if the snake leaves a tile, you need to set its value to 0 (world[x][y] = 0) and every tile it enters to 1 (world[x][y] = 1)
public void spawnApple() {
boolean spawned = false;
while(!spawned) {
// The lower left corner is always an int-value
int x = (int)MathUtils.random(0, 23);
int y = (int)MathUtils.random(0, 40);
if (world[x][y] == 0) {
// Add Apple at x,y
world[x][y] = 2;
}
}
}
Hope it helps!
private void checkAndPlaceApple() {
if(!appleAvailable) {
do {
appleX = MathUtils.random(Gdx.graphics.getWidth / 20 - 1) * 20;
appleY = MathUtils.random(Gdx.graphics.getHeight / 20 - 1) * 20;
appleAvailable = true;
} while(appleX == snakeX && appleY == snakeY);
}
}
The previous code shows the required rule for placing the apple on the
screen. First, we check whether we need to place an apple, then we randomly pick
a location on the screen, which is a multiple of 20, and we repick it if the picked location contains the snake. As we are working in a 0-indexed environment we need to subtract one (1-20 becomes 0-19 and 1-15 becomes 0-14).
I'm trying to make simple collision detection using the switch statement. The statement takes the y position of a certain object and then it detects if the object's x is the same as another object. The problem is that I have if statements inside of the cases it goes through the whole if statement, even if the condition isn't met. The object is supposed to be sent back to the starting point after it gets hit by an enemy (enemies are moving through the screen) and moves in increments of 19 so the case is met. The problem is I can't seem to move it up because it keeps getting sent back to the starting spot whenever I meet the case (y = 221). When I remove deadObject() from the switch statement, it works fine and only prints "dead" when it's running into an enemy. How can I go about to fixing this?
I've been looking around on the internet about this but I can't find anything AS3 related to if statements in switch statements. Thanks for any help
public function enterFrame(me:Event)
{
position = objectA.y
switch(position)
{
case 221:
if (objectA.x == enemy1.x || objectA.x == enemy1.x + 10)
trace("dead1");
deadObject()
if (objectA.x == enemy2.x || objectA.x == enemy2.x + 10)
trace("dead1");
deadObject()
if (objectA.x == enemy3.x || objectA.x == enemy3.x + 10)
trace("dead1");
deadObject()
break;
}
}
public function deadObject()
{
objectA.x = 133;
objectA = 240;
}
I believe this is a simple syntax problem. Your interpreter is smart enough to know that the trace statement belongs to the if statement but now you throw in another function and it gets confused.
My advice would be to always follow best practice and put brackets where they belong
Please also see the following:
Is it bad practice to use an if-statement without brackets?
public function enterFrame(me:Event)
{
position = objectA.y;
switch(position)
{
case 221:
if (objectA.x == enemy1.x || objectA.x == enemy1.x + 10)
{
trace("dead1");
deadObject();
}
if (objectA.x == enemy2.x || objectA.x == enemy2.x + 10)
{
trace("dead1");
deadObject();
}
if (objectA.x == enemy3.x || objectA.x == enemy3.x + 10)
{
trace("dead1");
deadObject();
}
break;
}
}
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?
I'm making a game with Flash Pro CS6 where you need to avoid falling cubes. When you've avoided une cube (cube_1) you get a point. I've made a scoreCounter texfield and setted it like a dynamic text. I didn't know how to tell Flash that when te animation of the movie clip "cube_1" was finished, it should have added a point, so I made an if statement that, depending of the cube's Y coordinate (> than the stage Y), you get a point. The problem is that I don't get any point!
The code is this:
timer.addEventListener(TimerEvent.TIMER, cubeFall);
function cubeFall(t:TimerEvent) {
time++;
if (time == 3) {
cube_1.play();
} else if (time == 10) {
cube_2.play();
} else if (time == 20) {
cube_3.play();
} else if (time == 30) {
cube_4.play();
} else if (time == 35) {
cube_5.play();
} else if (time == 40) {
cube_6.play();
} else if (time == 50) {
cube_7.play();
} else if (time == 60) {
cube_8.play();
}
// Add Score
else if (cube_1.y > 480 || cube_2.y > 480 || cube_3.y > 480 || cube_4.y > 480 || cube_5.y > 480 || cube_6.y > 480 || cube_7.y > 480 || cube_8.y > 480 ) {
score++;
scoreCounter.text = "Score: " + score;
}
}