【问题标题】:Ran into an issue with javascript canvas graphics and motion遇到 javascript 画布图形和运动的问题
【发布时间】:2019-09-04 21:51:01
【问题描述】:

我正在创建一个 JavaScript 画布游戏,但遇到了问题。我通过更改对象的位置、清除画布然后重绘对象来创建运动。对于我提供的代码,球元素移动得很好,但是当矩形移动时,前一个元素不会被删除。这导致在屏幕下方绘制一条线。如果有人看到我需要解决的问题,请告诉我。

var canvas = document.getElementById("myCanvas");
var ctx = canvas.getContext("2d");
var p1;
var p2;
var ball;

p1 = new rectangle(10, 120, "black", 10, 120);
p2 = new rectangle(10, 120, "black", 1180, 120);
ball = new circle(600, 580, 10, "blue");

function gameupdate() {
  ctx.clearRect(0, 0, canvas.width, canvas.height);
  movep1();
  moveball();
}

function rectangle(width, height, color, x, y) {
  this.width = width;
  this.height = height;
  this.x = x;
  this.y = y;
  this.color = color;
  ctx.fillStyle = color;
  ctx.fillRect(this.x, this.y, this.width, this.height);
}

function circle(x, y, r, color) {
  this.x = x;
  this.y = y;
  this.r = r;
  this.color = color;
  ctx.fillStyle = color;
  ctx.beginPath();
  ctx.arc(this.x, this.y, this.r, 0, 2 * Math.PI);
  ctx.fill();
  ctx.stroke();
  ctx.closePath();
}

function moveball() {
  ball.y += -3;
  ball.x += 3;
  new circle(ball.x, ball.y, 10, "blue");
}

function movep1() {
  p1.y += 1;
  new rectangle(p1.x, p1.y, "black", p1.width, p1.height);
}

setInterval(gameupdate, 10);
<canvas id="myCanvas"></canvas>

【问题讨论】:

  • 您使用的是什么浏览器,因为某些浏览器需要不同的方式来清除画布。例如,较旧的浏览器要求您执行canvas.width = canvas.width,通过调整其大小来清除整个画布。
  • TYPO:在 movep1 中调用 new rectangle(p1.x, p1.y, "black", p1.width, p1.height) 而它被声明为 function rectangle(width, height, color, x, y) x, ywidth, height 是倒置的,所以你的代码只会改变矩形的高度。 minimal fix 但是,您最好不要每次都生成new 形状,而只是重绘您在初始化时创建的形状,并且在进行视觉动画时也不要使用setInterval,更喜欢requestAnimationFrame 循环。 better fix

标签: javascript canvas


【解决方案1】:

所以它在我的机器上运行良好,但是,您可能使用的是旧版浏览器,因此请使用 canvas.width = canvas.widthctx.clearRect() 来清除画布。我还注意到您试图创建一个类,但它更像是一个函数,所以我把它变成了一个类。

我建议您使用 ES6 类,因为它们让生活变得如此轻松,并使代码更简洁。以下是开始学习 ES6 类的一些地方:

代码如下:

var canvas = document.getElementById('ctx');
var ctx = canvas.getContext("2d");
canvas.width = window.innerWidth;
canvas.height = window.innerHeight;
var p1;
var p2;
var ball;

p1 = new Rectangle (10,120, "black", 10, 120);
p2 = new Rectangle (10, 120, "black", 1180, 120);
ball = new Circle (600,580,10,"blue");

function gameupdate() {
ctx.clearRect(0, 0, canvas.width, canvas.height);
canvas.width = canvas.width;
movep1();
moveball();
drawAll();
}

function Rectangle (width,height,color,x,y) {
    this.width = width;
    this.height = height;
    this.x = x;
    this.y = y;
    this.color = color;

    this.draw = function(){
        ctx.fillStyle = color;
        ctx.fillRect(this.x,this.y,this.width,this.height);
    }  

    return this;
} 

function Circle (x,y,r,color) {
    this.x = x;
    this.y = y;
    this.r = r;
    this.color = color;

    this.draw = function(){
        ctx.fillStyle = color;
        ctx.beginPath();
        ctx.arc(this.x, this.y, this.r,0, 2* Math.PI);
        ctx.fill();
        ctx.stroke();
        ctx.closePath();
    }
    

    return this;
}

function moveball () {
    ball.y += -3;
    ball.x += 3;
}

function movep1 () {
    p1.y += 1;
}

function drawAll() {
    p1.draw();
    p2.draw();
    ball.draw();
}

setInterval(gameupdate,10);
#ctx {
			width: 100%;
			height: 100%;
		}
<canvas id="ctx" width="100%" height="100%"></canvas>

希望这会有所帮助!

【讨论】: