Collisions and controllers

This commit is contained in:
Evert Prants 2018-08-21 01:50:59 +03:00
parent 1644012dfe
commit 6804452a3e
Signed by: evert
GPG Key ID: 1688DA83D222D0B5
5 changed files with 102 additions and 15 deletions

2
dist/dwelibs.min.js vendored

File diff suppressed because one or more lines are too long

63
src/controller.js Normal file
View File

@ -0,0 +1,63 @@
DWE.Controller = {}
DWE.Controller.Entity = class Entity extends DWE.Math.Box2 {
constructor (x, y, w, h) {
super(x, y, w, h)
this.velocity = new DWE.Math.Vector2(0, 0)
this.scale = 1
}
collide (map, collisionLayer, mapOrigin, viewport) {
let dir = map.collideLayer(this, mapOrigin, viewport, collisionLayer, 2 * this.scale * map.tileWidth)
if (dir === 'l' || dir === 'r') {
this.velocity.x = 0
} else if (dir === 'b' && this.velocity.y < 0) {
this.velocity.y = 0
} else if (dir === 't' && this.velocity.y > 0) {
this.velocity.y = 0
}
}
update (delta) {
this.x += this.velocity.x * delta
this.y += this.velocity.y * delta
}
}
// A platformer entity
DWE.Controller.OrthoEntity = class OrthoEntity extends DWE.Controller.Entity {
constructor(x, y, w, h) {
super(x, y, w, h)
this.grounded = false
this.jumping = false
}
collide (map, collisionLayer, mapOrigin, viewport) {
let collision = map.collideLayer(this, mapOrigin, viewport, collisionLayer, 2 * this.scale * map.tileWidth)
this.grounded = false
if (collision) {
if (collision.dir === 'l' || collision.dir === 'r') {
this.velocity.x = 0
this.jumping = false
} else if (collision.dir === 'b') {
this.grounded = true
this.jumping = false
} else if (collision.dir === 't') {
this.velocity.y *= -1
this.jumping = false
}
this.x -= collision.x
this.y -= collision.y
}
}
update (delta) {
if (this.grounded)
this.velocity.y = 0
this.x += this.velocity.x * delta
this.y += this.velocity.y * delta
}
}

View File

@ -18,5 +18,8 @@ require('./image.js')
// File helpers
require('./file.js')
// File helpers
// Tiled map loader
require('./tiled.js')
// Character controllers
require('./controller.js')

View File

@ -17,11 +17,6 @@ DWE.Math.intersectsBox = function (ax, ay, aw, ah, bx, by, bw, bh) {
(Math.abs(ay - by) * 2 <= (ah + bh))
}
DWE.Math.intersects2Box = function (a, b) {
return (Math.abs(a.x - b.x) * 2 <= (a.width + b.width)) &&
(Math.abs(a.y - b.y) * 2 <= (a.height + b.height))
}
DWE.Math.clamp = function (val, min, max) {
return Math.max(min, Math.min(max, val))
}
@ -112,7 +107,34 @@ DWE.Math.Box2 = class Box2 extends DWE.Math.Vector2 {
intersectsBox (box) {
if (!(box instanceof DWE.Math.Box2)) throw new Error('Intersection function takes another Box2 as an argument.')
return DWE.Math.intersects2Box(this, box)
// get the vectors to check against
var vX = (box.x + (box.width / 2)) - (this.x + (this.width / 2))
var vY = (box.y + (box.height / 2)) - (this.y + (this.height / 2))
// add the half widths and half heights of the objects
var hWidths = (box.width / 2) + (this.width / 2)
var hHeights = (box.height / 2) + (this.height / 2)
var colDir = null
// if the x and y vector are less than the half width or half height, they we must be inside the object, causing a collision
// figures out on which side we are colliding (top, bottom, left, or right)
if (Math.abs(vX) < hWidths && Math.abs(vY) < hHeights) {
var oX = hWidths - Math.abs(vX)
var oY = hHeights - Math.abs(vY)
if (oX >= oY) {
if (vY > 0) {
colDir = {dir: 't', y: oY, x: 0}
} else {
colDir = {dir: 'b', y: -oY, x: 0}
}
} else {
if (vX > 0) {
colDir = {dir: 'l', y: 0, x: oX}
} else {
colDir = {dir: 'r', y: 0, x: -oX}
}
}
}
return colDir
}
intersectsCircle (circle) {

View File

@ -151,18 +151,17 @@ DWE.Tiled.Map = class {
if (!this.layers[name]) return null
var layer = this.layers[name]
var collisions = null
var posAbs = new DWE.Math.Box2((object.x * this.scale) + origin.x + layer.x - viewport.x,
(object.y * this.scale) + origin.y + layer.y - viewport.y, object.width, object.height)
var posAbs = new DWE.Math.Box2(object.x + origin.x + layer.x - viewport.x,
object.y + origin.y + layer.y - viewport.y, object.width * this.scale, object.height * this.scale)
for (let i in layer.tiles) {
let tile = layer.tiles[i]
let tilePosAbs = new DWE.Math.Box2((tile.x * this.tileWidth * this.scale) + origin.x + layer.x + viewport.x,
(tile.y * this.tileHeight * this.scale) + origin.y + layer.y + viewport.y, this.tileWidth, this.tileHeight)
(tile.y * this.tileHeight * this.scale) + origin.y + layer.y + viewport.y, this.tileWidth * this.scale, this.tileHeight * this.scale)
if (tilePosAbs.distance(posAbs) > effectiveRange) continue
if (posAbs.intersectsBox(tilePosAbs)) {
if (!collisions) collisions = []
collisions.push(tilePosAbs.subtract(posAbs).normalize())
}
collisions = tilePosAbs.intersectsBox(posAbs)
if (collisions) break
}
return collisions