Remember once played a very simple little game, a ball on the move, then under a board to meet, if you don’t catch crashed while the game is over, although forget its name, but have been more,, just until recently in the New Year’s day demand unsaturated, just want to do but didn’t begin, just two days this konvajs in learning, Just have this little article, very simple, just three steps, package you learn in three minutes.

Konvajs profile

Konvajs is as convenient to canvas as jquery is to DOM, snap. SVG and SVG. With konvajs, you can quickly draw commonly used graphics and easily add styles, events, animation effects and so on. Mom doesn’t have to worry about me checking the mouse position anymore. Documentation: konvajs.org/.

Using Konvajs is basically a three-step process. The first step is to create a “stage” :

import { Stage } from 'konva'
const stage = new Stage({
    container: 'container'.// The container element id
    width: 500.height: 500
})
Copy the code

Step 2 is to create a “layer” and add it to the “stage” :

import { Layer } from 'konva'
const layer = new Layer()
stage.add(layer)
Copy the code

A layer corresponds to a Canvas element.

The third step is to create various shapes to add to the “layer”.

The first step

A ball and a paddle.

Example code for copying circles and rectangles directly from official documentation, balls:

import { Circle } from 'konva'
createCircle () {
    // The center coordinates of the ball
    this.centerX = this.stage.width() / 2
    this.centerY = 100
    this.circle = new Circle({
        x: this.centerX,
        y: this.centerY,
        radius: this.radius,
        fill: 'red'.stroke: 'black'.strokeWidth: 4
    })
    this.layer.add(this.circle)
    this.layer.draw()// Redraw, which needs to be called after each change
}
Copy the code

Baffles are:

import { Rect } from 'konva'
createRect () {
    this.rect = new Rect({
        x: (this.stage.width() - 100) / 2.y: this.height - 50.width: 100.height: 10.fill: 'green'.stroke: 'black'.strokeWidth: 4.draggable: true.// Allow dragging
        dragBoundFunc: function (pos) {// Control can only be dragged horizontally
            return {
                x: pos.x,
                y: this.absolutePosition().y// Get the absolute position of y}}})this.layer.add(this.rect)
    this.layer.draw()
}
Copy the code

The second step

To make the ball move, give the ball an initial speed, an acceleration, then reverse the speed after hitting the wall, and gradually increase the speed, used to increase the difficulty of the game:

this.speedX = Math.random() * 3
this.speedY = Math.random() * 3
this.speedStep = 0.01

runCircle () {
    // Change the ball position
    this.centerX += this.speedX
    this.centerY += this.speedY
    this.circle.x(this.centerX)
    this.circle.y(this.centerY)
    // Hit the wall
    if (this.centerX - this.radius <= 0 || this.centerX + this.radius >= this.width) {// The left and right walls
        this.speedX = -this.speedX// Reverse the horizontal speed
    }
    if (this.centerY - this.radius <= 0) {// Only the top wall is judged, the bottom wall is used to end the game
        this.speedY = -this.speedY
    }
    // Check the impact plate
    this.collisionCheck()
    // End of game check
    if (this.centerY + this.radius >= this.height) {// Hit the bottom wall and the game is over
        return this.gameOver()
    }
    / / acceleration
    // Increase the speed before reaching the maximum speed
    if (Math.abs(this.speedX) < this.maxSpeed) {
        this.speedX > 0 ? this.speedX += this.speedStep : this.speedX -= this.speedStep
    }
    if (Math.abs(this.speedY) < this.maxSpeed) {
        this.speedY > 0 ? this.speedY += this.speedStep : this.speedY -= this.speedStep
    }
}
Copy the code

Then use requestAnimationFrame to refresh continuously:

update () {
    window.requestAnimationFrame(() = > {
        this.runCircle()
        this.update()
        this.layer.draw()
    })
}
Copy the code

The third step

Testing balls and baffle whether collision, hit the speed reverse, principle is to find a rectangle around the point closest to the ball’s center, and then determine the points and small ball center distance is less than the sphere, how do you determine this point is also very simple, if the center of the circle to the left side of the rectangle, then this point must be in the left side of the rectangle, point the value of x is the rect. X, If it is on the right side of the rectangle, the value of point x must be on the right side of the rectangle, which is rect.x + rect.width. If it is between the rectangles, since the line between the nearest point and the center of the circle must be reset to the edge of the rectangle, the value of point x is the center of the circle x, and the value of point y is computed in the same way as that of x.

collisionCheck () {! [](https://p1-juejin.byteimg.com/tos-cn-i-k3u1fbpfcp/0440226e4a95497d8890494d9efda590~tplv-k3u1fbpfcp-watermark.image)
    let minx = 0
    let miny = 0
    let rectX = this.rect.x()
    let rectY = this.rect.y()
    let rectWidth = this.rect.width()
    let rectHeight = this.rect.height()
    // Determine the x-coordinate of the rectangle nearest to the ball
    if (this.centerX < rectX) {// On the left side of the rectangle
        minx = rectX
    } else if (this.centerX > rectX + rectWidth) {// On the right side of the rectangle
        minx = rectX + rectWidth
    } else {// Between the left and right rectangles
        minx = this.centerX
    }
    // Determine the y coordinate of the nearest point on the rectangle to the ball
    if (this.centerY < rectY) {// Above the rectangle
        miny = rectY
    } else if (this.centerY > rectY + rectHeight) {// Under the rectangle
        miny = rectY + rectHeight
    } else {// Between the rectangle
        miny = this.centerY
    }
    // If the distance is less than the radius, a collision has occurred
    if (this.getTwoPointDistance(minx, miny, this.centerX, this.centerY) <= this.radius) {
        // Hit left or right, then horizontal velocity x reverse
        if (minx === rectX || minx === rectX + rectWidth) {
            this.speedX = -this.speedX
        }
        // If the rectangle is hit, the vertical velocity y is reversed
        if (miny === rectY) {
            this.speedY = -this.speedY
        }
    }
}
Copy the code

This is the end of the game, you can have fun:

Example code: github.com/wanglin2/Ba… .