ActionScript 3, How to get character to jump for longer - actionscript-3

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.

Related

Gravity / velocity & jump issue (AS3, platformer)

I'm currently trying to program a flash game for Android.
I have more or less working gravity & velocity and hit tests - so I don't fall through my platforms.
The problem now is, as soon as I hit "jump", the hit test stops working and i fall through the platforms. If I set my character to a different, higher position I don't even fall down.
Can anyone help me figure this out?
Here is my code:
import flash.events.MouseEvent;
import flash.events.Event;
var gravity:Number = 2;
var velocity:Number = 1.1;
var jumpPower:Number = 0;
var isJumping:Boolean = false;
stage.addEventListener(Event.ENTER_FRAME, touchPlatform);
player.addEventListener(Event.ENTER_FRAME, appeal);
function touchPlatform(e:Event):void
{
if(kurz.hitTestObject(player))
{
hitPlatform = true;
}
else if(kurz2.hitTestObject(player))
{
hitPlatform = true;
}
}
function appeal(e:Event):void
{
gravity *= velocity;
player.y += gravity;
if(hitPlatform == true)
{
velocity = 0;
}
}
jump.addEventListener(MouseEvent.CLICK, doJump);
stage.addEventListener(Event.ENTER_FRAME, update);
function doJump(e:MouseEvent):void
{
if(!isJumping)
{
jumpPower = 30;
isJumping = true;
}
}
function update(e:Event):void
{
if(isJumping)
{
player.y -= jumpPower;
jumpPower -= 2;
}
else
{
isJumping = false;
}
}
Your issue is that once you start jumping, you never stop! No where (that can be reached) do you set isJumping to false. Also, your jumping value and your gravity are currently running in tandem, you only want one OR the other affecting your player at any given time.
Try something like this (see code comments for explainations)
import flash.events.MouseEvent;
import flash.events.Event;
var gravity:Number = 2;
var velocity:Number = 1.1;
var jumpPower:Number = 0;
var isJumping:Boolean = false;
jump.addEventListener(MouseEvent.CLICK, doJump);
function doJump(e:MouseEvent):void {
if(!isJumping){
jumpPower = 30;
isJumping = true;
}
}
//Just one ENTER_FRAME handler is better,
//then you have more control over the order in which code gets run
//I've combined your three into one and called it gameLoop
stage.addEventListener(Event.ENTER_FRAME, gameLoop);
function gameLoop(e:Event):void {
//this is the same, I just combined your 2 if's into one.
if(kurz.hitTestObject(player) || kurz2.hitTestObject(player)){
hitPlatform = true;
}
//you should set the velocity before assigning it to the player
if(hitPlatform == true){
velocity = 0;
gravity = 2; //you probably want to reset gravity to default too
isJumping = false; //SET isJumping to false now that you've hit a platform! <-------------
}else{
velocity = 1.1; //you need to reset velocity when not on a platform
}
//Now that we've determined the velocity and if we're jumping, let's move the player the appropriate amount
if(isJumping){
//Since we're currently jumping, use the jumpPower instead of gravity
player.y -= jumpPower;
jumpPower -= 2;
}else{
if(!hitPlatform){
//Since we're NOT JUMPING, and not on a platform, use gravity.
gravity *= velocity;
player.y += gravity;
}
}
}

Move and Scale a MovieClip smoothly between multiple points

I have a set-up of 3 horizontal rows with a button aligned to each of them and a character (centered to each row) that I want to move between these rows (think of Little Big Planet). I was able to program it so the character moves between the 3 rows and has a set scale when it does, but I want to see the character actually moving between the points; not just watch it teleport to the location. I've tried everything I can think of: Loops, Boolean on/off, some velocity/distance/difference shenanigans, etc., but I'm having no success getting it to move at a button click and continue moving until it reaches its point. I'm also not sure if it can be set-up to scale incrementally until it reaches a desired end scale size or not. I saw a slightly similar problem asked on a site, but solution they gave uses the Point class and a lot of math, and I have never had success getting my Flash to use Points. Any suggestions would be appreciated.
package
{
import flash.display.MovieClip;
import flash.events.Event;
import flash.events.MouseEvent;
public class Main_Test_5 extends MovieClip
{
private var cam:MovieClip = new MovieClip();
private var player:Player = new Player();
private var topPosition:uint = 170;
private var centerPosition:uint = 270;
private var bottomPosition:uint = 370;
private var UI:UserInterface = new UserInterface();
private var testBackground:TestBackground = new TestBackground();
public function Main_Test_5():void
{
player.x = 100;
player.y = 370;
cam.addChild(player);
addChild (UI);
// add event listeners
stage.addEventListener(Event.ENTER_FRAME, checkEveryFrame);
UI.topButton.addEventListener(MouseEvent.CLICK, topButtonClick);
UI.centerButton.addEventListener(MouseEvent.CLICK, centerButtonClick);
UI.bottomButton.addEventListener(MouseEvent.CLICK, bottomButtonClick);
addChild (cam);
}
public function checkEveryFrame(event:Event):void
{
cam.x -= player.x - player.x;
cam.y -= player.y - player.y;
}
public function topButtonClick (event:MouseEvent):void
{
trace ("Top Click");
if (player.y > topPosition) // 170, player.y starts at 370
{
player.y -= 100;
}
else if (player.y <= topPosition)
{
player.y = topPosition;
}
if (player.y == topPosition)
{
player.scaleY = 0.8;
player.scaleX = 0.8;
}
else if (player.y != topPosition)
{
player.scaleY = 0.9;
player.scaleX = 0.9;
}
}
public function centerButtonClick (event:MouseEvent):void
{
trace ("Center Click");
if (player.y > centerPosition) // 270
{
player.y -= 100;
}
if (player.y < centerPosition)
{
player.y += 100;
}
if (player.y == centerPosition)
{
player.scaleY = 0.9;
player.scaleX = 0.9;
}
}
public function bottomButtonClick (event:MouseEvent):void
{
trace ("Bottom Click");
if (player.y < bottomPosition) // 370
{
player.y += 100;
}
if (player.y >= bottomPosition)
{
player.y = bottomPosition;
}
if (player.y == bottomPosition)
{
player.scaleY = 1;
player.scaleX = 1;
}
else if (player.y != bottomPosition)
{
player.scaleY = 0.9;
player.scaleX = 0.9;
}
}
}
}
Sounds like you'd like something simple. So I would suggest using a Tweening library. The most prolific of which is Greensocks TweenLite, which is now part of their Animation Platform
Using tweenlite, you would just do the following:
In place of:
player.y += 100;
You would do:
TweenLite.to(player, 1,{y: player.y + 100, ease: Quad.EaseInOut});
This would tween (move gradually over time) your player object from it's current position to the specified y (player.y + 100). It would do it over 1 second and with a nice in and out ease.
You can add more properties to the tween (scaleX/Y, x) anything really.
Do note, there are many Tweening platform alternatives, including one baked into Flash Professional. TweenLite is not free to use if you charge your end users a fee for your application. Be sure to review their license if you use it commercially.

AS3 Smooth Jumping

I would like to know how to make a smooth jump in my game. Its a 2D game and the code is really simple but I would want to know how to make it better for it to slow down when it gets to the max height and then smooth drop.
This is all I have for jumping:
Player.y -= 50;
Your best bet would be to use a physics engine (Box2d etc). If you don't want the overhead of one though (if the only thing you'd use it for is jumping and not collisions) then you just need to add some friction to your logic.
var friction :Number = .85; //how fast to slow down / speed up - the lower the number the quicker (must be less than 1, and more than 0 to work properly)
var velocity :Number = 50; //how much to move every increment, reset every jump to default value
var direction :int = -1; //reset this to -1 every time the jump starts
function jumpLoop(){ //lets assume this is running every frame while jumping
player.y += velocity * direction; //take the current velocity, and apply it in the current direction
if(direction < 0){
velocity *= friction; //reduce velocity as player ascends
}else{
velocity *= 1 + (1 - friction); //increase velocity now that player is falling
}
if(velocity < 1) direction = 1; //if player is moving less than 1 pixel now, change direction
if(player.y > stage.stageHeight - player.height){ //stage.stageheight being wherever your floor is
player.y = stage.stageHeight - player.height; //put player on the floor exactly
//jump is over, stop the jumpLoop
}
}
Copy/paste the following code... jump() can be replaced by jump2() (without bouncing effect). The jumping will be produced by the space bar:
const FA:Number = .99; // air resistance
const CR_BM:Number = .8; // bouncing coefficient
const µ:Number = .03; // floor friction
const LB:int = stage.stageHeight; // floor (bottom limit)
const G:int = 2.5; // gravity
const R:int = 50;
var ball:MovieClip = new MovieClip();
this.addChild(ball);
var ba:* = ball.graphics;
ba.beginFill(0xFFCC00);
ba.lineStyle(0, 0x666666);
ba.drawCircle(0, 0, R);
ba.endFill();
ball.vx = 2;
ball.vy = -30;
ball.r = R;
ball.x = 100;
ball.y = LB - R;
stage.addEventListener(KeyboardEvent.KEY_DOWN, myKeyDown);
function myKeyDown(e:KeyboardEvent):void {
if (e.keyCode == Keyboard.SPACE) {
ball.vy = -30;
addEventListener(Event.ENTER_FRAME, jump);
}
}
function jump(e:Event):void {
ball.vy = ball.vy + G;
ball.vx *= FA;
ball.vy *= FA;
ball.x += ball.vx;
ball.y += ball.vy;
if (ball.y > LB - ball.r) {
ball.y = LB - ball.r;
ball.vy = -1 * ball.vy * CR_BM;
ball.vx += ball.vx * - µ;
}
}
/*
function jump2(e:Event):void {
ball.vy = ball.vy + G;
ball.vx *= FA;
ball.vy *= FA;
ball.x += ball.vx;
ball.y += ball.vy;
if (ball.y > LB - ball.r) {
ball.y = LB - ball.r;
}
}
*/

Make movie clip 'Enemy' follow 'player' instead of walking on set xy axis? Flash, AS3

curious to know if I can somehow make the enemy movie clip in my flash game follow the movie clip the player controls, called 'player' in this instance. At the minute, it's just set to walk -3 on X and 1.5 on Y.
Not really sure if I need to post any code on here, just in case, here is my code inside the Enemy Movie clip.
Thanks in advance!
import flash.events.MouseEvent;
var catxSpeed:Number = -3;
var catySpeed:Number = 1.5;
var myParent:*;
var ground:Number;
var jumping:Boolean = false;
var health:Number;
this.addEventListener(Event.ENTER_FRAME, updatecat);
function updatecat(event:Event):void
{
this.x += catxSpeed;
if(myParent.player.hitTestObject(this))
{
myParent.hit();
}
this.y += catySpeed;
if(jumping == true)
{
catySpeed +=1;
if(this.y >= ground)
{
catxSpeed = -3;
catySpeed = 0;
this.y = ground;
jumping = false;
if(health < 1)
{
shutDown();
}
}
}
}
function activate(passParent:*):void
{
ground = this.y;
this.addEventListener(Event.ENTER_FRAME, updatecat);
this.addEventListener(MouseEvent.MOUSE_DOWN, hit);
myParent = passParent;
health = Math.round(myParent.randomise(2,4));
}
function shutDown():void
{
this.removeEventListener(Event.ENTER_FRAME, updatecat);
this.parent.removeChild(this);
}
function hit(event:MouseEvent):void
{
catxSpeed = 30;
catySpeed = -15;
jumping = true;
myParent.addToScore(1);
health--;
}
if (enemy.x > this.x) this.x += catxSpeed;
else this.x -= catxSpeed;
if (enemy.y > this.y) this.y += catySpeed;
else this.y -= catySpeed;

Flash AS3 Snooker Game

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!