Includes a demo scene, some of the military-themed macros, and then selections of entities of varying sizestags/v0.1.0
| @@ -65,6 +65,13 @@ | |||||
| <span class="menubar-group" id="spawners"> | <span class="menubar-group" id="spawners"> | ||||
| </span> | </span> | ||||
| </span> | |||||
| <span class="menubar-group" id="scenes"> | |||||
| <button id="load-scene">Load</button> | |||||
| <select id="scene-choices"> | |||||
| </select> | |||||
| </span> | |||||
| <span class="menubar-group"> | <span class="menubar-group"> | ||||
| <button id="open-help">Help</button> | <button id="open-help">Help</button> | ||||
| </span> | </span> | ||||
| @@ -573,6 +573,18 @@ function updateViewOptions(entity, view, changed) { | |||||
| }); | }); | ||||
| } | } | ||||
| function getSortedEntities() { | |||||
| return Object.keys(entities).sort((a, b) => { | |||||
| const entA = entities[a]; | |||||
| const entB = entities[b]; | |||||
| const viewA = entA.view; | |||||
| const viewB = entB.view; | |||||
| const heightA = entA.views[viewA].height.to("meter").value; | |||||
| const heightB = entB.views[viewB].height.to("meter").value; | |||||
| return heightA - heightB; | |||||
| }); | |||||
| } | |||||
| function clearViewOptions() { | function clearViewOptions() { | ||||
| const holder = document.querySelector("#options-view"); | const holder = document.querySelector("#options-view"); | ||||
| @@ -648,7 +660,7 @@ function arrangeEntities(order) { | |||||
| order.forEach(key => { | order.forEach(key => { | ||||
| document.querySelector("#entity-" + key).dataset.x = x; | document.querySelector("#entity-" + key).dataset.x = x; | ||||
| x += 0.8 / order.length | |||||
| x += 0.8 / (order.length - 1); | |||||
| }); | }); | ||||
| updateSizes(); | updateSizes(); | ||||
| @@ -740,6 +752,20 @@ function displayEntity(entity, view, x, y) { | |||||
| document.addEventListener("DOMContentLoaded", () => { | document.addEventListener("DOMContentLoaded", () => { | ||||
| prepareEntities(); | prepareEntities(); | ||||
| const sceneChoices = document.querySelector("#scene-choices"); | |||||
| Object.entries(scenes).forEach(([id, scene]) => { | |||||
| const option = document.createElement("option"); | |||||
| option.innerText = id; | |||||
| option.value = id; | |||||
| sceneChoices.appendChild(option); | |||||
| }); | |||||
| document.querySelector("#load-scene").addEventListener("click", e => { | |||||
| const chosen = sceneChoices.value; | |||||
| removeAllEntities(); | |||||
| scenes[chosen](); | |||||
| }); | |||||
| entityX = document.querySelector("#entities").getBoundingClientRect().x; | entityX = document.querySelector("#entities").getBoundingClientRect().x; | ||||
| canvasWidth = document.querySelector("#display").clientWidth - 100; | canvasWidth = document.querySelector("#display").clientWidth - 100; | ||||
| canvasHeight = document.querySelector("#display").clientHeight - 50; | canvasHeight = document.querySelector("#display").clientHeight - 50; | ||||
| @@ -768,30 +794,7 @@ document.addEventListener("DOMContentLoaded", () => { | |||||
| unitSelector.appendChild(option); | unitSelector.appendChild(option); | ||||
| }); | }); | ||||
| const stuff = availableEntities.characters.map(x => x.constructor).filter(x => { | |||||
| const result = x(); | |||||
| return result.views[result.defaultView].height.toNumber("meters") < 1000; | |||||
| }) | |||||
| let x = 0.2; | |||||
| stuff.forEach(entity => { | |||||
| displayEntity(entity(), entity().defaultView, x, 1); | |||||
| x += 0.7 / stuff.length; | |||||
| }) | |||||
| const order = Object.keys(entities).sort((a, b) => { | |||||
| const entA = entities[a]; | |||||
| const entB = entities[b]; | |||||
| const viewA = entA.view; | |||||
| const viewB = entB.view; | |||||
| const heightA = entA.views[viewA].height.to("meter").value; | |||||
| const heightB = entB.views[viewB].height.to("meter").value; | |||||
| return heightA - heightB; | |||||
| }); | |||||
| arrangeEntities(order); | |||||
| scenes["Demo"](); | |||||
| fitWorld(); | fitWorld(); | ||||
| document.querySelector("#world").addEventListener("wheel", e => { | document.querySelector("#world").addEventListener("wheel", e => { | ||||
| @@ -1,6 +1,31 @@ | |||||
| const scenes = {}; | const scenes = {}; | ||||
| scenes["military"] = () => { | |||||
| scenes["Demo"] = () => { | |||||
| removeAllEntities(); | |||||
| let entity = availableEntitiesByName["Fen"].constructor(); | |||||
| displayEntity(entity, entity.defaultView, 0, 1); | |||||
| entity = availableEntitiesByName["Deerpuff"].constructor(); | |||||
| displayEntity(entity, entity.defaultView, 0, 1); | |||||
| entity = availableEntitiesByName["Sofia"].constructor(); | |||||
| entity.views[entity.view].height = entity.sizes[2].height; | |||||
| displayEntity(entity, entity.defaultView, 0, 1); | |||||
| entity = availableEntitiesByName["Vivian"].constructor(); | |||||
| entity.views[entity.view].height = entity.sizes[2].height; | |||||
| displayEntity(entity, entity.defaultView, 0, 1); | |||||
| arrangeEntities(getSortedEntities()); | |||||
| entity = availableEntitiesByName["Houston"].constructor(); | |||||
| displayEntity(entity, entity.defaultView, 0.5, 1); | |||||
| fitWorld(); | |||||
| } | |||||
| scenes["Military"] = () => { | |||||
| removeAllEntities(); | removeAllEntities(); | ||||
| let entity = availableEntitiesByName["Asana (Mech)"].constructor(); | let entity = availableEntitiesByName["Asana (Mech)"].constructor(); | ||||
| @@ -12,17 +37,37 @@ scenes["military"] = () => { | |||||
| entity = availableEntitiesByName["Leopard 2 Rev. 1"].constructor(); | entity = availableEntitiesByName["Leopard 2 Rev. 1"].constructor(); | ||||
| displayEntity(entity, entity.defaultView, 0, 1); | displayEntity(entity, entity.defaultView, 0, 1); | ||||
| entity = availableEntitiesByName["Asana"].constructor(); | |||||
| displayEntity(entity, entity.defaultView, 0, 1); | |||||
| const order = Object.keys(entities).sort((a, b) => { | |||||
| const entA = entities[a]; | |||||
| const entB = entities[b]; | |||||
| const viewA = document.querySelector("#entity-" + a).dataset.view; | |||||
| const viewB = document.querySelector("#entity-" + b).dataset.view; | |||||
| const heightA = entA.views[viewA].height.to("meter").value; | |||||
| const heightB = entB.views[viewB].height.to("meter").value; | |||||
| return heightA - heightB; | |||||
| }); | |||||
| entity = availableEntitiesByName["Ashtrek"].constructor(); | |||||
| entity.views[entity.view].height = entity.sizes[0].height; | |||||
| displayEntity(entity, entity.defaultView, 0, 1); | |||||
| arrangeEntities(order); | |||||
| arrangeEntities(getSortedEntities()); | |||||
| fitWorld(); | fitWorld(); | ||||
| } | } | ||||
| function makeSlice(min, max) { | |||||
| return () => { | |||||
| const characters = availableEntities["characters"].filter(x => { | |||||
| const entity = x.constructor(); | |||||
| return math.compare(entity.views[entity.view].height, min) == 1 && math.compare(entity.views[entity.view].height, max) == -1 | |||||
| }); | |||||
| characters.forEach(character => { | |||||
| const entity = character.constructor(); | |||||
| displayEntity(entity, entity.view, 0, 1); | |||||
| }); | |||||
| arrangeEntities(getSortedEntities()); | |||||
| fitWorld(); | |||||
| } | |||||
| } | |||||
| scenes["x < 10m"] = makeSlice(math.unit(0, "meters"), math.unit(10, "meters")); | |||||
| scenes["10m < x < 100m"] = makeSlice(math.unit(10, "meters"), math.unit(100, "meters")); | |||||
| scenes["100m < x < 1km"] = makeSlice(math.unit(100, "meters"), math.unit(1000, "meters")); | |||||
| scenes["1km < x < 10km"] = makeSlice(math.unit(1000, "meters"), math.unit(10000, "meters")); | |||||
| scenes["10km < x < 100km"] = makeSlice(math.unit(10000, "meters"), math.unit(100000, "meters")); | |||||
| scenes["100km < x < 1000km"] = makeSlice(math.unit(100000, "meters"), math.unit(1000000, "meters")); | |||||