import { initializeContext, Vec3, Mat4, Vec4, Vec2 } from "./common.js"; import { Graphics, fullscreenCanvas, Camera } from "./graphics.js"; import * as drawing from "./draw.js"; import * as wasm from "./wasm.js"; import { Input } from "./input.js"; import { bush, Grid, Tile, tree } from "./world.js"; import * as Assets from "./assets.js"; const vertexShader = `#version 300 es layout(location = 0) in vec3 a_position; layout(location = 1) in vec2 a_tex_position; layout(location = 2) in vec4 a_color; out vec4 v_color; out vec2 v_tex_position; uniform mat4 u_matrix; uniform bool u_isIso; uniform bool u_isTex; mat4 Iso = mat4( 1, -1, 0, 0, 1, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1 ); void main() { vec4 orthographic; if (u_isIso) { vec4 isometric = Iso * vec4(a_position.xyz, 1.0); orthographic = u_matrix * isometric; //orthographic = u_matrix * vec4(a_position.xyz, 1.0); } else { orthographic = u_matrix * vec4(a_position.xyz, 1.0); } gl_Position = orthographic; if (u_isTex) { v_tex_position = a_tex_position; } else { v_color = a_color; } } `; const fragmentShader = `#version 300 es precision highp float; in vec4 v_color; in vec2 v_tex_position; out vec4 outColor; uniform sampler2D u_texture; uniform bool u_isTex; void main() { if (u_isTex) { outColor = texture(u_texture, v_tex_position); } else { outColor = v_color; } } `; function draw(gfx, camera, dt, grid) { gfx.clear(0, 0, 0, 0); camera.update(dt); let right = gfx.ctx.canvas.width; let left = 0; let top = gfx.ctx.canvas.height; let bottom = 0; let near = -100; let far = 100; let m = Mat4.IDENTITY(); let mo = Mat4.orthographic(left, right, bottom, top, near, far); let mc = Mat4.translate(new Vec3((gfx.ctx.canvas.width / 2 - camera.position.x), (gfx.ctx.canvas.height / 2 - camera.position.y), 1.0)); let mr = Mat4.translate(new Vec3(-(gfx.ctx.canvas.width / 2 - camera.position.x), -(gfx.ctx.canvas.height / 2 - camera.position.y), 1.0)); let mt = Mat4.translate(camera.position); let ms = Mat4.scale(new Vec3(camera.scale, camera.scale, 1)); m = m.multNew(mr); m = m.multNew(ms); m = m.multNew(mc); m = m.multNew(mt); m = m.multNew(mo); gfx.ctx.uniformMatrix4fv(gfx.getUniform("u_matrix"), false, m.splat()); drawing.drawIsometricGrid(gfx, grid); gfx.draw(); } function addDefaultKeybinds(input, camera) { input.addKeyAction("KeyA", [], camera, (c) => { c.movement.x = 0; }, (c) => { c.movement.x = 1; }); input.addKeyAction("KeyD", [], camera, (c) => { c.movement.y = 0; }, (c) => { c.movement.y = -1; }); input.addKeyAction("KeyW", [], camera, (c) => { c.movement.z = 0; }, (c) => { c.movement.z = -1; }); input.addKeyAction("KeyS", [], camera, (c) => { c.movement.w = 0; }, (c) => { c.movement.w = 1; }); input.addKeyAction("KeyQ", [], camera, (c) => { c.scaling = 0.0; }, (c) => { c.scaling = 1.0; }); input.addKeyAction("KeyE", [], camera, (c) => { c.scaling = 0.0; }, (c) => { c.scaling = -1.0; }); } (async () => { const canvasId = "game"; const ctx = initializeContext(canvasId); if (ctx === null) return; const gfx = new Graphics(ctx, vertexShader, fragmentShader); fullscreenCanvas(gfx, canvasId); let a = gfx.createAttribute("a_position"); a.format(3, ctx.FLOAT, false, 0); a = gfx.createAttribute("a_color"); a.format(4, ctx.FLOAT, false, 0); a = gfx.createAttribute("a_tex_position"); a.format(2, ctx.FLOAT, false, 0); gfx.createUniform("u_matrix"); gfx.createUniform("u_isIso"); gfx.createUniform("u_isTex"); let camera = new Camera(new Vec3(0, 0, -1)); await Assets.assets.load(gfx); let m = Mat4.isometric(); let size = 100; let grid = new Grid(m.transformNew(new Vec4(ctx.canvas.width / 4, ctx.canvas.height / 2, 0, 1)).reduce(), 24, size, size, 10); grid.fillLayer(new Tile({ top: Assets.assets.get("grass"), right: Assets.Colors.Brown, left: Assets.Colors.Brown, }), 0); tree(grid, new Vec2(size / 2, size / 2)); bush(grid, new Vec2(size / 2 + 4, size / 2 + 4)); //for (let i = 0; i < 10; i++) { // tree(grid, new Vec2(Math.floor(Math.random() * size - 1), Math.floor(Math.random() * size - 1))); //} //grid.setTile(new Tile(Assets.AssetToTileFill("log"), TileEdge.Both), new Vec3(0, 29, 1)); let prevTimestamp = 0; const frame = (timestamp) => { const deltaTime = (timestamp - prevTimestamp) / 1000; prevTimestamp = timestamp; fullscreenCanvas(gfx, "game"); draw(gfx, camera, deltaTime, grid); window.requestAnimationFrame(frame); }; window.requestAnimationFrame((timestamp) => { prevTimestamp = timestamp; window.requestAnimationFrame(frame); }); const input = new Input(); addDefaultKeybinds(input, camera); const wasmgl = new wasm.WASMGL(await wasm.loadWasmModule("./src/wasm/module.wasm")); })();