base game screen
This commit is contained in:
parent
cc8889963f
commit
6843988709
|
@ -7,6 +7,7 @@ export {}
|
||||||
|
|
||||||
declare module 'vue' {
|
declare module 'vue' {
|
||||||
export interface GlobalComponents {
|
export interface GlobalComponents {
|
||||||
|
Game: typeof import('./src/components/Game.vue')['default']
|
||||||
Home: typeof import('./src/components/Home.vue')['default']
|
Home: typeof import('./src/components/Home.vue')['default']
|
||||||
IMdi3dRotation: typeof import('~icons/mdi/3d-rotation')['default']
|
IMdi3dRotation: typeof import('~icons/mdi/3d-rotation')['default']
|
||||||
IMdiCard: typeof import('~icons/mdi/card')['default']
|
IMdiCard: typeof import('~icons/mdi/card')['default']
|
||||||
|
@ -17,5 +18,7 @@ declare module 'vue' {
|
||||||
IMdiVideo3d: typeof import('~icons/mdi/video3d')['default']
|
IMdiVideo3d: typeof import('~icons/mdi/video3d')['default']
|
||||||
Projects: typeof import('./src/components/Projects.vue')['default']
|
Projects: typeof import('./src/components/Projects.vue')['default']
|
||||||
RandomIcon: typeof import('./src/components/RandomIcon.vue')['default']
|
RandomIcon: typeof import('./src/components/RandomIcon.vue')['default']
|
||||||
|
RouterLink: typeof import('vue-router')['RouterLink']
|
||||||
|
RouterView: typeof import('vue-router')['RouterView']
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -9,6 +9,7 @@
|
||||||
"version": "0.0.0",
|
"version": "0.0.0",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@fireworks-js/vue": "^2.10.7",
|
"@fireworks-js/vue": "^2.10.7",
|
||||||
|
"@vueuse/components": "^10.9.0",
|
||||||
"@vueuse/core": "^10.9.0",
|
"@vueuse/core": "^10.9.0",
|
||||||
"pinia": "^2.1.7",
|
"pinia": "^2.1.7",
|
||||||
"reset-css": "^5.0.2",
|
"reset-css": "^5.0.2",
|
||||||
|
@ -950,6 +951,41 @@
|
||||||
"resolved": "https://registry.npmjs.org/@vue/shared/-/shared-3.4.25.tgz",
|
"resolved": "https://registry.npmjs.org/@vue/shared/-/shared-3.4.25.tgz",
|
||||||
"integrity": "sha512-k0yappJ77g2+KNrIaF0FFnzwLvUBLUYr8VOwz+/6vLsmItFp51AcxLL7Ey3iPd7BIRyWPOcqUjMnm7OkahXllA=="
|
"integrity": "sha512-k0yappJ77g2+KNrIaF0FFnzwLvUBLUYr8VOwz+/6vLsmItFp51AcxLL7Ey3iPd7BIRyWPOcqUjMnm7OkahXllA=="
|
||||||
},
|
},
|
||||||
|
"node_modules/@vueuse/components": {
|
||||||
|
"version": "10.9.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/@vueuse/components/-/components-10.9.0.tgz",
|
||||||
|
"integrity": "sha512-BHQpA0yIi3y7zKa1gYD0FUzLLkcRTqVhP8smnvsCK6GFpd94Nziq1XVPD7YpFeho0k5BzbBiNZF7V/DpkJ967A==",
|
||||||
|
"dependencies": {
|
||||||
|
"@vueuse/core": "10.9.0",
|
||||||
|
"@vueuse/shared": "10.9.0",
|
||||||
|
"vue-demi": ">=0.14.7"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/@vueuse/components/node_modules/vue-demi": {
|
||||||
|
"version": "0.14.7",
|
||||||
|
"resolved": "https://registry.npmjs.org/vue-demi/-/vue-demi-0.14.7.tgz",
|
||||||
|
"integrity": "sha512-EOG8KXDQNwkJILkx/gPcoL/7vH+hORoBaKgGe+6W7VFMvCYJfmF2dGbvgDroVnI8LU7/kTu8mbjRZGBU1z9NTA==",
|
||||||
|
"hasInstallScript": true,
|
||||||
|
"bin": {
|
||||||
|
"vue-demi-fix": "bin/vue-demi-fix.js",
|
||||||
|
"vue-demi-switch": "bin/vue-demi-switch.js"
|
||||||
|
},
|
||||||
|
"engines": {
|
||||||
|
"node": ">=12"
|
||||||
|
},
|
||||||
|
"funding": {
|
||||||
|
"url": "https://github.com/sponsors/antfu"
|
||||||
|
},
|
||||||
|
"peerDependencies": {
|
||||||
|
"@vue/composition-api": "^1.0.0-rc.1",
|
||||||
|
"vue": "^3.0.0-0 || ^2.6.0"
|
||||||
|
},
|
||||||
|
"peerDependenciesMeta": {
|
||||||
|
"@vue/composition-api": {
|
||||||
|
"optional": true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
"node_modules/@vueuse/core": {
|
"node_modules/@vueuse/core": {
|
||||||
"version": "10.9.0",
|
"version": "10.9.0",
|
||||||
"resolved": "https://registry.npmjs.org/@vueuse/core/-/core-10.9.0.tgz",
|
"resolved": "https://registry.npmjs.org/@vueuse/core/-/core-10.9.0.tgz",
|
||||||
|
|
|
@ -10,6 +10,7 @@
|
||||||
},
|
},
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@fireworks-js/vue": "^2.10.7",
|
"@fireworks-js/vue": "^2.10.7",
|
||||||
|
"@vueuse/components": "^10.9.0",
|
||||||
"@vueuse/core": "^10.9.0",
|
"@vueuse/core": "^10.9.0",
|
||||||
"pinia": "^2.1.7",
|
"pinia": "^2.1.7",
|
||||||
"reset-css": "^5.0.2",
|
"reset-css": "^5.0.2",
|
||||||
|
|
|
@ -1,3 +1,99 @@
|
||||||
|
<script setup lang="ts">
|
||||||
|
import { ref } from 'vue';
|
||||||
|
import { UseDraggable } from '@vueuse/components';
|
||||||
|
import type { Position } from '@vueuse/core';
|
||||||
|
import { random_сolor, shuffle_array, getRandomIntInclusive } from '../helpers';
|
||||||
|
|
||||||
|
import icon1 from '~icons/mdi/square';
|
||||||
|
import icon1_o from '~icons/mdi/square-outline';
|
||||||
|
import icon2 from '~icons/mdi/triangle';
|
||||||
|
import icon2_o from '~icons/mdi/triangle-outline';
|
||||||
|
import icon3 from '~icons/mdi/circle';
|
||||||
|
import icon3_o from '~icons/mdi/circle-outline';
|
||||||
|
import icon4 from '~icons/mdi/hexagon';
|
||||||
|
import icon4_o from '~icons/mdi/hexagon-outline';
|
||||||
|
|
||||||
|
const icons = [
|
||||||
|
{
|
||||||
|
fill: icon1,
|
||||||
|
outline: icon1_o,
|
||||||
|
color: random_сolor(),
|
||||||
|
ref: ref<HTMLElement | null>(null)
|
||||||
|
},
|
||||||
|
{
|
||||||
|
fill: icon2,
|
||||||
|
outline: icon2_o, color: random_сolor(),
|
||||||
|
ref: ref<HTMLElement | null>(null)
|
||||||
|
},
|
||||||
|
{
|
||||||
|
fill: icon3,
|
||||||
|
outline: icon3_o, color: random_сolor(),
|
||||||
|
ref: ref<HTMLElement | null>(null)
|
||||||
|
},
|
||||||
|
{
|
||||||
|
fill: icon4,
|
||||||
|
outline: icon4_o, color: random_сolor(),
|
||||||
|
ref: ref<HTMLElement | null>(null)
|
||||||
|
},
|
||||||
|
]
|
||||||
|
|
||||||
|
const active_drag = ref<string | null>(null)
|
||||||
|
const dragStart = (_: Position, event: PointerEvent) => {
|
||||||
|
const element = event.currentTarget
|
||||||
|
if (element instanceof HTMLElement && element.dataset.id) {
|
||||||
|
active_drag.value = element.dataset.id
|
||||||
|
console.log(`update active drag ${element.dataset.id}`)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
const dragEnd = (position: Position, event: PointerEvent) => {
|
||||||
|
const target = document.elementsFromPoint(position.x, position.y).find(el => el.className == 'target-item')
|
||||||
|
if (target instanceof HTMLElement && target.dataset.id) {
|
||||||
|
const targetId = target.dataset.id
|
||||||
|
const sourceId = active_drag.value
|
||||||
|
if (targetId == sourceId) {
|
||||||
|
console.log('n')
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</script>
|
||||||
<template>
|
<template>
|
||||||
game time
|
<div class="game">
|
||||||
|
<div class="target">
|
||||||
|
<span class="target-item" v-for="(item, i) in shuffle_array(icons)" :data-id="i">
|
||||||
|
<component :is="item.outline" :style="{ 'color': item.color }"></component>
|
||||||
|
</span>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<UseDraggable v-for="(item, i) in shuffle_array(icons)" class="source-item" :data-id="i"
|
||||||
|
:initial-value="{ x: getRandomIntInclusive(100, 1400), y: getRandomIntInclusive(300, 700) }"
|
||||||
|
:on-start="dragStart" :on-end="dragEnd">
|
||||||
|
<component :is="item.fill" :style="{ 'color': item.color }" :ref="item.ref"></component>
|
||||||
|
</UseDraggable>
|
||||||
|
|
||||||
|
</div>
|
||||||
</template>
|
</template>
|
||||||
|
<style scoped lans="scss">
|
||||||
|
.game {
|
||||||
|
position: fixed;
|
||||||
|
display: flex;
|
||||||
|
height: 100vh;
|
||||||
|
width: 100vw;
|
||||||
|
position: relative;
|
||||||
|
}
|
||||||
|
|
||||||
|
.target {
|
||||||
|
display: flex;
|
||||||
|
width: 100%;
|
||||||
|
justify-content: center;
|
||||||
|
gap: 2rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
.target-item {
|
||||||
|
font-size: 12rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
.source-item {
|
||||||
|
font-size: 7rem;
|
||||||
|
position: absolute;
|
||||||
|
}
|
||||||
|
</style>
|
|
@ -3,3 +3,25 @@ export const getRandomIntInclusive = (min: number, max: number) => {
|
||||||
const maxFloored = Math.floor(max);
|
const maxFloored = Math.floor(max);
|
||||||
return Math.floor(Math.random() * (maxFloored - minCeiled + 1) + minCeiled); // The maximum is inclusive and the minimum is inclusive
|
return Math.floor(Math.random() * (maxFloored - minCeiled + 1) + minCeiled); // The maximum is inclusive and the minimum is inclusive
|
||||||
}
|
}
|
||||||
|
export const shuffle_array = (array: any[]) => {
|
||||||
|
let currentIndex = array.length;
|
||||||
|
|
||||||
|
// While there remain elements to shuffle...
|
||||||
|
while (currentIndex != 0) {
|
||||||
|
|
||||||
|
// Pick a remaining element...
|
||||||
|
let randomIndex = Math.floor(Math.random() * currentIndex);
|
||||||
|
currentIndex--;
|
||||||
|
|
||||||
|
// And swap it with the current element.
|
||||||
|
[array[currentIndex], array[randomIndex]] = [
|
||||||
|
array[randomIndex], array[currentIndex]];
|
||||||
|
}
|
||||||
|
return array
|
||||||
|
}
|
||||||
|
|
||||||
|
export const random_сolor = () => {
|
||||||
|
const r = () => Math.floor(200 * Math.random());
|
||||||
|
|
||||||
|
return `rgb(${r()}, ${r()}, ${r()})`;
|
||||||
|
}
|
Loading…
Reference in New Issue