Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/javascript/399.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_Css_Html_Html5 Canvas - Fatal编程技术网

Javascript 函数绘制混合特性

Javascript 函数绘制混合特性,javascript,css,html,html5-canvas,Javascript,Css,Html,Html5 Canvas,我正在尝试创建一个2d平台,代码是它的基础 由于一些未知的原因,我的最终函数图混合了其他函数的属性(特别是颜色和线宽等) 如果存在类型原因(“此.”功能不合适等) 我想知道更多的项目 任何好的回答都将不胜感激 /*main.js*/ var canvas=document.getElementById(“canvas”); var ctx=canvas.getContext(“2d”) 函数Shooter(){ 这是x=100; 这个y=500; 这个尺寸=50; this.color=“蓝色

我正在尝试创建一个2d平台,代码是它的基础

由于一些未知的原因,我的最终函数图混合了其他函数的属性(特别是颜色和线宽等)

如果存在类型原因(“此.”功能不合适等)

我想知道更多的项目

任何好的回答都将不胜感激

/*main.js*/
var canvas=document.getElementById(“canvas”);
var ctx=canvas.getContext(“2d”)
函数Shooter(){
这是x=100;
这个y=500;
这个尺寸=50;
this.color=“蓝色”;
this.borderColor=“黑色”;
这是一个宽度为5;
this.draw=函数(){
ctx.fillRect(this.x,this.y,this.size,this.size);
ctx.strokeRect(this.x,this.y,this.size,this.size);
ctx.fillStyle=this.color;
ctx.strokeStyle=this.borderColor;
ctx.lineWidth=此.borderWidth;
}
}
功能枪(){
这个.x=sh.x+sh.size/2+10;
这个.y=sh.y+sh.size/2;
此参数为:color=“grey”;
this.borderColor=“brown”;
此值为1.borderWidth=1;
这个宽度=20;
这个高度=10;
this.draw=函数(){
ctx.fillRect(this.x,this.y,this.width,this.height);
ctx.strokeRect(这个.x,这个.y,这个.宽度,这个.高度);
ctx.fillStyle=this.color;
ctx.strokeStyle=this.borderColor;
ctx.lineWidth=此.borderWidth;
}
}
函数Bullet(){
这个.x=sh.x+sh.size*2;
这个.y=sh.y+sh.size/2;
this.color=“橙色”;
这个半径=5;
这是1.vx=20;
this.borderColor=“绿色”;
此值为0.borderWidth=2;
this.draw=函数(){
弧(这个.x,这个.y,这个.radius,0,2*Math.PI);
ctx.fillStyle=this.color;
ctx.strokeStyle=this.borderColor;
ctx.lineWidth=此.borderWidth;
ctx.stroke();
}
}
var sh=新射手();
var g=新枪();
var b=新项目符号();
函数绘图(){
sh.draw();
g、 draw();
b、 draw();
请求动画帧(绘制);
}
draw()
/*main.css*/
html,正文{
溢出:隐藏;
}

页面标题

问题在于首先绘制形状,然后设置填充和笔划。这样可以为下一个形状设置填充和笔划

在我的代码中,我使用了
ctx.translate(0,-400)
,因为否则画布会太大。设置画布大小时删除此行

var canvas=document.getElementById(“canvas”);
var ctx=canvas.getContext(“2d”);
//设置画布大小
画布宽度=400;
画布高度=200;
ctx.translate(0,-400);
函数Shooter(){
这是x=100;
这个y=500;
这个尺寸=50;
this.color=“蓝色”;
this.borderColor=“黑色”;
这是一个宽度为5;
this.draw=函数(){
//首先设置此形状的颜色
ctx.fillStyle=this.color;
ctx.strokeStyle=this.borderColor;
ctx.lineWidth=此.borderWidth;
//然后填充并划过形状
ctx.fillRect(this.x,this.y,this.size,this.size);
ctx.strokeRect(this.x,this.y,this.size,this.size);
}
}
功能枪(){
这个.x=sh.x+sh.size/2+10;
这个.y=sh.y+sh.size/2;
此参数为:color=“grey”;
this.borderColor=“brown”;
此值为1.borderWidth=1;
这个宽度=20;
这个高度=10;
this.draw=函数(){
ctx.fillStyle=this.color;
ctx.strokeStyle=this.borderColor;
ctx.lineWidth=此.borderWidth;
ctx.fillRect(this.x,this.y,this.width,this.height);ctx.strokeRect(this.x,this.y,this.width,this.height);
}
}
函数Bullet(){
这个.x=sh.x+sh.size*2;
这个.y=sh.y+sh.size/2;
this.color=“橙色”;
这个半径=5;
这是1.vx=20;
this.borderColor=“绿色”;
此值为0.borderWidth=2;
this.draw=函数(){
ctx.beginPath();
弧(这个.x,这个.y,这个.radius,0,2*Math.PI);
ctx.fillStyle=this.color;
ctx.strokeStyle=this.borderColor;
ctx.lineWidth=此.borderWidth;
ctx.fill();
ctx.stroke();
}
}
var sh=新射手();
var g=新枪();
var b=新项目符号();
函数绘图(){
sh.draw();
g、 draw();
b、 draw();
请求动画帧(绘制);
}
draw()
canvas{border:1px solid}
一些额外的要点。 现有版本将解决您的问题,但是我有一些时间,并注意到您的代码中有一些可以改进的地方

表演为王 在编写游戏(或为此制作内容动画)时,您将看到动画的复杂性(动画和绘制项目的数量)达到某个阶段,设备无法再以全帧速运行。当您尝试覆盖更大范围的设备时,这将成为更大的问题

要在Javascript中获得每行代码的最高速度,您需要了解有关对象的一些简单规则,以及它们是如何创建和销毁的(为其他对象释放内存)

JavaScript是可管理的 这意味着作为一个程序员,你不需要担心内存。您创建了一个对象,并为您找到了该对象的内存。当您不再需要对象时,javascript将清理内存,以便其他对象可以自由使用

这使得用Javascript编程更容易。但是,在动画中,这可能会成为一个问题,因为管理内存分配和清理(也称为删除分配的内存或GC垃圾收集)的代码需要时间。如果动画需要很长时间来计算和渲染每个帧,则GC将强制阻止脚本并进行清理

这种内存管理是Javascript动画(游戏)中最大的Jank来源

它还引入了创建对象的额外处理,因为在创建新对象时必须定位和分配空闲内存。信息技术
function Shooter() {
    // Use closure to define the properties of the object
    var x = 100;
    var y = 500;
    const size = 50;
    const style = {
        fillStyle : "blue",
        strokeStyle : "black",
        lineWidth : 5,
    }
    // the interface object defines functions and properties that
    // need to be accessed from outside this function
    const API = {
        draw() {
            ctx.fillStyle = style.fillStyle;
            ctx.strokeStyle = style.strokeStyle;
            ctx.lineWidth = style.lineWidth;

            ctx.fillRect(x, y, size, size);
            ctx.strokeRect(x, y, size, size);

            // it is quicker to do the above two lines as
            /*
            ctx.beginPath(); // this function is done automatically 
                             // for fillRect and strokeRect. It                                 
            ctx.rect(x, y, size, size);
            ctx.fill();
            ctx.stroke();
            */
        }
    }
    return API;
}
const player = new Shooter();
// or
const player = Shooter();  / You dont need the new for this type of object

// to draw

player.draw();
const bullets = (() => { // a singleton
    function Bullet() { }
    const radius = 5;
    const startLife = 100;
    this.radius = 5;
    const style = {
        fillStyle : "orange",
        strokeStyle : "green",
        lineWidth : 2,
    }    
    // to hold the interface 
    Bullets.prototype = {
        init(x,y,dx,dy) { // dx,dy are delta
            this.life = startLife;
            this.x = x;
            this.y = y;
            this.dx = dx;
            this.dy = dy;
        },
        draw() {
            ctx.arc(this.x, this.y, radius, 0 , Math.PI * 2);
        },
        move() {
            this.x += this.dx;
            this.y += this.dy;
            this.life --;
        }
    };
    const pool = []; // holds unused bullets
    const bullets = []; // holds active bullets
    // The API that manages the bullets
    const API = {
        fire(x,y,dx,dy) {
            var b;
            if(pool.length) {
                b = bullets.pop();
            } else {
                b = new Bullet();
            }               
            b.init(x,y,dx,dy);
            bullets.push(bullets); // put on active array
        },
        update() {
            var i;
            for(i = 0; i < bullets.length; i ++) {
                const b = bullets[i];
                b.move();
                if(b.life <= 0) { // is the bullet is no longer needed move to the pool
                    pool.push(bullets.splice(i--, 1)[0]);
                }
            }            
        },
        draw() {
            ctx.lineWidth = style.lineWidth;
            ctx.fillStyle = style.fillStyle;
            ctx.strokeStyle = style.strokeStyle;
            ctx.beginPath();
            for(const b of bullets) { b.draw() }
            ctx.fill();
            ctx.stroke();            
        },
        get count() { return bullets.length }, // get the number of active
        clear() { // remove all 
            pool.push(...bullets); // move all active to the pool;
            bullets.length = 0; // empty the array;
        },
        reset() { // cleans up all memory
            pool.length = 0;
            bullets.length = 0;
        }
    };
    return API;
})();
// simple example
bullets.fire(gun.x, gun.y, gun.dirX, gun.dirY);
bullets.update(); // update all bullets
if(bullets.count) { // if there are bullets to draw
    bullets.draw();
}        
bullets.clear(); // remove bullets from previouse play
bullets.clear();    
function Gun(player, bullets) {
    this.owner = player;
    this.bullets = bullets; // the bullet pool to use.
    this.x = player.x + player.size / 2 + 10;
    this.y = player.y + player.size / 2;

    this.width = 20;
    this.height = 10;
    const style = {
        fillStyle : "grey",
        strokeStyle : "brown",
        lineWidth : 1,
    };   
}

// Moving the API to the prototype improves memory use and makes creation a little quicker
Gun.prototype = {
    update() {
        this.x = this.owner.x + this.owner.size / 2 + 10;
        this.y = this.owner.y + this.owner.size / 2;
    },
    draw() {
        ctx.lineWidth = this.style.lineWidth;
        ctx.fillStyle = this.style.fillStyle;
        ctx.strokeStyle = this.style.strokeStyle;
        ctx.beginPath();
        ctx.rect(this.x,this.y,this.width,this.height);
        ctx.fill();
        ctx.stroke();
    },
    shoot() {
        this.bullets.fire(this.x, this.y, 10, 0);
    },
}