Answered step by step
Verified Expert Solution
Link Copied!

Question

00
1 Approved Answer

I have a browser game written in typescript. I'm having trouble with the collision detection. The problem is, the player character gets stuck on all

I have a browser game written in typescript. I'm having trouble with the collision detection. The problem is, the player character gets stuck on all upper and lower colliders, but is absolutely fine with the left and right wall colliders. Any help is appreciated. Here are the scripts for collision, aabb, and player:

BOX COLLIDER

module objects {

export class BoxCollider {

public x:number;

public y:number;

public offset_x:number;

public offset_y:number;

public width: number;

public height: number;

public halfW: number;

public halfH: number;

public center:math.Vec2 = new math.Vec2();

public extends:math.Vec2 = new math.Vec2();

public aabb: managers.AABB;

constructor(offset_x:number, offset_y:number, x:number, y:number, width:number, height:number) {

this.x = x;

this.y = y;

this.offset_x = offset_x;

this.offset_y = offset_y;

this.width = width;

this.height = height;

this.halfW = width / 2;

this.halfH = height / 2;

this.Update(x, y);

}

public Update(x:number, y:number):void {

this.x = x;

this.y = y;

this.aabb = this.GetAABB(this.x, this.y);

}

public GetAABB(x:number, y:number):managers.AABB {

this.center = new math.Vec2(this.offset_x + x + this.halfW, this.offset_y + y + this.halfH);

this.extends = new math.Vec2(this.halfW, this.halfH);

return new managers.AABB(this.center, this.extends);

}

private cached :createjs.Shape;

public DebugLine() :void {

if (this.cached !== null) {

objects.Game.stage.removeChild(this.cached);

}

let graphics = new createjs.Graphics();

graphics.beginStroke("#000637")

.drawRect(this.offset_x + this.x, this.offset_y + this.y, this.width, this.height)

.endStroke();

this.cached = new createjs.Shape(graphics);

objects.Game.stage.addChild(this.cached);

}

}

}

COLLISIONS

module managers {

export class Collision {

public static CheckDistance(obj1: objects.GameObject, obj2: objects.GameObject):boolean {

// Create 2 temporary Vec2 objects used for collision detections

let p1: math.Vec2 = new math.Vec2(obj1.x, obj1.y);

let p2: math.Vec2 = new math.Vec2(obj2.x, obj2.y);

if(math.Vec2.Distance(p1, p2) < (obj1.halfH + obj2.halfH)) {

if(!obj2.isColliding) {

// console.log("Colliding with " + obj2.name);

switch(obj2.name) {

case "enemy":

break;

}

obj2.isColliding = true;

}

return true;

}

else {

obj2.isColliding = false;

return false;

}

}

public static CheckAABB(obj1: objects.GameObject, obj2: objects.GameObject):boolean {

let aabb1 = obj1.boxCollider.aabb;

let aabb2 = obj2.boxCollider.aabb;

let md = aabb1.minkowskiDifference(aabb2);

if (md.CheckCollided())

{

if(!obj2.isColliding) {

obj2.isColliding = true;

var penetrationVector:math.Vec2 = md.closestPointOnBoundsToPoint(math.Vec2.zero);

obj1.OnColliderEnter(penetrationVector, obj2);

}

return true;

}

if (obj2.isColliding) {

obj1.OnColliderExit(penetrationVector, obj2);

}

//boxA.center += penetrationVector;

obj2.isColliding = false;

return false;

}

public static CheckAABBCollision(aabb1: managers.AABB, aabb2: managers.AABB):managers.AABB {

return aabb1.minkowskiDifference(aabb2);

}

}

}

PLAYER

module objects{

export class Player extends objects.GameObject {

// Variables

private static speed:number = 5;

public time: number;

private timeToAction:number = 0.5;

public deltaTime: number;

// Constructor

constructor(assetManager:createjs.LoadQueue){

super(assetManager, "player");

this.Start();

this.time = 0;

this.deltaTime = 0;

}

// Methods / Functions

public Start():void{

this.x = 990;

this.y = 525;

}

private CheckCollision: (x:number, y:number) => managers.AABB;

public UpdateIfPossible(Check: (x:number, y:number) => managers.AABB): void {

this.CheckCollision = Check;

this.Update();

}

protected Update():void{

super.Update();

this.Move();

this.CheckBounds();

this.lastPosition.x = this.x;

this.lastPosition.y = this.y;

}

public Reset(): void{

}

public OnColliderEnter(penetration: math.Vec2, obj: GameObject) {

console.log(obj.name + ' penetration : ' + math.Vec2.Print(penetration));

}

public OnColliderExit(penetration: math.Vec2, obj: GameObject) {

}

public Move() :void {

if(this.x<=20&&this.y<=20){

// console.log("YOOOO");

objects.Game.currentScene = config.Scene.FINISH;

}

if (objects.Game.keyboard.moveLeft) {

if (this.CheckMovement(this.CheckCollision, true, Player.speed)) {

//this.scaleX *=-1;

this.x -= Player.speed;

}

if (!this.isLeft) {

this.FlipHorizontally();

}

}

if (objects.Game.keyboard.moveRight) {

if (this.CheckMovement(this.CheckCollision, false, Player.speed)) {

this.x += Player.speed;

}

if (this.isLeft) {

this.FlipHorizontally();

}

}

if (objects.Game.keyboard.moveUp) {

if (this.CheckMovement(this.CheckCollision, false, Player.speed)) {

this.y -= Player.speed;

}

}

if (objects.Game.keyboard.moveDown) {

if (this.CheckMovement(this.CheckCollision, false, Player.speed)) {

this.y += Player.speed;

}

}

}

public CheckMovement(Check: (x:number, y:number) => managers.AABB, isLeftMovement: boolean, speed:number): boolean {

let md:managers.AABB = Check(this.x + (isLeftMovement? 0 - speed:speed), this.y);

return !md.isCollided;// && md.closestPointOnBoundsToPoint(math.Vec2.zero).x != 0;

}

public CheckBounds(): void {

// hardcoding the play area for now

/*if (this.x >= 837.5){

this.x = 837.5;

}

if (this.x <= 235.5){

this.x = 235.5;

}*/

}

}

}

AABB

module managers{

export class AABB

{

public center:math.Vec2 = new math.Vec2();

public extents:math.Vec2 = new math.Vec2();

public min:math.Vec2;

public max:math.Vec2;

public size:math.Vec2;

public isCollided:boolean;

constructor (center:math.Vec2, extents:math.Vec2)

{

this.center = center;

this.extents = extents;

this.min = new math.Vec2(this.center.x - this.extents.x, this.center.y - this.extents.y);

this.max = new math.Vec2(this.center.x + this.extents.x, this.center.y + this.extents.y);

this.size = new math.Vec2(this.extents.x * 2, this.extents.y * 2);

}

public minkowskiDifference(other:AABB):AABB

{

var topLeft:math.Vec2 = math.Vec2.Difference(other.max, this.min);

var fullSize:math.Vec2 = math.Vec2.Sum(this.size, other.size);

return new AABB(math.Vec2.Sum(topLeft, math.Vec2.Divide(fullSize, 2)), math.Vec2.Divide(fullSize, 2));

}

public closestPointOnBoundsToPoint(point:math.Vec2):math.Vec2

{

var minDist:number = Math.abs(point.x - this.min.x);

var boundsPoint:math.Vec2 = new math.Vec2(this.min.x, point.y);

if (Math.abs(this.max.x - point.x) < minDist)

{

minDist = Math.abs(this.max.x - point.x);

boundsPoint = new math.Vec2(this.max.x, point.y);

}

if (Math.abs(this.max.y - point.y) < minDist)

{

minDist = Math.abs(this.max.y - point.y);

boundsPoint = new math.Vec2(point.x, this.max.y);

}

if (Math.abs(this.min.y - point.y) < minDist)

{

minDist = Math.abs(this.min.y - point.y);

boundsPoint = new math.Vec2(point.x, this.min.y);

}

return boundsPoint;

}

//work only if this object is the result of checking aabb collision using minkowskiDifference

public CheckCollided():boolean {

this.isCollided = this.min.x <= 0 &&

this.max.x >= 0 &&

this.min.y <= 0 &&

this.max.y >= 0;

return this.isCollided;

}

}

}

Step by Step Solution

There are 3 Steps involved in it

Step: 1

blur-text-image

Get Instant Access with AI-Powered Solutions

See step-by-step solutions with expert insights and AI powered tools for academic success

Step: 2

blur-text-image

Step: 3

blur-text-image

Ace Your Homework with AI

Get the answers you need in no time with our AI-driven, step-by-step assistance

Get Started