Compare commits

...
Author SHA1 Message Date
legonzaur 32c4c9a4bf Merge branch 'main' into feat/switch-assets 2024-05-21 19:09:26 +00:00
Erzangel 06ac020723 feat: more original cards, fix heron 15, settings img 2024-05-21 21:08:13 +02:00
legonzaur 125bb0e894 Chore: cleanup settings view
release-tag / release-image (push) Successful in 35s
2024-05-19 22:25:17 +02:00
legonzaur 221935faae Feat: fix some shaders issue, add framerate slider
release-tag / release-image (push) Successful in 30s
2024-05-19 22:04:09 +02:00
legonzaur ab975d499e Fix : normalize borders
release-tag / release-image (push) Successful in 35s
2024-05-19 21:49:58 +02:00
legonzaur dcac9ecd56 Fix : slow down shader animations
release-tag / release-image (push) Successful in 39s
2024-05-19 21:47:53 +02:00
legonzaur 86ae4c57f8 Fix : switch to setTimeout for animations 2024-05-19 21:47:34 +02:00
legonzaur b3ca9eafd8 Feat : add border to bottom of market
release-tag / release-image (push) Successful in 51s
2024-05-19 21:46:08 +02:00
legonzaur 2b678a51a7 Fix : add background back
release-tag / release-image (push) Successful in 1m14s
2024-05-19 21:11:28 +02:00
legonzaur e18a8dce49 Feat : Add shader quality slider 2024-05-19 18:55:13 +02:00
legonzaur 2c2342580b Merge remote-tracking branch 'origin/feat/switch-assets' into feat-shader-background 2024-05-19 18:49:34 +02:00
legonzaur cfc04b8451 WIP 2024-05-19 18:49:29 +02:00
legonzaur 02e6548eea Feat: add persistentSettingsStore using LocalStorage plugin 2024-05-19 18:44:57 +02:00
legonzaur 2aac51a018 Feat: add persistentSettingsStore using LocalStorage plugin 2024-05-19 18:44:37 +02:00
legonzaur 658add7888 Feat: add persistentSettingsStore using LocalStorage plugin 2024-05-19 18:44:07 +02:00
Erzangel 5cd57a7266 feat(wip): button to switch assets 2024-05-19 17:49:33 +02:00
legonzaur 58d0e4a416 Add shaders everywhere! 2024-05-19 13:22:05 +02:00
legonzaur 1fc3378083 Merge branch 'main' into feat-shader-background 2024-05-19 10:24:23 +02:00
legonzaur f16dad82ae Feat : darken background 2024-05-19 01:38:08 +02:00
legonzaur 51171fc2e1 Feat : temporarily remove self background 2024-05-19 01:32:59 +02:00
legonzaur d5c65cfb14 Feat : add game board to current_player 2024-05-19 01:23:11 +02:00
legonzaur caa54e6ece WIP canvas 2024-05-19 01:20:10 +02: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