feat/switch-assets #86

Merged
legonzaur merged 22 commits from feat/switch-assets into main 2024-05-21 19:09:34 +00:00
156 changed files with 956 additions and 25 deletions
+1 -3
View File
@@ -1,6 +1,6 @@
<script setup lang="ts"> <script setup lang="ts">
import goStore, { setReady, oauth2_register_discord, setup_websocket, heron_cookie_login } from "@/netcode"; import goStore, { oauth2_register_discord, setup_websocket, heron_cookie_login } from "@/netcode";
await setup_websocket() await setup_websocket()
@@ -10,8 +10,6 @@ useHead
: 'Héron Realms', : 'Héron Realms',
}) })
const heron_session = useCookie('heron_session') const heron_session = useCookie('heron_session')
const route = useRoute() const route = useRoute()
+34
View File
@@ -0,0 +1,34 @@
#ifdef GL_ES
precision mediump float;
#endif
#define FBM_OCTAVES 6
#include "lygia/generative/fbm.glsl"
uniform vec2 u_resolution;
uniform vec2 u_mouse;
uniform vec3 u_color_start;
uniform vec3 u_color_end;
uniform vec2 u_offset;
uniform float u_time;
void main(){
vec2 st=(gl_FragCoord.xy+u_offset)/u_resolution;
vec2 q=vec2(0.);
q.x=fbm(st);
q.y=fbm(st+vec2(1.));
q=q*.5+.5;
vec2 r=vec2(0.);
r.x=fbm(st+1.*q+vec2(1.7,9.2)+.00515*u_time);
r.y=fbm(st+1.*q+vec2(8.3,2.8)+.0126*u_time);
r=r*.5+.5;
float f=fbm(st+r);
vec3 color=mix(u_color_start,u_color_end,f*.3);
gl_FragColor=vec4(color,1.);
}
+158
View File
@@ -0,0 +1,158 @@
<script setup lang="ts">
import noise from "~/assets/shaders/noise.frag?raw"
const canvas = ref<HTMLCanvasElement | null>(null)
const settingsStore = useSettingsStore()
declare const webglUtils: {
createProgramFromSources: (gl: WebGLRenderingContext, array: [string, string]) => WebGLProgram,
resizeCanvasToDisplaySize: (e: HTMLCanvasElement | OffscreenCanvas) => any
}
declare const resolveLygiaAsync: (source: string) => Promise<string>
export interface Props {
colorStart?: [number, number, number]
colorEnd?: [number, number, number]
}
const props = withDefaults(defineProps<Props>(), {
colorStart: () => [0, .3, 0],
colorEnd: () => [0, 1, 0]
})
const targetFramerate = 1000 / settingsStore.shaderFramerate
const interval = ref<ReturnType<typeof setInterval>>()
let fragmentShader = await resolveLygiaAsync(noise);
async function main(canvas: HTMLCanvasElement, fragmentShader2: string) {
// Get A WebGL context
/** @type {HTMLCanvasElement} */
const gl = canvas.getContext("webgl");
if (!gl) {
return;
}
const vs = `attribute vec4 a_position;void main() {gl_Position = a_position;}`;
// setup GLSL program
const program = webglUtils.createProgramFromSources(gl, [vs, fragmentShader2]);
// look up where the vertex data needs to go.
const positionAttributeLocation = gl.getAttribLocation(program, "a_position");
// look up uniform locations
const offset = gl.getUniformLocation(program, "u_offset");
const resolutionLocation = gl.getUniformLocation(program, "u_resolution");
const colorStart = gl.getUniformLocation(program, "u_color_start");
const quality = gl.getUniformLocation(program, "u_quality");
const colorEnd = gl.getUniformLocation(program, "u_color_end");
const timeLocation = gl.getUniformLocation(program, "u_time");
// Create a buffer to put three 2d clip space points in
const positionBuffer = gl.createBuffer();
// Bind it to ARRAY_BUFFER (think of it as ARRAY_BUFFER = positionBuffer)
gl.bindBuffer(gl.ARRAY_BUFFER, positionBuffer);
// fill it with a 2 triangles that cover clipspace
gl.bufferData(gl.ARRAY_BUFFER, new Float32Array([
-1, -1, // first triangle
1, -1,
-1, 1,
-1, 1, // second triangle
1, -1,
1, 1,
]), gl.STATIC_DRAW);
const gl2 = gl
function render(time: number) {
time *= 0.001; // convert to seconds
webglUtils.resizeCanvasToDisplaySize(gl2.canvas);
// Tell WebGL how to convert from clip space to pixels
gl2.viewport(0, 0, gl2.canvas.width, gl2.canvas.height);
// Tell it to use our program (pair of shaders)
gl2.useProgram(program);
// Turn on the attribute
gl2.enableVertexAttribArray(positionAttributeLocation);
// Bind the position buffer.
gl2.bindBuffer(gl2.ARRAY_BUFFER, positionBuffer);
// Tell the attribute how to get data out of positionBuffer (ARRAY_BUFFER)
gl2.vertexAttribPointer(
positionAttributeLocation,
2, // 2 components per iteration
gl2.FLOAT, // the data is 32bit floats
false, // don't normalize the data
0, // 0 = move forward size * sizeof(type) each iteration to get the next position
0, // start at the beginning of the buffer
);
const bounds = canvas.getBoundingClientRect()
const aspectRatio = Math.max(window.screen.width, window.screen.height) * devicePixelRatio
gl2.uniform2f(offset, bounds.left, -bounds.bottom);
// console.log(canvas.getBoundingClientRect().left * window.devicePixelRatio)
gl2.uniform1i(quality, settingsStore.shaderQuality)
gl2.uniform2f(resolutionLocation, aspectRatio, aspectRatio);
gl2.uniform3f(colorStart, props.colorStart[0], props.colorStart[1], props.colorStart[2]);
gl2.uniform3f(colorEnd, props.colorEnd[0], props.colorEnd[1], props.colorEnd[2]);
gl2.uniform1f(timeLocation, time);
gl2.drawArrays(
gl2.TRIANGLES,
0, // offset
6, // num vertices to process
);
}
clearInterval(interval.value)
interval.value = setInterval(() => requestAnimationFrame(render), targetFramerate)
}
async function reloadShader() {
nextTick(() => {
if (!canvas.value) { return }
let fragmentShader2 = fragmentShader.replace("#define FBM_OCTAVES 6", "#define FBM_OCTAVES " + settingsStore.shaderQuality);
clearInterval(interval.value)
main(canvas.value, fragmentShader2);
})
}
watch(() => settingsStore.shaderQuality, (newValue, oldValue) => {
reloadShader()
})
watch(() => settingsStore.shaderFramerate, (newValue, oldValue) => {
reloadShader()
})
onMounted(async () => {
reloadShader()
})
onUnmounted(() => {
clearInterval(interval.value)
})
</script>
<template>
<canvas v-if="settingsStore.shaderQuality != 0" ref="canvas" id="background">test</canvas>
</template>
<style scoped>
#background {
left: 0;
position: absolute;
height: 100%;
width: 100%;
}
</style>
+3 -1
View File
@@ -5,6 +5,7 @@ export interface Props {
card_id: number | undefined card_id: number | undefined
} }
const settingsStore = useSettingsStore()
const props = defineProps<Props>() const props = defineProps<Props>()
const card: Ref<Element | null> = ref(null) const card: Ref<Element | null> = ref(null)
@@ -32,7 +33,8 @@ const y = computed(() => {
<template> <template>
<div :class="`card_overlay`" :style="`top: ${y}px; left: ${x}px`" ref="card"> <div :class="`card_overlay`" :style="`top: ${y}px; left: ${x}px`" ref="card">
<img :class="`card_image`" v-if="props.card_id" <img :class="`card_image`" v-if="props.card_id"
:src="'/cards/' + props.card_id.toString().padStart(3, '0') + '.png'" draggable="false"> :src="`/cards/${settingsStore.cardStyle}/` + props.card_id.toString().padStart(3, '0') + '.png'"
draggable="false">
<!-- <img :class="`card_image`" v-if="!props.card_id" :src="'/cards/background.png'" draggable="false"> --> <!-- <img :class="`card_image`" v-if="!props.card_id" :src="'/cards/background.png'" draggable="false"> -->
</div> </div>
+5 -1
View File
@@ -1,5 +1,6 @@
<script setup lang="ts"> <script setup lang="ts">
import goStore from '~/netcode'; import goStore from '~/netcode';
import { useSettingsStore } from '~/stores/settingsStore';
export interface Props { export interface Props {
card_id: number | undefined card_id: number | undefined
@@ -16,6 +17,8 @@ const props = withDefaults(defineProps<Props>(), {
const emit = defineEmits(["click"]) const emit = defineEmits(["click"])
const settingsStore = useSettingsStore()
const childCount = ref<number>(0) const childCount = ref<number>(0)
function cardClick() { function cardClick() {
@@ -48,7 +51,8 @@ watch(
<slot></slot> <slot></slot>
</div> </div>
<img :class="`card_image`" v-if="props.card_id" <img :class="`card_image`" v-if="props.card_id"
:src="'/cards/' + props.card_id.toString().padStart(3, '0') + '.png'" draggable="false"> :src="`/cards/${settingsStore.cardStyle}/` + props.card_id.toString().padStart(3, '0') + '.png'"
draggable="false">
<img :class="`card_image`" v-if="!props.card_id" :src="'/cards/background.png'" draggable="false"> <img :class="`card_image`" v-if="!props.card_id" :src="'/cards/background.png'" draggable="false">
+14 -14
View File
@@ -41,6 +41,7 @@ watch(
}) })
const showResults = ref(false) const showResults = ref(false)
const showOptions = ref(false)
const isWinner = ref(false) const isWinner = ref(false)
function showLoserScreen() { function showLoserScreen() {
@@ -62,20 +63,23 @@ function showWinnerScreen() {
<MarketCards></MarketCards> <MarketCards></MarketCards>
</div> </div>
<div id="player_list"> <div id="player_list">
<AnimatedBackground />
<PlayerListElement v-for="p in goStore.current_game?.players" :player="p"> <PlayerListElement v-for="p in goStore.current_game?.players" :player="p">
</PlayerListElement> </PlayerListElement>
</div> </div>
<div id="current_player" <div id="current_player">
:class="(goStore.current_game?.current_turn && (goStore.current_game?.current_turn === goStore.self?.team)) ? 'self' : ''"> <template v-for="p in current_players">
<PlayerSlot v-for="p in current_players" :player="p"></PlayerSlot> <AnimatedBackground :color-start="goStore.self == p ? [.0, .3, .3] : undefined"
:color-end="goStore.self == p ? [.0, 1, 1] : undefined" />
<PlayerSlot :player="p"></PlayerSlot>
</template>
</div> </div>
</div> </div>
<ResultDialog <ResultDialog :isVisible="showResults" :won="isWinner" :players="goStore.current_game?.players"
:isVisible="showResults"
:won="isWinner"
:players="goStore.current_game?.players"
@close="showResults = false"> @close="showResults = false">
</ResultDialog> </ResultDialog>
<GlobalOverlay></GlobalOverlay>
<SelfView></SelfView> <SelfView></SelfView>
</template> </template>
@@ -95,22 +99,18 @@ function showWinnerScreen() {
overflow: auto; overflow: auto;
position: relative; position: relative;
isolation: isolate; isolation: isolate;
} background: url('/images/bg-darkgrass.png');
#current_player.self {
background-image: url('../images/bg-grass.png');
} }
#market { #market {
grid-area: market; grid-area: market;
background-image: url("/images/bg-sand.png"); background-image: url("/images/bg-sand.png");
padding: 10px; border-bottom: 3px solid black;
;
} }
#current_player { #current_player {
grid-area: current_player; grid-area: current_player;
background-image: url("/images/bg-darkgrass.png");
} }
#player_list { #player_list {
+31
View File
@@ -0,0 +1,31 @@
<script setup lang="ts">
import goStore from '~/netcode';
const displayOptions = ref(false)
</script>
<template>
<div :class="`card_overlay`" ref="card">
<img class="settings_button" src="/settings.png" alt="settings" @click="displayOptions = true"/>
</div>
<OptionsDialog :isVisible="displayOptions" @close="displayOptions = false" />
</template>
<style scoped>
.card_overlay {
/* display: none; */
position: fixed;
z-index: 999;
display: flex;
pointer-events: none;
/* top: left: */
top: 0;
}
.settings_button {
pointer-events: all;
width: 30px;
padding: 5px;
}
</style>
+4
View File
@@ -7,10 +7,12 @@ const isTurn = computed(() => goStore.self && goStore.current_game?.started && (
const clientStore = useClientSideStore() const clientStore = useClientSideStore()
const buyableFiregem = computed(() => goStore?.current_game?.gem_stack.at(-1)) const buyableFiregem = computed(() => goStore?.current_game?.gem_stack.at(-1))
</script> </script>
<template> <template>
<div id="market"> <div id="market">
<AnimatedBackground :color-end="[1, 1, 0]" :color-start="[.3, .3, 0]"></AnimatedBackground>
<CardPreview :tilted="false" :card_id="undefined"></CardPreview> <CardPreview :tilted="false" :card_id="undefined"></CardPreview>
<div class="separator"></div> <div class="separator"></div>
<CardPreview :tilted="false" :card_id="c?.card_id" v-for="c in goStore.current_game?.market" <CardPreview :tilted="false" :card_id="c?.card_id" v-for="c in goStore.current_game?.market"
@@ -60,6 +62,8 @@ const buyableFiregem = computed(() => goStore?.current_game?.gem_stack.at(-1))
z-index: 2; z-index: 2;
position: relative; position: relative;
gap: 2px; gap: 2px;
padding: 10px;
;
} }
.separator { .separator {
+129
View File
@@ -0,0 +1,129 @@
<script setup lang="ts">
const settingsStore = useSettingsStore()
export interface Props {
isVisible: boolean;
}
const props = withDefaults(defineProps<Props>(), {
})
const emit = defineEmits(['close'])
const close = () => {
emit('close')
}
watch(() => settingsStore.shaderQuality, async () => {
console.log(settingsStore.shaderQuality)
})
</script>
<template>
<div v-if="isVisible" class="dialog-overlay" @click="close">
<div class="dialog-box" @click.stop>
<div class="dialog-header">
<h3>Visuals</h3>
</div>
<div class="dialog-header">
<span>Toggle Card Style</span>
</div>
<div class="dialog-body">
<button @click="settingsStore.switchCardStyles">Toggle Card style</button>
</div>
<div class="dialog-header">
<h3>Graphics</h3>
</div>
<div class="dialog-header">
<span>Shader Quality</span>
</div>
<div class="dialog-body">
<input type="range" min="0" max="10" v-model="settingsStore.shaderQuality">
</div>
<div class="dialog-footer">
<span>
<template v-if="settingsStore.shaderQuality == 0">
Disabled
</template>
<template v-if="settingsStore.shaderQuality > 0">
{{ settingsStore.shaderQuality }}
</template>
</span>
</div>
<div class="dialog-header">
<span>Shader Framerate</span>
</div>
<div class="dialog-body">
<input type="range" min="10" max="60" step="5" v-model="settingsStore.shaderFramerate"
:disabled="settingsStore.shaderQuality == 0">
</div>
<div class="dialog-footer">
<span>{{ settingsStore.shaderFramerate }} fps</span>
</div>
</div>
</div>
</template>
<style scoped>
.dialog-overlay {
position: fixed;
top: 0;
left: 0;
width: 100%;
height: 100%;
background: rgba(0, 0, 0, 0.5);
display: flex;
justify-content: center;
align-items: center;
z-index: 1000;
display: grid;
}
.dialog-box {
background-image: url('../images/bg-grass.png');
padding: 0 20px;
border-radius: 5px;
width: 800px;
border-radius: 30px;
max-width: 100%;
color: white;
text-align: center;
text-shadow: 2px 2px 4px rgba(0, 0, 0, 0.8);
display: grid;
grid-template-columns: 33% 33% 33%;
}
.dialog-box h3 {
font-size: 30px;
font-family: 'Segoe UI', Tahoma, Geneva, Verdana, sans-serif;
margin: 0;
width: 100%;
padding: 10px 0;
color: white;
text-shadow: 2px 2px 4px rgba(0, 0, 0, 0.8);
}
.dialog-header,
.dialog-footer {
display: flex;
justify-content: space-between;
align-items: center;
padding: 10px 0;
}
.dialog-header {
grid-column-start: 1;
}
.dialog-body {
padding: 10px 0;
grid-column-start: 2;
}
.dialog-footer {
grid-column-start: 3;
}
</style>
+3 -1
View File
@@ -18,6 +18,7 @@ const props = defineProps<Props>()
<template> <template>
<div :class="`player_list_element ${goStore.self === props.player ? 'self' : ''}`"> <div :class="`player_list_element ${goStore.self === props.player ? 'self' : ''}`">
<AnimatedBackground v-if="goStore.self === props.player" :color-start="[.0, .3, .3]" :color-end="[.0, 1, 1]" />
<div class="button" id="player_list_buttons"> <div class="button" id="player_list_buttons">
<div class="main_button" @click="show('main')"> <div class="main_button" @click="show('main')">
<div class="tooltip">Board</div> <div class="tooltip">Board</div>
@@ -119,10 +120,11 @@ const props = defineProps<Props>()
"button player"; "button player";
border-bottom: 5px solid black; border-bottom: 5px solid black;
min-height: 200px; min-height: 200px;
position: relative;
} }
.player_list_element.self { .player_list_element.self {
background-image: url('../images/bg-grass.png'); background-image: url('/images/bg-grass.png');
} }
.view { .view {
+1 -1
View File
@@ -92,7 +92,7 @@ function check_for_guard(player: Player) {
</script> </script>
<template> <template>
<div :class="`player ${isPlayerTurn ? 'turn' : ''} ${discard_unwrapped ? 'discard_unwrapped' : ''}`"> <div class="player" :class="{ turn: isPlayerTurn, discard_unwrapped, self: isSelf }">
<template v-if="!hide_stack_and_discard"> <template v-if="!hide_stack_and_discard">
<div class="stack"> <div class="stack">
+1 -1
View File
@@ -66,7 +66,7 @@ const close = () => {
} }
.dialog-box { .dialog-box {
background-image: url('../images/bg-grass.png'); background-image: url('/images/bg-grass.png');
padding: 0 20px; padding: 0 20px;
border-radius: 5px; border-radius: 5px;
width: 800px; width: 800px;
+10
View File
@@ -10,5 +10,15 @@ export default defineNuxtConfig({
}, },
modules: [ modules: [
'@pinia/nuxt', '@pinia/nuxt',
'@pinia-plugin-persistedstate/nuxt',
], ],
app: {
head: {
script: [{
src: "/webgl-utils.js"
}, {
src: "https://lygia.xyz/resolve.js"
}]
}
},
}) })
+28
View File
@@ -12,6 +12,9 @@
"pinia": "^2.1.7", "pinia": "^2.1.7",
"vue": "^3.4.21", "vue": "^3.4.21",
"vue-router": "^4.3.0" "vue-router": "^4.3.0"
},
"devDependencies": {
"@pinia-plugin-persistedstate/nuxt": "^1.2.0"
} }
}, },
"node_modules/@ampproject/remapping": { "node_modules/@ampproject/remapping": {
@@ -2093,6 +2096,21 @@
"node": ">=0.10" "node": ">=0.10"
} }
}, },
"node_modules/@pinia-plugin-persistedstate/nuxt": {
"version": "1.2.0",
"resolved": "https://registry.npmjs.org/@pinia-plugin-persistedstate/nuxt/-/nuxt-1.2.0.tgz",
"integrity": "sha512-2rtgx5viGSMQMCoFYZMHguA2FhFKCUvw0PwETfqQegsWeBHlqk1/D0G/9xqep8Hq+c1BuFx+jNLJzoLXtYfivg==",
"dev": true,
"license": "MIT",
"dependencies": {
"@nuxt/kit": "^3.8.0",
"defu": "^6.1.2",
"pinia-plugin-persistedstate": ">=3.2.0"
},
"peerDependencies": {
"@pinia/nuxt": "^0.5.0"
}
},
"node_modules/@pinia/nuxt": { "node_modules/@pinia/nuxt": {
"version": "0.5.1", "version": "0.5.1",
"resolved": "https://registry.npmjs.org/@pinia/nuxt/-/nuxt-0.5.1.tgz", "resolved": "https://registry.npmjs.org/@pinia/nuxt/-/nuxt-0.5.1.tgz",
@@ -7803,6 +7821,16 @@
} }
} }
}, },
"node_modules/pinia-plugin-persistedstate": {
"version": "3.2.1",
"resolved": "https://registry.npmjs.org/pinia-plugin-persistedstate/-/pinia-plugin-persistedstate-3.2.1.tgz",
"integrity": "sha512-MK++8LRUsGF7r45PjBFES82ISnPzyO6IZx3CH5vyPseFLZCk1g2kgx6l/nW8pEBKxxd4do0P6bJw+mUSZIEZUQ==",
"dev": true,
"license": "MIT",
"peerDependencies": {
"pinia": "^2.0.0"
}
},
"node_modules/pinia/node_modules/vue-demi": { "node_modules/pinia/node_modules/vue-demi": {
"version": "0.14.7", "version": "0.14.7",
"resolved": "https://registry.npmjs.org/vue-demi/-/vue-demi-0.14.7.tgz", "resolved": "https://registry.npmjs.org/vue-demi/-/vue-demi-0.14.7.tgz",
+3
View File
@@ -15,5 +15,8 @@
"pinia": "^2.1.7", "pinia": "^2.1.7",
"vue": "^3.4.21", "vue": "^3.4.21",
"vue-router": "^4.3.0" "vue-router": "^4.3.0"
},
"devDependencies": {
"@pinia-plugin-persistedstate/nuxt": "^1.2.0"
} }
} }
BIN
View File
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.

Some files were not shown because too many files have changed in this diff Show More