JavaScript+;画布移动对象
我想在画布上做一个乒乓球游戏。我想我应该先让球穿过街道。问题是当我循环draw函数时,它会变成一条线,而不是每个新位置的一个球。(请参见下面的屏幕截图。) 我认为清理画布,然后重新绘制所有内容可以解决问题,但显然不行 这是我的密码: HTML: JavaScript:JavaScript+;画布移动对象,javascript,css,html,canvas,Javascript,Css,Html,Canvas,我想在画布上做一个乒乓球游戏。我想我应该先让球穿过街道。问题是当我循环draw函数时,它会变成一条线,而不是每个新位置的一个球。(请参见下面的屏幕截图。) 我认为清理画布,然后重新绘制所有内容可以解决问题,但显然不行 这是我的密码: HTML: JavaScript: window.addEventListener("load", eventWindowLoaded, false); function eventWindowLoaded(){ var canvas=document.
window.addEventListener("load", eventWindowLoaded, false);
function eventWindowLoaded(){
var canvas=document.querySelector("canvas");
var ctx=canvas.getContext("2d");
var canWidth=canvas.width;
var canHeight=canvas.height;
var pi=Math.PI;
var timer=null;
var ms=16;
var gameBall={
size:30,
positionX:0,
positionY:0,
color:"#FFF",
set setSize(newSize){
this.size=newSize;
},
set setPosX(posX){
this.positionX=posX;
},
set setPosY(posY){
this.positionY=posY;
},
set setColor(newColor){
this.color=newColor;
},
get getSize(){
return this.size;
},
get getPosX(){
return this.positionX;
},
get getPosY(){
return this.positionY;
},
get getColor(){
return this.color;
}
}
function clearCanvas(){
ctx.clearRect(0,0,canWidth,canHeight);
}
function drawBackground(){
ctx.fillStyle="#000";
ctx.fillRect(0,0,canWidth,canHeight);
}
function drawBall(){
ctx.save();
var posX=gameBall.getPosX;
var posY=gameBall.getPosY;
var size=gameBall.getSize;
ctx.fillStyle=gameBall.getColor;
ctx.arc(posX,posY,size,0,2*pi,true);
ctx.fill();
ctx.restore();
}
function updateBall(){
//clearCanvas();
//drawBackground();
gameBall.setPosX=gameBall.getPosX+3;
gameBall.setPosY=gameBall.getPosY+3;
drawBall();
}
gameBall.setPosX=100;
gameBall.setPosY=100;
drawBackground();
timer=setInterval(updateBall, ms);
}
下面是您的小提琴的工作版本。它针对以下两个问题进行了重构:
- 由于画布不允许重新定位现有的球图形,因此先前的球仍然存在。.save和.restore命令只保存和恢复上下文属性,而不保存和恢复画布上的图形。相反,您必须擦除画布并在新位置重新绘制球。因此,(1)牵引地面,(2)更新和(3)updateBall中的牵引球是在画布上“移动”的正确方式
- 每次绘制
(球)时,必须调用context.arc
。否则,将重新绘制.arc命令的所有早期版本context.beginPath
函数eventWindowLoaded(){
var canvas=document.querySelector(“canvas”);
var ctx=canvas.getContext(“2d”);
var canWidth=canvas.width;
var canHeight=canvas.height;
var-pi=Math.pi;
var定时器=null;
var-ms=1000/60*1;
var游戏球={
尺码:30,
位置X:0,
位置Y:0,
颜色:“FFF”,
设置设置大小(新闻大小){
this.size=newSize;
},
设置setPosX(posX){
这个.positionX=posX;
},
设置setPosY(posY){
这个。positionY=posY;
},
设置设置颜色(新颜色){
this.color=newColor;
},
获取getSize(){
返回此.size;
},
获取getPosX(){
返回此.x;
},
获取getPosY(){
返回此.positionY;
},
获取getColor(){
返回此.color;
}
}
函数clearCanvas(){
ctx.clearRect(0,0,canWidth,canHeight);
}
函数{
ctx.save();
var posX=gameBall.getPosX;
var posY=gameBall.getPosY;
var size=gameBall.getSize;
ctx.fillStyle=gameBall.getColor;
ctx.beginPath();
ctx.arc(posX,posY,size,0,2*pi,真);
ctx.fill();
ctx.restore();
}
函数updateBall(){
//clearCanvas();
gameBall.setPosX=gameBall.getPosX+3;
gameBall.setPosY=gameBall.getPosY+3;
ctx.fillStyle='black';
ctx.fillRect(0,0,canvas.width,canvas.height);
牵引杆();
}
gameBall.setPosX=35;
gameBall.setPosY=35;
计时器=设置间隔(updateBall,毫秒);
}
eventWindowLoaded()代码>
正文{
背景色:#E93D19;
颜色:#341711;
字体系列:“Lucida Sans Unicode”,“Lucida Grande”,无衬线;
字体大小:2vw;
}
#内容{
文本对齐:居中;
垫面:3%;
}
帆布{
背景色:黑色;
}
导航{
高度:100px;
宽度:100%;
文本对齐:居中;
字体大小:3vw;
}
#导航列表{
背景色:#FD851D;
列表样式类型:无;
保证金:0;
溢出:隐藏;
填充:0;
转化:translateY(10%);
}
#李海军{
显示:内联;
}
#导航列表a{
颜色:#C91D09;
文字装饰:无;
}
#导航列表a:悬停{
背景色:#C91D09;
颜色:#FD851D;
}
您的浏览器不支持HTML5画布
每次重画帧时,都需要清除画布
绘制路径时,需要确保在每个帧中创建新路径,而不是添加到当前路径。这通常是通过调用ctx.beginPath()
清除上下文的当前路径来完成的。我建议在绘制新位置等之前,在每次更新时清除画布。我看到您在updateBall
函数中有此功能,但它似乎被注释掉了。我说它不起作用是对的吗?它目前被注释掉的原因是我在尝试几种不同的解决方案(例如“ctx.save()和ctx.restore()”)。遗憾的是两者都不起作用。我创建了一个小提琴(代码稍微更新了,但问题仍然存在)@Phrosen。在处理了两个问题后,我添加了一个答案,显示了您的小提琴的工作版本。祝你的项目好运!我也需要关闭路径吗?老实说,我不太清楚begin/closePath的作用。不,closePath只是在最后一点和起点之间创建一条线。这对于确保路径“整洁”非常有用。下面是一个例子:实际上,这是closePath的一个更好的例子:但是每次更新都需要做大量的工作,就像我们只是为了删除球的早期版本。我尝试创建一个与背景颜色相同的球,但颜色与背景不匹配。有没有一种方法可以在不重新构建整个画布的情况下进行处理?
body {
background-color: #E93D19;
color: #341711;
font-family: "Lucida Sans Unicode", "Lucida Grande", sans-serif;
font-size: 2vw;
}
#content {
text-align: center;
padding-top: 3%;
}
canvas {
background-color: white;
}
nav {
height: 100px;
width: 100%;
text-align: center;
font-size: 3vw;
}
#navlist {
background-color: #FD851D;
list-style-type: none;
margin: 0;
overflow: hidden;
padding: 0;
transform: translateY(10%);
}
#navlist li {
display: inline;
}
#navlist a {
color: #C91D09;
text-decoration: none;
}
#navlist a:hover {
background-color: #C91D09;
color: #FD851D;
}
window.addEventListener("load", eventWindowLoaded, false);
function eventWindowLoaded(){
var canvas=document.querySelector("canvas");
var ctx=canvas.getContext("2d");
var canWidth=canvas.width;
var canHeight=canvas.height;
var pi=Math.PI;
var timer=null;
var ms=16;
var gameBall={
size:30,
positionX:0,
positionY:0,
color:"#FFF",
set setSize(newSize){
this.size=newSize;
},
set setPosX(posX){
this.positionX=posX;
},
set setPosY(posY){
this.positionY=posY;
},
set setColor(newColor){
this.color=newColor;
},
get getSize(){
return this.size;
},
get getPosX(){
return this.positionX;
},
get getPosY(){
return this.positionY;
},
get getColor(){
return this.color;
}
}
function clearCanvas(){
ctx.clearRect(0,0,canWidth,canHeight);
}
function drawBackground(){
ctx.fillStyle="#000";
ctx.fillRect(0,0,canWidth,canHeight);
}
function drawBall(){
ctx.save();
var posX=gameBall.getPosX;
var posY=gameBall.getPosY;
var size=gameBall.getSize;
ctx.fillStyle=gameBall.getColor;
ctx.arc(posX,posY,size,0,2*pi,true);
ctx.fill();
ctx.restore();
}
function updateBall(){
//clearCanvas();
//drawBackground();
gameBall.setPosX=gameBall.getPosX+3;
gameBall.setPosY=gameBall.getPosY+3;
drawBall();
}
gameBall.setPosX=100;
gameBall.setPosY=100;
drawBackground();
timer=setInterval(updateBall, ms);
}