瓷砖基础游戏的颜色系统



我开始了一个项目,教自己tile base游戏引擎背后的机制。到目前为止,我有一个很好的小演示,但我不知道如何实现每个瓷砖的颜色。我希望任何瓷砖都是任何颜色,但这对我来说很复杂。

整个游戏对屏幕上的每个对象/组件使用2d阵列。有一个中央2d阵列,用于存储所有的墙壁和地砖,以及任何不是单独移动对象的东西。我的想法是有一个存储颜色值的并行数组。然后迭代并相应地更改每个瓦片的颜色。

我进行实际绘图的代码的基本部分在一个名为字体的类中

class Font{
constructor(src, tilesizeX, tilesizeY){
this.fontImage = new Image();
this.imageBuffer = new Image();
// this.fontImage.setAttribute('crossOrigin', '')
this.fontImage.src = src;
this.colors = ["#00F","#09f","#fff", "#999"]
//this.fontImage.onload = this.drawChar();
}
drawChar(charCode, posX, posY, color){
var charmap = [
[' ','a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n', 'o', 'p', 'q', 'r', 's', 't', 'u', 'v', 'w', 'x','y', 'z', '☺', '☻','♡','♦','♣','♤', '•', '◘', '○', '◙','♂','♀','♪','♫','☼','►','◄','↕','‼','¶','§','▬','↨','↑','↓','→','←','∟','↔','▲','▼',
'░','▒','▓','│','┤','╡','╢','╖','╕','╣','║','╗','╝','╜','╛','┐',
'└','┴','┬','├','─','┼','╞','╟','╚','╔','╩','╦','╠','═','╬','╧',
'╨','╤','╥','╙','╘','╒','╓','╫','╪','┘','┌','█','▄','▌','▐','▀',
'space', '!','"','#','$','%','&',"'",'(',')','*','+',',','-','.','/',
'0','1','2','3','4','5','6','7','8','9',':',';','<','=','>','?',
'@','A','B','C','D','E','F','G','H','I','J','K','L','M','N','O',
'P','Q','R','S','T','U','V','W','X','Y','Z','[','/',']','^','_',
],
[
[0,0],[6, 1], [6, 2], [6, 3], [6, 4], [6, 5], [6, 6], [6, 7], [6, 8], [6, 9], [6, 10], [6, 11], [6, 12],[6, 13],[6, 14], [6, 15],[7,0],
[7, 1],[7, 2], [7, 3], [7, 4], [7, 5], [7, 6], [7, 7], [7, 8],[7, 9],[7, 10],
[0, 1], [0, 2],[0,3], [0,4],[0,5],[0,6],[0,7],[0,8],[0,9],[0,10],[0,11],[0,12],[0,13],[0,14],[0,15],
[1,0],[1,1], [1, 2], [1, 3], [1, 4], [1, 5], [1, 6], [1, 7], [1, 8], [1, 9], [1, 10], [1, 11], [1, 12], [1, 13], [1, 14], [1, 15],

[11,0],[11,1],[11,2],[11,3],[11,4], [11, 5], [11, 6], [11, 7], [11, 8], [11, 9], [11, 10], [11, 11], [11, 12], [11, 13], [11, 14], [11, 15],
[12,0],[12,1],[12,2],[12,3],[12,4], [12, 5], [12, 6], [12, 7], [12, 8], [12, 9], [12, 10], [12, 11], [12, 12], [12, 13], [12, 14], [12, 15],
[13,0],[13,1],[13,2],[13,3],[13,4], [13, 5], [13, 6], [13, 7], [13, 8], [13, 9], [13, 10], [13, 11], [13, 12], [13, 13], [13, 14], [13, 15],
[2,0],[2,1], [2, 2], [2, 3], [2, 4], [2, 5], [2, 6], [2, 7], [2, 8], [2, 9], [2, 10], [2, 11], [2, 12], [2, 13], [2, 14], [2, 15],
[3,0],[3,1], [3, 2], [3, 3], [3, 4], [3, 5], [3, 6], [3, 7], [3, 8], [3, 9], [3, 10], [3, 11], [3, 12], [3, 13], [3, 14], [3, 15],
[4,0],[4,1], [4, 2], [4, 3], [4, 4], [4, 5], [4, 6], [4, 7], [4, 8], [4, 9], [4, 10], [4, 11], [4, 12], [4, 13], [4, 14], [4, 15],
[5,0],[5,1], [5, 2], [5, 3], [5, 4], [5, 5], [5, 6], [5, 7], [5, 8], [5, 9], [5, 10], [5, 11], [5, 12], [5, 13], [5, 14], [5, 15],
]
]
var scopeX = charmap[1][charmap[0].indexOf(charCode)][1] * 8;
var scopeY = charmap[1][charmap[0].indexOf(charCode)][0] * 16
game.ctx.drawImage(this.fontImage, scopeX, scopeY, 7 , 15 , posX, posY, 16, 32);

}
}

如果我在drawChar()函数的末尾使用此代码

game.ctx.drawImage(this.fontImage, scopeX, scopeY, 7, 15, posX, posY, 16, 32);
game.ctx.globalCompositeOperation = "source-out"
game.ctx.fillStyle = this.colors[getRandomInt(0, 3)];
game.ctx.fillRect(0, 0, 16, 32);

game.ctx.globalCompositeOperation = "source-over"

根据需要对第一瓦片进行着色,但是没有显示其他瓦片。我对游戏开发的所有复杂性还是个新手,不知道该如何添加颜色

我使用2d数组,如下所示:

var map = [
[1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1],
[1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1],
[1,0,0,2,0,0,0,3,0,0,0,0,0,4,0,0,0,2,0,1],
[1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1],
[1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1],
[1,0,0,3,0,0,0,4,0,0,0,0,0,0,0,0,0,0,0,1],
[1,0,0,0,0,0,0,0,0,0,0,0,0,3,0,0,0,0,0,1],
[1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,2,0,1],
[1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1],
[1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1],
]

然后i循环浏览地图中的所有值,并根据值设置填充样式。

for (y = 0; y < map.length; y++) {
for (x = 0; x < map[y].length; x++) {
ctx.fillStyle = ["green", "red", "yellow", "blue"][map[y][x]];
ctx.fillRect(x * tilesize, y * tilesize, tilesize, tilesize);
}
}

你也可以使用图像而不是颜色,

switch(map[x][y]){
case 1:
img = stone;
break;
case 2:
img = grass;
break;
} 
ctx.fillImage(img,0,0,300,300,x*tilesize,y*tilesize,tilesize,tilesize);

有关这些参数的更多信息,请查阅ctx.fillImage()。

然后最后的程序会像这个

<canvas id="c" width=800 height=800></canvas>
<script>
const canvas = document.getElementById('c');
const ctx = canvas.getContext('2d');
var tilesize = 10
var map = [
[1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1],
[1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1],
[1,0,0,2,0,0,0,3,0,0,0,0,0,4,0,0,0,2,0,1],
[1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1],
[1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1],
[1,0,0,3,0,0,0,4,0,0,0,0,0,0,0,0,0,0,0,1],
[1,0,0,0,0,0,0,0,0,0,0,0,0,3,0,0,0,0,0,1],
[1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,2,0,1],
[1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1],
[1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1],
]
function drawmap() {
for (y = 0; y < map.length; y++) {
for (x = 0; x < map[y].length; x++) {
ctx.fillStyle = ["red", "blue", "cyan", "yellow"][map[y][x]]
ctx.fillRect(x * tilesize, y * tilesize, tilesize, tilesize)
}
}
}
drawmap()
</script>

<img id="stone" src="https://encrypted-tbn0.gstatic.com/images? 
q=tbn:ANd9GcTFYnQ2tB7R4YVGtOquPzZxc2fq_taDOYryug&usqp=CAU" style="display:none;">
<img id="grass" src="https://encrypted-tbn0.gstatic.com/images? 
q=tbn:ANd9GcTFYnQ2tB7R4YVGtOquPzZxc2fq_taDOYryug&usqp=CAU" style="display:none;">
<canvas id="c" width=800 height=800></canvas>
<script>
const canvas = document.getElementById('c');
const ctx = canvas.getContext('2d');
var grass = document.getElementById("grass")
var stone = document.getElementById("stone")
var tilesize = 10
var map = [
[1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1],
[1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1],
[1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,2,0,1],
[1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1],
[1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1],
[1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1],
[1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1],
[1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1],
[1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1],
[1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1],
]
function drawmap() {
for (y = 0; y < map.length; y++) {
for (x = 0; x < map[y].length; x++) {
switch(map[y][x]){
case 1:
img = stone;
break;
case 2:
img = grass;
break;
}
ctx.drawImage(img,0,0,300,300,x*tilesize,y*tilesize,tilesize,tilesize);
}
}
}

我知道这不是你想要的,但这是一个非常好和快速的方法来做到这一点。

最新更新