Este es un juego sencillo para niños que están aprendiendo las tablas de multiplicar. Lo he publicado a manera didáctica sobre lo que se puede hacer en WordPress usando además HTML/CSS/Vue.JS/Bootstrap 4.5.
Dedicado al gran Santiago el Leoncito Núñez.
El código fuente está realizado en HTML/CSS/JS con Bootstrap 4 y VueJS.
¡Espero que les sea de utilidad!
{{welcome}}
{{description}}
Haz clic en empezar cuando estés listo!
| {{item}} | ||||
|---|---|---|---|---|
| {{operation.question}} | {{operation.result}} |
{{finalResultMessage}}
Seguidamente presentamos el código fuente para efectos didácticos.
Haz clic para ver el código fuente<!DOCTYPE html>
<html>
<head>
<title>Juego de las Tablas de Multiplicar</title>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
</head>
<body>
<!--CDN-based Bootstrap and VueJS-->
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/4.5.2/css/bootstrap.min.css">
<script src="https://cdn.jsdelivr.net/npm/vue@2.6.14"></script>
<!--APP: The HTML Side-->
<div id="app" class="container-fluid">
<!--Welcome-->
<h2 class="text-primary">{{welcome}}</h2>
<h4 class="text-info">{{description}}</h4>
<p class="text-info">Haz clic en empezar cuando estés listo!</p>
<!--Botón para iniciar el juego-->
<button class="btn btn-primary"
v-on:click="begin"
:disabled="operations.length>0 && operations.length < maxRounds">{{cmdBegin_text}}</button>
<hr>
<!-- UI Principal del juego -->
<table class="table table-sm-center table-bordered table-hover text-sm">
<tr>
<th v-for="item in opHeaders" class="text-center">{{item}}</th>
</tr>
<tr v-for="operation in operations">
<td class="text-center" style="white-space: nowrap;">{{operation.question}}</td>
<td class="text-center"><button :disabled="!operation.active" v-on:click="checkResponse(operation, operation.op1)" class="btn btn-sm btn-warning text-center" style="width: 3.5em"><span>{{operation.op1}}</span></button></td>
<td class="text-center"><button :disabled="!operation.active" v-on:click="checkResponse(operation, operation.op2)" class="btn btn-sm btn-warning text-center" style="width: 3.5em">{{operation.op2}}</button></td>
<td class="text-center"><button :disabled="!operation.active" v-on:click="checkResponse(operation, operation.op3)" class="btn btn-sm btn-warning text-center" style="width: 3.5em">{{operation.op3}}</button></td>
<td class="text-center"><span class="text-center" style="width: 10em">{{operation.result}}</span></td>
</tr>
</table>
<!-- Resumen de resultados -->
<div>
<button type="button" class="btn btn-primary" style="margin:5px">
<span class="badge badge-light">{{totalTries}} </span> Intentos
</button>
<button type="button" class="btn btn-danger" style="margin:5px">
<span class="badge badge-light">{{totalErrors}} </span> Errores
</button>
<button type="button" class="btn btn-info" style="margin:5px">
<span class="badge badge-light">{{totalTries > 0 ? ((1-(totalErrors/totalTries))*100).toFixed(2): 0}} % </span> Efectividad
</button>
<button type="button" class="btn btn-info" style="margin:5px">
<span class="badge badge-light">{{(averageTimeMs/1000).toFixed(2)}}seg.</span> Tiempo Promedio
</button>
<h4 class="text-primary">{{finalResultMessage}}</h4>
</div>
</div>
<!-- Client side logic -->
<script>
var myObject = new Vue({
el: '#app',
data: {
welcome: '¡Bienvenido al juego de las Tablas de Multiplicar!',
description: 'Conforme aparecen las operaciones deberás escoger la respuesta correcta. Tu misión es responder en el menor tiempo posible.',
opHeaders: ["Reto", "(a)", "(b)", "(c)", "Tiempo"],
cmdBegin_text: "Empezar",
operations: [],
maxRounds: 5,
totalTries: 0,
totalErrors: 0,
totalTimeMs: 0,
averageTimeMs: 0,
finalResultMessage: ""
},
methods: {
/**
* Inicia una partida
* @return {undefined}
*/
begin: function () {
let vm = this;
vm.resetData(vm);
vm.createChallenge(vm);
vm.cmdBegin_text = "Jugando...";
},
/**
* Chequea y procesa la respuesta del usuario.
* @param {type} operation
* @param {type} response
* @return {undefined}
*/
checkResponse: function (operation, response) {
let vm = this;
vm.totalTries++;
if (operation.rightAnswer === response) {
operation.active = false;
clearInterval(operation.timer);
vm.totalTimeMs += operation.timerCounter;
vm.averageTimeMs = vm.totalTimeMs / vm.operations.length;
if ((vm.operations).length < vm.maxRounds) {
vm.createChallenge(vm);
} else {
if (vm.totalTries > 0 && (vm.totalErrors / vm.totalTries) < 0.20) {
vm.finalResultMessage = `¡FELICITACIONES! tu promedio de efectividad es ${(100 * (1 - (vm.totalErrors / vm.totalTries))).toFixed(2)}% con un tiempo promedio de ${(vm.averageTimeMs / 1000).toFixed(2)} segundos.`;
} else {
vm.finalResultMessage = `Tu promedio de efectividad es bajo (${(100 * (1 - (vm.totalErrors / vm.totalTries))).toFixed(2)} %). Mejor suerte la próxima vez.`;
}
vm.cmdBegin_text = "Volver a Jugar";
}
} else {
vm.totalErrors++;
}
console.log(operation, response);
},
resetData: function (vm) {
vm.totalTries = 0;
vm.totalErrors = 0;
vm.totalTimeMs = 0;
vm.averageTimeMs = 0;
vm.finalResultMessage = "";
vm.operations = [];
},
intervalProcessor: function (opToAdd) {
opToAdd.timerCounter += 100;
if (opToAdd.timerCounter < 1000) {
opToAdd.result = opToAdd.timerCounter + " ms";
} else {
opToAdd.result = (opToAdd.timerCounter / 1000).toFixed(2) + " s";
}
},
craftOptions: function (goodResult) {
let options = [];
const goodPosition = Math.floor(Math.random() * 3);
for (let i = 0; i < 3; i++) {
if (i === goodPosition) {
options.push(goodResult);
} else {
let option = -1;
while (option === -1 || option === goodResult) {
option = Math.floor(Math.random() * 10 + 1) * Math.floor(Math.random() * 10 + 1);
}
options.push(option);
}
}
return options;
},
/**
* Inicializa una nueva operación
* @param {type} vm
* @return {undefined}
*/
createChallenge: function (vm) {
const operand1 = Math.floor(Math.random() * 10 + 1);
const operand2 = Math.floor(Math.random() * 10 + 1);
const goodResult = operand1 * operand2;
const options = vm.craftOptions(goodResult);
let opToAdd = {
question: `${operand1} X ${operand2}`,
op1: options[0],
op2: options[1],
op3: options[2],
result: "0.00 ms",
rightAnswer: goodResult
};
opToAdd.timerCounter = 0;
opToAdd.active = true;
opToAdd.timer = setInterval(function () {
vm.intervalProcessor(opToAdd);
}, 100);
vm.operations.push(opToAdd);
console.log(opToAdd);
}
}
});
</script>
</body>
</html>
![]()
Comentarios