Ich habe lokalen Server läuft auf Nodejs mit Box2d bei Schwerelosigkeit. Und Client mit cocos2d-x. Wenn ich einige Bewegungsdaten von meinem Client austrage, bekommt der Server diese Bewegungsdaten und wendet sie auf die Objekte an. Das Problem betrifft Kollisionen. Wenn die Kraft auf ein dynamisches Objekt (Player) angewendet wird, kollidiert ein Objekt mit einem anderen dynamischen Objekt namens B (Ball) in der Schwerelosigkeitswelt. B Objekt schwebt niemals nach einer Kollision. Bewegt sich nur mit geringer Menge und stoppt plötzlich. (Ich habe versucht, linear auf 0 gesetzt Dämpfung und hält noch einmal.)Node.js Box2d Kollisionen funktioniert nicht wie erwartet bei Schwerelosigkeit?
Server-Seite-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;
alles funktioniert wenn ich einen "move" -Aufruf von meinem Client ausstelle. Kollisionen funktionieren jedoch nicht wie erwartet.
ich denke, ich habe eine Lösung gefunden, die nicht zuverlässig ist. Stellen Sie die Schwerkraft einfach auf 0,0001 auf der Y-Achse ein. Impuls auf Objekte nach Kollisionen funktioniert jetzt. –