mirror of
https://github.com/logsol/chuck.js.git
synced 2026-05-11 10:37:34 +00:00
Fix Planck debug draw: add camera sync and hide sensors like Box2D
This commit is contained in:
parent
955179eec9
commit
d584065757
6 changed files with 109 additions and 18 deletions
|
|
@ -32,6 +32,11 @@ function (Parent, Box2D, PhysicsEngine, ViewManager, PlayerController, nc, reque
|
||||||
|
|
||||||
Parent.call(this, options);
|
Parent.call(this, options);
|
||||||
|
|
||||||
|
// Set reference to this GameController in the physics engine for camera access
|
||||||
|
if (this.physicsEngine && this.physicsEngine.setGameController) {
|
||||||
|
this.physicsEngine.setGameController(this);
|
||||||
|
}
|
||||||
|
|
||||||
this.ncTokens = this.ncTokens.concat([
|
this.ncTokens = this.ncTokens.concat([
|
||||||
nc.on(nc.ns.client.game.gameStats.toggle, this.toggleGameStats, this)
|
nc.on(nc.ns.client.game.gameStats.toggle, this.toggleGameStats, this)
|
||||||
]);
|
]);
|
||||||
|
|
|
||||||
|
|
@ -52,15 +52,59 @@ function (Parent, Settings, domController, Box2D, nc, PlanckDebugDraw, debugLaye
|
||||||
Engine.prototype.renderDebug = function () {
|
Engine.prototype.renderDebug = function () {
|
||||||
if (this.debugDraw) {
|
if (this.debugDraw) {
|
||||||
this.debugDraw.clear();
|
this.debugDraw.clear();
|
||||||
|
|
||||||
|
// Get camera position from the game view
|
||||||
|
var cameraPos = this.getCameraPosition();
|
||||||
|
var zoom = this.getCameraZoom();
|
||||||
|
|
||||||
|
// Apply camera transformations to debug draw
|
||||||
|
this.debugDraw.setTransform(cameraPos, zoom);
|
||||||
this.debugDraw.drawWorld(this.world);
|
this.debugDraw.drawWorld(this.world);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
Engine.prototype.getCameraPosition = function() {
|
||||||
|
// Get camera position from the view system
|
||||||
|
// This needs to match the layer positioning logic
|
||||||
|
if (this.gameController && this.gameController.view && this.gameController.view.layerManager) {
|
||||||
|
var layerManager = this.gameController.view.layerManager;
|
||||||
|
var tileLayer = layerManager.getLayerById('tile'); // Use tile layer as reference
|
||||||
|
|
||||||
|
if (tileLayer) {
|
||||||
|
return {
|
||||||
|
x: tileLayer.position.current.x,
|
||||||
|
y: tileLayer.position.current.y,
|
||||||
|
zoom: tileLayer.zoom.current
|
||||||
|
};
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Fallback to default position
|
||||||
|
return { x: 0, y: 0, zoom: 1 };
|
||||||
|
};
|
||||||
|
|
||||||
|
Engine.prototype.getCameraZoom = function() {
|
||||||
|
if (this.gameController && this.gameController.view && this.gameController.view.layerManager) {
|
||||||
|
var layerManager = this.gameController.view.layerManager;
|
||||||
|
var tileLayer = layerManager.getLayerById('tile');
|
||||||
|
|
||||||
|
if (tileLayer) {
|
||||||
|
return tileLayer.zoom.current;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return 1;
|
||||||
|
};
|
||||||
|
|
||||||
|
Engine.prototype.setGameController = function(gameController) {
|
||||||
|
this.gameController = gameController;
|
||||||
|
};
|
||||||
|
|
||||||
Engine.prototype.update = function () {
|
Engine.prototype.update = function () {
|
||||||
Parent.prototype.update.call(this);
|
Parent.prototype.update.call(this);
|
||||||
|
|
||||||
if(this.debugMode) {
|
if(this.debugMode && this.debugDraw) {
|
||||||
this.world.DrawDebugData();
|
this.debugDraw.drawWorld(this.world);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -10,6 +10,8 @@ function (Settings) {
|
||||||
this.canvas = canvas;
|
this.canvas = canvas;
|
||||||
this.ctx = canvas.getContext('2d');
|
this.ctx = canvas.getContext('2d');
|
||||||
this.scale = Settings.RATIO;
|
this.scale = Settings.RATIO;
|
||||||
|
this.cameraPos = { x: 0, y: 0 };
|
||||||
|
this.cameraZoom = 1;
|
||||||
this.flags = {
|
this.flags = {
|
||||||
shapes: true,
|
shapes: true,
|
||||||
joints: false,
|
joints: false,
|
||||||
|
|
@ -23,12 +25,23 @@ function (Settings) {
|
||||||
this.ctx.clearRect(0, 0, this.canvas.width, this.canvas.height);
|
this.ctx.clearRect(0, 0, this.canvas.width, this.canvas.height);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
PlanckDebugDraw.prototype.setTransform = function(cameraPos, zoom) {
|
||||||
|
this.cameraPos = cameraPos;
|
||||||
|
this.cameraZoom = zoom || 1;
|
||||||
|
};
|
||||||
|
|
||||||
PlanckDebugDraw.prototype.drawWorld = function(world) {
|
PlanckDebugDraw.prototype.drawWorld = function(world) {
|
||||||
if (!this.flags.shapes) return;
|
if (!this.flags.shapes) return;
|
||||||
|
|
||||||
this.ctx.save();
|
this.ctx.save();
|
||||||
this.ctx.scale(this.scale, this.scale);
|
|
||||||
this.ctx.lineWidth = 1 / this.scale;
|
// Apply camera transformations like the game layers do
|
||||||
|
var transformedX = this.cameraPos.x * this.cameraZoom + Settings.STAGE_WIDTH / 2;
|
||||||
|
var transformedY = this.cameraPos.y * this.cameraZoom + Settings.STAGE_HEIGHT / 2;
|
||||||
|
|
||||||
|
this.ctx.translate(transformedX, transformedY);
|
||||||
|
this.ctx.scale(this.scale * this.cameraZoom, this.scale * this.cameraZoom);
|
||||||
|
this.ctx.lineWidth = 0.5 / this.scale;
|
||||||
|
|
||||||
// Iterate through all bodies
|
// Iterate through all bodies
|
||||||
for (var body = world.getBodyList(); body; body = body.getNext()) {
|
for (var body = world.getBodyList(); body; body = body.getNext()) {
|
||||||
|
|
@ -38,6 +51,11 @@ function (Settings) {
|
||||||
for (var fixture = body.getFixtureList(); fixture; fixture = fixture.getNext()) {
|
for (var fixture = body.getFixtureList(); fixture; fixture = fixture.getNext()) {
|
||||||
var shape = fixture.getShape();
|
var shape = fixture.getShape();
|
||||||
|
|
||||||
|
// Skip sensor fixtures to match old Box2D behavior
|
||||||
|
if (fixture.isSensor()) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
if (body.isDynamic()) {
|
if (body.isDynamic()) {
|
||||||
this.ctx.strokeStyle = '#ff0000'; // Red for dynamic bodies
|
this.ctx.strokeStyle = '#ff0000'; // Red for dynamic bodies
|
||||||
this.ctx.fillStyle = 'rgba(255, 0, 0, 0.1)';
|
this.ctx.fillStyle = 'rgba(255, 0, 0, 0.1)';
|
||||||
|
|
|
||||||
|
|
@ -39,7 +39,7 @@ function () {
|
||||||
VIEW_CONTROLLER: 0 ? "Three" : "Pixi",
|
VIEW_CONTROLLER: 0 ? "Three" : "Pixi",
|
||||||
ARROW_GLIDE: 30, // % of the way per frame
|
ARROW_GLIDE: 30, // % of the way per frame
|
||||||
SHOW_LAYER_INFO: false,
|
SHOW_LAYER_INFO: false,
|
||||||
ENABLE_POINTER_LOCK_FILTER: true,
|
ENABLE_POINTER_LOCK_FILTER: false,
|
||||||
|
|
||||||
// GAME PLAY
|
// GAME PLAY
|
||||||
WALK_SPEED: 4,
|
WALK_SPEED: 4,
|
||||||
|
|
|
||||||
|
|
@ -32,6 +32,20 @@ function (Planck) {
|
||||||
var userDataA = contact.getFixtureA().getUserData();
|
var userDataA = contact.getFixtureA().getUserData();
|
||||||
var userDataB = contact.getFixtureB().getUserData();
|
var userDataB = contact.getFixtureB().getUserData();
|
||||||
|
|
||||||
|
// Check if this is a foot sensor collision
|
||||||
|
var isFootSensorCollision = false;
|
||||||
|
var footSensorUserData = null;
|
||||||
|
|
||||||
|
if (userDataA && userDataA.isFootSensor) {
|
||||||
|
isFootSensorCollision = true;
|
||||||
|
footSensorUserData = userDataA;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (userDataB && userDataB.isFootSensor) {
|
||||||
|
isFootSensorCollision = true;
|
||||||
|
footSensorUserData = userDataB;
|
||||||
|
}
|
||||||
|
|
||||||
if (userDataA && userDataA.onCollisionChange) {
|
if (userDataA && userDataA.onCollisionChange) {
|
||||||
userDataA.onCollisionChange(isColliding, contact.getFixtureB());
|
userDataA.onCollisionChange(isColliding, contact.getFixtureB());
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -105,20 +105,26 @@ function (Parent, Exception, planck, Settings, CollisionDetector, Item, nc, Asse
|
||||||
|
|
||||||
this.legs = this.body.createFixture(fixtureDef);
|
this.legs = this.body.createFixture(fixtureDef);
|
||||||
|
|
||||||
fixtureDef.density = 0;
|
// Create a fresh fixture definition for the foot sensor
|
||||||
|
var footSensorDef = {
|
||||||
|
shape: null,
|
||||||
|
density: 0,
|
||||||
|
friction: 0,
|
||||||
|
restitution: 0,
|
||||||
|
isSensor: true,
|
||||||
|
userData: {
|
||||||
|
onCollisionChange: this.onFootSensorDetection.bind(this),
|
||||||
|
isFootSensor: true
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
var feetShape = planck.Circle(
|
var feetShape = planck.Circle(
|
||||||
(this.width - 1) / 2 / Settings.RATIO, // the -1 one prevents collisions with walls
|
(this.width - 1) / 2 / Settings.RATIO, // the -1 one prevents collisions with walls
|
||||||
planck.Vec2(0, 2 / Settings.RATIO) // 2 is offset into ground
|
planck.Vec2(0, -20 / Settings.RATIO) // 20 pixels down from center (dramatic test)
|
||||||
);
|
);
|
||||||
fixtureDef.shape = feetShape;
|
footSensorDef.shape = feetShape;
|
||||||
fixtureDef.isSensor = true;
|
|
||||||
|
|
||||||
fixtureDef.userData = {
|
this.footSensor = this.body.createFixture(footSensorDef);
|
||||||
onCollisionChange: this.onFootSensorDetection.bind(this)
|
|
||||||
};
|
|
||||||
|
|
||||||
this.footSensor = this.body.createFixture(fixtureDef);
|
|
||||||
|
|
||||||
var grabSensorLeftShape = planck.Box(
|
var grabSensorLeftShape = planck.Box(
|
||||||
this.reachDistance / 2 / Settings.RATIO,
|
this.reachDistance / 2 / Settings.RATIO,
|
||||||
|
|
@ -312,7 +318,11 @@ function (Parent, Exception, planck, Settings, CollisionDetector, Item, nc, Asse
|
||||||
};
|
};
|
||||||
|
|
||||||
Doll.prototype.setStanding = function (isStanding) {
|
Doll.prototype.setStanding = function (isStanding) {
|
||||||
if (this.standing == isStanding) return;
|
if (this.standing == isStanding) {
|
||||||
|
console.log('setStanding called but no change needed, already:', isStanding);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
console.log('*** STANDING STATE CHANGE: ', this.standing, '->', isStanding, '***');
|
||||||
this.standing = isStanding;
|
this.standing = isStanding;
|
||||||
if(isStanding) this.setActionState("stand");
|
if(isStanding) this.setActionState("stand");
|
||||||
};
|
};
|
||||||
|
|
@ -394,23 +404,23 @@ function (Parent, Exception, planck, Settings, CollisionDetector, Item, nc, Asse
|
||||||
return this.nearbyDolls.length > 0;
|
return this.nearbyDolls.length > 0;
|
||||||
};
|
};
|
||||||
|
|
||||||
Doll.prototype.onFootSensorDetection = function(isColliding, fixture) { // jshint unused:false
|
Doll.prototype.onFootSensorDetection = function(isColliding, fixture) {
|
||||||
|
|
||||||
var self = this;
|
var self = this;
|
||||||
|
|
||||||
var hasJumpStartVelocity = this.body.getLinearVelocity().y < -Settings.JUMP_SPEED;
|
var hasJumpStartVelocity = this.body.getLinearVelocity().y < -Settings.JUMP_SPEED;
|
||||||
|
var currentVelocity = this.body.getLinearVelocity();
|
||||||
|
|
||||||
if(isColliding) {
|
if(isColliding) {
|
||||||
if(!hasJumpStartVelocity) {
|
if(!hasJumpStartVelocity) {
|
||||||
this.setStanding(true);
|
this.setStanding(true);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
|
|
||||||
var contactCount = 0;
|
var contactCount = 0;
|
||||||
|
|
||||||
var edge = self.body.getContactList();
|
var edge = self.body.getContactList();
|
||||||
while (edge) {
|
while (edge) {
|
||||||
var contact = edge.contact;
|
var contact = edge.contact;
|
||||||
|
|
||||||
if(!contact.isTouching()) {
|
if(!contact.isTouching()) {
|
||||||
edge = edge.next;
|
edge = edge.next;
|
||||||
continue;
|
continue;
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue