I have been working on a snake game in Javascript using HTML 5 Canvas. The game works with no errors and the image is being loaded by the webpage, however the image is not drawn.
<script>
$(document).ready(function(){
// get canvas context
var cvs = $("canvas").get(0);
var ctx = cvs.getContext("2d");
// declare variables
var food;
var snake;
var grid = 20;
var h = cvs.height;
var w = cvs.width;
var apple = new Image();
//Makes the canvas look sharp
cvs.width *= 2;
cvs.height *= 2;
cvs.style.width = cvs.width / 2;
cvs.style.height = cvs.height / 2;
ctx.scale(2, 2);
function init(){
apple.src = "food.png";
keyPress();
reset();
setInterval(draw, 1000 / 10);
}
function reset(){
snake = {
direction: "right",
x: 0,
y: 0,
length: 5,
pieces: [],
score: 0
};
food = [];
addFood();
}
function draw() {
// calls functions and clears squares
updateSnake();
moveSnake();
ctx.clearRect(0, 0, w, h);
drawFood();
drawSnake();
// stores score as a string
var snakeText = snake.score.toString();
// add 0's to counter
while (snakeText.length < 3) {
snakeText = "0" + snakeText;
}
// displays score counter
ctx.fillStyle = "red";
ctx.textBaseline= "top";
ctx.font = "20px monospace";
ctx.fillText("Score: " + snakeText, 5, 0);
}
// draw visible snake
function drawSnake(){
ctx.fillStyle = "green";
ctx.strokeStyle = "black";
ctx.lineWidth = 1;
// draw square on snakes head
ctx.beginPath();
ctx.rect(snake.x, snake.y, grid, grid);
ctx.stroke();
ctx.fill();
// draws a square on all of the snakes body piecees
for (var i = 0; i < snake.pieces.length; i++) {
ctx.beginPath();
ctx.rect(snake.pieces[i].x, snake.pieces[i].y, grid, grid);
ctx.stroke();
ctx.fill();
}
}
function updateSnake(){
// detects collision with snakes head and body
for (var i = 0; i < snake.pieces.length; i++) {
if(snake.x == snake.pieces[i].x && snake.y == snake.pieces[i].y){
reset();
}
}
// get the last element of the food array
var foodIndex = food.length - 1;
// go through food array
while (foodIndex >= 0) {
// detects snake collision with food, increase snake length, remove food, increase score
if(snake.x == food[foodIndex].x && snake.y == food[foodIndex].y){
snake.length +=1;
food.splice(foodIndex, 1);
snake.score+=1;
//add new food
addFood();
}
// go to the next piece of food
foodIndex--;
}
// clamps down array to length of snake
snake.pieces.length = Math.min(snake.pieces.length, snake.length - 1);
// adds the snake pieces to beeginning of array, at the snakes head location
snake.pieces.unshift({
x: snake.x,
y: snake.y
});
}
// generates food in random locations
function addFood(){
var valid;
// generates food if allowed
while (true) {
valid = true;
var newFood = {
x: Math.floor(Math.random()*(w / grid)) * grid,
y: Math.floor(Math.random()*(h / grid)) * grid
};
// stops food being put on the snakes head
if (snake.x == newFood.x && snake.y == newFood.y) {
console.log("head");
valid = false;
}
// stops food from being put on the sankes body
for (var i = 0; i < snake.pieces.length; i++) {
if(newFood.x == snake.pieces[i].x && newFood.y == snake.pieces[i].y){
console.log("body");
valid = false;
}
}
// stops food from being out on top of each other
for (var i = 0; i < food.length; i++) {
if(newFood.x == food[i].x && newFood.y == food[i].y){
valid = false;
}
}
// add new food to array
if (valid) {
food.push(newFood);
break;
}
}
}
window.addFood = addFood;
// draws the visible food
function drawFood(){
ctx.fillStyle = "salmon";
ctx.strokeStyle = "black";
//Draws at the foods location
for (var i = 0; i < food.length; i++) {
ctx.drawImage(apple, food.x, food.y, grid, grid);
}
}
function moveSnake(){
if(snake.direction == "right"){
snake.x+= grid;
}
if(snake.direction == "left"){
snake.x-= grid;
}
if(snake.direction == "up"){
snake.y-= grid;
}
if(snake.direction == "down"){
snake.y+= grid;
}
if(snake.x < 0){
reset();
}
if(snake.x > w-20){
reset();
}
if(snake.y > h-20){
reset();
}
if(snake.y < 0){
reset();
}
}
// detects keys pressed
function keyPress(){
$(document).keydown(function(e){
if(e.keyCode == 37 && snake.direction != "right"){
snake.direction = "left";
}
if(e.keyCode == 39 && snake.direction != "left"){
snake.direction = "right";
}
if(e.keyCode == 38 && snake.direction != "down"){
snake.direction = "up";
}
if(e.keyCode == 40 && snake.direction != "up"){
snake.direction = "down";
}
})
}
init();
});
</script>
<canvas width="400" height="400" style="border: solid black 1px">
Sorry, no canvas support!
</canvas>
The image is created in the variablees and given a source in my init() function:
var cvs = $("canvas").get(0);
var ctx = cvs.getContext("2d");
// declare variables
var food;
var snake;
var grid = 20;
var h = cvs.height;
var w = cvs.width;
var apple = new Image();
//Makes the canvas look sharp
cvs.width *= 2;
cvs.height *= 2;
cvs.style.width = cvs.width / 2;
cvs.style.height = cvs.height / 2;
ctx.scale(2, 2);
function init(){
apple.src = "food.png";
keyPress();
reset();
setInterval(draw, 1000 / 10);
}
drawImage() is called here in the drawFood() function:
function drawFood(){
ctx.fillStyle = "salmon";
ctx.strokeStyle = "black";
//Draws at the foods location
for (var i = 0; i < food.length; i++) {
ctx.drawImage(apple, food.x, food.y, grid, grid);
}
}
I have tried using an onLoad function / EventListeners but cannot get it to work.
Thanks.
The problem is in the draw food function
function drawFood(){
ctx.fillStyle = "salmon";
ctx.strokeStyle = "black";
//Draws at the foods location
for (var i = 0; i < food.length; i++) {
// you had ctx.drawImage(apple, food.x, food.y, grid, grid);
// should be
ctx.drawImage(apple, food[i].x, food[i].y, grid, grid);
}
}
But you should still check images have loaded before you try to draw them. There are plenty of examples of how to load images here on stackoverflow.
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.