i have local server runs on nodejs with box2d at zero gravity. And client with cocos2d-x. When i emit some movement data from my client, server gets and applies this movement data to the objects. Problem is about collisions. When force is applied to A dynamic object(Player), A object collides with another dynamic object called B (ball) at zero gravity world. B object never floats after collision. Just moves with small amount of unit and stops suddenly. ( i tried to set linear damping to 0 and it still stops suddenly.)
Server side codes :
World.js
var Box2D = require('./box2d.js');
var s = require('./Server.js');
var b2Vec2 = Box2D.Common.Math.b2Vec2,
b2BodyDef = Box2D.Dynamics.b2BodyDef,
b2AABB = Box2D.Collision.b2AABB,
b2Body = Box2D.Dynamics.b2Body,
b2FixtureDef = Box2D.Dynamics.b2FixtureDef,
b2Fixture = Box2D.Dynamics.b2Fixture,
b2World = Box2D.Dynamics.b2World,
b2MassData = Box2D.Collision.Shapes.b2MassData,
b2PolygonShape = Box2D.Collision.Shapes.b2PolygonShape,
b2CircleShape = Box2D.Collision.Shapes.b2CircleShape,
b2DebugDraw = Box2D.Dynamics.b2DebugDraw,
b2MouseJointDef = Box2D.Dynamics.Joints.b2MouseJointDef,
b2EdgeShape = Box2D.Collision.Shapes.b2EdgeShape;
function World(world, gravity, velocity, name, room) {
this._room = room;
this._name = name;
this._world = world;
this._gravity = gravity;
this._velocity = velocity;
this._gameElements = {};
this._scale = 30;
this._interval;
this._size = 50;
this._w = 900;
this._h = 500;
this._fps = 60;
this._inteval;
this._PI2 = Math.PI * 2;
this._D2R = Math.PI / 180;
this._R2D = 180 / Math.PI;
this._debug = false;
}
World.prototype.startEnv = function () {
this._world = new b2World(new b2Vec2(0, this._gravity), true);
this.createArea(0, 0, this._w, 5, true);
this.createArea(0, this._h, this._w, 5, true);
this.createArea(0, 0, 5, this._h, true);
this.createArea(this._w, 0, 5, this._h, true);
this.createBox(0.1,450, 250, 12, 12, false, true, 'ball','ball');
this.createBox(1,250,250, 25, 25, false, true, 'blue','anilgulgor');
//this.createBox(650, 250, 25, 25, false, true, 'red', username);
this._inteval = setInterval(() => {
this.update();
}, 1000 / this._fps);
this.update();
}
World.prototype.update = function () {
this._world.Step(1 / this._fps, this._gravity, this._velocity);
this._gameElements = this.gameStep();
s.emitObjectsToClients(this._room.name, this._gameElements);
console.log(this._gameElements + "name : " + this._name);
this._world.ClearForces();
}
World.prototype.gameStep = function () {
var elements = [];
var i = 0;
for (var b = this._world.m_bodyList; b; b = b.m_next) {
for (var f = b.m_fixtureList; f; f = f.m_next) {
if (f.m_body.m_userData) {
var x = Math.floor(f.m_body.m_xf.position.x * this._scale);
var y = Math.floor(f.m_body.m_xf.position.y * this._scale);
var r = Math.round(((f.m_body.m_sweep.a + this._PI2) % this._PI2) * this._R2D * 100) / 100;
var width = f.m_body.m_userData.width;
var height = f.m_body.m_userData.height;
var static = f.m_body.m_userData.static;
var type = f.m_body.m_userData.type;
var gameObj = {
x: x,
y: y,
r: r,
w: width,
h: height,
s: static,
t: type
}
elements.push(gameObj);
}
}
}
console.log(elements);
return { elements: elements };
}
World.prototype.createBox = function (d,x, y, w2, h2, static, circle, type, username) {
var bodyDef = new b2BodyDef;
bodyDef.type = static ? b2Body.b2_staticBody : b2Body.b2_dynamicBody;
bodyDef.position.x = x / this._scale;
bodyDef.position.y = y / this._scale;
bodyDef.userData = { width: w2, height: h2, static: static, type: type, userName: username };
bodyDef.allowSleep = false;
bodyDef.linearDamping = 0.5;
bodyDef.fixedRotation = true;
var fixDef = new b2FixtureDef;
fixDef.density = d;
fixDef.friction = 0.1;
fixDef.restitution = 1;
if (circle) {
var circleShape = new b2CircleShape;
circleShape.m_radius = w2 / this._scale;
fixDef.shape = circleShape;
} else {
fixDef.shape = new b2PolygonShape;
fixDef.shape.SetAsBox(w2 / this._scale, h2 / this._scale);
}
return this._world.CreateBody(bodyDef).CreateFixture(fixDef);
}
World.prototype.applyForce = function (username, force) {
for (var b = this._world.m_bodyList; b; b = b.m_next) {
for (var f = b.m_fixtureList; f; f = f.m_next) {
if(f.m_body.m_userData){
if (f.m_body.m_userData.userName == username) {
var forceVec = JSON.parse(force);
f.m_body.ApplyForce(new b2Vec2(forceVec.forceX, forceVec.forceY) , f.m_body.m_xf.position);
//f.m_body.SetLinearVelocity(new b2Vec2(forceVec.forceX, forceVec.forceY));
console.log(forceVec.forceX + " " + forceVec.forceY);
}
}
}
}
}
World.prototype.createArea = function (x, y, w2, h2, static) {
var bodyDef = new b2BodyDef;
bodyDef.type = static ? b2Body.b2_staticBody : b2Body.b2_dynamicBody;
bodyDef.position.x = x / this._scale;
bodyDef.position.y = y / this._scale;
var fixDef = new b2FixtureDef;
fixDef.density = 1.5;
fixDef.friction = 0.2;
fixDef.restitution = 1.0;
fixDef.shape = new b2PolygonShape;
fixDef.shape.SetAsBox(w2 / this._scale, h2 / this._scale);
return this._world.CreateBody(bodyDef).CreateFixture(fixDef);
}
module.exports = World;
Server.js
const http = require('http');
const express = require('express');
const socketIO = require('socket.io');
const World = require('./World.js');
var usernames = [];
var roomToJoin;
//port
const port = process.env.PORT || 3000;
var app = express();
var server = http.createServer(app);
var io = socketIO(server);
//server listen
server.listen(port, () => {
console.log(`Server is on port ${port}`);
});
io.on('connection', function (socket) {
//event fired when we get a new connection
console.log('user connected');
socket.emit('connected', `connected to the server`);
//wait for addMe command with username parameter
socket.on('addMe', function (username) {
//Starting procedure of joining room
console.log(`${username} started addMe procedure to join room`);
//socket username is binded with client username
socket.username = username;
//socket room name is statically given.
socket.room = 'room1';
//add username to the global username list
usernames.push(username);
if (roomToJoin != null) {
if (roomToJoin.length < 2) {
//room is available to join
//client join static room
socket.join(socket.room, (err) => {
if (!err) {
roomToJoin = io.sockets.adapter.rooms[socket.room];
roomToJoin.name = socket.room;
console.log(roomToJoin.length + " clients in room");
//join room sucessfully
socket.emit('connectedToRoom', `connected to the room name : ${socket.room}`);
//broadcast to another users in the room to warn that some user has connected
socket.broadcast.to(socket.room).emit('userConnectedToRoom', 'GameServer', `${username} has connected to the ${socket.room}`);
//room capacity is full right now
//we can start and emit world object positions to the clients
//startEmittingObjectPositionsToClients(roomToJoin);
}
else {
socket.emit('canNotConnectRoom', 'can not connect to the room');
}
});
}
}
else {
//there is no room name socket.room
socket.join(socket.room, (err) => {
if (!err) {
roomToJoin = io.sockets.adapter.rooms[socket.room];
roomToJoin.name = socket.room;
console.log(roomToJoin.length + " clients in room");
//world definition
var world;
var w = new World(world, 0, 100, `${socket.room} world`, roomToJoin);
// assign creator world to the roomToJoin.world
roomToJoin.world = w;
//join room sucessfully
socket.emit('connectedToRoom', `connected to the room name : ${socket.room}`);
//broadcast to another users in the room to warn that some user has connected
socket.broadcast.to(socket.room).emit('userConnectedToRoom', 'GameServer', `${username} has connected to the ${socket.room}`);
startEmittingObjectPositionsToClients(roomToJoin);
}
else {
socket.emit('canNotConnectRoom', 'can not connect to the room');
}
});
}
});
socket.on('move', function(moveData) {
var room = io.sockets.adapter.rooms[socket.room];
console.log(room);
room.world.applyForce('anilgulgor', moveData);
console.log(moveData);
});
});
function startEmittingObjectPositionsToClients(room) {
room.world.startEnv();
}
function emitObjectsToClients(roomName, gameElements) {
console.log(roomName);
io.sockets.in(roomName).emit('worldStep', gameElements);
console.log('gönderdiiiiiiiiiiiim');
}
module.exports.emitObjectsToClients = emitObjectsToClients;
Everything works when i emit "move" call from my client. But collisions don't work as i expected.
via anıl gülgör
No comments:
Post a Comment