146 lines
6.9 KiB
Vue
146 lines
6.9 KiB
Vue
<template>
|
|
<teleport to=".scene-designer .lines" v-if="active">
|
|
<OffsetLine v-for="(t, i) in modelValue.activationTriggers" :x1="vd.x1" :y1="vd.y1"
|
|
:x2="parent.data.items.find(i=>i.data.id == t)?.vd.x1"
|
|
:y2="parent.data.items.find(i=>i.data.id == t)?.vd.y1" :o1="52" :o2="52"
|
|
class="trigger" marker-start="url(#arrow)" ></OffsetLine>
|
|
</teleport>
|
|
<teleport to=".scene-designer .game-objects" v-if="active">
|
|
<g @mousedown="$emit('target', {target:vd, attrs:['x1', 'y1'], delta: true})" :class="{gameObject: true, selected}"
|
|
v-show="showInView">
|
|
<line :x1="vd.x1" :y1="vd.y1" :x2="parent.vd.x1" :y2="parent.vd.y1"></line>
|
|
<svg-icon :src="`/asset/thumb/${modelValue.go||modelValue.type}.webp`" :x="vd.x1" :y="vd.y1" :size="37"></svg-icon>
|
|
<text :x="vd.x1" :y="vd.y1" dy="58">{{ modelValue.title }}</text>
|
|
<image v-if="modelValue.go" :href="`/asset/thumb/${modelValue.type}.webp`" width="25" class="cursor-pointer"
|
|
:x="vd.x1 + 37 - 10" :y="vd.y1 - 37 - 10">
|
|
</image>
|
|
<image v-if="modelValue.go" href="/static/svg/play-circle.svg" width="20" class="cursor-pointer"
|
|
:x="vd.x1 + 37 - 10" :y="vd.y1 + 37 - 10" @click="$emit('preview', modelValue.go)">
|
|
</image>
|
|
</g>
|
|
</teleport>
|
|
<teleport to=".scene-designer .lines" v-if="active && targetScene">
|
|
<OffsetLine :x1="targetScene.vd.x1" :y1="targetScene.vd.y1"
|
|
:x2="modelValue.__this.vd.x1" :y2="modelValue.__this.vd.y1" :o1="88" :o2="55"
|
|
class="scene-switcher" marker-start="url(#arrow)" ></OffsetLine>
|
|
</teleport>
|
|
<v-card v-if="selected" :title="modelValue.title" class="mx-2" variant="text">
|
|
<v-select :label="l.gameObjectType" v-model="modelValue.type" density="compact" hide-details
|
|
:items="InteractiveObjectTypes.map(e=>({title: l.interactiveObjects[e], value: e}))">
|
|
<template v-slot:item="{ props }">
|
|
<v-list-item v-bind="props">
|
|
<template v-slot:append>
|
|
<img :src="`/asset/thumb/${props.value}.webp`" height="37"></img>
|
|
</template>
|
|
</v-list-item>
|
|
</template>
|
|
</v-select>
|
|
<v-form class="pt-4">
|
|
<v-text-field density="compact" :label="l.name" v-model="modelValue.title"></v-text-field>
|
|
<!-- <v-text-field density="compact" :label="l.id" v-model="modelValue.id"></v-text-field> -->
|
|
<v-number-input density="compact" v-if="!cpc[modelValue.type].__noPoints" :label="l.completionPoints" v-model="modelValue.points"></v-number-input>
|
|
</v-form>
|
|
<div v-if="selected && modelValue.type">
|
|
<component :is="modelValue.type" v-model="mv"></component>
|
|
</div>
|
|
|
|
<v-card :title="l.activationConditions" v-if="modelValue.type != 'CharacterObject'">
|
|
<v-number-input density="compact" :label="l.minActivationScore" v-model="modelValue.activationScore"></v-number-input>
|
|
<v-select density="compact" :label="l.completionElements" v-model="modelValue.activationTriggers"
|
|
:items="parent.data.items.filter(v=>!v.data.exclude && v.data!==modelValue).map(v=>({title: v.data.title, value: v.data.id}))" multiple ></v-select>
|
|
<v-select :label="l.activatoinType" :items="activationTypes" density="compact" v-model="modelValue.activationType"></v-select>
|
|
</v-card>
|
|
</v-card>
|
|
|
|
</template>
|
|
|
|
<script>
|
|
import SvgIcon from './SvgIcon.vue';
|
|
|
|
import VideoPlayer from '../InteractiveObjects/VideoPlayer/VideoPlayer.vue';
|
|
import TextObject from '../InteractiveObjects/TextObject/TextObject.vue';
|
|
import ImageObject from '../InteractiveObjects/ImageObject/ImageObject.vue';
|
|
import PuzzleGame1 from '../InteractiveObjects/PuzzleGame1/PuzzleGame1.vue';
|
|
import PuzzleGame2 from '../InteractiveObjects/PuzzleGame2/PuzzleGame2.vue';
|
|
import MazeQuizGame from '../InteractiveObjects/MazeQuizGame/MazeQuizGame.vue';
|
|
import ClassicPuzzle from '../InteractiveObjects/ClassicPuzzle/ClassicPuzzle.vue';
|
|
import PairMatchingGame from '../InteractiveObjects/PairMatchingGame/PairMatchingGame.vue';
|
|
import SingleQuestion from '../InteractiveObjects/SingleQuestion/SingleQuestion.vue';
|
|
import Particles from '../InteractiveObjects/Particles/Particles.vue';
|
|
import GenericObject from '../InteractiveObjects/GenericObject/GenericObject.vue';
|
|
import CharacterObject from '../InteractiveObjects/CharacterObject/CharacterObject.vue';
|
|
import SceneSwitcher from '../InteractiveObjects/SceneSwitcher/SceneSwitcher.vue';
|
|
import Teleporter from '../InteractiveObjects/Teleporter/Teleporter.vue';
|
|
import OffsetLine from './OffsetLine.vue';
|
|
|
|
import { InteractiveObjectTypes } from '../InteractiveObjects/InteractiveObject';
|
|
|
|
const components = {
|
|
SvgIcon, OffsetLine, GenericObject, CharacterObject, VideoPlayer, TextObject, ImageObject, SceneSwitcher,
|
|
PuzzleGame1, PuzzleGame2, MazeQuizGame, Particles, ClassicPuzzle, PairMatchingGame, SingleQuestion, Teleporter
|
|
};
|
|
|
|
import { markRaw } from 'vue';
|
|
|
|
export default {
|
|
emits:['target', 'preview'],
|
|
props:{
|
|
//context: Object,
|
|
modelValue: Object,
|
|
vd: Object,
|
|
selected: Boolean,
|
|
cid:String,
|
|
visible: Boolean,
|
|
parent: Object
|
|
},
|
|
data(){
|
|
return {
|
|
InteractiveObjectTypes,
|
|
active: false,
|
|
activationTypes: ['unlock', 'appear'],
|
|
cpc: markRaw(components)
|
|
}
|
|
},
|
|
components,
|
|
mounted(){
|
|
this.active = true;
|
|
this.modelValue.points ??= 10;
|
|
this.modelValue.activationScore ??= 0;
|
|
this.modelValue.type ??= 'GenericObject';
|
|
//this.modelValue.title ??= this.l.interactiveObjects[this.modelValue.type]
|
|
this.activationTypes = this.activationTypes.map(t=>({title: this.l.activationTypes[t], value: t}))
|
|
if (components[this.modelValue.type].__transform){
|
|
components[this.modelValue.type].__transform(this.modelValue)
|
|
}
|
|
},
|
|
watch:{
|
|
'modelValue.type'(n){
|
|
if (components[this.modelValue.type].__noPoints){
|
|
this.modelValue.points = 0;
|
|
}else{
|
|
this.modelValue.points = 10;
|
|
}
|
|
}
|
|
},
|
|
computed:{
|
|
showInView(){
|
|
this.vd.__showInView = this.visible && this.parent.visible;
|
|
return this.vd.__showInView;
|
|
},
|
|
mv(){
|
|
return this.modelValue
|
|
},
|
|
targetScene(){
|
|
return this.modelValue.__root.scenes.find(s=>s.data.id == this.modelValue?.switchScene)
|
|
},
|
|
},
|
|
steps: [['x1', 'y1']],
|
|
name: 'game-object',
|
|
modifiers: ['x1', 'y1'],
|
|
methods:{
|
|
intersect(v){
|
|
return Utils.intersectPointRect([this.vd.x1, this.vd.y1], v);
|
|
}
|
|
}
|
|
}
|
|
</script> |