Reputation: 1911
I'm working on creating a tic-tac-toe game in canvas. I'm currently stuck at a point where I detect if there is a symbol(X or O) already at x/y cordinates on the canvas.
I tried using ImageData to check if an element is present but it returns an error if nothing is there. I also thought perhaps I could assign an ID to the square or the symbol. However that doesn't seem to be possible from what I've read.
Any help would be appreciated.
You can see the game running here http://jsfiddle.net/weeklygame/dvJ5X/30/
function TTT() {
this.canvas = document.getElementById('ttt');
this.context = this.canvas.getContext('2d');
this.width = this.width;
this.height = this.height;
this.square = 100;
this.boxes = [];
this.turn = Math.floor(Math.random() * 2) + 1;
this.message = $('.message');
};
var ttt = new TTT();
TTT.prototype.currentPlayer = function() {
var symbol = (this.turn === 1) ? 'X' : 'O';
ttt.message.html('It is ' + symbol + '\'s turn');
};
// Draw the board
TTT.prototype.draw = function(callback) {
// Draw Grid
for(var row = 0; row <= 200; row += 100) {
var group = [];
for(var column = 0; column <= 200; column += 100) {
group.push(column);
this.context.strokeStyle = 'white';
this.context.strokeRect(column,row,this.square,this.square);
};
this.boxes.push(group);
};
callback;
};
// Get center of the click area cordinates
TTT.prototype.cordinates = function(e) {
var row = Math.floor(e.clientX / 100) * 100,
column = Math.floor(e.clientY / 100) * 100;
return [row, column];
};
// Check if the clicked box has symbol
TTT.prototype.check = function(row, column) {
};
// Get cordinates and set image in container
TTT.prototype.click = function(e) {
var cordinates = ttt.cordinates(e),
x = cordinates[0] + 100 / 2,
y = cordinates[1] + 100 / 2,
image = new Image();
if (ttt.turn === 1) {
image.src = 'http://s8.postimg.org/tdp7xn6lt/naught.png';
ttt.turn = 2;
} else {
image.src = 'http://s8.postimg.org/9kd44xt81/cross.png';
ttt.turn = 1;
};
ttt.context.drawImage(image, x - (image.width / 2), y - (image.height / 2));
ttt.currentPlayer();
};
function render() {
ttt.draw($('#ttt').on("click", ttt.click));
ttt.currentPlayer();
};
(function init() {
render();
})();
Upvotes: 1
Views: 1252
Reputation: 1250
To detect which field was clicked, iterate through your 9 fields and check if the clicked position is in the area where the field is drawn.
To be able to do this, store the state of your fields (position and if it has a X, O or nothing in it). You should also store the 9 fields in an array, so you can easily iterate over them. I would store it in a two dimensional array (3x3).
function Field(x, y) {
this.x = x;
this.y = y;
this.value = null; // Can be null, 'X' or 'O'
}
Initialisation of the tic tac toe field:
var fields = [
[new Field(0,0), new Field(1,0), new Field(2,0)],
[new Field(0,1), new Field(1,1), new Field(2,1)],
[new Field(0,2), new Field(1,2), new Field(2,2)]
];
Iteration:
for (var y = 0; y <= 2; y++) {
for (var x = 0; x <= 2; x++) {
var field = fields[y][x];
// Do something with the field.
}
}
I would store the position of the fields with model coordinates. So you multiply the coordinates with a value to get the coordinates for drawing on the canvas.
Upvotes: 2
Reputation: 6373
Would it not be easier for you to keep track of the grid positions using an array. When you place something on the grid allocate that position in the array. That way rather than having to work out a way to read it from the Canvas you just look in the array. This also allows you to quickly redraw the canvas from the array when needed, such as when the screen resizes...
Upvotes: 3