读取'时出错;无法读取属性'x'未定义的'在HTML5 Canvas代码中

Error reading 'Cannot read property 'x' of undefined' in HTML5 Canvas code

本文关键字:读取 HTML5 代码 Canvas 属性 出错 未定义      更新时间:2023-09-26

我的JavaScript代码有问题。由于我这样做是为了让你可以从画布中删除形状,所以当我尝试向画布添加其他形状时,会出现一个错误。错误为:"无法读取未定义的属性"x"。"。当出现错误时,它引用代码的第116行,内容为:"var dx=tmpRingB.x-tmpRing.x;"。我需要使它不会出现这个错误。代码如下。

var shapeObj = function (counter, context, canvas, settingsBox) {
    //Where sound info goes (freq, vol, amp, adsr etc)
    this.id = "shape"+counter;
    this.ctx = context;
    this.canvas = canvas;
    this.sBox = settingsBox;
    this.audioProperties = {
        duration: Math.random()*1-0.1,
        frequency: Math.random()*44000-220
    }
    this.x = Math.random()*this.ctx.canvas.width;
    this.y = Math.random()*this.ctx.canvas.height;
    this.radius = 40;
    this.vx = Math.random()*6-3;
    this.vy = Math.random()*6-3;
    this.draw = function () {
        this.ctx.beginPath();
        this.ctx.arc(this.x, this.y, this.radius, 0, Math.PI*2, false);
        this.ctx.closePath();
        this.ctx.stroke();
    }
    this.clickTest = function (e) {
        var canvasOffset = this.canvas.offset();
        var canvasX = Math.floor(e.pageX-canvasOffset.left);
        var canvasY = Math.floor(e.pageY-canvasOffset.top);         
        var dX = this.x-canvasX;
        var dY = this.y-canvasY;
        var distance = Math.sqrt((dX*dX)+(dY*dY));
        if (distance <= this.radius) {
            this.manageClick();
        } 
    };
    this.manageClick = function(){
        alert('this is ' + this.id);
        this.sBox.populate(this.audioProperties, this);
        this.radius -= 10;
    }
    this.update = function(newProps){
        // repopulate the shapes with new settings
    }
}
var settingsBox = function (){
    this.populate = function(props, obj){
        for (a in props){
            alert(props[a]);    
        }
    }
}
$(document).ready(function() {
    var canvas = $('#myCanvas');
    var ctx = canvas.get(0).getContext("2d");
    var canvasWidth = canvas.width();
    var canvasHeight = canvas.height();
    $(window).resize(resizeCanvas);
    function resizeCanvas() {
        canvas.attr("width", $(window).get(0).innerWidth - 2);
        canvas.attr("height", $(window).get(0).innerHeight - 124);  
        canvasWidth = canvas.width();
        canvasHeight = canvas.height();
    };
    resizeCanvas();
    canvas.onselectstart = function () { return false; }
    ctx.strokeStyle = "rgb(255, 255, 255)";
    ctx.lineWidth = 5;
    var playAnimation = true;
    $(canvas).click(function(e) {
        for (i = 0; i < objects.length; i++) {
            objects[i].clickTest(e);
        }
    });
    objects = [];
    sBox = new settingsBox();
    for (var i = 0; i < 4; i++) {
        var ring = new shapeObj(i, ctx, canvas, sBox);
        objects[i] = ring;  
        objects[i].draw();
    }
    $("#button4").click(function() {
        var ring = new shapeObj(i, ctx, canvas, sBox);
        objects[i] = ring;  
        objects[i++].draw();
        playSoundA();
    });
    function animate() {
        ctx.clearRect(0, 0, ctx.canvas.width, ctx.canvas.height);
        deadObjects = [];
        for (var i = 0; i < objects.length; i++) {
            var tmpRing = objects[i];
            for (var j = i+1; j < objects.length; j++) {
                var tmpRingB = objects[j];
                var dx = tmpRingB.x - tmpRing.x;
                var dy = tmpRingB.y - tmpRing.y;
                var dist = Math.sqrt((dx * dx) + (dy * dy));
                if(dist < tmpRing.radius + tmpRingB.radius) {
                    playSound();
                    //Put collision animations here!!!
                    var angle = Math.atan2(dy, dx);
                    var sine = Math.sin(angle);
                    var cosine = Math.cos(angle);
                    var x = 0;
                    var y = 0;
                    var xb = dx * cosine + dy * sine;
                    var yb = dy * cosine - dx * sine;
                    var vx = tmpRing.vx * cosine + tmpRing.vy * sine;
                    var vy = tmpRing.vy * cosine - tmpRing.vx * sine;
                    var vxb = tmpRingB.vx * cosine + tmpRingB.vy * sine;
                    var vyb = tmpRingB.vy * cosine - tmpRingB.vx * sine;
                    vx *= -1;
                    vxb *= -1;
                    xb = x + (tmpRing.radius + tmpRingB.radius);
                    tmpRing.x = tmpRing.x + (x * cosine - y * sine);
                    tmpRing.y = tmpRing.y + (y * cosine + x * sine);
                    tmpRingB.x = tmpRing.x + (xb * cosine - yb * sine);
                    tmpRingB.y = tmpRing.y + (yb * cosine + xb * sine);
                    tmpRing.vx = vx * cosine - vy * sine;
                    tmpRing.vy = vy * cosine + vx * sine;
                    tmpRingB.vx = vxb * cosine - vyb * sine;
                    tmpRingB.vy = vyb * cosine + vxb * sine;
                    tmpRing.loop = true;
                };
            };
            tmpRing.x += tmpRing.vx;
            tmpRing.y += tmpRing.vy;
            if (tmpRing.x - tmpRing.radius < 0) {
                playSound();
                tmpRing.x = tmpRing.radius;
                tmpRing.vx *= -1;
            } else if (tmpRing.x + tmpRing.radius > ctx.canvas.width) {
                playSound();
                tmpRing.x = ctx.canvas.width - tmpRing.radius;
                tmpRing.vx *= -1;   
            };
            if (tmpRing.y - tmpRing.radius < 0) {
                playSound();
                tmpRing.y = tmpRing.radius;
                tmpRing.vy *= -1;
            } else if (tmpRing.y + tmpRing.radius > ctx.canvas.height) {
                playSound();
                tmpRing.y = ctx.canvas.height - tmpRing.radius;
                tmpRing.vy *= -1;   
            };
            if(tmpRing.radius <= 0) {
                deadObjects.push(tmpRing);  
            }
            objects[i].draw();
        };
        if (deadObjects.length > 0) {
            for (var d = 0; d < deadObjects.length; d++) {
                var tmpDeadObject = deadObjects[d];
                objects.splice(objects.indexOf(tmpDeadObject), 1);
            }
        }
        if(playAnimation) {
            setTimeout(animate, 33);    
        };
    };
    animate();    
});     

有什么想法吗?

谢谢你的帮助。

您的对象未定义,因为您已经删除了它。一个简单的解决方案是检查对象是否仍在定义中。

在出现错误的行之前插入以下行。如果(!(tmpRingB&tmpRing))继续;

一个更好的解决方案是在删除阵列时对其进行清理。