?
Solved

actionscript 3.0 jump character

Posted on 2011-09-17
12
Medium Priority
?
873 Views
Last Modified: 2012-06-27
I'm quite new to flash/actionscript and I've got a question.
I need to make a small flash game for my school, but I can't really figure out yet how to jump correct/smoothly.

I've got the following code, this code makes sure I can walk left and right.
//Functions
function movePlayer() {
	if(pDir == "LEFT"){
		player.x -= 5;
	}
	if(pDir == "RIGHT"){
		player.x += 5;
	}
 	if(pDir == "UP"){
		
	}
} // Move the player

function rotatePlayer() {
	if(pDir == "LEFT"){
		player.rotation = 180;
	}
	if(pDir == "RIGHT"){
		player.rotation = 0;
	}
} // Rotate the player

function onTick(e:TimerEvent) {
	rotatePlayer();
	movePlayer();
}

function keyPressedDown(e:KeyboardEvent) {
	var key:uint = e.keyCode;	
	player.play();
	if(key == 100){
		pDir = "LEFT";
	}
	if(key == 102){
		pDir = "RIGHT";
	}
	if(key == 104){
		pDir = "UP";
	} 	
} // KeyPressedDown

Open in new window


Another thing is, when I switch from left to right, it does that but not smoothly. It takes about a second for the program to realize it needs to walk the other way.

Can anyone help me?
Thanks
0
Comment
Question by:ErnstJacobs
[X]
Welcome to Experts Exchange

Add your voice to the tech community where 5M+ people just like you are talking about what matters.

  • Help others & share knowledge
  • Earn cash & points
  • Learn & ask questions
  • 6
  • 5
12 Comments
 
LVL 29

Expert Comment

by:dgofman
ID: 36555414
Please can you attach your FLA file? You can save as CS4 and attach to EE
I have the errors

1120: Access of undefined property pDir.
1120: Access of undefined property player.
0
 

Author Comment

by:ErnstJacobs
ID: 36555755
Ofcourse, sorry about that. I've attached the cs4 .fla file.

cs4-app.fla
0
 
LVL 14

Expert Comment

by:tomaugerdotcom
ID: 36556803
The key to jumping, unlike your other movement, is that for a few frames, the player doesn't have complete control over the character's movement. You must consider:

1. do you want the character to be able to change horizontal direction while he's in mid-air (some games do, others do not)?

2. do you care about gravity?

3. is he just jumping over obstacles or enemies, or is he jumping up onto other things? (that makes life much more complicated)

The other things you must consider:

4. do you want the character to always jump the same height? Does the player have to keep the JUMP key held down or will the character jump the same height even if the player releases the key right away?

5. how high do you want the maximum height to be before the character starts to reverse direction and fall?


0
Get real performance insights from real users

Key features:
- Total Pages Views and Load times
- Top Pages Viewed and Load Times
- Real Time Site Page Build Performance
- Users’ Browser and Platform Performance
- Geographic User Breakdown
- And more

 

Author Comment

by:ErnstJacobs
ID: 36556942
@tomaugerdotcom
Those are very good questions

1: yes, I want it to be ale to change directions.
2: Well actually, yes. I want the game to be able to change gravity so you can walk on the ceiling.
3: Both, over enemies but also getting on platforms.
4: It Would be nice how longer you keep it pressed the higher it goes (til certain height)
5: I don't know the maximum yet really... not too high
0
 
LVL 14

Expert Comment

by:tomaugerdotcom
ID: 36558018
Okay, so the biggest issue you're going to have is collision detection against the "floor" (or ceiling) and I won't get into that because that's not really what your question is about.

So here are the kinds of things we'll do to modify your movePlayer():

First of all, replace your multiple "if" statements with a single switch { } block. Not only is this easier to follow, but right now if your player presses left AND right at the same time, both actions are being processed, which is really not necessary.

So:

switch (pDir){
 case "LEFT": 
    player.x -= 5;
    break;
  case "RIGHT":
    player.x += 5;
    break;
}

Open in new window


Okay, now that that's out of the way, the next thing we need to do make your guy go up. Now, we're not going to do all the things you want to do at this point. Let's start with the basics: you press "UP" and the guy starts to jump, he slows down because of gravity, reverses direction and ends up at the same y-position that he was at when he started the jump. Let's get that working.

// somewhere earlier
var heroJuping:Boolean = false; // will be true as long as Hero is in the air
var jumpStartingY:Number; // this will hold the hero's starting y-position so we can check when he lands
var heroVelocityY:Number = 0; // this is used to determine whether the hero moves up or down


// and then after your switch (so we can still move horizontally while jumping)
if (pDir == "UP" && ! heroJumping){
  // notice that we check to see whether our hero is ALREADY jumping.
  // This prevents the "mid-air bounce" phenomena

  heroJumping = true;
  heroVelocityY = - 20; // set this to whatever you like. The number is like the "force" of his jump.
  jumpStartingY = player.y; // store this to test whether we've "landed"
}

// and then near the end of the movePlayer code, we want to update his y-position
var newY:Number = player.y + heroVelocity; // move the character
heroVelocityY += 9.8; // effects of "gravity". The 9.8 number is actually completely bogus and can be whatever you like as long as it's positive (for normal gravity at least!)

// now we need to check whether we've "landed"
if (newY > jumpStartingY){
  // we've landed!
  newY = jumpStartingY; // set us firmly back on the "ground"
  heroJumping = false;
  heroVelocityY = 0; // he ain't jumping no more, sucka.
}

// finally, plot his new position
player.y = newY;

Open in new window

0
 
LVL 14

Expert Comment

by:tomaugerdotcom
ID: 36558025
Landing on platforms is much much trickier. In most platformers, you can jump up "through" the next level above you but then not go back through the platform after that. So you need to perform a collision detection against your character's feet, or possibly a point collision detection against his bottom registration point (easier). You also have to make sure that you're colliding with the TOP of the platform, not the bottom, and you also want to make sure you only test for collision on his way DOWN. Again, that is if you're trying to emulate a "classic" platformer mechanic.

Things get real ugly when you start messing with gravity, because then everything has to have an "upside" as well as a "downside" and your physics need to work in both directions. This makes optimization and simplification hard.

In those cases, you may just want to fart around with Box2D. I highly recommend trying http://www.sideroller.com/wck/ Box2D + World Construction Kit, which is a highly usable, very simple way to get some unbelievable physics into your games and is used in games all the time. Do yourself a favour and check that out regardless - hours of physics fun!
0
 

Author Comment

by:ErnstJacobs
ID: 36559259
I've done what you showed me and got the following code (included attachment also)
The problem is that it doesn't do anything at all yet.

import flash.display.Stage;
import flash.display.MovieClip;
import flash.events.KeyboardEvent;
import flash.utils.Timer;
import flash.events.TimerEvent;

//Declaring Variables
var stageVar:Stage = stage;
var player:MovieClip = player;
var pDir:String = "NONE";
var gameTimer:Timer = new Timer(0);
var heroJumping:Boolean = false; // true when player in air
var jumpStartingY:Number; // start position jump
var heroVelocity:Number = 0; // up or down


//Init
player.stop();
stageVar.frameRate = 31;
gameTimer.repeatCount = 0;
gameTimer.delay = 20;
gameTimer.start();

//Events
stageVar.addEventListener(KeyboardEvent.KEY_DOWN, keyPressedDown);
stageVar.addEventListener(KeyboardEvent.KEY_UP, keyPressedUp);
gameTimer.addEventListener(TimerEvent.TIMER, onTick);

//Functions
function movePlayer() {
	switch (pDir){
	 case "LEFT": 
		player.x -= 5;
		break;
	 case "RIGHT":
		player.x += 5;
		break;
	}
	if(pDir == "UP" && !heroJumping){
 		heroJumping = true;
  		heroVelocityY = - 20; // "force" of jump
 		jumpStartingY = player.y; // are we down again?
	}
	
	var newY:Number = player.y + heroVelocity; // move the player
	heroVelocityY += 9.8; // effects of "gravity"
	
	if (newY > jumpStartingY){
  		// we've landed!
		newY = jumpStartingY; // set on ground
		heroJumping = false;
		heroVelocityY = 0; // Not jumping anymore
		
		player.y = newY;
	}	
} // Move the player

function rotatePlayer() {
	if(pDir == "LEFT"){
		player.rotation = 180;
	}
	if(pDir == "RIGHT"){
		player.rotation = 0;
	}
} // Rotate the player

function onTick(e:TimerEvent) {
	rotatePlayer();
	movePlayer();
}

function keyPressedDown(e:KeyboardEvent) {
	var key:uint = e.keyCode;	
	trace(e.keyCode);
	player.play();
	if(key == 100){
		pDir = "LEFT";
	}
	if(key == 102){
		pDir = "RIGHT";
	}
	if(key == 104){
		pDir = "UP";
	} 	
} // KeyPressedDown

function keyPressedUp(event:KeyboardEvent):void {
	player.stop();
	pDir = "NONE";
}

Open in new window

cs4-d.fla
0
 
LVL 14

Expert Comment

by:tomaugerdotcom
ID: 36559908
Hey Ernst. Okay, one thing that strikes me right away is my own mistake. Since you're not using physics completely in this simulation, we should probably turn "off" gravity whenever he's NOT jumping:

so wrap lines 45 to 55 in the following if statement:
if (heroJumping){
 // .. lines 45 .. 55 go here
}

Otherwise, your guy will start to fall through the floor, even if he's not jumping!

0
 
LVL 14

Expert Comment

by:tomaugerdotcom
ID: 36559943
Next, make sure that wherever you talk about "heroVelocity" we always use the variable name "heroVelocityY". This may be a typo in my original code, or just an oversight. You were getting variable name errors in your trace.

Also, when testing the Flash Player, your keyboard event if they're expecting actual letters to be pressed, will be trapped by the IDE's keyboard shortcuts. One workaround is to use the arrow keys instead: left = 37, right = 39, up = 38.
0
 
LVL 14

Accepted Solution

by:
tomaugerdotcom earned 2000 total points
ID: 36559972
If you look at my original example, line 30 is outside the if() statement that checks to see whether the hero has landed. This is pretty important, otherwise the engine will not render the hero changin y-position until he's landed again, so you won't see him jump, even though he's jumping.

Here, take a look at some final working code. The only other change is reducing the "gravity" amount to 4 so we get a longer jump. Still looks like a flea jumping though...

import flash.display.Stage;
import flash.display.MovieClip;
import flash.events.KeyboardEvent;
import flash.utils.Timer;
import flash.events.TimerEvent;

//Declaring Variables
var stageVar:Stage = stage;
var player:MovieClip = player;
var pDir:String = "NONE";
var gameTimer:Timer = new Timer(0);
var heroJumping:Boolean = false; // true when player in air
var jumpStartingY:Number; // start position jump
var heroVelocityY:Number = 0; // up or down


//Init
player.stop();
stageVar.frameRate = 31;
gameTimer.repeatCount = 0;
gameTimer.delay = 20;
gameTimer.start();

//Events
stageVar.addEventListener(KeyboardEvent.KEY_DOWN, keyPressedDown);
stageVar.addEventListener(KeyboardEvent.KEY_UP, keyPressedUp);
gameTimer.addEventListener(TimerEvent.TIMER, onTick);

//Functions
function movePlayer() {
	switch (pDir){
	 case "LEFT": 
		player.x -= 5;
		break;
	 case "RIGHT":
		player.x += 5;
		break;
	}
	if(pDir == "UP" && !heroJumping){
 		heroJumping = true;
  		heroVelocityY = - 20; // "force" of jump
 		jumpStartingY = player.y; // are we down again?
	}
	
	if (heroJumping){
		var newY:Number = player.y + heroVelocityY; // move the player
		heroVelocityY += 4; // effects of "gravity"
		
		if (newY > jumpStartingY){
			// we've landed!
			newY = jumpStartingY; // set on ground
			heroJumping = false;
			heroVelocityY = 0; // Not jumping anymore
		}
		
		player.y = newY;
	}
} // Move the player

function rotatePlayer() {
	if(pDir == "LEFT"){
		player.rotation = 180;
	}
	if(pDir == "RIGHT"){
		player.rotation = 0;
	}
} // Rotate the player

function onTick(e:TimerEvent) {
	rotatePlayer();
	movePlayer();
}

function keyPressedDown(e:KeyboardEvent) {
	var key:uint = e.keyCode;	
	trace(e.keyCode);
	player.play();
	if(key == 37){
		pDir = "LEFT";
	}
	if(key == 39){
		pDir = "RIGHT";
	}
	if(key == 38){
		pDir = "UP";
	} 	
} // KeyPressedDown

function keyPressedUp(event:KeyboardEvent):void {
	player.stop();
	pDir = "NONE";
}

Open in new window

0
 

Author Comment

by:ErnstJacobs
ID: 36582231
Sorry for not responding yet. i cant edit/test the code since im not at hom. i will saturday. thank you
0
 

Author Closing Comment

by:ErnstJacobs
ID: 36598346
Thank you very much, it just needs some tweaking but it works now!
0

Featured Post

Use Filtering Commands to Process Files in Linux

Learn how to manipulate data with the help of various filtering commands such as `cat`, `fmt`, `pr`, and others in Linux.

Question has a verified solution.

If you are experiencing a similar issue, please ask a related question

In this tutorial I will show you how to provide a dynamic RTF document on your website generated with data from your database. For this tutorial you will need Microsoft Word or WordPad, WhizBase and Microsoft Access. In this tutorial I will show …
In threads here at EE, each comment has a unique Identifier (ID). It is easy to get the full path for an ID via the right-click context menu. However, we often want to post a short link within a thread rather than the full link. This article shows a…
The goal of the tutorial is to teach the user how to select which audio input to use. Once you have an audio input plugged into the laptop or computer, you will go into the audio input settings and choose which audio input you want to use.
This Micro Tutorial will teach to how to utilize bit rate in Adobe Flash Media Live Encoder.
Suggested Courses

752 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question