Ojorrones y Tazamorras
by Marcos F
HTML
<script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.5.17/vue.js"></script>
<script src="https://fonts.googleapis.com/css?family=Roboto"></script>
<div id="app">
<div class="conv">
<div class="node" v-if="conv.text.length">
<div class="image">
<img :src="conv.char.avatar">
</div>
<div class="wrapper">
<h3>{{conv.char.name}}</h3>
<p>
{{conv.char.bio}}
</p>
<transition name="transition-text">
<div v-if="show.text">
<div class="text" v-html="conv.text"></div>
<ul class="options">
<li v-for="option in conv.options" @click="option._command">{{option.text}}</li>
</ul>
</div>
</transition>
</div>
</div>
<transition name="transition-text">
<div class="item-new" v-if="show.item">
<h3><strong>{{show.item.name}}</strong> added</h3>
</div>
</transition>
</div>
</div>
CSS
html {
font-size: 80%;
}
body {
margin: 0;
background: #424863;
color: white;
font-family: 'Roboto', sans-serif;
}
ul {
list-style: none;
display: flex;
margin: 0;
padding: 0;
}
li {
background: white;
color: #2e354c;
padding: 4px 10px;
cursor: pointer;
cursor: pointer;
border-radius: 2px;
}
li+li {
margin-left: 10px;
}
#app {
padding: 10px;
}
.node {
display: flex;
background: #2e354c;
padding: 16px;
border-radius: 4px;
}
.node .image {
width: 60px;
}
.node .image img {
width: 100%;
box-shadow: 0 2px 0 0 rgba(30, 34, 59, 0.5);
border-radius: 4px;
}
.node .wrapper {
padding-left: 20px;
width: calc(100% - 80px);
}
.node .wrapper h3 {
font-size: 1rem;
padding: 0;
margin: 0;
}
.node .wrapper p {
padding: 0;
margin: 0;
font-size: 0.9rem;
color: #979aa6;
}
.node .wrapper .text {
padding: 10px 0;
font-size: 1.2rem;
}
.item-new {
display: inline-block;
background: #eaeaea;
color: #666;
padding: 10px 16px;
margin-top: 10px;
border-radius: 4px;
}
.item-new h3 {
font-size: 1rem;
padding: 0;
margin: 0;
}
.item-new h3 strong {
color: #333;
}
.transition-text-enter-active {
transition: all 1s ease;
}
.transition-text-enter {
opacity: 0;
transform: translateY(20px);
}
.transition-text-enter-to {
opacity: 1;
transform: translateY(0);
}
.transition-text-leave-active {
transition: all .2s ease;
}
.transition-text-leave {
opacity: 1;
transform: translateY(0);
}
.transition-text-leave-to {
opacity: 0;
transform: translateY(20px);
}
JavaScript
var _vue = new Vue({
el: '#app',
data: {
chars: {},
inventory: {},
conv: {
char: false,
text: '',
options: []
},
show: {
text: false,
item: false
}
},
mounted: function() {
/* INI-Here goes the chars */
this.char_create({
'name': 'anorak',
'avatar': 'https://encrypted-tbn0.gstatic.com/images?q=tbn:ANd9GcQzLhaCL4X9MH1FzZhsiq_jpd4--l0SLPNyYg&usqp=CAU',
'bio': 'abrigrate que hace fresco'
});
this.char_create({
'name': 'el ano del calabozo',
'avatar': 'https://encrypted-tbn0.gstatic.com/images?q=tbn:ANd9GcRfue2_Pgq5Fo9W42jcEi9H_Jrg2HohRTGHtA&usqp=CAU',
'bio': 'el apretón definitivo'
});
/* END-Here goes the chars */
/* INI-Here goes the logic */
this.char_say('anorak', 'es peligroso ir solo ...', [{
'text': 'Coger espada',
'command': () => {
this.item_give({
'name': 'Espada alargada'
});
return this.char_say('anorak', 'bien hecho');
}
}]).then((text) => {
return this.char_say('anorak', 'algo más? que no se te olvide nada', [{
'text': 'Coger una muda por si acaso',
'command': () => {
this.item_give({
'name': 'Calzoncillos espaciales'
});
return this.char_say('anorak', 'En marcha');
}
}, {
'text': 'Nunca llevé ropa interior',
'command': () => {
return this.char_say('anorak', 'En marcha');
}
}]);
}).then((text) => {
return this.char_say('anorak', 'Algo se mueve entre los arbustos');
}).then((text) => {
return this.char_say('el ano del calabozo', 'Eh!, idos a molestar a otra parte');
});
/* END-Here goes the logic */
},
methods: {
char_create: function(charOB) {
this.$set(this.chars, charOB.name, charOB);
},
char_say: function(name, text, options) {
return new Promise((resolve, reject) => {
if (!(name in...