Compare commits
13 Commits
master
...
feature/pa
Author | SHA1 | Date | |
---|---|---|---|
|
18acbd96b2 | ||
|
14ad28dd29 | ||
|
4d6a9561ae | ||
|
1316c814ec | ||
|
2d701de8d1 | ||
|
9f53e28f35 | ||
|
e620ff9c94 | ||
|
5446079fe6 | ||
|
de6b327837 | ||
|
18df8c17ec | ||
|
2c88c9ce20 | ||
|
2eade7a21b | ||
|
ae48ce9de2 |
6
.gitignore
vendored
6
.gitignore
vendored
@ -1,7 +1,3 @@
|
||||
.idea/
|
||||
.DS_Store
|
||||
node_modules/
|
||||
dist/
|
||||
docs/
|
||||
examples/*/dist/
|
||||
browse.VC.db
|
||||
node_modules/
|
2
dist/es5.js
vendored
Normal file
2
dist/es5.js
vendored
Normal file
File diff suppressed because one or more lines are too long
1
dist/es5.js.map
vendored
Normal file
1
dist/es5.js.map
vendored
Normal file
File diff suppressed because one or more lines are too long
@ -1,103 +0,0 @@
|
||||
"use strict";
|
||||
|
||||
import MomentumEngine from "../../src/es6";
|
||||
|
||||
let KeyConsts = MomentumEngine.Consts.Input.Keys;
|
||||
|
||||
let black = new MomentumEngine.Classes.Color(0, 0, 0),
|
||||
fireParticleWidth = 150,
|
||||
fireParticleHeight = 150;
|
||||
|
||||
|
||||
let startColour = new MomentumEngine.Classes.Color(250, 218, 68, 1),
|
||||
startColourRandom = new MomentumEngine.Classes.Color(62, 60, 60, 0),
|
||||
finishColour = new MomentumEngine.Classes.Color(245, 35, 0, 0),
|
||||
finishColourRandom = new MomentumEngine.Classes.Color(60, 60, 60, 0);
|
||||
|
||||
|
||||
class RandomColor extends MomentumEngine.Classes.Color {
|
||||
|
||||
constructor (initialColor, deltaColor) {
|
||||
|
||||
let r = initialColor.r + (deltaColor.r * RandomColor._rand()),
|
||||
g = initialColor.g + (deltaColor.g * RandomColor._rand()),
|
||||
b = initialColor.b + (deltaColor.b * RandomColor._rand()),
|
||||
a = initialColor.a + (deltaColor.a * RandomColor._rand());
|
||||
|
||||
super(~~r, ~~g, ~~b, ~~a);
|
||||
|
||||
}
|
||||
|
||||
static _rand () {
|
||||
return (Math.random() * 2 - 1);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
class FireParticle extends MomentumEngine.Classes.Entity {
|
||||
|
||||
constructor (x, y) {
|
||||
super(x, y);
|
||||
this.timeToLive = 10000;
|
||||
this.startColor = new RandomColor(startColour, startColourRandom);
|
||||
this.finishColor = new RandomColor(finishColour, startColour);
|
||||
this.deltaColor = startColour.clone().subtract(finishColour);
|
||||
}
|
||||
|
||||
update (delta) {
|
||||
this.startColor.a = this.startColor.a - (delta * 0.0001);
|
||||
}
|
||||
|
||||
render () {
|
||||
|
||||
var gradient = this._game.context.createRadialGradient(
|
||||
this.relativeLeft + fireParticleWidth / 2,
|
||||
this.relativeTop + fireParticleHeight / 2,
|
||||
fireParticleWidth / 10,
|
||||
this.relativeLeft + fireParticleWidth / 2,
|
||||
this.relativeTop + fireParticleHeight / 2,
|
||||
fireParticleWidth / 2
|
||||
);
|
||||
|
||||
gradient.addColorStop(0, this.startColor.toString());
|
||||
gradient.addColorStop(1, "rgba(0, 0, 0, 0)");
|
||||
this._game.context.fillStyle = gradient;
|
||||
this._game.context.fillRect(this.relativeLeft, this.relativeTop, fireParticleWidth, fireParticleHeight);
|
||||
|
||||
return true;
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
window.onload = function () {
|
||||
|
||||
let width = 640,
|
||||
height = 360,
|
||||
baseSize = width / 64;
|
||||
|
||||
let fireDemo = new MomentumEngine.Classes.Game({
|
||||
canvas: document.getElementById("canvas"),
|
||||
width: width,
|
||||
height: height,
|
||||
fixRatio: true,
|
||||
desiredFps: 60,
|
||||
inputs: {
|
||||
keyboard: true
|
||||
}
|
||||
});
|
||||
|
||||
let mainScene = new MomentumEngine.Classes.Rect(0, 0, width, height, black);
|
||||
fireDemo.addChildEntity(mainScene);
|
||||
|
||||
let fireEmitter = new MomentumEngine.Classes.Emitter(width / 2 - (fireParticleWidth / 2), height / 2 - (fireParticleHeight / 2), 250, new MomentumEngine.Classes.Vector2D(0.02, 0.02), FireParticle);
|
||||
mainScene.addChildEntity(fireEmitter);
|
||||
|
||||
fireEmitter.setParticleParent(mainScene);
|
||||
fireEmitter.emitting = true;
|
||||
|
||||
fireDemo.start();
|
||||
|
||||
};
|
@ -1,10 +0,0 @@
|
||||
<!doctype html>
|
||||
<html>
|
||||
<head>
|
||||
<title>Fire - MomentumEngine</title>
|
||||
<script type="application/javascript" src="./dist/fire.js"></script>
|
||||
</head>
|
||||
<body>
|
||||
<canvas id="canvas"></canvas>
|
||||
</body>
|
||||
</html>
|
2
examples/particles/dist/particles.js
vendored
Normal file
2
examples/particles/dist/particles.js
vendored
Normal file
File diff suppressed because one or more lines are too long
1
examples/particles/dist/particles.js.map
vendored
Normal file
1
examples/particles/dist/particles.js.map
vendored
Normal file
File diff suppressed because one or more lines are too long
@ -8,12 +8,12 @@ let KeyConsts = MomentumEngine.Consts.Input.Keys;
|
||||
class BlueParticle extends MomentumEngine.Classes.Rect {
|
||||
|
||||
constructor (x, y) {
|
||||
super(x, y, 1, 1, new MomentumEngine.Classes.Color(0, 255, 0));
|
||||
this.timeToLive = 25500;
|
||||
super(x, y, 1, 1, new MomentumEngine.Classes.Color(255, 255, 255, 0));
|
||||
this.timeToLive = 5000;
|
||||
}
|
||||
|
||||
update (delta) {
|
||||
this.color.a = this.color.a - (delta * 0.00004);
|
||||
this.color.a = this.color.a - (delta * 0.00025);
|
||||
}
|
||||
|
||||
}
|
||||
@ -25,7 +25,7 @@ window.onload = function () {
|
||||
height = 360,
|
||||
baseSize = width / 64;
|
||||
|
||||
let particleDemo = new MomentumEngine.Classes.Game({
|
||||
let particles = new MomentumEngine.Classes.Game({
|
||||
canvas: document.getElementById("canvas"),
|
||||
width: width,
|
||||
height: height,
|
||||
@ -37,54 +37,40 @@ window.onload = function () {
|
||||
});
|
||||
|
||||
let black = new MomentumEngine.Classes.Color(0, 0, 0),
|
||||
red = new MomentumEngine.Classes.Color(255, 0, 0),
|
||||
blue = new MomentumEngine.Classes.Color(0, 0, 255);
|
||||
red = new MomentumEngine.Classes.Color(255, 0, 0);
|
||||
|
||||
let mainScene = new MomentumEngine.Classes.Rect(0, 0, width, height, black);
|
||||
particleDemo.addChildEntity(mainScene);
|
||||
particles.addChildEntity(mainScene);
|
||||
|
||||
let emitterRect = new MomentumEngine.Classes.Rect(width / 8 - baseSize, height / 2 - baseSize, baseSize * 2, baseSize * 2, red),
|
||||
let rect = new MomentumEngine.Classes.Rect(width / 2 - baseSize, height / 2 - baseSize, baseSize * 2, baseSize * 2, red),
|
||||
emitter = new MomentumEngine.Classes.Emitter(baseSize, baseSize, 4, new MomentumEngine.Classes.Vector2D(0, 0.05), BlueParticle);
|
||||
|
||||
let bottomFieldRect = new MomentumEngine.Classes.Rect(width - (baseSize * 33), height - (baseSize * 11), baseSize * 2, baseSize * 2, blue),
|
||||
bottomField = new MomentumEngine.Classes.Field(baseSize, baseSize, 0.1);
|
||||
mainScene.addChildEntity(rect);
|
||||
rect.addChildEntity(emitter);
|
||||
|
||||
let topFieldRect = new MomentumEngine.Classes.Rect(width - (baseSize * 33), baseSize * 9, baseSize * 2, baseSize * 2, blue),
|
||||
topField = new MomentumEngine.Classes.Field(baseSize, baseSize, 0.1);
|
||||
rect.update = function (delta) {
|
||||
|
||||
mainScene.addChildEntity(emitterRect);
|
||||
emitterRect.addChildEntity(emitter);
|
||||
|
||||
mainScene.addChildEntity(bottomFieldRect);
|
||||
bottomFieldRect.addChildEntity(bottomField);
|
||||
mainScene.addChildEntity(topFieldRect);
|
||||
topFieldRect.addChildEntity(topField);
|
||||
|
||||
emitterRect.update = function (delta) {
|
||||
|
||||
if (particleDemo.inputs.keyboard.isPressed(KeyConsts.UP)) {
|
||||
emitterRect.pos.y -= (0.2 * delta);
|
||||
if (particles.inputs.keyboard.isPressed(KeyConsts.UP)) {
|
||||
rect.pos.y -= (0.2 * delta);
|
||||
}
|
||||
|
||||
if (particleDemo.inputs.keyboard.isPressed(KeyConsts.DOWN)) {
|
||||
emitterRect.pos.y += (0.2 * delta);
|
||||
if (particles.inputs.keyboard.isPressed(KeyConsts.DOWN)) {
|
||||
rect.pos.y += (0.2 * delta);
|
||||
}
|
||||
|
||||
if (particleDemo.inputs.keyboard.isPressed(KeyConsts.LEFT)) {
|
||||
emitterRect.pos.x -= (0.2 * delta);
|
||||
if (particles.inputs.keyboard.isPressed(KeyConsts.LEFT)) {
|
||||
rect.pos.x -= (0.2 * delta);
|
||||
}
|
||||
|
||||
if (particleDemo.inputs.keyboard.isPressed(KeyConsts.RIGHT)) {
|
||||
emitterRect.pos.x += (0.2 * delta);
|
||||
if (particles.inputs.keyboard.isPressed(KeyConsts.RIGHT)) {
|
||||
rect.pos.x += (0.2 * delta);
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
emitter.setParticleParent(mainScene);
|
||||
emitter.particleFields.push(bottomField, topField);
|
||||
emitter.spread = Math.PI / 8;
|
||||
emitter.emitting = true;
|
||||
|
||||
particleDemo.start();
|
||||
particles.start();
|
||||
|
||||
};
|
@ -2,7 +2,8 @@
|
||||
<html>
|
||||
<head>
|
||||
<title>Pong - MomentumEngine</title>
|
||||
<script type="application/javascript" src="./dist/pong.js"></script>
|
||||
<script type="application/javascript" src="../../dist/es5.js"></script>
|
||||
<script type="application/javascript" src="./pong.js"></script>
|
||||
</head>
|
||||
<body>
|
||||
<canvas id="canvas"></canvas>
|
||||
|
@ -1,332 +1,118 @@
|
||||
"use strict";
|
||||
|
||||
import MomentumEngine from "../../src/es6";
|
||||
|
||||
|
||||
let KeyConsts = MomentumEngine.Consts.Input.Keys;
|
||||
|
||||
let width = 640,
|
||||
height = 360,
|
||||
baseSize = width / 64;
|
||||
|
||||
let white = new MomentumEngine.Classes.Color(255, 255, 255),
|
||||
black = new MomentumEngine.Classes.Color(0, 0, 0),
|
||||
red = new MomentumEngine.Classes.Color(255, 0, 0);
|
||||
|
||||
let font = new MomentumEngine.Classes.Font("Arial", 32, white, red);
|
||||
|
||||
|
||||
class Ball extends MomentumEngine.Classes.Rect {
|
||||
|
||||
|
||||
constructor (startingLeft, startingTop) {
|
||||
|
||||
super(startingLeft, startingTop, baseSize, baseSize, white);
|
||||
|
||||
this.startingLeft = startingLeft;
|
||||
this.startingTop = startingTop;
|
||||
this.speed = new MomentumEngine.Classes.Vector2D(0.1, 0.05); // Starting ball speed
|
||||
|
||||
}
|
||||
|
||||
|
||||
update (delta) {
|
||||
|
||||
this.pos.add(this.speed.clone().multiply(delta));
|
||||
|
||||
if (this.left + baseSize > width && this.speed.x > 0) {
|
||||
|
||||
this.left = this.startingLeft;
|
||||
this.top = this.startingTop;
|
||||
this.game.leftScoreboard.increment();
|
||||
|
||||
} else if (this.left < 0 && this.speed.x < 0) {
|
||||
|
||||
this.left = this.startingLeft;
|
||||
this.top = this.startingTop;
|
||||
this.game.rightScoreboard.increment();
|
||||
|
||||
}
|
||||
|
||||
if ((this.top + baseSize > height && this.speed.y > 0) || (this.top < 0 && this.speed.y < 0)) {
|
||||
this.speed.y = -this.speed.y;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
||||
class Paddle extends MomentumEngine.Classes.Rect {
|
||||
|
||||
|
||||
constructor (posLeft, keys) {
|
||||
|
||||
super(posLeft, baseSize, baseSize, baseSize * 7, white);
|
||||
|
||||
this.keyUp = keys.up;
|
||||
this.keyDown = keys.down;
|
||||
this.scoreboard = null;
|
||||
|
||||
}
|
||||
|
||||
|
||||
update (delta) {
|
||||
|
||||
if (this.keyUp(this, delta)) {
|
||||
this.top -= (0.5 * delta);
|
||||
} else if (this.keyDown(this, delta)) {
|
||||
this.top += (0.5 * delta);
|
||||
}
|
||||
|
||||
if (this.top > height - (baseSize * 8)) {
|
||||
this.top = height - (baseSize * 8);
|
||||
} else if (this.top < baseSize) {
|
||||
this.top = baseSize;
|
||||
}
|
||||
|
||||
this.balls.forEach((ball) => {
|
||||
if (this.isCollidingWith(ball)) {
|
||||
ball.speed.x = -ball.speed.x;
|
||||
}
|
||||
});
|
||||
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
||||
class Scoreboard extends MomentumEngine.Classes.Text {
|
||||
|
||||
|
||||
constructor (posLeft) {
|
||||
super(posLeft, 35, font);
|
||||
this.score = 0;
|
||||
this.text = "Score: 0";
|
||||
}
|
||||
|
||||
|
||||
increment () {
|
||||
this.score++;
|
||||
this.text = `Score: ${this.score}`;
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
||||
class Pong extends MomentumEngine.Classes.Game {
|
||||
|
||||
|
||||
constructor (canvas, width, height) {
|
||||
|
||||
super({
|
||||
canvas: canvas,
|
||||
width: width,
|
||||
height: height,
|
||||
fixRatio: true,
|
||||
desiredFps: 60,
|
||||
//fixFrameRate: true,
|
||||
fullscreen: {
|
||||
nativeResolution: true,
|
||||
maintainAspectRatio: true
|
||||
},
|
||||
inputs: {
|
||||
keyboard: true,
|
||||
gamepad: true
|
||||
}
|
||||
});
|
||||
|
||||
let background = new MomentumEngine.Classes.Rect(0, 0, width, height, black);
|
||||
this.addChildEntity(background);
|
||||
|
||||
this.balls = [];
|
||||
this.paddles = [];
|
||||
|
||||
}
|
||||
|
||||
|
||||
setLeftScoreboard (scoreboard) {
|
||||
this.leftScoreboard = scoreboard;
|
||||
this.addChildEntity(scoreboard);
|
||||
}
|
||||
|
||||
setRightScoreboard (scoreboard) {
|
||||
this.rightScoreboard = scoreboard;
|
||||
this.addChildEntity(scoreboard);
|
||||
}
|
||||
|
||||
|
||||
addBall (ball) {
|
||||
ball.game = this;
|
||||
this.balls.push(ball);
|
||||
this.addChildEntity(ball);
|
||||
}
|
||||
|
||||
|
||||
addPaddle (paddle) {
|
||||
this.paddles.push(paddle);
|
||||
this.addChildEntity(paddle);
|
||||
paddle.balls = this.balls;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
var leftPaddleUpCondition = function (paddle, delta) {
|
||||
|
||||
let gamepadInput = paddle._game.inputs.gamepad;
|
||||
|
||||
let gamepadConnected = (gamepadInput.numGamepads >= 1),
|
||||
axisMoved = false;
|
||||
|
||||
if (gamepadConnected) {
|
||||
|
||||
let upDownAxes = gamepadInput.getGamepadById(0).getAxis(1);
|
||||
|
||||
if (upDownAxes < -0.1) {
|
||||
this.top += (0.5 * delta) * upDownAxes;
|
||||
axisMoved = true;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
if (!axisMoved) {
|
||||
if (paddle._game.inputs.keyboard.isPressed(KeyConsts.CHAR_Q)) {
|
||||
this.top -= 0.5 * delta;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
|
||||
var leftPaddleDownCondition = function (paddle, delta) {
|
||||
|
||||
let gamepadInput = paddle._game.inputs.gamepad;
|
||||
|
||||
let gamepadConnected = (gamepadInput.numGamepads >= 1),
|
||||
axisMoved = false;
|
||||
|
||||
if (gamepadConnected) {
|
||||
|
||||
let upDownAxes = gamepadInput.getGamepadById(0).getAxis(1);
|
||||
|
||||
if (upDownAxes > 0.1) {
|
||||
this.top += (0.5 * delta) * upDownAxes;
|
||||
axisMoved = true;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
if (!axisMoved) {
|
||||
if (paddle._game.inputs.keyboard.isPressed(KeyConsts.CHAR_A)) {
|
||||
this.top += 0.5 * delta;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
|
||||
var rightPaddleUpCondition = function (paddle, delta) {
|
||||
|
||||
let gamepadInput = paddle._game.inputs.gamepad;
|
||||
|
||||
let gamepadConnected = (gamepadInput.numGamepads >= 1 && gamepadInput.getGamepadById(0).numAxis >= 6),
|
||||
axisMoved = false;
|
||||
|
||||
if (gamepadConnected) {
|
||||
|
||||
let upDownAxes = gamepadInput.getGamepadById(0).getAxis(4);
|
||||
|
||||
if (upDownAxes < -0.1) {
|
||||
this.top += (0.5 * delta) * upDownAxes;
|
||||
axisMoved = true;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
if (!axisMoved) {
|
||||
if (paddle._game.inputs.keyboard.isPressed(KeyConsts.CHAR_O)) {
|
||||
this.top -= 0.5 * delta;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
|
||||
var rightPaddleDownCondition = function (paddle, delta) {
|
||||
|
||||
let gamepadInput = paddle._game.inputs.gamepad;
|
||||
|
||||
let gamepadConnected = (gamepadInput.numGamepads >= 1),
|
||||
axisMoved = false;
|
||||
|
||||
if (gamepadConnected) {
|
||||
|
||||
let upDownAxes = gamepadInput.getGamepadById(0).getAxis(4);
|
||||
|
||||
if (upDownAxes > 0.1) {
|
||||
this.top += (0.5 * delta) * upDownAxes;
|
||||
axisMoved = true;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
if (!axisMoved) {
|
||||
if (paddle._game.inputs.keyboard.isPressed(KeyConsts.CHAR_L)) {
|
||||
this.top += 0.5 * delta;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
window.onload = function () {
|
||||
|
||||
var pong = new Pong(document.getElementById("canvas"), width, height);
|
||||
|
||||
var ball = new Ball((width / 2) - (baseSize / 2), (height / 2) - (baseSize / 2));
|
||||
var KeyConsts = MomentumEngine.Consts.Input.Keys;
|
||||
|
||||
var leftPaddle = new Paddle(baseSize, {
|
||||
up: leftPaddleUpCondition,
|
||||
down: leftPaddleDownCondition
|
||||
|
||||
var width = 640,
|
||||
height = 360,
|
||||
baseSize = width / 64;
|
||||
|
||||
|
||||
var pong = new MomentumEngine.Classes.Game({
|
||||
canvas: document.getElementById("canvas"),
|
||||
width: width,
|
||||
height: height,
|
||||
fixRatio: true,
|
||||
desiredFps: 60,
|
||||
inputs: {
|
||||
keyboard: true
|
||||
}
|
||||
});
|
||||
|
||||
var rightPaddle = new Paddle(width - (baseSize * 2), {
|
||||
up: rightPaddleUpCondition,
|
||||
down: rightPaddleDownCondition
|
||||
});
|
||||
|
||||
var leftScoreboard = new Scoreboard(baseSize),
|
||||
rightScoreboard = new Scoreboard(width - baseSize);
|
||||
// Colors
|
||||
var white = new MomentumEngine.Classes.Color(255, 255, 255),
|
||||
black = new MomentumEngine.Classes.Color(0, 0, 0);
|
||||
|
||||
|
||||
// All of these are instances of MomentumEngine.Classes.Entity
|
||||
var mainScene = new MomentumEngine.Classes.Rect(0, 0, width, height, black),
|
||||
ball = new MomentumEngine.Classes.Rect((width / 2) - (baseSize / 2), (height / 2) - (baseSize / 2), baseSize, baseSize, white),
|
||||
leftPaddle = new MomentumEngine.Classes.Rect(baseSize, baseSize, baseSize, baseSize * 7, white),
|
||||
rightPaddle = new MomentumEngine.Classes.Rect(width - (baseSize * 2), baseSize, baseSize, baseSize * 7, white);
|
||||
|
||||
rightScoreboard.textAlign = "right"; // Right align the text of the right scoreboard
|
||||
|
||||
// Create scene graph
|
||||
pong.addBall(ball);
|
||||
pong.addPaddle(leftPaddle);
|
||||
pong.addPaddle(rightPaddle);
|
||||
pong.addChildEntity(mainScene);
|
||||
mainScene.addChildEntity(ball);
|
||||
mainScene.addChildEntity(leftPaddle);
|
||||
mainScene.addChildEntity(rightPaddle);
|
||||
|
||||
|
||||
// Update the ball position
|
||||
ball.state.speed = new MomentumEngine.Classes.Vector2D(0.1, 0.05); // Current ball speed
|
||||
|
||||
ball.update = function (delta) {
|
||||
|
||||
this.pos.add(this.state.speed.clone().multiply(delta));
|
||||
|
||||
if ((this.pos.x + baseSize > width && this.state.speed.x > 0) || (this.pos.x < 0 && this.state.speed.x < 0)) {
|
||||
this.state.speed.x = -this.state.speed.x;
|
||||
}
|
||||
|
||||
if ((this.pos.y + baseSize > height && this.state.speed.y > 0) || (this.pos.y < 0 && this.state.speed.y < 0)) {
|
||||
this.state.speed.y = -this.state.speed.y;
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
|
||||
// Update the left paddle according to keyboard input
|
||||
leftPaddle.update = function (delta) {
|
||||
|
||||
if (pong.inputs.keyboard.isPressed(KeyConsts.CHAR_Q) || pong.inputs.keyboard.isPressed(KeyConsts.UP)) {
|
||||
leftPaddle.pos.y -= (0.5 * delta);
|
||||
}
|
||||
|
||||
if (pong.inputs.keyboard.isPressed(KeyConsts.CHAR_A) || pong.inputs.keyboard.isPressed(KeyConsts.DOWN)) {
|
||||
leftPaddle.pos.y += (0.5 * delta);
|
||||
}
|
||||
|
||||
if (leftPaddle.pos.y > height - (baseSize * 8)) {
|
||||
leftPaddle.pos.y = height - (baseSize * 8);
|
||||
}
|
||||
|
||||
if (leftPaddle.pos.y < baseSize) {
|
||||
leftPaddle.pos.y = baseSize;
|
||||
}
|
||||
|
||||
if (leftPaddle.isCollidingWith(ball) && ball.state.speed.x < 0) {
|
||||
ball.state.speed.x = -ball.state.speed.x;
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
|
||||
// Update the right paddle according to keyboard input
|
||||
rightPaddle.update = function (delta) {
|
||||
|
||||
if (pong.inputs.keyboard.isPressed(KeyConsts.CHAR_O)) {
|
||||
rightPaddle.pos.y -= (0.5 * delta);
|
||||
}
|
||||
|
||||
if (pong.inputs.keyboard.isPressed(KeyConsts.CHAR_L)) {
|
||||
rightPaddle.pos.y += (0.5 * delta);
|
||||
}
|
||||
|
||||
if (rightPaddle.pos.y > height - (baseSize * 8)) {
|
||||
rightPaddle.pos.y = height - (baseSize * 8);
|
||||
}
|
||||
|
||||
if (rightPaddle.pos.y < baseSize) {
|
||||
rightPaddle.pos.y = baseSize;
|
||||
}
|
||||
|
||||
if (rightPaddle.isCollidingWith(ball) && ball.state.speed.x > 0) {
|
||||
ball.state.speed.x = -ball.state.speed.x;
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
pong.setLeftScoreboard(leftScoreboard);
|
||||
pong.setRightScoreboard(rightScoreboard);
|
||||
|
||||
pong.start();
|
||||
|
||||
|
||||
document.addEventListener("keydown", function(e) {
|
||||
if (e.keyCode == 13) {
|
||||
pong.toggleFullScreen();
|
||||
}
|
||||
}, false);
|
||||
|
||||
|
||||
};
|
@ -2,7 +2,8 @@
|
||||
<html>
|
||||
<head>
|
||||
<title>Snowflakes - MomentumEngine</title>
|
||||
<script type="application/javascript" src="./dist/snowflakes.js"></script>
|
||||
<script type="application/javascript" src="../../dist/es5.js"></script>
|
||||
<script type="application/javascript" src="./snowflakes.js"></script>
|
||||
</head>
|
||||
<body>
|
||||
<canvas id="canvas"></canvas>
|
||||
|
@ -1,13 +1,11 @@
|
||||
"use strict";
|
||||
|
||||
import MomentumEngine from "../../src/es6";
|
||||
|
||||
let KeyConsts = MomentumEngine.Consts.Input.Keys;
|
||||
|
||||
|
||||
window.onload = function () {
|
||||
|
||||
|
||||
var KeyConsts = MomentumEngine.Consts.Input.Keys;
|
||||
|
||||
|
||||
var width = 640,
|
||||
height = 360;
|
||||
|
||||
@ -45,14 +43,14 @@ window.onload = function () {
|
||||
var newSnowflake = new MomentumEngine.Classes.Sprite(startPos, -100, 100, 100, snowflakeImg);
|
||||
|
||||
newSnowflake.update = function () {
|
||||
this.top = this.top + (delta * 0.06);
|
||||
this.pos.y = this.pos.y + (delta * 0.06);
|
||||
};
|
||||
|
||||
mainScene.addChildEntity(newSnowflake);
|
||||
|
||||
mainScene.children.forEach(function (oldSnowflake) {
|
||||
|
||||
if (oldSnowflake.top > height) {
|
||||
if (oldSnowflake.pos.y > height) {
|
||||
// Clean up snowflakes that are no longer visible
|
||||
mainScene.detachChildEntity(oldSnowflake);
|
||||
}
|
||||
|
94
gulpfile.js
94
gulpfile.js
@ -3,33 +3,7 @@
|
||||
var gulp = require("gulp"),
|
||||
path = require("path"),
|
||||
gutil = require("gulp-util"),
|
||||
webpack = require("webpack"),
|
||||
jsdoc = require("gulp-jsdoc3");
|
||||
|
||||
|
||||
let minify = true,
|
||||
watch = false,
|
||||
examples = [
|
||||
"fire",
|
||||
"particles",
|
||||
"pong",
|
||||
"snowflakes"
|
||||
];
|
||||
|
||||
|
||||
process.argv.forEach((arg) => {
|
||||
|
||||
if (arg == "--dev" || arg == "-d") {
|
||||
minify = false;
|
||||
gutil.log("[Momentum Engine] dev flag passed, enabled");
|
||||
}
|
||||
|
||||
if (arg == "--watch" || arg == "-w") {
|
||||
watch = true;
|
||||
gutil.log("[Momentum Engine] watch flag passed, enabled");
|
||||
}
|
||||
|
||||
});
|
||||
webpack = require("webpack");
|
||||
|
||||
|
||||
var build = function (options, callback) {
|
||||
@ -51,13 +25,16 @@ var build = function (options, callback) {
|
||||
}
|
||||
|
||||
webpack({
|
||||
entry: options.entry,
|
||||
entry: {
|
||||
"es5": path.join(__dirname, "src", "es5.js"),
|
||||
"particles": path.join(__dirname, "examples/particles", "particles.js")
|
||||
},
|
||||
bail: !options.watch,
|
||||
watch: options.watch,
|
||||
devtool: "source-map",
|
||||
plugins: plugins,
|
||||
output: {
|
||||
path: options.path,
|
||||
path: path.join(__dirname, "dist"),
|
||||
filename: "[name].js"
|
||||
},
|
||||
module: {
|
||||
@ -101,51 +78,34 @@ var build = function (options, callback) {
|
||||
};
|
||||
|
||||
|
||||
examples.forEach((example) => {
|
||||
|
||||
let entry = {};
|
||||
entry[example] = path.join(__dirname, "examples", example, `${example}.js`);
|
||||
|
||||
gulp.task(`${example}-example`, (callback) => {
|
||||
|
||||
build({
|
||||
entry: entry,
|
||||
path: path.join(__dirname, "examples", example, "dist"),
|
||||
watch: watch,
|
||||
minify: minify
|
||||
}, callback);
|
||||
});
|
||||
|
||||
gulp.task("move", () => {
|
||||
gulp.src([
|
||||
"./dist/particles.*"
|
||||
], {
|
||||
base: "./dist"
|
||||
}).pipe(gulp.dest("examples/particles/dist"));
|
||||
});
|
||||
|
||||
|
||||
gulp.task("examples", examples.map((example) => { return `${example}-example`; }));
|
||||
|
||||
|
||||
gulp.task("engine", (callback) => {
|
||||
gulp.task("build-dev", (callback) => {
|
||||
build({
|
||||
entry: {
|
||||
"es5": path.join(__dirname, "src", "es5.js")
|
||||
},
|
||||
path: path.join(__dirname, "dist"),
|
||||
watch: watch,
|
||||
minify: minify
|
||||
watch: false,
|
||||
minify: false
|
||||
}, callback);
|
||||
});
|
||||
|
||||
|
||||
gulp.task("docs", (callback) => {
|
||||
gulp.src([
|
||||
"src/classes/*.js"
|
||||
], {
|
||||
read: false
|
||||
}).pipe(jsdoc({
|
||||
opts: {
|
||||
destination: "docs"
|
||||
}
|
||||
}, callback));
|
||||
})
|
||||
gulp.task("build", (callback) => {
|
||||
build({
|
||||
watch: false,
|
||||
minify: true
|
||||
}, callback);
|
||||
});
|
||||
|
||||
|
||||
gulp.task("build", ["engine", "docs", "examples"]);
|
||||
gulp.task("default", ["build"]);
|
||||
gulp.task("watch", () => {
|
||||
build({
|
||||
watch: true,
|
||||
minify: false
|
||||
});
|
||||
});
|
33
package.json
33
package.json
@ -1,31 +1,26 @@
|
||||
{
|
||||
"name": "momentumengine",
|
||||
"version": "0.10.0",
|
||||
"version": "0.0.1",
|
||||
"description": "An ES6 game and animation engine.",
|
||||
"main": "src/es6.js",
|
||||
"repository": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/nathankunicki/momentumengine.git"
|
||||
},
|
||||
"scripts": {
|
||||
"postinstall": "gulp --silent",
|
||||
"build": "gulp",
|
||||
"test": "echo \"Error: no test specified\" && exit 1"
|
||||
},
|
||||
"author": "Nathan Kunicki <me@nathankunicki.com>",
|
||||
"license": "MIT",
|
||||
"license": "ISC",
|
||||
"engines": {
|
||||
"node": "^7.6.0"
|
||||
"node": "^4.2.3"
|
||||
},
|
||||
"dependencies": {
|
||||
"babel-core": "6.23.1",
|
||||
"babel-loader": "6.3.2",
|
||||
"babel-plugin-transform-runtime": "6.23.0",
|
||||
"babel-preset-es2015": "6.22.0",
|
||||
"babel-preset-stage-0": "6.22.0",
|
||||
"devDependencies": {
|
||||
"babel-core": "6.5.2",
|
||||
"babel-loader": "6.2.2",
|
||||
"babel-plugin-transform-runtime": "6.5.2",
|
||||
"babel-preset-es2015": "6.5.0",
|
||||
"babel-preset-stage-0": "6.5.0",
|
||||
"babel-runtime": "6.5.0",
|
||||
"gulp": "3.9.1",
|
||||
"gulp-jsdoc3": "1.0.1",
|
||||
"gulp-util": "3.0.8",
|
||||
"webpack": "2.2.1"
|
||||
}
|
||||
"gulp-util": "3.0.7",
|
||||
"webpack": "1.12.13"
|
||||
},
|
||||
"dependencies": {}
|
||||
}
|
||||
|
@ -1,87 +0,0 @@
|
||||
"use strict";
|
||||
|
||||
class AudioTrack {
|
||||
|
||||
|
||||
constructor (src) {
|
||||
|
||||
this._loaded = false; // Default is true, set it to false until the audio has loaded
|
||||
this._error = false; // If the audio fails to load, this will contain the reason
|
||||
this._loop = false;
|
||||
|
||||
this._audioObj = new Audio();
|
||||
|
||||
this._audioObj.addEventListener("loadeddata", () => {
|
||||
this._loaded = true;
|
||||
this._error = false;
|
||||
|
||||
this._audioObj.addEventListener("ended", () => {
|
||||
if (this._loop) {
|
||||
this._audioObj.currentTime = 0;
|
||||
this._audioObj.play();
|
||||
}
|
||||
});
|
||||
|
||||
});
|
||||
|
||||
this._audioObj.addEventListener("error", (err) => {
|
||||
this._loaded = false;
|
||||
this._error = err;
|
||||
});
|
||||
|
||||
this._audioObj.src = src;
|
||||
|
||||
}
|
||||
|
||||
|
||||
get loop () {
|
||||
return this._loop;
|
||||
}
|
||||
|
||||
|
||||
set loop (shouldLoop) {
|
||||
return this._loop = shouldLoop;
|
||||
}
|
||||
|
||||
|
||||
play () {
|
||||
if (this._loaded) {
|
||||
return this._audioObj.play();
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
pause () {
|
||||
if (this._loaded) {
|
||||
return this._audioObj.pause();
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
seek (seconds) {
|
||||
if (this._loaded) {
|
||||
return this._audioObj.currentTime = seconds;
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
isLoaded () {
|
||||
return this._loaded;
|
||||
}
|
||||
|
||||
|
||||
isError () {
|
||||
return this._error;
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
||||
export default AudioTrack;
|
@ -1,128 +1,28 @@
|
||||
"use strict";
|
||||
|
||||
|
||||
/**
|
||||
* Class representing a color
|
||||
*/
|
||||
class Color {
|
||||
|
||||
|
||||
/**
|
||||
* Create a color
|
||||
* @param {number} red - Red value (0-255)
|
||||
* @param {number} green - Green value (0-255)
|
||||
* @param {number} blue - Blue value (0-255)
|
||||
* @param {number} alpha - Alpha value (0-1)
|
||||
*/
|
||||
constructor (red = 0, green = 0, blue = 0, alpha = 1) {
|
||||
constructor (r, g, b, a) {
|
||||
|
||||
this.red = red;
|
||||
this.green = green;
|
||||
this.blue = blue;
|
||||
this.alpha = alpha;
|
||||
this.r = r || 0;
|
||||
this.g = g || 0;
|
||||
this.b = b || 0;
|
||||
this.a = a || 1;
|
||||
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Returns the rgba (rgba()) string representation of the color
|
||||
* @returns {string}
|
||||
*/
|
||||
toString () {
|
||||
return `rgba(${this.red}, ${this.green}, ${this.blue}, ${this.alpha})`;
|
||||
return `rgba(${this.r}, ${this.g}, ${this.b}, ${this.a})`;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Returns the hex (#) representation of the color
|
||||
* @returns {string}
|
||||
*/
|
||||
toHex () {
|
||||
return `#${((r << 16) | (g << 8) | b).toString(16)}`;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Clones the color and returns a new color
|
||||
* @returns {Color}
|
||||
*/
|
||||
clone () {
|
||||
return new Color(this.red, this.green, this.blue, this.alpha);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Add a color to this color
|
||||
* @param {Color} color - Color to add
|
||||
* @returns {Color}
|
||||
*/
|
||||
add (color) {
|
||||
|
||||
if (color instanceof Color) {
|
||||
this.red += color.r; this.green += color.g; this.blue += color.b; this.alpha += color.a;
|
||||
} else {
|
||||
this.red += color; this.green += color; this.blue += color; this.alpha += color;
|
||||
}
|
||||
|
||||
return this;
|
||||
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Subtract a color from this color
|
||||
* @param {Color} color - Color to subtract
|
||||
* @returns {Color}
|
||||
*/
|
||||
subtract (color) {
|
||||
|
||||
if (color instanceof Color) {
|
||||
this.red -= color.r; this.green -= color.g; this.blue -= color.b; this.alpha -= color.a;
|
||||
} else {
|
||||
this.red -= color; this.green -= color; this.blue -= color; this.alpha -= color;
|
||||
}
|
||||
|
||||
return this;
|
||||
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Multiply this color with another color
|
||||
* @param {Color} color - Color to multiply with
|
||||
* @returns {Color}
|
||||
*/
|
||||
multiply (color) {
|
||||
|
||||
if (color instanceof Color) {
|
||||
this.red *= color.r; this.green *= color.g; this.blue *= color.b; this.alpha *= color.a;
|
||||
} else {
|
||||
this.red *= color; this.green *= color; this.blue *= color; this.alpha *= color;
|
||||
}
|
||||
|
||||
return this;
|
||||
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Divide this color with another color
|
||||
* @param {Color} color - Color to divide by
|
||||
* @returns {Color}
|
||||
*/
|
||||
divide (color) {
|
||||
|
||||
if (color instanceof Color) {
|
||||
this.red /= color.r; this.green /= color.g; this.blue /= color.b; this.alpha /= color.a;
|
||||
} else {
|
||||
this.red /= color; this.green /= color; this.blue /= color; this.alpha /= color;
|
||||
}
|
||||
|
||||
return this;
|
||||
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
@ -3,8 +3,6 @@
|
||||
import Entity from "./entity.js";
|
||||
import Vector2D from "./vector2d.js";
|
||||
|
||||
import Utils from "../libs/utils";
|
||||
|
||||
|
||||
class Emitter extends Entity {
|
||||
|
||||
@ -15,7 +13,6 @@ class Emitter extends Entity {
|
||||
|
||||
this.particleVelocity = velocity;
|
||||
this.particleClass = particle;
|
||||
this.particleFields = [];
|
||||
|
||||
this.rate = rate;
|
||||
this.emitting = false;
|
||||
@ -42,10 +39,8 @@ class Emitter extends Entity {
|
||||
magnitude = this.particleVelocity.length(),
|
||||
velocity = Vector2D.fromAngle(angle, magnitude);
|
||||
|
||||
// NK: This might cause a bug where child renders have an incorrect position because preprocess should normally be called after the update function but before the render, here it is before update. We'll see.
|
||||
let particle = new ParticleClass(this.relativeLeft, this.relativeTop);
|
||||
let particle = new ParticleClass(this._calculatedPos.x, this._calculatedPos.y);
|
||||
particle.velocity = velocity;
|
||||
Utils.mergeIntoArray(particle.fields, this.particleFields);
|
||||
|
||||
//this._particles.push(particle);
|
||||
parent.addChildEntity(particle);
|
||||
@ -55,9 +50,13 @@ class Emitter extends Entity {
|
||||
|
||||
_triggerEmissions () {
|
||||
|
||||
// We prematurely call preprocess so that child particles can spawn from the emitters permission but be children of a different parent
|
||||
// NK: This might cause a bug where child renders have an incorrect position because preprocess should normally be called after the update function but before the render, here it is before update. We'll see.
|
||||
this._preprocess();
|
||||
|
||||
if (this.emitting) {
|
||||
|
||||
let currentTime = Date.now();
|
||||
let currentTime = +(new Date());
|
||||
|
||||
if (!this._wasEmitting) {
|
||||
this._wasEmitting = true;
|
||||
|
@ -2,35 +2,20 @@
|
||||
|
||||
import Vector2D from "./vector2d.js";
|
||||
|
||||
|
||||
/**
|
||||
* Class representing an entity in a scene
|
||||
*/
|
||||
class Entity {
|
||||
|
||||
|
||||
/**
|
||||
* Create an entity
|
||||
* @param {number} x - x (Left) position of the entity
|
||||
* @param {number} y - y (Top) position of the entity
|
||||
*/
|
||||
constructor (x = 0, y = 0) {
|
||||
constructor (x, y) {
|
||||
|
||||
this.pos = new Vector2D(x, y);
|
||||
this.pos = new Vector2D(x || 0, y || 0);
|
||||
this.velocity = new Vector2D(0, 0);
|
||||
this.acceleration = new Vector2D(0, 0);
|
||||
this.size = new Vector2D(0, 0);
|
||||
this.rotation = 0;
|
||||
this.display = true;
|
||||
|
||||
this.fields = [];
|
||||
|
||||
this.state = {};
|
||||
this.children = [];
|
||||
|
||||
this._relativePos = this.pos.clone();
|
||||
this._lastRelativePosCalculated = 0;
|
||||
this._lastRelativeSizeCalculated = 0;
|
||||
this._calculatedPos = this.pos.clone();
|
||||
this._lastCalculated = 0;
|
||||
this._game = null;
|
||||
this._parent = null;
|
||||
|
||||
@ -39,91 +24,6 @@ class Entity {
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* x (Left) position of the entity
|
||||
*/
|
||||
get left () {
|
||||
return this.pos.x;
|
||||
}
|
||||
|
||||
set left (val) {
|
||||
let res = (this.pos.x = val);
|
||||
if (this._parent) {
|
||||
this._relativePos.x = this.pos.x + this._parent.relativeLeft;
|
||||
} else {
|
||||
this._relativePos.x = this.pos.x;
|
||||
}
|
||||
return res;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* y (Top) position of the entity
|
||||
*/
|
||||
get top () {
|
||||
return this.pos.y;
|
||||
}
|
||||
|
||||
set top (val) {
|
||||
let res = (this.pos.y = val);
|
||||
if (this._parent) {
|
||||
this._relativePos.y = this.pos.y + this._parent.relativeTop;
|
||||
} else {
|
||||
this._relativePos.y = this.pos.y;
|
||||
}
|
||||
return res;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Returns the absolute x (Left) position relative to the entities parent tree
|
||||
* @returns {number} x - x (Left) position relative to the entities parent tree
|
||||
*/
|
||||
get relativeLeft () {
|
||||
return this._calculateRelativePos().x;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Returns the absolute y (Top) position relative to the entities parent tree
|
||||
* @returns {number} y - y (Top) position relative to the entities parent tree
|
||||
*/
|
||||
get relativeTop () {
|
||||
return this._calculateRelativePos().y;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Width of the entity
|
||||
*/
|
||||
get width () {
|
||||
return this.size.x;
|
||||
}
|
||||
|
||||
|
||||
set width (width) {
|
||||
return this.size.x = width;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Height of the entity
|
||||
*/
|
||||
get height () {
|
||||
return this.size.y;
|
||||
}
|
||||
|
||||
|
||||
set height (height) {
|
||||
return this.size.y = height;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Set the velocity of the entity
|
||||
* @param {Number} x - x (Left) velocity
|
||||
* @param {Number} y - y (Top) velocity
|
||||
*/
|
||||
setVelocity (x, y) {
|
||||
|
||||
if (x instanceof Vector2D) {
|
||||
@ -136,11 +36,6 @@ class Entity {
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Set the acceleration of the entity
|
||||
* @param x {Number} x - x (Left) acceleration
|
||||
* @param y {Number} y - y (Top) acceleration
|
||||
*/
|
||||
setAcceleration (x, y) {
|
||||
|
||||
if (x instanceof Vector2D) {
|
||||
@ -153,11 +48,6 @@ class Entity {
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Creates a new child entity.
|
||||
* Note: This creates an instance of Entity, the base class. Under most circumstances you should use addChildEntity with an entity you have created.
|
||||
* @returns {Entity}
|
||||
*/
|
||||
createChildEntity () {
|
||||
|
||||
let child = new Entity();
|
||||
@ -171,11 +61,6 @@ class Entity {
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Add an entity as a child
|
||||
* @param {Entity} child - The child entity
|
||||
* @returns {Entity}
|
||||
*/
|
||||
addChildEntity (child) {
|
||||
|
||||
child._updateGame(this._game);
|
||||
@ -187,11 +72,6 @@ class Entity {
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Removes entity from children
|
||||
* @param {Entity} child - The child entity
|
||||
* @returns {boolean} Indicates successful removal
|
||||
*/
|
||||
detachChildEntity (child) {
|
||||
|
||||
for (let i = 0; i < this.children.length; i++) {
|
||||
@ -208,31 +88,33 @@ class Entity {
|
||||
}
|
||||
|
||||
|
||||
_calculateRelativePos () {
|
||||
_preprocess () {
|
||||
|
||||
// NK: The purpose of this function is to calculate the true position of the entity relative to all its parents. It does this recursively, calling the _calculateRelativePos method all the way back up the tree and continuously adding the results together.
|
||||
// NK: The purpose of this function is to calculate the true position of the entity relative to all its parents. It does this recursively, calling the _preprocess method all the way back up the tree and continuously adding the results together.
|
||||
|
||||
// Note there is a limiter, where the last calculated frame is stored, so that if the position has already been calculated for that node in this particular frame, the cached result is used rather than recalculating.
|
||||
|
||||
// When rendering, the draw calls should use this._relativePos rather than this.pos in order for the position to be correct.
|
||||
// When rendering, the draw calls should use this._calculatedPos rather than this.pos in order for the position to be correct.
|
||||
|
||||
if (this._game && this._lastRelativePosCalculated < this._game.frameCounter) {
|
||||
if (this._game && this._lastCalculated < this._game.frameCounter) {
|
||||
|
||||
if (this._parent) {
|
||||
|
||||
this._relativePos.x = this.pos.x + this._parent.relativeLeft;
|
||||
this._relativePos.y = this.pos.y + this._parent.relativeTop;
|
||||
let parentPos = this._parent._preprocess();
|
||||
|
||||
this._calculatedPos.x = this.pos.x + parentPos.x;
|
||||
this._calculatedPos.y = this.pos.y + parentPos.y;
|
||||
|
||||
} else {
|
||||
this._relativePos.x = this.pos.x;
|
||||
this._relativePos.y = this.pos.y;
|
||||
this._calculatedPos.x = this.pos.x;
|
||||
this._calculatedPos.y = this.pos.y;
|
||||
}
|
||||
|
||||
this._lastRelativePosCalculated = this._game.frameCounter;
|
||||
this._lastCalculated = this._game.frameCounter;
|
||||
|
||||
}
|
||||
|
||||
return this._relativePos;
|
||||
return this._calculatedPos;
|
||||
|
||||
}
|
||||
|
||||
@ -248,99 +130,22 @@ class Entity {
|
||||
}
|
||||
|
||||
|
||||
_scaleForLeft (val) {
|
||||
|
||||
let game = this._game;
|
||||
|
||||
if (!game.isFullScreen) {
|
||||
return val;
|
||||
} else {
|
||||
return (game._fullScreenXPos + (val * game._fullScreenXScaling));
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
_scaleForWidth (val) {
|
||||
|
||||
let game = this._game;
|
||||
|
||||
if (!game.isFullScreen) {
|
||||
return val;
|
||||
} else {
|
||||
return (val * game._fullScreenXScaling);
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
_scaleForTop (val) {
|
||||
|
||||
let game = this._game;
|
||||
|
||||
if (!game.isFullScreen) {
|
||||
return val;
|
||||
} else {
|
||||
return (game._fullScreenYPos + (val * game._fullScreenYScaling));
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
_scaleForHeight (val) {
|
||||
|
||||
let game = this._game;
|
||||
|
||||
if (!game.isFullScreen) {
|
||||
return val;
|
||||
} else {
|
||||
return (val * game._fullScreenYScaling);
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
_calculateFields (delta) {
|
||||
|
||||
let acceleration = new Vector2D(0, 0);
|
||||
|
||||
for (let i = 0; i < this.fields.length; i++) {
|
||||
|
||||
let field = this.fields[i];
|
||||
|
||||
// NK: These call _relativePos, I don't like using this outside of the render method...
|
||||
let vector = new Vector2D(
|
||||
field.relativeLeft - this.relativeLeft,
|
||||
field.relativeTop - this.relativeTop
|
||||
);
|
||||
|
||||
let force = field.mass / Math.pow(vector.dot(vector), 1.5);
|
||||
|
||||
acceleration.add(vector.multiply(force).multiply(delta));
|
||||
|
||||
}
|
||||
|
||||
return this.acceleration.clone().add(acceleration);
|
||||
|
||||
}
|
||||
|
||||
|
||||
_updateEntity (delta) {
|
||||
|
||||
if (this.timeToLive) {
|
||||
if (Date.now() - this._creationTime > this.timeToLive) {
|
||||
if (+(new Date()) - this._creationTime > this.timeToLive) {
|
||||
this._parent.detachChildEntity(this);
|
||||
}
|
||||
}
|
||||
|
||||
// Calculate new position based on velocity and acceleration if there's one set
|
||||
if (this.velocity && (this.velocity.x !== 0 || this.velocity.y !== 0)) {
|
||||
if (this.velocity) {
|
||||
|
||||
this.velocity.add(this._calculateFields(delta));
|
||||
this.pos.x += (this.velocity.x * delta);
|
||||
this.pos.y += (this.velocity.y * delta);
|
||||
if (this.acceleration) {
|
||||
this.velocity.add(this.acceleration);
|
||||
}
|
||||
|
||||
this.pos.add(this.velocity.clone().multiply(delta));
|
||||
|
||||
}
|
||||
|
||||
@ -360,11 +165,9 @@ class Entity {
|
||||
|
||||
_renderEntity () {
|
||||
|
||||
let rendered = this.display && this.render && this.render();
|
||||
this._preprocess();
|
||||
|
||||
if (rendered) {
|
||||
this._game._lastFrameTotalRenders++;
|
||||
}
|
||||
let rendered = this.render && this.render();
|
||||
|
||||
if (rendered || (typeof rendered == "undefined") || (typeof this.render === "undefined")) {
|
||||
|
||||
|
@ -1,21 +0,0 @@
|
||||
"use strict";
|
||||
|
||||
import Entity from "./entity.js";
|
||||
import Vector2D from "./vector2d.js";
|
||||
|
||||
|
||||
class Field extends Entity {
|
||||
|
||||
|
||||
constructor (x, y, mass) {
|
||||
|
||||
super(x, y);
|
||||
this.mass = mass;
|
||||
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
||||
export default Field;
|
@ -1,22 +0,0 @@
|
||||
"use strict";
|
||||
|
||||
import Color from "./color.js";
|
||||
|
||||
|
||||
class Font {
|
||||
|
||||
|
||||
constructor(family, size, fill = null, stroke = null) {
|
||||
|
||||
this.family = family;
|
||||
this.size = `${size}px`;
|
||||
this.fill = fill;
|
||||
this.stroke = stroke;
|
||||
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
||||
export default Font;
|
@ -1,10 +1,7 @@
|
||||
"use strict";
|
||||
|
||||
import Entity from "./entity.js";
|
||||
import Vector2D from "./vector2d.js";
|
||||
|
||||
import KeyboardInput from "./keyboardinput.js";
|
||||
import GamepadInput from "./gamepadinput.js";
|
||||
|
||||
class Game extends Entity {
|
||||
|
||||
@ -13,7 +10,6 @@ class Game extends Entity {
|
||||
|
||||
super(); // Call entity constructor
|
||||
config = config || {};
|
||||
config.fullscreen = config.fullscreen || {};
|
||||
config.inputs = config.inputs || {};
|
||||
|
||||
|
||||
@ -36,13 +32,9 @@ class Game extends Entity {
|
||||
throw new Error("MomentumEngine.Classes.Game must be constructed with canvas height");
|
||||
}
|
||||
|
||||
this.scale = 1;
|
||||
|
||||
// Optional params
|
||||
this.desiredFps = config.desiredFps || 60;
|
||||
this.fixFrameRate = !!config.fixFrameRate;
|
||||
|
||||
this.fullScreenNativeResolution = !!config.fullscreen.nativeResolution;
|
||||
|
||||
if (config.fixRatio) {
|
||||
|
||||
@ -65,45 +57,19 @@ class Game extends Entity {
|
||||
}
|
||||
|
||||
this.scale = deviceRatio / backingStoreRatio;
|
||||
this._deviceRatio = deviceRatio;
|
||||
|
||||
this.canvas.width = this.width * this.scale;
|
||||
this.canvas.height = this.height * this.scale;
|
||||
|
||||
this.canvas.style.width = `${this.width}px`;
|
||||
this.canvas.style.height = `${this.height}px`;
|
||||
|
||||
|
||||
// Calculate fullscreen settings
|
||||
|
||||
if (config.fullscreen.nativeResolution) {
|
||||
this._fullScreenXScaling = screen.width / this.width;
|
||||
this._fullScreenYScaling = screen.height / this.height;
|
||||
} else {
|
||||
this._fullScreenXScaling = 1;
|
||||
this._fullScreenYScaling = 1;
|
||||
}
|
||||
|
||||
this._fullScreenXPos = 0;
|
||||
this._fullScreenYPos = 0;
|
||||
|
||||
if (config.fullscreen.maintainAspectRatio) {
|
||||
if (this._fullScreenXScaling > this._fullScreenYScaling) {
|
||||
this._fullScreenXScaling = this._fullScreenYScaling;
|
||||
this._fullScreenXPos = (screen.width - (this.width * this._fullScreenXScaling)) / 2;
|
||||
} else {
|
||||
this._fullScreenYScaling = this._fullScreenXScaling;
|
||||
this._fullScreenYPos = (screen.height - (this.height * this._fullScreenYScaling)) / 2;
|
||||
}
|
||||
}
|
||||
|
||||
this.canvas.style.width = this.width + "px";
|
||||
this.canvas.style.height = this.height + "px";
|
||||
|
||||
// Call getContext last for Ejecta only.
|
||||
if (typeof ejecta !== "undefined") {
|
||||
this.context = this.canvas.getContext("2d");
|
||||
}
|
||||
|
||||
this.context.scale(this._deviceRatio, this._deviceRatio);
|
||||
this.context.scale(deviceRatio, deviceRatio);
|
||||
|
||||
} else {
|
||||
|
||||
@ -122,43 +88,14 @@ class Game extends Entity {
|
||||
// Initialize defaults
|
||||
this.frameCounter = 0;
|
||||
|
||||
|
||||
// Initialize input methods
|
||||
this.inputs = {};
|
||||
|
||||
if (config.inputs.keyboard) {
|
||||
this.inputs.keyboard = new KeyboardInput(this);
|
||||
}
|
||||
|
||||
if (config.inputs.gamepad) {
|
||||
this.inputs.gamepad = new GamepadInput(this);
|
||||
}
|
||||
|
||||
this._game = this;
|
||||
this._lastFrameTimestamp = 0;
|
||||
this._lastFrameTotalRenders = 0;
|
||||
this._wantPause = true;
|
||||
this._fullScreenLastFrame = false;
|
||||
|
||||
}
|
||||
|
||||
|
||||
setCamera (x, y) {
|
||||
|
||||
if (x instanceof Vector2D) {
|
||||
|
||||
let pos = x.clone();
|
||||
pos.x = -pos.x;
|
||||
pos.y = -pos.y;
|
||||
|
||||
this.pos = pos;
|
||||
|
||||
} else {
|
||||
|
||||
this.pos.x = -x;
|
||||
this.pos.y = -y;
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@ -167,61 +104,8 @@ class Game extends Entity {
|
||||
|
||||
this.frameCounter++;
|
||||
|
||||
this._preStep();
|
||||
this._updateEntity(delta);
|
||||
this._renderEntity();
|
||||
this._updateInputs(); // NK: This happens at the end for reasons
|
||||
|
||||
}
|
||||
|
||||
|
||||
_updateInputs () {
|
||||
|
||||
for (let input in this.inputs) {
|
||||
if (this.inputs[input].update) {
|
||||
this.inputs[input].update();
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
_preStep () {
|
||||
|
||||
if (this.isFullScreen) {
|
||||
|
||||
if (this._fullScreenLastFrame == false) {
|
||||
|
||||
this.canvas.style.width = `${screen.width}px`;
|
||||
this.canvas.style.height = `${screen.height}px`;
|
||||
|
||||
if (this.fullScreenNativeResolution) {
|
||||
this.canvas.width = screen.width * this.scale;
|
||||
this.canvas.height = screen.height * this.scale;
|
||||
this.context.scale(this._deviceRatio, this._deviceRatio);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
this._fullScreenLastFrame = true;
|
||||
|
||||
} else {
|
||||
|
||||
if (this._fullScreenLastFrame == true) {
|
||||
|
||||
this.canvas.style.width = `${this.width}px`;
|
||||
this.canvas.style.height = `${this.height}px`;
|
||||
|
||||
this.canvas.width = this.width * this.scale;
|
||||
this.canvas.height = this.height * this.scale;
|
||||
|
||||
this.context.scale(this._deviceRatio, this._deviceRatio);
|
||||
|
||||
}
|
||||
|
||||
this._fullScreenLastFrame = false;
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@ -262,13 +146,8 @@ class Game extends Entity {
|
||||
let currentTimestamp = +(new Date()),
|
||||
delta = currentTimestamp - self._lastFrameTimestamp;
|
||||
|
||||
if (self.fixFrameRate) {
|
||||
delta = 1000 / self.desiredFps;
|
||||
}
|
||||
|
||||
//delta = Math.min(delta, 1000 / self.desiredFps);
|
||||
delta = Math.min(delta, 1000 / self.desiredFps);
|
||||
self._lastFrameTimestamp = currentTimestamp;
|
||||
self._lastFrameTotalRenders = 0;
|
||||
|
||||
self.step(delta);
|
||||
|
||||
@ -294,34 +173,6 @@ class Game extends Entity {
|
||||
}
|
||||
|
||||
|
||||
toggleFullScreen () {
|
||||
|
||||
if (!document.mozFullScreen && !document.webkitFullScreen) {
|
||||
|
||||
if (this.canvas.mozRequestFullScreen) {
|
||||
this.canvas.mozRequestFullScreen();
|
||||
} else {
|
||||
this.canvas.webkitRequestFullScreen(Element.ALLOW_KEYBOARD_INPUT);
|
||||
}
|
||||
|
||||
} else {
|
||||
|
||||
if (document.mozCancelFullScreen) {
|
||||
document.mozCancelFullScreen();
|
||||
} else {
|
||||
document.webkitCancelFullScreen();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
get isFullScreen () {
|
||||
return document.fullScreen || document.mozFullScreen || document.webkitIsFullScreen;
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
@ -1,155 +0,0 @@
|
||||
"use strict";
|
||||
|
||||
|
||||
class Gamepad {
|
||||
|
||||
constructor (gamepadObj) {
|
||||
this._gamepadObj = gamepadObj;
|
||||
}
|
||||
|
||||
get numButtons () {
|
||||
return this._gamepadObj.buttons.length;
|
||||
}
|
||||
|
||||
get numAxis () {
|
||||
return this._gamepadObj.axes.length;
|
||||
}
|
||||
|
||||
isPressed (buttonId) {
|
||||
|
||||
if (this._gamepadObj.buttons[buttonId]) {
|
||||
return !!this._gamepadObj.buttons[buttonId].pressed;
|
||||
} else {
|
||||
throw new Error(`Button ${buttonId} not found on gamepad`);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
getAxis (axisId) {
|
||||
|
||||
if (typeof this._gamepadObj.axes[axisId] !== "undefined") {
|
||||
return this._gamepadObj.axes[axisId];
|
||||
} else {
|
||||
throw new Error(`Axis ${axisId} not found on gamepad`);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
class GamepadInput {
|
||||
|
||||
|
||||
constructor () {
|
||||
|
||||
var self = this;
|
||||
|
||||
self._gamepadState = {};
|
||||
self.gamepadIds = [];
|
||||
|
||||
if ('ongamepadconnected' in window) {
|
||||
|
||||
window.addEventListener("gamepadconnected", (event) => {
|
||||
self._gamepadState[event.gamepad.index] = new Gamepad(event.gamepad);
|
||||
self.gamepadIds.push(event.gamepad.index);
|
||||
console.log(`Gamepad ${event.gamepad.index} connected`);
|
||||
});
|
||||
|
||||
window.addEventListener("gamepaddisconnected", (event) => {
|
||||
delete self._gamepadState[event.gamepad.index];
|
||||
self.gamepadIds.splice(self.gamepadIds.indexOf(event.gamepad.index));
|
||||
console.log(`Gamepad ${event.gamepad.index} disconnected`);
|
||||
});
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
update () {
|
||||
|
||||
if (!("ongamepadconnected" in window)) {
|
||||
|
||||
let gamepads = navigator.getGamepads ? navigator.getGamepads() : (navigator.webkitGetGamepads ? navigator.webkitGetGamepads : []);
|
||||
|
||||
// If there are more gamepads registered than we know about, make ourselves aware of the new ones
|
||||
if (gamepads.length != this.gamepadIds.length) {
|
||||
|
||||
for (let i = 0; i < gamepads.length; i++) {
|
||||
|
||||
let gamepad = gamepads[i];
|
||||
|
||||
if (gamepad) {
|
||||
|
||||
if (this.gamepadIds.indexOf(gamepad.index) < 0) {
|
||||
this._gamepadState[gamepad.index] = new Gamepad(gamepad);
|
||||
this.gamepadIds.push(gamepad.index);
|
||||
|
||||
console.log(`Gamepad ${gamepad.index} connected`);
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
// If there is still a mismatch, then we assume some gamepads have been disconnected, so we need to remove them
|
||||
if (gamepads.length != this.gamepadIds.length) {
|
||||
|
||||
for (let i = 0; i < this.gamepadIds.length; i++) {
|
||||
|
||||
let found = false;
|
||||
|
||||
for (let j = 0; j < gamepads.length; j++) {
|
||||
|
||||
let gamepad = gamepads[i];
|
||||
|
||||
if (gamepad && gamepad.index == this.gamepadIds[i]) {
|
||||
found = true;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
if (!found) {
|
||||
|
||||
console.log(`Gamepad ${this.gamepadIds[i]} disconnected`);
|
||||
|
||||
delete this._gamepadState[this.gamepadIds[i]];
|
||||
this.gamepadIds.splice(this.gamepadIds.indexOf(this.gamepadIds[i]));
|
||||
|
||||
i--;
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
get numGamepads () {
|
||||
return this.gamepadIds.length;
|
||||
}
|
||||
|
||||
|
||||
getGamepadById (gamepadId) {
|
||||
|
||||
if (this._gamepadState[gamepadId]) {
|
||||
return this._gamepadState[gamepadId];
|
||||
} else {
|
||||
throw new Error(`Gamepad ${buttonId} is not connected`);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
||||
export default GamepadInput;
|
@ -15,7 +15,7 @@ class ImageLoader {
|
||||
this._error = false;
|
||||
});
|
||||
|
||||
this._imageObj.addEventListener("error", (err) => {
|
||||
this._imageObj.addEventListener("_error", (err) => {
|
||||
this._loaded = false;
|
||||
this._error = err;
|
||||
});
|
||||
|
@ -99,10 +99,6 @@ const KeyConsts = {
|
||||
};
|
||||
|
||||
|
||||
let wasReleased = {},
|
||||
wasPressed = {};
|
||||
|
||||
|
||||
class KeyboardInput {
|
||||
|
||||
|
||||
@ -123,52 +119,16 @@ class KeyboardInput {
|
||||
|
||||
|
||||
isPressed (keyCode) {
|
||||
console.log("[MomentumEngine] WARNING: MomentumEngine.Classes.KeyboardInput.isPressed is deprecated. Use isDown instead.")
|
||||
return !!this._keyState[keyCode];
|
||||
}
|
||||
|
||||
|
||||
isDown (keyCode) {
|
||||
|
||||
return !!this._keyState[keyCode];
|
||||
}
|
||||
|
||||
|
||||
wasPressed (keyCode) {
|
||||
|
||||
let pressed = !!wasPressed[keyCode];
|
||||
|
||||
if (pressed) {
|
||||
wasPressed[keyCode] = false;
|
||||
}
|
||||
|
||||
return pressed;
|
||||
|
||||
}
|
||||
|
||||
|
||||
wasReleased (keyCode) {
|
||||
|
||||
let pressed = !!wasReleased[keyCode];
|
||||
|
||||
if (pressed) {
|
||||
wasReleased[keyCode] = false;
|
||||
}
|
||||
|
||||
return pressed;
|
||||
}
|
||||
|
||||
|
||||
_keyDownHandler (event) {
|
||||
wasReleased[event.keyCode] = false;
|
||||
wasPressed[event.keyCode] = true;
|
||||
this._keyState[event.keyCode] = true;
|
||||
}
|
||||
|
||||
|
||||
_keyUpHandler (event) {
|
||||
wasReleased[event.keyCode] = true;
|
||||
wasPressed[event.keyCode] = false;
|
||||
this._keyState[event.keyCode] = false;
|
||||
}
|
||||
|
||||
|
@ -1,57 +0,0 @@
|
||||
"use strict";
|
||||
|
||||
import Entity from "./entity.js";
|
||||
import Vector2D from "./vector2d.js";
|
||||
|
||||
import CollisionMethods from "../libs/collisionmethods.js";
|
||||
|
||||
|
||||
class Path extends Entity {
|
||||
|
||||
|
||||
constructor (x, y, width, height, color) {
|
||||
|
||||
super(x, y);
|
||||
|
||||
if (width instanceof Array) {
|
||||
color = height;
|
||||
this.coords = width;
|
||||
} else {
|
||||
this.coords = [new Vector2D(width, height)];
|
||||
}
|
||||
|
||||
this.color = color;
|
||||
|
||||
}
|
||||
|
||||
|
||||
render () {
|
||||
|
||||
if (this._game) {
|
||||
|
||||
let ctx = this._game.context;
|
||||
ctx.strokeStyle = this.color.toString();
|
||||
|
||||
ctx.beginPath();
|
||||
ctx.moveTo(this._scaleForLeft(this.relativeLeft), this._scaleForTop(this.relativeTop));
|
||||
|
||||
for (let coord in this.coords) {
|
||||
ctx.lineTo(this._scaleForWidth(this.relativeLeft + this.coords[coord].x), this._scaleForHeight(this.relativeTop + this.coords[coord].y));
|
||||
}
|
||||
|
||||
//ctx.closePath();
|
||||
ctx.stroke();
|
||||
|
||||
return true;
|
||||
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
||||
export default Path;
|
@ -1,41 +1,24 @@
|
||||
"use strict";
|
||||
|
||||
import Entity from "./entity.js";
|
||||
import Vector2D from "./vector2d.js";
|
||||
|
||||
import CollisionMethods from "../libs/collisionmethods.js";
|
||||
|
||||
|
||||
/**
|
||||
* Class representing a rectangle in a scene
|
||||
* @extends Entity
|
||||
*/
|
||||
class Rect extends Entity {
|
||||
|
||||
|
||||
/**
|
||||
* Create a rectangle
|
||||
* @param {number} x - x (Left) position of the rectangle
|
||||
* @param {number} y - y (Top) position of the rectangle
|
||||
* @param {number} width - Width of the rectangle
|
||||
* @param {number} height - Height of the rectangle
|
||||
* @param {Color} color - Color of the rectangle
|
||||
*/
|
||||
constructor (x, y, width, height, color) {
|
||||
|
||||
super(x, y);
|
||||
|
||||
this.size.x = width || 0;
|
||||
this.size.y = height || 0;
|
||||
this.size = new Vector2D(width, height);
|
||||
this.color = color;
|
||||
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Detects if the rectangle is colliding with another entity
|
||||
* @param {Entity} entity - Entity to check against
|
||||
* @returns {boolean} Indicates whether the entities are colliding
|
||||
*/
|
||||
isCollidingWith (entity) {
|
||||
|
||||
if (entity instanceof Rect) {
|
||||
@ -49,31 +32,8 @@ class Rect extends Entity {
|
||||
|
||||
if (this._game) {
|
||||
|
||||
let left = this._scaleForLeft(this.relativeLeft),
|
||||
top = this._scaleForTop(this.relativeTop),
|
||||
width = this._scaleForWidth(this.width),
|
||||
height = this._scaleForHeight(this.height),
|
||||
ctx = this._game.context;
|
||||
|
||||
let xRot = left + (width / 2),
|
||||
yRot = top + (height / 2);
|
||||
|
||||
if (this.rotation > 0) {
|
||||
// Rotate the canvas based on the central point of this entity
|
||||
ctx.translate(xRot, yRot);
|
||||
ctx.rotate(this.rotation * Math.PI / 180);
|
||||
ctx.translate(-xRot, -yRot);
|
||||
}
|
||||
|
||||
ctx.fillStyle = this.color.toString();
|
||||
ctx.fillRect(left, top, width, height);
|
||||
|
||||
if (this.rotation > 0) {
|
||||
// Rotate back after drawing
|
||||
ctx.translate(xRot, yRot);
|
||||
ctx.rotate(-(this.rotation * Math.PI / 180));
|
||||
ctx.translate(-xRot, -yRot);
|
||||
}
|
||||
this._game.context.fillStyle = this.color.toString();
|
||||
this._game.context.fillRect(this._calculatedPos.x, this._calculatedPos.y, this.size.x, this.size.y);
|
||||
|
||||
return true;
|
||||
|
||||
|
@ -18,8 +18,7 @@ class Sprite extends Entity {
|
||||
|
||||
super(x, y);
|
||||
|
||||
this.size.x = width || 0;
|
||||
this.size.y = height || 0;
|
||||
this.size = new Vector2D(width || 0, height || 0);
|
||||
|
||||
this._image = image;
|
||||
this._imagePos = new Vector2D(0, 0);
|
||||
@ -58,10 +57,10 @@ class Sprite extends Entity {
|
||||
this._imagePos.y,
|
||||
this._imageSize.x || subWidth,
|
||||
this._imageSize.y || subHeight,
|
||||
this._scaleForLeft(this.relativeLeft),
|
||||
this._scaleForTop(this.relativeTop),
|
||||
this._scaleForWidth(this.width || subWidth),
|
||||
this._scaleForHeight(this.height || subHeight)
|
||||
this._calculatedPos.x,
|
||||
this._calculatedPos.y,
|
||||
this.size.x || subWidth,
|
||||
this.size.y || subHeight
|
||||
);
|
||||
|
||||
return true;
|
||||
|
@ -1,113 +0,0 @@
|
||||
"use strict";
|
||||
|
||||
import Entity from "./entity.js";
|
||||
import Vector2D from "./vector2d.js";
|
||||
|
||||
|
||||
class Text extends Entity {
|
||||
|
||||
|
||||
constructor (x, y, font, text) {
|
||||
|
||||
super(x, y);
|
||||
|
||||
this.font = font;
|
||||
this.text = text;
|
||||
|
||||
this.textAlign = "start";
|
||||
this.textBaseline = "alphabetic";
|
||||
this.direction = "inherit";
|
||||
this.letterSpacing = 0;
|
||||
|
||||
}
|
||||
|
||||
|
||||
isCollidingWith (entity) {
|
||||
|
||||
if (entity instanceof Rect) {
|
||||
return CollisionMethods.AABB(this, entity);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
_renderText (text, x, y, letterSpacing, renderFunc) {
|
||||
|
||||
// Code modified from original by David Hong (sozonov): https://jsfiddle.net/sozonov/mg1jkz3q/
|
||||
|
||||
if (!text || typeof text !== "string" || text.length === 0) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (letterSpacing == 0) {
|
||||
renderFunc(text, x, y);
|
||||
return;
|
||||
}
|
||||
|
||||
let characters = text.split(""),
|
||||
index = 0,
|
||||
current,
|
||||
currentPosition = x,
|
||||
align = 1;
|
||||
|
||||
if (this.textAlign === "right") {
|
||||
characters = characters.reverse();
|
||||
align = -1;
|
||||
} else if (this.textAlign === "center") {
|
||||
|
||||
let totalWidth = 0;
|
||||
|
||||
for (let i = 0; i < characters.length; i++) {
|
||||
// NK: We want to cache the results of measureText instead of recalculating every character every frame
|
||||
totalWidth += (this._game.context.measureText(characters[i]).width + letterSpacing);
|
||||
}
|
||||
|
||||
currentPosition = x - (totalWidth / 2);
|
||||
|
||||
}
|
||||
|
||||
while (index < text.length) {
|
||||
|
||||
current = characters[index++];
|
||||
renderFunc(current, currentPosition, y);
|
||||
// NK: We want to cache the results of measureText instead of recalculating every character every frame
|
||||
currentPosition += (align * (this._game.context.measureText(current).width + letterSpacing));
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
render () {
|
||||
|
||||
if (this._game) {
|
||||
|
||||
this._game.context.font = `${this.font.size} ${this.font.family}`;
|
||||
|
||||
this._game.context.textAlign = this.textAlign;
|
||||
this._game.context.textBaseline = this.textBaseline;
|
||||
this._game.context.direction = this.direction;
|
||||
|
||||
if (this.font.fill) {
|
||||
this._game.context.fillStyle = this.font.fill;
|
||||
this._renderText(this.text, this._scaleForLeft(this.relativeLeft), this._scaleForTop(this.relativeTop), this.letterSpacing, this._game.context.fillText.bind(this._game.context));
|
||||
}
|
||||
|
||||
if (this.font.stroke) {
|
||||
this._game.context.strokeStyle = this.font.stroke;
|
||||
this._renderText(this.text, this._scaleForLeft(this.relativeLeft), this._scaleForTop(this.relativeTop), this.letterSpacing, this._game.context.strokeText.bind(this._game.context));
|
||||
}
|
||||
|
||||
return true;
|
||||
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
||||
export default Text;
|
@ -112,7 +112,7 @@ class Vector2D {
|
||||
|
||||
|
||||
toString () {
|
||||
return `[${this.x},${this.y}]`;
|
||||
return `[${this.x}},${this.y}}]`;
|
||||
}
|
||||
|
||||
|
||||
|
26
src/es5.js
26
src/es5.js
@ -2,35 +2,25 @@
|
||||
|
||||
import Game from "./classes/game.js";
|
||||
import Emitter from "./classes/emitter.js";
|
||||
import Field from "./classes/field.js";
|
||||
import Entity from "./classes/entity.js";
|
||||
import Vector2D from "./classes/vector2d.js";
|
||||
import Sprite from "./classes/sprite.js";
|
||||
import Rect from "./classes/rect.js";
|
||||
import Path from "./classes/path.js";
|
||||
import Color from "./classes/color.js";
|
||||
import Text from "./classes/text.js";
|
||||
import Font from "./classes/font.js";
|
||||
import AudioTrack from "./classes/audio.js";
|
||||
import ImageLoader from "./classes/imageloader.js";
|
||||
|
||||
import {KeyConsts} from "./classes/keyboardinput.js";
|
||||
|
||||
|
||||
const Classes = {
|
||||
Game,
|
||||
Emitter,
|
||||
Field,
|
||||
Entity,
|
||||
Sprite,
|
||||
Rect,
|
||||
Path,
|
||||
Vector2D,
|
||||
Color,
|
||||
Text,
|
||||
Font,
|
||||
AudioTrack,
|
||||
ImageLoader
|
||||
Game: Game,
|
||||
Emitter: Emitter,
|
||||
Entity: Entity,
|
||||
Sprite: Sprite,
|
||||
Rect: Rect,
|
||||
Vector2D: Vector2D,
|
||||
Color: Color,
|
||||
ImageLoader: ImageLoader
|
||||
};
|
||||
|
||||
|
||||
|
26
src/es6.js
26
src/es6.js
@ -2,35 +2,25 @@
|
||||
|
||||
import Game from "./classes/game.js";
|
||||
import Emitter from "./classes/emitter.js";
|
||||
import Field from "./classes/field.js";
|
||||
import Entity from "./classes/entity.js";
|
||||
import Vector2D from "./classes/vector2d.js";
|
||||
import Sprite from "./classes/sprite.js";
|
||||
import Rect from "./classes/rect.js";
|
||||
import Path from "./classes/path.js";
|
||||
import Color from "./classes/color.js";
|
||||
import Text from "./classes/text.js";
|
||||
import Font from "./classes/font.js";
|
||||
import AudioTrack from "./classes/audio.js";
|
||||
import ImageLoader from "./classes/imageloader.js";
|
||||
|
||||
import {KeyConsts} from "./classes/keyboardinput.js";
|
||||
|
||||
|
||||
const Classes = {
|
||||
Game,
|
||||
Emitter,
|
||||
Field,
|
||||
Entity,
|
||||
Sprite,
|
||||
Rect,
|
||||
Path,
|
||||
Vector2D,
|
||||
Color,
|
||||
Text,
|
||||
Font,
|
||||
AudioTrack,
|
||||
ImageLoader
|
||||
Game: Game,
|
||||
Emitter: Emitter,
|
||||
Entity: Entity,
|
||||
Sprite: Sprite,
|
||||
Rect: Rect,
|
||||
Vector2D: Vector2D,
|
||||
Color: Color,
|
||||
ImageLoader: ImageLoader
|
||||
};
|
||||
|
||||
|
||||
|
@ -9,12 +9,10 @@ class CollisionMethods {
|
||||
throw new Error("AABB collisions can only be checked on these entity types: Rect");
|
||||
}
|
||||
|
||||
let colliding = (entity1.left < entity2.left + entity2.width &&
|
||||
entity1.left + entity1.width > entity2.left &&
|
||||
entity1.top < entity2.top + entity2.height &&
|
||||
entity1.height + entity1.top > entity2.top);
|
||||
|
||||
return colliding;
|
||||
return (entity1.pos.x < entity2.pos.x + entity2.size.x &&
|
||||
entity1.pos.x + entity1.size.x > entity2.pos.x &&
|
||||
entity1.pos.y < entity2.pos.y + entity2.size.y &&
|
||||
entity1.size.y + entity1.pos.y > entity2.pos.y);
|
||||
|
||||
}
|
||||
|
||||
|
@ -1,20 +0,0 @@
|
||||
class Utils {
|
||||
|
||||
|
||||
static mergeIntoArray (dest, source) {
|
||||
|
||||
source.forEach((item) => {
|
||||
if (dest.indexOf(item) < 0) {
|
||||
dest.push(item);
|
||||
}
|
||||
});
|
||||
|
||||
return dest;
|
||||
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
||||
export default Utils;
|
Loading…
x
Reference in New Issue
Block a user