Collisions and controllers
This commit is contained in:
parent
1644012dfe
commit
6804452a3e
2
dist/dwelibs.min.js
vendored
2
dist/dwelibs.min.js
vendored
File diff suppressed because one or more lines are too long
63
src/controller.js
Normal file
63
src/controller.js
Normal 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
|
||||||
|
}
|
||||||
|
}
|
@ -18,5 +18,8 @@ require('./image.js')
|
|||||||
// File helpers
|
// File helpers
|
||||||
require('./file.js')
|
require('./file.js')
|
||||||
|
|
||||||
// File helpers
|
// Tiled map loader
|
||||||
require('./tiled.js')
|
require('./tiled.js')
|
||||||
|
|
||||||
|
// Character controllers
|
||||||
|
require('./controller.js')
|
||||||
|
34
src/math.js
34
src/math.js
@ -17,11 +17,6 @@ DWE.Math.intersectsBox = function (ax, ay, aw, ah, bx, by, bw, bh) {
|
|||||||
(Math.abs(ay - by) * 2 <= (ah + 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) {
|
DWE.Math.clamp = function (val, min, max) {
|
||||||
return Math.max(min, Math.min(max, val))
|
return Math.max(min, Math.min(max, val))
|
||||||
}
|
}
|
||||||
@ -112,7 +107,34 @@ DWE.Math.Box2 = class Box2 extends DWE.Math.Vector2 {
|
|||||||
|
|
||||||
intersectsBox (box) {
|
intersectsBox (box) {
|
||||||
if (!(box instanceof DWE.Math.Box2)) throw new Error('Intersection function takes another Box2 as an argument.')
|
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) {
|
intersectsCircle (circle) {
|
||||||
|
13
src/tiled.js
13
src/tiled.js
@ -151,18 +151,17 @@ DWE.Tiled.Map = class {
|
|||||||
if (!this.layers[name]) return null
|
if (!this.layers[name]) return null
|
||||||
var layer = this.layers[name]
|
var layer = this.layers[name]
|
||||||
var collisions = null
|
var collisions = null
|
||||||
var posAbs = new DWE.Math.Box2((object.x * this.scale) + origin.x + layer.x - viewport.x,
|
var posAbs = new DWE.Math.Box2(object.x + origin.x + layer.x - viewport.x,
|
||||||
(object.y * this.scale) + origin.y + layer.y - viewport.y, object.width, object.height)
|
object.y + origin.y + layer.y - viewport.y, object.width * this.scale, object.height * this.scale)
|
||||||
|
|
||||||
for (let i in layer.tiles) {
|
for (let i in layer.tiles) {
|
||||||
let tile = layer.tiles[i]
|
let tile = layer.tiles[i]
|
||||||
let tilePosAbs = new DWE.Math.Box2((tile.x * this.tileWidth * this.scale) + origin.x + layer.x + viewport.x,
|
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 (tilePosAbs.distance(posAbs) > effectiveRange) continue
|
||||||
if (posAbs.intersectsBox(tilePosAbs)) {
|
collisions = tilePosAbs.intersectsBox(posAbs)
|
||||||
if (!collisions) collisions = []
|
if (collisions) break
|
||||||
collisions.push(tilePosAbs.subtract(posAbs).normalize())
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return collisions
|
return collisions
|
||||||
|
Reference in New Issue
Block a user