【问题标题】:How to make a scrolling starfield如何制作滚动星空
【发布时间】:2014-02-25 18:26:06
【问题描述】:

我想写一个简单的从右到左滚动的starfield。我随机打印出星星。现在,我如何瞄准每颗星星并随机给它一个速度(比如 1-10)并开始移动它?我还需要在每颗星星到达左边缘后将其放回右边缘。

以下是我目前编写的代码:

<!DOCTYPE html>
<html>
<head>
<script>


 function stars()
 {
    canvas = document.getElementById("can");

    if(canvas.getContext)
    {
       ctx = canvas.getContext("2d");
       ctx.fillStyle = "black";
       ctx.rect (0, 0, 400, 400);
       ctx.fill();
       starfield();
    }
  }
  //print  random stars
  function starfield()
  {
     for (i=0; i<10; i++)
     {
        var x = Math.floor(Math.random()*399);
        var y = Math.floor(Math.random()*399);
        var tempx = x;
        ctx.fillStyle = "white";
        ctx.beginPath();
        ctx.arc(x, y, 3, 0, Math.PI*2, true);
        ctx.closePath();
        ctx.fill();
     }
  }

</script>

</head>
<body onload="stars()">
<h1>Stars</h1>
<canvas id="can" width="400" height="400"style="border:2px solid #000100" ></canvas>
</body >
</html>

【问题讨论】:

  • 你可以使用 jQuery 解决方案吗?
  • 对不起,我不使用 jquery。目前还在努力学习 js :)
  • 您只需为我使用 jQuery 解决方案发布的答案导入一个外部文件
  • 检查我的答案。如果它非常适合你,那么我可以发布整个代码

标签: javascript html


【解决方案1】:

这是 Codepen 上的 quick demo。将星星保存在数组中后,我使用requestAnimationFrame 运行绘图代码并更新每一帧的位置。

function stars() {
  canvas = document.getElementById("can");
  console.log(canvas);
  if (canvas.getContext) {
    ctx = canvas.getContext("2d");
    ctx.fillStyle = "black";
    ctx.rect(0, 0, 400, 400);
    ctx.fill();
    starfield();
  }
}
// Create random stars with random velocity.
var starList = []
function starfield() {
  for (i = 0; i < 20; i++) {
    var star = {
      x: Math.floor(Math.random() * 399),
      y: Math.floor(Math.random() * 399),
      vx: Math.ceil(Math.random() * 10)
    };
    starList.push(star);
  }
}

function run() {
  // Register for the next frame
  window.requestAnimationFrame(run);

  // Reset the canvas
  ctx.fillStyle = "black";
  ctx.rect(0, 0, 400, 400);
  ctx.fill();

  // Update position and draw each star.
  var star;
  for(var i=0, j=starList.length; i<j; i++) {
    star = starList[i];
    star.x = (star.x - star.vx + 400) % 400;
    ctx.fillStyle = "white";
    ctx.beginPath();
    ctx.arc(star.x, star.y, 3, 0, Math.PI * 2, true);
    ctx.closePath();
    ctx.fill();
  }
}

stars();
run();

【讨论】:

  • 这就是我想要做的!所以正如上面的巴里所说,我需要将星星位置放入一个数组并更新每个周期。谢谢你。
  • +1 用于在此处使用 window.requestAnimationFrame() 而不是 settimeout()setinterval() 函数。
【解决方案2】:

将您的x,y 坐标放入一个数组中,然后创建一个绘制该数组的函数。

var stars = [
  {x:110, y:80},
  {x:120, y:20},
  {x:130, y:60},
  {x:140, y:40}
]

然后在每次使用绘图函数之前创建一个函数来更改x,y 坐标(例如递增y=y+1)。

奖励: 该阵列解决方案允许您让每颗星以自己的速度移动,您可以在该阵列中存储一个增量(例如 1 到 3),然后改为使用y=y+delta。这看起来是 3D 的。 你甚至可以更进一步,有一个单独的 x 和 y 增量,让星星从中间飞出,这更加 3D!

或者更简单/更快的可能是让渲染函数接受 x,y 偏移量。然后它甚至可以环绕,这样从屏幕一侧掉下来的东西就会回到另一侧。看起来你在太空中旋转。

【讨论】:

  • 谢谢巴里。我还没有完全掌握数组的窍门。生病尝试做一个我只移动一颗星然后从那里去的地方。
  • 这些星星是开始尝试数组的绝佳项目。祝你好运!如果你找到一个可以打印整个数组的函数,例如console.log(stars)console.table(stars),那么在调试代码时可能会派上用场。
【解决方案3】:

我模拟恒星向一个点(如中心)移动的简单方法是简单地将 X 和 Y 除以 Z 坐标。

nx = x / z ny = y / z

并在迭代时简单地减小 z 值。当 z 很大时,您的点将围绕一个点,并且随着 z 减小,结果会越来越大,这模仿了星星的“移动”。

【讨论】:

    【解决方案4】:

    只提供一个使用 jQuery 的解决方案,因为与完整的画布解决方案相比,使用它可以用更少的代码行获得输出。它使用两个画布 div 来获得所需的输出:

    Check this fiddle

    问题中发布的代码中的少量更新代码

    <script>
     function stars(){
         canvas = document.getElementById("can1");
         canvasCopy = document.getElementById("can2");
    
     if(canvas.getContext){
             ctx = canvas.getContext("2d");
             ctx.fillStyle = "black";
             ctx.rect (0, 0, 400, 400);
             ctx.fill();
             starfield();
             var destCtx = canvasCopy.getContext('2d');
             destCtx.drawImage(canvas, 0, 0);
         }
     }
    //print  random stars
    function starfield(){
        for (i=0;i<10;i++){
            var x = Math.floor(Math.random()*399);
            var y = Math.floor(Math.random()*399);
            var tempx = x;
            ctx.fillStyle = "white";
            ctx.beginPath();
            ctx.arc(x, y, 3, 0, Math.PI*2, true);
            ctx.closePath();
            ctx.fill();
        }
    }
    </script>
    
    <body onload="stars()">
    <h1>Stars</h1>
        <div id="starBlocks">
        <canvas id="can1" width="400" height="400"style="border:2px solid #000100" ></canvas>
        <canvas id="can2" width="400" height="400"style="border:2px solid #000100" ></canvas>
        </div>
    </body >
    

    jQuery

    function playStars()
    {
        $('#starBlocks').animate({
            scrollLeft : 400
        },10000,'linear',function(){
            $('#starBlocks').scrollLeft(0);
            playStars();
        });
    }
    playStars();
    

    CSS

    #starBlocks{
        white-space:nowrap;
        font-size:0px;
        width:400px;
        overflow:hidden;
    }
    

    【讨论】:

    • 感谢 zword。抱歉,我还没有使用 jquery。还在为js苦苦挣扎! :)
    • @user2827914 您只需要导入一个外部 js 文件即可在我的回答中使用上述代码
    猜你喜欢
    • 1970-01-01
    • 2012-09-10
    • 1970-01-01
    • 2021-06-24
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多