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