Question
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
Get Instant Access to Expert-Tailored Solutions
See step-by-step solutions with expert insights and AI powered tools for academic success
Step: 2
Step: 3
Ace Your Homework with AI
Get the answers you need in no time with our AI-driven, step-by-step assistance
Get Started