Solved

actionscript 3.0 jump character

Posted on 2011-09-17
12
744 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
  • 6
  • 5
12 Comments
 
LVL 29

Expert Comment

by:dgofman
Comment Utility
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
Comment Utility
Ofcourse, sorry about that. I've attached the cs4 .fla file.

cs4-app.fla
0
 
LVL 14

Expert Comment

by:tomaugerdotcom
Comment Utility
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
 

Author Comment

by:ErnstJacobs
Comment Utility
@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
Comment Utility
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
Comment Utility
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
Why You Should Analyze Threat Actor TTPs

After years of analyzing threat actor behavior, it’s become clear that at any given time there are specific tactics, techniques, and procedures (TTPs) that are particularly prevalent. By analyzing and understanding these TTPs, you can dramatically enhance your security program.

 

Author Comment

by:ErnstJacobs
Comment Utility
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
Comment Utility
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
Comment Utility
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 500 total points
Comment Utility
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
Comment Utility
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
Comment Utility
Thank you very much, it just needs some tweaking but it works now!
0

Featured Post

How to improve team productivity

Quip adds documents, spreadsheets, and tasklists to your Slack experience
- Elevate ideas to Quip docs
- Share Quip docs in Slack
- Get notified of changes to your docs
- Available on iOS/Android/Desktop/Web
- Online/Offline

Join & Write a Comment

I hope you'll find this tutorial useful and interesting. So let's try to extend Tcl with a new package.  For anyone more deeply interested please check out the book "Practical Programming in Tcl and Tk". It's really one of the best written books abo…
I have found that much of my time doing support ends up being a constant repetition of the same steps to different people.  Early on I stated using web pages with Frequently Asked Questions (FAQs) to alleviate most of the burden.  Sometimes this jus…
This Micro Tutorial will teach to how to utilize bit rate in Adobe Flash Media Live Encoder.
In this fourth video of the Xpdf series, we discuss and demonstrate the PDFinfo utility, which retrieves the contents of a PDF's Info Dictionary, as well as some other information, including the page count. We show how to isolate the page count in a…

771 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

Need Help in Real-Time?

Connect with top rated Experts

11 Experts available now in Live!

Get 1:1 Help Now