Teach you step by step to develop a brick-breaking game with vue3

Teach you step by step to develop a brick-breaking game with vue3

Preface

I wrote a few examples using vue3, and I feel that the composition API of Vue3 is well designed. I changed my habits a bit, but it would be nice to write two more. This time I am writing about a game that I found very fun in my childhood - Breakout. It is fun to play when I am bored and the playability is quite high. This time I tried to use vite+vue3 packaging directly. Vite is also ready to use out of the box. Its feature is that it can also clear dead code and package on demand, so the packaging speed is also very fast. Students who have not used it can try it.

Game Effects

Game Requirements

  1. Create a scene
  2. Create a ball and a bunch of hit blocks
  3. Create a movable block that can be controlled to move left and right
  4. When the ball hits the left and right upper boundaries and the moving block, it bounces back
  5. The game ends when the ball hits the lower boundary

Full code

<template>

    <button @click="stop">Stop</button>
    <button @click="start">Game start</button>
    <div style="color: red; text-align: center;font-size: 25px">score:{{scroce}}</div>

    <div class="box" :style="{width :boxWidth +'px', height:boxHeight +'px'}">
        <div class="str">{{str}}</div>
        <div class="kuaiBox">
            <div class="kuai" v-for="(item,index) in arr" :key="index" :style="{opacity :item.active ? '0':'1'}"></div>
        </div>
        <div class="ball" :style="{left :x + 'px', top : y + 'px', width : ball +'px', height: ball+'px'}"></div>
        <div class="bottomMove"
             :style="{left :mx + 'px' , top : my + 'px',width :moveBottomW +'px',height : moveBottomH+'px' }"></div>
    </div>
</template>

<script setup>
    import {onMounted, onUnmounted, reactive, toRefs} from 'vue'

    const boxWidth = 500, // Scene width boxHeight = 300, // Scene height ball = 10, // Ball width and height moveBottomH = 5, // Move block height moveBottomW = 100 // Move block quick reading const strArr = 'Congratulations, challenge successful!!'

    //Use reactive to save some observable information const state = reactive({
        x: boxWidth / 2 - ball / 2, // The default position of the ball's x-axis position is in the middle y: boxHeight - ball - moveBottomH, // The default position of the ball's y-axis position is in the middle mx: boxWidth / 2 - moveBottomW / 2, // The default position of the moving block is in the middle my: boxHeight - moveBottomH, // The default position of the moving block's y-axis position is in the middle // Array of hit blocks arr: Array.from({length: 50}, (_, index) => {
            return {
                index,
                active: false
            }
        }),
        str: '', // Returns the word "successful challenge" scroce: 0 // Score })
    // Use toRefs to deconstruct the information of the observed object for template use const {x, y, mx, my, arr, str, scroce} = toRefs(state)
    let timer = null, // ball timer speed = 3, // ball speed map = {x: 10, y: 10},
        timer2 = null, // Challenge success word display timer index = 0 // Challenge success word display index value // Challenge success word display method const strFun = () => {
        if (strArr.length === index) clearInterval(timer2)
        state.str += strArr.substr(index, 1)
        index++
    }

    
    //Method for moving the ball// 1. Here, the map object is used to record the coordinate information to determine whether the ball bounces when it hits the left, right, top, and moving blocks// 2. Loop through the bricks to detect when the ball collides with the bricks and disappears const moveBall = () => {
        const {offsetTop, offsetHeight, offsetLeft, offsetWidth} = document.querySelector('.bottomMove')
        if (state.x <= 0) {
            map.x = speed
        } else if (state.x > boxWidth - ball) {
            map.x = -speed
        }
        if (state.y <= 0) {
            map.y = speed
        }
        if (state.y >= offsetTop - offsetHeight &&
            state.y <= offsetTop + offsetHeight &&
            state.x >= offsetLeft &&
            state.x < offsetLeft + offsetWidth) {
            map.y = -speed
        }
        if (state.y > boxHeight) {
            clearInterval(timer)
            alert('game over')
            window.location.reload()
        }
        Array.from(state.arr).forEach((item, index) => {
            const {
                offsetLeft,
                offsetTop,
                offsetWidth,
                offsetHeight
            } = document.querySelectorAll('.kuai')[index]
            if (state.x > offsetLeft
                && state.x < offsetLeft + offsetWidth
                && state.y > offsetTop
                && state.y < offsetTop + offsetHeight) {
                if (!state.arr[index].active) {
                    state.scroce += 100
                }
                state.arr[index].active = true
            }
        })
        if (Array.from(state.arr).every(item => item.active)) {
            clearInterval(timer)
            timer2 = setInterval(strFun, 1000)
        }
        state.x = state.x += map.x
        state.y = state.y += map.y
    }

    //Method to move the block left and right, catch the ball const bottomMove = ev => {
        if (ev.code === 'Space') clearInterval(timer)
        switch (ev.key) {
            case 'ArrowRight':
                state.mx += 100
                break
            case 'ArrowLeft':
                state.mx -= 100
                break
        }
        state.mx = state.mx < 0 ? 0 : state.mx
        state.mx = state.mx > boxWidth - moveBottomW ? boxWidth - moveBottomW : state.mx
    }
    // Pause the game const stop = () => {
        clearInterval(timer)
    }
    // Start the game const start = () => {
        timer = setInterval(moveBall, 20)
    }
    
    // Bind moving block event onMounted(() => {
        document.addEventListener('keyup', bottomMove)
    })
    // Move out of the moving block event onUnmounted(() => {
        clearInterval(timer)
    })
</script>

<style>

    .bottomMove {
        width: 100px;
        height: 10px;
        background: red;
        position: absolute;
        transition-duration: 100ms;
        transition-timing-function: ease-out;
    }

    .ball {
        width: 20px;
        height: 20px;
        background-color: red;
        border-radius: 50%;
        position: absolute;
    }

    .kuaiBox {
        display: flex;
        flex-wrap: wrap;
    }

    .kuai {
        width: 30px;
        height: 10px;
        background: red;
        margin: 10px;
        transition-duration: 100ms;
        transition-timing-function: ease-in;
    }

    .str {
        text-align: center;
        font-size: 50px;
        color: red;

    }

    .box {

        justify-content: center;
        width: 500px;
        height: 500px;
        margin: 0 auto;
        position: relative;
        border: 5px solid red;
        overflow: hidden;
    }

    .picker {
        width: 50px;
        height: 50px;
    }
</style>

at last

I will continue to use vue3 and write more examples in the future.

Attached is the address of the brick breaking game

shinewen189.github.io/nigo-ball-v…

This is the end of this article about developing a brick-breaking game with vue3. For more relevant vue3 brick-breaking game content, please search 123WORDPRESS.COM's previous articles or continue to browse the following related articles. I hope everyone will support 123WORDPRESS.COM in the future!

You may also be interested in:
  • An example of refactoring a jigsaw puzzle game using vue3

<<:  How to quickly create tens of millions of test data in MySQL

>>:  The difference and usage of Ctrl+z, Ctrl+c and Ctrl+d in Linux commands

Recommend

How to add ansible service in alpine image

Use apk add ansible to add the ansible service to...

Detailed explanation of styles in uni-app

Table of contents Styles in uni-app Summarize Sty...

CSS3 uses the transition property to achieve transition effects

Detailed description of properties The purpose of...

Detailed explanation of cocoscreater prefab

Table of contents Prefab How to create a prefab T...

How to reset the root password in mysql8.0.12

After installing the database, if you accidentall...

JavaScript implements the protocol example in which the user must check the box

In js, set the user to read a certain agreement b...

Summarize the problems encountered in using Vue Element UI

Table of contents 1. DateTimePicker date selectio...

Notes on using the blockquote tag

<br />Semanticization cannot be explained in...

Detailed tutorial on using the tomcat8-maven-plugin plugin in Maven

I searched a lot of articles online but didn'...

Cross-browser development experience summary (I) HTML tags

Add a DOCTYPE to the page Since different browser...

Summary of common docker commands (recommended)

1. Summary: In general, they can be divided into ...

How to install Docker CE on Ubuntu 18.04 (Community Edition)

Uninstall old versions If you have installed an o...