Skip to main content
edited body
Source Link
_frames_a_sec = 20;60;    
public void run() {
        while(true) {
            long timeElapsed = System.currentTimeMillis() - _lastUpdate;
            _lastUpdate = System.currentTimeMillis();

            if(timeElapsed > 80) {
                timeElapsed = 80;
            }

            update((int)timeElapsed);

            try {
                Thread.sleep((1000/_FRAMES_A_SEC));
            } catch(Exception ex) { }
        }
    }
_frames_a_sec = 20;    
public void run() {
        while(true) {
            long timeElapsed = System.currentTimeMillis() - _lastUpdate;
            _lastUpdate = System.currentTimeMillis();

            if(timeElapsed > 80) {
                timeElapsed = 80;
            }

            update((int)timeElapsed);

            try {
                Thread.sleep((1000/_FRAMES_A_SEC));
            } catch(Exception ex) { }
        }
    }
_frames_a_sec = 60;    
public void run() {
        while(true) {
            long timeElapsed = System.currentTimeMillis() - _lastUpdate;
            _lastUpdate = System.currentTimeMillis();

            if(timeElapsed > 80) {
                timeElapsed = 80;
            }

            update((int)timeElapsed);

            try {
                Thread.sleep((1000/_FRAMES_A_SEC));
            } catch(Exception ex) { }
        }
    }
added 6079 characters in body
Source Link

UPDATE

Added the code to make it more clear.

The main loop:

_frames_a_sec = 20;    
public void run() {
        while(true) {
            long timeElapsed = System.currentTimeMillis() - _lastUpdate;
            _lastUpdate = System.currentTimeMillis();

            if(timeElapsed > 80) {
                timeElapsed = 80;
            }

            update((int)timeElapsed);

            try {
                Thread.sleep((1000/_FRAMES_A_SEC));
            } catch(Exception ex) { }
        }
    }

Map update method:

public void update(int timeElapsed) {
        //update entities
        for(Entity entity : _mapEntities) {
            entity.update(timeElapsed);
        }

        //check for collisions
        checkMapCollision();
    }

Entity (abstract) update method:

public void update(int timeElapsed) {
        _velocity.x = 0.0F;

        if(!_isOnLand) {
        //add gravity
        _velocity.y += Map._GRAVITY_PER_SEC * timeElapsed;
    } else {
        _velocity.y = 0.0F;
    }
}

Mario (extends Entity) update method:

@Override
    public void update(int timeElapsed) {
        super.update(timeElapsed);

        if(_state == STATES.IDLE) {
            
        } else if(_isMoving) {
            _marioSmallWalk.update(timeElapsed);
        }

        if(_state == STATES.JUMPING) {
            setVelocityY(getVelocity().y + _jumpSpeed);

            _jumpSpeed += _JUMP_DECREASE * timeElapsed;

            //falling?
            if(getVelocity().y > 0) {
                setState(STATES.FALLING);
            }
        } 
        
        if(_isMoving) {
            double walkSpd = (_WALK_SPEED_SEC * timeElapsed);

            if(getFacing() == FACING.LEFT) {
                walkSpd = -walkSpd;
            }

            setVelocityX(getVelocity().x + walkSpd);
        }

        //falling?
        if(getVelocity().y > (Map._GRAVITY_PER_SEC * timeElapsed) + 1.0F) {
            setState(STATES.FALLING);
        }
    }

Map Collsion check method:

public void checkMapCollision() {
    for(Entity entity : _mapEntities) {
        placeEntityAtX(entity);
        placeEntityAtY(entity);
    }
}

X check method:

private void placeEntityAtX(Entity entity) {
        Vector2d dir = entity.getDirection();
        Rectangle bounds = entity.getBounds();
        boolean positionSet = false;

        bounds = new Rectangle((int)(bounds.x + dir.x), bounds.y, bounds.width, bounds.height);
        Block[] corners = getCornerBlocks(bounds);

        if(dir.x > 0) {
            if(corners[1].isSolid() || corners[3].isSolid()) {
                Rectangle blkBounds;

                if(corners[3].isSolid()) {
                    blkBounds = corners[3].getBounds();
                } else {
                    blkBounds = corners[1].getBounds();
                }

                entity.setPositionX(blkBounds.x - (bounds.width-entity.getCurrentSprite().getOffsetX())-1);
                positionSet = true;
            }
        } else if(dir.x < 0) {
            if(corners[0].isSolid() || corners[2].isSolid()) {
                Rectangle blkBounds;

                if(corners[2].isSolid()) {
                    blkBounds = corners[2].getBounds();
                } else {
                    blkBounds = corners[0].getBounds();
                }

                entity.setPositionX(blkBounds.x + blkBounds.width + (bounds.width/2) + 1);
                positionSet = true;
            }
        }

        if(!positionSet) {
            //set the original position
            entity.setPositionX((int)(entity.getX() + dir.x));
        }
    }

and the y:

private void placeEntityAtY(Entity entity) {
        Vector2d dir = entity.getDirection();
        Rectangle bounds = entity.getBounds();
        boolean positionSet = false;

        bounds = new Rectangle(bounds.x, (int)(bounds.y + dir.y), bounds.width, bounds.height);
        Block[] corners = getCornerBlocks(bounds);

        //moving down
        if(dir.y > 0) {
            if(corners[2].isSolid() || corners[3].isSolid()) {
                Rectangle blkBounds = null;

                if(corners[2].isSolid()) {
                    blkBounds = corners[2].getBounds();
                } else {
                    blkBounds = corners[3].getBounds();
                }

                entity.setPositionY(blkBounds.y);
                entity.landed();
                positionSet = true;
            } 
        } else if (dir.y < 0) {
            if(corners[0].isSolid() || corners[1].isSolid()) {
                Rectangle blkBounds = null;

                if(corners[0].isSolid()) {
                    blkBounds = corners[0].getBounds();
                } else {
                    blkBounds = corners[1].getBounds();
                }

                entity.setPositionY(blkBounds.y + blkBounds.height + bounds.height);
                entity.roof();
                positionSet = true;
            }
        } else {
            if(!corners[2].isSolid() && !corners[3].isSolid()) {
                entity.falling();
            }
        }

        if(!positionSet) {
            //set the original position
            entity.setPositionY((int)(entity.getY() + dir.y));
        }
    }

UPDATE

Added the code to make it more clear.

The main loop:

_frames_a_sec = 20;    
public void run() {
        while(true) {
            long timeElapsed = System.currentTimeMillis() - _lastUpdate;
            _lastUpdate = System.currentTimeMillis();

            if(timeElapsed > 80) {
                timeElapsed = 80;
            }

            update((int)timeElapsed);

            try {
                Thread.sleep((1000/_FRAMES_A_SEC));
            } catch(Exception ex) { }
        }
    }

Map update method:

public void update(int timeElapsed) {
        //update entities
        for(Entity entity : _mapEntities) {
            entity.update(timeElapsed);
        }

        //check for collisions
        checkMapCollision();
    }

Entity (abstract) update method:

public void update(int timeElapsed) {
        _velocity.x = 0.0F;

        if(!_isOnLand) {
        //add gravity
        _velocity.y += Map._GRAVITY_PER_SEC * timeElapsed;
    } else {
        _velocity.y = 0.0F;
    }
}

Mario (extends Entity) update method:

@Override
    public void update(int timeElapsed) {
        super.update(timeElapsed);

        if(_state == STATES.IDLE) {
            
        } else if(_isMoving) {
            _marioSmallWalk.update(timeElapsed);
        }

        if(_state == STATES.JUMPING) {
            setVelocityY(getVelocity().y + _jumpSpeed);

            _jumpSpeed += _JUMP_DECREASE * timeElapsed;

            //falling?
            if(getVelocity().y > 0) {
                setState(STATES.FALLING);
            }
        } 
        
        if(_isMoving) {
            double walkSpd = (_WALK_SPEED_SEC * timeElapsed);

            if(getFacing() == FACING.LEFT) {
                walkSpd = -walkSpd;
            }

            setVelocityX(getVelocity().x + walkSpd);
        }

        //falling?
        if(getVelocity().y > (Map._GRAVITY_PER_SEC * timeElapsed) + 1.0F) {
            setState(STATES.FALLING);
        }
    }

Map Collsion check method:

public void checkMapCollision() {
    for(Entity entity : _mapEntities) {
        placeEntityAtX(entity);
        placeEntityAtY(entity);
    }
}

X check method:

private void placeEntityAtX(Entity entity) {
        Vector2d dir = entity.getDirection();
        Rectangle bounds = entity.getBounds();
        boolean positionSet = false;

        bounds = new Rectangle((int)(bounds.x + dir.x), bounds.y, bounds.width, bounds.height);
        Block[] corners = getCornerBlocks(bounds);

        if(dir.x > 0) {
            if(corners[1].isSolid() || corners[3].isSolid()) {
                Rectangle blkBounds;

                if(corners[3].isSolid()) {
                    blkBounds = corners[3].getBounds();
                } else {
                    blkBounds = corners[1].getBounds();
                }

                entity.setPositionX(blkBounds.x - (bounds.width-entity.getCurrentSprite().getOffsetX())-1);
                positionSet = true;
            }
        } else if(dir.x < 0) {
            if(corners[0].isSolid() || corners[2].isSolid()) {
                Rectangle blkBounds;

                if(corners[2].isSolid()) {
                    blkBounds = corners[2].getBounds();
                } else {
                    blkBounds = corners[0].getBounds();
                }

                entity.setPositionX(blkBounds.x + blkBounds.width + (bounds.width/2) + 1);
                positionSet = true;
            }
        }

        if(!positionSet) {
            //set the original position
            entity.setPositionX((int)(entity.getX() + dir.x));
        }
    }

and the y:

private void placeEntityAtY(Entity entity) {
        Vector2d dir = entity.getDirection();
        Rectangle bounds = entity.getBounds();
        boolean positionSet = false;

        bounds = new Rectangle(bounds.x, (int)(bounds.y + dir.y), bounds.width, bounds.height);
        Block[] corners = getCornerBlocks(bounds);

        //moving down
        if(dir.y > 0) {
            if(corners[2].isSolid() || corners[3].isSolid()) {
                Rectangle blkBounds = null;

                if(corners[2].isSolid()) {
                    blkBounds = corners[2].getBounds();
                } else {
                    blkBounds = corners[3].getBounds();
                }

                entity.setPositionY(blkBounds.y);
                entity.landed();
                positionSet = true;
            } 
        } else if (dir.y < 0) {
            if(corners[0].isSolid() || corners[1].isSolid()) {
                Rectangle blkBounds = null;

                if(corners[0].isSolid()) {
                    blkBounds = corners[0].getBounds();
                } else {
                    blkBounds = corners[1].getBounds();
                }

                entity.setPositionY(blkBounds.y + blkBounds.height + bounds.height);
                entity.roof();
                positionSet = true;
            }
        } else {
            if(!corners[2].isSolid() && !corners[3].isSolid()) {
                entity.falling();
            }
        }

        if(!positionSet) {
            //set the original position
            entity.setPositionY((int)(entity.getY() + dir.y));
        }
    }
Tweeted twitter.com/#!/StackGameDev/status/71911231631532032
added 2 characters in body; edited title
Source Link

Tile based collision detection: Failing failing when player is going totoo fast.

I'm creating a side scroller and I'm have a problem with my collision detection.

The collision detection works perfect when the player is falling inat a constant speed, but when I implement more realistic gravity, then the player falls totoo fast. Resulting - resulting in that the collision will be checked with the tiles under the floor/platform causing that the player canto be able to jump troughthrough platforms.

The way my update and collision works is like following:

  • Update entities velocity (no position change)
  • Check for collisions (first x, then y)
    • if collision, then move the entity as close as possible, otherwise set the position with the velocity.

The collision method works like this:

  • Get the four corners of the player.
  • Get from that four corners the tiles.
  • Collision check.

How can I solve this problem?

Tile based collision detection: Failing when player is going to fast.

I'm creating a side scroller and I'm have a problem with my collision detection.

The collision detection works perfect when the player is falling in a constant speed, but when I implement more realistic gravity, then the player falls to fast. Resulting in that the collision will be checked with the tiles under the floor/platform causing that the player can jump trough platforms.

The way my update and collision works is like following:

  • Update entities velocity (no position change)
  • Check for collisions (first x, then y)
    • if collision, then move the entity as close as possible, otherwise set the position with the velocity.

The collision method works like this:

  • Get the four corners of the player.
  • Get from that four corners the tiles.
  • Collision check.

How can I solve this problem?

Tile based collision detection failing when player is going too fast

I'm creating a side scroller and I'm have a problem with my collision detection.

The collision detection works perfect when the player is falling at a constant speed, but when I implement more realistic gravity the player falls too fast - resulting in that the collision will be checked with the tiles under the floor/platform causing the player to be able to jump through platforms.

The way my update and collision works is like following:

  • Update entities velocity (no position change)
  • Check for collisions (first x, then y)
    • if collision, then move the entity as close as possible, otherwise set the position with the velocity.

The collision method works like this:

  • Get the four corners of the player.
  • Get from that four corners the tiles.
  • Collision check.

How can I solve this problem?

Source Link
Loading