Infinite grid

This commit is contained in:
ducdat0507 2022-12-18 17:58:08 +07:00
parent c92eb6ab3b
commit 317712bdbe
5 changed files with 196 additions and 7799 deletions

7731
package-lock.json generated

File diff suppressed because it is too large Load diff

View file

@ -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",

View file

@ -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>

View file

@ -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;
}
async function onClick(e: MouseEvent) { if (pointerDown.value && (pointerDrag.value || Math.abs(e.movementX) > 2 || Math.abs(e.movementY) > 2)) {
if (compSelected.value === "") { pointerDrag.value = true;
console.warn("You haven't hovered over anything, trickster!"); mapOffset.x += e.movementX / blockSize;
return; mapOffset.y += e.movementY / blockSize;
} }
let { x, y } = getRelativeCoords(e);
x = roundDownTo(x, blockWidth) / blockWidth;
y = roundDownTo(y, blockHeight) / blockHeight;
const basicData = structuredClone(
FACTORY_COMPONENTS[compSelected.value]
) as FactoryComponent;
basicData.type = compSelected.value;
const sheet = await Assets.load(basicData.imageSrc);
basicData.sprite = new Sprite(sheet);
basicData.sprite.x = x;
basicData.sprite.y = y;
basicData.sprite.width = blockWidth;
basicData.sprite.height = blockHeight;
spriteContainer.addChild(basicData.sprite);
} }
function onMouseEnter() { 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);
x = roundDownTo(x - tx, blockSize) / blockSize;
y = roundDownTo(y - ty, blockSize) / blockSize;
const basicData = structuredClone(
FACTORY_COMPONENTS[compSelected.value]
) as FactoryComponent;
basicData.type = compSelected.value;
const sheet = await Assets.load(basicData.imageSrc);
basicData.sprite = new Sprite(sheet);
basicData.sprite.x = x * blockSize;
basicData.sprite.y = y * blockSize;
basicData.sprite.width = blockSize;
basicData.sprite.height = blockSize;
spriteContainer.addChild(basicData.sprite);
}
}
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,59 +186,44 @@ 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}
{whatIsHovered.value === "" onPointerenter={onFactoryMouseEnter}
? undefined onPointerleave={onFactoryMouseLeave}
: FACTORY_COMPONENTS[whatIsHovered.value].description} />
</div> <div cellspacing="0" cellpadding="0" border="0" class="container">
</td> <div style="line-height: 2.5em; min-height: 2.5em">
</tr> {whatIsHovered.value === ""
<tr> ? undefined
<td style="vertical-align: top" class="comps"> : FACTORY_COMPONENTS[whatIsHovered.value].description}
<h3>Components</h3> </div>
<div> <div class="comps">
{Object.entries(FACTORY_COMPONENTS).map(value => { <div>
const key = value[0] as FactoryCompNames; {Object.entries(FACTORY_COMPONENTS).map(value => {
const item = value[1]; const key = value[0] as FactoryCompNames;
return ( const item = value[1];
<img return (
src={item.imageSrc} <img
style={{ src={item.imageSrc}
width: "20%", class={{ selected: compSelected.value === key }}
"aspect-ratio": "1", onMouseenter={() => onComponentHover(key)}
border: onMouseleave={() => onComponentHover("")}
compSelected.value === key onClick={() => onCompClick(key)}
? "1px solid white" ></img>
: "" );
}} })}
onMouseenter={() => onComponentHover(key)} </div>
onMouseleave={() => onComponentHover("")} </div>
onClick={() => onCompClick(key)} </div>
></img>
);
})}
</div>
</td>
<td>
<Factory
application={app}
onMousemove={onMouseMove}
onClick={onClick}
onMouseenter={onMouseEnter}
onMouseleave={onMouseLeave}
/>
</td>
</tr>
</table>
</div> </div>
)), )),
components components

View file

@ -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;
} }