-
Collision problems
Hi
I'm trying to make a game, but I am having some small problems.
I've been following some tutorials trying to get movement, collision and scrolling right but the tutorials are all pretty different.
Anyway, I have two problems. The biggest one is that the jumping function is.... Sketchy at best. Sometimes if you jump the player sprite will fall through the level when you hit something, sometimes the player will go through half a block before stopping and sometimes it will look fine. I've tried to find out why this is, but it seems to be completely random.
I would also appreciate some suggestions as to how I would integrate walls that work when it comes to stopping the character. I have an idea for this which would be to set the speed variable to 0 whenever the player hits a block and then reset it every time the move function is enabled again (This was how I did it without the scrolling) but I do not know how to integrate it here.
Anyway, the code is sort of messy. (Also, if it's relevant the player is 32 pixels long and 64 tall)
Code:
//********************************************
//********************************************
//*******Misc variable list*******************
//********************************************
//********************************************
//Defines the true or false value of keys
var varRight:Boolean = false;
var varLeft:Boolean = false;
var varUp:Boolean = false;
var varDown:Boolean = false;
//Defines player speed
var speed:Number = 10;
//Jumping variables
var jumping:Boolean = false;
var jumpSpeedLimit:int = 25;
var jumpSpeed:Number = jumpSpeedLimit;
var playerOnGround:Boolean = false;
//Event listeners checking if events happen
stage.addEventListener(Event.ENTER_FRAME, movement);
stage.addEventListener(KeyboardEvent.KEY_DOWN , checkKeys);
stage.addEventListener(KeyboardEvent.KEY_UP, keyUps);
//********************************************
//********************************************
//*******Player code and functions************
//********************************************
//********************************************
//Checks if keys are down
function checkKeys(event:KeyboardEvent){
if (event.keyCode == 68) {
varRight = true;
}
if (event.keyCode == 87) {
varUp = true;
}
if (event.keyCode == 65) {
varLeft = true;
}
if (event.keyCode == 83) {
varDown = true;
}
}
//Checks if keys are up
function keyUps(event:KeyboardEvent) {
if (event.keyCode == 68) {
event.keyCode = 0;
varRight=false;
}
if (event.keyCode == 87) {
event.keyCode = 0;
varUp=false;
}
if (event.keyCode == 65) {
event.keyCode = 0;
varLeft=false;
}
if (event.keyCode == 83) {
event.keyCode = 0;
varDown=false;
}
}
//jumping function
function jump():void{
//if player isn't already jumping
if(!jumping){
//then start jumping
jumping = true;
jumpSpeed = jumpSpeedLimit*-1;
blockHolder.y -= jumpSpeed;
} else {
//then continue jumping if already in the air
//crazy math that I won't explain
if(jumpSpeed < 0){
jumpSpeed *= 1 - jumpSpeedLimit/125;
if(jumpSpeed > -jumpSpeedLimit/5){
jumpSpeed *= -1;
}
}
if(jumpSpeed > 0 && jumpSpeed <= jumpSpeedLimit){
jumpSpeed *= 1 + jumpSpeedLimit/50;
}
blockHolder.y -= jumpSpeed;
for(var i:int = 0;i<blockHolder.numChildren; i++){
//getting the current block
var hitBlock:DisplayObject = blockHolder.getChildAt(i);
//checking hit test
if(player.hitTestObject(hitBlock)){
//if player is falling down
if(jumpSpeed > 0){
//stop jumping
jumping = false;
//and set the guys coordinates to be on top of the block
player.y = hitBlock.y - player.height/2;
//he's on solid ground
playerOnGround = true;
//break out of the loop
break;
} else {
jumpSpeed = Math.abs(jumpSpeed);
//making the main guy get away from the block
player.y = hitBlock.y + hitBlock.height + 1;
}
}
}
}
}
function resetspeed():void{
speed = 10;
}
//Moves the player according to check keys functions.
function movement(event:Event):void{
//The colission checker
for(var i:int = 0;i<blockHolder.numChildren; i++){
//getting the current block
var hitBlock:DisplayObject = blockHolder.getChildAt(i);
//checking hit test and if main is above the brick
if(player.hitTestObject(hitBlock) && player.y < hitBlock.y){
//this time, we just make playerOnGround true
playerOnGround = true;
//and break from the loop
break;
}
playerOnGround = false;
}
//then we make him fall if he isn't on ground
if(!playerOnGround){
jumping = true;
}
//reset speed so player can move again
//resetspeed();
if (varRight == true) {
blockHolder.x -= speed;
}
if (varUp || jumping) {
jump();
}
if (varLeft == true) {
blockHolder.x += speed;
}
}
//********************************************
//********************************************
//*******Level codes and stuff****************
//********************************************
//********************************************
//levelcount
var lvlCurrent:int = 1;
//this variable will hold the character
var X:String = 'PLAYER';
//current row we are creating
var row:int = 0;
//the array for level 1
var lvlArray1:Array = new Array(
1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,
1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,
1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,
1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,
1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,
1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,
1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,
1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,
1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,
1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,
1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,
1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,
1,0,0,0,0,0,0,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,
1,0,0,0,0,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,
1,0,0,1,1,1,1,0,0,0,0,0,0,0,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,
1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,
1,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,
1,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,
1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,
1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,
1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,
1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,
1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,
1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1
);
//this guy will hold all of the blocks
var blockHolder:Sprite = new Sprite();
//then we add him to stage
addChild(blockHolder);
function createLvl():void{
//getting the current level that we are on
var lvlArray:Array = MovieClip(root)['lvlArray'+lvlCurrent];
//we have to find how far this level goes
//this will be used so we know when to move to the next row
//there will always be 24 rows, so this is how we find it out
//of course, this will make the lvl formatting very strict
var lvlColumns:int = Math.ceil(lvlArray.length/24);
//now we must create the level
for(var i:int = 0;i<lvlArray.length;i++){
//checking if we move onto the next row
//this checks if i is divisible by the # of columns
if(i/lvlColumns == int(i/lvlColumns)){
row ++;
}
if(lvlArray[i] == 1){
//making a new block
var newBlock:Block = new Block();
//drawing the block
newBlock.graphics.beginFill(0x000000/*The color for shape*/,1/*The alpha for the shape*/);
//turning the shape into a square
newBlock.graphics.drawRect(0,0,32,32);
//change the coordinates of the block
newBlock.x = (i-(row-1)*lvlColumns)*newBlock.width;
newBlock.y = (row-1)*newBlock.height;
//then finally adding it to stage
blockHolder.addChild(newBlock);
} else if (lvlArray[i] == 'MAIN'){
player.x = (i-(row-1)*lvlColumns)*newBlock.width;
player.y = (row-1)*newBlock.height;
}
}
//reset the row for another use
row = 0;
//then we center the screen on the main character
//this variable will tell us how far away we have to move everything
//400 is about centered for player we'll use that number
//mainmovey is the vertical thing, so just do the right thing
var mainMove:int = 400 - player.x;
var mainMovey:int = 300 - player.y;
//then move player and the entire level to center on him
player.x += mainMove;
blockHolder.x += mainMove;
player.y += mainMovey
blockHolder.y +=mainMovey
}
//running the createlvl funciton
createLvl();
All help is appreciated.
-
Senior Member
- The right of the People to create Flash movies shall not be infringed. -
-
Alright, so I kind of got it to work, this is still just a movement thing making sure player doesn't fall through the floor.
The problem is that the player instance is jumping a lot when standing still on a block.
Here's the updated move function (I scrapped the jump function for now, I'm going to work on that later)
Code:
//The colission checker
function collcheck():void{
for (var i:int=0; i < blockHolder.numChildren; i++) {
//getting the current block
var hitBlock:DisplayObject = blockHolder.getChildAt(i);
//checking hit test and if main is above the brick
if (player.hitTestObject(hitBlock) && player.y < hitBlock.y) {
//player.y -= 16;
blockHolder.y += 32;
stopscrolly = true;
}
else
{
stopscrolly = false;
}
}
}
//Moves the player according to check keys functions.
function movement(event:Event):void{
//then we check collision
collcheck();
//reset speed so player can move again
resetspeed();
//Gravity effect!
if (stopscrolly == true){
graveff = 0;
}
else
{
graveff = 25;
}
gravity();
if (varRight == true) {
blockHolder.x -= speed;
}
if (varUp || jumping) {
jump();
}
if (varLeft == true) {
blockHolder.x += speed;
}
}
-
Pumpkin Carving 2008
Maybe replace:
with
Code:
player.y = hitBlock.y - player.height;
The 'Boose':
ASUS Sabertooth P67 TUF
Intel Core i7-2600K Quad-Core Sandy Bridge 3.4GHz Overclocked to 4.2GHz
8GB G.Skill Ripjaws 1600 DDR3
ASUS ENGTX550 TI DC/DI/1GD5 GeForce GTX 550 Ti (Fermi) 1GB 1GDDR5 (Overclocked to 1.1GHz)
New addition: OCZ Vertex 240GB SATA III SSD
WEI Score: 7.6
-
Nope.
I think the whole blockHolder.y vs player.y is confusing me a whole lot.
EDIT: Also, maybe relevant I have a function that moves blockHolder (The gravity function) down.
Last edited by organburner; 09-28-2009 at 02:25 PM.
-
I ve already done this you should have a look to my code. It's open source so you are free to use it if you mentionned me.
- http://sourceforge.net/
- http://angelstreetv2.free.fr/as3/IsoEngine_AS3.swf
-
Sorry, since this is a school project I really should do this myself with the help of tutorials instead of just using someone's engine.
-
Alright, so I got the vertical collision to kind of work (Still need to work in a jump function and horizontal collision though)
This is the part of the code I changed
Code:
//The colission checker
function collcheck():void{
for (var i:int=0; i < blockHolder.numChildren; i++) {
//getting the current block
var hitBlock:DisplayObject = blockHolder.getChildAt(i);
//checking hit test and if main is above the brick
if (player.hitTestObject(hitBlock) && player.y < hitBlock.y) {
blockHolder.y += player.height/8.7;
stopscrolly = true;
}
else
{
graveff = 15;
stopscrolly = false;
}
}
}
//Moves the player according to check keys functions.
function movement(event:Event):void{
//then we check collision
collcheck();
//reset speed so player can move again
resetspeed();
//Gravity effect!
while (stopscrolly == true){
graveff = 0;
break;
}
Also changed gravity effect to 15. If I change that I need to recalculate the player.height/8.7 line to make it perfect (If I had the gravity to 25 and had the correct calculation however, the player would move 15 or so pixels into the block before stopping)
Anyone have any good ideas about the horizontal collision?
Last edited by organburner; 10-02-2009 at 12:42 PM.
-
Double post, but I thought I'd post the way I got it to work properly.
I went into the player symbol, and created four boxes just barely extruding from the player, called them hitbox and then the direction they were facing (So hitboxbottom, hitboxright hitboxleft etc) and then I made them invisible by turning alpha down to zero.
So then all I had to do was to check for player.hitbox collision and then turn that speed down until there was no collision anymore. It's a crude way to do it, and probably not efficient at all, but I am in a hurry to get this done.
I still need to create the jump function (I just need to make it so that the player doesn't teleport 90 pixels into the air instantly)
There also seems to be some bug where the player will go down into the blocks if they are at a certain height.
Anyway, hitboxes.
Posting Permissions
- You may not post new threads
- You may not post replies
- You may not post attachments
- You may not edit your posts
-
Forum Rules
|
Click Here to Expand Forum to Full Width
|