135 lines
3.6 KiB
JavaScript
135 lines
3.6 KiB
JavaScript
window.Minecraft = class {
|
|
|
|
/**
|
|
* Create Minecraft instance and render it on a canvas
|
|
*/
|
|
constructor(canvasWrapperId) {
|
|
this.worldRenderer = new WorldRenderer(this);
|
|
this.window = new GameWindow(this, this.worldRenderer, canvasWrapperId);
|
|
this.timer = new Timer(20);
|
|
|
|
this.frames = 0;
|
|
this.lastTime = Date.now();
|
|
|
|
// Create all blocks
|
|
Block.create();
|
|
|
|
// Create world
|
|
this.world = new World();
|
|
this.worldRenderer.scene.add(this.world.group);
|
|
|
|
// Create player
|
|
this.player = new Player(this.world);
|
|
this.pickedBlock = 1;
|
|
|
|
// Initialize
|
|
this.init();
|
|
}
|
|
|
|
init() {
|
|
// Start render loop
|
|
this.running = true;
|
|
this.requestNextFrame();
|
|
}
|
|
|
|
requestNextFrame() {
|
|
let scope = this;
|
|
requestAnimationFrame(function () {
|
|
if (scope.running) {
|
|
scope.requestNextFrame();
|
|
scope.onLoop();
|
|
}
|
|
});
|
|
}
|
|
|
|
onLoop() {
|
|
this.window.stats.begin();
|
|
|
|
// Update the timer
|
|
this.timer.advanceTime();
|
|
|
|
// Call the tick to reach updates 20 per seconds
|
|
for (let i = 0; i < this.timer.ticks; i++) {
|
|
this.onTick();
|
|
}
|
|
|
|
// Render the game
|
|
this.onRender(this.timer.partialTicks);
|
|
|
|
// Increase rendered frame
|
|
this.frames++;
|
|
|
|
// Loop if a second passed
|
|
while (Date.now() >= this.lastTime + 1000) {
|
|
//console.log(this.frames + " fps");
|
|
|
|
this.lastTime += 1000;
|
|
this.frames = 0;
|
|
}
|
|
|
|
this.window.stats.end();
|
|
}
|
|
|
|
onRender(partialTicks) {
|
|
// Player rotation
|
|
if (this.window.mouseLocked) {
|
|
this.player.turn(this.window.mouseMotionX, this.window.mouseMotionY);
|
|
|
|
this.window.mouseMotionX = 0;
|
|
this.window.mouseMotionY = 0;
|
|
}
|
|
|
|
// Render the game
|
|
this.worldRenderer.render(partialTicks);
|
|
}
|
|
|
|
onTick() {
|
|
// Tick world
|
|
this.world.onTick();
|
|
|
|
// Tick the player
|
|
this.player.onTick();
|
|
}
|
|
|
|
onMouseClicked(button) {
|
|
if (this.window.mouseLocked) {
|
|
let hitResult = this.player.rayTrace(5, this.timer.partialTicks);
|
|
|
|
// Destroy block
|
|
if (button === 0) {
|
|
if (hitResult != null) {
|
|
this.world.setBlockAt(hitResult.x, hitResult.y, hitResult.z, 0);
|
|
this.world.updateBlockLightAt(hitResult.x, hitResult.y, hitResult.z);
|
|
}
|
|
}
|
|
|
|
// Pick block
|
|
if (button === 1) {
|
|
if (hitResult != null) {
|
|
let typeId = this.world.getBlockAt(hitResult.x, hitResult.y, hitResult.z);
|
|
if (typeId !== 0) {
|
|
this.pickedBlock = typeId;
|
|
}
|
|
}
|
|
}
|
|
|
|
// Place block
|
|
if (button === 2) {
|
|
if (hitResult != null) {
|
|
let x = hitResult.x + hitResult.face.x;
|
|
let y = hitResult.y + hitResult.face.y;
|
|
let z = hitResult.z + hitResult.face.z;
|
|
|
|
let placedBoundingBox = new BoundingBox(x, y, z, x + 1, y + 1, z + 1);
|
|
|
|
// Don't place blocks if the player is standing there
|
|
if (!placedBoundingBox.intersects(this.player.boundingBox)) {
|
|
this.world.setBlockAt(x, y, z, this.pickedBlock);
|
|
this.world.updateBlockLightAt(x, y, z);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
} |