Added image classes, new example (snowflakes)
This commit is contained in:
parent
9d0f3db412
commit
5a76bc6773
@ -6,6 +6,6 @@
|
||||
<script type="application/javascript" src="./pong.js"></script>
|
||||
</head>
|
||||
<body>
|
||||
<canvas id="game"></canvas>
|
||||
<canvas id="canvas"></canvas>
|
||||
</body>
|
||||
</html>
|
@ -12,7 +12,7 @@ window.onload = function () {
|
||||
|
||||
|
||||
var pong = new MomentumEngine.Classes.Game({
|
||||
canvas: document.getElementById("game"),
|
||||
canvas: document.getElementById("canvas"),
|
||||
width: width,
|
||||
height: height,
|
||||
fixRatio: true,
|
||||
@ -28,7 +28,7 @@ window.onload = function () {
|
||||
black = new MomentumEngine.Classes.Color(0, 0, 0);
|
||||
|
||||
|
||||
// All of these are instances of MomentumEngine.Entity;
|
||||
// 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),
|
||||
@ -81,7 +81,6 @@ window.onload = function () {
|
||||
|
||||
if (leftPaddle.isCollidingWith(ball) && ball.state.speed.x < 0) {
|
||||
ball.state.speed.x = -ball.state.speed.x;
|
||||
console.log(ball.state.speed.length());
|
||||
}
|
||||
|
||||
};
|
||||
@ -111,8 +110,6 @@ window.onload = function () {
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
|
||||
pong.start();
|
||||
|
||||
|
||||
|
11
examples/snowflakes/index.html
Normal file
11
examples/snowflakes/index.html
Normal file
@ -0,0 +1,11 @@
|
||||
<!doctype html>
|
||||
<html>
|
||||
<head>
|
||||
<title>Snowflakes - MomentumEngine</title>
|
||||
<script type="application/javascript" src="../../dist/es5.js"></script>
|
||||
<script type="application/javascript" src="./snowflakes.js"></script>
|
||||
</head>
|
||||
<body>
|
||||
<canvas id="canvas"></canvas>
|
||||
</body>
|
||||
</html>
|
116
examples/snowflakes/pong.js
Normal file
116
examples/snowflakes/pong.js
Normal file
@ -0,0 +1,116 @@
|
||||
"use strict";
|
||||
|
||||
window.onload = function () {
|
||||
|
||||
|
||||
var KeyConsts = MomentumEngine.Consts.Input.Keys;
|
||||
|
||||
|
||||
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
|
||||
}
|
||||
});
|
||||
|
||||
|
||||
// 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.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);
|
||||
|
||||
|
||||
// Create scene graph
|
||||
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 () {
|
||||
|
||||
this.pos.add(this.state.speed.clone().multiply(pong.lastFrameDelta));
|
||||
|
||||
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 () {
|
||||
|
||||
if (pong.inputs.keyboard.isPressed(KeyConsts.CHAR_Q) || pong.inputs.keyboard.isPressed(KeyConsts.UP)) {
|
||||
leftPaddle.pos.y -= (0.5 * pong.lastFrameDelta);
|
||||
}
|
||||
|
||||
if (pong.inputs.keyboard.isPressed(KeyConsts.CHAR_A) || pong.inputs.keyboard.isPressed(KeyConsts.DOWN)) {
|
||||
leftPaddle.pos.y += (0.5 * pong.lastFrameDelta);
|
||||
}
|
||||
|
||||
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 () {
|
||||
|
||||
if (pong.inputs.keyboard.isPressed(KeyConsts.CHAR_O)) {
|
||||
rightPaddle.pos.y -= (0.5 * pong.lastFrameDelta);
|
||||
}
|
||||
|
||||
if (pong.inputs.keyboard.isPressed(KeyConsts.CHAR_L)) {
|
||||
rightPaddle.pos.y += (0.5 * pong.lastFrameDelta);
|
||||
}
|
||||
|
||||
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.start();
|
||||
|
||||
|
||||
};
|
BIN
examples/snowflakes/snowflake.png
Normal file
BIN
examples/snowflakes/snowflake.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 194 KiB |
67
examples/snowflakes/snowflakes.js
Normal file
67
examples/snowflakes/snowflakes.js
Normal file
@ -0,0 +1,67 @@
|
||||
"use strict";
|
||||
|
||||
window.onload = function () {
|
||||
|
||||
|
||||
var KeyConsts = MomentumEngine.Consts.Input.Keys;
|
||||
|
||||
|
||||
var width = 640,
|
||||
height = 360;
|
||||
|
||||
|
||||
var snowflakes = new MomentumEngine.Classes.Game({
|
||||
canvas: document.getElementById("canvas"),
|
||||
width: width,
|
||||
height: height,
|
||||
fixRatio: true,
|
||||
desiredFps: 60
|
||||
});
|
||||
|
||||
|
||||
// Colors
|
||||
var blue = new MomentumEngine.Classes.Color(204, 255, 255);
|
||||
|
||||
|
||||
// All of these are instances of MomentumEngine.Classes.Entity
|
||||
var mainScene = new MomentumEngine.Classes.Rect(0, 0, width, height, blue);
|
||||
|
||||
|
||||
// Load images
|
||||
var snowflakeImg = new MomentumEngine.Classes.ImageLoader("./snowflake.png");
|
||||
|
||||
|
||||
// Create scene graph
|
||||
snowflakes.addChildEntity(mainScene);
|
||||
|
||||
mainScene.update = function () {
|
||||
|
||||
if ((snowflakes.frameCounter % 120) == 0) { // Every two seconds or so, add a new snowflake
|
||||
|
||||
var startPos = (Math.random() * width) - 50;
|
||||
|
||||
var newSnowflake = new MomentumEngine.Classes.Sprite(startPos, -100, 100, 100, snowflakeImg);
|
||||
|
||||
newSnowflake.update = function () {
|
||||
this.pos.y = this.pos.y + (snowflakes.lastFrameDelta * 0.06);
|
||||
};
|
||||
|
||||
mainScene.addChildEntity(newSnowflake);
|
||||
|
||||
mainScene.children.forEach((oldSnowflake) => {
|
||||
|
||||
if (oldSnowflake.pos.y > height) {
|
||||
mainScene.detachChildEntity(oldSnowflake);
|
||||
}
|
||||
|
||||
});
|
||||
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
|
||||
snowflakes.start();
|
||||
|
||||
|
||||
};
|
@ -1,3 +1,5 @@
|
||||
"use strict";
|
||||
|
||||
class Color {
|
||||
|
||||
|
||||
|
@ -9,6 +9,7 @@ class Entity {
|
||||
|
||||
this.pos = new Vector2D(x || 0, y || 0);
|
||||
|
||||
this._ready = true;
|
||||
this.state = {};
|
||||
this.children = [];
|
||||
|
||||
@ -44,22 +45,40 @@ class Entity {
|
||||
}
|
||||
|
||||
|
||||
detachChildEntity (entity) {
|
||||
// Not implemented
|
||||
detachChildEntity (child) {
|
||||
|
||||
for (var i = 0; i < this.children.length; i++) {
|
||||
if (this.children[i] == child) {
|
||||
|
||||
this.children.splice(i, 1);
|
||||
return true;
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
|
||||
}
|
||||
|
||||
|
||||
_recalculatePos () {
|
||||
isReady () {
|
||||
return this._ready;
|
||||
}
|
||||
|
||||
// NK: This should be called within "render", not "update". 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 _recalculatePos method all the way back up the tree and continuously adding the results together.
|
||||
|
||||
_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 _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._calculatedPos rather than this.pos in order for the position to be correct.
|
||||
|
||||
if (this._game && this._lastCalculated < this._game.frameCounter) {
|
||||
|
||||
if (this._parent) {
|
||||
|
||||
let parentPos = this._parent._recalculatePos();
|
||||
let parentPos = this._parent._preprocess();
|
||||
|
||||
this._calculatedPos.x = this.pos.x + parentPos.x;
|
||||
this._calculatedPos.y = this.pos.y + parentPos.y;
|
||||
@ -91,9 +110,9 @@ class Entity {
|
||||
|
||||
_updateEntity () {
|
||||
|
||||
this._recalculatePos();
|
||||
var updated = this.update && this.update();
|
||||
|
||||
if ((this.update && this.update()) || (typeof this.update === "undefined")) {
|
||||
if (this.isReady() && (updated || (typeof updated == "undefined") || (typeof this.update === "undefined"))) {
|
||||
|
||||
this.children.forEach((child) => {
|
||||
child._updateEntity();
|
||||
@ -106,7 +125,11 @@ class Entity {
|
||||
|
||||
_renderEntity () {
|
||||
|
||||
if ((this.render && this.render()) || (typeof this.render === "undefined")) {
|
||||
this._preprocess();
|
||||
|
||||
var rendered = this.render && this.render();
|
||||
|
||||
if (this.isReady() && (rendered || (typeof rendered == "undefined") || (typeof this.render === "undefined"))) {
|
||||
|
||||
this.children.forEach((child) => {
|
||||
child._renderEntity();
|
||||
|
@ -17,19 +17,19 @@ class Game extends Entity {
|
||||
if (config.canvas) {
|
||||
this.canvas = config.canvas;
|
||||
} else {
|
||||
throw new Error("MomentumEngine.Game must be constructed with a canvas");
|
||||
throw new Error("MomentumEngine.Classes.Game must be constructed with a canvas");
|
||||
}
|
||||
|
||||
if (config.width) {
|
||||
this.width = config.width;
|
||||
} else {
|
||||
throw new Error("MomentumEngine.Game must be constructed with canvas width");
|
||||
throw new Error("MomentumEngine.Classes.Game must be constructed with canvas width");
|
||||
}
|
||||
|
||||
if (config.height) {
|
||||
this.height = config.height;
|
||||
} else {
|
||||
throw new Error("MomentumEngine.Game must be constructed with canvas height");
|
||||
throw new Error("MomentumEngine.Classes.Game must be constructed with canvas height");
|
||||
}
|
||||
|
||||
|
||||
@ -126,6 +126,7 @@ class Game extends Entity {
|
||||
})();
|
||||
|
||||
self._lastFrameTimestamp = +(new Date());
|
||||
self.startTime = self._lastFrameTimestamp;
|
||||
|
||||
var loop = function () {
|
||||
|
||||
|
52
src/classes/imageloader.js
Normal file
52
src/classes/imageloader.js
Normal file
@ -0,0 +1,52 @@
|
||||
"use strict";
|
||||
|
||||
class ImageLoader {
|
||||
|
||||
|
||||
constructor (src) {
|
||||
|
||||
this._loaded = false; // Default is true, set it to false until the image has loaded
|
||||
this._error = false; // If the image fails to load, this will contain the reason
|
||||
|
||||
this._imageObj = new Image();
|
||||
|
||||
this._imageObj.addEventListener("load", () => {
|
||||
this._loaded = true;
|
||||
this._error = false;
|
||||
});
|
||||
|
||||
this._imageObj.addEventListener("_error", (err) => {
|
||||
this._loaded = false;
|
||||
this._error = err;
|
||||
});
|
||||
|
||||
this._imageObj.src = src;
|
||||
|
||||
}
|
||||
|
||||
|
||||
getImageObj () {
|
||||
|
||||
if (this._loaded) {
|
||||
return this._imageObj;
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
isLoaded () {
|
||||
return this._loaded;
|
||||
}
|
||||
|
||||
|
||||
isError () {
|
||||
return this._error;
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
||||
export default ImageLoader;
|
78
src/classes/sprite.js
Normal file
78
src/classes/sprite.js
Normal file
@ -0,0 +1,78 @@
|
||||
"use strict";
|
||||
|
||||
import Entity from "./entity.js";
|
||||
import Vector2D from "./vector2d.js";
|
||||
import ImageLoader from "./imageloader.js";
|
||||
|
||||
import CollisionMethods from "../libs/collisionmethods.js";
|
||||
|
||||
|
||||
class Sprite extends Entity {
|
||||
|
||||
|
||||
constructor (x, y, width, height, image) {
|
||||
|
||||
if (!image instanceof ImageLoader) {
|
||||
throw new Error("MomentumEngine.Classes.Sprite must be instantiated with an ImageLoader instance");
|
||||
}
|
||||
|
||||
super(x, y);
|
||||
|
||||
this.size = new Vector2D(width || 0, height || 0);
|
||||
|
||||
this._image = image;
|
||||
this._imagePos = new Vector2D(0, 0);
|
||||
this._imageSize = new Vector2D(0, 0);
|
||||
|
||||
}
|
||||
|
||||
|
||||
setImageCoords (x, y, width, height) {
|
||||
|
||||
this._imagePos.x = x;
|
||||
this._imagePos.y = y;
|
||||
this._imageSize.x = width || 0;
|
||||
this._imageSize.y = height || 0;
|
||||
|
||||
}
|
||||
|
||||
|
||||
isReady () { // Overrides super isReady
|
||||
return (this._image.isLoaded() && !this._image.isError());
|
||||
}
|
||||
|
||||
|
||||
render () {
|
||||
|
||||
if (this.isReady()) {
|
||||
|
||||
var imageObj = this._image.getImageObj();
|
||||
|
||||
var subWidth = imageObj.width - this._imagePos.x,
|
||||
subHeight = imageObj.height - this._imagePos.y;
|
||||
|
||||
this._game.context.drawImage(
|
||||
imageObj,
|
||||
this._imagePos.x,
|
||||
this._imagePos.y,
|
||||
this._imageSize.x || subWidth,
|
||||
this._imageSize.y || subHeight,
|
||||
this._calculatedPos.x,
|
||||
this._calculatedPos.y,
|
||||
this.size.x || subWidth,
|
||||
this.size.y || subHeight
|
||||
);
|
||||
|
||||
return true;
|
||||
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
||||
export default Sprite;
|
@ -3,8 +3,10 @@
|
||||
import Game from "./classes/game.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 Color from "./classes/color.js";
|
||||
import ImageLoader from "./classes/imageloader.js";
|
||||
|
||||
import {KeyConsts} from "./classes/keyboardinput.js";
|
||||
|
||||
@ -12,9 +14,11 @@ import {KeyConsts} from "./classes/keyboardinput.js";
|
||||
const Classes = {
|
||||
Game: Game,
|
||||
Entity: Entity,
|
||||
Sprite: Sprite,
|
||||
Rect: Rect,
|
||||
Vector2D: Vector2D,
|
||||
Color: Color
|
||||
Color: Color,
|
||||
ImageLoader: ImageLoader
|
||||
};
|
||||
|
||||
|
||||
|
@ -3,8 +3,10 @@
|
||||
import Game from "./classes/game.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 Color from "./classes/color.js";
|
||||
import ImageLoader from "./classes/imageloader.js";
|
||||
|
||||
import {KeyConsts} from "./classes/keyboardinput.js";
|
||||
|
||||
@ -12,9 +14,11 @@ import {KeyConsts} from "./classes/keyboardinput.js";
|
||||
const Classes = {
|
||||
Game: Game,
|
||||
Entity: Entity,
|
||||
Sprite: Sprite,
|
||||
Rect: Rect,
|
||||
Vector2D: Vector2D,
|
||||
Color: Color
|
||||
Color: Color,
|
||||
ImageLoader: ImageLoader
|
||||
};
|
||||
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user