I was wondering how I could write in my html/js code a simple leaderboard with the score at the end of the game. I have a level, score and a clickcount score that I want to register.
I don't have any knowledge with databases and server and such, so I really want to keep it 'simple' because I also want to understand what I am typing.
window.addEventListener("load", function() {
//constants
var GAME_WIDTH = 640;
var GAME_HEIGHT = 360;
//keep the game going
var gameLive = true;
//current level
var level = 1;
//Count per click
var clickCount = 0;
//Score
var score = 0;
//enemies
var enemies = [{
x: 100, //x coordinate
y: 100, //y coordinate
speedY: 2, //speed in Y
w: 40, //width
h: 40 //heght
},
{
x: 200,
y: 0,
speedY: 2,
w: 40,
h: 40
},
{
x: 330,
y: 100,
speedY: 3,
w: 40,
h: 40
},
{
x: 450,
y: 100,
speedY: -3,
w: 40,
h: 40
}
];
//the player object
var player = {
x: 10,
y: 160,
speedX: 2.5,
isMoving: false, //keep track whether the player is moving or not
w: 40,
h: 40
};
//the goal object
var goal = {
x: 580,
y: 160,
w: 50,
h: 36
}
// var zonder waarde
var img = {};
var movePlayer = function() {
clickCount += 1;
player.isMoving = true;
document.getElementById('clickCount').innerHTML = clickCount;
}
var stopPlayer = function() {
player.isMoving = false;
}
//grab the canvas and context
var canvas = document.getElementById("mycanvas");
var ctx = canvas.getContext("2d");
//event listeners to move player
canvas.addEventListener('mousedown', movePlayer);
canvas.addEventListener('mouseup', stopPlayer);
canvas.addEventListener('touchstart', movePlayer);
canvas.addEventListener('touchend', stopPlayer);
//img load
var load = function() {
img.player = new Image();
img.player.src = 'images/ping.png';
img.background = new Image();
img.background.src = 'images/sea.png';
img.enemy = new Image();
img.enemy.src = 'images/enemy.png';
img.goal = new Image();
img.goal.src = 'images/fish.png';
};
//update the logic
var update = function() {
//check if you've won the game
if (checkCollision(player, goal)) {
// level +1
level++;
// level in console
console.log(level);
// get player back in position
player.x = 10;
player.y = 160;
//increase the speed of the enemies by 1
//increase the speed of the enemies by 1
enemies.forEach(function(enemies) {
if (enemies.speedY > 0) {
enemies.speedY++;
} else {
enemies.speedY--;
}
});
}
//update player
if (player.isMoving) {
player.x = player.x + player.speedX;
score += 1;
}
enemies.forEach(function(element, index) {
//check for collision with player
if (checkCollision(player, element)) {
//stop the game
gameLive = false;
// alert for the level/ points/game over/ and click count
alert('Game Over!' + "\n" + "\n" + "Level: " + level + "\n" + "Score: " + score + '\n' + "Click count:" + " " + clickCount);
//reload page
window.location = "";
};
//move enemy
element.y += element.speedY;
//check borders
if (element.y <= 10) {
element.y = 10;
//element.speedY = element.speedY * -1;
element.speedY *= -1;
} else if (element.y >= GAME_HEIGHT - 50) {
element.y = GAME_HEIGHT - 50;
element.speedY *= -1;
}
});
};
//show the game on the screen
var draw = function() {
//clear the canvas
ctx.clearRect(0, 0, GAME_WIDTH, GAME_HEIGHT);
//draw background
ctx.drawImage(img.background, 0, 0);
//draw player
ctx.drawImage(img.player, player.x, player.y);
//draw enemies
enemies.forEach(function(element, index) {
ctx.drawImage(img.enemy, element.x, element.y);
});
//draw goal
ctx.drawImage(img.goal, goal.x, goal.y);
//for seeing the level in canvas
//color points
ctx.fillStyle = "#339900";
//font points
ctx.font = "60px Michroma";
//level shower
ctx.fillText(level, 10, 55);
//point shower
ctx.font = "15px Michroma";
ctx.fillText(score, 585, 30);
};
//gets executed multiple times per second
var step = function() {
update();
draw();
if (gameLive) {
window.requestAnimationFrame(step);
}
};
//check the collision between two rectangles
var checkCollision = function(rect1, rect2) {
var closeOnWidth = Math.abs(rect1.x - rect2.x) <= Math.max(rect1.w, rect2.w);
var closeOnHeight = Math.abs(rect1.y - rect2.y) <= Math.max(rect1.h, rect2.h);
return closeOnWidth && closeOnHeight;
}
//initial kick
load();
step();
});
<div id="centerCanvas">
<canvas id="mycanvas" width="640" height="360"></canvas>
</div>
<div id="clickCount"><span>0</span></div>
A fast database setup that integrates with your script can be Google's Firebase database.
Add Firebase to your Javascript Project
Installation & Setup of Database in Javascript
How to Structure Your Databse
After running through the Firebase web portal to set up your account and project, as an example, you can use the following in your JS file to write a record to the database:
var config = {
apiKey: "yourApiKey",
authDomain: "yourProjectId.firebaseapp.com",
databaseURL: "https://yourDatabaseName.firebaseio.com"
};
firebase.initializeApp(config);
// Get a reference to the database service
var database = firebase.database();
function writeUserData(userName, clickCount, score) {
firebase.database().ref('highscores/' + name).set({
userName: userName,
clickCount: clickCount,
score: score
});
}
Related
I'm coding an infinite runner game in javascript using the html5 canvas, and it's been going pretty well so far, but I have been getting the jump mechanism in place, and sometimes the player will phase through the platform they land on, which they shouldn't do, as i have code in place to prevent that. By the way, while the player will not be able to phase through the sides of the platforms in the finished game, I have no code in place to prevent it yet. This only happens on the platform one object. Any idea why it is doing this? My code is here-
const canvas = document.getElementById('gameframe')
const ctx = canvas.getContext('2d')
var player = {
y: 250,
x: 250,
w: 30,
h: 30
}
var plat1 = {
x: 250,
y: 350,
w: 250,
h: 300
}
var plat2 = {
x: 50,
y: 400,
w: 250,
h: 300
}
var plat3 = {
x: -200,
y: 375,
w: 250,
h: 300
}
var currentPlat = {
x: 1,
y: 1,
w: 1,
h: 1
}
function renderPlatforms() {
ctx.fillStyle = 'black';
ctx.rect(plat1.x, plat1.y, plat1.w, plat1.h);
ctx.rect(plat2.x, plat2.y, plat2.w, plat2.h);
ctx.rect(plat3.x, plat3.y, plat3.w, plat3.h);
ctx.fill();
plat1.x--;
plat2.x--;
plat3.x--;
if (plat1.x === 0 - plat1.w) {
plat1.x = 500;
}
if (plat2.x === 0 - plat2.w) {
plat2.x = 500;
}
if (plat3.x === 0 - plat3.w) {
plat3.x = 500;
}
}
function renderPlayer() {
ctx.rect(player.x, player.y, player.w, player.h)
ctx.fill();
}
function draw() {
getCurrentPlat();
doGravity();
ctx.beginPath();
ctx.clearRect(0, 0, canvas.width, canvas.height);
renderPlayer();
renderPlatforms();
ctx.fill();
setTimeout(draw, 3)
}
draw();
function getCurrentPlat() {
if (player.x + player.w >= plat1.x && player.x <= plat1.x + plat1.w) {
currentPlat.x = plat1.x;
currentPlat.y = plat1.y;
currentPlat.w = plat1.w;
currentPlat.h = plat1.h;
console.log('on platform one')
console.log()
}
if (player.x + player.w >= plat2.x && player.x <= plat2.x + plat2.w) {
currentPlat.x = plat2.x;
currentPlat.y = plat2.y;
currentPlat.w = plat2.w;
currentPlat.h = plat2.h;
}
if (player.x + player.w >= plat3.x && player.x <= plat3.x + plat3.w) {
currentPlat.x = plat3.x;
currentPlat.y = plat3.y;
currentPlat.w = plat3.w;
currentPlat.h = plat3.h;
}
}
function doGravity() {
if (player.y + 30 < currentPlat.y && jumping === false) {
player.y++;
}
}
var cntr = 0
var jumping = false
function jump() {
jumping = true;
if (cntr < 90) {
cntr++;
player.y--;
setTimeout(jump, 2);
} else {
function fls() {
jumping = false;
}
cntr = 0;
setTimeout(fls, 50)
}
}
<!DOCTYPE html>
<html>
<canvas width='500' height='500' id='gameframe' style='border-style: solid;'>Sorry, canvas is not supported for your browser. </canvas>
<button onclick='jump()'>jump</button>
<script src='script.js'></script>
</html>
Not sure if it was intentional but your platforms do overlap...
see it in the sample below
I did improve your code to use an array for the platforms instead of individual items, then we can loop platforms.forEach that should help you reduce the duplicate code, and adding many more platforms in the future will be very easy.
const canvas = document.getElementById('gameframe')
const ctx = canvas.getContext('2d')
var platforms = [
{x: 250, y: 50, w: 250,h: 301},
{x: 50, y: 100, w: 250,h: 302},
{x: -200, y: 75, w: 250,h: 303}
]
function renderPlatforms() {
platforms.forEach(function(p) {
ctx.beginPath();
ctx.rect(p.x, p.y, p.w, p.h);
ctx.fillText(p.x, p.x +5, p.y-5);
ctx.fillText(p.w + " / " +p.h, p.x +5, p.y+20);
ctx.stroke();
if (p.x-- === 0 - p.w) p.x = canvas.width;
})
}
function draw() {
ctx.clearRect(0, 0, canvas.width, canvas.height);
renderPlatforms();
setTimeout(draw, 10)
}
draw();
<canvas width='500' height='150' id='gameframe' style='border-style: solid;'></canvas>
If you are going to overlap the platforms like that you have to change your logic and check if the player collides with any of the platforms your approach to only check against one (a current platform) is creating problems.
When troubleshooting games I find ctx.fillText() more helpful than the console.log() you can show on screen the values of the objects also quite often slowing down the game helps you see if the values really change when you expect them too change.
I created a little game with JavaScript while i am learning it.
I would like to get a count clicker in it. So you can see how many times you have clicked on the canvas before you die. (so it resets right after the 'game over'.
Here is the JS code i have at the moment:
window.addEventListener("load", function () {
//constants
var GAME_WIDTH = 640;
var GAME_HEIGHT = 360;
//keep the game going
var gameLive = true;
//current level
var level = 1;
//enemies
var enemies = [{
x: 100, //x coordinate
y: 100, //y coordinate
speedY: 2, //speed in Y
w: 40, //width
h: 40 //heght
},
{
x: 200,
y: 0,
speedY: 2,
w: 40,
h: 40
},
{
x: 330,
y: 100,
speedY: 3,
w: 40,
h: 40
},
{
x: 450,
y: 100,
speedY: -3,
w: 40,
h: 40
}
];
//the player object
var player = {
x: 10,
y: 160,
speedX: 2.5,
isMoving: false, //keep track whether the player is moving or not
w: 40,
h: 40
};
//the goal object
var goal = {
x: 580,
y: 160,
w: 50,
h: 36
}
// var zonder waarde
var img = {};
var movePlayer = function () {
player.isMoving = true;
}
var stopPlayer = function () {
player.isMoving = false;
}
//grab the canvas and context
var canvas = document.getElementById("mycanvas");
var ctx = canvas.getContext("2d");
//event listeners to move player
canvas.addEventListener('mousedown', movePlayer);
canvas.addEventListener('mouseup', stopPlayer);
canvas.addEventListener('touchstart', movePlayer);
canvas.addEventListener('touchend', stopPlayer);
var load = function () {
img.player = new Image();
img.player.src = 'images/ping.png';
img.background = new Image();
img.background.src = 'images/sea.png';
img.enemy = new Image();
img.enemy.src = 'images/enemy.png';
img.goal = new Image();
img.goal.src = 'images/fish.png';
};
//update the logic
var update = function () {
//check if you've won the game
if (checkCollision(player, goal)) {
// leven +1
level++;
// level in console
console.log(level);
// get player back in position
player.x = 10;
player.y = 160;
//increase the speed of the enemies by 1
//increase the speed of the enemies by 1
enemies.forEach(function (enemies) {
if (enemies.speedY > 0) {
enemies.speedY++;
} else {
enemies.speedY--;
}
});
}
//update player
if (player.isMoving) {
player.x = player.x + player.speedX;
}
enemies.forEach(function (element, index) {
//check for collision with player
if (checkCollision(player, element)) {
//stop the game
gameLive = false;
alert('Game Over!');
//reload page
window.location = "";
};
//move enemy
element.y += element.speedY;
//check borders
if (element.y <= 10) {
element.y = 10;
//element.speedY = element.speedY * -1;
element.speedY *= -1;
} else if (element.y >= GAME_HEIGHT - 50) {
element.y = GAME_HEIGHT - 50;
element.speedY *= -1;
}
});
};
//show the game on the screen
var draw = function () {
//clear the canvas
ctx.clearRect(0, 0, GAME_WIDTH, GAME_HEIGHT);
//draw background
ctx.drawImage(img.background, 0, 0);
//draw player
ctx.drawImage(img.player, player.x, player.y);
//draw enemies
enemies.forEach(function (element, index) {
ctx.drawImage(img.enemy, element.x, element.y);
});
//draw goal
ctx.drawImage(img.goal, goal.x, goal.y);
//for seeing the level in canvas
//color points
ctx.fillStyle = "#339900";
//font points
ctx.font = "60px Michroma";
//point shower
ctx.fillText(level, 10, 55);
};
//gets executed multiple times per second
var step = function () {
update();
draw();
if (gameLive) {
window.requestAnimationFrame(step);
}
};
//check the collision between two rectangles
var checkCollision = function (rect1, rect2) {
var closeOnWidth = Math.abs(rect1.x - rect2.x) <= Math.max(rect1.w, rect2.w);
var closeOnHeight = Math.abs(rect1.y - rect2.y) <= Math.max(rect1.h, rect2.h);
return closeOnWidth && closeOnHeight;
}
//initial kick
load();
step();
});
I tried some things out of hand but i couldn't figure it out. Thanks a lot for your help! :)
Kind regards
Add a new variable to increment then within the movePlayer function increment this value. When the game is over you can reset the variable to 0.
For example, below the current level variable add var clickCount = 0;
Then within the movePlayer function add clickCount += 1;
As you are currently reloading the page once the game ends the variable will be reset.
This variable could be output in a simple DIV on the page and does not have to be part of the canvas.
It would be best if you had a working example with the images too. You could do this on https://codesandbox.io/ or https://codepen.io/
UPDATE
Add a DOM element <div id="clickCount">0</div> onto your page. Then replace the movePlayer with the below.
var movePlayer = function () {
clickCount += 1;
player.isMoving = true;
document.getElementById('clickCount').innerHTML = clickCount;
}
This will then update the DIV with the new count, you can then use CSS to position and style the DIV as you want.
I'm trying to use Javascript to create a Canvas Game which is similar to Bug Smasher or Ant Smasher game. It means the obj will move randomly, and when u click on it, the score will increase. ( I'm not allowed to use JQuery )
I almost finished all the work. But there's an error I cannot figure out: Everytime I click on the object, the score increases but it overwrites the number "0" like this:
And this is my code:
// Create the canvas
var canvas = document.createElement("canvas");
var ctx = canvas.getContext('2d');
var timer = 0;
var caught = false;
var fps = 10;
document.body.appendChild(canvas);
canvas.width = 800;
canvas.height = 544;
// Background image
var bgReady = false;
var bgImage = new Image();
bgImage.onload = function () {
bgReady = true;
};
bgImage.src = "images/background.png";
// nar image
var narReady = false;
var narImage = new Image();
narImage.onload = function () {
narReady = true;
};
narImage.src = "images/nar.png";
var nar = {};
var narCaught = 0;
// When nar is caught, reset
var reset = function () {
nar.x = 40 + (Math.random() * (canvas.width - 70));
do {
nar.y = 40 + (Math.random() * (canvas.height - 70));
}
while (nar.y < 100)
};
//mousedown event
window.addEventListener("mousedown", onMouseDown, false);
function onMouseDown(e) {
if (e.button != 0) return;
mouseXinCanvas = e.clientX;
mouseYinCanvas = e.clientY;
if (narBody(nar, mouseXinCanvas, mouseYinCanvas)) {
caught = true;
clearInterval(timer);
timer = setInterval(reset, 20000 / fps);
reset();
}
if (ResetScore(mouseXinCanvas, mouseYinCanvas)) {
location.reload();
}
if (ResetSpeed(mouseXinCanvas, mouseYinCanvas)) {
clearInterval(timer);
timer = setInterval(reset, 20000 / fps);
reset();
render();
}
};
//nar's body define
function narBody(nar, x, y) {
if (x <= (nar.x + 80)
&& nar.x <= (x + 80)
&& y <= (nar.y + 80)
&& nar.y <= (y + 80)
) {
fps = fps + 5;
narCaught++;
return true;
}
return false;
};
//Reset Score box
function ResetScore(x, y) {
if (x > (305)
&& x < (545)
&& y > (15)
&& y < (85)
) {
return true;
}
return false;
};
//Reset speed box
function ResetSpeed(x, y) {
if (x > (605)
&& x < (845)
&& y > (15)
&& y < (85)
) {
fps = 10;
return true;
}
return false;
};
// Draw everything
var render = function () {
if (bgReady) {
ctx.drawImage(bgImage, 0, 100);
}
if (narReady) {
ctx.drawImage(narImage, nar.x, nar.y);
}
if (caught == true) {
if (bgReady) {
ctx.drawImage(bgImage, 0, 100);
}
caught = false;
}
// Score, Title
ctx.fillStyle = "rgb(65, 226, 24)";
ctx.font = "34px Helvetica";
ctx.textAlign = "left";
ctx.textBaseline = "top";
ctx.fillText("Catch Naruto!!!", 5, 40);
ctx.font = "20px Helvetica";
ctx.fillText("Score: " + narCaught, 10, 10);
// Reset Score, Speed button
ctx.fillStyle = "rgb(30, 168, 99)";
ctx.fillRect(250, 10, 250, 80);
ctx.fillRect(520, 10, 250, 80);
ctx.fillStyle = "rgb(30, 168, 99)";
ctx.fillRect(255, 15, 240, 70);
ctx.fillRect(525, 15, 240, 70);
ctx.fillStyle = "rgb(255, 255, 255)";
ctx.font = "34px Arial";
ctx.fillText("Reset Score", 275, 30);
ctx.fillText("Reset Speed", 545, 30);
};
// The main game loop
var main = function () {
render();
// Request to do this again ASAP
requestAnimationFrame(main);
};
// Cross-browser support for requestAnimationFrame
var w = window;
requestAnimationFrame = w.requestAnimationFrame || w.webkitRequestAnimationFrame || w.msRequestAnimationFrame || w.mozRequestAnimationFrame;
// Let's play this game!
//var then = Date.now();
reset();
main();
<html lang="en">
<head>
<meta charset="utf-8">
<title>Assignment 5</title>
</head>
<body>
<script src="game.js"></script>
</body>
</html>
Please help ! :(
The problem is simple to solve. You just need to clear all the previous frame's rendering before you render the new frame.
Just add the following line to the render function
ctx.clearRect(0,0,ctx.canvas.width,ctx.canvas.height);
You will notice that the quality of the text also improves. This is because you are no long drawing over the top of the old text,
I dont know what the background image is so I clear the whole canvas. But if the background image is not transparent you only need to clear what it does not cover.
See change below
// Create the canvas
var canvas = document.createElement("canvas");
var ctx = canvas.getContext('2d');
var timer = 0;
var caught = false;
var fps = 10;
document.body.appendChild(canvas);
canvas.width = 800;
canvas.height = 544;
// Background image
var bgReady = false;
var bgImage = new Image();
bgImage.onload = function () {
bgReady = true;
};
bgImage.src = "images/background.png";
// nar image
var narReady = false;
var narImage = new Image();
narImage.onload = function () {
narReady = true;
};
narImage.src = "images/nar.png";
var nar = {};
var narCaught = 0;
// When nar is caught, reset
var reset = function () {
nar.x = 40 + (Math.random() * (canvas.width - 70));
do {
nar.y = 40 + (Math.random() * (canvas.height - 70));
}
while (nar.y < 100)
};
//mousedown event
window.addEventListener("mousedown", onMouseDown, false);
function onMouseDown(e) {
if (e.button != 0) return;
mouseXinCanvas = e.clientX;
mouseYinCanvas = e.clientY;
if (narBody(nar, mouseXinCanvas, mouseYinCanvas)) {
caught = true;
clearInterval(timer);
timer = setInterval(reset, 20000 / fps);
reset();
}
if (ResetScore(mouseXinCanvas, mouseYinCanvas)) {
location.reload();
}
if (ResetSpeed(mouseXinCanvas, mouseYinCanvas)) {
clearInterval(timer);
timer = setInterval(reset, 20000 / fps);
reset();
render();
}
};
//nar's body define
function narBody(nar, x, y) {
if (x <= (nar.x + 80)
&& nar.x <= (x + 80)
&& y <= (nar.y + 80)
&& nar.y <= (y + 80)
) {
fps = fps + 5;
narCaught++;
return true;
}
return false;
};
//Reset Score box
function ResetScore(x, y) {
if (x > (305)
&& x < (545)
&& y > (15)
&& y < (85)
) {
return true;
}
return false;
};
//Reset speed box
function ResetSpeed(x, y) {
if (x > (605)
&& x < (845)
&& y > (15)
&& y < (85)
) {
fps = 10;
return true;
}
return false;
};
// Draw everything
var render = function () {
//===========================================================
// add the following line to clear the display.
ctx.clearRect(0,0,ctx.canvas.width,ctx.canvas.height);
if (bgReady) {
ctx.drawImage(bgImage, 0, 100);
}
if (narReady) {
ctx.drawImage(narImage, nar.x, nar.y);
}
if (caught == true) {
if (bgReady) {
ctx.drawImage(bgImage, 0, 100);
}
caught = false;
}
// Score, Title
ctx.fillStyle = "rgb(65, 226, 24)";
ctx.font = "34px Helvetica";
ctx.textAlign = "left";
ctx.textBaseline = "top";
ctx.fillText("Catch Naruto!!!", 5, 40);
ctx.font = "20px Helvetica";
ctx.fillText("Score: " + narCaught, 10, 10);
// Reset Score, Speed button
ctx.fillStyle = "rgb(30, 168, 99)";
ctx.fillRect(250, 10, 250, 80);
ctx.fillRect(520, 10, 250, 80);
ctx.fillStyle = "rgb(30, 168, 99)";
ctx.fillRect(255, 15, 240, 70);
ctx.fillRect(525, 15, 240, 70);
ctx.fillStyle = "rgb(255, 255, 255)";
ctx.font = "34px Arial";
ctx.fillText("Reset Score", 275, 30);
ctx.fillText("Reset Speed", 545, 30);
};
// The main game loop
var main = function () {
render();
// Request to do this again ASAP
requestAnimationFrame(main);
};
// Cross-browser support for requestAnimationFrame
var w = window;
requestAnimationFrame = w.requestAnimationFrame || w.webkitRequestAnimationFrame || w.msRequestAnimationFrame || w.mozRequestAnimationFrame;
// Let's play this game!
//var then = Date.now();
reset();
main();
Using NodeJS and Socket.io, I'm making a quick canvas app that moves a shape across the screen. This data will appear on all clients. Each square is timestamped to determine draw order.
Below is client.html. It says that I "cannot set property lastUpdate" of undefined. How is it considered undefined? I tried defining it so many times at the top. What's wrong?
<!DOCTYPE html>
<html lang="en">
<head>
<script src="/socket.io/socket.io.js"></script>
<script>
"use strict";
var canvas;
var ctx;
var socket;
//var lastUpdate = new Date().getTime();
/*var square = {
lastUpdate: new Date().getTime(),
x: 0,
y: 0,
height: 100,
width: 100
};*/
//
//var person = {name: 'user' + (Math.floor((Math.random() * 1000)) + 1)};
//var user = 'user' + (Math.floor((Math.random() * 1000)) + 1);
//var user = Object.keys(something about name);
//var user = Object.keys(user);
//function person(name) {
//this.name = name;
//}
//var user = Object.keys(person);
//lets try using a prototype
/*function user(lastUpdate, x, y, width, height) {
this.lastUpdate = lastUpdate;
this.x = x;
this.y = y;
this.width = width;
this.height = height;
}*/
var name = {lastUpdate: new Date().getTime(), x: 0, y: 0, width: 100, height: 100};
var user = Object.keys(name);
var draws = {};
function updatePosition() {
var message = {
xUpdate: 10,
yUpdate: 5
}
socket.emit('movementUpdate', message);
}
/*function redraw() {
ctx.clearRect(0, 0, canvas.width, canvas.height);
ctx.fillRect(square.x, square.y, square.width, square.height);
}*/
//
function draw() {
ctx.clearRect(0, 0, canvas.width, canvas.height);
var keys = Object.keys(draws);
for(var i = 0; i < keys.length; i++)
{
var drawCall = draws[keys[i]];
//order to draw
//gets drawcalls instead of var square
ctx.fillRect(drawCall.x, drawCall.y, drawCall.width, drawCall.height);
}
}
//
function setup() {
var time = new Date().getTime();
//console.log(time);
var x = Math.floor(Math.random()*(300-10) + 10); //random x position
var x = Math.floor(Math.random()*(300-10) + 10); //random y position
draws[user] = {lastUpdate: time, x: x, y: y, width: 100, height: 100};
}
/*function update(data) {
square = data;
redraw();
}*/
//
function handleMessage(data) {
if(!draws[data.name])
{
draws[data.name] = data.coords;
}
else if(data.coords.lastUpdate > draws[data.name].lastUpdate)
{
draws[data.name] = data.coords;
}
draw(); //redraw after updates
}
function init() {
canvas = document.querySelector("#canvas");
ctx = canvas.getContext("2d");
socket = io.connect();
socket.on('connect', function () {
//setInterval(updatePosition, 1000);
setInterval(function()
{
var time = new Date().getTime();
//console.log(time);
console.log(draws);
**draws[user].lastUpdate = time; //lastUpdate is UNDEFINED**
draws[user].x += 5;
socket.emit('draw', {name: user, coords: draws[user]});
draw();
}, 3000);
});
socket.on('updatedDraw', handleMessage);
//socket.on('updatedMovement', updatePosition); //UNDEFINED, used to be 'update'. Could it be 'handleMessage'?
}
window.onload = init;
</script>
</head>
<body>
<canvas id="canvas" height="500" width="500">Please use an HTML 5 browser</canvas>
</body>
</html>
How change the speed of each shape?
I tried to play with pct but I guess this is wrong way:
var canvas = document.getElementById("canvas");
var ctx = canvas.getContext("2d");
window.requestAnimFrame = (function (callback) {
return window.requestAnimationFrame || window.webkitRequestAnimationFrame || window.mozRequestAnimationFrame || window.oRequestAnimationFrame || window.msRequestAnimationFrame || function (callback) {
window.setTimeout(callback, 1000 / 60);
};
})();
// shape stuff
var shapes = [];
var points;
// shape#1
points = pointsToSingleArray([{
x: 20,
y: 20
}, {
x: 50,
y: 100
}, {
x: 75,
y: 20
}, {
x: 100,
y: 100
}]);
shapes.push({
width: 20,
height: 10,
waypoints: points,
color: "red"
});
// shape#2
points = pointsToSingleArray([{
x: 0,
y: 0
}, {
x: 180,
y: 0
}, {
x: 180,
y: 180
}, {
x: 0,
y: 180
}, {
x: 0,
y: 0
}, {
x: 100,
y: 80
}]);
shapes.push({
width: 20,
height: 20,
waypoints: points,
color: "blue"
});
// animation stuff
var index = 0;
var fps = 60;
// start animating
animate();
function pointsToSingleArray(points) {
// array to hold all points on this polyline
var allPoints = [];
// analyze all lines formed by this points array
for (var a = 1; a < points.length; a++) { // loop through each array in points[]
// vars for interpolating steps along a line
var dx = points[a].x - points[a - 1].x;
var dy = points[a].y - points[a - 1].y;
var startX = points[a - 1].x;
var startY = points[a - 1].y;
// calc 100 steps along this particular line segment
for (var i = 1; i <= 100; i++) {
var pct = Math.min(1, i * .01);
var nextX = startX + dx * pct;
var nextY = startY + dy * pct;
allPoints.push({
x: nextX,
y: nextY
});
}
}
return (allPoints);
}
function animate() {
setTimeout(function () {
// this flag becomes true if we made any moves
// If true, we later request another animation frame
var weMoved = false;
// clear the canvas
ctx.clearRect(0, 0, canvas.width, canvas.height);
// draw all shapes
for (var i = 0; i < shapes.length; i++) {
// get reference to next shape
var shape = shapes[i];
// check if we still have waypoint steps for this shape
if (index < shape.waypoints.length) {
// we're not done, so set the weMoved flag
weMoved = true;
// draw this shape at its next XY
drawShape(shape, index);
} else {
// we're done animating this shape
// draw it in its final position
drawShape(shape, shape.waypoints.length - 1);
}
}
// goto next index XY in the waypoints array
// Note: incrementing by 2 doubles animation speed
index += 2;
// if weMoved this frame, request another animation loop
if (weMoved) {
requestAnimFrame(animate)
};
}, 1000 / fps);
}
function drawShape(shape, waypointIndex) {
var x = shape.waypoints[waypointIndex].x;
var y = shape.waypoints[waypointIndex].y;
ctx.fillStyle = shape.color;
ctx.fillRect(x, y, shape.width, shape.height);
}
Maybe somebody know examples with changing speed, or how to make the code better.
http://jsfiddle.net/4DxLL/ - changing speed
var index = [0, 0];
shapes.push({
width: 20,
height: 10,
waypoints: points,
color: "red",
speed: 10,
});
index[i] += shape.speed;