如何在 Java Scipt 中为类的实例定义颜色

问题描述

我正在制作一款突破性游戏,我必须制作一些块并为它们提供在数组中定义的随机颜色,但是为了制作更多块,我不得不使用 for 循环。因此,当我将它们添加到我的更新功能时,颜色以帧速率闪烁。如果你运行代码段,我想你会更好地理解

还有一件事:canvasRendering...rundedRectangle 是一个绘制圆角矩形的函数,有人请找到解决方案!

CanvasRenderingContext2D.prototype.roundedRectangle = function(x,y,width,height,rounded) {
    const radiansInCircle = 2 * Math.PI;
    const halfradians = (2 * Math.PI)/2;
    const quarterradians = (2 * Math.PI)/4  ;
    
    // top left arc
    this.arc(rounded + x,rounded + y,rounded,-quarterradians,halfradians,true);
    
    // line from top left to bottom left
    this.lineto(x,y + height - rounded);
  
    // bottom left arc  
    this.arc(rounded + x,height - rounded + y,quarterradians,true)  ;
    
    // line from bottom left to bottom right
    this.lineto(x + width - rounded,y + height);
  
    // bottom right arc
    this.arc(x + width - rounded,y + height - rounded,true)  ;
    
    // line from bottom right to top right
    this.lineto(x + width,y + rounded)  ;
  
    // top right arc
    this.arc(x + width - rounded,y + rounded,true)  ;
    // line from top right to top left
    this.lineto(x + rounded,y)  ;
};

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

function Player(x,w,h){
    this.x = x;
    this.y = y;
    this.w = w;
    this.h = h;
    this.show = function(){
        ctx.beginPath();
        ctx.rect(this.x,this.y,this.w,this.h);
        ctx.fillStyle = "#ffff";
        ctx.fill();
        ctx.closePath();
    };
    this.move = function(speed){
        this.x += speed;
    };
}

function Ball(x,r){
    this.x = x;
    this.y = y;
    this.r = r;
    this.show = function(){
        ctx.beginPath();
        ctx.arc(this.x,this.r,2* Math.PI);
        ctx.fillStyle = "tomato";
        ctx.fill();
        ctx.closePath();
    };
    this.move= function(speedX,speedY){
        this.show();
        this.speed = 2;
        this.x += speedX;
        this.y += speedY;
    };

}

var colors = ['#A5E75A','#7254AD','#FFD606','#FF093D'];
function Block(x,h){
    this.x = x;
    this.y = y;
    this.w = w;
    this.h = h;
    this.status =1;
    this.show= function(color){
        ctx.beginPath();
        ctx.roundedRectangle(this.x,this.h,5);
        //ctx.arc(this.x,10,2*Math.PI);
        //ctx.fillStyle = colors[Math.floor(Math.random()*colors.length)];
        ctx.fillStyle = color;
        ctx.fill();
        ctx.closePath();
    };
}

var player = new Player(canvas.width/2-50,780,100,20);
var ball = new Ball(player.x+player.w/2,player.y,15);


var rigthpressed = false;
var leftpressed = false;

var blocks = [];
var rowCount = 5;
var columnCount = 6;
var noInRow = 6;
var blockCount = (rowCount*columnCount)+1;
var rc = {blockRow : 0,blockCol : 0};


for(let i = 0; i < blockCount; i++){
    blocks.push(new Block(rc.blockCol*60+25,rc.blockRow*60-30,50,50)); 
    rc.blockCoL++;
    if(i % noInRow === 0){
        rc.blockRow++;
        rc.blockCol = 0;
    }
}


window.addEventListener("keydown",function(e){
    if(e.keyCode == 39){
        rigthpressed = true;
    }
    if(e.keyCode == 37){
        leftpressed = true;
    }
});
window.addEventListener("keyup",function(e){
    if(e.keyCode == 39){
        rigthpressed = false;
    }
    if(e.keyCode == 37){
        leftpressed = false;
    }
});

function objMovement(){
    if(rigthpressed){
        player.move(5);
        if (player.x > canvas.width-player.w){
            player.x = canvas.width-player.w;
        }
    }
    if(leftpressed){
        player.move(-5);
        if(player.x < 0){
            player.x = 0;
        }
    }

    if(ball.x > canvas.width-ball.r || ball.x < 0+ball.r){
        ballSpeedX = -ballSpeedX;
    }
    if (/*ball.y > canvas.height-ball.r ||*/ball.y < 0+ball.r){
        ballSpeedY = -ballSpeedY;
    }
    if(ball.x<player.x+player.w &&ball.x>player.x && ball.y>player.y && ball.y<player.y+player.h){
        ballSpeedY = -ballSpeedY;
        ballSpeedX= ballSpeedX;
    }
    function Bump(){
        if (ball.x>player.x && ball.x<player.x+player.w/2){
            if (ball.y >= player.y){
                ballSpeedX = -5;
            }
        }
        if(ball.x>player.x+player.w/2 && ball.x<player.x+player.w){
            if(ball.y >= player.y){
                ballSpeedX = 5;
            }
        }
    }   
    //Bump();
}

function reload(){
    if (ball.y>canvas.height){
        //alert('gameOver');
        ball.x =player.x+player.w/2;
        ball.y = player.y-ball.r;
        ballSpeedX = 0;
        ballSpeedY = 0;
    }
}

var ballSpeedX = 0;
var ballSpeedY = -0;

function collision(){
    for(let i=1;i<blockCount;i++){
        if(ball.x>blocks[i].x && 
            ball.x<blocks[i].x+blocks[i].w && 
            ball.y>blocks[i].y && 
            ball.y<blocks[i].y+blocks[i].h){
            blocks[i].status = 0;
            ballSpeedY = -ballSpeedY;
            blocks.splice(i,1);
            blockCount--;
            //ballSpeedX = 0;
            //ballSpeedY = 0;
            console.log('hit');
    
        }
    } 
}

function update(){
    ctx.clearRect(0,canvas.width,canvas.height);

    objMovement();
    for(let i=1;i<blockCount;i++){  
        if(blocks[i].status == 1){
            blocks[i].show(colors[Math.floor(Math.random()*colors.length)]);
        }
    }
    collision();
    ball.show();
    ball.move(ballSpeedX,ballSpeedY);
    player.show();
    reload();
    window.requestAnimationFrame(update);
}
update();
<!DOCTYPE html>
<html lang="en">
<head>
    <Meta charset="UTF-8">
    <title>??</title>
    <style>
        #body{
            background-color: rgb(31,30,30);
        }
        #gameCanvas{
            border: 15px solid rgb(44,44,44);
            border-radius: 20px;
            background-color:rgb(19,18,18);
            margin: 250px;
        }
    </style>
</head>
<body id="body">
    <canvas id="gameCanvas" width=400 height=800></canvas>
    <script type="text/javascript" src="./index.js"></script>
    
</body>
</html>

解决方法

因为每次更新时您都会从画布中删除并重绘所有矩形并在显示时分配新颜色,所以每次更新时都会为它们分配一种新颜色。您可以通过向矩形添加属性 color 来避免这种情况,该矩形使用随机颜色初始化(一次,因此在初始 for 循环中),并更改 show 函数以使用 { {1}} 而不是接受颜色作为参数。这样,您就不会在每次更新时为矩形分配新颜色,也不会在每次更新时更改颜色。