Added Sprite, Spritesheet and made batching actually do shit
This commit is contained in:
parent
2e9ec2565b
commit
37a91de848
|
@ -1,36 +1,26 @@
|
|||
import { Texture } from "./graphics.js";
|
||||
import { Vec2 } from "./common.js";
|
||||
import { Texture, Spritesheet } from "./graphics.js";
|
||||
export const Colors = {
|
||||
Red: [1, 0, 0, 1],
|
||||
Green: [0, 1, 0, 1],
|
||||
Blue: [0, 0, 1, 1],
|
||||
Brown: [0.341, 0.337, 0.204, 1],
|
||||
};
|
||||
export function AssetToTileFill(name) {
|
||||
let asset = assets.get(name);
|
||||
return {
|
||||
left: asset,
|
||||
top: asset,
|
||||
right: asset,
|
||||
};
|
||||
}
|
||||
export class Assets {
|
||||
assets = new Map();
|
||||
loaded = false;
|
||||
push(name, asset) {
|
||||
if (this.assets.get(name) !== undefined)
|
||||
throw new Error("Asset name occupied!");
|
||||
this.assets.set(name, asset);
|
||||
}
|
||||
get(name) {
|
||||
if (!this.loaded)
|
||||
throw new Error("Tried to assess assets without loading them!");
|
||||
return this.assets.get(name);
|
||||
let a = this.assets.get(name);
|
||||
if (a === undefined)
|
||||
throw new Error("Couldn't find asset: " + name);
|
||||
return a;
|
||||
}
|
||||
async load(gfx) {
|
||||
assets.push("grass", await Texture.load(gfx, "../../assets/grass2.png"));
|
||||
assets.push("leaves", await Texture.load(gfx, "../../assets/greenary.png"));
|
||||
assets.push("log", await Texture.load(gfx, "../../assets/log.png"));
|
||||
this.loaded = true;
|
||||
assets.push("sprites", new Spritesheet(await Texture.load(gfx, "../../assets/sprites.png"), new Vec2(16, 16)));
|
||||
}
|
||||
}
|
||||
export const assets = new Assets();
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
import {Graphics, Texture} from "./graphics.js";
|
||||
import {TileFill} from "./world.js";
|
||||
import {Vec2} from "./common.js";
|
||||
import {Graphics, Texture, Spritesheet} from "./graphics.js";
|
||||
|
||||
export type Color = [number, number, number, number]
|
||||
|
||||
|
@ -10,21 +10,10 @@ export const Colors = {
|
|||
Brown : [0.341, 0.337, 0.204, 1] as Color,
|
||||
}
|
||||
|
||||
export type Asset = Texture;
|
||||
|
||||
export function AssetToTileFill(name: string): TileFill {
|
||||
let asset = assets.get(name);
|
||||
|
||||
return {
|
||||
left: asset,
|
||||
top: asset,
|
||||
right: asset,
|
||||
};
|
||||
}
|
||||
export type Asset = Texture | Spritesheet;
|
||||
|
||||
export class Assets {
|
||||
assets: Map<string, Asset> = new Map();
|
||||
loaded: boolean = false;
|
||||
|
||||
push(name: string, asset: Asset) {
|
||||
if (this.assets.get(name) !== undefined)
|
||||
|
@ -34,18 +23,15 @@ export class Assets {
|
|||
}
|
||||
|
||||
get(name: string): Asset {
|
||||
if (!this.loaded)
|
||||
throw new Error("Tried to assess assets without loading them!");
|
||||
|
||||
return this.assets.get(name)!;
|
||||
let a = this.assets.get(name);
|
||||
if (a === undefined)
|
||||
throw new Error("Couldn't find asset: " + name);
|
||||
|
||||
return a;
|
||||
}
|
||||
|
||||
async load(gfx: Graphics) {
|
||||
assets.push("grass", await Texture.load(gfx, "../../assets/grass2.png"));
|
||||
assets.push("leaves", await Texture.load(gfx, "../../assets/greenary.png"));
|
||||
assets.push("log", await Texture.load(gfx, "../../assets/log.png"));
|
||||
|
||||
this.loaded = true;
|
||||
assets.push("sprites", new Spritesheet(await Texture.load(gfx, "../../assets/sprites.png"), new Vec2(16, 16)));
|
||||
}
|
||||
}
|
||||
|
||||
|
|
155
src/js/draw.js
155
src/js/draw.js
|
@ -1,30 +1,20 @@
|
|||
import { Vec3 } from "./common.js";
|
||||
import { Texture, DrawTag } from "./graphics.js";
|
||||
import { DrawTag, Sprite } from "./graphics.js";
|
||||
import { TileEdge } from "./world.js";
|
||||
// TODO: Don't assume tile size is same in all directions
|
||||
function cull(point, screen, tileSize) {
|
||||
if (point.x + tileSize < screen.x)
|
||||
return true;
|
||||
if (point.x + tileSize > screen.x + screen.z)
|
||||
return true;
|
||||
if (point.y - tileSize < screen.y)
|
||||
return true;
|
||||
if (point.y + tileSize > screen.y + screen.w)
|
||||
return true;
|
||||
return false;
|
||||
}
|
||||
import * as Assets from "./assets.js";
|
||||
// Attrib format
|
||||
// position color uv
|
||||
// (3) (4) (2) => 3 + 4 + 2 = 9 <=> data.len % 9 == 0
|
||||
// (3) (4) (3) => 3 + 4 + 3 = 10 <=> vertexSize == 10
|
||||
export class Rectangle {
|
||||
fill;
|
||||
attribs = ["a_position", "a_color", "a_tex_position"];
|
||||
attribs = ["a_position", "a_color", "a_tex"];
|
||||
tags = [];
|
||||
data = [];
|
||||
stride = 0;
|
||||
vertexStride = 0;
|
||||
constructor(fill, tags, attribs) {
|
||||
this.fill = fill;
|
||||
vertexSize = 10;
|
||||
sprites = Assets.assets.get("sprites");
|
||||
constructor(tags, sprites, attribs) {
|
||||
if (sprites !== undefined) {
|
||||
this.sprites = sprites;
|
||||
}
|
||||
if (attribs !== undefined) {
|
||||
this.attribs = attribs;
|
||||
}
|
||||
|
@ -32,61 +22,59 @@ export class Rectangle {
|
|||
this.tags = tags;
|
||||
}
|
||||
}
|
||||
overrideDraw(draw) {
|
||||
this.draw = draw;
|
||||
}
|
||||
draw(gfx, corners) {
|
||||
if (this.fill instanceof Texture) {
|
||||
this.data = [
|
||||
corners[0].x, corners[0].y, corners[0].z, 0, 0, 0, 0, 0, 0,
|
||||
corners[1].x, corners[1].y, corners[1].z, 0, 0, 0, 0, -1, 0,
|
||||
corners[3].x, corners[3].y, corners[3].z, 0, 0, 0, 0, 0, -1,
|
||||
corners[2].x, corners[2].y, corners[2].z, 0, 0, 0, 0, -1, -1,
|
||||
corners[1].x, corners[1].y, corners[1].z, 0, 0, 0, 0, -1, 0,
|
||||
corners[3].x, corners[3].y, corners[3].z, 0, 0, 0, 0, 0, -1,
|
||||
];
|
||||
}
|
||||
else {
|
||||
this.data = [
|
||||
corners[0].x, corners[0].y, corners[0].z, this.fill[0], this.fill[1], this.fill[2], this.fill[3], 0, 0,
|
||||
corners[1].x, corners[1].y, corners[1].z, this.fill[0], this.fill[1], this.fill[2], this.fill[3], 0, 0,
|
||||
corners[3].x, corners[3].y, corners[3].z, this.fill[0], this.fill[1], this.fill[2], this.fill[3], 0, 0,
|
||||
corners[2].x, corners[2].y, corners[2].z, this.fill[0], this.fill[1], this.fill[2], this.fill[3], 0, 0,
|
||||
corners[1].x, corners[1].y, corners[1].z, this.fill[0], this.fill[1], this.fill[2], this.fill[3], 0, 0,
|
||||
corners[3].x, corners[3].y, corners[3].z, this.fill[0], this.fill[1], this.fill[2], this.fill[3], 0, 0,
|
||||
];
|
||||
}
|
||||
this.vertexStride = 9;
|
||||
this.stride = this.vertexStride * 4;
|
||||
gfx.toRender.push({ ...this });
|
||||
}
|
||||
drawExts(gfx, position, exts) {
|
||||
if (this.fill instanceof Texture) {
|
||||
this.data = [
|
||||
position.x, position.y, position.z, 0, 0, 0, 0, 0, 0,
|
||||
position.x + exts.x, position.y, position.z, 0, 0, 0, 0, -1, 0,
|
||||
position.x, position.y + exts.y, position.z, 0, 0, 0, 0, 0, -1,
|
||||
position.x + exts.x, position.y + exts.y, position.z, 0, 0, 0, 0, -1, -1,
|
||||
position.x + exts.x, position.y, position.z, 0, 0, 0, 0, -1, 0,
|
||||
position.x, position.y + exts.y, position.z, 0, 0, 0, 0, 0, -1,
|
||||
];
|
||||
}
|
||||
else {
|
||||
this.data = [
|
||||
position.x, position.y, position.z, this.fill[0], this.fill[1], this.fill[2], this.fill[3], 0, 0,
|
||||
position.x + exts.x, position.y, position.z, this.fill[0], this.fill[1], this.fill[2], this.fill[3], 0, 0,
|
||||
position.x, position.y + exts.y, position.z, this.fill[0], this.fill[1], this.fill[2], this.fill[3], 0, 0,
|
||||
position.x + exts.x, position.y + exts.y, position.z, this.fill[0], this.fill[1], this.fill[2], this.fill[3], 0, 0,
|
||||
position.x + exts.x, position.y, position.z, this.fill[0], this.fill[1], this.fill[2], this.fill[3], 0, 0,
|
||||
position.x, position.y + exts.y, position.z, this.fill[0], this.fill[1], this.fill[2], this.fill[3], 0, 0,
|
||||
];
|
||||
}
|
||||
this.vertexStride = 9;
|
||||
this.stride = this.vertexStride * 4;
|
||||
commit(gfx) {
|
||||
gfx.toRender.push(this);
|
||||
}
|
||||
draw(corners, fill) {
|
||||
if (fill instanceof Sprite) {
|
||||
let uvs = Assets.assets.get("sprites").getUVs(fill.id);
|
||||
this.data.push([
|
||||
corners[0].x, corners[0].y, corners[0].z, 0, 0, 0, 0, uvs[0].x, uvs[0].y, 1,
|
||||
corners[1].x, corners[1].y, corners[1].z, 0, 0, 0, 0, uvs[1].x, uvs[1].y, 1,
|
||||
corners[3].x, corners[3].y, corners[3].z, 0, 0, 0, 0, uvs[3].x, uvs[3].y, 1,
|
||||
corners[2].x, corners[2].y, corners[2].z, 0, 0, 0, 0, uvs[2].x, uvs[2].y, 1,
|
||||
corners[1].x, corners[1].y, corners[1].z, 0, 0, 0, 0, uvs[1].x, uvs[1].y, 1,
|
||||
corners[3].x, corners[3].y, corners[3].z, 0, 0, 0, 0, uvs[3].x, uvs[3].y, 1,
|
||||
]);
|
||||
}
|
||||
else {
|
||||
let color = fill;
|
||||
this.data.push([
|
||||
corners[0].x, corners[0].y, corners[0].z, color[0], color[1], color[2], color[3], 0, 0, 0,
|
||||
corners[1].x, corners[1].y, corners[1].z, color[0], color[1], color[2], color[3], 0, 0, 0,
|
||||
corners[3].x, corners[3].y, corners[3].z, color[0], color[1], color[2], color[3], 0, 0, 0,
|
||||
corners[2].x, corners[2].y, corners[2].z, color[0], color[1], color[2], color[3], 0, 0, 0,
|
||||
corners[1].x, corners[1].y, corners[1].z, color[0], color[1], color[2], color[3], 0, 0, 0,
|
||||
corners[3].x, corners[3].y, corners[3].z, color[0], color[1], color[2], color[3], 0, 0, 0,
|
||||
]);
|
||||
}
|
||||
}
|
||||
drawExts(position, exts, fill) {
|
||||
if (fill instanceof Sprite) {
|
||||
let uvs = Assets.assets.get("sprites").getUVs(fill.id);
|
||||
this.data.push([
|
||||
position.x, position.y, position.z, 0, 0, 0, 0, uvs[0].x, uvs[0].y, 1,
|
||||
position.x + exts.x, position.y, position.z, 0, 0, 0, 0, uvs[1].x, uvs[1].y, 1,
|
||||
position.x, position.y + exts.y, position.z, 0, 0, 0, 0, uvs[3].x, uvs[3].y, 1,
|
||||
position.x + exts.x, position.y + exts.y, position.z, 0, 0, 0, 0, uvs[2].x, uvs[2].y, 1,
|
||||
position.x + exts.x, position.y, position.z, 0, 0, 0, 0, uvs[1].x, uvs[1].y, 1,
|
||||
position.x, position.y + exts.y, position.z, 0, 0, 0, 0, uvs[3].x, uvs[3].y, 1,
|
||||
]);
|
||||
}
|
||||
else {
|
||||
let color = fill;
|
||||
this.data.push([
|
||||
position.x, position.y, position.z, color[0], color[1], color[2], color[3], 0, 0,
|
||||
position.x + exts.x, position.y, position.z, color[0], color[1], color[2], color[3], 0, 0,
|
||||
position.x, position.y + exts.y, position.z, color[0], color[1], color[2], color[3], 0, 0,
|
||||
position.x + exts.x, position.y + exts.y, position.z, color[0], color[1], color[2], color[3], 0, 0,
|
||||
position.x + exts.x, position.y, position.z, color[0], color[1], color[2], color[3], 0, 0,
|
||||
position.x, position.y + exts.y, position.z, color[0], color[1], color[2], color[3], 0, 0,
|
||||
]);
|
||||
}
|
||||
}
|
||||
}
|
||||
export function drawIsometricCube(gfx, position, exts, color, edge) {
|
||||
export function drawIsometricCube(position, exts, r, fill, edge) {
|
||||
let points = [
|
||||
// Left Top
|
||||
position,
|
||||
|
@ -101,41 +89,39 @@ export function drawIsometricCube(gfx, position, exts, color, edge) {
|
|||
new Vec3(position.x + 1.5 * exts.x, position.y + 0.5 * exts.y, position.z + 0.25 * exts.z),
|
||||
new Vec3(position.x + 0.5 * exts.x, position.y - 0.5 * exts.y, position.z + 0.25 * exts.z),
|
||||
];
|
||||
let r = new Rectangle(color.top, [
|
||||
DrawTag.ISO,
|
||||
]);
|
||||
// Top
|
||||
r.draw(gfx, [
|
||||
r.draw([
|
||||
points[0],
|
||||
points[1],
|
||||
points[3],
|
||||
points[2],
|
||||
]);
|
||||
], fill.top);
|
||||
// Right Edge
|
||||
if (edge == TileEdge.Right || edge == TileEdge.Both) {
|
||||
r.fill = color.right;
|
||||
r.draw(gfx, [
|
||||
r.draw([
|
||||
points[3],
|
||||
points[2],
|
||||
points[4],
|
||||
points[5],
|
||||
]);
|
||||
], fill.right);
|
||||
}
|
||||
// Left Edge
|
||||
if (edge == TileEdge.Left || edge == TileEdge.Both) {
|
||||
r.fill = color.left;
|
||||
r.draw(gfx, [
|
||||
r.draw([
|
||||
points[0],
|
||||
points[2],
|
||||
points[4],
|
||||
points[6],
|
||||
]);
|
||||
], fill.left);
|
||||
}
|
||||
}
|
||||
export function drawIsometricGrid(gfx, grid) {
|
||||
let position = { ...grid.position };
|
||||
let exts = new Vec3(grid.tileSize, grid.tileSize, 0);
|
||||
let tileCoord = new Vec3(0, 0, 0);
|
||||
let rect = new Rectangle([
|
||||
DrawTag.ISO,
|
||||
]);
|
||||
// TODO: Optimize this
|
||||
// 1. Grid based occlusion culling
|
||||
// 2. frustum culling
|
||||
|
@ -152,7 +138,7 @@ export function drawIsometricGrid(gfx, grid) {
|
|||
position.x += grid.tileSize;
|
||||
continue;
|
||||
}
|
||||
drawIsometricCube(gfx, new Vec3(position.x - grid.tileSize / 2 * k, position.y + grid.tileSize / 2 * k, position.z), exts, tile.fill, tile.edge);
|
||||
drawIsometricCube(new Vec3(position.x - grid.tileSize / 2 * k, position.y + grid.tileSize / 2 * k, position.z), exts, rect, tile.fill, tile.edge);
|
||||
position.x += grid.tileSize;
|
||||
}
|
||||
position.y -= grid.tileSize;
|
||||
|
@ -160,4 +146,5 @@ export function drawIsometricGrid(gfx, grid) {
|
|||
}
|
||||
position.y = grid.position.y;
|
||||
}
|
||||
rect.commit(gfx);
|
||||
}
|
||||
|
|
189
src/js/draw.ts
189
src/js/draw.ts
|
@ -1,40 +1,25 @@
|
|||
import { Vec3, Vec2, Vec4 } from "./common.js"
|
||||
import { Graphics, Texture, Drawable, DrawTag } from "./graphics.js";
|
||||
import { TileEdge, TileFill, Grid } from "./world.js";
|
||||
import { Vec3, Vec2 } from "./common.js"
|
||||
import { Graphics, Drawable, DrawTag, Sprite, Spritesheet } from "./graphics.js";
|
||||
import { TileEdge, TileFill, TileFillament, Grid } from "./world.js";
|
||||
import * as Assets from "./assets.js";
|
||||
|
||||
// TODO: Don't assume tile size is same in all directions
|
||||
function cull(point: Vec3, screen: Vec4, tileSize: number): boolean {
|
||||
if (point.x + tileSize < screen.x)
|
||||
return true;
|
||||
|
||||
if (point.x + tileSize > screen.x + screen.z)
|
||||
return true;
|
||||
|
||||
if (point.y - tileSize < screen.y)
|
||||
return true;
|
||||
|
||||
if (point.y + tileSize > screen.y + screen.w)
|
||||
return true;
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
// Attrib format
|
||||
// position color uv
|
||||
// (3) (4) (2) => 3 + 4 + 2 = 9 <=> data.len % 9 == 0
|
||||
// (3) (4) (3) => 3 + 4 + 3 = 10 <=> vertexSize == 10
|
||||
|
||||
export class Rectangle implements Drawable {
|
||||
fill: Texture | Assets.Color;
|
||||
attribs: string[] = ["a_position", "a_color", "a_tex_position"];
|
||||
attribs: string[] = ["a_position", "a_color", "a_tex"];
|
||||
tags: Array<DrawTag> = [];
|
||||
|
||||
data: number[] = [];
|
||||
stride: number = 0;
|
||||
vertexStride: number = 0;
|
||||
data: number[][] = [];
|
||||
vertexSize: number = 10;
|
||||
|
||||
constructor(fill: Texture | Assets.Color, tags?: Array<DrawTag>, attribs?: string[]) {
|
||||
this.fill = fill;
|
||||
sprites: Spritesheet = Assets.assets.get("sprites") as Spritesheet;
|
||||
|
||||
constructor(tags?: Array<DrawTag>, sprites?: Spritesheet, attribs?: string[]) {
|
||||
if (sprites !== undefined) {
|
||||
this.sprites = sprites;
|
||||
}
|
||||
|
||||
if (attribs !== undefined) {
|
||||
this.attribs = attribs;
|
||||
|
@ -45,68 +30,68 @@ export class Rectangle implements Drawable {
|
|||
}
|
||||
}
|
||||
|
||||
overrideDraw(draw: (...args: any[]) => void) {
|
||||
this.draw = draw;
|
||||
}
|
||||
|
||||
draw(gfx: Graphics, corners: [Vec3, Vec3, Vec3, Vec3]) {
|
||||
if (this.fill instanceof Texture) {
|
||||
this.data = [
|
||||
corners[0].x, corners[0].y, corners[0].z, 0, 0, 0, 0, 0, 0,
|
||||
corners[1].x, corners[1].y, corners[1].z, 0, 0, 0, 0, -1, 0,
|
||||
corners[3].x, corners[3].y, corners[3].z, 0, 0, 0, 0, 0, -1,
|
||||
|
||||
corners[2].x, corners[2].y, corners[2].z, 0, 0, 0, 0, -1, -1,
|
||||
corners[1].x, corners[1].y, corners[1].z, 0, 0, 0, 0, -1, 0,
|
||||
corners[3].x, corners[3].y, corners[3].z, 0, 0, 0, 0, 0, -1,
|
||||
]
|
||||
} else {
|
||||
this.data = [
|
||||
corners[0].x, corners[0].y, corners[0].z, this.fill[0], this.fill[1], this.fill[2], this.fill[3], 0, 0,
|
||||
corners[1].x, corners[1].y, corners[1].z, this.fill[0], this.fill[1], this.fill[2], this.fill[3], 0, 0,
|
||||
corners[3].x, corners[3].y, corners[3].z, this.fill[0], this.fill[1], this.fill[2], this.fill[3], 0, 0,
|
||||
|
||||
corners[2].x, corners[2].y, corners[2].z, this.fill[0], this.fill[1], this.fill[2], this.fill[3], 0, 0,
|
||||
corners[1].x, corners[1].y, corners[1].z, this.fill[0], this.fill[1], this.fill[2], this.fill[3], 0, 0,
|
||||
corners[3].x, corners[3].y, corners[3].z, this.fill[0], this.fill[1], this.fill[2], this.fill[3], 0, 0,
|
||||
]
|
||||
}
|
||||
|
||||
this.vertexStride = 9;
|
||||
this.stride = this.vertexStride * 4
|
||||
gfx.toRender.push({...this});
|
||||
}
|
||||
|
||||
drawExts(gfx: Graphics, position: Vec3, exts: Vec2) {
|
||||
if (this.fill instanceof Texture) {
|
||||
this.data = [
|
||||
position.x, position.y, position.z, 0, 0, 0, 0, 0, 0,
|
||||
position.x + exts.x, position.y, position.z, 0, 0, 0, 0, -1, 0,
|
||||
position.x, position.y + exts.y, position.z, 0, 0, 0, 0, 0, -1,
|
||||
|
||||
position.x + exts.x, position.y + exts.y, position.z, 0, 0, 0, 0, -1, -1,
|
||||
position.x + exts.x, position.y, position.z, 0, 0, 0, 0, -1, 0,
|
||||
position.x, position.y + exts.y, position.z, 0, 0, 0, 0, 0, -1,
|
||||
]
|
||||
} else {
|
||||
this.data = [
|
||||
position.x, position.y, position.z, this.fill[0], this.fill[1], this.fill[2], this.fill[3], 0, 0,
|
||||
position.x + exts.x, position.y, position.z, this.fill[0], this.fill[1], this.fill[2], this.fill[3], 0, 0,
|
||||
position.x, position.y + exts.y, position.z, this.fill[0], this.fill[1], this.fill[2], this.fill[3], 0, 0,
|
||||
|
||||
position.x + exts.x, position.y + exts.y, position.z, this.fill[0], this.fill[1], this.fill[2], this.fill[3], 0, 0,
|
||||
position.x + exts.x, position.y, position.z, this.fill[0], this.fill[1], this.fill[2], this.fill[3], 0, 0,
|
||||
position.x, position.y + exts.y, position.z, this.fill[0], this.fill[1], this.fill[2], this.fill[3], 0, 0,
|
||||
]
|
||||
}
|
||||
|
||||
this.vertexStride = 9;
|
||||
this.stride = this.vertexStride * 4
|
||||
commit(gfx: Graphics) {
|
||||
gfx.toRender.push(this);
|
||||
}
|
||||
|
||||
draw(corners: [Vec3, Vec3, Vec3, Vec3], fill: TileFillament) {
|
||||
if (fill instanceof Sprite) {
|
||||
let uvs = (Assets.assets.get("sprites") as Spritesheet).getUVs(fill.id);
|
||||
|
||||
this.data.push([
|
||||
corners[0].x, corners[0].y, corners[0].z, 0, 0, 0, 0, uvs[0].x, uvs[0].y, 1,
|
||||
corners[1].x, corners[1].y, corners[1].z, 0, 0, 0, 0, uvs[1].x, uvs[1].y, 1,
|
||||
corners[3].x, corners[3].y, corners[3].z, 0, 0, 0, 0, uvs[3].x, uvs[3].y, 1,
|
||||
|
||||
corners[2].x, corners[2].y, corners[2].z, 0, 0, 0, 0, uvs[2].x, uvs[2].y, 1,
|
||||
corners[1].x, corners[1].y, corners[1].z, 0, 0, 0, 0, uvs[1].x, uvs[1].y, 1,
|
||||
corners[3].x, corners[3].y, corners[3].z, 0, 0, 0, 0, uvs[3].x, uvs[3].y, 1,
|
||||
]);
|
||||
} else {
|
||||
let color = fill;
|
||||
|
||||
this.data.push([
|
||||
corners[0].x, corners[0].y, corners[0].z, color[0], color[1], color[2], color[3], 0, 0, 0,
|
||||
corners[1].x, corners[1].y, corners[1].z, color[0], color[1], color[2], color[3], 0, 0, 0,
|
||||
corners[3].x, corners[3].y, corners[3].z, color[0], color[1], color[2], color[3], 0, 0, 0,
|
||||
|
||||
corners[2].x, corners[2].y, corners[2].z, color[0], color[1], color[2], color[3], 0, 0, 0,
|
||||
corners[1].x, corners[1].y, corners[1].z, color[0], color[1], color[2], color[3], 0, 0, 0,
|
||||
corners[3].x, corners[3].y, corners[3].z, color[0], color[1], color[2], color[3], 0, 0, 0,
|
||||
]);
|
||||
}
|
||||
}
|
||||
|
||||
drawExts(position: Vec3, exts: Vec2, fill: TileFillament) {
|
||||
if (fill instanceof Sprite) {
|
||||
let uvs = (Assets.assets.get("sprites") as Spritesheet).getUVs(fill.id);
|
||||
|
||||
this.data.push([
|
||||
position.x, position.y, position.z, 0, 0, 0, 0, uvs[0].x, uvs[0].y, 1,
|
||||
position.x + exts.x, position.y, position.z, 0, 0, 0, 0, uvs[1].x, uvs[1].y, 1,
|
||||
position.x, position.y + exts.y, position.z, 0, 0, 0, 0, uvs[3].x, uvs[3].y, 1,
|
||||
|
||||
position.x + exts.x, position.y + exts.y, position.z, 0, 0, 0, 0, uvs[2].x, uvs[2].y, 1,
|
||||
position.x + exts.x, position.y, position.z, 0, 0, 0, 0, uvs[1].x, uvs[1].y, 1,
|
||||
position.x, position.y + exts.y, position.z, 0, 0, 0, 0, uvs[3].x, uvs[3].y, 1,
|
||||
]);
|
||||
} else {
|
||||
let color = fill;
|
||||
|
||||
this.data.push([
|
||||
position.x, position.y, position.z, color[0], color[1], color[2], color[3], 0, 0,
|
||||
position.x + exts.x, position.y, position.z, color[0], color[1], color[2], color[3], 0, 0,
|
||||
position.x, position.y + exts.y, position.z, color[0], color[1], color[2], color[3], 0, 0,
|
||||
|
||||
position.x + exts.x, position.y + exts.y, position.z, color[0], color[1], color[2], color[3], 0, 0,
|
||||
position.x + exts.x, position.y, position.z, color[0], color[1], color[2], color[3], 0, 0,
|
||||
position.x, position.y + exts.y, position.z, color[0], color[1], color[2], color[3], 0, 0,
|
||||
]);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
export function drawIsometricCube(gfx: Graphics, position: Vec3, exts: Vec3, color: TileFill, edge: TileEdge) {
|
||||
export function drawIsometricCube(position: Vec3, exts: Vec3, r: Rectangle, fill: TileFill, edge: TileEdge) {
|
||||
let points = [
|
||||
// Left Top
|
||||
position,
|
||||
|
@ -122,49 +107,40 @@ export function drawIsometricCube(gfx: Graphics, position: Vec3, exts: Vec3, col
|
|||
new Vec3(position.x + 0.5 * exts.x, position.y - 0.5 * exts.y, position.z + 0.25 * exts.z),
|
||||
];
|
||||
|
||||
let r = new Rectangle(color.top, [
|
||||
DrawTag.ISO,
|
||||
]);
|
||||
|
||||
// Top
|
||||
r.draw(
|
||||
gfx,
|
||||
[
|
||||
points[0],
|
||||
points[1],
|
||||
points[3],
|
||||
points[2],
|
||||
],
|
||||
fill.top
|
||||
);
|
||||
|
||||
// Right Edge
|
||||
|
||||
if (edge == TileEdge.Right || edge == TileEdge.Both) {
|
||||
r.fill = color.right;
|
||||
|
||||
r.draw(
|
||||
gfx,
|
||||
[
|
||||
points[3],
|
||||
points[2],
|
||||
points[4],
|
||||
points[5],
|
||||
]
|
||||
],
|
||||
fill.right
|
||||
);
|
||||
}
|
||||
|
||||
// Left Edge
|
||||
if (edge == TileEdge.Left || edge == TileEdge.Both) {
|
||||
r.fill = color.left;
|
||||
|
||||
r.draw(
|
||||
gfx,
|
||||
[
|
||||
points[0],
|
||||
points[2],
|
||||
points[4],
|
||||
points[6],
|
||||
]
|
||||
],
|
||||
fill.left
|
||||
);
|
||||
}
|
||||
}
|
||||
|
@ -173,6 +149,9 @@ export function drawIsometricGrid(gfx: Graphics, grid: Grid) {
|
|||
let position = {...grid.position} as Vec3;
|
||||
let exts = new Vec3(grid.tileSize, grid.tileSize, 0);
|
||||
let tileCoord = new Vec3(0, 0, 0);
|
||||
let rect = new Rectangle([
|
||||
DrawTag.ISO,
|
||||
]);
|
||||
|
||||
// TODO: Optimize this
|
||||
// 1. Grid based occlusion culling
|
||||
|
@ -193,7 +172,13 @@ export function drawIsometricGrid(gfx: Graphics, grid: Grid) {
|
|||
continue;
|
||||
}
|
||||
|
||||
drawIsometricCube(gfx, new Vec3(position.x - grid.tileSize / 2 * k, position.y + grid.tileSize / 2 * k, position.z), exts, tile.fill, tile.edge);
|
||||
drawIsometricCube(
|
||||
new Vec3(position.x - grid.tileSize / 2 * k, position.y + grid.tileSize / 2 * k, position.z),
|
||||
exts,
|
||||
rect,
|
||||
tile.fill,
|
||||
tile.edge
|
||||
);
|
||||
|
||||
position.x += grid.tileSize;
|
||||
}
|
||||
|
@ -202,4 +187,6 @@ export function drawIsometricGrid(gfx: Graphics, grid: Grid) {
|
|||
}
|
||||
position.y = grid.position.y;
|
||||
}
|
||||
|
||||
rect.commit(gfx);
|
||||
}
|
||||
|
|
|
@ -92,15 +92,16 @@ export class Graphics {
|
|||
}
|
||||
draw() {
|
||||
for (let o of this.toRender) {
|
||||
const data = o.data.flat();
|
||||
this.ctx.bindBuffer(this.ctx.ARRAY_BUFFER, this.vbo);
|
||||
this.ctx.bufferData(this.ctx.ARRAY_BUFFER, new Float32Array(o.data), this.ctx.STATIC_DRAW);
|
||||
this.ctx.bufferData(this.ctx.ARRAY_BUFFER, new Float32Array(data), this.ctx.STATIC_DRAW);
|
||||
let aid = 0;
|
||||
for (let a of o.attribs) {
|
||||
let attr = this.getAttribute(a);
|
||||
if (!attr.formatted)
|
||||
throw new Error("Tried to use unformatted attribute!");
|
||||
this.ctx.enableVertexAttribArray(attr.loc);
|
||||
this.ctx.vertexAttribPointer(attr.loc, attr.size, attr.type, attr.normalized, o.stride, aid * 4);
|
||||
this.ctx.vertexAttribPointer(attr.loc, attr.size, attr.type, attr.normalized, o.vertexSize * 4, aid * 4);
|
||||
aid += attr.size;
|
||||
}
|
||||
// Generalize the tag uniforms aka. don't hard code them
|
||||
|
@ -112,15 +113,9 @@ export class Graphics {
|
|||
}
|
||||
}
|
||||
}
|
||||
if (o.fill instanceof Texture) {
|
||||
this.ctx.uniform1i(this.getUniform("u_isTex"), 1);
|
||||
o.fill.bind(this);
|
||||
}
|
||||
this.ctx.drawArrays(this.ctx.TRIANGLES, 0, o.data.length / o.vertexStride);
|
||||
if (o.fill instanceof Texture) {
|
||||
this.ctx.uniform1i(this.getUniform("u_isTex"), 0);
|
||||
o.fill.unbind(this);
|
||||
}
|
||||
o.sprites?.bind(this);
|
||||
this.ctx.drawArrays(this.ctx.TRIANGLES, 0, data.length / o.vertexSize);
|
||||
o.sprites?.unbind(this);
|
||||
for (let t of o.tags) {
|
||||
switch (t) {
|
||||
case DrawTag.ISO: {
|
||||
|
@ -183,6 +178,48 @@ export class Texture {
|
|||
gfx.ctx.bindTexture(gfx.ctx.TEXTURE_2D, null);
|
||||
}
|
||||
}
|
||||
export class Sprite {
|
||||
id = 0;
|
||||
constructor(id) {
|
||||
this.id = id;
|
||||
}
|
||||
static id(id) {
|
||||
return new Sprite(id);
|
||||
}
|
||||
static tile(id) {
|
||||
let s = new Sprite(id);
|
||||
return {
|
||||
left: s,
|
||||
top: s,
|
||||
right: s,
|
||||
};
|
||||
}
|
||||
}
|
||||
;
|
||||
export class Spritesheet {
|
||||
texture; // Texture is a horizontal spritesheet
|
||||
spriteSize; // width and height of one sprite
|
||||
spriteCount; // number of sprites
|
||||
constructor(texture, spriteSize) {
|
||||
this.texture = texture;
|
||||
this.spriteSize = spriteSize;
|
||||
this.spriteCount = texture.width / spriteSize.x;
|
||||
}
|
||||
getUVs(id) {
|
||||
return [
|
||||
new Vec2((this.spriteSize.x * id) / this.texture.width, 0),
|
||||
new Vec2((this.spriteSize.x * (id + 1)) / this.texture.width, 0),
|
||||
new Vec2((this.spriteSize.x * (id + 1)) / this.texture.width, -1),
|
||||
new Vec2((this.spriteSize.x * id) / this.texture.width, -1),
|
||||
];
|
||||
}
|
||||
bind(gfx) {
|
||||
this.texture.bind(gfx);
|
||||
}
|
||||
unbind(gfx) {
|
||||
this.texture.unbind(gfx);
|
||||
}
|
||||
}
|
||||
async function loadTexture(path) {
|
||||
return new Promise(resolve => {
|
||||
const img = new Image();
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
import * as Assets from "./assets.js";
|
||||
import {Vec2, Vec3, Vec4} from "./common.js";
|
||||
import { TileFillament, TileFill } from "./world.js";
|
||||
|
||||
export function fullscreenCanvas(gfx: Graphics, id: string) {
|
||||
const canvas = document.getElementById(id) as HTMLCanvasElement;
|
||||
|
@ -57,13 +57,13 @@ export enum DrawTag {
|
|||
}
|
||||
|
||||
export interface Drawable {
|
||||
fill: Texture | Assets.Color;
|
||||
attribs: string[];
|
||||
tags: Array<DrawTag>;
|
||||
|
||||
data: Array<number>;
|
||||
vertexStride: number;
|
||||
stride: number;
|
||||
data: number[][];
|
||||
vertexSize: number;
|
||||
|
||||
sprites: Spritesheet | undefined;
|
||||
}
|
||||
|
||||
export class Graphics {
|
||||
|
@ -131,8 +131,10 @@ export class Graphics {
|
|||
|
||||
draw() {
|
||||
for (let o of this.toRender) {
|
||||
const data = o.data.flat();
|
||||
|
||||
this.ctx.bindBuffer(this.ctx.ARRAY_BUFFER, this.vbo);
|
||||
this.ctx.bufferData(this.ctx.ARRAY_BUFFER, new Float32Array(o.data), this.ctx.STATIC_DRAW);
|
||||
this.ctx.bufferData(this.ctx.ARRAY_BUFFER, new Float32Array(data), this.ctx.STATIC_DRAW);
|
||||
|
||||
let aid = 0;
|
||||
for (let a of o.attribs) {
|
||||
|
@ -141,7 +143,7 @@ export class Graphics {
|
|||
throw new Error("Tried to use unformatted attribute!");
|
||||
|
||||
this.ctx.enableVertexAttribArray(attr.loc);
|
||||
this.ctx.vertexAttribPointer(attr.loc, attr.size, attr.type, attr.normalized, o.stride, aid * 4);
|
||||
this.ctx.vertexAttribPointer(attr.loc, attr.size, attr.type, attr.normalized, o.vertexSize * 4, aid * 4);
|
||||
aid += attr.size;
|
||||
}
|
||||
|
||||
|
@ -154,20 +156,12 @@ export class Graphics {
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
o.sprites?.bind(this);
|
||||
|
||||
this.ctx.drawArrays(this.ctx.TRIANGLES, 0, data.length / o.vertexSize);
|
||||
|
||||
if (o.fill instanceof Texture)
|
||||
{
|
||||
this.ctx.uniform1i(this.getUniform("u_isTex"), 1);
|
||||
o.fill.bind(this);
|
||||
}
|
||||
|
||||
this.ctx.drawArrays(this.ctx.TRIANGLES, 0, o.data.length / o.vertexStride);
|
||||
|
||||
if (o.fill instanceof Texture)
|
||||
{
|
||||
this.ctx.uniform1i(this.getUniform("u_isTex"), 0);
|
||||
o.fill.unbind(this);
|
||||
}
|
||||
o.sprites?.unbind(this);
|
||||
|
||||
for (let t of o.tags) {
|
||||
switch (t) {
|
||||
|
@ -177,7 +171,6 @@ export class Graphics {
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
// TODO: Maybe add persistent rendering?
|
||||
|
@ -251,6 +244,59 @@ export class Texture {
|
|||
}
|
||||
}
|
||||
|
||||
export type SpriteId = number;
|
||||
|
||||
export class Sprite {
|
||||
id: SpriteId = 0;
|
||||
|
||||
private constructor(id: SpriteId) {
|
||||
this.id = id;
|
||||
}
|
||||
|
||||
static id(id: SpriteId): Sprite {
|
||||
return new Sprite(id);
|
||||
}
|
||||
|
||||
static tile(id: SpriteId): TileFill {
|
||||
let s = new Sprite(id);
|
||||
|
||||
return {
|
||||
left: s,
|
||||
top: s,
|
||||
right: s,
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
export class Spritesheet {
|
||||
texture: Texture; // Texture is a horizontal spritesheet
|
||||
spriteSize: Vec2; // width and height of one sprite
|
||||
spriteCount: number; // number of sprites
|
||||
|
||||
constructor(texture: Texture, spriteSize: Vec2) {
|
||||
this.texture = texture;
|
||||
this.spriteSize = spriteSize;
|
||||
this.spriteCount = texture.width / spriteSize.x;
|
||||
}
|
||||
|
||||
getUVs(id: number): [Vec2, Vec2, Vec2, Vec2] {
|
||||
return [
|
||||
new Vec2((this.spriteSize.x * id) / this.texture.width, 0),
|
||||
new Vec2((this.spriteSize.x * (id + 1)) / this.texture.width, 0),
|
||||
new Vec2((this.spriteSize.x * (id + 1)) / this.texture.width, -1),
|
||||
new Vec2((this.spriteSize.x * id) / this.texture.width, -1),
|
||||
];
|
||||
}
|
||||
|
||||
bind(gfx: Graphics) {
|
||||
this.texture.bind(gfx);
|
||||
}
|
||||
|
||||
unbind(gfx: Graphics) {
|
||||
this.texture.unbind(gfx);
|
||||
}
|
||||
}
|
||||
|
||||
async function loadTexture(path: string): Promise<HTMLImageElement> {
|
||||
return new Promise(resolve => {
|
||||
const img = new Image();
|
||||
|
|
|
@ -1,22 +1,21 @@
|
|||
import { initializeContext, Vec3, Mat4, Vec4, Vec2 } from "./common.js";
|
||||
import { Graphics, fullscreenCanvas, Camera } from "./graphics.js";
|
||||
import { Graphics, fullscreenCanvas, Camera, Sprite } 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 { 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 = 1) in vec3 a_tex;
|
||||
layout(location = 2) in vec4 a_color;
|
||||
|
||||
out vec4 v_color;
|
||||
out vec2 v_tex_position;
|
||||
out vec3 v_tex;
|
||||
|
||||
uniform mat4 u_matrix;
|
||||
uniform bool u_isIso;
|
||||
uniform bool u_isTex;
|
||||
|
||||
mat4 Iso = mat4(
|
||||
1, -1, 0, 0,
|
||||
|
@ -38,11 +37,8 @@ const vertexShader = `#version 300 es
|
|||
|
||||
gl_Position = orthographic;
|
||||
|
||||
if (u_isTex) {
|
||||
v_tex_position = a_tex_position;
|
||||
} else {
|
||||
v_color = a_color;
|
||||
}
|
||||
v_tex = a_tex;
|
||||
v_color = a_color;
|
||||
}
|
||||
`;
|
||||
const fragmentShader = `#version 300 es
|
||||
|
@ -50,15 +46,14 @@ const fragmentShader = `#version 300 es
|
|||
precision highp float;
|
||||
|
||||
in vec4 v_color;
|
||||
in vec2 v_tex_position;
|
||||
in vec3 v_tex;
|
||||
out vec4 outColor;
|
||||
|
||||
uniform sampler2D u_texture;
|
||||
uniform bool u_isTex;
|
||||
|
||||
void main() {
|
||||
if (u_isTex) {
|
||||
outColor = texture(u_texture, v_tex_position);
|
||||
if (v_tex.z == 1.0) {
|
||||
outColor = texture(u_texture, v_tex.xy);
|
||||
} else {
|
||||
outColor = v_color;
|
||||
}
|
||||
|
@ -131,23 +126,21 @@ function addDefaultKeybinds(input, camera) {
|
|||
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);
|
||||
a = gfx.createAttribute("a_tex");
|
||||
a.format(3, 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"),
|
||||
top: Sprite.id(0),
|
||||
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));
|
||||
tree(grid, new Vec2(5, 5));
|
||||
//for (let i = 0; i < 10; i++) {
|
||||
// tree(grid, new Vec2(Math.floor(Math.random() * size - 1), Math.floor(Math.random() * size - 1)));
|
||||
//}
|
||||
|
|
|
@ -1,24 +1,23 @@
|
|||
import { initializeContext, Vec3, Mat4, Vec4, Vec2 } from "./common.js";
|
||||
import { Graphics, fullscreenCanvas, Camera, DrawTag } from "./graphics.js";
|
||||
import { Graphics, fullscreenCanvas, Camera, Sprite } from "./graphics.js";
|
||||
import * as drawing from "./draw.js";
|
||||
import * as wasm from "./wasm.js";
|
||||
import { Input } from "./input.js";
|
||||
import {bush, Grid, Tile, TileEdge, tree} from "./world.js";
|
||||
import {Grid, Tile, TileEdge, 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 = 1) in vec3 a_tex;
|
||||
layout(location = 2) in vec4 a_color;
|
||||
|
||||
out vec4 v_color;
|
||||
out vec2 v_tex_position;
|
||||
out vec3 v_tex;
|
||||
|
||||
uniform mat4 u_matrix;
|
||||
uniform bool u_isIso;
|
||||
uniform bool u_isTex;
|
||||
|
||||
mat4 Iso = mat4(
|
||||
1, -1, 0, 0,
|
||||
|
@ -40,11 +39,8 @@ const vertexShader =
|
|||
|
||||
gl_Position = orthographic;
|
||||
|
||||
if (u_isTex) {
|
||||
v_tex_position = a_tex_position;
|
||||
} else {
|
||||
v_color = a_color;
|
||||
}
|
||||
v_tex = a_tex;
|
||||
v_color = a_color;
|
||||
}
|
||||
`;
|
||||
|
||||
|
@ -54,15 +50,14 @@ const fragmentShader =
|
|||
precision highp float;
|
||||
|
||||
in vec4 v_color;
|
||||
in vec2 v_tex_position;
|
||||
in vec3 v_tex;
|
||||
out vec4 outColor;
|
||||
|
||||
uniform sampler2D u_texture;
|
||||
uniform bool u_isTex;
|
||||
|
||||
void main() {
|
||||
if (u_isTex) {
|
||||
outColor = texture(u_texture, v_tex_position);
|
||||
if (v_tex.z == 1.0) {
|
||||
outColor = texture(u_texture, v_tex.xy);
|
||||
} else {
|
||||
outColor = v_color;
|
||||
}
|
||||
|
@ -178,12 +173,11 @@ function addDefaultKeybinds(input: Input, camera: Camera) {
|
|||
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)
|
||||
a = gfx.createAttribute("a_tex");
|
||||
a.format(3, 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));
|
||||
|
||||
|
@ -194,13 +188,11 @@ function addDefaultKeybinds(input: Input, camera: Camera) {
|
|||
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"),
|
||||
top: Sprite.id(0),
|
||||
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));
|
||||
tree(grid, new Vec2(5, 5));
|
||||
//for (let i = 0; i < 10; i++) {
|
||||
// tree(grid, new Vec2(Math.floor(Math.random() * size - 1), Math.floor(Math.random() * size - 1)));
|
||||
//}
|
||||
|
@ -211,7 +203,7 @@ function addDefaultKeybinds(input: Input, camera: Camera) {
|
|||
const frame = (timestamp: number) => {
|
||||
const deltaTime = (timestamp - prevTimestamp)/1000;
|
||||
prevTimestamp = timestamp;
|
||||
|
||||
|
||||
fullscreenCanvas(gfx, "game");
|
||||
draw(gfx, camera, deltaTime, grid);
|
||||
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
import * as Assets from "./assets.js";
|
||||
import { Vec3 } from "./common.js";
|
||||
import { Sprite } from "./graphics.js";
|
||||
export var TileEdge;
|
||||
(function (TileEdge) {
|
||||
TileEdge[TileEdge["None"] = 0] = "None";
|
||||
|
@ -73,25 +73,28 @@ export class Grid {
|
|||
}
|
||||
}
|
||||
export function tree(grid, position) {
|
||||
grid.setTile(new Tile(Assets.AssetToTileFill("log"), TileEdge.Both), new Vec3(position.x, position.y, 1));
|
||||
grid.setTile(new Tile(Assets.AssetToTileFill("log"), TileEdge.Both), new Vec3(position.x, position.y, 2));
|
||||
grid.setTile(new Tile(Assets.AssetToTileFill("log"), TileEdge.Both), new Vec3(position.x, position.y, 3));
|
||||
grid.setTile(new Tile(Assets.AssetToTileFill("log"), TileEdge.Both), new Vec3(position.x, position.y, 4));
|
||||
grid.setTile(new Tile(Assets.AssetToTileFill("leaves"), TileEdge.None), new Vec3(position.x, position.y, 4));
|
||||
grid.setTile(new Tile(Assets.AssetToTileFill("leaves"), TileEdge.Both), new Vec3(position.x, position.y + 1, 4));
|
||||
grid.setTile(new Tile(Assets.AssetToTileFill("leaves"), TileEdge.Both), new Vec3(position.x, position.y + 1, 5));
|
||||
grid.setTile(new Tile(Assets.AssetToTileFill("leaves"), TileEdge.Both), new Vec3(position.x, position.y, 5));
|
||||
grid.setTile(new Tile(Assets.AssetToTileFill("leaves"), TileEdge.Both), new Vec3(position.x + 1, position.y, 4));
|
||||
grid.setTile(new Tile(Assets.AssetToTileFill("leaves"), TileEdge.Both), new Vec3(position.x + 1, position.y, 5));
|
||||
grid.setTile(new Tile(Assets.AssetToTileFill("leaves"), TileEdge.Both), new Vec3(position.x + 1, position.y + 1, 4));
|
||||
grid.setTile(new Tile(Assets.AssetToTileFill("leaves"), TileEdge.Both), new Vec3(position.x + 1, position.y + 1, 5));
|
||||
let log = Sprite.tile(2);
|
||||
let leaves = Sprite.tile(1);
|
||||
grid.setTile(new Tile(log, TileEdge.Both), new Vec3(position.x, position.y, 1));
|
||||
grid.setTile(new Tile(log, TileEdge.Both), new Vec3(position.x, position.y, 2));
|
||||
grid.setTile(new Tile(log, TileEdge.Both), new Vec3(position.x, position.y, 3));
|
||||
grid.setTile(new Tile(log, TileEdge.Both), new Vec3(position.x, position.y, 4));
|
||||
grid.setTile(new Tile(log, TileEdge.None), new Vec3(position.x, position.y, 4));
|
||||
grid.setTile(new Tile(leaves, TileEdge.Both), new Vec3(position.x, position.y + 1, 4));
|
||||
grid.setTile(new Tile(leaves, TileEdge.Both), new Vec3(position.x, position.y + 1, 5));
|
||||
grid.setTile(new Tile(leaves, TileEdge.Both), new Vec3(position.x, position.y, 5));
|
||||
grid.setTile(new Tile(leaves, TileEdge.Both), new Vec3(position.x + 1, position.y, 4));
|
||||
grid.setTile(new Tile(leaves, TileEdge.Both), new Vec3(position.x + 1, position.y, 5));
|
||||
grid.setTile(new Tile(leaves, TileEdge.Both), new Vec3(position.x + 1, position.y + 1, 4));
|
||||
grid.setTile(new Tile(leaves, TileEdge.Both), new Vec3(position.x + 1, position.y + 1, 5));
|
||||
}
|
||||
export function bush(grid, position) {
|
||||
grid.setTile(new Tile(Assets.AssetToTileFill("leaves"), TileEdge.Both), position.extend(1));
|
||||
grid.setTile(new Tile(Assets.AssetToTileFill("leaves"), TileEdge.Both), new Vec3(position.x + 1, position.y, 1));
|
||||
grid.setTile(new Tile(Assets.AssetToTileFill("leaves"), TileEdge.Both), new Vec3(position.x, position.y + 1, 1));
|
||||
grid.setTile(new Tile(Assets.AssetToTileFill("leaves"), TileEdge.Both), new Vec3(position.x + 1, position.y + 1, 1));
|
||||
grid.setTile(new Tile(Assets.AssetToTileFill("leaves"), TileEdge.Both), position.extend(2));
|
||||
grid.setTile(new Tile(Assets.AssetToTileFill("leaves"), TileEdge.Both), new Vec3(position.x + 1, position.y, 2));
|
||||
grid.setTile(new Tile(Assets.AssetToTileFill("leaves"), TileEdge.Both), new Vec3(position.x, position.y + 1, 2));
|
||||
let leaves = Sprite.tile(1);
|
||||
grid.setTile(new Tile(leaves, TileEdge.Both), position.extend(1));
|
||||
grid.setTile(new Tile(leaves, TileEdge.Both), new Vec3(position.x + 1, position.y, 1));
|
||||
grid.setTile(new Tile(leaves, TileEdge.Both), new Vec3(position.x, position.y + 1, 1));
|
||||
grid.setTile(new Tile(leaves, TileEdge.Both), new Vec3(position.x + 1, position.y + 1, 1));
|
||||
grid.setTile(new Tile(leaves, TileEdge.Both), position.extend(2));
|
||||
grid.setTile(new Tile(leaves, TileEdge.Both), new Vec3(position.x + 1, position.y, 2));
|
||||
grid.setTile(new Tile(leaves, TileEdge.Both), new Vec3(position.x, position.y + 1, 2));
|
||||
}
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
import * as Assets from "./assets.js";
|
||||
import {Vec2, Vec3} from "./common.js";
|
||||
import {Texture} from "./graphics.js";
|
||||
import {Sprite} from "./graphics.js";
|
||||
|
||||
export enum TileEdge {
|
||||
None,
|
||||
|
@ -9,8 +9,12 @@ export enum TileEdge {
|
|||
Both,
|
||||
}
|
||||
|
||||
export type TileFillament = Texture | Assets.Color;
|
||||
export type TileFill = { left: TileFillament, top: TileFillament, right: TileFillament };
|
||||
export type TileFillament = Sprite | Assets.Color;
|
||||
export type TileFill = {
|
||||
right: TileFillament
|
||||
left: TileFillament,
|
||||
top: TileFillament,
|
||||
};
|
||||
|
||||
export class Tile {
|
||||
fill: TileFill = {
|
||||
|
@ -31,8 +35,8 @@ export class Tile {
|
|||
|
||||
export function ColorToTile(c: Assets.Color) {
|
||||
return {
|
||||
left: c,
|
||||
top: c,
|
||||
left: c,
|
||||
top: c,
|
||||
right: c,
|
||||
};
|
||||
}
|
||||
|
@ -96,27 +100,32 @@ export class Grid {
|
|||
}
|
||||
|
||||
export function tree(grid: Grid, position: Vec2) {
|
||||
grid.setTile(new Tile(Assets.AssetToTileFill("log"), TileEdge.Both), new Vec3(position.x, position.y, 1));
|
||||
grid.setTile(new Tile(Assets.AssetToTileFill("log"), TileEdge.Both), new Vec3(position.x, position.y, 2));
|
||||
grid.setTile(new Tile(Assets.AssetToTileFill("log"), TileEdge.Both), new Vec3(position.x, position.y, 3));
|
||||
grid.setTile(new Tile(Assets.AssetToTileFill("log"), TileEdge.Both), new Vec3(position.x, position.y, 4));
|
||||
grid.setTile(new Tile(Assets.AssetToTileFill("leaves"), TileEdge.None), new Vec3(position.x, position.y, 4));
|
||||
grid.setTile(new Tile(Assets.AssetToTileFill("leaves"), TileEdge.Both), new Vec3(position.x, position.y + 1, 4));
|
||||
grid.setTile(new Tile(Assets.AssetToTileFill("leaves"), TileEdge.Both), new Vec3(position.x, position.y + 1, 5));
|
||||
grid.setTile(new Tile(Assets.AssetToTileFill("leaves"), TileEdge.Both), new Vec3(position.x, position.y, 5));
|
||||
grid.setTile(new Tile(Assets.AssetToTileFill("leaves"), TileEdge.Both), new Vec3(position.x + 1, position.y, 4));
|
||||
grid.setTile(new Tile(Assets.AssetToTileFill("leaves"), TileEdge.Both), new Vec3(position.x + 1, position.y, 5));
|
||||
grid.setTile(new Tile(Assets.AssetToTileFill("leaves"), TileEdge.Both), new Vec3(position.x + 1, position.y + 1, 4));
|
||||
grid.setTile(new Tile(Assets.AssetToTileFill("leaves"), TileEdge.Both), new Vec3(position.x + 1, position.y + 1, 5));
|
||||
let log = Sprite.tile(2);
|
||||
let leaves = Sprite.tile(1);
|
||||
|
||||
grid.setTile(new Tile(log, TileEdge.Both), new Vec3(position.x, position.y, 1));
|
||||
grid.setTile(new Tile(log, TileEdge.Both), new Vec3(position.x, position.y, 2));
|
||||
grid.setTile(new Tile(log, TileEdge.Both), new Vec3(position.x, position.y, 3));
|
||||
grid.setTile(new Tile(log, TileEdge.Both), new Vec3(position.x, position.y, 4));
|
||||
grid.setTile(new Tile(log, TileEdge.None), new Vec3(position.x, position.y, 4));
|
||||
grid.setTile(new Tile(leaves, TileEdge.Both), new Vec3(position.x, position.y + 1, 4));
|
||||
grid.setTile(new Tile(leaves, TileEdge.Both), new Vec3(position.x, position.y + 1, 5));
|
||||
grid.setTile(new Tile(leaves, TileEdge.Both), new Vec3(position.x, position.y, 5));
|
||||
grid.setTile(new Tile(leaves, TileEdge.Both), new Vec3(position.x + 1, position.y, 4));
|
||||
grid.setTile(new Tile(leaves, TileEdge.Both), new Vec3(position.x + 1, position.y, 5));
|
||||
grid.setTile(new Tile(leaves, TileEdge.Both), new Vec3(position.x + 1, position.y + 1, 4));
|
||||
grid.setTile(new Tile(leaves, TileEdge.Both), new Vec3(position.x + 1, position.y + 1, 5));
|
||||
}
|
||||
|
||||
export function bush(grid: Grid, position: Vec2) {
|
||||
grid.setTile(new Tile(Assets.AssetToTileFill("leaves"), TileEdge.Both), position.extend(1));
|
||||
grid.setTile(new Tile(Assets.AssetToTileFill("leaves"), TileEdge.Both), new Vec3(position.x + 1, position.y, 1));
|
||||
grid.setTile(new Tile(Assets.AssetToTileFill("leaves"), TileEdge.Both), new Vec3(position.x, position.y + 1, 1));
|
||||
grid.setTile(new Tile(Assets.AssetToTileFill("leaves"), TileEdge.Both), new Vec3(position.x + 1, position.y + 1, 1));
|
||||
let leaves = Sprite.tile(1);
|
||||
|
||||
grid.setTile(new Tile(Assets.AssetToTileFill("leaves"), TileEdge.Both), position.extend(2));
|
||||
grid.setTile(new Tile(Assets.AssetToTileFill("leaves"), TileEdge.Both), new Vec3(position.x + 1, position.y, 2));
|
||||
grid.setTile(new Tile(Assets.AssetToTileFill("leaves"), TileEdge.Both), new Vec3(position.x, position.y + 1, 2));
|
||||
grid.setTile(new Tile(leaves, TileEdge.Both), position.extend(1));
|
||||
grid.setTile(new Tile(leaves, TileEdge.Both), new Vec3(position.x + 1, position.y, 1));
|
||||
grid.setTile(new Tile(leaves, TileEdge.Both), new Vec3(position.x, position.y + 1, 1));
|
||||
grid.setTile(new Tile(leaves, TileEdge.Both), new Vec3(position.x + 1, position.y + 1, 1));
|
||||
|
||||
grid.setTile(new Tile(leaves, TileEdge.Both), position.extend(2));
|
||||
grid.setTile(new Tile(leaves, TileEdge.Both), new Vec3(position.x + 1, position.y, 2));
|
||||
grid.setTile(new Tile(leaves, TileEdge.Both), new Vec3(position.x, position.y + 1, 2));
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue