I have been working on an internship. The application I need to make needs to have different colors in the intersecting areas. I made a global variable of color. I am changing its values in the buttons I have created. But whenever I press the button it changes color of each intersecting area even though I have pushed it in array with its own color. How can I solve this issue
let squares = [];
let overlappingsquares = []; //variable to hold squares drawn in intersecting area
let dragObject = null; // variable to hold the object being dragged
var myColour = (255);
function setup() {
createCanvas(600, 520);
button1 = createButton("Alpha");
button2 = createButton("Bravo");
button3 = createButton("Charlie");
button4 = createButton("Delta");
button5 = createButton("Echo");
button6 = createButton("Foxtrot");
button7 = createButton("Golf");
button8 = createButton("Hotel");
button9 = createButton("India");
button10 = createButton("Juliet");
button1.mousePressed(fun1);
button2.mousePressed(fun2);
button3.mousePressed(fun3);
button4.mousePressed(fun4);
button5.mousePressed(fun5);
button6.mousePressed(fun6);
button7.mousePressed(fun7);
button8.mousePressed(fun8);
button9.mousePressed(fun9);
button10.mousePressed(fun10);
//frameRate(1);
}
function draw() {
background(135,206,250);
//myColour = (255);
// if a square is being dragged, update its position
if (this.dragObject != null) {
this.dragObject.position.x = mouseX;
this.dragObject.position.y = mouseY;
}
//draw all squares
for (let i = 0; i < squares.length; i++) {
let s = squares[i];
s.show();
}
for (let i = 0; i < squares.length; i++) {
for (let j = i + 1; j < squares.length; j++) {
//block checking collision
if (i != j && squares[i].collides(squares[j])) {
squares[i].changecolor();
//set intersection color
//fill(myColour);
//calculate parameters
newX = Math.max(squares[i].position.x, squares[j].position.x);
newY = Math.max(squares[i].position.y, squares[j].position.y);
newW = Math.min(squares[i].position.x + squares[i].w, squares[j].position.x + squares[j].w) - newX;
newH = Math.min(squares[i].position.y + squares[i].h, squares[j].position.y + squares[j].h) - newY;
//draw rectangle
let col = myColour
let Osquare = new OverlappingSquares(newX, newY, newW, newH, col);
overlappingsquares.push(Osquare);
}
}
}
}
function mousePressed() {
if (this.dragObject == null) {
//ask every square if they are being "hit"
for (let i = 0; i < squares.length; i++) {
let s = squares[i];
if (s.hitTest()) {
//if so, set the drag object as this square and return
this.dragObject = s;
return;
}
}
//no squares are hit, create a new square.
let square = new Square(mouseX, mouseY);
squares.push(square);
}
}
//mouse is released, release the current dragged object if there is one
function mouseReleased() {
this.dragObject = null;
}
class Square {
constructor(InitialX, InitialY) {
this.w = 60;
this.h = 60;
this.position = {
x: InitialX,
y: InitialY
};
}
//basic test of mouse position against square position and if its inside the rectangle
hitTest() {
let x = mouseX - this.position.x;
let y = mouseY - this.position.y;
return (x > 0 && x < this.w) && (y > 0 && y < this.h);
}
show() {
fill(50);
rect(this.position.x, this.position.y, this.w, this.h);
}
collides(sqr) {
if (this.position.x < sqr.position.x + sqr.w &&
this.position.x + this.w > sqr.position.x &&
this.position.y < sqr.position.y + sqr.h &&
this.position.y + this.h > sqr.position.y) {
return true;
}
return false;
}
changecolor() {
for (let i = 0; i < squares.length; i++) {
let s = squares[i];
s.show();
}
for (let i = 0; i < overlappingsquares.length; i++) {
let s = overlappingsquares[i];
s.show();
}
}
}
//Overlapping sqaures class
class OverlappingSquares {
constructor(X, Y, W, H, C) {
this.w = W;
this.h = H;
this.col = C
this.position = {
x: X,
y: Y
};
}
show() {
fill(this.col)
rect(this.position.x, this.position.y, this.w, this.h);
}
}
function fun1() {
myColour = color(0,255, 0); //green
}
function fun2() {
myColour = color(255, 0, 0); //red
}
function fun3() {
myColour = color(0, 0, 200); //blue
}
function fun4() {
myColour = color(250, 0, 150); //pink
}
function fun5() {
myColour = color(128, 0, 128); //purple
}
function fun6() {
myColour = color(255, 255, 0); //yellow
}
function fun7() {
myColour = color(128, 0, 0); //marroon
}
function fun8() {
myColour = color(255, 128, 0); //orange
}
function fun9() {
myColour = color(192, 105, 50); //brown
}
function fun10() {
myColour = color(255,228,196); //bisque
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/p5.js/0.9.0/p5.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/p5.js/0.9.0/addons/p5.dom.js"></script>
I went through your code and spotted this snippet
//draw rectangle
let col = myColour
let Osquare = new OverlappingSquares(newX, newY, newW, newH, col);
overlappingsquares.push(Osquare);
It's within the loop that you are calling on every single cycle. When ever you select a button, it sets the new value for 'myColour', and within the next loop it will color all overlapping elements. You don't really tell in detail what's your goal. But some how you will need to add another color variable and identify which button intersection you want to color which way...
I think it would be better to solve this in a different way. Looping over all elements will make your program lag.
Related
Using p5.js / p5.play I'm trying to click a moving sprite, but stuck on how to get the moving sprites coords and position. At the moment when I click anywhere on the canvas a random sprite disappears. I've been trying to use mouseX and mouseY. Very new to coding and just trying to learn fundamentals.
let enemy;
let spawnTimer = 0;
function setup() {
createCanvas(900, 900);
spritegroup = new Group();
clickedgroup = new Group();
}
function draw() {
background(255, 255, 255);
spritegroup.cull(20);
clickedgroup.cull(20);
spawnSprites();
spriteClicked();
drawSprites();
}
function spawnSprites() {
if (spawnTimer === 60) {
for (var i = 0; i < 2; i++) {
var angle = random(360);
var x = random(50, 850);
var y = -5 * sin(radians(angle));
createEnemy(3, x, y);
spawnTimer = 0;
}
}
spawnTimer++;
}
function createEnemy(type, x, y) {
enemy = createSprite(x, y);
enemy[floor(random(0, 4))];
enemy.setSpeed(3.5 - type / 2, 90);
spritegroup.add(enemy);
enemy.setCollider("rectangle", 0, 0, 100, 100);
enemy.debug = true;
return enemy;
}
function spriteClicked() {
if (mouseIsPressed == true)
if (
(mouseX > enemy.position.x,
enemy.position.y && mouseY > enemy.position.x,
enemy.position.y)
) {
enemy.remove();
}
}
The easiest way is to use sprite.mouse :)
https://p5play.org/learn/input_devices.html?page=3
So far, I've done research into the design by Armin Hoffman (rubber band design). The objective is to create a grid of circles which can be selected to change from white to black and connect these circles in a natural fluid shape that avoids white circles but never traps them. I've been using Codecademy to learn the basics while copying and studying examples on the p5.js website and additionally following The Coding Train on Youtube (specifically: 7.4 mouse interaction and 7.6 clicking on objects).
Check #MauriceMeilleur on Twitter between Feb 2021 and Aug 2021
Also: https://discourse.processing.org/t/shape-generator-help-armin-hofmanns-rubber-band-shape-generator/33190
Every time I try to make a matrix or array of x and y values stored and to be used in the for loop within the draw/setup functions, it becomes invalid and it doesn't show the shapes I would like.
I know I'm missing info.
This is my latest trial:
class boundingBox {
createBox() {
stroke(0);
strokeWeight(3);
fill(255, 255, 255, 255);
rect(100, 100, 700, 700);
}
}
function Bubble(x, y, x1, y1, x2, y2, x3, y3) {
// creating a distinction from x/y private and x/y public
this.x = x;
this.y = y;
this.x1 = x1;
this.y1 = y1;
this.x2 = x2;
this.y2 = y2;
this.x3 = x3;
this.y3 = y3;
//this.x = x = [225,350,475,600];
//this.y = y = [225,350,475,600];
// creating color public for later use
this.col = color(255);
// this expression works to make a public function within a private function
this.display = function() {
stroke(0);
fill(this.col);
// creating the ability to display the circles within the parameters set
//ellipse(this.x, this.y, 48,48);
// in theory this should loop through the x array position values against all the y values in it's array creating multiple circles
for (i = 0; i < 4; i++) {
ellipse(this.x /*[i]*/ , this.y, 100, 100);
ellipse(this.x1, this.y1, 100, 100);
ellipse(this.x2, this.y2, 100, 100);
ellipse(this.x3, this.y3, 100, 100);
}
}
//this.move = function() {
// //making the circles change position and act like they are moving within air
// this.x = this.x + random(-0.5, 0.5);
// this.y = this.y + random(-0.5, 0.5);
// this.x1 = this.x1 + random(-0.5, 0.5);
// this.y1 = this.y1 + random(-0.5, 0.5);
// //this.x = this.x + random(1, 0.5);
// //this.y = this.y + random(1, 0.5);
//}
// again expression to make function but this time implementing a clicking function
this.clicked = function() {
// calculating the distance from the circle center to help fill it with color and nothing else
var d = dist(mouseX, mouseY, this.x, this.y)
// diameter of the circle
if (d < 50) {
this.col = color(0, 0, 0)
}
}
//joinBubbles(bubbles); {
// bubbles.forEach(element => {
// let dis = dist(this.x, this.y, element.x, element.y);
// stroke(200, 200, 200, 127);
// line(this.x, this.y, element.x, element.y);
// });
//}
//}
//class lines {
// constructor(){
// this.x4 = x4;
// this.y4 = y4;
// this.x5 = x5;
// this.y5 = y5;
// }
// this.displayLine = function(){
// stroke(0)
// }
}
let bubbles = [];
let boxii = [];
function setup() {
createCanvas(1536, 1250);
for (let i = 0; i < 1; i++) {
boxii.push(new boundingBox());
}
for (let i = 200; i < 860; i += 165) {
//var x = random (width);
var x = 200;
var y = i;
bubbles.push(new Bubble(x, y /*x1,y1*/ ));
}
for (let i = 200; i < 860; i += 165) {
//var x = random (width);
var x1 = 375;
var y1 = i;
bubbles.push(new Bubble(x1, y1 /*x1,y1*/ ));
}
for (let i = 200; i < 860; i += 165) {
//var x = random (width);
var x2 = 550;
var y2 = i;
bubbles.push(new Bubble(x2, y2 /*x1,y1*/ ));
}
for (let i = 200; i < 860; i += 165) {
//var x = random (width);
var x3 = 700;
var y3 = i;
bubbles.push(new Bubble(x3, y3 /*x1,y1*/ ));
}
//for (let i = 0; i < 1; i++) {
//var x1 = 400;
//var y1 = 200;
//bubbles.push(new Bubble(x1,y1));
//}
//for (let i = 200; i < 1000; i+=200){
//var x2 = 200;
//var y2 = i;
//bubbles.push(new Bubble(x2,y2));
//}
}
function mousePressed() {
// checking where the mouse presses so that clicking outside the circle does nothing
for (let i = 0; i < bubbles.length; i++) {
//for (let i = 0; i < 4; i++) {
// using this function on all the circles and again using .this to bring properties from /bubble
bubbles[i].clicked();
}
}
function draw() {
background(140);
for (let i = 0; i < 1; i++) {
boxii[i].createBox();
}
for (let i = 0; i < bubbles.length; i++) {
//bubbles[i].move();
bubbles[i].display();
}
if (mousePressed) {
for (let i = 0; i < bubbles.length; i++) {
bubbles[i].display(fill(0))
}
}
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/p5.js/1.4.1/p5.js"></script>
This is in continuation to my previous post here Changing color of intersecting area of squares
I was able to make the intersecting area of the squares change color. The issue was that I wanted multiple intersecting squares and not a single one so I modified the code. Now the problem is that the square is leaving a trail since it is drawing square wherever it moves. And it starts to slow down after a while. How can I overcome this
function draw() {
background(135,206,250);
myColour = (255);
// if a square is being dragged, update its position
if (this.dragObject != null) {
this.dragObject.position.x = mouseX;
this.dragObject.position.y = mouseY;
}
//draw all squares
for (let i = 0; i < squares.length; i++) {
let s = squares[i];
s.show();
}
for (let i = 0; i < squares.length; i++) {
for (let j = i + 1; j < squares.length; j++) {
//block checking collision
if (i != j && squares[i].collides(squares[j])) {
squares[i].changecolor();
//set intersection color
fill(myColour);
//calculate parameters
newX = Math.max(squares[i].position.x, squares[j].position.x);
newY = Math.max(squares[i].position.y, squares[j].position.y);
newW = Math.min(squares[i].position.x + squares[i].w, squares[j].position.x + squares[j].w) - newX;
newH = Math.min(squares[i].position.y + squares[i].h, squares[j].position.y + squares[j].h) - newY;
//draw rectangle
let Osquare = new OverlappingSquares(newX, newY, newW, newH);
overlappingsquares.push(Osquare);
}
}
}
}
changecolor() {
// fill(random(255), random(255), random(255));
// background(200, 255, 100);
for (let i = 0; i < squares.length; i++) {
let s = squares[i];
s.show();
}
for (let i = 0; i < overlappingsquares.length; i++) {
let s = overlappingsquares[i];
s.show();
}
}
//Overlapping sqaures class
class OverlappingSquares {
constructor(X, Y, W, H) {
this.w = W;
this.h = H;
this.position = {
x: X,
y: Y
};
}
show() {
fill(myColour)
rect(this.position.x, this.position.y, this.w, this.h);
}
}
In my UFO shooter game I would like the player to be able to spike the closest UFO, to insure chaos and awesomeness. Lol. Anyways, I can't seem to figure out how to store the closest current UFO (or drone, as I call them in the code)...
Here are all of the functions and classes for the game. (kinda messy, I know, but I'll probably revise it later)
var score = 0;
var bullets = [];
var drones = [];
var keys = [];
keyPressed = function () {
keys[keyCode]=true;
};
keyReleased = function () {
keys[keyCode]=false;
};
var player = function (x,y) {
this.x = 25;
this.y = 440;
this.w = 15;
this.h = 20;
this.xvel = 0;
this.yvel = 0;
this.accel = 0.2;
this.frict = 0.08;
this.isShooting = false;
this.update = function () {
this.leftGun = this.x-11-this.xvel;
this.rightGun = this.x+20-this.xvel;
if (this.isShooting) {
this.gunsY = random(this.y,this.y+7);
} else {
this.gunsY = this.y+3;
}
if (keys[LEFT]) {
this.xvel -= this.accel;
}
if (keys[RIGHT]) {
this.xvel += this.accel;
}
if (keys[UP]) {
this.yvel -= this.accel;
}
if (keys[DOWN]) {
this.yvel += this.accel;
}
if (this.xvel > 0 || this.xvel < 0) {
this.xvel -= this.xvel * this.frict;
}
if (this.yvel > 0 || this.yvel < 0) {
this.yvel -= this.yvel * this.frict;
}
fill(255, 255, 255);
//rect(this.x-this.w/2,this.y + 5,this.w,this.h);
triangle(this.x,this.y+this.h-this.xvel+this.yvel,this.x+this.xvel+7,this.y,this.x+15,this.y+this.h+this.xvel+this.yvel);
fill(0,0,255);
//ellipse(this.x+7,this.y+14,7,7);
rect(this.leftGun,this.gunsY,4,15);
rect(this.rightGun,this.gunsY,4,15);
this.x += this.xvel;
this.y += this.yvel;
};
};
var p1 = new player();
// verify status
var active = function(obj){
return obj.x>0 && obj.y<height+100;
};
var bulletActive = function(blt){
return blt.x>0 && blt.x < width && blt.y>0 && blt.y<height+20;
};
var droneArt = function(){
var zz = this.z/2;
var dam = map(this.h, 0, 100, 0, this.z);
if (this.h<0){
this.x = -100;
score+=(80-this.z);
return;
}
fill(255, 0, 0);
rect(this.x-zz, this.y-zz-10, this.z, 4);
fill(0, 255, 0);
rect(this.x-zz, this.y-zz-10, dam, 4);
pushMatrix();
translate(this.x,this.y);
//rotate(r);
fill(255, 255, 255);
ellipse(0,0,this.z,this.z);
fill(0, 0, 0);
ellipse(0,0,this.z-this.z/1.8,this.z-this.z/1.8);
for(var i = 0; i < 360; i += 45){
rotate(i);
fill(0, 0, 0);
noStroke();
ellipse(this.z-this.z/1.6,0,this.z-this.z/1.15,this.z-this.z/1.15);
}
//r++;
popMatrix();
this.y += 0.4;
/*
for(var i = 0; i < 360; i += 45){
rotate(i);
fill(255,0,0);
ellipse(this.z-this.z/1.6,0,this.z-this.z/2,5);
}
*/
};
// drone object
var drone = function(x, y){
return {
x:x,
y:y,
z:20 + floor(random(2)) * 20,
h:100,
draw:droneArt };
};
// bullet object
var bullet = function(x, y, s, id){
return {
x:x, y:y, s:s, z:3,
draw: function(){
if (id==="canon"){
this.y -= 7;
fill(255, 97, 97);
ellipse(this.x+2,this.y+9,this.z*3,this.z*4);
fill(255, 0, 0);
ellipse(this.x,this.y+9,this.z*3.2,this.z*4.2);
} else {
this.y -= 14;
fill(102, 102, 255);
rect(this.x-this.z/2, this.y, this.z, this.z+10);
}
}
};
};
// collision test
var kill = function(obj){
var test = function(blt){
if (dist(obj.x, obj.y, blt.x, blt.y)<(obj.z+blt.z)/2){
obj.h -= blt.s;
blt.x = -100;
}
};
return test;
};
var r = 0;
var drawDrone = function(drn){
//r += 0.2;
pushMatrix();
translate(drone.x,0);
rotate(r);
drn.draw();
popMatrix();
bullets.forEach(kill(drn));
};
var drawBullet = function(blt){
blt.draw();
};
var ufo;
var distance;
var minUFO = 10000;
var drones = [drone(100, 100), drone(200, -100), drone(300, 0)];
/*minUFO = minUFO === null || t > minUFO ? t : minUFO;*/
var minUFO = 9999999999;
var findNearestDrone = function () {
for(var i=0; i < drones.length; i++) {
var ufo = drones[i];
var po = dist(ufo.x,ufo.y,p1.x,p1.y);
if (po < minUFO) {
minUFO = po;
}
fill(255, 0, 0);
stroke(255,0,0);
strokeWeight(2);
line(ufo.x,ufo.y,p1.x+8,p1.y);
noStroke();
//println(ufo + " drone " + i);
text(minUFO,30,100);
}
};
It turns out that, unlike what I expected; but logically, the minUFO only ever gets smaller. Instead of storing the position of the closest current UFO, it seems to store the smallest distance between the UFO and the player ever recorded in the session. Which, turns out, isn't what I want either. Anybody know how to store the current closest drone's position? Not just the distance like I have it right now, but its actual position. Thank you, and I'm sincerely sorry for my incredible ability to take a millennia to get to the point.
You should put the var minUFO = 9999999999; inside the findNearestDrone function. That way the variable is reset every time you call the function and is no longer influenced by the previous smallest distance.
Next, similarly to the way you store the minUFO, you can use a variable that keeps track of either the ufo itself or the index that is associated with the nearest ufo (so far).
I've modified your code with both options:
//initiate vars outside function
var nearestUFO;
var nearestIndex;
var findNearestDrone = function () {
//initiate var that tracks min distance inside function
var minUFO = 9999999999;
for(var i=0; i < drones.length; i++) {
var ufo = drones[i];
var po = dist(ufo.x,ufo.y,p1.x,p1.y);
if (po < minUFO) {
minUFO = po;
//store the current nearest ufo / index
nearestUFO= ufo;
nearestIndex= i;
}
fill(255, 0, 0);
stroke(255,0,0);
strokeWeight(2);
line(ufo.x,ufo.y,p1.x+8,p1.y);
noStroke();
//println(ufo + " drone " + i);
text(minUFO,30,100);
}
};
I am trying to make Conway's Game of Life in JavaScript, but cannot find what is wrong with a specific function after hours of debugging.
The program works by making a 2d array based of global "row" and "column" variables, and then pushes "Square" objects to each space in the array. The program then sets an interval for the "draw" function for a specific interval, (the global variable "rate").
I apologize if this is hard to understand, but basically, every specific time interval, like every 1000 milliseconds, the program checks every "Square" object in the array, updates the amount of neighbors it has, and then draws it on the screen.
This is where I am stuck; the update function is supposed to check all 8 neighbors that a square has, (or 3-5 if it is an edge square) but it will only check 4 neighbors. No matter what I do, if I click a square to populate it, only the top, top left, top right, and left neighbors of the now populated square will register that their neighbor has become populated.
Other than this bug the code is working fine, and i'm 99% sure the problem is in this one function, because the code will still function as a cellular automata currently, just not as Conway's Game of Life.
var canvas = document.getElementById("life");
var ctx = canvas.getContext('2d');
var timer;
var rate = 1000;
var rows = 20;
var columns = 20;
var width = 20;
var clickX;
var clickY;
var board;
var running = false;
var checkArray = [
[-1, 0, 1, 1, 1, 0, -1, -1],
[-1, -1, -1, 0, 1, 1, 1, 0]
];
var visuals = true;
var gridColor = "#000000";
/*
live cell with < 2 neighbors = death
live cell with 2 or 3 neighbors = live for 1 generation
live cell with > 4 neighbors = death
dead cell with 3 neighbors = live for 1 generation
0 = death
1 = death
2 = continues life if alive
3 = continues life if alive OR brings to life if dead
4 = death
5 = death
6 = death
7 = death
8 = death
*/
window.onload = function() {
makeBoard();
var timer = setInterval(draw, rate);
window.addEventListener("mousedown", clickHandler);
// for(var i = 0; i < 8; i++){
// var checkIndexX = checkArray[0][i];
// var checkIndexY = checkArray[1][i];
// console.log(checkIndexX, checkIndexY);
// }
}
function makeBoard() {
board = new Array(columns);
for (var i = 0; i < rows; i++) {
var intRow = new Array(rows);
for (var j = 0; j < columns; j++) {
intRow[j] = new Square(false, j, i);
}
board[i] = intRow;
}
}
function draw() {
ctx.clearRect(0, 0, canvas.width, canvas.height);
for (var y = 0; y < rows; y++) {
for (var x = 0; x < columns; x++) {
if (running) {
board[y][x].update();
}
board[y][x].draw();
if (visuals) {
board[y][x].visuals();
}
}
}
drawRunButton();
}
function Square(alive, PARX, PARY) {
this.alive = false;
this.X = PARX;
this.Y = PARY;
this.neighbors = 0;
this.update = function() {
this.neighbors = 0;
for (var i = 0; i < 8; i++) {
var checkIndexX = checkArray[0][i];
var checkIndexY = checkArray[1][i];
if ((this.X + checkIndexX) >= 0 && (this.X + checkIndexX) < columns &&
(this.Y + checkIndexY) >= 0 && (this.Y + checkIndexY) < rows) {
var check = board[this.Y + checkIndexY][this.X + checkIndexX];
// console.log(this.X, this.Y, check.X, check.Y, checkIndexX, checkIndexY);
if (check.alive) {
this.neighbors++;
}
}
}
if (this.alive) {
if (this.neighbors < 2 || this.neighbors > 3) {
this.alive = false;
}
} else {
if (this.neighbors == 3) {
this.alive = true;
}
}
};
this.visuals = function() {
drawVisuals(this.neighbors, this.X * width, this.Y * width);
};
this.draw = function(alive) {
drawSquare(this.alive, this.X * width, this.Y * width, width);
}
}
function clickHandler(e) {
var clickX = e.screenX - 68;
var clickY = e.screenY - 112;
mapClick(clickX, clickY);
manageRun(clickX, clickY);
}
function mapClick(x, y) {
var indexX = Math.floor(x / width);
var indexY = Math.floor(y / width);
if (indexX >= 0 && indexX < columns && indexY >= 0 && indexY < rows) {
board[indexY][indexX].alive = true;
}
}
function manageRun(x, y) {
if (x >= (columns * width) + 5 && x <= (columns * width) + 45 && y >= 5 && y <= 45) {
if (running) {
running = false;
} else {
running = true;
}
console.log(running);
}
}
function drawRunButton() {
drawSquare(false, (columns * width) + 5, 5, 40)
}
function drawSquare(fill, x, y, width) {
ctx.beginPath();
ctx.moveTo(x, y);
ctx.lineTo(x + width, y);
ctx.lineTo(x + width, y + width);
ctx.lineTo(x, y + width);
ctx.lineTo(x, y);
if (fill) {
ctx.fillStyle = gridColor;
ctx.fill();
} else {
ctx.strokeStyle = gridColor;
ctx.stroke();
}
}
function drawVisuals(neighbors, x, y) {
ctx.beginPath();
ctx.fillStyle = "#ff0000";
ctx.font = '20px serif';
ctx.fillText(neighbors, x + (width / 3), y + (width / 1.25));
}
<!DOCTYPE html>
<html>
<head>
<title>template.com</title>
<link href="style.css" type="text/css" rel="stylesheet">
</head>
<body>
<canvas id="life" width="1400" height="700" style="border: 1px solid black"></canvas>
</body>
</html>