• uniapp中用canvas实现小球碰撞的小动画


    uniapp 我就不想喷了,踩了很多坑,把代码贡献出来让大家少踩些坑。

    实现的功能:

    • 生成n个球在canvas中运动,相互碰撞后会反弹,反弹后的速度计算我研究过了,可以参考代码直接用
    • 防止球出边框
    • 防止小球之间碰撞过度,或者说“穿模”。采用的方法是碰撞后让两个小球都多走一帧。其实这样并不能完全防止“穿模”,但可以防止小球粘在一起不停的穿模
    • uniapp中的requestAnimationFrame的使用,包括开始与停止动画
    • 利用四叉树优化了碰撞检测,网上有些示例是直接让区域内所有的小球之间进行一次碰撞检测

    代码是vue3写的。uniapp官方说做动画推荐用什么renderjs,不知道直接这样写还会有什么坑,目前在h5中测试没问题。

    四叉树类的代码见我上一篇文章

    ball类的代码:

    复制代码
    export class Ball {
        // 提供圆心坐标和半径
        constructor(x, y, r, speedX, speedY, color, index) {
            this.centerX = x
            this.centerY = y
            this.r = r
    
            this.x = x - r
            this.y = y - r
            this.width = 2 * r
            this.height = 2 * r
    
            this.color = color
    
            this.speedX = speedX
            this.speedY = speedY
            
            this.index = index // 索引
        }
        // 将球填充到canvas context
        fillTo(ctx) {
            ctx.beginPath()
            ctx.arc(this.centerX, this.centerY, this.r, 0, 2 * Math.PI)
            ctx.setFillStyle(this.color)
            ctx.closePath()
            ctx.fill()
        }
    
        // 判断是否与另一个球相交
        intersectAt(ball2) {
            let dx = this.centerX - ball2.centerX
            let dy = this.centerY - ball2.centerY
            let distance = Math.sqrt(dx * dx + dy * dy)
            return this.r + ball2.r >= distance
        }
    
        // 移动 width height 是canvas的宽高
        move(width, height) {
    
            this.centerX += this.speedX
            if (this.centerX - this.r <= 0) {
                this.centerX = this.r
                this.speedX = -this.speedX
            }
            if (this.r + this.centerX >= width) {
                this.centerX = width - this.r
                this.speedX = -this.speedX
            }
            
            this.centerY += this.speedY
            
            if (this.centerY - this.r <= 0) {
                this.centerY = this.r
                this.speedY = -this.speedY
            }
            
            if (this.centerY + this.r >= height) {
                this.centerY = height - this.r
                this.speedY = -this.speedY
            }
    
            this.x = this.centerX - this.r
            this.y = this.centerY - this.r
        }
    
    
    }
    复制代码

     

     

    page的代码:

    复制代码
    
    
    
    
    
    复制代码

     

  • 相关阅读:
    面向智慧文博的知识图谱构建综述
    Android JNI 异常定位(2)—— addr2line
    C++学习 --deque
    C语言 函数
    95后大厂程序员删库被判刑,只因项目被接手对领导心生不满
    阿里云配置https,配置SSL证书
    (Vue笔记)VSCode创建与运行 Vue-cli + @Vue-cli 项目
    WSL 常用命令
    这份华为以太网接口配置命令太真香了!
    uniapp如何处理图片加载过程中的错误
  • 原文地址:https://www.cnblogs.com/zbit/p/16555216.html