mirror of
https://github.com/thepaperpilot/Advent-Incremental.git
synced 2024-11-23 17:01:49 +00:00
Infinite grid
This commit is contained in:
parent
c92eb6ab3b
commit
317712bdbe
5 changed files with 196 additions and 7799 deletions
7731
package-lock.json
generated
7731
package-lock.json
generated
File diff suppressed because it is too large
Load diff
17
package.json
17
package.json
|
@ -19,11 +19,28 @@
|
||||||
"@fontsource/roboto-mono": "^4.5.8",
|
"@fontsource/roboto-mono": "^4.5.8",
|
||||||
"@pixi/app": "^6.5.8",
|
"@pixi/app": "^6.5.8",
|
||||||
"@pixi/assets": "^6.5.8",
|
"@pixi/assets": "^6.5.8",
|
||||||
|
"@pixi/basis": "^6.5.8",
|
||||||
|
"@pixi/compressed-textures": "^6.5.8",
|
||||||
|
"@pixi/constants": "^6.5.8",
|
||||||
|
"@pixi/core": "^6.5.8",
|
||||||
|
"@pixi/display": "^6.5.8",
|
||||||
|
"@pixi/extensions": "^6.5.8",
|
||||||
"@pixi/graphics": "^6.5.8",
|
"@pixi/graphics": "^6.5.8",
|
||||||
|
"@pixi/loaders": "^6.5.8",
|
||||||
|
"@pixi/math": "^6.5.8",
|
||||||
|
"@pixi/mesh": "^6.5.8",
|
||||||
"@pixi/particle-emitter": "^5.0.8",
|
"@pixi/particle-emitter": "^5.0.8",
|
||||||
|
"@pixi/runner": "^6.5.8",
|
||||||
|
"@pixi/settings": "^6.5.8",
|
||||||
"@pixi/sprite": "^6.5.8",
|
"@pixi/sprite": "^6.5.8",
|
||||||
|
"@pixi/spritesheet": "^6.5.8",
|
||||||
|
"@pixi/text": "^6.5.8",
|
||||||
|
"@pixi/text-bitmap": "^6.5.8",
|
||||||
|
"@pixi/ticker": "^6.5.8",
|
||||||
|
"@pixi/utils": "^6.5.8",
|
||||||
"@vitejs/plugin-vue": "^2.3.3",
|
"@vitejs/plugin-vue": "^2.3.3",
|
||||||
"@vitejs/plugin-vue-jsx": "^1.3.10",
|
"@vitejs/plugin-vue-jsx": "^1.3.10",
|
||||||
|
"eslint-plugin-vue": "^8.0.1",
|
||||||
"is-plain-object": "^5.0.0",
|
"is-plain-object": "^5.0.0",
|
||||||
"lz-string": "^1.4.4",
|
"lz-string": "^1.4.4",
|
||||||
"nanoevents": "^6.0.2",
|
"nanoevents": "^6.0.2",
|
||||||
|
|
|
@ -4,7 +4,6 @@
|
||||||
<script setup lang="ts">
|
<script setup lang="ts">
|
||||||
import type { Application } from "@pixi/app";
|
import type { Application } from "@pixi/app";
|
||||||
import { onMounted, shallowRef } from "vue";
|
import { onMounted, shallowRef } from "vue";
|
||||||
import { blockAmts } from "./factory";
|
|
||||||
import "lib/pixi";
|
import "lib/pixi";
|
||||||
|
|
||||||
const element = shallowRef<HTMLElement | null>(null);
|
const element = shallowRef<HTMLElement | null>(null);
|
||||||
|
@ -15,8 +14,8 @@ console.log(props.application);
|
||||||
onMounted(() => {
|
onMounted(() => {
|
||||||
if (element.value !== null) {
|
if (element.value !== null) {
|
||||||
element.value?.append(props.application.view);
|
element.value?.append(props.application.view);
|
||||||
//props.application.resizeTo = element.value;
|
props.application.resizeTo = element.value;
|
||||||
//props.application.resize();
|
props.application.resize();
|
||||||
} else {
|
} else {
|
||||||
throw new TypeError("This should not occur");
|
throw new TypeError("This should not occur");
|
||||||
}
|
}
|
||||||
|
@ -24,7 +23,10 @@ onMounted(() => {
|
||||||
</script>
|
</script>
|
||||||
<style scoped>
|
<style scoped>
|
||||||
.factoryDisp {
|
.factoryDisp {
|
||||||
width: 100%;
|
position: absolute;
|
||||||
height: 100%;
|
top: 0;
|
||||||
|
bottom: 0;
|
||||||
|
left: 0;
|
||||||
|
right: 0;
|
||||||
}
|
}
|
||||||
</style>
|
</style>
|
||||||
|
|
|
@ -15,6 +15,7 @@ import player from "game/player";
|
||||||
import "./styles/factory.css";
|
import "./styles/factory.css";
|
||||||
import { globalBus } from "game/events";
|
import { globalBus } from "game/events";
|
||||||
import { Container } from "@pixi/display";
|
import { Container } from "@pixi/display";
|
||||||
|
import { Matrix } from "@pixi/math";
|
||||||
|
|
||||||
const id = "factory";
|
const id = "factory";
|
||||||
|
|
||||||
|
@ -23,15 +24,6 @@ const day = 20;
|
||||||
|
|
||||||
// 20x20 block size
|
// 20x20 block size
|
||||||
// TODO: unhardcode stuff
|
// TODO: unhardcode stuff
|
||||||
const size = {
|
|
||||||
width: 1000,
|
|
||||||
height: 340
|
|
||||||
};
|
|
||||||
export const blockAmts = {
|
|
||||||
w: 50,
|
|
||||||
h: 17
|
|
||||||
};
|
|
||||||
|
|
||||||
function roundDownTo(num: number, multiple: number) {
|
function roundDownTo(num: number, multiple: number) {
|
||||||
return Math.floor(num / multiple) * multiple;
|
return Math.floor(num / multiple) * multiple;
|
||||||
}
|
}
|
||||||
|
@ -43,6 +35,8 @@ function getRelativeCoords(e: MouseEvent) {
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const blockSize = 50;
|
||||||
|
|
||||||
interface FactoryComponent {
|
interface FactoryComponent {
|
||||||
directionIn: Direction | undefined;
|
directionIn: Direction | undefined;
|
||||||
directionOut: Direction | undefined;
|
directionOut: Direction | undefined;
|
||||||
|
@ -86,76 +80,98 @@ const factory = createLayer(id, () => {
|
||||||
x: 0,
|
x: 0,
|
||||||
y: 0
|
y: 0
|
||||||
});
|
});
|
||||||
|
const mapOffset = reactive({
|
||||||
|
x: 0,
|
||||||
|
y: 0
|
||||||
|
});
|
||||||
const isMouseHoverShown = ref(false);
|
const isMouseHoverShown = ref(false);
|
||||||
const whatIsHovered = ref<FactoryCompNames | "">("");
|
const whatIsHovered = ref<FactoryCompNames | "">("");
|
||||||
const compSelected = ref<FactoryCompNames | "">("");
|
const compSelected = ref<FactoryCompNames | "">("");
|
||||||
const components: Ref<unknown[][]> = persistent(
|
const components: Ref<Record<string, unknown>> = persistent({});
|
||||||
Array(blockAmts.h)
|
|
||||||
.fill(undefined)
|
|
||||||
.map(() => Array(blockAmts.w).fill(undefined))
|
|
||||||
);
|
|
||||||
|
|
||||||
// pixi
|
// pixi
|
||||||
const app = new Application(size);
|
const app = new Application({
|
||||||
|
backgroundAlpha: 0
|
||||||
|
});
|
||||||
const graphicContainer = new Graphics();
|
const graphicContainer = new Graphics();
|
||||||
const spriteContainer = new Container();
|
const spriteContainer = new Container();
|
||||||
let blockWidth = 0;
|
|
||||||
let blockHeight = 0;
|
|
||||||
app.stage.addChild(graphicContainer, spriteContainer);
|
app.stage.addChild(graphicContainer, spriteContainer);
|
||||||
|
|
||||||
globalBus.on("update", () => {
|
globalBus.on("update", () => {
|
||||||
blockWidth = app.screen.width / blockAmts.w;
|
|
||||||
blockHeight = app.screen.height / blockAmts.h;
|
|
||||||
});
|
});
|
||||||
|
|
||||||
// draw graphics
|
// draw graphics
|
||||||
function updateGraphics() {
|
function updateGraphics() {
|
||||||
|
app.resize();
|
||||||
graphicContainer.clear();
|
graphicContainer.clear();
|
||||||
|
|
||||||
|
spriteContainer.x = mapOffset.x * blockSize + app.view.width / 2;
|
||||||
|
spriteContainer.y = mapOffset.y * blockSize + app.view.height / 2;
|
||||||
|
|
||||||
if (isMouseHoverShown.value) {
|
if (isMouseHoverShown.value) {
|
||||||
|
let { tx, ty } = spriteContainer.localTransform;
|
||||||
graphicContainer.beginFill(0x808080);
|
graphicContainer.beginFill(0x808080);
|
||||||
graphicContainer.drawRect(
|
graphicContainer.drawRect(
|
||||||
roundDownTo(mouseCoords.x, blockWidth),
|
roundDownTo(mouseCoords.x - tx, blockSize) + tx,
|
||||||
roundDownTo(mouseCoords.y, blockHeight),
|
roundDownTo(mouseCoords.y - ty, blockSize) + ty,
|
||||||
blockWidth,
|
blockSize,
|
||||||
blockHeight
|
blockSize
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
watchEffect(updateGraphics);
|
watchEffect(updateGraphics);
|
||||||
|
|
||||||
function onMouseMove(e: MouseEvent) {
|
let pointerDown = ref(false), pointerDrag = ref(false);
|
||||||
// some code to get the x and y coords relative to element
|
|
||||||
// https://stackoverflow.com/questions/3234256/find-mouse-position-relative-to-element
|
function onFactoryPointerMove(e: PointerEvent) {
|
||||||
|
|
||||||
const { x, y } = getRelativeCoords(e);
|
const { x, y } = getRelativeCoords(e);
|
||||||
mouseCoords.x = x;
|
mouseCoords.x = x;
|
||||||
mouseCoords.y = y;
|
mouseCoords.y = y;
|
||||||
|
|
||||||
|
if (pointerDown.value && (pointerDrag.value || Math.abs(e.movementX) > 2 || Math.abs(e.movementY) > 2)) {
|
||||||
|
pointerDrag.value = true;
|
||||||
|
mapOffset.x += e.movementX / blockSize;
|
||||||
|
mapOffset.y += e.movementY / blockSize;
|
||||||
}
|
}
|
||||||
async function onClick(e: MouseEvent) {
|
|
||||||
if (compSelected.value === "") {
|
|
||||||
console.warn("You haven't hovered over anything, trickster!");
|
|
||||||
return;
|
|
||||||
}
|
}
|
||||||
|
async function onFactoryPointerDown(e: PointerEvent) {
|
||||||
|
window.addEventListener("pointerup", onFactoryPointerUp);
|
||||||
|
pointerDown.value = true;
|
||||||
|
}
|
||||||
|
async function onFactoryPointerUp(e: PointerEvent) {
|
||||||
|
if (!pointerDrag.value) {
|
||||||
|
if (compSelected.value !== "") {
|
||||||
|
let { tx, ty } = spriteContainer.localTransform;
|
||||||
let { x, y } = getRelativeCoords(e);
|
let { x, y } = getRelativeCoords(e);
|
||||||
x = roundDownTo(x, blockWidth) / blockWidth;
|
x = roundDownTo(x - tx, blockSize) / blockSize;
|
||||||
y = roundDownTo(y, blockHeight) / blockHeight;
|
y = roundDownTo(y - ty, blockSize) / blockSize;
|
||||||
|
|
||||||
const basicData = structuredClone(
|
const basicData = structuredClone(
|
||||||
FACTORY_COMPONENTS[compSelected.value]
|
FACTORY_COMPONENTS[compSelected.value]
|
||||||
) as FactoryComponent;
|
) as FactoryComponent;
|
||||||
basicData.type = compSelected.value;
|
basicData.type = compSelected.value;
|
||||||
const sheet = await Assets.load(basicData.imageSrc);
|
const sheet = await Assets.load(basicData.imageSrc);
|
||||||
basicData.sprite = new Sprite(sheet);
|
basicData.sprite = new Sprite(sheet);
|
||||||
basicData.sprite.x = x;
|
|
||||||
basicData.sprite.y = y;
|
basicData.sprite.x = x * blockSize;
|
||||||
basicData.sprite.width = blockWidth;
|
basicData.sprite.y = y * blockSize;
|
||||||
basicData.sprite.height = blockHeight;
|
basicData.sprite.width = blockSize;
|
||||||
|
basicData.sprite.height = blockSize;
|
||||||
spriteContainer.addChild(basicData.sprite);
|
spriteContainer.addChild(basicData.sprite);
|
||||||
}
|
}
|
||||||
function onMouseEnter() {
|
}
|
||||||
|
|
||||||
|
window.removeEventListener("pointerup", onFactoryPointerUp);
|
||||||
|
pointerDown.value = pointerDrag.value = false;
|
||||||
|
}
|
||||||
|
function onFactoryMouseEnter() {
|
||||||
isMouseHoverShown.value = true;
|
isMouseHoverShown.value = true;
|
||||||
}
|
}
|
||||||
function onMouseLeave() {
|
function onFactoryMouseLeave() {
|
||||||
isMouseHoverShown.value = false;
|
isMouseHoverShown.value = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
function goBack() {
|
function goBack() {
|
||||||
player.tabs.splice(0, Infinity, "main");
|
player.tabs.splice(0, Infinity, "main");
|
||||||
}
|
}
|
||||||
|
@ -170,25 +186,27 @@ const factory = createLayer(id, () => {
|
||||||
day,
|
day,
|
||||||
color,
|
color,
|
||||||
minWidth: 700,
|
minWidth: 700,
|
||||||
minimizable: false,
|
style: { overflow: "hidden" },
|
||||||
|
draggable: false,
|
||||||
display: jsx(() => (
|
display: jsx(() => (
|
||||||
<div class="layer-container">
|
<div class="layer-container">
|
||||||
<button class="goBack" onClick={goBack}>
|
<button class="goBack" onClick={goBack}>
|
||||||
❌
|
❌
|
||||||
</button>
|
</button>
|
||||||
<table cellspacing="0" cellpadding="0" border="0" class="container">
|
<Factory
|
||||||
<tr>
|
application={app}
|
||||||
<td class="info" colspan="2">
|
onPointermove={onFactoryPointerMove}
|
||||||
<div style="min-height: 3em">
|
onPointerdown={onFactoryPointerDown}
|
||||||
|
onPointerenter={onFactoryMouseEnter}
|
||||||
|
onPointerleave={onFactoryMouseLeave}
|
||||||
|
/>
|
||||||
|
<div cellspacing="0" cellpadding="0" border="0" class="container">
|
||||||
|
<div style="line-height: 2.5em; min-height: 2.5em">
|
||||||
{whatIsHovered.value === ""
|
{whatIsHovered.value === ""
|
||||||
? undefined
|
? undefined
|
||||||
: FACTORY_COMPONENTS[whatIsHovered.value].description}
|
: FACTORY_COMPONENTS[whatIsHovered.value].description}
|
||||||
</div>
|
</div>
|
||||||
</td>
|
<div class="comps">
|
||||||
</tr>
|
|
||||||
<tr>
|
|
||||||
<td style="vertical-align: top" class="comps">
|
|
||||||
<h3>Components</h3>
|
|
||||||
<div>
|
<div>
|
||||||
{Object.entries(FACTORY_COMPONENTS).map(value => {
|
{Object.entries(FACTORY_COMPONENTS).map(value => {
|
||||||
const key = value[0] as FactoryCompNames;
|
const key = value[0] as FactoryCompNames;
|
||||||
|
@ -196,14 +214,7 @@ const factory = createLayer(id, () => {
|
||||||
return (
|
return (
|
||||||
<img
|
<img
|
||||||
src={item.imageSrc}
|
src={item.imageSrc}
|
||||||
style={{
|
class={{ selected: compSelected.value === key }}
|
||||||
width: "20%",
|
|
||||||
"aspect-ratio": "1",
|
|
||||||
border:
|
|
||||||
compSelected.value === key
|
|
||||||
? "1px solid white"
|
|
||||||
: ""
|
|
||||||
}}
|
|
||||||
onMouseenter={() => onComponentHover(key)}
|
onMouseenter={() => onComponentHover(key)}
|
||||||
onMouseleave={() => onComponentHover("")}
|
onMouseleave={() => onComponentHover("")}
|
||||||
onClick={() => onCompClick(key)}
|
onClick={() => onCompClick(key)}
|
||||||
|
@ -211,18 +222,8 @@ const factory = createLayer(id, () => {
|
||||||
);
|
);
|
||||||
})}
|
})}
|
||||||
</div>
|
</div>
|
||||||
</td>
|
</div>
|
||||||
<td>
|
</div>
|
||||||
<Factory
|
|
||||||
application={app}
|
|
||||||
onMousemove={onMouseMove}
|
|
||||||
onClick={onClick}
|
|
||||||
onMouseenter={onMouseEnter}
|
|
||||||
onMouseleave={onMouseLeave}
|
|
||||||
/>
|
|
||||||
</td>
|
|
||||||
</tr>
|
|
||||||
</table>
|
|
||||||
</div>
|
</div>
|
||||||
)),
|
)),
|
||||||
components
|
components
|
||||||
|
|
|
@ -1,16 +1,40 @@
|
||||||
|
|
||||||
|
.factoryDisp {
|
||||||
|
position: absolute;
|
||||||
|
|
||||||
|
top: 0;
|
||||||
|
bottom: 0;
|
||||||
|
left: 0;
|
||||||
|
right: 0;
|
||||||
|
|
||||||
|
background: snow;
|
||||||
|
touch-action: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
.factoryDisp canvas {
|
||||||
|
filter: drop-shadow(1px 1px 2px #0007);
|
||||||
|
}
|
||||||
.container {
|
.container {
|
||||||
width: 100%;
|
position: absolute;
|
||||||
height: 100%;
|
|
||||||
|
bottom: -5px;
|
||||||
|
height: 100px;
|
||||||
|
left: 10%;
|
||||||
|
right: 10%;
|
||||||
|
|
||||||
|
background: var(--raised-background);
|
||||||
|
border-radius: var(--border-radius) var(--border-radius) 0 0;
|
||||||
|
box-shadow: 0 2px 10px black;
|
||||||
|
|
||||||
margin: 0;
|
margin: 0;
|
||||||
padding: 0;
|
padding: 0;
|
||||||
}
|
}
|
||||||
.factoryDisp {
|
|
||||||
border-left: 1px solid white;
|
.comps > div > img {
|
||||||
border-bottom: 1px solid white;
|
width: 50px;
|
||||||
|
height: 50px;
|
||||||
}
|
}
|
||||||
.info {
|
.comps > div > img.selected {
|
||||||
border-bottom: 1px solid white;
|
transform: translateY(-5px);
|
||||||
}
|
filter: drop-shadow(0 5px 5px #0007);
|
||||||
.comps {
|
|
||||||
border-bottom: 1px solid white;
|
|
||||||
}
|
}
|
Loading…
Reference in a new issue