Terrain collision.
This commit is contained in:
parent
0cd532f45a
commit
b7f669224d
|
@ -40,6 +40,16 @@ export default class Movable
|
||||||
return this.animations[this.currentAnimation].getRect();
|
return this.animations[this.currentAnimation].getRect();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
getWidth()
|
||||||
|
{
|
||||||
|
return this.getRect().width;
|
||||||
|
}
|
||||||
|
|
||||||
|
getHeight()
|
||||||
|
{
|
||||||
|
return this.getRect().height;
|
||||||
|
}
|
||||||
|
|
||||||
getPositionFootLeft()
|
getPositionFootLeft()
|
||||||
{
|
{
|
||||||
return new GeometryPoint(
|
return new GeometryPoint(
|
||||||
|
@ -50,7 +60,23 @@ export default class Movable
|
||||||
getPositionFootRight()
|
getPositionFootRight()
|
||||||
{
|
{
|
||||||
return new GeometryPoint(
|
return new GeometryPoint(
|
||||||
this.position.x + this.animations[this.currentAnimation].getWidth() * 0.5, this.position.y
|
this.position.x + this.getWidth() * 0.5, this.position.y
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
getPositionHeadLeft()
|
||||||
|
{
|
||||||
|
return new GeometryPoint(
|
||||||
|
this.position.x - this.animations[this.currentAnimation].getWidth() * 0.5,
|
||||||
|
this.position.y - this.animations[this.currentAnimation].getHeight()
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
getPositionHeadRight()
|
||||||
|
{
|
||||||
|
return new GeometryPoint(
|
||||||
|
this.position.x + this.getWidth() * 0.5,
|
||||||
|
this.position.y - this.animations[this.currentAnimation].getHeight()
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
108
js/module.js
108
js/module.js
|
@ -2,7 +2,6 @@ import Key from "./Key.js";
|
||||||
import MrCroc from "./MrCroc.js";
|
import MrCroc from "./MrCroc.js";
|
||||||
import RetroArchitecture from "./retro/RetroArchitecture.js";
|
import RetroArchitecture from "./retro/RetroArchitecture.js";
|
||||||
import FileLoader from "./FileLoader.js";
|
import FileLoader from "./FileLoader.js";
|
||||||
import GeometryPoint from "./geometry/GeometryPoint.js";
|
|
||||||
|
|
||||||
class ImageLoader
|
class ImageLoader
|
||||||
{
|
{
|
||||||
|
@ -44,11 +43,10 @@ function MainLoop(timestamp)
|
||||||
|
|
||||||
let delta = (timestamp - lastTimestamp) / (10 / GAME_SPEED);
|
let delta = (timestamp - lastTimestamp) / (10 / GAME_SPEED);
|
||||||
|
|
||||||
if (KeyLeft.isPressed()) {
|
let lastCeilingHeight = Math.max(
|
||||||
mrCroc.moveLeft(timestamp, delta);
|
architecture.getCeilingHeight(mrCroc.getPositionHeadLeft()),
|
||||||
} else if (KeyRight.isPressed()) {
|
architecture.getCeilingHeight(mrCroc.getPositionHeadRight()),
|
||||||
mrCroc.moveRight(timestamp, delta);
|
);
|
||||||
}
|
|
||||||
|
|
||||||
lastGroundHeight = Math.min(
|
lastGroundHeight = Math.min(
|
||||||
architecture.getGroundHeight(mrCroc.getPositionFootLeft()),
|
architecture.getGroundHeight(mrCroc.getPositionFootLeft()),
|
||||||
|
@ -62,47 +60,76 @@ function MainLoop(timestamp)
|
||||||
architecture.getGroundHeight(mrCroc.getPositionFootRight())
|
architecture.getGroundHeight(mrCroc.getPositionFootRight())
|
||||||
);
|
);
|
||||||
|
|
||||||
if (mrCroc.position.y < lastGroundHeight) {
|
|
||||||
mrCroc.fallSpeed += GRAVITY * delta;
|
mrCroc.fallSpeed += GRAVITY * delta;
|
||||||
}
|
|
||||||
/*
|
|
||||||
|
|
||||||
if (architecture.hasRectCollision(mrCroc.getRect())) {
|
if (mrCroc.position.y >= lastGroundHeight) {
|
||||||
mrCroc.position.x = lastPosition.x;
|
|
||||||
}
|
|
||||||
let archIntersections = architecture.getCollisionRects(mrCroc.getRect());
|
|
||||||
|
|
||||||
let width = archIntersections.getUniqueWidth();
|
|
||||||
|
|
||||||
if (width !== null) {
|
|
||||||
if (width.x === mrCroc.position.x) {
|
|
||||||
mrCroc.position.x += width.width;
|
|
||||||
} else {
|
|
||||||
mrCroc.position.x = width.x - mrCroc.getRect().width;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
*/
|
|
||||||
|
|
||||||
if (mrCroc.position.y !== lastGroundHeight) {
|
|
||||||
if (lastGroundHeight < groundHeight) {
|
|
||||||
mrCroc.position.y = lastGroundHeight;
|
mrCroc.position.y = lastGroundHeight;
|
||||||
mrCroc.fallSpeed = 0;
|
mrCroc.fallSpeed = 0;
|
||||||
} else {
|
|
||||||
mrCroc.fallSpeed += GRAVITY * delta;
|
|
||||||
}
|
}
|
||||||
} else {
|
|
||||||
if (!mrCroc.isJumping && mrCroc.fallSpeed === 0 && KeyJump.isPressed()) {
|
if (mrCroc.position.y - mrCroc.getHeight() <= lastCeilingHeight) {
|
||||||
|
mrCroc.fallSpeed = 0;
|
||||||
|
mrCroc.position.y = lastCeilingHeight + mrCroc.getHeight() + 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!mrCroc.isJumping && mrCroc.fallSpeed === 0 && mrCroc.position.y === groundHeight && KeyJump.isPressed()) {
|
||||||
mrCroc.jump();
|
mrCroc.jump();
|
||||||
} else if (!KeyJump.isPressed()) {
|
} else if (!KeyJump.isPressed()) {
|
||||||
mrCroc.isJumping = false;
|
mrCroc.isJumping = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
let lastWallRight = Math.min(
|
||||||
|
architecture.getWallRight(mrCroc.getPositionHeadRight()),
|
||||||
|
architecture.getWallRight(mrCroc.getPositionFootRight())
|
||||||
|
);
|
||||||
|
|
||||||
|
let lastWallLeft = Math.max(
|
||||||
|
architecture.getWallLeft(mrCroc.getPositionHeadLeft()),
|
||||||
|
architecture.getWallLeft(mrCroc.getPositionFootLeft())
|
||||||
|
);
|
||||||
|
|
||||||
|
if (KeyLeft.isPressed()) {
|
||||||
|
mrCroc.moveLeft(timestamp, delta);
|
||||||
|
|
||||||
|
let wallLeft = Math.max(
|
||||||
|
architecture.getWallLeft(mrCroc.getPositionHeadLeft()),
|
||||||
|
architecture.getWallLeft(mrCroc.getPositionFootLeft())
|
||||||
|
);
|
||||||
|
|
||||||
|
if (wallLeft < lastWallLeft) {
|
||||||
|
mrCroc.position.x = lastWallLeft + 1;
|
||||||
|
}
|
||||||
|
} else if (KeyRight.isPressed()) {
|
||||||
|
mrCroc.moveRight(timestamp, delta);
|
||||||
|
|
||||||
|
let wallRight = Math.min(
|
||||||
|
architecture.getWallRight(mrCroc.getPositionHeadRight()),
|
||||||
|
architecture.getWallRight(mrCroc.getPositionFootRight())
|
||||||
|
);
|
||||||
|
|
||||||
|
if (wallRight > lastWallRight) {
|
||||||
|
mrCroc.position.x = lastWallRight - 1;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (timestamp - lastRendered >= FRAME_DURATION) {
|
if (timestamp - lastRendered >= FRAME_DURATION) {
|
||||||
context.clearRect(0, 0, window.innerWidth, window.innerHeight);
|
context.clearRect(0, 0, window.innerWidth, window.innerHeight);
|
||||||
architecture.draw(context);
|
architecture.draw(context);
|
||||||
mrCroc.draw(context);
|
mrCroc.draw(context);
|
||||||
|
|
||||||
|
/*
|
||||||
|
context.fillRect(0, lastCeilingHeight, window.innerWidth, 1);
|
||||||
|
context.fillRect(0, lastGroundHeight, window.innerWidth, 1);
|
||||||
|
context.fillStyle = 'black';
|
||||||
|
context.fillRect(lastWallRight, 0, 1, window.innerHeight);
|
||||||
|
context.fillStyle = 'red';
|
||||||
|
context.fillRect(lastWallLeft, 0, 1, window.innerHeight);
|
||||||
|
mrCroc.getPositionHeadRight().draw(context);
|
||||||
|
mrCroc.getPositionFootRight().draw(context);
|
||||||
|
mrCroc.getPositionHeadLeft().draw(context);
|
||||||
|
mrCroc.getPositionFootLeft().draw(context);
|
||||||
|
*/
|
||||||
|
|
||||||
lastRendered = timestamp;
|
lastRendered = timestamp;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -114,13 +141,11 @@ function MainLoop(timestamp)
|
||||||
const FPS = 60;
|
const FPS = 60;
|
||||||
const FRAME_DURATION = 1000 / FPS;
|
const FRAME_DURATION = 1000 / FPS;
|
||||||
const GAME_SPEED = 1;
|
const GAME_SPEED = 1;
|
||||||
const GRAVITY = 1;
|
const GRAVITY = 2;
|
||||||
|
|
||||||
let levelJson = new FileLoader('levels/test.json');
|
let levelJson = new FileLoader('levels/test.json');
|
||||||
const LEVEL = levelJson.getContent();
|
const LEVEL = levelJson.getContent();
|
||||||
|
|
||||||
console.log(LEVEL);
|
|
||||||
|
|
||||||
let lastRendered = undefined;
|
let lastRendered = undefined;
|
||||||
let lastTimestamp = undefined;
|
let lastTimestamp = undefined;
|
||||||
let groundHeight = undefined;
|
let groundHeight = undefined;
|
||||||
|
@ -151,7 +176,7 @@ imgBackground.src = 'graphics/ground.jpg';
|
||||||
loader.addImage(imgBackground);
|
loader.addImage(imgBackground);
|
||||||
|
|
||||||
let imgArch = new Image();
|
let imgArch = new Image();
|
||||||
imgArch.src = 'graphics/maria-world.jpg';
|
imgArch.src = 'graphics/tileset-landscape01.jpg';
|
||||||
loader.addImage(imgArch);
|
loader.addImage(imgArch);
|
||||||
|
|
||||||
window.addEventListener(
|
window.addEventListener(
|
||||||
|
@ -161,6 +186,14 @@ window.addEventListener(
|
||||||
canvas.width = window.innerWidth;
|
canvas.width = window.innerWidth;
|
||||||
canvas.height = window.innerHeight;
|
canvas.height = window.innerHeight;
|
||||||
|
|
||||||
|
window.addEventListener(
|
||||||
|
'resize',
|
||||||
|
function () {
|
||||||
|
canvas.width = window.innerWidth;
|
||||||
|
canvas.height = window.innerHeight;
|
||||||
|
}
|
||||||
|
);
|
||||||
|
|
||||||
context = canvas.getContext('2d');
|
context = canvas.getContext('2d');
|
||||||
|
|
||||||
architecture = RetroArchitecture.createFromJson(LEVEL);
|
architecture = RetroArchitecture.createFromJson(LEVEL);
|
||||||
|
@ -169,9 +202,6 @@ window.addEventListener(
|
||||||
mrCroc.position.x = 300;
|
mrCroc.position.x = 300;
|
||||||
mrCroc.position.y = 100;
|
mrCroc.position.y = 100;
|
||||||
|
|
||||||
architecture.draw(context);
|
|
||||||
mrCroc.draw(context);
|
|
||||||
|
|
||||||
window.requestAnimationFrame(MainLoop);
|
window.requestAnimationFrame(MainLoop);
|
||||||
}
|
}
|
||||||
);
|
);
|
||||||
|
|
|
@ -1,6 +1,7 @@
|
||||||
import RetroSprite from "./RetroSprite.js";
|
import RetroSprite from "./RetroSprite.js";
|
||||||
import RetroArchitectureTile from "./RetroArchitectureTile.js";
|
import RetroArchitectureTile from "./RetroArchitectureTile.js";
|
||||||
import GeometryRectCollection from "../geometry/GeometryRectCollection.js";
|
import GeometryRectCollection from "../geometry/GeometryRectCollection.js";
|
||||||
|
import GeometryPoint from "../geometry/GeometryPoint.js";
|
||||||
|
|
||||||
export default class RetroArchitecture
|
export default class RetroArchitecture
|
||||||
{
|
{
|
||||||
|
@ -67,10 +68,10 @@ export default class RetroArchitecture
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
getTileForPosition(position)
|
getTileForPosition(position, offsetX = 0, offsetY = 0)
|
||||||
{
|
{
|
||||||
let x = parseInt(position.x / this.tileWidth);
|
let x = parseInt(position.x / this.tileWidth) + offsetX;
|
||||||
let y = parseInt(position.y / this.tileHeight);
|
let y = parseInt(position.y / this.tileHeight) + offsetY;
|
||||||
|
|
||||||
if (x < 0 || x >= this.columns || y < 0 || y >= this.rows) {
|
if (x < 0 || x >= this.columns || y < 0 || y >= this.rows) {
|
||||||
return null;
|
return null;
|
||||||
|
@ -79,13 +80,28 @@ export default class RetroArchitecture
|
||||||
return {x: x, y: y};
|
return {x: x, y: y};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
getCeilingHeight(position)
|
||||||
|
{
|
||||||
|
let tilePosition = this.getTileForPosition(position, 0);
|
||||||
|
|
||||||
|
while (tilePosition !== null && tilePosition.y > 0) {
|
||||||
|
if (this.matrix[tilePosition.y][tilePosition.x] !== null) {
|
||||||
|
return tilePosition.y * this.tileHeight + this.tileHeight;
|
||||||
|
}
|
||||||
|
|
||||||
|
tilePosition.y--;
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
getGroundHeight(position)
|
getGroundHeight(position)
|
||||||
{
|
{
|
||||||
let tilePosition = this.getTileForPosition(position);
|
let tilePosition = this.getTileForPosition(position);
|
||||||
|
|
||||||
while (tilePosition !== null && tilePosition.y < this.rows) {
|
while (tilePosition !== null && tilePosition.y < this.rows) {
|
||||||
if (this.matrix[tilePosition.y][tilePosition.x] !== null) {
|
if (this.matrix[tilePosition.y][tilePosition.x] !== null) {
|
||||||
return tilePosition.y * this.tileHeight
|
return tilePosition.y * this.tileHeight;
|
||||||
}
|
}
|
||||||
|
|
||||||
tilePosition.y++;
|
tilePosition.y++;
|
||||||
|
@ -94,6 +110,36 @@ export default class RetroArchitecture
|
||||||
return this.tileHeight * this.rows;
|
return this.tileHeight * this.rows;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
getWallRight(position)
|
||||||
|
{
|
||||||
|
let tilePosition = this.getTileForPosition(new GeometryPoint(position.x, position.y), 1, -1);
|
||||||
|
|
||||||
|
while (tilePosition !== null && tilePosition.x < this.columns) {
|
||||||
|
if (this.matrix[tilePosition.y][tilePosition.x] !== null) {
|
||||||
|
return tilePosition.x * this.tileWidth - this.tileWidth * 0.5;
|
||||||
|
}
|
||||||
|
|
||||||
|
tilePosition.x++;
|
||||||
|
}
|
||||||
|
|
||||||
|
return this.tileWidth * this.columns;
|
||||||
|
}
|
||||||
|
|
||||||
|
getWallLeft(position)
|
||||||
|
{
|
||||||
|
let tilePosition = this.getTileForPosition(new GeometryPoint(position.x, position.y), -1,-1);
|
||||||
|
|
||||||
|
while (tilePosition !== null && tilePosition.x > 0) {
|
||||||
|
if (this.matrix[tilePosition.y][tilePosition.x] !== null) {
|
||||||
|
return tilePosition.x * this.tileWidth + this.tileWidth * 1.5;
|
||||||
|
}
|
||||||
|
|
||||||
|
tilePosition.x--;
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
draw(context)
|
draw(context)
|
||||||
{
|
{
|
||||||
for (let y = 0; y < this.rows; y++) {
|
for (let y = 0; y < this.rows; y++) {
|
||||||
|
|
Loading…
Reference in New Issue