A Flash Developer Resource Site

Results 1 to 9 of 9

Thread: Collision problems

  1. #1
    Junior Member
    Join Date
    Sep 2009
    Posts
    22

    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.

  2. #2
    Senior Member cancerinform's Avatar
    Join Date
    Mar 2002
    Location
    press the picture...
    Posts
    13,449
    Moved to Games forum.
    - The right of the People to create Flash movies shall not be infringed. -

  3. #3
    Junior Member
    Join Date
    Sep 2009
    Posts
    22
    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;
    
    }
    }

  4. #4
    Pumpkin Carving 2008 ImprisonedPride's Avatar
    Join Date
    Apr 2006
    Location
    Grand Rapids MI
    Posts
    2,378
    Maybe replace:

    Code:
    		//player.y -= 16;
    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

  5. #5
    Junior Member
    Join Date
    Sep 2009
    Posts
    22
    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.

  6. #6
    Isometric Engine AS3
    Join Date
    Apr 2009
    Location
    France
    Posts
    18
    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

  7. #7
    Junior Member
    Join Date
    Sep 2009
    Posts
    22
    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.

  8. #8
    Junior Member
    Join Date
    Sep 2009
    Posts
    22
    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.

  9. #9
    Junior Member
    Join Date
    Sep 2009
    Posts
    22
    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
  •  




Click Here to Expand Forum to Full Width

HTML5 Development Center