Hello all! This is my first post so I hope i'm in the right place. :)
game client: web browser, html canvas & javascript with socket.io (client)
server: node.js & socket.io(server)
I am trying to make this game a multiplayer game (for now just have multiple characters on the same screen). I have removed the monster and it's functionality. I have sent the movement of my character to the server (via x,y coordinates) and then the server then emits them to all connected clients:
Great! I've figured that out! :D
Right now if multiple people connect they all can control the character and see it live.
Now I am wanting to make it so I can generate the character once I am connected to the websocket server, so I can make more than one character on the screen. So my idea would be that once I connect I would then send a message to the server saying "hey, i'm a new character" the server would respond and send all clients a message to create a character at this location. I can't seem to find out what parts of my javascript code I should move around to do this... Could someone help me out with this? I would ask my teacher but she doesn't know websockets as much as I do...Besides that, is this the right type of thinking?
Also, it seems like I am sending too much coordinates to the server, I don't know how much is too much for the sockets to handle but I feel like it's unnecessary. I am not noticing much latency even from different ip's though so I am not sure. What is the right amount of times you have to send your location to the server per second?
If you guys have any recomendations on what I should do that'd be great! If not, do you have any good articles on how I should acheive this?
Thanks guys!
My client code:
var uname = prompt("Please enter a username!");
var socket = io.connect('http://192.168.2.5:8654');
socket.emit('username', { name: uname });
var i = 0;
// Create the canvas
var canvas = document.createElement("canvas");
var ctx = canvas.getContext("2d");
canvas.width = 512;
canvas.height = 480;
document.body.appendChild(canvas);
// Background image
var bgReady = false;
var bgImage = new Image();
bgImage.onload = function () {
bgReady = true;
};
bgImage.src = "images/background.png";
// Hero image
var heroReady = false;
var heroImage = new Image();
heroImage.onload = function () {
heroReady = true;
};
heroImage.src = "images/hero.png";
var keydown = true;
addEventListener("keydown", function (e) {
//e.code
// alert(e.code);
if (e.code == "ArrowLeft" || e.code == "ArrowUp" || e.code == "ArrowRight" || e.code == "ArrowDown") {
console.log("good");
if (keydown == true) {
socket.emit('sendactiondown', { ecode: e.code});
keydown = false;
}
}
//
}, false);
addEventListener("keyup", function (e) {
if (e.code == "ArrowLeft" || e.code == "ArrowUp" || e.code == "ArrowRight" || e.code == "ArrowDown") {
keydown = true;
socket.emit('sendactionup', { ecode: e.code});
}
}, false);
// Game objects
var hero = {
speed: 256 // movement in pixels per second
};
socket.on('poscallback', function(data){
// Set starting position
hero.x = data.xpos;
hero.y = data.ypos;
render(data.xpos, data.ypos);
});
// Update game objects
// var update = function (modifier) {
// hero.y -= hero.speed * modifier;
// hero.x -= hero.speed * modifier;
// };
// Draw everything
var render = function (x, y) {
if (bgReady) {
ctx.drawImage(bgImage, 0, 0);
}
if (heroReady) {
ctx.drawImage(heroImage, x, y);
// console.log(hero.x+" "+hero.y);
}
};
// The main game loop
var main = function () {
var now = Date.now();
var delta = now - then;
update(delta / 1000);
then = now;
// Request to do this again ASAP
requestAnimationFrame(main);
};
// Update game objects
var update = function (modifier) {
if (38 in keysDown) { // Player holding up
hero.y -= hero.speed * modifier;
}
if (40 in keysDown) { // Player holding down
hero.y += hero.speed * modifier;
}
if (37 in keysDown) { // Player holding left
hero.x -= hero.speed * modifier;
}
if (39 in keysDown) { // Player holding right
hero.x += hero.speed * modifier;
}
};
// 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();
main();
My server code:
var express = require('express');
var app = express();
var server = require('http').createServer(app);
var io = require('socket.io').listen(server);
var players = [];
// array.push(item.id);
server.listen(process.env.PORT || 8654);
console.log('Server is running.');
io.on('connection', function (socket) {
var playerx = Math.floor(Math.random() * 500) + 1;
var playery = Math.floor(Math.random() * 500) + 1;
socket.on('username', function(data){
players.push(data.name);
io.sockets.emit('poscallback', { xpos: playerx, ypos: playery});
console.log(data.name+"has joined!");
})
socket.on('sendpos', function(data){
console.log(": X:"+data.x+" Y:"+data.y);
io.sockets.emit('recvupdate', { x: data.x, y: data.y});
});
//for handeling character movement
socket.on('sendactiondown', function(data){
//HERE IS WHERE I TRIED THE WHILE LOOP TO INCREMENT THE X AND Y.
console.log(data.ecode+" down");
// io.sockets.emit('recvupdate', { x: data.x, y: data.y});
});
socket.on('sendactionup', function(data){
console.log(data.ecode+" up");
//SET CONDITIONAL HERE TO BREAK OUT OF LOOP
// io.sockets.emit('recvupdate', { x: data.x, y: data.y});
});
// socket.on('disconnect', function() {
// console.log('user dissconnected');
// });
});
Exuse my extra code, I am testing some things
EDIT (1/21/17):
I have taken all of your guy's information and started working on having the server move the character, rather than the client. What I basically mean is instead of incrementing the x and y on the client I am starting to do it on the server. I am runing into a problem though. The way that the client did it was by means of the event listener. It would fire off multiple times as you held it down, then they incremented the x (and or) y by having it go through the functions each time it is fired. So on the server it only gets triggered when the key press is down and up (because I made it that way, thought it would be better than sending the server "arrow up" each time it is fired). How do I "move" the character on the server? I tried a while loop that incremented the x and y accordingly with a conditional that would knock it out of the loop once the keypressed UP command was sent to it. I did not have any luck so could anyone recommend what I should do?... :wacko:
I have updated the code above.