Demogorgon slayer

Fight against a demogorgon. This is just a test project for vue js.

by Markus Westphal

HTML

<!DOCTYPE html>
<html>

  <head>
    <title>Demogorgon Slayer</title>
    <script src="https://npmcdn.com/vue/dist/vue.js"></script>
    <link rel="stylesheet" href="css/foundation.min.css">
    <link rel="stylesheet" href="css/app.css">
  </head>

  <body class="dark">
    <div id="app">
      <section class="row" :class="{rotate: rotate}">
        <div class="small-6 columns">
          <h1 class="text-center">YOU</h1>
          <div class="healthbar">
            <div class="healthbar text-center" style="background-color: green; margin: 0; color: white;" :style="{width: myHealth + '%'}">
              {{ myHealth }} %
            </div>
          </div>
        </div>
        <div class="small-6 columns">
          <h1 class="text-center">DEMOGORGON</h1>
          <div class="healthbar">
            <div class="healthbar text-center" style="background-color: green; margin: 0; color: white;" :style="{width: demoHealth + '%'}">
              {{ demoHealth }} %
            </div>
          </div>
        </div>
      </section>
      <section class="row controls" v-show="!showControls">
        <div class="small-12 columns">
          <button id="start-game" @click="resetValues()">START NEW GAME</button>
        </div>
      </section>
      <section class="row controls" v-show="showControls" :class="{rotate: rotate}">
        <div class="small-12 columns">
          <button id="attack" @click="attack()">ATTACK</button>
          <button id="special-attack" @click="specialAttack()" :disabled="maxSpecials == 0">SPECIAL ATTACK</button>
          <button id="heal" @click="heal()" :disabled="maxHeal == 0">HEAL</button>
          <button id="give-up" @click="resetValues(); showControls = false">GIVE UP</button>
        </div>
      </section>
      <section class="row log" v-show="logElements.length > 0">
        <div class="small-12 columns">
          <ul v-for="element in logElements">
            <li :class="element.type">
              {{element.message}}
       ...

CSS

@import url('https://fonts.googleapis.com/css?family=Permanent+Marker&display=swap');

.dark {
  background-color: #1c0502;
  color: #ed2b12;
  font-family: 'Permanent Marker', cursive;
  text-transform: uppercase;
}

#app {
  width: 100%;
  height: 100%;
  z-index: 99;
}

canvas {
  position: fixed;
  padding: 0;
  margin: 0;
  top: 0;
  left: 0;
  width: 100%;
  height: 100%;
  z-index: -99;
}

.text-center {
  text-align: center;
}

.healthbar {
  width: 80%;
  height: 40px;
  background-color: #d5d5d5;
  margin: auto;
  transition: width 500ms;
}

.controls,
.log {
  margin-top: 30px;
  text-align: center;
  padding: 10px;
  border: 1px solid #ccc;
  box-shadow: 0px 3px 6px #ccc;
  z-index: 99;
}

.turn {
  margin-top: 20px;
  margin-bottom: 20px;
  font-weight: bold;
  font-size: 22px;
}

.log ul {
  list-style: none;
  font-weight: bold;
  text-transform: uppercase;
}

.log ul li {
  margin: 5px;
}

.log ul .player-turn {
  color: black;
  background-color: yellow;
}

.log ul .monster-turn {
  color: #ed2b12;
  background-color: black;
}

button {
  font-size: 20px;
  background-color: #eee;
  padding: 12px;
  box-shadow: 0 1px 1px black;
  margin: 10px;
}

#start-game {
  color: black;
  background-color: #ed2b12;
}

#start-game:hover {
  color: #ed2b12;
  background-color: black;
}

#attack {
  color: black;
  background-color: #ed2b12;
}

#attack:hover {
  color: #ed2b12;
  background-color: black;
}

#special-attack {
  background-color: #000000;
}

#special-attack:hover {
  background-color: #f7ff00;
}

#heal {
  background-color: #aaffb0;
}

#heal:hover {
  background-color: #76ff7e;
}

#give-up {
  background-color: #ffffff;
}

#give-up:hover {
  background-color: #c7c7c7;
}

.rotate {
  transform: rotate(-180deg);

  /* Safari */
  -webkit-transform: rotate(-180deg);

  /* Firefox */
  -moz-transform: rotate(-180deg);

  /* IE */
  -ms-transform: rotate(-180deg);

  /* Opera */
  -o-transform: rotate(-180deg);

  /* Internet Explorer */
  filter:...

JavaScript

new Vue({
  el: '#app',
  data: {
    showControls: false,
    myHealth: 100,
    demoHealth: 100,
    logElements: [],
    maxSpecials: 3,
    maxHeal: 5,
    rotate: false
  },
  methods: {
    resetValues: function() {
      this.showControls = true;
      this.myHealth = 100;
      this.demoHealth = 100;
      this.logElements = [];
      this.maxHeal = 5;
      this.maxSpecials = 3;
      this.rotate = false;
    },
    attack: function() {
      let meDamage = Math.floor(Math.random() * 5 + 1);
      let demoDamage = Math.floor(Math.random() * 5 + 1);
      this.promoteHits(meDamage, demoDamage);
      this.winOrLose();
    },
    specialAttack: function() {
      if (this.maxSpecials > 0) {
        let meDamage = Math.floor(Math.random() * 5 + 1);
        let demoDamage = Math.floor(Math.random() * 10 + 1);
        this.promoteHits(meDamage, demoDamage);
        this.maxSpecials -= 1;
      } else {
        alert('No specials left!');
      }
      this.winOrLose();
    },
    heal: function() {
      if (this.maxHeal > 0) {
        this.myHealth += this.myHealth <= 100 ? 10 : 0;
        let meDamage = Math.floor(Math.random() * 5 + 1);
        this.logElements.unshift({
          message: 'YOU GOT A MEDIKIT: + 10',
          type: 'player-turn'
        });
        this.promoteHits(meDamage, 0);
        this.maxHeal -= 1;
      } else {
        alert('No medikits left!');
      }
      this.winOrLose();
    },
    winOrLose: function() {
      if (this.myHealth <= 0) {
        alert('GAME OVER');
        this.logElements.unshift({
          message: 'YOU ARE DEAD!',
          type: 'monster-turn'
        });
        this.showControls = false
      } else if (this.demoHealth <= 0) {
        alert('YOU WIN!!!');
        this.showControls = false;
        this.logElements.unshift({
          message: 'YOU KILLED THE DEMOGORGON!',
          type: 'player-turn'
        });
        this.rotate = false;
      }
    },
    promoteHits: function(meDamage,...