AS3 Accelerometer & Wind Movement - actionscript-3

I am using the standard Accelerometer template & am trying to create a wind effect on the ball, however I am having trouble getting my coded wind to move ball as ball only seems to respond to Accelerometer movements.
is there any way to move ball without disabling Accelerometer?
I have setup wind directions & strength, but when I test even when screen is flat & ball is in center of screen the wind variables / code has no effect.
an example of wind move ball function I am using is
if (windD == "left")
{ball.x -= ball.x-WindStrength;}
if (windD == "right")
{ball.x += ball.x+WindStrength;}
Any ideas.

OK, I figured it out.
My problem was I was trying to add a wind movement function in its own function outside Accellerometer movement functions.
Solution: was to move my wind code inside accellerometer function:
ball.addEventListener(Event.ENTER_FRAME, moveBall);
function moveBall(evt:Event){
ball.x -= accelX*10;
ball.y += accelY*10;
if(ball.x > (480-ball.width/2)){
ball.x = 480-ball.width/2;
}
if(ball.x < (0+ball.width/2)){
ball.x = 0+ball.width/2;
}
if(ball.y > (800-ball.width/2)){
ball.y = 800-ball.width/2;
}
if(ball.y < (0+ball.width/2)){
ball.y = 0+ball.width/2;
}
// Wind Functions
//Wind Strength
if (this.Stage_Txt_Box.text == "1")
{WindStrength = int(2);}
if (this.Stage_Txt_Box.text == "2")
{WindStrength = int(3);}
if (this.Stage_Txt_Box.text == "3")
{WindStrength = int(4);}
if (this.Stage_Txt_Box.text == "4")
{WindStrength = int(5);}
if (this.Stage_Txt_Box.text == "5")
{WindStrength = int(6);}
if (this.Stage_Txt_Box.text == "6")
{WindStrength = int(7);}
if (this.Stage_Txt_Box.text == "7")
{WindStrength = int(8);}
if (this.Stage_Txt_Box.text == "8")
{WindStrength = int(9);}
//Wind Directions
trace(WindStrength);
if (windD == "left")
{ball.x -= WindStrength; trace("Wind is blowing left");}
if (windD == "right")
{ball.x += WindStrength; trace("Wind is blowing right");}
if (windD == "up")
{ball.y -= WindStrength; trace("Wind is blowing up");}
if (windD == "down")
{ball.y += WindStrength; trace("Wind is blowing down");}
}

Related

AS3 How to make sprite face direction it is moving

So I have two movieclips: mcMain which is my character that faces the right and I have mcMainLeft which is my character that is facing the left. I tried to implement code so that when the left arrow is pressed, mcMainLeft is visible and is moving to the left. Same thing for mcMain and to the right. So what ends up happening is that when I move left, it moves left and the character faces left, but then I'll click the right arrow and move it right and it won't move my current character at the current location, it'll start from a different position. I'm not sure what the deal is.
Here is my code:
//These variables will note which keys are down
var leftKeyDown:Boolean = false;
var upKeyDown:Boolean = false;
var rightKeyDown:Boolean = false;
var downKeyDown:Boolean = false;
//the main character's speed
var mainSpeed:Number = 7;
//whether or not the main guy is jumping
var mainJumping:Boolean = false;
//how quickly should the jump start off
var jumpSpeedLimit:int = 15;
//the current speed of the jump;
var jumpSpeed:Number = 0;
//set coordinates of pacman left and right
mcMain.x = 270;
mcMain.y = 370;
mcMainLeft.x = 270;
mcMainLeft.y = 370;
//make pacman left invisible on startup
mcMainLeft.visible = false;
//move character function
mcMain.addEventListener(Event.ENTER_FRAME, moveChar);
mcMainLeft.addEventListener(Event.ENTER_FRAME, moveChar);
function moveChar(event:Event):void{
//if certain keys are down, then move the character
if(leftKeyDown ){
mcMainLeft.x -= mainSpeed;
}
if(rightKeyDown){
mcMain.x += mainSpeed;
}
if(upKeyDown || mainJumping){
mainJump();
}
}
//listening for the keystrokes
//this listener will listen for down keystrokes
stage.addEventListener(KeyboardEvent.KEY_DOWN, checkKeysDown);
function checkKeysDown(event:KeyboardEvent):void{
//making the booleans true based on the keycode
//WASD Keys or arrow keys
if(event.keyCode == 37 || event.keyCode == 65){
leftKeyDown = true;
mcMain.visible = false;
mcMainLeft.visible = true;
}
if(event.keyCode == 38 || event.keyCode == 87){
upKeyDown = true;
}
if(event.keyCode == 39 || event.keyCode == 68){
rightKeyDown = true;
mcMain.visible = true;
mcMainLeft.visible = false;
}
if(event.keyCode == 40 || event.keyCode == 83){
downKeyDown = true;
}
}
//this listener will listen for keys being released
stage.addEventListener(KeyboardEvent.KEY_UP, checkKeysUp);
function checkKeysUp(event:KeyboardEvent):void{
//making the booleans false based on the keycode
if(event.keyCode == 37 || event.keyCode == 65){
leftKeyDown = false;
}
if(event.keyCode == 38 || event.keyCode == 87){
upKeyDown = false;
}
if(event.keyCode == 39 || event.keyCode == 68){
rightKeyDown = false;
}
if(event.keyCode == 40 || event.keyCode == 83){
downKeyDown = false;
}
}
//jumping function
function mainJump():void{
//if main isn't already jumping
if(!mainJumping){
//then start jumping
mainJumping = true;
jumpSpeed = jumpSpeedLimit*-1;
mcMain.y += jumpSpeed;
mcMainLeft.y += jumpSpeed;
} else {
//then continue jumping if already in the air
if(jumpSpeed < 0){
jumpSpeed *= 1 - jumpSpeedLimit/75;
if(jumpSpeed > -jumpSpeedLimit/5){
jumpSpeed *= -1;
}
}
if(jumpSpeed > 0 && jumpSpeed <= jumpSpeedLimit){
jumpSpeed *= 1 + jumpSpeedLimit/50;
}
mcMain.y += jumpSpeed;
mcMainLeft.y += jumpSpeed;
//if main hits the floor, then stop jumping
//of course, we'll change this once we create the level
if(mcMain.y || mcMainLeft.y >= stage.stageHeight - mcMain.height || mcMainLeft.height){
mainJumping = false;
mcMain.y = stage.stageHeight - mcMain.height;
mcMainLeft.y = stage.stageHeight - mcMainLeft.height;
}
}
}
That's because you have basically two character objects (mcMain and mcMainLeft) but always only moving one of them. The other one is invisible and stays on the starting position.
Make a MovieClip with two frames, each holding the mcMain and mcMainLeft. Place a stop() at the first frame so the movieclip does not loop by itself. Then use that combined movieclip as your character:
function moveChar(event:Event):void{
//if certain keys are down, then move the character
if(leftKeyDown ){
myNewCharacter.x -= mainSpeed;
}
if(rightKeyDown){
myNewCharacter.x += mainSpeed;
}
if(upKeyDown || mainJumping){
mainJump();
}
}
And instead of switching the visibility jump to the correct frame of your new movieclip to display your character facing left or right:
myNewCharacter.gotoAndStop(2); // or 1
mcMain.scaleX = -1; // will face left
and
mcMain.scaleX = 1; // will face right
then you can use the value of .scaleX as your variable in logical blocks of code.

as3 - player moves through objects

So I'm making a collision detection when player touches an object. When it touches the object, you move and stop when colliding, but for example, if I press the D key to go right, and I press the A key and let go, then the player starts moving through the object.
This is my player moving code.
public function onKeyDown(event: KeyboardEvent): void
{
if (event.keyCode == Keyboard.D)
{
isRight = true;
}
if (event.keyCode == Keyboard.A)
{
isLeft = true;
}
if (event.keyCode == Keyboard.W)
{
isUp = true;
}
if (event.keyCode == Keyboard.S)
{
isDown = true;
}
}
private function onKeyUp(event: KeyboardEvent): void
{
if (event.keyCode == Keyboard.A || event.keyCode == Keyboard.D)
{
vx = 0;
}
else if (event.keyCode == Keyboard.S || event.keyCode == Keyboard.W)
{
vy = 0;
}
}
public function onEnterFrame(event: Event): void
{
if (isRight)
{
vx = 5;
x += vx;
}
if (isLeft)
{
vx = 5;
x -= vy;
}
if (isUp)
{
vx = 5;
y -= vy;
}
if (isDown)
{
vx = 5;
y += vy;
}
//collision detection
if (player.collisionArea.hitTestObject(wall0))
{
player.x -= vx;
player.y -= vy;
}
}
Your issue, is that vx is always 5. So one direction you subtract 5 from the x, the other direction you add it.
Yet in your collision if statement, you are always subtracting it from the player's x (which if moving left, would keep moving the player left until it's past the object it's colliding with).
Also, in your isLeft check, you are subtracting the vy value, but I imagine you want to actually subtract the vx value. On that same note, in your isUp/isDown checks, your set the vx var to 5, but it seems like you should be setting the vy.
As it's unclear what x and y affect in context to the player, it's hard to give you an exact code example.
Most likely, you just need to move the player to the wall edge, and choose the side based off the direction of the player:
//collision detection
if (player.collisionArea.hitTestObject(wall0))
{
//if the player x is colliding
if(player.x + player.width > wall0.x && player.x < wall0.x + wall0.width){
player.x = isRight ? wall0.x - player.width : wall0.x + wall0.width;
}else if(player.y + player.height > wall0.y && player.y < wall0.y + wall0.height){
player.y = isDown ? wall0.y - player.height : wall0.y + wall0.height;
}
}

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.
}
}

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?

Player velocity will never go to zero after collision?

My collision code is supposed to inverse the x velocity and reduce it to a third, then when the player is not pressing either "A" or "D" keys, the velocity should slowly reduce to zero, however, once the player collides the velocity only reduces to a small decimal between .25 and .70 (either positive or negative based on previous directions.)
//Function to determine what to do with keys
function KeyHandler():void{
//A Key Handlers
if(aKeyPressed == true){
if(Math.abs(_vx) < MaxSpeed){
_vx += -6;
}
}
//Player _vx somehow won't hit zero!!!
else if(aKeyPressed == false){
if(_vx < 0){
_vx += 1;
}
}
//D Key Handlers
if(dKeyPressed == true){
if(Math.abs(_vx) < MaxSpeed){
_vx += 6;
}
}
else if(dKeyPressed == false){
if( _vx > 0){
_vx += -1;
}
}
//W Key Handlers
if(wKeyPressed == true){
if(Jumped == false){
_vy = -15;
Jumped = true;
}
}
else if(wKeyPressed == false){
}
}
//Code for Right Collision
if(RightCollision){
while(RightCollision){
Player.x -= 0.1;
RightCollision = false;
if(_boundaries.hitTestPoint((Player.x + (Player.width / 2)), (Player.y - (Player.height / 2)), true)){RightCollision = true;}
}
_vx *= -.33
}
//Code for Left Collision
if(LeftCollision){
while(LeftCollision){
Player.x += 0.1;
LeftCollision = false;
if(_boundaries.hitTestPoint((Player.x - (Player.width / 2)), (Player.y - (Player.height / 2)), true)){LeftCollision = true;}
}
_vx *= -.33
}
Note that abs(-.25) + abs(.7) ~ 1.0
The collision sets the velocity to something that is not an integer (e.g. 2 * .33 ~ .7), so +/- 1 will skip past 0 without landing on it.
The simple fix is to keep the velocity an integer which can be done with Math.floor, for instance. (Account for the difference in +/- velocities: floor only moves numbers one direction.)
Happy coding.
Also, I am not sure how the int type works in AS3 work, which might be worth exploring.