Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/html/71.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/7/jsf/5.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Javascript 画布:设置简单星形场的动画_Javascript_Html_Performance_Animation_Canvas - Fatal编程技术网

Javascript 画布:设置简单星形场的动画

Javascript 画布:设置简单星形场的动画,javascript,html,performance,animation,canvas,Javascript,Html,Performance,Animation,Canvas,我对画布比较陌生。在寻找我的脚,我创造了一个简单的街机游戏 我的问题是关于CPU性能/效率 我正在创建100个随机定位的白点作为黑色背景上的星星。在每个requestAnimationFrame上,星星向左移动一个像素,当它们到达最左侧时,该列像素被放置在屏幕最右侧 使用requestAnimationFrame调用以下函数: bgAnimateId = requestAnimationFrame( scrollBg ); function scrollBg() { var imgDa

我对画布比较陌生。在寻找我的脚,我创造了一个简单的街机游戏

我的问题是关于CPU性能/效率

我正在创建100个随机定位的白点作为黑色背景上的星星。在每个requestAnimationFrame上,星星向左移动一个像素,当它们到达最左侧时,该列像素被放置在屏幕最右侧

使用requestAnimationFrame调用以下函数:

bgAnimateId = requestAnimationFrame( scrollBg );

function scrollBg() {
    var imgData = ctx.getImageData( 0, 0, 1, canvas.height );
    var areaToMoveLeft = ctx.getImageData( 1, 0, canvas.width-1, canvas.height );
    ctx.putImageData( areaToMoveLeft, 0, 0 );
    ctx.putImageData( imgData, canvas.width-1, 0 );
    bgAnimateId = requestAnimationFrame( scrollBg );
}
我关心的是-是创建100个小画布元素(或100个div)并制作动画更好,还是使用我上面使用的像素方法更好


非常感谢您提前提供的帮助/指导:-)

事实证明,
context.getImageData
context.putImageData
执行起来非常昂贵,100张画布太多了

因此,这里有一个创建高效平移星场的计划:

使用
context.drawImage
非常有效,执行起来也不太昂贵

下面介绍如何在画布上绘制随机星域,然后将该画布另存为图像:

// draw a random starfield on the canvas
bkCtx.beginPath();
bkCtx.fillStyle="darkblue";
bkCtx.rect(0,0,background.width,background.height);
bkCtx.fill();
bkCtx.beginPath();
for(var n=0;n<100;n++){
    var x=parseInt(Math.random()*canvas.width);
    var y=parseInt(Math.random()*canvas.height);
    var radius=Math.random()*3;
    bkCtx.arc(x,y,radius,0,Math.PI*2,false);
    bkCtx.closePath();
}
bkCtx.fillStyle="white";
bkCtx.fill();

// create an new image using the starfield canvas
var img=document.createElement("img");
img.src=background.toDataURL();
现在,前面的画布用于所有游戏对象

您的游戏效率高,性能好,有2张画布专门用于他们自己的目的

下面是代码和小提琴:


正文{padding:20px;}
#容器{
位置:相对位置;
边框:1px纯蓝色;
宽度:300px;
高度:300px;
}
.副NVS{
位置:绝对位置;
}
$(函数(){
//保罗·爱尔兰的伟大英国皇家空军
window.requestAnimFrame=(函数(回调){
返回window.requestAnimationFrame | | | window.webkitRequestAnimationFrame | | | window.mozRequestAnimationFrame | | window.oRequestAnimationFrame | | window.msRequestAnimationFrame||
函数(回调){
设置超时(回调,1000/60);
};
})();
var canvas=document.getElementById(“canvas”);
var ctx=canvas.getContext(“2d”);
var background=document.getElementById(“背景”);
var bkCtx=background.getContext(“2d”);
//创建随机星星的图像
var backImage=RandomStarsImage();
//在前面的画布上画画
ctx.beginPath();
ctx.fillStyle=“红色”;
ctx.rect(75100100,50);
ctx.arc(175125,25,0,数学PI*2,假);
ctx.closePath();
ctx.fill();
//开始在背景画布上平移随机星星图像
var fps=60;
var offsetLeft=0;
潘斯塔();
函数panStars(){
//增加左偏移量
offsetLeft+=1;
如果(offsetLeft>backImage.width){offsetLeft=0;}
//绘制星域图像并再次绘制
//填充第一幅图像右侧的空白
clearRect(0,0,背景.宽度,背景.高度);
bkCtx.drawImage(背景图像,-offsetLeft,0);
bkCtx.drawImage(backImage,backImage.width offsetLeft,0);
setTimeout(函数(){
请求帧(panStars);
},1000/帧);
}
函数RandomStarsImage(){
//在画布上绘制一个随机星域
bkCtx.beginPath();
bkCtx.fillStyle=“暗蓝色”;
bkCtx.rect(0,0,背景.宽度,背景.高度);
bkCtx.fill();
bkCtx.beginPath();

对于(var n=0;您是否存在实际性能问题,或者这是关于过早优化的问题?嗨,markE。非常感谢您的完美解决方案。即使将宽度/高度加倍,动画在我的笔记本电脑上仍然非常流畅,干杯…:-)嗨,Mark,我将“代码”复制到“myDir/soStars.html”文件中。我制作了一个“myDir/css/reset.css”从复制内容(&M)。我双击了soStars.html并在WinXP sp3上的FF 21.0中启动。结果spaceship显示西斯白色背景,但没有星形字段。我在fireBug中设置了一个断点“bkCtx.clearRect(0,0,background.width,background.height);”结果星形字段显示。我重置断点并将其设置为“setTimeout(function(){”.结果无星场谢谢你的帮助-爱与和平Joe@JoeCodeswelluser601770:糟糕!我忘了添加Paul Irish的伟大requestAnimationFrame回退(由您的FF使用)。我已经更新了我的答案和提琴,所以它们现在应该可以为你工作了。谢谢提醒!javascript代码什么时候调用?这是我不确定的部分。@DougHauf.Hi--很高兴见到你。在网页上,你可以将脚本(例如javascript)放在里面,将javascript放在这里。标记。上面的代码也使用jQuery(一个消除不同浏览器制造商之间不一致的网页附加库)。下面的代码告诉浏览器首先等待所有标签元素加载到页面上,然后在
$(function(){lotsofjavascript})内运行脚本;
我通常不推荐w3学校(他们有时有一些不准确的信息)但他们确实有相当好的教程:
<div id="container">
  <canvas id="background" class="subcanvs" width=300; height=300;></canvas>
  <canvas id="canvas" class="subcanvs" width=300; height=300;></canvas>
</div>

#container{
  position:relative;
  border:1px solid blue;
  width:300px;
  height:300px;
}
.subcanvs{
  position:absolute;
}
var fps = 60;
var offsetLeft=0;
panStars();

function panStars() {

    // increase the left offset
    offsetLeft+=1;
    if(offsetLeft>backImage.width){ offsetLeft=0; }

    // draw the starfield image and
    // draw it again to fill the empty space on the right of the first image
    bkCtx.clearRect(0,0,background.width,background.height);
    bkCtx.drawImage(backImage,-offsetLeft,0);
    bkCtx.drawImage(backImage,backImage.width-offsetLeft,0);

    setTimeout(function() {
        requestAnimationFrame(panStars);
    }, 1000 / fps);
}
<!doctype html>
<html>
<head>
<link rel="stylesheet" type="text/css" media="all" href="css/reset.css" /> <!-- reset css -->
<script type="text/javascript" src="http://code.jquery.com/jquery.min.js"></script>

<style>
body{padding:20px;}
#container{
  position:relative;
  border:1px solid blue;
  width:300px;
  height:300px;
}
.subcanvs{
  position:absolute;
}
</style>

<script>
$(function(){

    // Paul Irish's great RAF shim
    window.requestAnimFrame = (function(callback) {
      return window.requestAnimationFrame || window.webkitRequestAnimationFrame || window.mozRequestAnimationFrame || window.oRequestAnimationFrame || window.msRequestAnimationFrame ||
      function(callback) {
        window.setTimeout(callback, 1000 / 60);
      };
    })();

    var canvas=document.getElementById("canvas");
    var ctx=canvas.getContext("2d");
    var background=document.getElementById("background");
    var bkCtx=background.getContext("2d");

    // create an image of random stars
    var backImage=RandomStarsImage();

    // draw on the front canvas
    ctx.beginPath();
    ctx.fillStyle="red";
    ctx.rect(75,100,100,50);
    ctx.arc(175,125,25,0,Math.PI*2,false);
    ctx.closePath();
    ctx.fill();

    // start panning the random stars image across the background canvas
    var fps = 60;
    var offsetLeft=0;
    panStars();

    function panStars() {

        // increase the left offset
        offsetLeft+=1;
        if(offsetLeft>backImage.width){ offsetLeft=0; }

        // draw the starfield image and draw it again 
        // to fill the empty space on the right of the first image
        bkCtx.clearRect(0,0,background.width,background.height);
        bkCtx.drawImage(backImage,-offsetLeft,0);
        bkCtx.drawImage(backImage,backImage.width-offsetLeft,0);

        setTimeout(function() {
            requestAnimFrame(panStars);
        }, 1000 / fps);
    }

    function RandomStarsImage(){

        // draw a random starfield on the canvas
        bkCtx.beginPath();
        bkCtx.fillStyle="darkblue";
        bkCtx.rect(0,0,background.width,background.height);
        bkCtx.fill();
        bkCtx.beginPath();
        for(var n=0;n<100;n++){
            var x=parseInt(Math.random()*canvas.width);
            var y=parseInt(Math.random()*canvas.height);
            var radius=Math.random()*3;
            bkCtx.arc(x,y,radius,0,Math.PI*2,false);
            bkCtx.closePath();
        }
        bkCtx.fillStyle="white";
        bkCtx.fill();

        // create an new image using the starfield canvas
        var img=document.createElement("img");
        img.src=background.toDataURL();
        return(img);
    }

}); // end $(function(){});
</script>

</head>

<body>
    <div id="container">
      <canvas id="background" class="subcanvs" width=300; height=300;></canvas>
      <canvas id="canvas" class="subcanvs" width=300; height=300;></canvas>
    </div>
</body>
</html>