mirror of
https://github.com/logsol/chuck.js.git
synced 2026-05-11 18:47:35 +00:00
- Fix critical bug in PlanckDebugDraw.js where circles were drawn at body center instead of local positions - Add DEBUG_DRAW_SENSORS support with orange styling and no outlines - Fix Chuck's sprite positioning to align with physics body center (pivot adjustments) - Correct fixture Y coordinates so Chuck stands upright instead of on his head - Position foot sensor correctly below legs for proper ground detection - Remove cyan crosses and make yellow center-of-mass crosses smaller - Make debug lines thinner for cleaner visualization
308 lines
No EOL
9.4 KiB
JavaScript
Executable file
308 lines
No EOL
9.4 KiB
JavaScript
Executable file
define([
|
|
"Game/Core/GameObjects/Doll",
|
|
"Game/Config/Settings",
|
|
"Lib/Utilities/NotificationCenter",
|
|
"Lib/Utilities/Exception",
|
|
"Lib/Utilities/ColorConverter",
|
|
"Game/Client/View/Abstract/Layer",
|
|
],
|
|
|
|
function (Parent, Settings, nc, Exception, ColorConverter, Layer) {
|
|
|
|
"use strict";
|
|
|
|
function Doll(physicsEngine, uid, player) {
|
|
this.layerId = Layer.ID.SPAWN;
|
|
this.animationDef = {
|
|
"stand": [1,1],
|
|
"walk": [2,28],
|
|
"walkback": [29,55],
|
|
//"jump": [56,80],
|
|
"jump": [81,91],
|
|
"fall": [81,91],
|
|
"duck": [92,97],
|
|
"standup": [98,103],
|
|
"run": [104,126]
|
|
}
|
|
|
|
this.lastStep = Date.now();
|
|
|
|
this.animatedMeshesContainer = {
|
|
withArms: {},
|
|
withoutArms: {}
|
|
};
|
|
this.animatedMeshes = this.animatedMeshesContainer.withArms;
|
|
this.headMesh = null;
|
|
this.holdingArmMesh = null;
|
|
|
|
var converter = new ColorConverter();
|
|
this.primaryColor = converter.getColorByName(player.getNickname());
|
|
|
|
Parent.call(this, physicsEngine, uid, player);
|
|
}
|
|
|
|
Doll.prototype = Object.create(Parent.prototype);
|
|
|
|
Doll.prototype.setActionState = function(state, force) {
|
|
|
|
if(!force && this.actionState == state) return;
|
|
|
|
if(!state) throw new Exception("action state is undefined");
|
|
|
|
if(this.animatedMeshes[this.actionState]) {
|
|
nc.trigger(
|
|
nc.ns.client.view.mesh.update,
|
|
this.layerId,
|
|
this.animatedMeshesContainer.withArms[this.actionState],
|
|
{ visible: false }
|
|
);
|
|
nc.trigger(
|
|
nc.ns.client.view.mesh.update,
|
|
this.layerId,
|
|
this.animatedMeshesContainer.withoutArms[this.actionState],
|
|
{ visible: false }
|
|
);
|
|
}
|
|
|
|
Parent.prototype.setActionState.call(this, state);
|
|
|
|
nc.trigger(
|
|
nc.ns.client.view.mesh.update,
|
|
this.layerId,
|
|
this.animatedMeshes[this.actionState],
|
|
{
|
|
visible: true,
|
|
xScale: this.lookDirection
|
|
}
|
|
);
|
|
}
|
|
|
|
Doll.prototype.createMesh = function() {
|
|
|
|
var self = this;
|
|
|
|
var setShirtColor = function (mesh) {
|
|
nc.trigger(nc.ns.client.view.mesh.addFilter, self.layerId, mesh, 'colorRangeReplace', {
|
|
minColor: 0x3b4a31,
|
|
maxColor: 0x657f54,
|
|
newColor: self.primaryColor,
|
|
brightnessOffset: 0.56
|
|
});
|
|
}
|
|
|
|
// Body
|
|
|
|
var padF = function(n) {
|
|
if(n<10) return "00" + n;
|
|
if(n<100) return "0" + n;
|
|
return n;
|
|
}
|
|
|
|
var self = this;
|
|
|
|
var arms = ["withArms", "withoutArms"];
|
|
for (var j = 0; j < arms.length; j++) {
|
|
var arm = arms[j];
|
|
for (var key in this.animationDef) {
|
|
var start = this.animationDef[key][0];
|
|
var end = this.animationDef[key][1];
|
|
|
|
var texturePaths = [];
|
|
for (var i = start; i <= end; i++) {
|
|
|
|
/*
|
|
// Multiple File Animations
|
|
texturePaths.push(
|
|
Settings.GRAPHICS_PATH
|
|
+ Settings.GRAPHICS_SUBPATH_CHARACTERS
|
|
+ this.characterName
|
|
+ "/Animation/" + arm.toUpperCaseFirstChar() + "/ChuckAnimations0"
|
|
+ padF(i)
|
|
+ ".png"
|
|
);
|
|
*/
|
|
|
|
// Single File Animations (animation names from chuck_sheet.json, use option fromFrame=true)
|
|
texturePaths.push(
|
|
"Chuck" + arm.toUpperCaseFirstChar() + "0" + padF(i) + ".png"
|
|
);
|
|
}
|
|
|
|
|
|
var callback = function(mesh) {
|
|
self.animatedMeshesContainer[arm][key] = mesh;
|
|
nc.trigger(nc.ns.client.view.mesh.add, self.layerId, mesh);
|
|
|
|
setShirtColor(mesh);
|
|
};
|
|
|
|
nc.trigger(nc.ns.client.view.animatedMesh.create, this.layerId, texturePaths, callback, {
|
|
visible: false,
|
|
pivot: {
|
|
x: 0,
|
|
y: 21 * 4
|
|
},
|
|
xScale: 0.25,
|
|
yScale: 0.25,
|
|
anchor: {
|
|
x: 0.5,
|
|
y: 0
|
|
},
|
|
fromFrame: true
|
|
});
|
|
}
|
|
|
|
};
|
|
|
|
// Head
|
|
|
|
var texturePath = Settings.GRAPHICS_PATH + "Characters/Chuck/head.png";
|
|
var callback = function (mesh) {
|
|
self.headMesh = mesh;
|
|
nc.trigger(nc.ns.client.view.mesh.add, self.layerId, mesh);
|
|
}
|
|
nc.trigger(nc.ns.client.view.mesh.create, this.layerId, texturePath, callback, {
|
|
pivot: {
|
|
x: 5,
|
|
y: 12
|
|
},
|
|
width: 10,
|
|
height: 12,
|
|
anchor: {
|
|
x: 0,
|
|
y: 0
|
|
}
|
|
});
|
|
|
|
// Holding arm
|
|
|
|
texturePath = Settings.GRAPHICS_PATH + "Characters/Chuck/holdingArm.png";
|
|
var callback = function (mesh) {
|
|
self.holdingArmMesh = mesh;
|
|
nc.trigger(nc.ns.client.view.mesh.add, self.layerId, mesh);
|
|
setShirtColor(mesh);
|
|
}
|
|
nc.trigger(nc.ns.client.view.mesh.create, this.layerId, texturePath, callback, {
|
|
visible: false,
|
|
pivot: {
|
|
//x: 35/2 * 4,
|
|
x: 0,
|
|
y: 21 * 4 // Reduced from 40 to 20 to match body pivot
|
|
},
|
|
width: 35,
|
|
height: 40,
|
|
anchor: {
|
|
x: 0.5,
|
|
y: 0
|
|
}
|
|
});
|
|
|
|
}
|
|
|
|
Doll.prototype.lookAt = function(x, y) {
|
|
var oldLookDirection = this.lookDirection;
|
|
|
|
Parent.prototype.lookAt.call(this, x, y);
|
|
|
|
if(oldLookDirection != this.lookDirection) {
|
|
for(var key in this.animatedMeshes) {
|
|
nc.trigger(nc.ns.client.view.mesh.update,
|
|
this.layerId,
|
|
this.animatedMeshes[key],
|
|
{
|
|
xScale: this.lookDirection
|
|
}
|
|
);
|
|
}
|
|
|
|
nc.trigger(nc.ns.client.view.mesh.update,
|
|
this.layerId,
|
|
this.holdingArmMesh,
|
|
{
|
|
xScale: this.lookDirection
|
|
}
|
|
);
|
|
}
|
|
|
|
var angle = Math.atan2(this.lookAtXY.x, this.lookAtXY.y) / 2 - 0.7855 * this.lookDirection; // 0.7855 = 45°
|
|
|
|
nc.trigger(nc.ns.client.view.mesh.update,
|
|
this.layerId,
|
|
this.headMesh,
|
|
{
|
|
xScale: this.lookDirection,
|
|
rotation: angle
|
|
}
|
|
);
|
|
}
|
|
|
|
Doll.prototype.grab = function(item) {
|
|
Parent.prototype.grab.call(this, item);
|
|
this.animatedMeshes = this.animatedMeshesContainer.withoutArms;
|
|
this.setActionState(this.actionState, true);
|
|
nc.trigger(nc.ns.client.view.mesh.update, this.layerId, this.holdingArmMesh, { visible: true });
|
|
};
|
|
|
|
Doll.prototype.throw = function(item, options) {
|
|
Parent.prototype.throw.call(this, item, options);
|
|
this.animatedMeshes = this.animatedMeshesContainer.withArms;
|
|
this.setActionState(this.actionState, true);
|
|
nc.trigger(nc.ns.client.view.mesh.update, this.layerId, this.holdingArmMesh, { visible: false });
|
|
};
|
|
|
|
Doll.prototype.destroy = function () {
|
|
for (var key in this.animatedMeshes) {
|
|
nc.trigger(nc.ns.client.view.mesh.remove, this.layerId, this.animatedMeshes[key]);
|
|
}
|
|
|
|
nc.trigger(nc.ns.client.view.mesh.remove, this.layerId, this.headMesh);
|
|
|
|
Parent.prototype.destroy.call(this);
|
|
}
|
|
|
|
Doll.prototype.render = function() {
|
|
if(this.actionState) {
|
|
|
|
var stepLength = (Date.now() - this.lastStep);
|
|
this.lastStep = Date.now();
|
|
|
|
// compare current framerate to wanted and get factor
|
|
// (stepLength / 60) * 2
|
|
// * 2 to scale to flash fps
|
|
|
|
var factor = stepLength / 30;
|
|
|
|
nc.trigger(nc.ns.client.view.mesh.update,
|
|
this.layerId,
|
|
this.animatedMeshes[this.actionState],
|
|
{
|
|
x: this.body.getPosition().x * Settings.RATIO,
|
|
y: this.body.getPosition().y * Settings.RATIO,
|
|
animationSpeed: factor
|
|
//rotation: this.body.GetAngle()
|
|
}
|
|
);
|
|
|
|
nc.trigger(nc.ns.client.view.mesh.update,
|
|
this.layerId,
|
|
this.headMesh,
|
|
{
|
|
x: this.body.getPosition().x * Settings.RATIO,
|
|
y: this.body.getPosition().y * Settings.RATIO - this.height/2 + this.headHeight +1
|
|
}
|
|
)
|
|
|
|
nc.trigger(nc.ns.client.view.mesh.update,
|
|
this.layerId,
|
|
this.holdingArmMesh,
|
|
{
|
|
x: this.body.getPosition().x * Settings.RATIO,
|
|
y: this.body.getPosition().y * Settings.RATIO
|
|
}
|
|
)
|
|
}
|
|
}
|
|
|
|
return Doll;
|
|
|
|
}); |