• Advertisement
  • Popular Tags

  • Popular Now

  • Advertisement
  • Similar Content

    • By Angelic Ice
      I'm actually an intense user of Lua for scripting-related events, but there is one thing that bothers me a lot: Serialising an in action scene.
      Let's take a dialogue-system as an example. In Lua, I see these often realised via co-routines, and did that myself quite often, but it's a difficult act to serialise the exact state. I know about serialisers like Pluto, but those are not really clean solutions, a change in the Lua-version etc. and suddenly the behaviour is anything but defined. I don't think I would want to serialise the raw content of Lua's stack etc.
      This concludes to my question: How are these systems serialised?
      Using a state-machine could be one thing, but I fear that writing such code might be difficult for casual scripter that want to modify the game a bit on their own - being an inherent reason of me picking Lua, as it is simple to understand and learn.
      Any solutions to this? I would love to see implementations, prototypes, or articles of any measure. Maybe there is a different simple scripting-language that solves this better?
      Thanks for your time.
    • By Garret Thomson
      Hey all,
      I just wanted to share a VS extension. It's useful for other people who are debugging multiple processes (aka server, player1, player2) with breakpoints that will break across those processes. It just puts up a (user defined sized) label in your window telling you which process the debugger dropped into. It's simple, but useful for rapid fire debugging for multiple processes to make it obvious that process you broke in. Just put some cookie text in your command lines and configure it from View -> Other Windows -> Process Hint.
      Feedback or questions welcome.
    • By Alex Snyder
      What exactly would a gameplay programmer do within a firm? As I look at job postings to get a better idea it seems that they're largely responsible for laying the foundation code for the game. That is to say that they're in charge of making the inventory and weapons systems work. Then someone else would step in and flush it out with all the weapons the game is supposed to have and a third person would step in to make it look pretty. Naturally the programmer would have to maintain, update, and fix these systems as they grew, but most of the work is in lying the foundation upon which everything else is built. Is this a relatively decent understanding of the overarching job role or am I fiercely underestimating it?
    • By drcrack
      It is a combination of fundamental RPG elements and challenging, session-based MOBA elements. Having features such as creating your unique build, customizing your outfit and preparing synergic team compositions with friends, players can brave dangerous adventures or merciless arena fights against deadly creatures and skilled players alike.

      This time with no grinding and no pay to win features.

      We're still looking for:
      1) 3D Character Artist
      2) 3D Environment Artist
      3) Animator
      4) Sound Designer
      5) VFX Artist

      Discord https://discord.gg/zXpY29V or drcrack#4575
    • By MadeWithRealLemons
      Hello all, I'm pretty new to programming and game development but I'm currently studying computer science at FSU and am just working on a project on that side that I hope to put on my resume one day... Any and all advice would be welcome!  I made a quick, shitty, little dev vlog where I just spliced a few of the features I've added into a single video.
      Please leave a comment if you have any words of encouragement or advice!  
  • Advertisement
  • Advertisement

Stuck on implementing platformer collision

Recommended Posts

So I am trying to make a platformer for a promotional project. This platforming game is easy. Only static obstacles, some variations of platform levels such that the sprite can jump to the next platform and jump down to the previous platform (like the NES Contra). The games suppose to behave like Mario. The platforming/environment is not complicated. You can jump up and down to platform, jump across obstacle, jump to next elevation etc. Please do take note, there is a degree of a proper platforming scheme (similar to Mario). Its just that the game is very basic.

The problem is, if my sprite goes (1,1) direction (jumping and then falling forward), my sprite snaps to one of the corners of the obstacle's hitbox. I surmised probably it is because I set some collision detections on four vertices on the hitbox of my sprite and comparing this against other hitboxes of perceived platforms (which btw, are on different size), I made it similar with 'raycasting'. It appears my sprite shows up on a position overlapping the bounding box of the platform when code proxied and correct the position of the sprite. Causing it to jitter on such corner. Sometimes it even teleports on the other side of the obstacle.

My code is a bit crude. I wanted to make it simple without using too much physics (like Box2D). As I believe this game is a simple as it gets, I felt like simpler solution suits this project better. But the fact I encountered problem like this make me feel regrettable doing this.

Here is my code so far:

package nick.runnypants.entities;

import kit.Entity;
import kit.creator.SceneSprite;
import kit.input.KeyboardEvent;
import kit.creator.CreatorObject;
import kit.display.Sprite;
import kit.input.Key;
import kit.physics.PhysicsBody;
import kit.System;
import kit.physics.Box2D;

import box2d.dynamics.BodyType;
import box2d.common.math.Vec2;

import nick.runnypants.entities.Collider;
import nick.runnypants.utils.MathUtils;

class Runner extends BoundedObject 
	public var moveSpeed : Float = 1550;
	public var jumpHeight : Float = 3;
	public var timeToJumpApex : Float = 0.35;
	public var showDebugLines : Bool = false;

	private var position : Vec2;
	private var velocity : Vec2;
	private var acceleration : Vec2;
	private var direction : Vec2;
	private var sprite : Sprite;
	private var sceneSprite : SceneSprite;
	private var jumpSpeed : Float;
	private var gravity : Float;
	private var isGrounded : Bool;
	private var keyPresses : Map<Key, Int>;
	private var perceivedPlatforms : Array<BoundedObject>;
	private var thisCollider : Collider;
	private var collisionInfo : CollisionInfo;

	public override function onStart() : Void
		perceivedPlatforms = new Array<BoundedObject>();
		sceneSprite = owner.getSceneSpriteFromParents();

		sprite = owner.getSprite();
	private function initPhysics()
		collisionInfo = new CollisionInfo();
		setBoundOffset(new Vec2(sprite.getNaturalWidth() / 2.0, sprite.getNaturalHeight() / 2.0));
		thisCollider = getCollider();

		position = new Vec2(sprite.x._, sprite.y._);
		acceleration = new Vec2(0, 0);
		velocity = new Vec2(0, 0);
		direction = new Vec2(0, 0);
		gravity = (2 * jumpHeight) / (timeToJumpApex * timeToJumpApex);
		jumpSpeed = gravity * timeToJumpApex;
	private function initControls()
		keyPresses = new Map<Key, Int>();
	public override function onUpdate(dt : Float) : Void
		direction = new Vec2(0, 0);


		velocity.x = direction.x * moveSpeed * dt;
		velocity.y = direction.y * moveSpeed * dt;
		// velocity.y += gravity * dt;

		if (collisionInfo.collideLeft || collisionInfo.collideRight)
			velocity.x = 0;
			direction.x = 0;
		if (collisionInfo.collideBottom)
			velocity.y = 0;
			direction.y = 0;
		position.x += MathUtils.lerp(velocity.x, moveSpeed * direction.x, dt);
		position.y += MathUtils.lerp(velocity.y, moveSpeed * direction.y, dt);
		sprite.x._ = position.x;
		sprite.y._ = position.y;
	private function resolveCollisions(velocity : Vec2)
		for (platform in perceivedPlatforms)
			var thatCollider = platform.getCollider();
			checkVerticalCollision(velocity, thatCollider);
			checkHorizontalCollision(velocity, thatCollider);
	private function checkVerticalCollision(velocity : Vec2, thatCollider : Collider)
		if (MathUtils.sign(velocity.y) == 1
			&& (MathUtils.isBetweenHorizontal(thisCollider.bottomLeft.x, thatCollider.topLeft, thatCollider.topRight)
			|| MathUtils.isBetweenHorizontal(thisCollider.bottomRight.x, thatCollider.topLeft, thatCollider.topRight)))
			var dist = thatCollider.topLeft.y - thisCollider.bottomLeft.y;
			if (dist <= 0 && thisCollider.topLeft.y < thatCollider.bottomLeft.y)
				position.y = thatCollider.topLeft.y - (sprite.getNaturalHeight() / 2.0);
				collisionInfo.collideBottom = true;
		else if (MathUtils.sign(velocity.y) == -1
			&& (MathUtils.isBetweenHorizontal(thisCollider.topLeft.x, thatCollider.bottomLeft, thatCollider.bottomRight)
			|| MathUtils.isBetweenHorizontal(thisCollider.topRight.x, thatCollider.bottomLeft, thatCollider.bottomLeft)))
			var dist = thisCollider.topLeft.y - thatCollider.bottomLeft.y;
			if (dist <= 0 && thisCollider.topLeft.y > thatCollider.topLeft.y)
				position.y = thatCollider.bottomLeft.y + (sprite.getNaturalHeight() / 2.0);
				collisionInfo.collideBottom = true;
	private function checkHorizontalCollision(velocity : Vec2, thatCollider : Collider)
		if (MathUtils.sign(velocity.x) == 1 
				&& (MathUtils.isBetweenVertical(thisCollider.bottomRight.y, thatCollider.topLeft, thatCollider.bottomLeft)
				|| MathUtils.isBetweenVertical(thisCollider.topRight.y, thatCollider.topLeft, thatCollider.bottomLeft)))
			var dist = thatCollider.topLeft.x - thisCollider.bottomRight.x;
			if (dist <= 0 && thisCollider.bottomRight.x < thatCollider.bottomRight.x) 
				position.x = thatCollider.topLeft.x - (sprite.getNaturalWidth() / 2.0);
				collisionInfo.collideRight = true;
		else if (MathUtils.sign(velocity.x) == -1 
			&& (MathUtils.isBetweenVertical(thisCollider.bottomLeft.y, thatCollider.topRight, thatCollider.bottomRight)
			|| MathUtils.isBetweenVertical(thisCollider.topLeft.y, thatCollider.topRight, thatCollider.bottomRight)))
			var dist = thisCollider.topLeft.x - thatCollider.bottomRight.x;
			if (dist <= 0 && thisCollider.bottomRight.x > thatCollider.bottomLeft.x)
				position.x = thatCollider.bottomRight.x + (sprite.getNaturalWidth() / 2.0);
				collisionInfo.collideLeft = true;
	private function perceivePlatforms()
		var platforms : Array<Entity> = sceneSprite.getObjectsByType(BoundedObject);
		for (e in platforms)
			perceivedPlatforms.insert(0, e.get(BoundedObject));
	private function updateInput() : Void
		if (keyPresses.get(Key.Left) != null || keyPresses.get(Key.A) != null)
			direction.x = -1;
		if (keyPresses.get(Key.Right) != null || keyPresses.get(Key.D) != null)
			direction.x = 1;
		if (keyPresses.get(Key.Up) != null || keyPresses.get(Key.W) != null)
			direction.y = -1;
		if (keyPresses.get(Key.Down) != null || keyPresses.get(Key.S) != null)
			direction.y = 1;
		//if (keyPresses.get(Key.Space) != null)
		//	jump();
	public function jump() : Void
		velocity.y = -jumpSpeed;
		isGrounded = false;
	public function onKeyDown(event : KeyboardEvent)
		keyPresses.set(event.key, event.id);
	public function onKeyUp(event : KeyboardEvent)

I disabled jumping/platforming mechanics and move the sprite on all directions. As you can see, if I move  diagonally towards  a particular obstacle, my sprite seems to collide a bit with platform's corner, and I had my code to correct its position. This doesn't look nice because, sometimes, the collision doesn't make sense and it looks jittery. Collision works well on a very strict movement, like coming from the left, right, top, bottom, but not combinations of those as my sprite teleports on the other side of the obstacle. 

I've been searching through the web and spent countless hour figuring this out and I can't seem to find any useful article. Though I came to know 'bullet through paper problem', 'SAT', 'Sweep'

etc. I am not totally sure if this is the solution to my problem, hence this post.

This is using 2dKit + Haxe language. 

I felt very dumb and I am really stuck.  Any help will be greatly appreciated.


Share this post

Link to post
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now

  • Advertisement