vue+canvas小球练习,数组问题

问题遇到的现象和发生背景

使用vue+canvas写小球运动代码,先写了一个小球对象,使用for循环赋值并用push加入小球数组,小球页面显示是正常的,但是一查看数组里每个值都是一样的。

用代码块功能插入代码,请勿粘贴截图

 

 


运行结果及报错内容

img

img

ball是data中的对象,数组压入的实际是ball的地址,任何一个地方修改ball后都会影响到数组中的引用的这个ball的内容。ballSet应该返回新的对象,改下面的就可以了
蛮多小问题。。
计时器中for循环越界了
for (let i = 0; i<=this.ballArr.length; i++)
===>去掉=号
for (let i = 0;i < this.ballArr.length; i++)

改改ball属性要传入对象,传入函数的是值变量,在ballRun里面修改不会影响到原来的ball值。而且没清空画布,导致重绘叠加了

用下面的就可以了

<template>
    <div id="app">
        <canvas id="mycanvas" width="390" height="844">123</canvas>
    </div>
</template>

<script>
    export default {
        name: 'cvs',
        data() {
            return {
                w: 390,
                h: 844,

                ballArr: []
            }
        },
        mounted() {
            // var clientWidth = document.documentElement.clientWidth;
            // var canvasWidth = Math.floor(clientWidth);
            // var canvasHeight = Math.floor(clientWidth*(1334/750));
            // var cvs = document.getElementById("mycanvas");
            // cvs.style.width = canvasWidth + 'px';
            // cvs.style.height = canvasHeight + 'px';
            for (let i = 0; i <= 5; i++) {
                let ball = this.ballSet();
                this.ballArr.push(ball);
                this.ballShow(this.ballArr[i].x, this.ballArr[i].y, this.ballArr[i].r, this.ballArr[i].color);
            };
            console.log(this.ballArr);
            setInterval(() => {
                for (let i = 0; i < this.ballArr.length; i++) {//更新ball属性
                    this.ballRun(this.ballArr[i].x, this.ballArr[i].y, this.ballArr[i].r, this.ballArr[i].xSpeed, this.ballArr[i].ySpeed, this.ballArr[i]);//传入ball对象
                }
                //清空画布后重绘

                var c = document.getElementById("mycanvas");
                var ctx = c.getContext("2d");
                ctx.clearRect(0, 0, 390, 844);
                for (let i = 0; i < this.ballArr.length; i++) {
                    this.ballShow(this.ballArr[i].x, this.ballArr[i].y, this.ballArr[i].r, this.ballArr[i].color);
                }
            }, 1500)
        },
        methods: {
            //球随机函数
            ran(num) {
                return Math.random() * num;
            },
            //球对象属性设定
            ballSet() {
                let ball = {};
                ball.x = this.ran(190) + 100;
                ball.y = this.ran(559.6) + 100;
                ball.r = this.ran(90) + 10;
                ball.color = '#' + parseInt(Math.random() * 0xffffff).toString(16);
                ball.xSpeed = this.ran(3) + 2;
                ball.ySpeed = this.ran(3) + 1;
                return ball;
            },
            //canvas画球
            ballShow(x, y, r, color) {
                var c = document.getElementById("mycanvas");
                var ctx = c.getContext("2d");
                ctx.beginPath();
                ctx.arc(x, y, r, 0, Math.PI * 2);
                ctx.fillStyle = color;
                ctx.fill();
            },
            //球运动
            ballRun(x, y, r, xSpeed, ySpeed,ball) {
                if (x - r <= 0 || x + r >= this.w) {
                    xSpeed = -xSpeed;
                }
                x = x + xSpeed;
                if (y - r <= 0 || y + r >= this.h) {
                    ySpeed = -ySpeed;
                }
                y = y + ySpeed;
                //x, y, r, xSpeed, ySpeed是值变量,更改后不会影响到ball属性,要传入ball对象来更改
                ball.xSpeed = xSpeed
                ball.x = x
                ball.ySpeed = ySpeed
                ball.y = y
            }
        },
    }
</script>

<style>
</style>

bill是一个对象
this.ballArr.push(this.ball);
每次都是将同一个ball对象添加到数组中的,所有ball是同一个。
页面显示正常是因为在添加时,直接取了当前添加对象的值用来去画球。

ballSet 在 for循环里也执行 然后再push 进 ballArr

您好,我是有问必答小助手,您的问题已经有小伙伴帮您解答,感谢您对有问必答的支持与关注!
PS:问答VIP年卡 【限时加赠:IT技术图书免费领】,了解详情>>> https://vip.csdn.net/askvip?utm_source=1146287632