mirror of
https://github.com/logsol/chuck.js.git
synced 2026-05-11 18:47:35 +00:00
387 lines
No EOL
12 KiB
JavaScript
387 lines
No EOL
12 KiB
JavaScript
define([
|
|
"Game/" + GLOBALS.context + "/GameObjects/Item",
|
|
"Lib/Vendor/Planck",
|
|
"Game/Config/Settings",
|
|
"Lib/Utilities/NotificationCenter",
|
|
"Lib/Utilities/Assert",
|
|
"Lib/Utilities/OptionsHelper",
|
|
"Game/Config/ItemSettings",
|
|
],
|
|
|
|
function (Parent, planck, Settings, nc, Assert, optionsHelper, ItemSettings) {
|
|
|
|
"use strict";
|
|
|
|
function RagDoll(physicsEngine, uid, options) {
|
|
|
|
// Sensor size
|
|
options.width = 20;
|
|
options.height = 40;
|
|
|
|
options.limbs = {};
|
|
options.limbs.chest = {
|
|
width: 6,
|
|
height: 18,
|
|
x: 0,
|
|
y: 0
|
|
};
|
|
|
|
options.limbs.head = {
|
|
width: 10,
|
|
height: 12,
|
|
x: 0,
|
|
y: - options.limbs.chest.height / 2 - 7
|
|
};
|
|
|
|
options.limbs.upperLeftLeg = {
|
|
width: 3,
|
|
height: 4,
|
|
x: -2,
|
|
y: options.limbs.chest.height / 2
|
|
};
|
|
|
|
options.limbs.upperRightLeg = {
|
|
width: 3,
|
|
height: 4,
|
|
x: 2,
|
|
y: options.limbs.chest.height / 2
|
|
};
|
|
|
|
options.limbs.lowerLeftLeg = {
|
|
width: 4,
|
|
height: 4,
|
|
x: -2,
|
|
y: options.limbs.chest.height / 2 + options.limbs.upperLeftLeg.height
|
|
};
|
|
|
|
options.limbs.lowerRightLeg = {
|
|
width: 4,
|
|
height: 4,
|
|
x: 2,
|
|
y: options.limbs.chest.height / 2 + options.limbs.upperRightLeg.height
|
|
};
|
|
|
|
|
|
|
|
|
|
|
|
options.limbs.upperLeftArm = {
|
|
width: 2,
|
|
height: 8,
|
|
x: -2,
|
|
y: -options.limbs.chest.height / 2
|
|
};
|
|
|
|
options.limbs.upperRightArm = {
|
|
width: 3,
|
|
height: 8,
|
|
x: 2,
|
|
y: -options.limbs.chest.height / 2
|
|
};
|
|
|
|
options.limbs.lowerLeftArm = {
|
|
width: 2,
|
|
height: 5,
|
|
x: -2,
|
|
y: -options.limbs.chest.height / 2 + options.limbs.upperLeftArm.height
|
|
};
|
|
|
|
options.limbs.lowerRightArm = {
|
|
width: 2,
|
|
height: 5,
|
|
x: 2,
|
|
y: -options.limbs.chest.height / 2 + options.limbs.upperRightArm.height
|
|
};
|
|
|
|
|
|
|
|
// FIXME
|
|
var ragdollOptions = optionsHelper.merge(ItemSettings.RagDoll, ItemSettings.Default);
|
|
options = optionsHelper.merge(options, ragdollOptions);
|
|
Parent.call(this, physicsEngine, uid, options);
|
|
//this.createSensor();
|
|
|
|
this.limbs = {};
|
|
this.addHead();
|
|
|
|
|
|
|
|
this.addLimb(
|
|
"upperLeftLeg",
|
|
this.body,
|
|
options.limbs.upperLeftLeg.x,
|
|
options.limbs.chest.height / 2
|
|
);
|
|
|
|
this.addLimb(
|
|
"upperRightLeg",
|
|
this.body,
|
|
options.limbs.upperRightLeg.x,
|
|
options.limbs.chest.height / 2
|
|
);
|
|
|
|
this.addLimb(
|
|
"lowerLeftLeg",
|
|
this.limbs.upperLeftLeg,
|
|
0,
|
|
options.limbs.upperLeftLeg.height / 2
|
|
);
|
|
|
|
this.addLimb(
|
|
"lowerRightLeg",
|
|
this.limbs.upperRightLeg,
|
|
0,
|
|
options.limbs.upperRightLeg.height / 2
|
|
);
|
|
|
|
|
|
|
|
|
|
this.addLimb(
|
|
"upperLeftArm",
|
|
this.body,
|
|
options.limbs.upperLeftArm.x,
|
|
-options.limbs.chest.height / 2
|
|
);
|
|
|
|
this.addLimb(
|
|
"upperRightArm",
|
|
this.body,
|
|
options.limbs.upperRightArm.x,
|
|
-options.limbs.chest.height / 2
|
|
);
|
|
|
|
this.addLimb(
|
|
"lowerLeftArm",
|
|
this.limbs.upperLeftArm,
|
|
0,
|
|
options.limbs.upperLeftArm.height / 2
|
|
);
|
|
|
|
this.addLimb(
|
|
"lowerRightArm",
|
|
this.limbs.upperRightArm,
|
|
0,
|
|
options.limbs.upperRightArm.height / 2
|
|
);
|
|
|
|
}
|
|
|
|
RagDoll.prototype = Object.create(Parent.prototype);
|
|
|
|
RagDoll.prototype.getId = function() {
|
|
return 55; //parseInt(this.uid.split("-")[1], 10);
|
|
};
|
|
|
|
RagDoll.prototype.getPosition = function() {
|
|
return this.body.GetPosition().clone();
|
|
};
|
|
|
|
RagDoll.prototype.getHeadPosition = function() {
|
|
return this.limbs.head.GetPosition().clone();
|
|
};
|
|
|
|
RagDoll.prototype.getBodyDef = function() {
|
|
var bodyDef = Parent.prototype.getBodyDef.call(this);
|
|
bodyDef.linearDamping = Settings.PLAYER_LINEAR_DAMPING;
|
|
bodyDef.type = 'dynamic';
|
|
bodyDef.position.y -= this.options.height / 2 / Settings.RATIO; // position it on top of ground
|
|
|
|
return bodyDef;
|
|
};
|
|
|
|
RagDoll.prototype.getFixtureDef = function() {
|
|
Assert.number(this.options.limbs.chest.width, this.options.limbs.chest.height);
|
|
|
|
var fixtureDef = Parent.prototype.getFixtureDef.call(this);
|
|
fixtureDef.density = Settings.PLAYER_DENSITY;
|
|
fixtureDef.friction = Settings.PLAYER_FRICTION;
|
|
fixtureDef.restitution = Settings.PLAYER_RESTITUTION;
|
|
fixtureDef.filter.groupIndex = -this.getId();
|
|
|
|
var shape = planck.Box(
|
|
this.options.limbs.chest.width / 2 / Settings.RATIO,
|
|
this.options.limbs.chest.height / 2 / Settings.RATIO,
|
|
planck.Vec2(0, 0)
|
|
);
|
|
|
|
fixtureDef.shape = shape;
|
|
|
|
return fixtureDef;
|
|
};
|
|
|
|
RagDoll.prototype.createSensor = function() {
|
|
Assert.number(this.options.width, this.options.height);
|
|
|
|
var w = this.options.width / Settings.RATIO;
|
|
var h = this.options.height / Settings.RATIO;
|
|
|
|
var itemShape = planck.Box(w / 2, h / 2, planck.Vec2(0, 0));
|
|
|
|
var fixtureDef = { shape: null, density: 1.0, friction: 0.3, restitution: 0.0, isSensor: false };
|
|
fixtureDef.shape = itemShape;
|
|
fixtureDef.isSensor = true;
|
|
|
|
fixtureDef.userData = {
|
|
onCollisionChange: this.onCollisionChange.bind(this)
|
|
};
|
|
|
|
this.body.createFixture(fixtureDef);
|
|
};
|
|
|
|
RagDoll.prototype.addHead = function() {
|
|
Assert.number(this.options.x, this.options.y);
|
|
Assert.number(this.options.limbs.head.x, this.options.limbs.head.y);
|
|
Assert.number(this.options.limbs.head.width);
|
|
|
|
var x = this.options.x + this.options.limbs.head.x,
|
|
y = this.options.y + this.options.limbs.head.y - this.options.height / 2; // position it on top of ground;
|
|
|
|
var bodyDef = {
|
|
type: 'dynamic',
|
|
position: planck.Vec2(x / Settings.RATIO, y / Settings.RATIO),
|
|
angle: 0
|
|
};
|
|
|
|
var shape = planck.Circle(this.options.limbs.head.width / 2 / Settings.RATIO, planck.Vec2(0, 0));
|
|
|
|
var fixtureDef = { shape: null, density: 1.0, friction: 0.3, restitution: 0.0, isSensor: false };
|
|
fixtureDef.density = Settings.PLAYER_DENSITY;
|
|
fixtureDef.friction = Settings.PLAYER_FRICTION;
|
|
fixtureDef.restitution = Settings.PLAYER_RESTITUTION;
|
|
fixtureDef.shape = shape;
|
|
fixtureDef.isSensor = false;
|
|
fixtureDef.filter.groupIndex = -this.getId();
|
|
|
|
var head = this.body.getWorld().createBody(bodyDef);
|
|
head.createFixture(fixtureDef);
|
|
|
|
this.limbs.head = head;
|
|
|
|
this.attachHead();
|
|
};
|
|
|
|
RagDoll.prototype.attachHead = function() {
|
|
var head = this.limbs.head;
|
|
|
|
var jointDef = new Box2D.Dynamics.Joints.b2RevoluteJointDef();
|
|
jointDef.enableMotor = false;
|
|
|
|
var pos = this.body.getWorldCenter().clone();
|
|
pos.y -= this.options.limbs.chest.height / 2 / Settings.RATIO;
|
|
jointDef.initialize(this.body, head, pos);
|
|
jointDef.lowerAngle = -0.25 * Box2D.Common.b2Settings.b2_pi; // -45 degrees
|
|
jointDef.upperAngle = 0.25 * Box2D.Common.b2Settings.b2_pi; // 45 degrees
|
|
jointDef.enableLimit = true;
|
|
|
|
this.body.getWorld().createJoint(jointDef);
|
|
};
|
|
|
|
RagDoll.prototype.addLimb = function(name, connectTo, xOffset, yOffset) {
|
|
Assert.number(xOffset, yOffset);
|
|
Assert.number(this.options.x, this.options.y);
|
|
Assert.number(this.options.limbs[name].x, this.options.limbs[name].y);
|
|
Assert.number(this.options.limbs[name].width, this.options.limbs[name].height);
|
|
|
|
var x = this.options.x + this.options.limbs[name].x,
|
|
y = this.options.y + this.options.limbs[name].y - this.options.height / 2; // position it on top of ground;;
|
|
|
|
var bodyDef = {
|
|
type: 'dynamic',
|
|
position: planck.Vec2(x / Settings.RATIO, y / Settings.RATIO),
|
|
angle: 0,
|
|
linearDamping: Settings.PLAYER_LINEAR_DAMPING
|
|
};
|
|
|
|
var shape = planck.Box(
|
|
this.options.limbs[name].width / 2 / Settings.RATIO,
|
|
this.options.limbs[name].height / 2 / Settings.RATIO,
|
|
planck.Vec2(0, this.options.limbs[name].height / 2 / Settings.RATIO)
|
|
);
|
|
|
|
var fixtureDef = { shape: null, density: 1.0, friction: 0.3, restitution: 0.0, isSensor: false };
|
|
fixtureDef.density = Settings.PLAYER_DENSITY;
|
|
fixtureDef.friction = Settings.PLAYER_FRICTION;
|
|
fixtureDef.restitution = Settings.PLAYER_RESTITUTION;
|
|
fixtureDef.shape = shape;
|
|
fixtureDef.isSensor = false;
|
|
fixtureDef.filter.groupIndex = -this.getId();
|
|
|
|
var limb = this.body.getWorld().createBody(bodyDef);
|
|
limb.createFixture(fixtureDef);
|
|
|
|
this.limbs[name] = limb;
|
|
|
|
var jointDef = new Box2D.Dynamics.Joints.b2RevoluteJointDef();
|
|
jointDef.enableMotor = false;
|
|
|
|
var pos = connectTo.getWorldCenter().clone();
|
|
pos.x += (xOffset / Settings.RATIO);
|
|
pos.y += (yOffset / Settings.RATIO);
|
|
jointDef.initialize(connectTo, limb, pos);
|
|
jointDef.lowerAngle = -0.15 * Box2D.Common.b2Settings.b2_pi; // -45 degrees
|
|
jointDef.upperAngle = 0.15 * Box2D.Common.b2Settings.b2_pi; // 45 degrees
|
|
jointDef.enableLimit = true;
|
|
|
|
this.body.getWorld().createJoint(jointDef);
|
|
};
|
|
|
|
RagDoll.prototype.detachHead = function() {
|
|
var joint = this.limbs.head.GetJointList().joint;
|
|
if(joint) {
|
|
this.body.getWorld().destroyJoint(joint);
|
|
}
|
|
};
|
|
|
|
RagDoll.prototype.reposition = function(handPosition, direction) {
|
|
Assert.number(this.options.limbs.head.x, this.options.limbs.head.y);
|
|
Assert.number(this.options.grabAngle);
|
|
Assert.number(direction);
|
|
|
|
Parent.prototype.reposition.call(this, handPosition, direction);
|
|
|
|
var chestPosition = this.body.GetPosition();
|
|
|
|
var position = planck.Vec2(
|
|
chestPosition.x + this.options.limbs.head.x / Settings.RATIO,
|
|
chestPosition.y + this.options.limbs.head.y / Settings.RATIO
|
|
);
|
|
this.limbs.head.SetPosition(position);
|
|
this.limbs.head.SetAngle((this.options.grabAngle || 0.0) * direction);
|
|
};
|
|
|
|
RagDoll.prototype.throw = function(options, carrierVelocity) {
|
|
Parent.prototype.throw.call(this, options, carrierVelocity);
|
|
|
|
for(var name in this.limbs) {
|
|
var body = this.limbs[name];
|
|
|
|
this.accelerateBody(body, options, carrierVelocity);
|
|
}
|
|
};
|
|
|
|
RagDoll.prototype.setVelocities = function(options) {
|
|
Assert.number(options.linearVelocity.x, options.linearVelocity.y);
|
|
Assert.number(options.angularVelocity);
|
|
|
|
this.body.SetLinearVelocity(options.linearVelocity);
|
|
this.body.setAngularVelocity(options.angularVelocity);
|
|
for(var name in this.limbs) {
|
|
this.limbs[name].SetLinearVelocity(options.linearVelocity);
|
|
}
|
|
};
|
|
|
|
RagDoll.prototype.destroy = function() {
|
|
|
|
var world = this.body.getWorld();
|
|
|
|
for (var name in this.limbs) {
|
|
world.destroyBody(this.limbs[name]);
|
|
}
|
|
|
|
Parent.prototype.destroy.call(this);
|
|
};
|
|
|
|
return RagDoll;
|
|
|
|
}); |