I'm trying to make flappy birds in actionscript (just for practicing and fun). This is my first programming language and I'm still new to this.
So the problem starts here, I want to make the bird rotates (as the real flappy bird does) every 2 seconds when no button is pressed. But it turned out that the timer still activates after I pressed spacebar again which I think it is supposed to stop the last timer first before activating the new one.
If I press spacebar 2 times, the timer will activate twice. Without stopping the timer first.
Code :
stage.addEventListener (KeyboardEvent.KEY_DOWN, jump);
function jump(event: KeyboardEvent):void
{
var myTimer4:Timer = new Timer (2000)
if(event.keyCode == 32)
{bird.y=bird.y-40;
bird.rotation=0;
myTimer4.stop();
myTimer4.start();
}
myTimer4.addEventListener(TimerEvent.TIMER, fall);
function fall (e:TimerEvent):void{
bird.rotation=40;
myTimer4.stop();
}
I think the problem might be you are creating a new instance of Timer every time the key is pressed and myTimer4 takes in a new reference. Try removing it outside the function scope like this:
var myTimer4:Timer = new Timer (2000);
function jump(event: KeyboardEvent):void
{
if(event.keyCode == 32)
{bird.y=bird.y-40;
bird.rotation=0;
myTimer4.stop();
myTimer4.start();
}
onClipEvent (load) {
power = 0.3;
yspeed = 0;
xspeed = 0;
friction = 0.95;
gravity = 0.5;
thrust = 3.75;
wind = 0.18;
_root.level1_text.text = 0+collected_coin19;
reverse = new Sound();
reverse.attachSound("hit2");
}
onClipEvent (enterFrame) {
if (Key.isDown(Key.LEFT)) {
xspeed -= power;
}
if (Key.isDown(Key.RIGHT)) {
xspeed += power;
}
if (Key.isDown(1)) {
yspeed -= power*thrust;
}
if (Key.isDown(Key.SPACE)) {
yspeed -= power*thrust;
}
xspeed += wind;
xspeed *= friction;
yspeed += gravity;
_y += yspeed;
_x += xspeed;
Try This one Might Help you
Related
I am making a platformer game in Flash (AS3) and the code I have below works. I want my character to jump high enough to allow it time to reach a platform. The only problem with code below is the speed at which it jumps up and down and the height of the jump. Tthe space bar is what triggers the function to run.
Please help as I would much appreciate it! :)
Player.addEventListener(Event.ENTER_FRAME, fl_MoveInDirectionOfKey);
stage.addEventListener(KeyboardEvent.KEY_DOWN, fl_SetKeyPressed);
stage.addEventListener(KeyboardEvent.KEY_UP, fl_UnsetKeyPressed);
function fl_MoveInDirectionOfKey(event:Event)
{
if (spacePressed){
var gravity:Number = 9.8;
var jumping:Boolean = false;
var jumpVar:Number = 0;
if(jumping != true)
{
jumpVar = -70;
jumping = true;
}
if(jumping)
{
spacePressed = false;
Player.y += jumpVar;
jumpVar += gravity;
}
Player.addEventListener(Event.ENTER_FRAME, drop);
function drop(event:Event)
{
Player.y -= jumpVar;
jumpVar -= gravity;
if(Player.y > 350){
Player.y = 350;
}
}
Player.removeEventListener(Event.ENTER_FRAME, fl_MoveInDirectionOfKey);
Player.addEventListener(Event.ENTER_FRAME, fl_MoveInDirectionOfKey);
/*var frameNumb:Number = 0;
Player.addEventListener(Event.ENTER_FRAME, jumpup);
spacePressed = false;
function jumpup(event:Event)
{
while(frameNumb < 30){
spacePressed = false;
Player.y -= 1;
frameNumb += 0.5;
}
Player.removeEventListener(Event.ENTER_FRAME, jumpup);
Player.addEventListener(Event.ENTER_FRAME, jumpdown);
function jumpdown(){
while(frameNumb > 0){
spacePressed = false;
Player.y += 1;
frameNumb -= 0.5;
}
}
}*/
}
if (leftPressed)
{
Player.x -= speed;
Player.gotoAndStop("left");
}
if (rightPressed)
{
Player.x += speed;
Player.gotoAndStop("right");
}
}
Thanks
Your use of 9.8 for gravity is meters-per-second-per-second. Since drop() is executed every frame, you're going to get some serious fast-forward gravity, unless the program is doing only 1 FPS. So, assuming you want more fluidity than 1 FPS, consider doing
jumpVar += gravity/fps;
However, to get the exact velocity required to lift you to a height, I think the calculation is...
initialVelocityInMetersPerSecond = Math.sqrt( 2 * gravity * metersToJump )
So instead of jumpVar = -70, you would do something like...
// get posititive distance since we'll use to get a square root
var metersToJump:Number = Player.y - platform.y;
jumpVar = -Math.sqrt( 2 * gravity * metersToJump );
...and then in the ENTER_FRAME handler...
Player.y += jumpVar / fps;
jumpVar += gravity / fps;
From your example it's not the case, but if you place the platform below the Player, it won't work as you can't get the root of a negative number!
In my example code I am not fixing the height of the platform, so how you decide on the target platform is a completely separate matter.
Still learning AS3. I would love to know more about these 2 simple statements.
My educated guess is movement or gravity on the x/y co-ords?
var dx:Number = x;
var dy:Number = x;
Much appreciation!
So the code makes the character if jumping, move up at a gradually slower rate until it hits the ground again, where isJumping becomes false again. Each time the character jumps the isJumping is made true again and the cycle repeats (jumpPower is what controls how high). There is also gravity, which is also controlling how fast the jump falls.. however! I would like to point out a major flaw in this code..
jumpPower should not be controlling how fast he falls, gravity should. When jumpPower reaches zero, it then begins to fall into the negatives untill the character reaches the ground. This means that gravity + jumpPower will both be speeding the character to the ground.
I don't know if you meant to do this, but I would recommend having only gravity being the thing sending your character to the ground. A better way to code this would to give the character a velocity, which you apply to its x and y cords each enter frame.
Something like this..
velocityY += gravity;
MainChar.y += velocityY;
This way, when the character jumps, you only need to call this once:
velocityY += jumpPower;
...
Your code with velocity...
var dx:Number = x; // Not sure what these are
var dy:Number = x; // Not sure what these are
var velocityX:Number = 0;
var velocityY:Number = 0;
function doJump(evt:MouseEvent):void {
if(!isJumping) {
jumpPower = -30;
velocityY += jumpPower;
isJumping = true;
}
}
function update(evt:Event):void {
if(MainChar.y + gravity < ground) {
velocityY += gravity
MainChar.y += velocityY;
} else {
velocityY = 0;
MainChar.y = ground;
isJumping = false;
}
}
....
Final note. How come your MainChar is a static class?
I suppose the point is, not much can be answered about this question as I don't expect we have all of the code here.
On one hand you don't need to use these 2 variables dx and dy. On the contrary you forgot to declare the variables used in the code: gravity, jumpPower, isJumping and ground.
On the other hand it's better to use enterFrame event only when necessary and remove it at the end of the movement (in your function update).
At last you don't need to use your boolean variable isJumping (by actualising the value of your variable jumpPower = 30 at the end of your function update).
So your code should really be more simple:
stage.addEventListener(MouseEvent.MOUSE_DOWN, doJump);
const GRAVITY:int = 3;
var jumpPower:int = 0;
var ground:int = stage.stageHeight - MainChar.height;
function doJump(evt:MouseEvent):void {
addEventListener(Event.ENTER_FRAME, update);
}
function update(evt:Event):void {
MainChar.y -= jumpPower;
jumpPower -= 2;
MainChar.y += GRAVITY;
if(MainChar.y + GRAVITY > ground) {
MainChar.y = ground;
jumpPower = 30;
removeEventListener(Event.ENTER_FRAME, update);
}
}
So I would like to add velocity to my swipe gesture. Currently I have it moving 10 px on swipe, but I want it to move with a velocity so the user can toss the object around on the screen. Here's the code I am currently using with the object moving the 10 px.
function onSwipe (e:TransformGestureEvent):void{
player_mc.gotoAndStop(5);
if (e.offsetX == 1) {
//User swiped towards right
player_mc.x += 10;
}
if (e.offsetX == -1) {
//User swiped towards left
player_mc.x -= 10;
}
if (e.offsetY == 1) {
//User swiped towards bottom
player_mc.y += 10;
}
if (e.offsetY == -1) {
//User swiped towards top
player_mc.y -= 10;
}
if(collision(player_mc.cp, level_mc))
{
player_mc.x = player_mc.prevX;
player_mc.y = player_mc.prevY;
}
}
Thanks for the help
Here is a way you can do this: (you'll want to swap the mouse events for touch events if using on mobile)
player_mc.addEventListener(MouseEvent.MOUSE_DOWN,startSwipe);
player_mc.addEventListener(MouseEvent.MOUSE_UP,endSwipe);
var velocity:Point = new Point(); //this stores the current velocity of the object
var previous:Point = new Point(); //this stores the previous frames x/y of the object.
var isDragging:Boolean = false;
var friction:Number = .85; //this how quickly to slow down the object once the mouse is released - smaller the number (must be less than 1) the quicker the object will slow/stop
function startSwipe(e){
isDragging = true;
player_mc.startDrag(false);
this.addEventListener(Event.ENTER_FRAME,enterFrameHandler);
}
function enterFrameHandler(e):void {
if(isDragging){
velocity.x += player_mc.x - previous.x; //we're adding the new velocity to the old one, then dividing in half to average the value - this makes it seem smoother
velocity.y += player_mc.y - previous.y;
velocity.x *= .5; //dividing in half
velocity.y *= .5;
previous.x = player_mc.x;
previous.y = player_mc.y;
}else{
velocity.x *= friction; //gradually slow down the object
velocity.y *= friction;
player_mc.x += velocity.x;
player_mc.y += velocity.y;
if(velocity.x < .05 && velocity.y < .05){ //once it gets slow enough, stop the enter frame handler
this.removeEventListener(Event.ENTER_FRAME,enterFrameHandler);
}
}
trace(velocity);
}
function endSwipe(e){
player_mc.stopDrag();
isDragging = false;
}
The question is clear. Character is stable on the stage and background and ground is moving. But when character hits the ground, it bounces again and again. Here is the code. how can i solve it? When i move the character its working perfect but when the moving object is ground bouncing problem happens.
here is the problem : http://www.swfcabin.com/open/1391814250
public function controller():void
{
if (rightKey || leftKey || jumpKey)
{
if (rightKey)
{
if (jumpWalk || canJump)
{
hero.gotoAndStop(2);
hero.scaleX = 1;
xSpeed -= speed;
}
}
if (leftKey)
{
if (jumpWalk || canJump)
{
hero.gotoAndStop(2);
hero.scaleX = -1;
xSpeed += speed;
}
}
if (jumpKey && canJump)
{
ySpeed += 15;
canJump = false;
}
}
else
{
hero.gotoAndStop(1);
}
if(!canJump){
hero.gotoAndStop(3);
}
ySpeed -= gravity;
if(ySpeed >10){
ySpeed = 10;
}
else if(ySpeed < -10){
ySpeed = -10;
}
if(xSpeed>10){
xSpeed = 10
}
else if(xSpeed < -10){
xSpeed = -10;
}
xSpeed *= 0.8;
level.x += xSpeed;
level.y += ySpeed;
}// controller function
public function loop(event:Event):void
{
controller();
while(level.hitTestPoint(hero.x , hero.y + hero.height/2 -1 - ySpeed , true)){
trace(ySpeed +"dasd");
ySpeed ++;
canJump = true;
} }
Here is what is happening now: when you are embedded in terrain, you are increasing the ySpeed -- the upward momentum -- until one 'tick' pulls the character out of the ground. But then the character is flying upward, because you increased their upward momentum. They still have that upward momentum until gravity pulls them back down, so they will keep 'bouncing'. To fix this, do the following:
Instead of ySpeed ++; in the main loop, try level.y++; This would represent pulling the hero out of the terrain when he is embedded (or actually pulling the terrain down, since your character is stationary), instead of changing his momentum to get him out.
You should also add ySpeed = 0; in there. That would represent losing all of your y-momentum when you hit the ground.
So your main loop would look like this:
public function loop(event:Event):void
{
controller();
while(level.hitTestPoint(hero.x , hero.y + hero.height/2 -1 - ySpeed , true)){
trace(ySpeed +"dasd");
level.y++;
ySpeed = 0;
canJump = true;
} }
So, I'm absolutely useless at Flash and stupidly thought creating a Snooker game wouldn't be too difficult for a school Assignment. I grossly underestimated.
I'm trying to make the cueBall MovieClip move towards the point where the Mouse clicked on the Stage.
So far I have made the cueBall move to the point where the Mouse clicked, but I need it to keep going (unless obstructed).
I think I need to somehow calculate the angle between the cueBall MovieClip and the Mouse and then tell the MovieClip to start moving in that direction.
Suggestions? It's probably something simple, I bet...
Thanks in advance.
addEventListener(Event.ENTER_FRAME, gameSetup);
var VelocityX;
var VelocityY;
var speed = 1;
var shootCount = 0;
var mouseXPos;
var mouseYPos;
function gameSetup(e:Event) {
removeEventListener(Event.ENTER_FRAME, gameSetup);
addEventListener(Event.ENTER_FRAME, aim);
addEventListener(Event.ENTER_FRAME, shoot);
}
function aim(e:Event) {
cueStick.x = cueBall.x;
cueStick.y = cueBall.y;
cueStick.rotation = (Math.atan2(mouseY-cueStick.y, mouseX-cueStick.x))*(180/Math.PI);
if (mouseX > 25.5 && mouseX < 614.5) {
aimBall.visible = true;
aimBall.x = mouseX;
} else if (mouseX < 25.5) {
aimBall.x = 25.5;
} else if (mouseX > 614.5) {
aimBall.x = 614.5;
}
if (mouseY > 25.5 && mouseY < 294.5) {
aimBall.visible = true;
aimBall.y = mouseY;
} else if (mouseY < 25.5) {
aimBall.y = 25.5;
} else if (mouseY > 294.5) {
aimBall.y = 294.5;
}
if (mouseX > 0 && mouseX < 640 && mouseY > 0 && mouseY < 320) {
Mouse.hide();
} else {
Mouse.show();
}
addEventListener(MouseEvent.MOUSE_DOWN, drawCue);
}
function drawCue(e:MouseEvent) {
removeEventListener(Event.ENTER_FRAME, aim);
addEventListener(MouseEvent.MOUSE_UP, shotAnim);
}
function shotAnim(e:MouseEvent) {
mouseXPos = mouseX;
mouseYPos = mouseY;
cueStick.rotation = (Math.atan2(mouseYPos-cueStick.y, mouseXPos-cueStick.x))*(180/Math.PI);
VelocityX = Math.cos(mouseX-cueBall.x) * speed;
VelocityY = Math.sin(mouseY-cueBall.y) * speed;
cueStick.gotoAndPlay(2);
}
function shoot(e:Event) {
if (shootCount == 1) {
cueBall.x += VelocityX;
cueBall.y += VelocityY;
trace(VelocityX);
trace(VelocityY);
cueStick.visible = false;
} else {
cueStick.visible = true;
}
}
Maybe this example is helpful to you:
http://www.emanueleferonato.com/2008/01/05/complete-flash-pool-game-with-highscores/
If I'm understanding you right, you already have it setup so that when the mouse is clicked, the ball teleports to the mouse's location.
What you want is for the ball to move to the mouse's position over a period of time.
To do this, you will use something called an EnterFrame event. EnterFrame calls a function every frame, which you need to get the ball smoothly rolling to the mouse.
addEventListener(Event.ENTER_FRAME,update);
function update(event:Event) {
// move the ball a little bit toward the mouse
}
Then, you need to determine in what direction the ball needs to roll. You will do this with trigonometric functions. In your OnClick handler, write something like:
VelocityX = Math.cos(mouse.x-ball.x) * SPEED;
VelocityY = Math.sin(mouse.y-ball.y) * SPEED;
Then, each frame, move the ball by that amount.
addEventListener(Event.ENTER_FRAME,update);
function update(event:Event) {
ball.x += VelocityX;
ball.y += VelocityY;
}
Hope that helped!