Javascript snake game bugs - javascript

There are two issues, I can't control the snake, and now it just resets constantly without giving the snake a chance to move. I figured that if i kept coding the problem would go away but sadly its not a perfect world.
I tried different key codes for controlling the snake but it didn't work.
window.onload = function() {
var cvs = document.getElementById("canvas");
var ctx = cvs.getContext("2d");
var cvsW = cvs.width;
var cvsH = cvs.height;
var snekW = 10;
var snekH = 10;
//score
var score = 0;
//default direction
var direction = "right";
//read users directions
document.addEventListener("keydown",getDirection);
//To my knowledge this function should control the snake with the
keyboard
function getDirection(e)
{
if(e.keyCode == 37 && direction != "right"){
direction = "left";
}else if(e.keyCode == 38 && direction != "down"){
direction = "up";
}else if(e.keyCode == 39 && direction != "left"){
direction = "right";
}else if(e.keycode == 40 && direction != "up"){
direction = "down";
}
}
function drawSnek(x,y)
{
ctx.fillStyle = "Lime";
ctx.fillRect(x*snekW,y*snekH,snekW,snekH);
ctx.fillStyle = "#000";
ctx.strokeRect(x*snekW,y*snekH,snekW,snekH);
}
var len = 4; //default length of the snake
var snek = []; //the snake is an array
for(var i = len-1; i>=0; i--)
{
snek.push({x:i,y:0});
}
//exceptions for direction of snake
if(direction == "left") snekx--;
else if( direction == "up") sneky--;
else if( direction == "right") snekx++;
else if( direction == "down") sneky++;
//Functions for creating snake food have been removed.
var newHead = { x: snekx, y: sneky};
snek.unshift(newHead);
drawScore(score);
}
setInterval(draw, 10); //I do not fully understand this function
}

There were several issues with your code:
You needed a draw function that could be called in an interval. In this draw function you could draw the individual parts of the snake.
You were unable to control the snake correctly as you had a typo in the down part of the callback function.
You have to either introduce x / y variables for the head of the snake or use the first element of the array to retrieve it.
Unshifting the new position using snek.unshift will cause the snake to grow indefinitely. Removing array elements using
snek.splice(len,snek.length - len);
solves this problem.
If you only draw new elements to the screen the old parts you drew will still exist in new frames. A good idea would be to clear the canvas using
ctx.clearRect(0, 0, cvsW, cvsH);
window.onload = function () {
var cvs = document.getElementById("canvas");
var ctx = cvs.getContext("2d");
var cvsW = cvs.width;
var cvsH = cvs.height;
var snekW = 10;
var snekH = 10;
//score
var score = 0;
//default direction
var direction = "right";
//read users directions
document.addEventListener("keydown", getDirection);
//To my knowledge this function should control the snake with the keyboard
function getDirection(e) {
if (e.keyCode == 37 && direction != "right") {
direction = "left";
} else if (e.keyCode == 38 && direction != "down") {
direction = "up";
} else if (e.keyCode == 39 && direction != "left") {
direction = "right";
} else if (e.keyCode == 40 && direction != "up") {
direction = "down";
}
}
function drawSnek(x, y) {
ctx.fillStyle = "Lime";
ctx.fillRect(x * snekW, y * snekH, snekW, snekH);
ctx.fillStyle = "#000";
ctx.strokeRect(x * snekW, y * snekH, snekW, snekH);
}
let snekx = 0;
let sneky = 0;
var len = 4; //default length of the snake
var snek = []; //the snake is an array
for (var i = len - 1; i >= 0; i--) {
snek.push({ x: i, y: 0 });
}
function draw() {
ctx.clearRect(0, 0, cvsW, cvsH);
//exceptions for direction of snake
if (direction == "left") snekx--;
else if (direction == "up") sneky--;
else if (direction == "right") snekx++;
else if (direction == "down") sneky++;
//Functions for creating snake food have been removed.
var newHead = { x: snekx, y: sneky };
snek.unshift(newHead);
for(let i = 0; i < snek.length; i++) {
drawSnek(snek[i].x, snek[i].y)
}
snek.splice(len,snek.length - len);
//drawScore(score);
}
setInterval(draw, 50); //I do not fully understand this function
}
CodePen with fixed code:
https://codepen.io/lukasmoeller/pen/PvVzqq?editors=1111
(boundaries are not checked - the snake will leave the canvas)
Explanation of setInterval(fn, interval)
setInterval calls the function specified using fn every interval ms until it is cleared. The interval can be cleared by using clearInterval, passing it the return value of setInterval. If you want to delay function execution at the beginning you could add setTimeout, add a callback that sets the interval:
setTimeout(function(){
setInterval(draw, 50);
}, 1000)
This would only start drawing the game every 50 ms after 1000ms have passed.

Related

snake game - snake movement using array.pop and array.unshift

In my code the snake and it's movement consists of an array. In other words the snake's head is the first array number and last number is snake's tail. I try to implement the movement using array.pop and array.unshift. The problem is that the snake gets bigger and bigger as it moves. I think it is some very small detail that I'm missing. Here is the code:
var canvas = document.getElementById("canvas");
var ctx = canvas.getContext("2d");
var cWidth = canvas.width;
var cHeight = canvas.height;
var boxWidth = 10;
var boxHeight = 10;
var boxWH = 10; //One box width and height
var points = 0;
var score = document.getElementById("Score");
var foodImg = new Image();
var k;
foodImg.src = "Pictures/apple2.png";
var snake = [];
snake[0] = {
x: cWidth/2,
y: cHeight/2
};
var food = {
x: Math.floor(Math.random()*60)*boxWH,
y: Math.floor(Math.random()*60)*boxWH
}
document.addEventListener("keydown", direction);
function direction(event){
var key = event.keyCode;
if(key == 65 && k != "right"){
k = "left";
}
else if(key == 68 && k != "left"){
k = "right";
}
else if(key == 87 && k != "down"){
k = "up";
}
else if(key == 83 && k != "up"){
k = "down";
}
}
function SnakeGame(){
ctx.fillStyle = "green";
ctx.fillRect(0, 0, cWidth, cHeight);
var game = setInterval(Draw, 100);
}
function Draw(){
for(var i = 0; i<snake.length; i++){
ctx.fillStyle = (i == 0) ? "red" : "white";
ctx.fillRect(snake[i].x, snake[i].y, boxWH, boxWH);
ctx.strokeStyle = "yellow";
ctx.strokeRect(snake[i].x, snake[i].y, boxWH, boxWH);
}
ctx.drawImage(foodImg, food.x, food.y);
var snakeX = snake[0].x;
var snakeY = snake[0].y;
snake.pop();
if(k == "right") snakeX += boxWH;
if(k == "left") snakeX -= boxWH;
if(k == "up") snakeY -= boxWH;
if(k == "down") snakeY += boxWH;
var nHead = {
x: snakeX,
y: snakeY
}
snake.unshift(nHead);
}
the problem is that the sanke gets bigger and bigger as it moves
The snake has the correct size, what happens is that it is leaving a "trail". To avoid that, you need to clear the canvas each Draw call.
Just move the command to fill the canvas from the SnakeGame function to the beginning of Draw, like this:
function SnakeGame(){
var game = setInterval(Draw, 100);
}
function Draw(){
ctx.fillStyle = "green";
ctx.fillRect(0, 0, cWidth, cHeight);
for(var i = 0; i<snake.length; i++){
ctx.fillStyle = (i == 0) ? "red" : "white";
ctx.fillRect(snake[i].x, snake[i].y, boxWH, boxWH);
//(...)
The problem has to do with the fact that you draw the snake onto the canvas without resetting it every time. The new snake tiles are drawn, but the old ones are also still there.
You can fix it by moving these lines to the beginning of the Draw function, so they are executed every time you are about to redraw the snake:
ctx.fillStyle = "green";
ctx.fillRect(0, 0, cWidth, cHeight);

Javascript game, make spaceship shoot on pressdown with interval

I am working on my gaming skills (mainly with arrays) to generate enemies and now bullets to take them down. I was able to set-up bullets while testing, but were visible only when I had a key pressed (space bar let's say) and with no interval in between, so the browser was not able to take that many at one point.
Is there any simple way to make the ship fire bullets with interval in between (not to load the browser that much) and maybe upon going to the enemy[i].x / y location to delete an enemy and the bullet can disappear ?
Here is the cleaned as much as possible code I have for now (HTML and JS file. Have some images as well and will provide URL to the game to check it if needed - http://sarahkerrigan.biz/spaceship
<!DOCTYPE html>
<html>
<head>
<title>Space Ship</title>
</head>
<body>
<h3>Space Ship</h3>
<canvas id="canvas" width="1000" height="600"></canvas>
<script src="spaceship.js"></script>
</body>
</html>
And here is the spaceship.js file:
var cvs = document.getElementById("canvas");
var ctx = cvs.getContext("2d");
//-------------------------------
// load images
var player = new Image();
var enemy = new Image();
var bullet = new Image();
player.src = "images/player.png";
enemy.src = "images/enemy.png";
bullet.src = "images/fire.png";
//-------------------------------
// vars
var score = 0;
var pause = 0;
var playerY = 300;
var playerX = 100;
var upPressed = false;
var downPressed = false;
var leftPressed = false;
var rightPressed = false;
// audio
var fire = new Audio();
var hit = new Audio();
fire.src = "sounds/fire.mp3";
hit.src = "sounds/hit.mp3";
//-------------------------------
// on key down
document.addEventListener("keydown", keyDownHandler);
function keyDownHandler(e) {
if (e.keyCode == 87) {
upPressed = true;
}
if (e.keyCode == 83) {
downPressed = true;
}
if (e.keyCode == 65) {
leftPressed = true;
}
if (e.keyCode == 68) {
rightPressed = true;
}
}
// on key up
document.addEventListener("keyup", keyUpHandler);
function keyUpHandler(e) {
if (e.keyCode == 87) {
upPressed = false;
}
if (e.keyCode == 83) {
downPressed = false;
}
if (e.keyCode == 65) {
leftPressed = false;
}
if (e.keyCode == 68) {
rightPressed = false;
}
}
//-------------------------------
function moveUp() {
if (playerY <= canvas.height - canvas.height){
}
else{
playerY -= 6;
}
}
function moveDown() {
if (playerY >= canvas.height - player.height){
}
else{
playerY += 6;
}
}
function moveLeft() {
if (playerX <= canvas.width - canvas.width){
}
else{
playerX -= 6;
}
}
function moveRight() {
if (playerX >= canvas.width - player.width){
}
else{
playerX += 6;
}
}
//-------------------------------
// Enemy coordinates
var enemies = [];
enemies[0] = {
x: cvs.width,
y: 0
};
//-------------------------------
// reload page
function reLoad() {
location.reload(); // reload the page
}
//-------------------------------
// draw images
function draw() {
ctx.fillStyle = "black";
ctx.fillRect(0, 0, canvas.width, canvas.height);
if (upPressed === true) {
moveUp();
}
if (downPressed === true) {
moveDown();
}
if (leftPressed === true) {
moveLeft();
}
if (rightPressed === true) {
moveRight();
}
//-------------------------------
for (var i = 0; i < enemies.length; i++) {
//draw the enemy
ctx.drawImage(enemy, enemies[i].x, enemies[i].y);
// enemy movement speed
enemies[i].x -= 3;
if (enemies[i].x == 880) {
enemies.push({
x: cvs.width,
y: Math.floor(Math.random() * enemy.height) * 10 - enemy.height
});
}
// detect collision
// if enemy hits player
if (playerX + player.width >= enemies[i].x && playerX <= enemies[i].x + enemy.width && (playerY <= enemies[i].y + enemy.height && playerY + player.height >= enemies[i].y)) {
pause = 1;
}
}
//-------------------------------
//draw the player
ctx.drawImage(player, playerX, playerY);
//draw score
ctx.fillStyle = "#fff";
ctx.font = "20px Verdana";
ctx.fillText("Destroyed ships : " + score + "$", 10, cvs.height - 20);
function onPause() {
if (pause >= 1) {
hit.play();
ctx.fillStyle = "#df8a62";
ctx.fillRect(150, 150, 280, 100);
ctx.fillStyle = "#000";
ctx.font = "20px Verdana";
ctx.fillText("You died:", 165, 170);
document.addEventListener("keydown", reLoad);
} else if (pause <= 0) {
requestAnimationFrame(draw);
}
}
onPause();
}
draw();
You want to use time intervals instead of listeners.
var myVar = setInterval(timeCycle, 50);
function timeCycle() {
//all the stuff you currently have listeners for.
}
This way when the time interval happens it will execute your key presses just once. Then if you want to change your rate of fire you add something like this:
setInterval(timeCycle, 50);
rateOfFire = 5;
shootCoolDown = 0;
function timeCycle() {
if (shootPressed === true) {
if(shootCoolDown === 0){
shootCoolDown = rateOfFire;
shoot();
}
}
if (shootCoolDown > 0){
shootCoolDown --;
}
}
This way it will shoot once every 5 game cycles (or 4-rounds per second in this case).
There are more fancy things you can do to create a delta-time system to offset lag by changing your sim rate based on the time it takes your timeCycle to execute, but that tends to be much more complex and easy to mess up, so I would not suggest going down that rabbit hole for beginners.
[EDIT]
So, I've seen several questions recently about deltaTime, but don't see any good examples of how to implement it; so, here is a basic example I threw together. To implement it, just replace the GAME STUFF part with your actual code of what happens in a game cycle, and run all of your time-based values through the delta() function, and it will convert your values from to units per second to units per currentFrame.
My game us under a load of <input type="text" id="lag" value="100000000"> operations per frame.<br>
My speed is = <input type="text" id="speed" value="500"> px per second<br>
I moved <span id="adjusted"></span>px this frame.<br>
FPS: <span id="fps"></span>
<script>
function wrapDelta(lastTime){
var d = new Date();
var n = d.getSeconds()*1000 + d.getMilliseconds();
if (lastTime >= n) {
lastTime -= 60000;
}
return n - lastTime;
}
function delta(input){
return input * deltaCoeff / 1000;
}
var d = new Date();
var ed = new Date();
var endTime = d.getSeconds()*1000 + d.getMilliseconds();
var startTime = d.getSeconds()*1000 + d.getMilliseconds();
var deltaCoeffMin = 25;
var deltaCoeff = deltaCoeffMin;
setInterval(function () {
d = new Date();
startTime = d.getSeconds()*1000 + d.getMilliseconds();
// START GAME STUFF
var lag = Math.round(Math.sqrt(document.getElementById('lag').value)); //because comparing large numbers caused a wierd lag spike at from 9999999 to 10000000
var speed = document.getElementById('speed').value;
document.getElementById('adjusted').innerHTML = delta(speed);
document.getElementById('fps').innerHTML = (1000/deltaCoeff).toFixed(2);
var i; var j; var k; for (i=0; i<lag; i++){ for (j=0; j<lag; j++){ k = 1234567*1.1;}} //This is just a random math loop to simulate the lag cause by actual game stuff
// END GAME STUFF
ed = new Date();
endTime = ed.getSeconds()*1000 + ed.getMilliseconds();
deltaCoeff = endTime - startTime;
if (deltaCoeff < deltaCoeffMin){deltaCoeff = deltaCoeffMin;}
} , deltaCoeffMin);
</script>
The call to requestAnimationFrame will run the draw function only at a rate supported by the monitor and only if the computer is fast enough. If the code is running slow, it will automatically skip a call to the draw function every now and then. Therefore, the draw function should only contain the rendering code and no logic.
You should first put any code that updates the game's state into another function called update. This function will be called at a consistent-ish rate using setInterval:
function update() {
// read inputs
// move objects
// detect collisions
// etc.
// render a new frame only if the browser is done drawing the previous one
requestAnimationFrame(draw);
}
// run the update function 60 times per second
var updateInterval = setInterval(update, 1000 / 60);
It's always good to store the updateInterval so that we can stop the game from running completely with clearInterval(updateInterval), but you might never need to use it.
Now that you have a somewhat consistent game speed, you can set a cooldown on the shooting like this:
if (fireCooldown > 0) {
fireCooldown -= 1;
}
if (/* holding the fire key */ && fireCooldown === 0) {
// create a projectile in front of the player ship
fireCooldown = 30;
}
You'll need to declare that variable somewhere first with var fireCooldown = 0; somewhere, but it should get you started.
As mentioned by Jake Holzinger in the comments, setInterval isn't 100% accurate and the update function might be called a few milliseconds later than expected. You'd have to check the time between two calls yourself using Date objects or other means if you wanted to time stuff perfectly, but I doubt this is necessary for a simple shooter game.

Tile map collide not working as expected in Javascript

I have been thinking of a way to set-up tile map collision with a player in the same way I have developed the game so far (or similar way if possible, so I do not have to redo everything :) ).
I got some ideas from tutorials and videos and decided to implement it to my code and the player definitely collides with something, though it doesn't look to be the correct tiles that it should be.
For example I want it to walk on over the tiles with Index 1, but to collide with tiles with Index 0 and 3, to stop the player movement.
Here is what I got so far:
<!doctype html>
<html>
<head>
<meta charset="UTF-8">
<title>Canvas Tile Map</title>
<style>
#canvas{
border: 1px solid black;
}
</style>
</head>
<body>
<canvas id="canvas" height="650px" width="1000px"></canvas>
<script>
var canvas = document.getElementById("canvas");
var context = canvas.getContext("2d");
var go = 0;
var canvasBegX = -64;
var canvasEndX = 999;
var canvasBegY = -64;
var canvasEndY = 649;
var heroX = 0;
var heroY = 0;
var heroIndexX = 0;
var heroIndexY = 0;
var heroIndexXnew = 0;
var heroIndexYnew = 0;
//--------------------------------------------------------------
//ADD CHECKER IF KEY IS PRESSED OR RELEASED
window.addEventListener('keydown', function (e) {
canvas.key = e.keyCode;
})
window.addEventListener('keyup', function (e) {
canvas.key = false;
})
//--------------------------------------------------------------
//THE MAP
var mapArray=[
[3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3],
[3,0,0,0,0,1,1,0,0,0,0,0,0,0,1,1,1,1,0,0,0,3],
[3,1,1,1,1,1,1,0,0,0,0,0,0,0,1,1,1,0,0,0,0,3],
[3,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,1,3],
[3,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,3],
[3,1,1,1,0,1,1,0,0,0,0,0,1,1,1,1,1,0,0,0,0,3],
[3,1,1,1,0,1,1,0,0,0,0,0,1,1,1,1,1,0,0,0,0,3],
[3,0,1,1,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,3],
[3,0,1,1,0,1,1,1,1,1,1,1,1,0,0,1,1,1,1,1,1,3],
[3,0,1,1,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,3],
[3,0,1,1,1,1,1,0,0,0,0,0,0,1,1,1,1,0,0,0,0,3],
[3,0,1,1,1,1,1,0,0,0,0,1,1,1,1,1,1,1,1,0,1,3],
[3,0,0,0,0,1,1,0,0,0,0,1,1,0,0,1,1,1,1,0,0,3],
[3,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,3],
[3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3]
];
// x= 22
// y= 15
//-----------------------------------------------------------------------
//------------------------------------------------------------------------------------------------------
//-----------------------------------------------------------------------
// DRAW PLAYER
player_image = new Image();
var player = new Object();
player.y = canvas.height/2-220; //player position y
player.x = canvas.width/2-340; //player position x
player.Width = 60;
player.Height = 60;
function drawPlayer() { // drawing the player
context.beginPath();
context.fillStyle = "red";
context.fillRect(player.x,player.y,player.Width,player.Height);
context.closePath();
}
//-----------------------------------------------------------------------
//------------------------------------------------------------------------------------------------------
//-----------------------------------------------------------------------
// These I need for the map co-ordinates and when it moves the map upon key-press
var updateX=(player.x-210); // Starting point of canvas X
var updateY=(player.y-160); // Starting point of canvas Y
var posX=updateX;
var posY=updateY;
//------------------------------------------------------------------------------------------------------
//-----------------------------------------------------------------------------------------------------
//-----------------------------------------------------------------------------------------------------
//DRAW THE MAP AND THE PLAYER
var grass = new Image();
var stone = new Image();
var black = new Image();
function drawMap() {
var posY = updateY; // new Y coordinates for the map after movement
grass.src= 'https://sarahkerrigan.biz/wpmtest/hosting/images/tile/grass.jpeg';
stone.src = 'https://sarahkerrigan.biz/wpmtest/hosting/images/tile/sand.jpeg';
black.src = 'https://sarahkerrigan.biz/wpmtest/hosting/images/tile/black.png';
//---------------------------------------------------------
// Draw the map loop
grass.onload = function (){
stone.onload = function (){
black.onload = function (){
for(var i=0; i < mapArray.length; i++){
for(var j=0; j < mapArray[i].length; j++){
if(mapArray[i][j]==0){
if (posY > canvasBegY && posY < canvasEndY && posX > canvasBegX && posX < canvasEndX){
context.drawImage(grass,posX, posY, 64, 64); // Load image for grass "0"
}
}
if(mapArray[i][j]==1){
if (posY > canvasBegY && posY < canvasEndY && posX > canvasBegX && posX < canvasEndX){
context.drawImage(stone,posX,posY,64,64); // Load image for stone "1"
}
}
if(mapArray[i][j]==3){
if (posY > canvasBegY && posY < canvasEndY && posX > canvasBegX && posX < canvasEndX){
context.drawImage(black,posX,posY,64,64); // Load image for black "3"
}
}
posX+=64;
}
posY+=64;
posX=updateX; // new X coordinates for the map after movement
//---------------------------------------------------------
drawPlayer(); // Draw the player
}
}
}
}
}
//-----------------------------------------------------------------------------------------------------
//------------------------------------------------------------------------------------------------------
//------------------------------------------------------------------------------------------------------
// PLAYER MOVEMENT BUTTONS
var rightPressed = false;
var leftPressed = false;
var upPressed = false;
var downPressed = false;
var endX=1408;
var endY=960;
document.addEventListener("keydown", keyDownHandler);
function keyDownHandler(e) {
if(e.keyCode == 39) {
rightPressed = true;
}
else if(e.keyCode == 37) {
leftPressed = true;
}
if(e.keyCode == 40) {
downPressed = true;
}
else if(e.keyCode == 38) {
upPressed = true;
}
}
document.addEventListener("keyup", keyUpHandler);
function keyUpHandler(e) {
if(e.keyCode == 39) {
rightPressed = false;
}
else if(e.keyCode == 37) {
leftPressed = false;
}
if(e.keyCode == 40) {
downPressed = false;
}
else if(e.keyCode == 38) {
upPressed = false;
}
}
//----------------------------------------------
//THE ACTUAL MOVEMENT + BOUNDARIES
function playerMovement(){
//------------------------------
//CHECK PLAYER X AND Y IN TILE INDEXES
heroX = Math.abs(updateX - player.x); //current hero X position starting from beginning of tilemap(outside of visible part)
heroY = Math.abs(updateY - player.y); //current hero Y position starting from beginning of tilemap(outside of visible part)
heroIndexX = heroX/64; // X index of hero to chech in which tile is currently located
heroIndexY = heroY/64; // Y index of hero to chech in which tile is currently located
heroIndexXnew = Math.ceil(heroIndexX); //index positioned on the right of the heroes index
heroIndexYnew = Math.ceil(heroIndexY) -2; //index positioned on the left of the heroes index
if(rightPressed) {
if (isPathTile(mapArray, heroIndexXnew, heroIndexYnew)){ // Nothing happens because you hit a tile
}else {
moveRight(); // if you are not at the wall, you go right
}
}
//------------------------------
else if(leftPressed) {
if (isPathTile(mapArray, heroIndexXnew - 2, heroIndexYnew)){ // Nothing happens because you hit a tile
}else {
moveLeft(); // if you are not at the wall, you go left
}
}
//------------------------------
if(downPressed) {
if(player.y>updateY+834){} // Nothing happens because you hit the bottom wall
else {
moveDown(); // if you are not at the wall, you go down
}
}
//------------------------------
else if(upPressed) {
if(player.y<updateY+64){} // Nothing happens because you hit the top wall
else {
moveUp(); // if you are not at the wall, you go up
}
}
}
//-----------------------------------------------------------------------
//------------------------------------------------------------------------------------------------------
//CAMERA BOUNDARIES
function moveRight(){
if(player.x<820){
player.x=player.x+4.1; //If you are at this position, move the player
}
else if(player.x>820){
updateX=updateX-4.1; //If you go over this position, move the background
}
}
function moveLeft(){
if(player.x>100){
player.x=player.x-4.1; //If you are at this position, move the player
}
else if(player.x<100){
updateX=updateX+4.1; //If you go over this position, move the background
}
}
function moveUp(){
if(player.y>80){
player.y=player.y-4.1; //If you are at this position, move the player
}
else if(player.y<80){
updateY=updateY+4.1; //If you go over this position, move the background
}
}
function moveDown(){
if(player.y<500){
player.y=player.y+4.1; //If you are at this position, move the player
}
else if(player.y>500){
updateY=updateY-4.1; //If you go over this position, move the background
}
}
//-----------------------------------------------------------------------
//------------------------------------------------------------------------------------------------------
//-----------------------------------------------------------------------
//------------------------------------------------------------------------------------------------------
//-----------------------------------------------------------------------
//------------------------------------------------------------------------------------------------------
// MOVEMENT BOUNDARIES WITH TILES
function isPathTile(mapArray, x, y) {
return (mapArray[x][y] === 0); // Because 0 is the path tile
}
//-----------------------------------------------------------------------
//------------------------------------------------------------------------------------------------------
//-----------------------------------------------------------------------
//------------------------------------------------------------------------------------------------------
// THE GAME LOOP
function gameLoop(){
console.log("index X =" + heroIndexXnew);
console.log("index Y =" + heroIndexYnew);
playerMovement(); //Check for movements
drawMap(); //Draw the map and the player
requestAnimationFrame(gameLoop);
}
//-----------------------------------------------------------------------
//------------------------------------------------------------------------------------------------------
gameLoop(); // start the gameLoop
</script>
</body>
</html>
And here is a code to test it -
var canvas = document.getElementById("canvas");
var context = canvas.getContext("2d");
var go = 0;
var canvasBegX = -64;
var canvasEndX = 999;
var canvasBegY = -64;
var canvasEndY = 649;
var heroX = 0;
var heroY = 0;
var heroIndexX = 0;
var heroIndexY = 0;
var heroIndexXnew = 0;
var heroIndexYnew = 0;
//--------------------------------------------------------------
//ADD CHECKER IF KEY IS PRESSED OR RELEASED
window.addEventListener('keydown', function (e) {
canvas.key = e.keyCode;
})
window.addEventListener('keyup', function (e) {
canvas.key = false;
})
//--------------------------------------------------------------
//THE MAP
var mapArray=[
[3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3],
[3,0,0,0,0,1,1,0,0,0,0,0,0,0,1,1,1,1,0,0,0,3],
[3,1,1,1,1,1,1,0,0,0,0,0,0,0,1,1,1,0,0,0,0,3],
[3,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,1,3],
[3,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,3],
[3,1,1,1,0,1,1,0,0,0,0,0,1,1,1,1,1,0,0,0,0,3],
[3,1,1,1,0,1,1,0,0,0,0,0,1,1,1,1,1,0,0,0,0,3],
[3,0,1,1,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,3],
[3,0,1,1,0,1,1,1,1,1,1,1,1,0,0,1,1,1,1,1,1,3],
[3,0,1,1,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,3],
[3,0,1,1,1,1,1,0,0,0,0,0,0,1,1,1,1,0,0,0,0,3],
[3,0,1,1,1,1,1,0,0,0,0,1,1,1,1,1,1,1,1,0,1,3],
[3,0,0,0,0,1,1,0,0,0,0,1,1,0,0,1,1,1,1,0,0,3],
[3,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,3],
[3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3]
];
// x= 22
// y= 15
//-----------------------------------------------------------------------
//------------------------------------------------------------------------------------------------------
//-----------------------------------------------------------------------
// DRAW PLAYER
player_image = new Image();
var player = new Object();
player.y = canvas.height/2-220; //player position y
player.x = canvas.width/2-340; //player position x
player.Width = 60;
player.Height = 60;
function drawPlayer() { // drawing the player
context.beginPath();
context.fillStyle = "red";
context.fillRect(player.x,player.y,player.Width,player.Height);
context.closePath();
}
//-----------------------------------------------------------------------
//------------------------------------------------------------------------------------------------------
//-----------------------------------------------------------------------
// These I need for the map co-ordinates and when it moves the map upon key-press
var updateX=(player.x-210); // Starting point of canvas X
var updateY=(player.y-160); // Starting point of canvas Y
var posX=updateX;
var posY=updateY;
//------------------------------------------------------------------------------------------------------
//-----------------------------------------------------------------------------------------------------
//-----------------------------------------------------------------------------------------------------
//DRAW THE MAP AND THE PLAYER
var grass = new Image();
var stone = new Image();
var black = new Image();
function drawMap() {
var posY = updateY; // new Y coordinates for the map after movement
grass.src= 'https://sarahkerrigan.biz/wpmtest/hosting/images/tile/grass.jpeg';
stone.src = 'https://sarahkerrigan.biz/wpmtest/hosting/images/tile/sand.jpeg';
black.src = 'https://sarahkerrigan.biz/wpmtest/hosting/images/tile/black.png';
//---------------------------------------------------------
// Draw the map loop
grass.onload = function (){
stone.onload = function (){
black.onload = function (){
for(var i=0; i < mapArray.length; i++){
for(var j=0; j < mapArray[i].length; j++){
if(mapArray[i][j]==0){
if (posY > canvasBegY && posY < canvasEndY && posX > canvasBegX && posX < canvasEndX){
context.drawImage(grass,posX, posY, 64, 64); // Load image for grass "0"
}
}
if(mapArray[i][j]==1){
if (posY > canvasBegY && posY < canvasEndY && posX > canvasBegX && posX < canvasEndX){
context.drawImage(stone,posX,posY,64,64); // Load image for stone "1"
}
}
if(mapArray[i][j]==3){
if (posY > canvasBegY && posY < canvasEndY && posX > canvasBegX && posX < canvasEndX){
context.drawImage(black,posX,posY,64,64); // Load image for black "3"
}
}
posX+=64;
}
posY+=64;
posX=updateX; // new X coordinates for the map after movement
//---------------------------------------------------------
drawPlayer(); // Draw the player
}
}
}
}
}
//-----------------------------------------------------------------------------------------------------
//------------------------------------------------------------------------------------------------------
//------------------------------------------------------------------------------------------------------
// PLAYER MOVEMENT BUTTONS
var rightPressed = false;
var leftPressed = false;
var upPressed = false;
var downPressed = false;
var endX=1408;
var endY=960;
document.addEventListener("keydown", keyDownHandler);
function keyDownHandler(e) {
if(e.keyCode == 39) {
rightPressed = true;
}
else if(e.keyCode == 37) {
leftPressed = true;
}
if(e.keyCode == 40) {
downPressed = true;
}
else if(e.keyCode == 38) {
upPressed = true;
}
}
document.addEventListener("keyup", keyUpHandler);
function keyUpHandler(e) {
if(e.keyCode == 39) {
rightPressed = false;
}
else if(e.keyCode == 37) {
leftPressed = false;
}
if(e.keyCode == 40) {
downPressed = false;
}
else if(e.keyCode == 38) {
upPressed = false;
}
}
//----------------------------------------------
//THE ACTUAL MOVEMENT + BOUNDARIES
function playerMovement(){
//------------------------------
//CHECK PLAYER X AND Y IN TILE INDEXES
heroX = Math.abs(updateX - player.x); //current hero X position starting from beginning of tilemap(outside of visible part)
heroY = Math.abs(updateY - player.y); //current hero Y position starting from beginning of tilemap(outside of visible part)
heroIndexX = heroX/64; // X index of hero to chech in which tile is currently located
heroIndexY = heroY/64; // Y index of hero to chech in which tile is currently located
heroIndexXnew = Math.ceil(heroIndexX); //index positioned on the right of the heroes index
heroIndexYnew = Math.ceil(heroIndexY) -2; //index positioned on the left of the heroes index
if(rightPressed) {
if (isPathTile(mapArray, heroIndexXnew, heroIndexYnew)){ // Nothing happens because you hit a tile
}else {
moveRight(); // if you are not at the wall, you go right
}
}
//------------------------------
else if(leftPressed) {
if (isPathTile(mapArray, heroIndexXnew - 2, heroIndexYnew)){ // Nothing happens because you hit a tile
}else {
moveLeft(); // if you are not at the wall, you go left
}
}
//------------------------------
if(downPressed) {
if(player.y>updateY+834){} // Nothing happens because you hit the bottom wall
else {
moveDown(); // if you are not at the wall, you go down
}
}
//------------------------------
else if(upPressed) {
if(player.y<updateY+64){} // Nothing happens because you hit the top wall
else {
moveUp(); // if you are not at the wall, you go up
}
}
}
//-----------------------------------------------------------------------
//------------------------------------------------------------------------------------------------------
//CAMERA BOUNDARIES
function moveRight(){
if(player.x<820){
player.x=player.x+4.1; //If you are at this position, move the player
}
else if(player.x>820){
updateX=updateX-4.1; //If you go over this position, move the background
}
}
function moveLeft(){
if(player.x>100){
player.x=player.x-4.1; //If you are at this position, move the player
}
else if(player.x<100){
updateX=updateX+4.1; //If you go over this position, move the background
}
}
function moveUp(){
if(player.y>80){
player.y=player.y-4.1; //If you are at this position, move the player
}
else if(player.y<80){
updateY=updateY+4.1; //If you go over this position, move the background
}
}
function moveDown(){
if(player.y<500){
player.y=player.y+4.1; //If you are at this position, move the player
}
else if(player.y>500){
updateY=updateY-4.1; //If you go over this position, move the background
}
}
//-----------------------------------------------------------------------
//------------------------------------------------------------------------------------------------------
//-----------------------------------------------------------------------
//------------------------------------------------------------------------------------------------------
//-----------------------------------------------------------------------
//------------------------------------------------------------------------------------------------------
// MOVEMENT BOUNDARIES WITH TILES
function isPathTile(mapArray, x, y) {
return (mapArray[x][y] === 0); // Because 0 is the path tile
}
//-----------------------------------------------------------------------
//------------------------------------------------------------------------------------------------------
//-----------------------------------------------------------------------
//------------------------------------------------------------------------------------------------------
// THE GAME LOOP
function gameLoop(){
console.log("index X =" + heroIndexXnew);
console.log("index Y =" + heroIndexYnew);
playerMovement(); //Check for movements
drawMap(); //Draw the map and the player
requestAnimationFrame(gameLoop);
}
//-----------------------------------------------------------------------
//------------------------------------------------------------------------------------------------------
gameLoop(); // start the gameLoop
#canvas{
border: 1px solid black;
}
<canvas id="canvas" height="650px" width="1000px"></canvas>
All the code has some vars, the tilemap array, drawing the tilemap in only the visible part of the canvas , the player of course with it for every time it draws, then we have the movement and where I believe something is not set correctly. There is a function isPathTile to see if the index next to the current player location is 0 and if it is, it does nothing (when right pressed, so the player does not move). I think that this is where I got it wrong. Much appreciated if anyone can take can a look at this.
<!doctype html>
<html>
<head>
<meta charset="utf-8">
<style>
body {
background-color: black;
}
canvas {
position: absolute;
margin: auto;
left: 0;
right: 0;
border: solid 1px white;
}
</style>
</head>
<body>
<canvas id="canvas"></canvas>
<script type="application/javascript">
// IIFE
// https://developer.mozilla.org/en-US/docs/Glossary/IIFE
void function() {
// Enforce strict mode inside the IIFE
// https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Strict_mode
"use strict";
// Var declaration
var canvasWidth = 320;
var canvasHeight = 320;
var canvas = null;
var ctx = null;
var player = {
// Position
x: 35.0,
y: 35.0,
// Velocity
dx: 0.0,
dy: 0.0,
// Size
width: 20,
height: 20,
// Input
up: false,
down: false,
left: false,
right: false
};
// Defined this way the map will need to be indexed as
// map[y][x]
// 0 = not solid
// 1 = solid
var mapTileSize = 32; // size for each tile in pixels
var map = [
[1,1,1,1,1,1,1,1,1,1],
[1,0,1,0,0,0,0,0,1,1],
[1,0,0,1,1,1,0,1,0,1],
[1,0,0,0,0,0,0,0,0,1],
[1,0,0,0,0,0,0,0,0,1],
[1,0,0,0,0,0,0,0,0,1],
[1,0,1,1,1,1,0,1,0,1],
[1,0,0,0,0,0,0,1,0,1],
[1,0,0,0,0,0,0,0,0,1],
[1,1,1,1,1,1,1,1,1,1]
];
// Runs after the page has finished loading
window.onload = function() {
canvas = document.getElementById("canvas");
canvas.width = canvasWidth;
canvas.height = canvasHeight;
ctx = canvas.getContext("2d");
loop();
}
// Key Input
window.onkeydown = function(e) {
switch(e.key) {
case "w": player.up = true; break;
case "s": player.down = true; break;
case "a": player.left = true; break;
case "d": player.right = true; break;
}
}
window.onkeyup = function(e) {
switch(e.key) {
case "w": player.up = false; break;
case "s": player.down = false; break;
case "a": player.left = false; break;
case "d": player.right = false; break;
}
}
function loop() {
// Tick
// Player movement
if (player.up) {
player.dy = -2;
}
if (player.down) {
player.dy = +2;
}
if (!player.up && !player.down) {
player.dy = 0;
}
if (player.left) {
player.dx = -2;
}
if (player.right) {
player.dx = +2;
}
if (!player.left && !player.right) {
player.dx = 0;
}
// Collision detection & resolution
// Only perform collision detection in either axis
// if the player is actually moving on that axis
// Map grid coordinates at the corners of the player's bounding box
/*
-> *-----* <-
| |
| |
| |
-> *-----* <-
*/
var invMapTileSize = 1.0 / mapTileSize;
var nextX = player.x + player.dx;
var nextY = player.y + player.dy;
// Current position
var currentMinX = (player.x * invMapTileSize) | 0;
var currentMaxX = ((player.x + player.width) * invMapTileSize) | 0;
var currentMinY = (player.y * invMapTileSize) | 0;
var currentMaxY = ((player.y + player.height) * invMapTileSize) | 0;
// Next position
var nextMinX = (nextX * invMapTileSize) | 0;
var nextMaxX = ((nextX + player.width) * invMapTileSize) | 0;
var nextMinY = (nextY * invMapTileSize) | 0;
var nextMaxY = ((nextY + player.height) * invMapTileSize) | 0;
/*
Collision checks are performed down along each axis of the player's
collision box, this way it won't matter if the player is larger
or smaller then the map tiles.
*/
// X axis collision
if (player.dx !== 0.0) {
for (var x = nextMinX; x <= nextMaxX; ++x) {
for (var y = currentMinY; y <= currentMaxY; ++y) {
if (map[y][x]) {
player.dx = 0.0;
break;
}
}
}
}
// Y axis collision
if (player.dy !== 0.0) {
for (var y = nextMinY; y <= nextMaxY; ++y) {
for (var x = currentMinX; x <= currentMaxX; ++x) {
if (map[y][x]) {
player.dy = 0.0;
break;
}
}
}
}
// Update player position
player.x = player.x + player.dx;
player.y = player.y + player.dy;
// render
ctx.fillStyle = "gray";
ctx.fillRect(0,0,canvasWidth,canvasHeight);
// draw map
ctx.fillStyle = "darkred";
ctx.beginPath();
for (var y = 0; y < map.length; ++y) {
for (var x = 0; x < map[0].length; ++x) {
if (map[y][x]) {
ctx.rect(
x * mapTileSize,
y * mapTileSize,
mapTileSize,
mapTileSize
);
}
}
}
ctx.fill();
// draw player
ctx.fillStyle = "darkblue";
ctx.fillRect(
player.x,
player.y,
player.width,
player.height
);
//
requestAnimationFrame(loop);
}
}();
</script>
</body>
</html>
After about a week was giving up on this one :D and finally figured it out. I was switching the places of my X and Y indexes and that is why it was not acting as it should be. Showing up the fix here if anyone is interested (only the Player movement has to be updated):
function playerMovement(){
//------------------------------
//CHECK PLAYER X AND Y IN TILE INDEXES
heroX = -updateX + player.x;
heroY = -updateY + player.y;
heroIndexX = heroX/64; // get the X index
heroIndexY = heroY/64; // get the Y index
heroIndexXnew = Math.ceil(heroIndexX);
heroIndexYnew = Math.ceil(heroIndexY);
if(rightPressed) {
player_image.src = './images/horseright1.png';
if(player.x>updateX+1258){ // Nothing happens because you hit the right wall
}else if (isPathTile(mapArray, heroIndexYnew, heroIndexXnew)){ // Nothing happens because you hit a tile
}else {
moveRight(); // if you are not at the wall, you go right
}
}
//------------------------------
else if(leftPressed) {
player_image.src = './images/horseleft1.png';
if(player.x<updateX+128){ // Nothing happens because you hit the left wall
}else if (isPathTile(mapArray, heroIndexYnew, heroIndexXnew - 1)){ // Nothing happens because you hit a tile
}else {
moveLeft(); // if you are not at the wall, you go left
}
}
//------------------------------
if(downPressed) {
if(player.y>updateY+834){ // Nothing happens because you hit the bottom wall
}else if (isPathTile(mapArray, heroIndexYnew, heroIndexXnew)){ // Nothing happens because you hit a tile
}else {
moveDown(); // if you are not at the wall, you go down
}
}
//------------------------------
else if(upPressed) {
if(player.y<updateY+64){ // Nothing happens because you hit the top wall
}else if (isPathTile(mapArray, heroIndexYnew - 1, heroIndexXnew)){ // Nothing happens because you hit a tile
}else {
moveUp(); // if you are not at the wall, you go up
}
}
}
A simple mistake and took me one hell of a time for debugging, though the logic is good and simple. Needs a bit of a touch on how it collides exactly as there are few things to be updated, but overall it works great!

Not working condition for killing snake plus not working property of an object

I am making snake game through javascript and I have come to 2 problems.
First problem: I set condition for "killing" snake when his X and Y hits the border of canvas and I can not get why it is not working.
Second problem: My method "draw" of "snake" is working fine how it is written but if I put instead of "var i = snake.dlzka" "var i = snake.snake_body.length" it types an error: Cannot read property 'x' of undefined.
var canvas = document.getElementById("canvas");
canvas.width = 800;
canvas.height = 650;
var ctx = canvas.getContext("2d");
var dotW = 10;
var dotH = 10;
var direction = "right"; //smer pohybu hadika
var snake = {
dlzka: 5,
snake_body: [],
arraySpawn: function(){
for(var i = snake.dlzka; i >= 0; i--){
this.snake_body.push({
x: i*dotW,
y: 0
});
}
},
draw: function(){
ctx.clearRect(0,0, canvas.width, canvas.height);
for(var i = snake.dlzka; i>0; i--){
//alert(snake.snake_body.length);
ctx.fillStyle = "blue";
ctx.fillRect(snake.snake_body[i].x, snake.snake_body[i].y, dotW, dotH);
}
snake.move();
},
move: function(){
var first = snake.snake_body[0];
var first_x = first.x;
var first_y = first.y;
switch(direction){
case "right":
first_x += 10;
break;
case "left":
first_x -= 10;
break;
case "up":
first_y -= 10;
break;
case "down":
first_y += 10;
break;
}
this.snake_body.pop();
this.snake_body.unshift({
x: first_x,
y: first_y
});
if((first_x == canvas.width || 0) || (first_y == canvas.height || 0)){
var restart = confirm("Do you want to play again?");
if(restart){
clearInterval(intervalID);
snake.snake_body = [];
snake.arraySpawn();
intervalID = setInterval(function(){snake.draw()}, 33);
}
}
},
update_direction: function(e){
var key = e.keyCode;
if(key == 37 && direction !== "right"){
direction = "left";
}else if(key == 38 && direction !== "down"){
direction = "up";
}else if(key == 39 && direction !== "left"){
direction = "right";
}else if(key == 40 && direction !== "up"){
direction = "down";
}
}
};
snake.arraySpawn();
var intervalID = setInterval(function(){snake.draw()}, 33);
window.onkeydown = snake.update_direction;
canvas{
border: 1px solid black;
}
<canvas id="canvas"></canvas>
fiddle: http://jsfiddle.net/scarface/pdz4k8dj/20/
The first problem arises from the code snippet (first_x == canvas.width || 0) Based on operator precedence rules and left to right evaluation, this evaluates to
((first_x == canvas.width) || 0)
which is not what you wanted. Try
(first_x == canvas.width || first_x == 0)
instead but please try and read the rules to make you sure you understand why. Note the test requires the canvas to be an exact multiple of the x (or y) amount the snake is moved by, and it arguably could be better written as
(first_x >= canvas.width || first_x <= 0)
Don't forget to change the y value test because it has exactly the same problem.
The second issue is due to not taking into account that array indices are zero based. So
for(var i = snake.snake_body.length; i>0; i--)
iterates from past the end of the array (generating the error) back to the second element. Changing this to
for(var i = snake.snake_body.length - 1; i >= 0; i--)
worked in the fiddle.

Using EaselJS sprite sheet in existing code

I want to modify existing code which uses an image to animate, and use a sprite sheet instead. I'm using the EaselJS library for this.
The piece of code that creates the objects for animation:
function initStageObjects(){
car = new Car('img/car.png',canvas.width()/2,canvas.height()/2);
}
And this is the complete code:
$(window).load(function(){
$(document).ready(function(){
// Canvas Variables
var canvas = $('#canvas');
var context = canvas.get(0).getContext('2d');
var canvasWidth = canvas.width();
var canvasHeight = canvas.height();
// Keyboard Variables
var leftKey = 37;
var upKey = 38;
var rightKey = 39;
var downKey = 40;
// Keyboard event listeners
$(window).keydown(function(e){
var keyCode = e.keyCode;
if(keyCode == leftKey){
car.left = true;
} else if(keyCode == upKey){
car.forward = true;
} else if(keyCode == rightKey){
car.right = true;
} else if (keyCode == downKey){
car.backward = true;
}
});
$(window).keyup(function(e){
var keyCode = e.keyCode;
if(keyCode == leftKey){
car.left = false;
} else if(keyCode == upKey){
car.forward = false;
} else if(keyCode == rightKey){
car.right = false;
} else if (keyCode == downKey){
car.backward = false;
}
});
// Start & Stop button controlls
var playAnimation = true;
var startButton = $('#startAnimation');
var stopButton = $('#stopAnimation');
startButton.hide();
startButton.click(function(){
$(this).hide();
stopButton.show();
playAnimation = true;
updateStage();
});
stopButton.click(function(){
$(this).hide();
startButton.show();
playAnimation = false;
});
// Resize canvas to full screen
function resizeCanvas(){
canvas.attr('width', $(window).get(0).innerWidth);
canvas.attr('height', $(window).get(0).innerHeight);
canvasWidth = canvas.width();
canvasHeight = canvas.height();
}
resizeCanvas();
$(window).resize(resizeCanvas);
function initialise(){
initStageObjects();
drawStageObjects();
updateStage();
}
// Car object and properties
function Car(src, x, y){
this.image = new Image();
this.image.src = src;
this.x = x;
this.y = y;
this.vx = 0;
this.vy = 0;
this.angle = 90;
this.topSpeed = 5;
this.acceleration = 0.1;
this.reverse = 0.1;
this.brakes = 0.3;
this.friction = 0.05;
this.handeling = 15;
this.grip = 15;
this.minGrip = 5;
this.speed = 0;
this.drift = 0;
this.left = false;
this.up = false;
this.right = false;
this.down = false;
}
// Create any objects needed for animation
function initStageObjects(){
car = new Car('img/car.png',canvas.width()/2,canvas.height()/2);
}
function drawStageObjects(){
context.save();
context.translate(car.x,car.y);
context.rotate((car.angle + car.drift) * Math.PI/180);
context.drawImage(car.image, -25 , (-47 + (Math.abs(car.drift / 3))));
// context.fillRect(-5, -5, 10, 10);
context.restore();
}
function clearCanvas(){
context.clearRect(0, 0, canvasWidth, canvasHeight);
context.beginPath();
}
function updateStageObjects(){
// Faster the car is going, the worse it handels
if(car.handeling > car.minGrip){
car.handeling = car.grip - car.speed;
}
else{
car.handeling = car.minGrip + 1;
}
// Car acceleration to top speed
if(car.forward){
if(car.speed < car.topSpeed){
car.speed = car.speed + car.acceleration;
}
}
else if(car.backward){
if(car.speed < 1){
car.speed = car.speed - car.reverse;
}
else if(car.speed > 1){
car.speed = car.speed - car.brakes;
}
}
// Car drifting logic
if(car.forward && car.left){
if(car.drift > -35){
car.drift = car.drift - 3;
}
}
else if(car.forward && car.right){
if(car.drift < 35){
car.drift = car.drift + 3;
}
}
else if(car.forward && !car.left && car.drift > -40 && car.drift < -3){
car.drift = car.drift + 3;
}
else if(car.forward && !car.right && car.drift < 40 && car.drift > 3){
car.drift = car.drift - 3;
}
if(car.drift > 3){
if(!car.forward && !car.left){
car.drift = car.drift - 4;
}
}
else if(car.drift > -40 && car.drift < -3){
if(!car.forward && !car.right){
car.drift = car.drift + 4;
}
}
// General car handeling when turning
if(car.left){
car.angle = car.angle - (car.handeling * car.speed/car.topSpeed);
} else if(car.right){
car.angle = car.angle + (car.handeling * car.speed/car.topSpeed);
}
// Use this div to display any info I need to see visually
$('#stats').html("Score: 0");
// Constant application of friction / air resistance
if(car.speed > 0){
car.speed = car.speed - car.friction;
} else if(car.speed < 0) {
car.speed = car.speed + car.friction;
}
// Update car velocity (speed + direction)
car.vy = -Math.cos(car.angle * Math.PI / 180) * car.speed;
car.vx = Math.sin(car.angle * Math.PI / 180) * car.speed;
// Plot the new velocity into x and y cords
car.y = car.y + car.vy;
car.x = car.x + car.vx;
}
// Main animation loop
function updateStage(){
clearCanvas();
updateStageObjects();
drawStageObjects();
if(playAnimation){
setTimeout(updateStage, 25);
}
}
// Initialise the animation loop
initialise();
});
});//]]>
// JavaScript Document
How could i replace the image being used by the sprite i created?
Even though you maybe could implement a createjs.SpriteSheet into a non-Createjs/non-EaselJS project I would strongly recommend you not to do that, EaselJS-classes where not designed to be used as single modular classes in any kind of project, they best work together in the framework. In the end you probably will need more time and probably end up with more code by trying get everything to work than with just converting your (yet still small) project to EaselJS all together. So learn something new today and refacture your project to EaselJS ;-)
but if you want more work, continue reading:
A createjs.SpriteSheet basically only handles SpriteSheet data and you can use mySpriteSheet.getFrame(int); to get the image and the source-rect to that frame so you can draw it to your canvas. But a SpriteSheet alone won't handle animations for you, so you would have to advance the "playhead" every frame yourself(go back to frame 0 if at the end ect...), or you can implement another createjs-class called createjs.BitmapAnimation - however, drawing this to your canvas would again require additional code or yet an additional createjs-class: you see where this is getting.

Categories

Resources