color system for tile base game - javascript

I have started a project to teach myself the mechanics behind tile-base game engines. So far I have a pretty good little demo working but I can't figure out how to implement colors for each tile. I would like for any tile to be any color but this proves to be complicated for me.
the entire game uses 2d arrays for every object/component on the screen. There is a central 2d array that stores all of the walls and floor tiles and anything that's not a separate moving object.
my idea was to have a parallel array that stores color values. Then to iterate and change the color of each tile accordingly.
The base part of my code where I do the actual drawing is in a class called font
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);
}
}
if I use this code at the end of my drawChar() function
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"
the first tile is colored as desired but none of the other tiles display. I am still new to all the intricacies of game development and do not know how I should go about adding colors

I use 2d arrays, like so:
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],
]
An then i loop through all of the values in the map and set the fill style depending on the value.
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);
}
}
And you can also use images instead of colors,
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);
Look up ctx.fillImage() for more info on those parameters.
Then the final program would look like this
<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>
OR
<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);
}
}
}
I know this is not exactly what you asked for,
but it is a very good and fast way to do this.

Related

2d array manipulation in javascript

I have a 2d array in the following format:
export const dataBubble = [
[0, 0, 0],
[0, 1, 0],
[0, 2, 0],
[0, 3, 0],
[0, 4, 0],
[0, 5, 0],
[0, 6, 0],
[0, 7, 0],
[0, 8, 0],
[0, 9, 0],
[0, 10, 0],
[1, 0, 6],
[1, 1, 8],
[1, 2, 5],
[1, 3, 6],
[1, 4, 1],
[1, 5, 4],
[1, 6, 5],
[1, 7, 5],
[1, 8, 4],
[1, 9, 3],
[1, 10, 9],
[2, 0, 5],
[2, 1, 5],
[2, 2, 5],
[2, 3, 6],
[2, 4, 8],
[2, 5, 7],
[2, 6, 8],
[2, 7, 5],
[2, 8, 4],
[2, 9, 2],
[2, 10, 8],
[3, 0, 9],
[3, 1, 5],
[3, 2, 9],
[3, 3, 8],
[3, 4, 5],
[3, 5, 4],
[3, 6, 2],
[3, 7, 5],
[3, 8, 7],
[3, 9, 6],
[3, 10, 3],
[4, 0, 7],
[4, 1, 3],
[4, 2, 9],
[4, 3, 5],
[4, 4, 11],
[4, 5, 6],
[4, 6, 7],
[4, 7, 6],
[4, 8, 4],
[4, 9, 4],
[4, 10, 5],
[5, 0, 1],
[5, 1, 3],
[5, 2, 6],
[5, 3, 8],
[5, 4, 5],
[5, 5, 5],
[5, 6, 4],
[5, 7, 8],
[5, 8, 9],
[5, 9, 2],
[5, 10, 4],
[6, 0, 2],
[6, 1, 1],
[6, 2, 0],
[6, 3, 3],
[6, 4, 8],
[6, 5, 5],
[6, 6, 6],
[6, 7, 2],
[6, 8, 5],
[6, 9, 6],
[6, 10, 4],
[7, 0, 1],
[7, 1, 0],
[7, 2, 5],
[7, 3, 0],
[7, 4, 5],
[7, 5, 8],
[7, 6, 9],
[7, 7, 0],
[7, 8, 7],
[7, 9, 8]
];
We need to reverse the array elements based on the first two elements of the inner array, such that the resultant array becomes:
[
[0,10,0],
[0,9,0],
[0,8,0],
[0,7,0],
[0,6,0],
[0,5,0],
[0,4,0],
[0,3,0],
[0,2,0],
[0,1,0],
[1,10,9],
[1,9,3],
[1,8,4],
[1,7,5],
.
.
.
.
.
.
.
.
.
[7,0,1]
I use this in a react js project, so is there anyway we can use the JS map function of an array to do it? If not what will be the optimal solution?
If your second value is guaranteed to be less than an amount (for example I assumed 1000 in this case) then you can do this:
dataBubble.sort((x, y) => (x[0] - y[0])*1000 + y[1] - x[1]);
Basically we sum them up, but give the first element a higher coefficient, thus making it the primary sorter.
Otherwise, you need to involve an if check:
dataBubble.sort((x, y) => {
if(x[0] == y[0]) {
return y[1] - x[1];
} else {
return x[0] - y[0];
}
});
If you return a negative value from the sort function, JS will put x before y. Otherwise it will put x after y.
If x[0] and y[0] are equal, we need to sort depending on x[1] and y[1]. y[1] - x[1] will be negative if x[1] is larger, therefore if x[1] is larger x will come before y.
If x[0] and y[0] are different we need to sort based on them. x[0] - y[0] will be negative if x[0] is smaller, therefore if x[0] is smaller, x will come before y.

How to point the range(dataClasses) for 2nd index in data using highcharts?

I have plotted a heatmap using highchart , but i wanted to give color range for y axis ie 2nd index in the data array but it takes 3rd index automatically.
Below is the jsfiddle code.
Links for my code
colorAxis: {
dataClasses: [{
from: 0,
to: 10,
color: 'rgb(191, 27, 0)'
},{
from:10,
to:30,
color:'rgb(234, 100, 96)'
},{
from:30,
to:100,
color:'rgb(242, 201, 109)'
},{
from:100,
color:'rgb(98, 158, 81)'
}]
},
series: [{
name: 'Sales per employee',
borderWidth: 1,
data: [[0, 0, 10], [0, 1, 19], [0, 2, 8], [0, 3, 24], [0, 4, 67], [1, 0, 92], [1, 1, 58], [1, 2, 78], [1, 3, 117], [1, 4, 48], [2, 0, 35], [2, 1, 15], [2, 2, 123], [2, 3, 64], [2, 4, 52], [3, 0, 72], [3, 1, 132], [3, 2, 114], [3, 3, 19], [3, 4, 16], [4, 0, 38], [4, 1, 5], [4, 2, 8], [4, 3, 117], [4, 4, 115], [5, 0, 88], [5, 1, 32], [5, 2, 12], [5, 3, 6], [5, 4, 120], [6, 0, 13], [6, 1, 44], [6, 2, 88], [6, 3, 98], [6, 4, 96], [7, 0, 31], [7, 1, 1], [7, 2, 82], [7, 3, 32], [7, 4, 30], [8, 0, 85], [8, 1, 97], [8, 2, 123], [8, 3, 64], [8, 4, 84], [9, 0, 47], [9, 1, 99], [9, 2, 31], [9, 3, 48], [9, 4, 91]],
dataLabels: {
enabled: true,
color: '#000000'
}
}]
The actual data is in below format
data: [[0, 0, 10], [0, 1, 19]]
Now range is plotted on the base of 2nd index ie 10,19 but i want to plot based on 1st index ie 0,1.
Change the default name of the property (of point object) that'll be used to compute the color :
Highcharts.seriesTypes.heatmap.prototype.colorKey = 'x'; // 'value' by default
Live demo: http://jsfiddle.net/BlackLabel/z3b1Lcqg/
Docs: https://www.highcharts.com/docs/extending-highcharts/extending-highcharts

BorderRadius Using HighCharts HeatMap

Would I be able to round the edges of a heatmap made with highcharts?
See their example here:
http://jsfiddle.net/gh/get/jquery/1.9.1/highslide-software/highcharts.com/tree/master/samples/highcharts/demo/heatmap/
I'm trying to get each square to have rounded edges, but the borderRadius command isn't working when I add it.
E.g.
series: [{
name: 'Sales per employee',
// My addition
borderRadius: 5,
borderWidth: 1,
data: [[0, 0, 10], [0, 1, 19], [0, 2, 8], [0, 3, 24], [0, 4, 67], [1, 0, 92], [1, 1, 58], [1, 2, 78], [1, 3, 117], [1, 4, 48], [2, 0, 35], [2, 1, 15], [2, 2, 123], [2, 3, 64], [2, 4, 52], [3, 0, 72], [3, 1, 132], [3, 2, 114], [3, 3, 19], [3, 4, 16], [4, 0, 38], [4, 1, 5], [4, 2, 8], [4, 3, 117], [4, 4, 115], [5, 0, 88], [5, 1, 32], [5, 2, 12], [5, 3, 6], [5, 4, 120], [6, 0, 13], [6, 1, 44], [6, 2, 88], [6, 3, 98], [6, 4, 96], [7, 0, 31], [7, 1, 1], [7, 2, 82], [7, 3, 32], [7, 4, 30], [8, 0, 85], [8, 1, 97], [8, 2, 123], [8, 3, 64], [8, 4, 84], [9, 0, 47], [9, 1, 114], [9, 2, 31], [9, 3, 48], [9, 4, 91]],
dataLabels: {
enabled: true,
color: '#000000'
}
}]
I have also tried:
plotOptions:{
heatmap:{
borderRadius:5
}
},
Neither seem to work.
In general it is no supported, but there is a very easy hack to implement this:
Highcharts.seriesTypes.heatmap.prototype.pointAttrToOptions.r = 'borderRadius';
Demo: http://jsfiddle.net/uds4vvfa/1/

Google Charts won't align on top

I've tried all the answers I could find here but I'm lost. I'm making a simple flask app to query a database and present information to my client. I'd like to use google charts but when I output a simple chart it shows up far down the page. I want it to align in the center at the top how can I achieve this without linking to external css? I've tried everything I could find so here is a cleaned up version of my html.
<html>
<head>
<script type="text/javascript" src="https://www.google.com/jsapi"></script>
<script type="text/javascript">
google.load('visualization', '1.0', {'packages':['corechart']});
google.setOnLoadCallback(drawChart);
function drawChart() {
var data = new google.visualization.DataTable();
data.addColumn('string', 'Patients');
data.addColumn('number', 'Date');
data.addRows([
['05/29', 26],
['05/30', 16],
['06/01', 32],
['06/02', 15],
['06/03', 23],
['06/04', 6],
['06/05', 16],
['06/06', 21],
['06/08', 29],
['06/09', 21],
['06/10', 19],
['06/11', 14],
['06/12', 14],
['06/13', 10],
['06/15', 17],
['06/16', 17],
['06/17', 12],
['06/18', 9],
['06/19', 9],
['06/20', 9],
['06/22', 8],
['06/23', 16],
['06/24', 9],
['06/25', 8],
['06/26', 6],
['06/27', 6],
['06/29', 2],
['06/30', 1],
['07/01', 1],
['07/02', 1],
['07/06', 9],
['07/07', 10],
['07/08', 8],
['07/09', 8],
['07/10', 11],
['07/11', 8],
['07/13', 7],
['07/14', 9],
['07/15', 8],
['07/16', 7],
['07/17', 8],
['07/18', 3],
['07/20', 8],
['07/21', 6],
['07/22', 1],
['07/23', 2],
['07/24', 6],
['07/25', 7],
['07/27', 4],
['07/28', 2],
['07/29', 3],
['07/30', 1],
['07/31', 5],
['08/01', 7],
['08/03', 6],
['08/04', 7],
['08/05', 7],
['08/06', 7],
['08/07', 3],
['08/08', 7],
['08/10', 8],
['08/11', 5],
['08/12', 3],
['08/13', 4],
['08/14', 5],
['08/15', 6],
['08/17', 5],
['08/18', 3],
['08/19', 4],
['08/20', 3],
['08/21', 3],
['08/22', 4],
['08/24', 3],
['08/25', 4],
['08/26', 5],
['08/27', 5],
['08/28', 6],
['08/29', 5],
['09/01', 4],
['09/02', 3],
['09/03', 1],
['09/04', 4],
['09/05', 3],
['09/07', 1],
['09/08', 2],
['09/09', 2],
['09/11', 2],
['09/12', 2],
['09/14', 5],
['09/15', 3],
['09/16', 2],
['09/17', 4],
['09/18', 6],
['09/19', 1],
['09/21', 2],
['09/22', 3],
['09/23', 3],
['09/24', 6],
['09/25', 4],
['09/26', 3],
['09/28', 7],
['09/29', 4],
['09/30', 5],
['10/01', 3],
['10/02', 2],
['10/03', 2],
['10/05', 4],
['10/06', 4],
['10/07', 5],
['10/08', 4],
['10/09', 5],
['10/10', 2],
['10/12', 2],
['10/13', 3],
['10/14', 3],
['10/15', 3],
['10/16', 4],
['10/17', 5],
['10/19', 3],
['10/20', 3],
['10/21', 3],
['10/22', 3],
['10/23', 7],
['10/24', 1],
['10/26', 4],
['10/27', 3],
['10/28', 4],
['10/29', 1],
['10/30', 2],
['11/02', 5],
['11/03', 1],
['11/04', 5],
['11/05', 6],
['11/06', 3],
['11/09', 7],
['11/10', 4],
['11/12', 4],
['11/13', 3],
['11/14', 2],
['11/16', 8],
['11/17', 1],
['11/18', 4],
['11/19', 7],
['11/20', 3],
['11/21', 4],
['11/23', 5],
]);
var options = {'title':'Future appointment projections',
'width':750,
'height':4000};
var chart = new google.visualization.BarChart(document.getElementById('chart_div'));
chart.draw(data, options); }
</script>
</head>
<body><div id="chart_div"></div></body></html>
I had to change the chart options like so:
var options = {'title':'Future appointment projections',
'width': 750,
'height': 4000,
'chartArea': {'height': '96%'},
'legend': {'position': 'bottom'}
};
Thanks to Approv3d of reddit for the assist.

javascript arrays, how to change this array structure

I have 3 arrays in javascript. I'd like to combine them all into 1 var, but name each item (like PHP's associate array). So the first item is red, second is green, third is blue. And then how do I call each item separately after?
[[2, 1], [4, 1], [10, 1], [19, 1]],
[[3, 1], [14, 1], [18, 1], [19, 1]],
[[7, 1], [6, 1], [8, 1], [17, 1]]
Do you mean something like this?
var combined = {
red: [[2, 1], [4, 1], [10, 1], [19, 1]],
green: [[3, 1], [14, 1], [18, 1], [19, 1]],
blue: [[7, 1], [6, 1], [8, 1], [17, 1]]
};
Then you can access the arrays as combined.red, combined.green, and combined.blue.

Categories