Create a Click Shape Game with Vue 3 and JavaScript

John Au-Yeung - Jan 17 '21 - - Dev Community

Check out my books on Amazon at https://www.amazon.com/John-Au-Yeung/e/B08FT5NT62

Subscribe to my email list now at http://jauyeung.net/subscribe/

Vue 3 is the latest version of the easy to use Vue JavaScript framework that lets us create front end apps.

In this article, we’ll look at how to create a click shape game with Vue 3 and JavaScript.

Create the Project

We can create the Vue project with Vue CLI.

To install it, we run:

npm install -g @vue/cli
Enter fullscreen mode Exit fullscreen mode

with NPM or:

yarn global add @vue/cli
Enter fullscreen mode Exit fullscreen mode

with Yarn.

Then we run:

vue create click-shape-game
Enter fullscreen mode Exit fullscreen mode

and select all the default options to create the project.

Create the Click Shape Game

The game lets us score by clicking on shapes that are shown in random locations.

To create the click shape game, we write:

<template>
  <button @click="start">start game</button>
  <button @click="end">end game</button>
  <p>score: {{ score }}</p>
  <div
    class="circle"
    v-if="circleX && circleY"
    :style="{ position: 'absolute', top: `${circleY}px`, left: `${circleX}px` }"
    @click="onClick"
  >
    &nbsp;
  </div>
</template>

<script>
export default {
  name: "App",
  data() {
    return {
      score: 0,
      circleX: undefined,
      circleY: undefined,
      timer: undefined,
    };
  },
  methods: {
    onClick() {
      this.score++;
    },
    start() {
      this.timer = setInterval(() => {
        this.circleX = Math.floor(Math.random() * window.innerWidth);
        this.circleY = Math.floor(
          Math.random() * (window.innerHeight - 50) + 50
        );
      }, 2000);
    },
    end() {
      clearInterval(this.timer);
      this.score = 0;
      this.circleX = undefined;
      this.circleY = undefined;
    },
  },
  beforeUnmount() {
    clearInterval(this.timer);
  },
};
</script>

<style scoped>
.circle {
  border: 1px solid black;
  width: 50px;
  height: 50px;
  border-radius: 50%;
}
</style>
Enter fullscreen mode Exit fullscreen mode

In the template, we have a button with the start game and end game buttons to start and end the game timer.

Below that, we have the score display.

And then we have the div that the player clicks on to score.

We set the style prop to the style with the top and left values. We need the px at the end to specify the position.

In the script tag, we have the data method to return the reactive property with their initial values.

circleX and circleY have the left and top values respectively.

timer has the timer.

onClick is the click handler of the div.

In the start method, we call setInterval with the callback to set the circleX and circleY values.

We set them to random values that are within the width and height of the screen.

In the end method, we call clearInterval to stop the timer.

And we reset the other reactive properties to their initial values.

In the beforeUnmount hook, we call clearInterval to remove the timer.

Then in the style tag, we have styles to make the div with class circle a circle.

Conclusion

We can create a click shape game easily with Vue 3 and JavaScript.

. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .