<div id="app">
  <!-- bag image -->
  <div 
    class="bag"
    v-bind:class="bagDestroyed"
  >
  </div>
  <!-- bag health -->
  <div class="bag-health">
    <div v-bind:style="{width: health + '%'}"></div>
  </div>
  <!-- game controls -->
  <div class="controls">
    <button
      class="punch"
      v-show="!ended"
      v-on:click="onPunch"
    >
      Punch
    </button>

    <button
      v-on:click="onRestart"
    >
      Restart
    </button>
  </div>
.bag {
    width: 200px;
    height: 300px;
    margin: 0 auto;
    background: url('https://raw.githubusercontent.com/iamshaunjp/vuejs-playlist/lesson-13/img/bag.png') center no-repeat;
    background-size: 50%;
    transform-origin: 50% 0;
}

.bag.burst {
    background: url('https://raw.githubusercontent.com/iamshaunjp/vuejs-playlist/lesson-13/img/bag-burst.png') center no-repeat;
    background-size: 50%; 
}

.bag-health {
    width: 200px;
    border: 2px solid #000;
    border-radius: 20px;
    margin: 0 auto 20px auto;
}

.bag-health div {
    height: 20px;
    border-radius: 20px;
    background: crimson;
}

.controls {
    width: 135px;
    margin: 0 auto;
}

.controls button {
  color: blue;
  background: none;
  border: 2px solid blue;
  border-radius: 20px;
  padding: 10px;
}
.controls button:active {
  background: #3f5efb;
  color: #fff;
  transition: .5s;
}

button:focus {
  outline: none;
}

.rotate {
    animation: rotate .5s;
}

.rrotate {
    animation: rrotate .5s;
}

@keyframes rotate {
    0% {
        transform: rotate(0deg);
    }
    40% {
        transform: rotate(20deg);
    }
    60% {
        transform: rotate(0deg);
    }
    70% {
        transform: rotate(-20deg);
    }
    100% {
        transform: rotate(0deg);
    }
}

@keyframes rrotate {
    0% {
        transform: rotate(0deg);
    }
    40% {
        transform: rotate(-20deg);
    }
    60% {
        transform: rotate(0deg);
    }
    70% {
        transform: rotate(20deg);
    }
    100% {
        transform: rotate(0deg);
    }
}
new Vue ({
    el: '#app',
    data: {
        health: 100,
        ended: false,
        rotate: true,
        rotateRev: false
    },
    methods: {
        onPunch: function() {
            this.health -= 10;
            this.rotate = !this.rotate;
            this.rotateRev = !this.rotateRev;
            if (this.health <= 0) {
                this.ended = true;
            }
        },

        onRestart: function() {
            this.health = 100;
            this.ended = false;
            this.rotate = true;
            this.rotateRev = false;
        }
    },
    computed: {
        bagDestroyed: function() {
            return {
                burst: this.ended,
                rotate: this.rotate,
                rrotate: this.rotateRev,
            }
        }
    }
});

External CSS

This Pen doesn't use any external CSS resources.

External JavaScript

  1. https://cdnjs.cloudflare.com/ajax/libs/vue/2.6.10/vue.min.js