Performance optimizations and refacturing.

This commit is contained in:
Mal 2020-02-12 23:30:04 +01:00
parent b06186043f
commit 72589544bd
6 changed files with 138 additions and 26 deletions

View File

@ -1,4 +1,5 @@
import GeometryPoint from "./geometry/GeometryPoint.js";
import GeometryRect from "./geometry/GeometryRect.js";
export default class Camera
{
@ -114,4 +115,20 @@ export default class Camera
}
}
}
getViewAsRect()
{
return new GeometryRect(this.position.x, this.position.y, this.width, this.height);
}
isMovableInsideView(movable)
{
let viewRect = this.getViewAsRect();
let distanceMovable = movable.getRect().getDiagonal().getLength() * 0.5;
let distanceCamera = viewRect.getDiagonal().getLength() * 0.5;
let distanceMin = distanceMovable + distanceCamera;
return movable.getCenter().getDistanceToPoint(viewRect.getCenter()) < distanceMin;
}
}

86
js/FrameRateMeasurer.js Normal file
View File

@ -0,0 +1,86 @@
import FrameRateMeasuredEvent from "./events/FrameRateMeasuredEvent.js";
export default class FrameRateMeasurer
{
constructor(rounds = 100)
{
this.rounds = rounds;
this.round = 0;
this.lastTimestamp = undefined;
this.frameDurations = [];
window.requestAnimationFrame(
(timestamp) => {
this.measureFrameRate(timestamp);
}
);
}
measureFrameRate(timestamp)
{
if (this.lastTimestamp !== undefined) {
this.round++;
this.frameDurations.push(timestamp - this.lastTimestamp);
this.lastTimestamp = timestamp;
if (this.round < this.rounds) {
window.requestAnimationFrame(
(timestamp) => {
this.measureFrameRate(timestamp);
}
);
} else {
window.dispatchEvent(new FrameRateMeasuredEvent(this.getAverageFrameRate()));
}
} else {
this.round = 0;
this.lastTimestamp = timestamp;
window.requestAnimationFrame(
(timestamp) => {
this.measureFrameRate(timestamp);
}
);
}
this.lastTimestamp = timestamp
}
getAverageFrameRate()
{
let frameDurationSum = 0;
this.frameDurations.forEach(
(duration) => {
frameDurationSum += duration;
}
);
let durationAverage = frameDurationSum / this.frameDurations.length;
return 1000 / durationAverage;
}
getFrameRate()
{
const DEFAULT_FRAME_RATES = [30, 60, 120];
let averageFrameRate = this.getAverageFrameRate();
let closestDistance = {frameRate: 0, distance: 99999};
DEFAULT_FRAME_RATES.forEach(
(frameRate) => {
let distance = Math.abs(frameRate - averageFrameRate);
if (closestDistance.distance > distance) {
closestDistance.frameRate = frameRate;
closestDistance.distance = distance;
}
}
);
console.log(this.frameDurations);
return closestDistance.frameRate;
}
}

View File

@ -109,7 +109,9 @@ export default class Movable
draw(context, camera)
{
this.animations[this.currentAnimation].setFootPosition(this.position.x, this.position.y);
this.animations[this.currentAnimation].draw(context, camera);
if (camera.isMovableInsideView(this)) {
this.animations[this.currentAnimation].setFootPosition(this.position.x, this.position.y);
this.animations[this.currentAnimation].draw(context, camera);
}
}
}

View File

@ -0,0 +1,9 @@
import InterfaceEvent from "./InterfaceEvent.js";
export default class FrameRateMeasuredEvent extends Event
{
constructor(frameRate) {
super(InterfaceEvent.FRAME_RATE_MEASURED);
this.frameRate = frameRate;
}
}

View File

@ -1,6 +1,7 @@
export default InterfaceEvent;
const InterfaceEvent = {
IMAGE_LOADED: 'imgloaded',
MEDIA_COLLECTION_LOADED: 'mediacollectionloaded',
};
IMAGE_LOADED: 'imageLoaded',
MEDIA_COLLECTION_LOADED: 'mediaCollectionLoaded',
FRAME_RATE_MEASURED: 'frameRateMeasured',
};
export default InterfaceEvent;

View File

@ -7,6 +7,8 @@ import FileLoader from "./FileLoader.js";
import Camera from "./Camera.js";
import Gisela from "./Gisela.js";
import Setting from "./Setting.js";
import InterfaceEvent from "./events/InterfaceEvent.js";
import FrameRateMeasurer from "./FrameRateMeasurer.js";
class ImageLoader
{
@ -27,8 +29,10 @@ class ImageLoader
return this.numberImagesLoaded / this.images.length;
}
addImage(image)
addImage(imagePath)
{
let image = new Image();
image.src = imagePath;
image.addEventListener(
'load', () => {
this.update();
@ -125,7 +129,7 @@ function MainLoop(timestamp)
camera.lockCameraIntoBorders();
/* Drawing */
if (timestamp - lastRendered >= FRAME_DURATION) {
if (timestamp - lastRendered >= frameDuration) {
context.clearRect(0, 0, window.innerWidth, window.innerHeight);
architecture.draw(context, camera);
@ -151,10 +155,10 @@ function MainLoop(timestamp)
window.requestAnimationFrame(MainLoop);
}
const FPS = 120;
const FRAME_DURATION = 1000 / FPS;
const GAME_SPEED = 1;
const GRAVITY = 2;
let fps;
let frameDuration;
let levelJson = new FileLoader('levels/level01.json');
@ -174,21 +178,12 @@ let KeyJump = new Key('Space');
let loader = new ImageLoader();
let imgAnimation = new Image();
imgAnimation.src = Setting.GRAPHICS_LOCATION + 'mr-croc-walk-right.png';
loader.addImage(imgAnimation);
loader.addImage(Setting.GRAPHICS_LOCATION + 'mr-croc-walk-right.png');
loader.addImage(Setting.GRAPHICS_LOCATION + 'mr-croc-walk-left.png');
loader.addImage(Setting.TILESET_LOCATION + 'landscape01.jpg');
loader.addImage(Setting.GRAPHICS_LOCATION + 'gisela-right.png');
let imgAnimationB = new Image();
imgAnimationB.src = Setting.GRAPHICS_LOCATION + 'mr-croc-walk-left.png';
loader.addImage(imgAnimationB);
let imgArch = new Image();
imgArch.src = Setting.TILESET_LOCATION + 'landscape01.jpg';
loader.addImage(imgArch);
let imgGisela = new Image();
imgGisela.src = Setting.GRAPHICS_LOCATION + 'gisela-right.png';
loader.addImage(imgGisela);
new FrameRateMeasurer();
window.addEventListener(
'imagesloaded',
@ -217,6 +212,8 @@ window.addEventListener(
gisela = new Gisela();
architecture.setMovableToTargetPosition(gisela);
fps = 120; //event.frameRate;
frameDuration = 1000 / fps;
window.requestAnimationFrame(MainLoop);
}
);
);