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

js basic syntax and maven project configuration tutorial case

Table of contents 1. js statement Second, js arra...

Detailed explanation of the use of MySQL group links

Grouping and linking in MYSQL are the two most co...

CSS3 achieves cool sliced ​​image carousel effect

Today we will learn how to use CSS to create a co...

React handwriting tab switching problem

Parent File import React, { useState } from '...

Introduction to several ways to introduce CSS in HTML

Table of contents 1. Embed CSS styles directly in...

WeChat applet selects the image control

This article example shares the specific code for...

Vite2.0 Pitfalls

Table of contents Vite project build optimization...

Two solutions for Vue package upload server refresh 404 problem

1: nginx server solution, modify the .conf config...

JavaScript destructuring assignment detailed explanation

Table of contents concept Array Destructuring Dec...

Docker and portainer configuration methods under Linux

1. Install and use Docer CE This article takes Ce...

Use of js optional chaining operator

Preface The optional chaining operator (?.) allow...

Analysis of three parameters of MySQL replication problem

Table of contents 01 sql_slave_skip_counter param...

Application of Beautiful Style Sheets in XHTML+CSS Web Page Creation

This is an article written a long time ago. Now it...

Implementation of scheduled backup in Mysql5.7

1. Find mysqldump.exe in the MySQL installation p...