【发布时间】:2021-05-04 05:19:59
【问题描述】:
我正在用 HTML Canvas 制作一个简单的游戏。作为其中的一部分,我想在背景中制作流星,创造旅行的幻觉。在星星到达画布的末端后,我想将其移除。每颗恒星都是 Star 类的一个实例,并且根据它的半径,它具有不同的速度。这就是问题开始的地方。当对每颗恒星使用恒定速度时,它们会像应有的那样一个接一个地消失。当速度改变时,“超越”较慢恒星的恒星,当到达画布的尽头时,不仅会消失,还会移除在它们之前排列的每颗恒星。 我尝试了以下描述的许多解决方案:
let canvas = document.querySelector("canvas");
let c = canvas.getContext('2d');
星级声明:
class Star{
constructor(x, y, radius, color, velocity){
this.x = x;
this.y = y;
this.radius = radius;
this.color = color;
this.velocity = velocity
}
draw(){
c.globalCompositeOperation='destination-over'
c.beginPath()
c.arc(this.x, this.y, this.radius, 0, Math.PI*2, false);
c.fillStyle = this.color;
c.shadowColor= "white"
c.shadowBlur=12
c.fill();
c.shadowBlur=0
}
update(){
this.draw();
this.y = this.y + this.radius/2;
}
}
创建星星并将其添加到数组中
let stars = [];
function createStar(){
setInterval(()=>{
//Create random radius and X position
let randomRadius = Math.floor((Math.random()*5))
let randomXPosition = Math.floor((Math.random()*780)+15)
let velocity = 1;
stars.push(new Star(randomXPosition, -randomRadius, randomRadius, "white",velocity));
console.log("stars:"+ stars.length);
},300)
}
下面我使用一个调用自身的函数来清除和刷新星图。我尝试使用 forEach 方法循环遍历 stars 数组,反向循环(如下例所示),我尝试将带有拼接函数的 if 语句放在单独的 setTimeout(()=>{},0) 或 setTimeout(()=>{ },10)。我尝试使用类似的条件
(forEach 方法会移除星星,但活跃星星的数量不会保持不变。它会不断缓慢增加)
function animate(){
c.clearRect(0, 0, canvas.width, canvas.height);
for(let i = stars.length-1; i>=0; i--){
stars[i].update()
if (stars[i].y > canvas.height +stars[i].radius ){
stars.splice(stars[i], 1)
}
}
requestAnimationFrame(animate);
}
animate();
createStar();
我尝试使用以下条件:
if (stars[i].y > 5000 ){
stars.splice(stars[i], 1)
}
但这不是应该如何解决的,因为星星的寿命要长 5000 像素,这让游戏变得迟钝。
只是为了明确问题。 如果我每 300 毫秒生成 5 颗星并将其推入名为“星”的数组中,我会得到例如 [星1,星2,星3,星4,星5]
假设star1 和star 2 的半径很小,它们移动缓慢。 Star3 更大,因此它移动得更快,超过了前两个。当star3 到达canvas.height + star[i].radius 时,它会在画布上方消失,但它也会使数组中star3 之前的每颗星都消失(在本例中是star1 和star2)。
这是我在 stackoverflow 上的第一篇文章。对于所有的轻描淡写,我提前道歉。
HTML 画布
<body>
<div class="container">
<button class="logOutButton">Log Out</button>
<button class="topScores">Top 10</button>
<header>
<p class="hello">Hello <span id="spanName"></span></p>
<p class="topScore">Your TOP score: <span id="score"></span></p>
</header>
<div class="gameTitle">
<h2 class="title">Space Warrior</h2>
</div>
<canvas class="canvas" width="800" height="500"></canvas>
</div>
<script src="User.js"></script>
</body>
编辑
我将 stars.splice(stars[i], 1) 更改为 stars.splice(i, 1) - 不工作
我尝试添加另一个像下面这样的删除数组,但数组 stars 只是慢慢变大(即使有些元素被删除了)
var removeStar = [];
// stars.forEach((star,starIndex)=>{
let total = stars.length-1;
for(let i = total; i>=0; i--){
stars[i].update();
if (stars[i].y > canvas.height + stars[i].radius){
removeStar.push(i);
}
};
for(let i = removeStar.length; i>0; i--){
stars.splice(removeStar[i-1],1)
}
【问题讨论】:
-
你能分享你的画布html吗?
-
c 未定义
-
我的错,忘记添加到问题中
-
添加变量
let total = stars.length - 1,而不是在for循环中使用动态长度。 -
像上面一样改了,但是不行
标签: javascript html arrays animation canvas