我正在通过HTML画布上的小型太空游戏来学习JS。我正在尝试从随机生成的恒星阵列中创建一个3D星空。 我有一个由12颗恒星组成的数组,这颗恒星是从包含34颗恒星的大星阵的元素中随机生成的。当一颗恒星离开屏幕的边界时,我想将它从较小的阵列中移除,并将其替换为较大的星形阵列中的另一个随机生成的元素,同时保持它在动画功能中不断移动。我已经尝试了几种方法,但我似乎无法找到正确的语法......或者可能是正确的方法来查看问题。任何帮助将不胜感激。代码如下:
<canvas id="myCanvas" width="1024" height="768">
</canvas>
<script>
var myCanvas = document.getElementById("myCanvas");
var ctx = myCanvas.getContext("2d");
var starsArray;
var randStarsArray;
var numStars = 12;
// Star object
var Star = function(x, y, width, height, velX, velY) {
this.x = x;
this.y = y;
this.width = width;
this.height = height;
this.velX = velX;
this.velY = velY;
}
// Create individual stars
var star1 = new Star(myCanvas.width/2 + (150 * Math.cos(135*Math.PI/180)), myCanvas.height/2 + (150 * Math.sin(135*Math.PI/180)), 5, 5, -6, 6);
var star2 = new Star(myCanvas.width/2 + (135 * Math.cos(135*Math.PI/180)), myCanvas.height/2 + (135 * Math.sin(135*Math.PI/180)), 5, 5, -6, 6);
var star3 = new Star(myCanvas.width/2 + (150 * Math.cos(320*Math.PI/180)), myCanvas.height/2 + (150 * Math.sin(320*Math.PI/180)), 5, 5, 6, -6);
var star4 = new Star(myCanvas.width/2 + (150 * Math.cos(310*Math.PI/180)), myCanvas.height/2 + (150 * Math.sin(310*Math.PI/180)), 5, 5, 6, -6);
var star5 = new Star(myCanvas.width/2 + (100 * Math.cos(270*Math.PI/180)), myCanvas.height/2 + (100 * Math.sin(270*Math.PI/180)), 5, 5, 0, -6);
var star6 = new Star(myCanvas.width/2 + (150 * Math.cos(0*Math.PI/180)), myCanvas.height/2 + (150 * Math.sin(0*Math.PI/180)), 5, 5, 6, 0);
var star7 = new Star(myCanvas.width/2 + (100 * Math.cos(90*Math.PI/180)), myCanvas.height/2 + (100 * Math.sin(90*Math.PI/180)), 5, 5, 0, 6);
var star8 = new Star(myCanvas.width/2 + (100 * Math.cos(180*Math.PI/180)), myCanvas.height/2 + (100 * Math.sin(180*Math.PI/180)), 5, 5, -6, 0);
var star9 = new Star(myCanvas.width/2 + (200 * Math.cos(270*Math.PI/180)), myCanvas.height/2 + (200 * Math.sin(270*Math.PI/180)), 5, 5, 0, -6);
var star10 = new Star(myCanvas.width/2 + (200 * Math.cos(0*Math.PI/180)), myCanvas.height/2 + (200 * Math.sin(0*Math.PI/180)), 5, 5, 6, 0);
var star11 = new Star(myCanvas.width/2 + (200 * Math.cos(90*Math.PI/180)), myCanvas.height/2 + (200 * Math.sin(90*Math.PI/180)), 5, 5, 0, 6);
var star12 = new Star(myCanvas.width/2 + (150 * Math.cos(60*Math.PI/180)), myCanvas.height/2 + (150 * Math.sin(60*Math.PI/180)), 5, 5, 3, 6);
var star13 = new Star(myCanvas.width/2 + (200 * Math.cos(45*Math.PI/180)), myCanvas.height/2 + (200 * Math.sin(45*Math.PI/180)), 5, 5, 6, 6);
var star14 = new Star(myCanvas.width/2 + (150 * Math.cos(210*Math.PI/180)), myCanvas.height/2 + (150 * Math.sin(210*Math.PI/180)), 5, 5, -6, -3);
var star15 = new Star(myCanvas.width/2 + (200 * Math.cos(225*Math.PI/180)), myCanvas.height/2 + (200 * Math.sin(225*Math.PI/180)), 5, 5, -6, -6);
var star16 = new Star(myCanvas.width/2 + (200 * Math.cos(150*Math.PI/180)), myCanvas.height/2 + (200 * Math.sin(150*Math.PI/180)), 5, 5, -6, 3);
var star17 = new Star(myCanvas.width/2 + (100 * Math.cos(150*Math.PI/180)), myCanvas.height/2 + (100 * Math.sin(150*Math.PI/180)), 5, 5, -6, 3);
var star18 = new Star(myCanvas.width/2 + (100 * Math.cos(30*Math.PI/180)), myCanvas.height/2 + (100 * Math.sin(30*Math.PI/180)), 5, 5, 6, 3);
var star19 = new Star(myCanvas.width/2 + (250 * Math.cos(180*Math.PI/180)), myCanvas.height/2 + (250 * Math.sin(180*Math.PI/180)), 5, 5, -6, 0);
var star20 = new Star(myCanvas.width/2 + (100 * Math.cos(330*Math.PI/180)), myCanvas.height/2 + (100 * Math.sin(330*Math.PI/180)), 5, 5, 6, -3);
var star21 = new Star(myCanvas.width/2 + (150 * Math.cos(300*Math.PI/180)), myCanvas.height/2 + (150 * Math.sin(300*Math.PI/180)), 5, 5, 3, -6);
var star22 = new Star(myCanvas.width/2 + (150 * Math.cos(240*Math.PI/180)), myCanvas.height/2 + (150 * Math.sin(240*Math.PI/180)), 5, 5, -3, -6);
var star23 = new Star(myCanvas.width/2 + (250 * Math.cos(240*Math.PI/180)), myCanvas.height/2 + (250 * Math.sin(240*Math.PI/180)), 5, 5, -3, -6);
var star24 = new Star(myCanvas.width/2 + (250 * Math.cos(330*Math.PI/180)), myCanvas.height/2 + (250 * Math.sin(330*Math.PI/180)), 5, 5, 6, -3);
var star25 = new Star(myCanvas.width/2 + (250 * Math.cos(30*Math.PI/180)), myCanvas.height/2 + (250 * Math.sin(30*Math.PI/180)), 5, 5, 6, 3);
var star26 = new Star(myCanvas.width/2 + (100 * Math.cos(120*Math.PI/180)), myCanvas.height/2 + (100 * Math.sin(120*Math.PI/180)), 5, 5, -3, 6);
var star27 = new Star(myCanvas.width/2 + (250 * Math.cos(135*Math.PI/180)), myCanvas.height/2 + (250 * Math.sin(135*Math.PI/180)), 5, 5, -6, 6);
var star28 = new Star(myCanvas.width/2 + (250 * Math.cos(120*Math.PI/180)), myCanvas.height/2 + (250 * Math.sin(120*Math.PI/180)), 5, 5, -3, 6);
var star29 = new Star(myCanvas.width/2 + (200 * Math.cos(210*Math.PI/180)), myCanvas.height/2 + (200 * Math.sin(210*Math.PI/180)), 5, 5, -6, -3);
var star30 = new Star(myCanvas.width/2 + (250 * Math.cos(300*Math.PI/180)), myCanvas.height/2 + (250 * Math.sin(300*Math.PI/180)), 5, 5, 3, -6);
var star31 = new Star(myCanvas.width/2 + (25 * Math.cos(45*Math.PI/180)), myCanvas.height/2 + (25 * Math.sin(45*Math.PI/180)), 5, 5, 6, -6);
var star32 = new Star(myCanvas.width/2 + (25 * Math.cos(225*Math.PI/180)), myCanvas.height/2 + (25 * Math.sin(225*Math.PI/180)), 5, 5, -6, -6);
var star33 = new Star(myCanvas.width/2 + (250 * Math.cos(60*Math.PI/180)), myCanvas.height/2 + (250 * Math.sin(60*Math.PI/180)), 5, 5, 3, 6);
var star34 = new Star(myCanvas.width/2 + (25 * Math.cos(315*Math.PI/180)), myCanvas.height/2 + (25 * Math.sin(315*Math.PI/180)), 5, 5, 6, -6);
// Game initialization
function init() {
startGame();
}
// Start game
function startGame(){
// Game variables
starsArray = new Array();
randStarsArray = new Array();
// Push stars onto array
starsArray.push(star1);
starsArray.push(star2);
starsArray.push(star3);
starsArray.push(star4);
starsArray.push(star5);
starsArray.push(star6);
starsArray.push(star7);
starsArray.push(star8);
starsArray.push(star9);
starsArray.push(star10);
starsArray.push(star11);
starsArray.push(star12);
starsArray.push(star13);
starsArray.push(star14);
starsArray.push(star15);
starsArray.push(star16);
starsArray.push(star17);
starsArray.push(star18);
starsArray.push(star19);
starsArray.push(star20);
starsArray.push(star21);
starsArray.push(star22);
starsArray.push(star23);
starsArray.push(star24);
starsArray.push(star25);
starsArray.push(star26);
starsArray.push(star27);
starsArray.push(star28);
starsArray.push(star29);
starsArray.push(star30);
starsArray.push(star31);
starsArray.push(star32);
starsArray.push(star33);
starsArray.push(star34);
for(i = 0; i < numStars; i++){
randStarsArray[i] = starsArray[Math.floor(Math.random() * 34)];
}
animate();
}
function changeStar(){
var index = randStarsArray.indexOf(tempStar);
if (index > -1) {
//randStarsArray[index] = starsArray[Math.floor(Math.random() * 34)];
randStarsArray.splice(index, 1);
randStarsArray.push(starsArray[Math.floor(Math.random() * 34)]);
}
}
// Animation loop
function animate(){
ctx.clearRect(0, 0, myCanvas.width, myCanvas.height);
for(i = 0; i < numStars; i++){
var tempStar = randStarsArray[i];
ctx.fillStyle = "rgb(255, 255, 255)"; // white stars
ctx.fillRect(randStarsArray[i].x, randStarsArray[i].y, randStarsArray[i].width, randStarsArray[i].height);
tempStar.x += tempStar.velX;
tempStar.y += tempStar.velY;
if(tempStar.x + tempStar.width < 0 || tempStar.x > myCanvas.width ||
tempStar.y + tempStar.height < 0 || tempStar.y > myCanvas.height){
changeStar();
}
}
setTimeout(animate, 33);
}
init();
</script>
答案 0 :(得分:0)
<script>
var Canvas = document.getElementById("Canvas");
var ctx = Canvas.getContext("2d");
var starsArray;
var randStarsArray;
var numStars = 12;
// Star object
var Star = function(x, y, width, height, velX, velY) {
this.x = x;
this.y = y;
this.width = width;
this.height = height;
this.velX = velX;
this.velY = velY;
}
var M = [150, 135, 150, 150, 100, 150, 100, 100, 200, 200, 200, 150, 200, 150, 200, 200, 100, 100, 250, 100, 150, 150, 250, 250, 250, 100, 250, 250, 200, 250, 25, 25, 250, 25];
var N = [135, 135, 320, 310, 270, 0, 90, 180, 270, 0, 90, 60, 45, 210, 225, 150, 150, 30, 180, 330, 300, 240, 240, 330, 30, 120, 135, 120, 210, 300, 45, 225, 60, 315];
var Z = [-6, -6, 6, 6, 0, 6, 0, -6, 0, 6, 0, 3, 6, -6, -6, -6, -6, 6, -6, 6, 3, -3, -3, 6, 6, -3, -3 - 6, -3, -6, 6, -6, 3, 6];
var K = [6, 6, -6, -6, -6, 0, 6, 0, -6, 0, 6, 6, 6, -3, -6, 3, 3, 3, 0, -3, -6, -6, -6, -3, 3, 6, 6, 6, -3, -6, -6, -6, 6, -6];
var star = [];
for (var i = 0; i <= 34; i++) {
star[i] = new Star(Canvas.width / 2 + (M[i] * Math.cos(N[i] * Math.PI / 180)), Canvas.height / 2 + (M[i] * Math.sin(N[i] * Math.PI / 180)), 5, 5, Z[i], K[i]);
}
// Game initialization
function init() {
startGame();
}
// Start game
function startGame() {
// Game variables
starsArray = [];
randStarsArray = [];
// Push stars onto array
// 这是所有的star
for (var i = 0; i < star.length; i++) {
starsArray.push(star[i])
}
// console.dir(starsArray);//所有的星星
var randomArray = []; //渲染的 星星
// 判断数据是否为12个数据
while (randomArray.length < numStars) {
var random = Math.floor(Math.random() * 34);
if (randomArray.indexOf(random) === -1) {
randomArray.push(random);
}
}
console.log(randomArray)
for (var i = 0; i < randomArray.length; i++) {
randStarsArray[i] = starsArray[randomArray[i]];
}
console.log(randStarsArray);
animate();
}
// Animation loop
function animate() {
ctx.clearRect(0, 0, Canvas.width, Canvas.height);
for (i = 0; i < numStars; i++) {
var tempStar = randStarsArray[i];
console.log(tempStar);
ctx.fillStyle = "rgb(55, 100, 0)"; // white stars
ctx.fillRect(tempStar.x, tempStar.y, tempStar.width, tempStar.height);
tempStar.x += tempStar.velX;
tempStar.y += tempStar.velY;
if (tempStar.x + tempStar.width < 0 || tempStar.x > Canvas.width ||
tempStar.y + tempStar.height < 0 || tempStar.y > Canvas.height) {
changeStar(tempStar);
}
}
setTimeout(animate, 300);
}
function changeStar(tempStar) {
var index = randStarsArray.indexOf(tempStar);
if (index > -1) {
//randStarsArray[index] = starsArray[Math.floor(Math.random() * 34)];
randStarsArray.splice(index, 1);
randStarsArray.push(starsArray[Math.floor(Math.random() * 34)]);
}
}
init();
</script>`enter code here`
答案 1 :(得分:0)
想出来,虽然我会按照mingye.wei在我有时间时所做的那样重构它,因为它看起来更好。我的答案太复杂了 - 弄清楚我必须在离开屏幕之后从randomArray中移除/拼出旧星,然后从starsArray中添加一个新的随机星到randomArray。事实证明,我需要做的就是用新生成的随机星更新tempStar的x,y,velX和velY。 starsarray。现在它不断运行。 :)代码如下:
//动画循环 function animate(){
import static org.mockito.BDDMockito.given;
答案 2 :(得分:0)
我想我会为可能感兴趣的人发布3D连续星空背景的重构代码。代码如下: var myCanvas = document.getElementById(“myCanvas”); var ctx = myCanvas.getContext(“2d”);
// star variables
var starsArray;
var randomStarsArray;
var numStars = 14;
// Star object
var Star = function(x, y, width, height, velX, velY) {
this.x = x;
this.y = y;
this.width = width;
this.height = height;
this.velX = velX;
this.velY = velY;
}
// Variables for Star object creation
// sD = distance of star from canvas center
// sA = angle from center origin
var sD = [150, 135, 150, 150, 100, 150, 100, 100, 200, 200, 200, 150, 200, 150, 200, 200, 100, 100, 250, 100, 150, 150, 250, 250, 250, 100, 250, 250, 200, 250, 25, 25, 250, 25];
var sA = [135, 135, 320, 310, 270, 0, 90, 180, 270, 0, 90, 60, 45, 210, 225, 150, 150, 30, 180, 330, 300, 240, 240, 330, 30, 120, 135, 120, 210, 300, 45, 225, 60, 315];
var sVX = [-6, -6, 6, 6, 0, 6, 0, -6, 0, 6, 0, 3, 6, -6, -6, -6, -6, 6, -6, 6, 3, -3, -3, 6, 6, -3, -3 - 6, -3, -6, 6, -6, 3, 6];
var sVY = [6, 6, -6, -6, -6, 0, 6, 0, -6, 0, 6, 6, 6, -3, -6, 3, 3, 3, 0, -3, -6, -6, -6, -3, 3, 6, 6, 6, -3, -6, -6, -6, 6, -6];
// Game initialization
function init(){
// Game variables
starsArray = [];
randomStarsArray = [];
// Push stars onto starsArray
for (var i = 0; i < 34; i++) {
starsArray[i] = new Star(myCanvas.width / 2 + (sD[i] * Math.cos(sA[i] * Math.PI / 180)), myCanvas.height / 2 + (sD[i] * Math.sin(sA[i] * Math.PI / 180)), 5, 5, sVX[i], sVY[i]);
}
// Create a small array of random stars from starsArray to draw
for(var i = 0; i < numStars; i++){
randomStarsArray[i] = starsArray[Math.floor(Math.random() * 34)];
}
animate();
}
// Animation loop
function animate(){
ctx.clearRect(0, 0, myCanvas.width, myCanvas.height);
for(var i = 0; i < numStars; i++){
var tempStar = randomStarsArray[i];
ctx.fillStyle = "rgb(255, 255, 255)"; // white stars
ctx.fillRect(tempStar.x, tempStar.y, tempStar.width, tempStar.height);
tempStar.x += tempStar.velX;
tempStar.y += tempStar.velY;
// When tempStar moves off the screen...
if(tempStar.x + tempStar.width < 0 || tempStar.x > myCanvas.width ||
tempStar.y + tempStar.height < 0 || tempStar.y > myCanvas.height){
// ... replace it with a new random star from starsArray
var renewStar = starsArray[Math.floor(Math.random() * 34)];
tempStar.x = renewStar.x;
tempStar.y = renewStar.y;
tempStar.velX = renewStar.velX;
tempStar.velY = renewStar.velY;
}
}
// setTimeout is used for recursive calls to loop a function
setTimeout(animate, 33);
}
init();