mirror of
https://github.com/genxium/DelayNoMore
synced 2025-10-09 00:26:39 +00:00
Initial commit for offline map, might break the online version.
This commit is contained in:
53
frontend/assets/scripts/AttackingCharacter.js
Normal file
53
frontend/assets/scripts/AttackingCharacter.js
Normal file
@@ -0,0 +1,53 @@
|
||||
const BaseCharacter = require("./BaseCharacter");
|
||||
|
||||
window.ATK_CHARACTER_STATE = {
|
||||
Idle1: [0, "Idle1"],
|
||||
Walking: [1, "Walking"],
|
||||
Atk1: [2, "Atk1"],
|
||||
};
|
||||
|
||||
cc.Class({
|
||||
extends: BaseCharacter,
|
||||
properties: {
|
||||
animNode: {
|
||||
type: cc.Node,
|
||||
default: null
|
||||
},
|
||||
},
|
||||
|
||||
ctor() {
|
||||
},
|
||||
|
||||
onLoad() {
|
||||
BaseCharacter.prototype.onLoad.call(this);
|
||||
this.characterState = ATK_CHARACTER_STATE.Idle1[0];
|
||||
this.animComp = this.animNode.getComponent(dragonBones.ArmatureDisplay);
|
||||
this.animComp.playAnimation(ATK_CHARACTER_STATE.Idle1[1]);
|
||||
},
|
||||
|
||||
scheduleNewDirection(newScheduledDirection, forceAnimSwitch) {
|
||||
BaseCharacter.prototype.scheduleNewDirection.call(this, newScheduledDirection, forceAnimSwitch);
|
||||
if (ATK_CHARACTER_STATE.Atk1[0] == this.characterState) {
|
||||
return;
|
||||
}
|
||||
|
||||
let newCharacterState = ATK_CHARACTER_STATE.Idle1[0];
|
||||
if (0 != newScheduledDirection.dx || 0 != newScheduledDirection.dy) {
|
||||
newCharacterState = ATK_CHARACTER_STATE.Walking[0];
|
||||
}
|
||||
|
||||
if (newCharacterState != this.characterState) {
|
||||
switch (newCharacterState) {
|
||||
case ATK_CHARACTER_STATE.Idle1[0]:
|
||||
this.animComp.playAnimation(ATK_CHARACTER_STATE.Idle1[1]);
|
||||
break;
|
||||
case ATK_CHARACTER_STATE.Walking[0]:
|
||||
this.animComp.playAnimation(ATK_CHARACTER_STATE.Walking[1]);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
this.characterState = newCharacterState;
|
||||
}
|
||||
},
|
||||
});
|
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"ver": "1.0.5",
|
||||
"uuid": "17759956-1f8c-421f-bac2-7f4dd7ccdcda",
|
||||
"uuid": "0b29c37b-2ac0-47be-ae68-b7b9a4b2dffb",
|
||||
"isPlugin": false,
|
||||
"loadPluginInWeb": true,
|
||||
"loadPluginInNative": true,
|
@@ -2,10 +2,6 @@ module.export = cc.Class({
|
||||
extends: cc.Component,
|
||||
|
||||
properties: {
|
||||
animComp: {
|
||||
type: cc.Animation,
|
||||
default: null,
|
||||
},
|
||||
lastMovedAt: {
|
||||
type: cc.Float,
|
||||
default: 0 // In "GMT milliseconds"
|
||||
@@ -21,24 +17,14 @@ module.export = cc.Class({
|
||||
};
|
||||
},
|
||||
|
||||
ctor() {},
|
||||
|
||||
onLoad() {
|
||||
const self = this;
|
||||
self.clips = {
|
||||
'02': 'Top',
|
||||
'0-2': 'Bottom',
|
||||
'-20': 'Left',
|
||||
'20': 'Right',
|
||||
'-11': 'TopLeft',
|
||||
'11': 'TopRight',
|
||||
'-1-1': 'BottomLeft',
|
||||
'1-1': 'BottomRight'
|
||||
};
|
||||
const canvasNode = self.mapNode.parent;
|
||||
self.mapIns = self.mapNode.getComponent("Map");
|
||||
const joystickInputControllerScriptIns = canvasNode.getComponent("TouchEventsManager");
|
||||
self.ctrl = joystickInputControllerScriptIns;
|
||||
self.animComp = self.node.getComponent(cc.Animation);
|
||||
self.animComp.play();
|
||||
},
|
||||
|
||||
scheduleNewDirection(newScheduledDirection, forceAnimSwitch) {
|
||||
@@ -48,19 +34,11 @@ module.export = cc.Class({
|
||||
|
||||
if (forceAnimSwitch || null == this.activeDirection || (newScheduledDirection.dx != this.activeDirection.dx || newScheduledDirection.dy != this.activeDirection.dy)) {
|
||||
this.activeDirection = newScheduledDirection;
|
||||
this.activeDirection = newScheduledDirection;
|
||||
const clipKey = newScheduledDirection.dx.toString() + newScheduledDirection.dy.toString();
|
||||
const clips = (this.attacked ? this.attackedClips : this.clips);
|
||||
let clip = clips[clipKey];
|
||||
if (!clip) {
|
||||
// Keep playing the current anim.
|
||||
if (0 !== newScheduledDirection.dx || 0 !== newScheduledDirection.dy) {
|
||||
cc.warn('Clip for clipKey === ' + clipKey + ' is invalid: ' + clip + '.');
|
||||
}
|
||||
} else {
|
||||
this.animComp.play(clip);
|
||||
if (this.attacked) {
|
||||
cc.log(`Attacked, switching to play clipKey = ${clipKey}, clip == ${clip}, this.activeDirection == ${JSON.stringify(this.activeDirection)}, this.activeDirection == ${JSON.stringify(this.activeDirection)}.`);
|
||||
if (this.animComp && this.animComp.node) {
|
||||
if (0 > newScheduledDirection.dx) {
|
||||
this.animComp.node.scaleX = (-1.0);
|
||||
} else if (0 < newScheduledDirection.dx) {
|
||||
this.animComp.node.scaleX = (1.0);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -84,13 +62,4 @@ module.export = cc.Class({
|
||||
this.speed = proposedSpeed;
|
||||
},
|
||||
|
||||
startFrozenDisplay() {
|
||||
const self = this;
|
||||
self.attacked = true;
|
||||
},
|
||||
|
||||
stopFrozenDisplay() {
|
||||
const self = this;
|
||||
self.attacked = false;
|
||||
},
|
||||
});
|
@@ -1,201 +0,0 @@
|
||||
module.export = cc.Class({
|
||||
extends: cc.Component,
|
||||
|
||||
properties: {
|
||||
localIdInBattle: {
|
||||
default: null,
|
||||
},
|
||||
linearSpeed: {
|
||||
default: 0.0,
|
||||
},
|
||||
},
|
||||
|
||||
ctor() {
|
||||
this.ctrl = null;
|
||||
this.activeDirection = null;
|
||||
},
|
||||
|
||||
onLoad() {
|
||||
},
|
||||
|
||||
_calculateVecToMoveByWithChosenDir(elapsedTime, sDir) {
|
||||
if (0 == sDir.dx && 0 == sDir.dy) {
|
||||
return cc.v2();
|
||||
}
|
||||
const self = this;
|
||||
const distanceToMove = (self.linearSpeed * elapsedTime);
|
||||
const denominator = Math.sqrt(sDir.dx * sDir.dx + sDir.dy * sDir.dy);
|
||||
const unitProjDx = (sDir.dx / denominator);
|
||||
const unitProjDy = (sDir.dy / denominator);
|
||||
return cc.v2(
|
||||
distanceToMove * unitProjDx,
|
||||
distanceToMove * unitProjDy,
|
||||
);
|
||||
},
|
||||
|
||||
_calculateVecToMoveBy(elapsedTime) {
|
||||
const self = this;
|
||||
if (null == self.activeDirection) {
|
||||
return null;
|
||||
}
|
||||
// Note that `sDir` used in this method MUST BE a copy in RAM.
|
||||
let sDir = {
|
||||
dx: self.activeDirection.dx,
|
||||
dy: self.activeDirection.dy,
|
||||
};
|
||||
|
||||
if (0 == sDir.dx && 0 == sDir.dy) {
|
||||
return cc.v2();
|
||||
}
|
||||
|
||||
return self._calculateVecToMoveByWithChosenDir(elapsedTime, sDir);
|
||||
},
|
||||
|
||||
_canMoveBy(vecToMoveBy) {
|
||||
return true;
|
||||
},
|
||||
|
||||
update(dt) {
|
||||
// Used only for EXTRAPOLATING the position of this bullet. The position might be corrected within `setData` as well.
|
||||
const self = this;
|
||||
if (null != self.bulletMaxDist) {
|
||||
const dxMoved = self.node.position.x - self.startAtPoint.x;
|
||||
const dyMoved = self.node.position.y - self.startAtPoint.y;
|
||||
const distanceMoved = Math.sqrt(dxMoved * dxMoved + dyMoved * dyMoved)
|
||||
self.node.opacity = 255*(1 - distanceMoved/self.bulletMaxDist);
|
||||
}
|
||||
|
||||
const vecToMoveBy = self._calculateVecToMoveBy(dt);
|
||||
if (null == vecToMoveBy) {
|
||||
return;
|
||||
}
|
||||
if (self._canMoveBy(vecToMoveBy)) {
|
||||
self.node.position = self.node.position.add(vecToMoveBy);
|
||||
}
|
||||
},
|
||||
|
||||
_calculateAngle(dx, dy) {
|
||||
if (dx == 0) {
|
||||
if (dy > 0) {
|
||||
return 90;
|
||||
}
|
||||
if (dy < 0) {
|
||||
return -90;
|
||||
}
|
||||
}
|
||||
|
||||
if (dx > 0) {
|
||||
if (dy == 0) {
|
||||
return 0;
|
||||
}
|
||||
if (dy > 0) {
|
||||
return 45;
|
||||
}
|
||||
if (dy < 0) {
|
||||
return -45;
|
||||
}
|
||||
}
|
||||
|
||||
if (dx < 0) {
|
||||
if (dy == 0) {
|
||||
return 180;
|
||||
}
|
||||
if (dy > 0) {
|
||||
return 135;
|
||||
}
|
||||
if (dy < 0) {
|
||||
return -135;
|
||||
}
|
||||
}
|
||||
|
||||
return null;
|
||||
},
|
||||
|
||||
setData(bulletLocalIdInBattle, bulletInfo, dtFromMapUpdate) {
|
||||
const targetNode = this.node;
|
||||
|
||||
if (true == bulletInfo.removed) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (null == bulletInfo.startAtPoint || null == bulletInfo.endAtPoint) {
|
||||
console.error(`Init bullet direction error, startAtPoint:${bulletInfo.startAtPoint}, endAtPoint:${bulletInfo.endAtPoint}`);
|
||||
return false;
|
||||
}
|
||||
|
||||
this.localIdInBattle = bulletLocalIdInBattle;
|
||||
this.linearSpeed = bulletInfo.linearSpeed * 1000000000; // The `bullet.LinearSpeed` on server-side is denoted in pts/nanoseconds.
|
||||
|
||||
const dx = bulletInfo.endAtPoint.x - bulletInfo.startAtPoint.x;
|
||||
const dy = bulletInfo.endAtPoint.y - bulletInfo.startAtPoint.y;
|
||||
|
||||
const discretizedDir = this.ctrl.discretizeDirection(dx, dy, this.ctrl.joyStickEps);
|
||||
const baseAngle = 0;
|
||||
const angleToRotate = baseAngle - this._calculateAngle(discretizedDir.dx, discretizedDir.dy);
|
||||
if (null == angleToRotate) {
|
||||
return false;
|
||||
}
|
||||
set2dRotation(targetNode, angleToRotate);
|
||||
|
||||
const newPos = cc.v2(
|
||||
bulletInfo.x,
|
||||
bulletInfo.y
|
||||
);
|
||||
|
||||
if (null == this.activeDirection) {
|
||||
// Initialization.
|
||||
this.startAtPoint = bulletInfo.startAtPoint;
|
||||
this.endAtPoint = bulletInfo.endAtPoint;
|
||||
this.bulletMaxDist = 600.0; // Hardcoded temporarily, matching that in "<backend>/models/room.go". -- YFLu, 2019-09-05.
|
||||
targetNode.setPosition(newPos);
|
||||
this.activeDirection = {
|
||||
dx: 0,
|
||||
dy: 0,
|
||||
};
|
||||
return true;
|
||||
}
|
||||
|
||||
const oldPos = cc.v2(
|
||||
targetNode.x,
|
||||
targetNode.y,
|
||||
);
|
||||
const toMoveByVec = newPos.sub(oldPos);
|
||||
const toMoveByVecMag = toMoveByVec.mag();
|
||||
const toTeleportDisThreshold = (this.linearSpeed * dtFromMapUpdate * 100);
|
||||
const notToMoveDisThreshold = (this.linearSpeed * dtFromMapUpdate * 0.5);
|
||||
if (toMoveByVecMag < notToMoveDisThreshold) {
|
||||
// To stop extrapolated moving.
|
||||
this.activeDirection = {
|
||||
dx: 0,
|
||||
dy: 0,
|
||||
};
|
||||
} else {
|
||||
if (toMoveByVecMag > toTeleportDisThreshold) {
|
||||
console.log("Bullet ", bulletLocalIdInBattle, " is teleporting! Having toMoveByVecMag == ", toMoveByVecMag, ", toTeleportDisThreshold == ", toTeleportDisThreshold);
|
||||
// To stop extrapolated moving.
|
||||
this.activeDirection = {
|
||||
dx: 0,
|
||||
dy: 0
|
||||
};
|
||||
// Deliberately NOT using `cc.Action`. -- YFLu, 2019-09-04
|
||||
targetNode.setPosition(newPos);
|
||||
} else {
|
||||
// The common case which is suitable for interpolation.
|
||||
const normalizedDir = {
|
||||
dx: toMoveByVec.x / toMoveByVecMag,
|
||||
dy: toMoveByVec.y / toMoveByVecMag,
|
||||
};
|
||||
if (isNaN(normalizedDir.dx) || isNaN(normalizedDir.dy)) {
|
||||
this.activeDirection = {
|
||||
dx: 0,
|
||||
dy: 0,
|
||||
};
|
||||
} else {
|
||||
this.activeDirection = normalizedDir;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
},
|
||||
});
|
@@ -1,9 +0,0 @@
|
||||
{
|
||||
"ver": "1.0.5",
|
||||
"uuid": "ea965d25-ec82-478c-bdb2-9ac07981ab0e",
|
||||
"isPlugin": false,
|
||||
"loadPluginInWeb": true,
|
||||
"loadPluginInNative": true,
|
||||
"loadPluginInEditor": false,
|
||||
"subMetas": {}
|
||||
}
|
@@ -1,8 +1,7 @@
|
||||
const BasePlayer = require("./BasePlayer");
|
||||
const AttackingCharacter = require("./AttackingCharacter");
|
||||
|
||||
cc.Class({
|
||||
extends: BasePlayer,
|
||||
// LIFE-CYCLE CALLBACKS:
|
||||
extends: AttackingCharacter,
|
||||
properties: {
|
||||
arrowTipNode: {
|
||||
type: cc.Node,
|
||||
@@ -14,21 +13,11 @@ cc.Class({
|
||||
}
|
||||
},
|
||||
start() {
|
||||
BasePlayer.prototype.start.call(this);
|
||||
AttackingCharacter.prototype.start.call(this);
|
||||
},
|
||||
|
||||
onLoad() {
|
||||
BasePlayer.prototype.onLoad.call(this);
|
||||
this.attackedClips = {
|
||||
'01': 'attackedLeft',
|
||||
'0-1': 'attackedRight',
|
||||
'-20': 'attackedLeft',
|
||||
'20': 'attackedRight',
|
||||
'-21': 'attackedLeft',
|
||||
'21': 'attackedRight',
|
||||
'-2-1': 'attackedLeft',
|
||||
'2-1': 'attackedRight'
|
||||
};
|
||||
AttackingCharacter.prototype.onLoad.call(this);
|
||||
this.arrowTipNode.active = false;
|
||||
|
||||
if (!this.mapIns.showCriticalCoordinateLabels) {
|
||||
@@ -51,7 +40,7 @@ cc.Class({
|
||||
},
|
||||
|
||||
update(dt) {
|
||||
BasePlayer.prototype.update.call(this, dt);
|
||||
AttackingCharacter.prototype.update.call(this, dt);
|
||||
if (this.mapIns.showCriticalCoordinateLabels) {
|
||||
this.coordLabel.string = `(${this.node.x.toFixed(2)}, ${this.node.y.toFixed(2)})`;
|
||||
}
|
@@ -40,6 +40,10 @@ cc.Class({
|
||||
type: cc.Node,
|
||||
default: null,
|
||||
},
|
||||
controlledCharacterPrefab: {
|
||||
type: cc.Prefab,
|
||||
default: null,
|
||||
},
|
||||
player1Prefab: {
|
||||
type: cc.Prefab,
|
||||
default: null,
|
||||
@@ -91,10 +95,6 @@ cc.Class({
|
||||
forceBigEndianFloatingNumDecoding: {
|
||||
default: false,
|
||||
},
|
||||
backgroundMapTiledIns: {
|
||||
type: cc.TiledMap,
|
||||
default: null
|
||||
},
|
||||
renderFrameIdLagTolerance: {
|
||||
type: cc.Integer,
|
||||
default: 4 // implies (renderFrameIdLagTolerance >> inputScaleFrames) count of inputFrameIds
|
||||
@@ -292,8 +292,6 @@ cc.Class({
|
||||
const self = this;
|
||||
const mapNode = self.node;
|
||||
const canvasNode = mapNode.parent;
|
||||
self.countdownLabel.string = "";
|
||||
self.countdownNanos = null;
|
||||
|
||||
// Clearing previous info of all players. [BEGINS]
|
||||
self.collisionPlayerIndexPrefix = (1 << 17); // For tracking the movements of players
|
||||
@@ -327,12 +325,20 @@ cc.Class({
|
||||
|
||||
self.battleState = ALL_BATTLE_STATES.WAITING;
|
||||
|
||||
if (self.countdownLabel) {
|
||||
self.countdownLabel.string = "";
|
||||
}
|
||||
self.countdownNanos = null;
|
||||
if (self.findingPlayerNode) {
|
||||
const findingPlayerScriptIns = self.findingPlayerNode.getComponent("FindingPlayer");
|
||||
findingPlayerScriptIns.init();
|
||||
}
|
||||
safelyAddChild(self.widgetsAboveAllNode, self.playersInfoNode);
|
||||
safelyAddChild(self.widgetsAboveAllNode, self.findingPlayerNode);
|
||||
if (self.playersInfoNode) {
|
||||
safelyAddChild(self.widgetsAboveAllNode, self.playersInfoNode);
|
||||
}
|
||||
if (self.findingPlayerNode) {
|
||||
safelyAddChild(self.widgetsAboveAllNode, self.findingPlayerNode);
|
||||
}
|
||||
},
|
||||
|
||||
onLoad() {
|
||||
@@ -463,8 +469,10 @@ cc.Class({
|
||||
for (let boundaryObj of boundaryObjs.barriers) {
|
||||
const x0 = boundaryObj.anchor.x,
|
||||
y0 = boundaryObj.anchor.y;
|
||||
|
||||
const newBarrier = self.collisionSys.createPolygon(x0, y0, Array.from(boundaryObj, p => { return [p.x, p.y]; }));
|
||||
|
||||
const newBarrier = self.collisionSys.createPolygon(x0, y0, Array.from(boundaryObj, p => {
|
||||
return [p.x, p.y];
|
||||
}));
|
||||
|
||||
if (self.showCriticalCoordinateLabels) {
|
||||
for (let i = 0; i < boundaryObj.length; ++i) {
|
||||
@@ -488,7 +496,7 @@ cc.Class({
|
||||
barrierVertLabelNode.setPosition(cc.v2(wx, wy));
|
||||
const barrierVertLabel = barrierVertLabelNode.addComponent(cc.Label);
|
||||
barrierVertLabel.fontSize = 12;
|
||||
barrierVertLabel.lineHeight = barrierVertLabel.fontSize+1;
|
||||
barrierVertLabel.lineHeight = barrierVertLabel.fontSize + 1;
|
||||
barrierVertLabel.string = `(${wx.toFixed(1)}, ${wy.toFixed(1)})`;
|
||||
safelyAddChild(self.node, barrierVertLabelNode);
|
||||
setLocalZOrder(barrierVertLabelNode, 5);
|
||||
@@ -608,10 +616,12 @@ cc.Class({
|
||||
self._initPlayerRichInfoDict(players, playerMetas);
|
||||
|
||||
// Show the top status indicators for IN_BATTLE
|
||||
const playersInfoScriptIns = self.playersInfoNode.getComponent("PlayersInfo");
|
||||
for (let i in playerMetas) {
|
||||
const playerMeta = playerMetas[i];
|
||||
playersInfoScriptIns.updateData(playerMeta);
|
||||
if (self.playersInfoNode) {
|
||||
const playersInfoScriptIns = self.playersInfoNode.getComponent("PlayersInfo");
|
||||
for (let i in playerMetas) {
|
||||
const playerMeta = playerMetas[i];
|
||||
playersInfoScriptIns.updateData(playerMeta);
|
||||
}
|
||||
}
|
||||
|
||||
self.renderFrameId = rdf.id;
|
||||
@@ -629,7 +639,7 @@ cc.Class({
|
||||
const canvasNode = self.canvasNode;
|
||||
self.ctrl = canvasNode.getComponent("TouchEventsManager");
|
||||
self.enableInputControls();
|
||||
if (self.countdownToBeginGameNode.parent) {
|
||||
if (self.countdownToBeginGameNode && self.countdownToBeginGameNode.parent) {
|
||||
self.countdownToBeginGameNode.parent.removeChild(self.countdownToBeginGameNode);
|
||||
}
|
||||
self.transitToState(ALL_MAP_STATES.VISUAL);
|
||||
@@ -751,10 +761,11 @@ cc.Class({
|
||||
spawnPlayerNode(joinIndex, vx, vy, playerRichInfo) {
|
||||
const self = this;
|
||||
const newPlayerNode = 1 == joinIndex ? cc.instantiate(self.player1Prefab) : cc.instantiate(self.player2Prefab); // hardcoded for now, car color determined solely by joinIndex
|
||||
const playerScriptIns = newPlayerNode.getComponent("ControlledCharacter");
|
||||
const wpos = self.virtualGridToWorldPos(vx, vy);
|
||||
|
||||
newPlayerNode.setPosition(cc.v2(wpos[0], wpos[1]));
|
||||
newPlayerNode.getComponent("SelfPlayer").mapNode = self.node;
|
||||
playerScriptIns.mapNode = self.node;
|
||||
const cpos = self.virtualGridToPlayerColliderPos(vx, vy, playerRichInfo);
|
||||
const d = playerRichInfo.colliderRadius * 2,
|
||||
x0 = cpos[0],
|
||||
@@ -769,7 +780,6 @@ cc.Class({
|
||||
setLocalZOrder(newPlayerNode, 5);
|
||||
|
||||
newPlayerNode.active = true;
|
||||
const playerScriptIns = newPlayerNode.getComponent("SelfPlayer");
|
||||
playerScriptIns.scheduleNewDirection({
|
||||
dx: playerRichInfo.dir.dx,
|
||||
dy: playerRichInfo.dir.dy
|
||||
@@ -933,23 +943,29 @@ cc.Class({
|
||||
self._initPlayerRichInfoDict(players, playerMetas);
|
||||
|
||||
// Show the top status indicators for IN_BATTLE
|
||||
const playersInfoScriptIns = self.playersInfoNode.getComponent("PlayersInfo");
|
||||
for (let i in playerMetas) {
|
||||
const playerMeta = playerMetas[i];
|
||||
playersInfoScriptIns.updateData(playerMeta);
|
||||
if (self.playersInfoNode) {
|
||||
const playersInfoScriptIns = self.playersInfoNode.getComponent("PlayersInfo");
|
||||
for (let i in playerMetas) {
|
||||
const playerMeta = playerMetas[i];
|
||||
playersInfoScriptIns.updateData(playerMeta);
|
||||
}
|
||||
}
|
||||
console.log("Calling `onBattleReadyToStart` with:", playerMetas);
|
||||
const findingPlayerScriptIns = self.findingPlayerNode.getComponent("FindingPlayer");
|
||||
findingPlayerScriptIns.hideExitButton();
|
||||
findingPlayerScriptIns.updatePlayersInfo(playerMetas);
|
||||
if (self.findingPlayerNode) {
|
||||
const findingPlayerScriptIns = self.findingPlayerNode.getComponent("FindingPlayer");
|
||||
findingPlayerScriptIns.hideExitButton();
|
||||
findingPlayerScriptIns.updatePlayersInfo(playerMetas);
|
||||
}
|
||||
|
||||
// Delay to hide the "finding player" GUI, then show a countdown clock
|
||||
window.setTimeout(() => {
|
||||
self.hideFindingPlayersGUI();
|
||||
const countDownScriptIns = self.countdownToBeginGameNode.getComponent("CountdownToBeginGame");
|
||||
countDownScriptIns.setData();
|
||||
self.showPopupInCanvas(self.countdownToBeginGameNode);
|
||||
}, 1500);
|
||||
if (self.countdownToBeginGameNode) {
|
||||
window.setTimeout(() => {
|
||||
self.hideFindingPlayersGUI();
|
||||
const countDownScriptIns = self.countdownToBeginGameNode.getComponent("CountdownToBeginGame");
|
||||
countDownScriptIns.setData();
|
||||
self.showPopupInCanvas(self.countdownToBeginGameNode);
|
||||
}, 1500);
|
||||
}
|
||||
},
|
||||
|
||||
applyRoomDownsyncFrameDynamics(rdf) {
|
||||
|
@@ -1,326 +0,0 @@
|
||||
const COLLISION_WITH_PLAYER_STATE = {
|
||||
WALKING_COLLIDABLE: 0,
|
||||
STILL_NEAR_SELF_PLAYER_ONLY_PLAYING_ANIM: 1,
|
||||
STILL_NEAR_SELF_PLAYER_ONLY_PLAYED_ANIM: 2,
|
||||
STILL_NEAR_OTHER_PLAYER_ONLY_PLAYING_ANIM: 3,
|
||||
STILL_NEAR_OTHER_PLAYER_ONLY_PLAYED_ANIM: 4,
|
||||
STILL_NEAR_SELF_PLAYER_NEAR_OTHER_PLAYER_PLAYING_ANIM: 5,
|
||||
STILL_NEAR_SELF_PLAYER_NEAR_OTHER_PLAYER_PLAYED_ANIM: 6,
|
||||
WALKING_COLLIDABLE_WITH_SELF_PLAYER_BUT_NOT_OTHER_PLAYER: 7,
|
||||
STILL_NEAR_NOBODY_PLAYING_ANIM: 8,
|
||||
};
|
||||
|
||||
const STILL_NEAR_SELF_PLAYER_STATE_SET = new Set();
|
||||
STILL_NEAR_SELF_PLAYER_STATE_SET.add(COLLISION_WITH_PLAYER_STATE.STILL_NEAR_SELF_PLAYER_ONLY_PLAYING_ANIM);
|
||||
STILL_NEAR_SELF_PLAYER_STATE_SET.add(COLLISION_WITH_PLAYER_STATE.STILL_NEAR_SELF_PLAYER_ONLY_PLAYED_ANIM);
|
||||
STILL_NEAR_SELF_PLAYER_STATE_SET.add(COLLISION_WITH_PLAYER_STATE.STILL_NEAR_SELF_PLAYER_NEAR_OTHER_PLAYER_PLAYING_ANIM);
|
||||
STILL_NEAR_SELF_PLAYER_STATE_SET.add(COLLISION_WITH_PLAYER_STATE.STILL_NEAR_SELF_PLAYER_NEAR_OTHER_PLAYER_PLAYED_ANIM);
|
||||
|
||||
const STILL_NEAR_OTHER_PLAYER_STATE_SET = new Set();
|
||||
STILL_NEAR_OTHER_PLAYER_STATE_SET.add(COLLISION_WITH_PLAYER_STATE.STILL_NEAR_OTHER_PLAYER_ONLY_PLAYING_ANIM);
|
||||
STILL_NEAR_OTHER_PLAYER_STATE_SET.add(COLLISION_WITH_PLAYER_STATE.STILL_NEAR_OTHER_PLAYER_ONLY_PLAYED_ANIM);
|
||||
STILL_NEAR_OTHER_PLAYER_STATE_SET.add(COLLISION_WITH_PLAYER_STATE.STILL_NEAR_SELF_PLAYER_NEAR_OTHER_PLAYER_PLAYING_ANIM);
|
||||
STILL_NEAR_OTHER_PLAYER_STATE_SET.add(COLLISION_WITH_PLAYER_STATE.STILL_NEAR_SELF_PLAYER_NEAR_OTHER_PLAYER_PLAYED_ANIM);
|
||||
|
||||
const STILL_SHOULD_NOT_PLAY_STUNNED_ANIM_SET = new Set();
|
||||
STILL_SHOULD_NOT_PLAY_STUNNED_ANIM_SET.add(COLLISION_WITH_PLAYER_STATE.STILL_NEAR_SELF_PLAYER_ONLY_PLAYING_ANIM);
|
||||
STILL_SHOULD_NOT_PLAY_STUNNED_ANIM_SET.add(COLLISION_WITH_PLAYER_STATE.STILL_NEAR_SELF_PLAYER_ONLY_PLAYED_ANIM);
|
||||
STILL_SHOULD_NOT_PLAY_STUNNED_ANIM_SET.add(COLLISION_WITH_PLAYER_STATE.STILL_NEAR_OTHER_PLAYER_ONLY_PLAYING_ANIM);
|
||||
STILL_SHOULD_NOT_PLAY_STUNNED_ANIM_SET.add(COLLISION_WITH_PLAYER_STATE.STILL_NEAR_OTHER_PLAYER_ONLY_PLAYED_ANIM);
|
||||
STILL_SHOULD_NOT_PLAY_STUNNED_ANIM_SET.add(COLLISION_WITH_PLAYER_STATE.STILL_NEAR_SELF_PLAYER_NEAR_OTHER_PLAYER_PLAYING_ANIM);
|
||||
STILL_SHOULD_NOT_PLAY_STUNNED_ANIM_SET.add(COLLISION_WITH_PLAYER_STATE.STILL_NEAR_SELF_PLAYER_NEAR_OTHER_PLAYER_PLAYED_ANIM);
|
||||
STILL_SHOULD_NOT_PLAY_STUNNED_ANIM_SET.add(COLLISION_WITH_PLAYER_STATE.STILL_NEAR_NOBODY_PLAYING_ANIM);
|
||||
|
||||
function transitWalkingConditionallyCollidableToUnconditionallyCollidable(currentCollisionWithPlayerState) {
|
||||
switch (currentCollisionWithPlayerState) {
|
||||
case COLLISION_WITH_PLAYER_STATE.WALKING_COLLIDABLE_WITH_SELF_PLAYER_BUT_NOT_OTHER_PLAYER:
|
||||
return COLLISION_WITH_PLAYER_STATE.WALKING_COLLIDABLE;
|
||||
}
|
||||
|
||||
return currentCollisionWithPlayerState;
|
||||
}
|
||||
|
||||
function transitUponSelfPlayerLeftProximityArea(currentCollisionWithPlayerState) {
|
||||
switch (currentCollisionWithPlayerState) {
|
||||
case COLLISION_WITH_PLAYER_STATE.STILL_NEAR_SELF_PLAYER_ONLY_PLAYING_ANIM:
|
||||
return COLLISION_WITH_PLAYER_STATE.STILL_NEAR_NOBODY_PLAYING_ANIM;
|
||||
|
||||
case COLLISION_WITH_PLAYER_STATE.STILL_NEAR_SELF_PLAYER_ONLY_PLAYED_ANIM:
|
||||
return COLLISION_WITH_PLAYER_STATE.WALKING_COLLIDABLE;
|
||||
|
||||
case COLLISION_WITH_PLAYER_STATE.STILL_NEAR_SELF_PLAYER_NEAR_OTHER_PLAYER_PLAYING_ANIM:
|
||||
return COLLISION_WITH_PLAYER_STATE.STILL_NEAR_OTHER_PLAYER_ONLY_PLAYING_ANIM;
|
||||
|
||||
case COLLISION_WITH_PLAYER_STATE.STILL_NEAR_SELF_PLAYER_NEAR_OTHER_PLAYER_PLAYED_ANIM:
|
||||
return COLLISION_WITH_PLAYER_STATE.WALKING_COLLIDABLE_WITH_SELF_PLAYER_BUT_NOT_OTHER_PLAYER;
|
||||
}
|
||||
return currentCollisionWithPlayerState;
|
||||
}
|
||||
|
||||
function transitDueToNoBodyInProximityArea(currentCollisionWithPlayerState) {
|
||||
switch (currentCollisionWithPlayerState) {
|
||||
case COLLISION_WITH_PLAYER_STATE.STILL_NEAR_SELF_PLAYER_ONLY_PLAYING_ANIM:
|
||||
case COLLISION_WITH_PLAYER_STATE.STILL_NEAR_OTHER_PLAYER_ONLY_PLAYING_ANIM:
|
||||
case COLLISION_WITH_PLAYER_STATE.STILL_NEAR_SELF_PLAYER_NEAR_OTHER_PLAYER_PLAYING_ANIM:
|
||||
return COLLISION_WITH_PLAYER_STATE.STILL_NEAR_NOBODY_PLAYING_ANIM;
|
||||
|
||||
case COLLISION_WITH_PLAYER_STATE.STILL_NEAR_SELF_PLAYER_ONLY_PLAYED_ANIM:
|
||||
case COLLISION_WITH_PLAYER_STATE.STILL_NEAR_OTHER_PLAYER_ONLY_PLAYED_ANIM:
|
||||
case COLLISION_WITH_PLAYER_STATE.STILL_NEAR_SELF_PLAYER_NEAR_OTHER_PLAYER_PLAYED_ANIM:
|
||||
return COLLISION_WITH_PLAYER_STATE.WALKING_COLLIDABLE_WITH_SELF_PLAYER_BUT_NOT_OTHER_PLAYER;
|
||||
}
|
||||
return currentCollisionWithPlayerState;
|
||||
}
|
||||
|
||||
function transitToPlayingStunnedAnim(currentCollisionWithPlayerState, dueToSelfPlayer, dueToOtherPlayer) {
|
||||
if (dueToSelfPlayer) {
|
||||
switch (currentCollisionWithPlayerState) {
|
||||
case COLLISION_WITH_PLAYER_STATE.WALKING_COLLIDABLE:
|
||||
case COLLISION_WITH_PLAYER_STATE.WALKING_COLLIDABLE_WITH_SELF_PLAYER_BUT_NOT_OTHER_PLAYER:
|
||||
return COLLISION_WITH_PLAYER_STATE.STILL_NEAR_SELF_PLAYER_ONLY_PLAYING_ANIM;
|
||||
}
|
||||
}
|
||||
|
||||
if (dueToOtherPlayer) {
|
||||
switch (currentCollisionWithPlayerState) {
|
||||
case COLLISION_WITH_PLAYER_STATE.WALKING_COLLIDABLE:
|
||||
return COLLISION_WITH_PLAYER_STATE.STILL_NEAR_OTHER_PLAYER_ONLY_PLAYING_ANIM;
|
||||
}
|
||||
}
|
||||
// TODO: Any error to throw?
|
||||
return currentCollisionWithPlayerState;
|
||||
}
|
||||
|
||||
function transitDuringPlayingStunnedAnim(currentCollisionWithPlayerState, dueToSelfPlayerComesIntoProximity, dueToOtherPlayerComesIntoProximity) {
|
||||
if (dueToSelfPlayerComesIntoProximity) {
|
||||
switch (currentCollisionWithPlayerState) {
|
||||
case COLLISION_WITH_PLAYER_STATE.STILL_NEAR_OTHER_PLAYER_ONLY_PLAYING_ANIM:
|
||||
return COLLISION_WITH_PLAYER_STATE.STILL_NEAR_SELF_PLAYER_NEAR_OTHER_PLAYER_PLAYING_ANIM;
|
||||
|
||||
case COLLISION_WITH_PLAYER_STATE.STILL_NEAR_NOBODY_PLAYING_ANIM:
|
||||
return COLLISION_WITH_PLAYER_STATE.STILL_NEAR_SELF_PLAYER_ONLY_PLAYING_ANIM;
|
||||
}
|
||||
}
|
||||
|
||||
if (dueToOtherPlayerComesIntoProximity) {
|
||||
switch (currentCollisionWithPlayerState) {
|
||||
case COLLISION_WITH_PLAYER_STATE.STILL_NEAR_SELF_PLAYER_ONLY_PLAYING_ANIM:
|
||||
return COLLISION_WITH_PLAYER_STATE.STILL_NEAR_SELF_PLAYER_NEAR_OTHER_PLAYER_PLAYING_ANIM;
|
||||
|
||||
case COLLISION_WITH_PLAYER_STATE.STILL_NEAR_NOBODY_PLAYING_ANIM:
|
||||
return COLLISION_WITH_PLAYER_STATE.STILL_NEAR_OTHER_PLAYER_ONLY_PLAYING_ANIM;
|
||||
}
|
||||
}
|
||||
// TODO: Any error to throw?
|
||||
return currentCollisionWithPlayerState;
|
||||
}
|
||||
|
||||
function transitStunnedAnimPlayingToPlayed(currentCollisionWithPlayerState, forceNotCollidableWithOtherPlayer) {
|
||||
switch (currentCollisionWithPlayerState) {
|
||||
case COLLISION_WITH_PLAYER_STATE.STILL_NEAR_SELF_PLAYER_ONLY_PLAYING_ANIM:
|
||||
return COLLISION_WITH_PLAYER_STATE.STILL_NEAR_SELF_PLAYER_ONLY_PLAYED_ANIM;
|
||||
|
||||
case COLLISION_WITH_PLAYER_STATE.STILL_NEAR_OTHER_PLAYER_ONLY_PLAYING_ANIM:
|
||||
return COLLISION_WITH_PLAYER_STATE.STILL_NEAR_OTHER_PLAYER_ONLY_PLAYED_ANIM;
|
||||
|
||||
case COLLISION_WITH_PLAYER_STATE.STILL_NEAR_SELF_PLAYER_NEAR_OTHER_PLAYER_PLAYING_ANIM:
|
||||
return COLLISION_WITH_PLAYER_STATE.STILL_NEAR_SELF_PLAYER_NEAR_OTHER_PLAYER_PLAYED_ANIM;
|
||||
|
||||
case COLLISION_WITH_PLAYER_STATE.STILL_NEAR_NOBODY_PLAYING_ANIM:
|
||||
return (true == forceNotCollidableWithOtherPlayer ? COLLISION_WITH_PLAYER_STATE.WALKING_COLLIDABLE_WITH_SELF_PLAYER_BUT_NOT_OTHER_PLAYER : COLLISION_WITH_PLAYER_STATE.WALKING_COLLIDABLE);
|
||||
}
|
||||
// TODO: Any error to throw?
|
||||
return currentCollisionWithPlayerState;
|
||||
}
|
||||
|
||||
function transitStunnedAnimPlayedToWalking(currentCollisionWithPlayerState) {
|
||||
/*
|
||||
* Intentionally NOT transiting for
|
||||
*
|
||||
* - STILL_NEAR_SELF_PLAYER_NEAR_OTHER_PLAYER_PLAYED_ANIM, or
|
||||
* - STILL_NEAR_SELF_PLAYER_ONLY_PLAYED_ANIM,
|
||||
*
|
||||
* which should be transited upon leaving of "SelfPlayer".
|
||||
*/
|
||||
switch (currentCollisionWithPlayerState) {
|
||||
case COLLISION_WITH_PLAYER_STATE.STILL_NEAR_OTHER_PLAYER_ONLY_PLAYED_ANIM:
|
||||
return COLLISION_WITH_PLAYER_STATE.WALKING_COLLIDABLE_WITH_SELF_PLAYER_BUT_NOT_OTHER_PLAYER;
|
||||
}
|
||||
// TODO: Any error to throw?
|
||||
return currentCollisionWithPlayerState;
|
||||
}
|
||||
|
||||
const BasePlayer = require("./BasePlayer");
|
||||
|
||||
cc.Class({
|
||||
extends: BasePlayer,
|
||||
|
||||
// LIFE-CYCLE CALLBACKS:
|
||||
start() {
|
||||
BasePlayer.prototype.start.call(this);
|
||||
|
||||
this.scheduleNewDirection(this._generateRandomDirection());
|
||||
},
|
||||
|
||||
onLoad() {
|
||||
BasePlayer.prototype.onLoad.call(this);
|
||||
const self = this;
|
||||
|
||||
this.collisionWithPlayerState = COLLISION_WITH_PLAYER_STATE.WALKING_COLLIDABLE;
|
||||
|
||||
this.clips = {
|
||||
'01': 'FlatHeadSisterRunTop',
|
||||
'0-1': 'FlatHeadSisterRunBottom',
|
||||
'-20': 'FlatHeadSisterRunLeft',
|
||||
'20': 'FlatHeadSisterRunRight',
|
||||
'-21': 'FlatHeadSisterRunTopLeft',
|
||||
'21': 'FlatHeadSisterRunTopRight',
|
||||
'-2-1': 'FlatHeadSisterRunBottomLeft',
|
||||
'2-1': 'FlatHeadSisterRunBottomRight'
|
||||
};
|
||||
|
||||
|
||||
self.onStunnedAnimPlayedSafe = () => {
|
||||
const oldCollisionWithPlayerState = self.collisionWithPlayerState;
|
||||
self.collisionWithPlayerState = transitStunnedAnimPlayingToPlayed(this.collisionWithPlayerState, true);
|
||||
if (oldCollisionWithPlayerState == self.collisionWithPlayerState || !self.node) return;
|
||||
|
||||
self.scheduleNewDirection(self._generateRandomDirection());
|
||||
self.collisionWithPlayerState = transitStunnedAnimPlayedToWalking(self.collisionWithPlayerState);
|
||||
setTimeout(() => {
|
||||
self.collisionWithPlayerState = transitWalkingConditionallyCollidableToUnconditionallyCollidable(self.collisionWithPlayerState);
|
||||
}, 5000);
|
||||
};
|
||||
|
||||
self.onStunnedAnimPlayedSafeAction = cc.callFunc(self.onStunnedAnimPlayedSafe, self);
|
||||
|
||||
self.playStunnedAnim = () => {
|
||||
let colliededAction1 = cc.rotateTo(0.2, -15);
|
||||
let colliededAction2 = cc.rotateTo(0.3, 15);
|
||||
let colliededAction3 = cc.rotateTo(0.2, 0);
|
||||
|
||||
self.node.runAction(cc.sequence(
|
||||
cc.callFunc(() => {
|
||||
self.player.pause()
|
||||
}, self),
|
||||
colliededAction1,
|
||||
colliededAction2,
|
||||
colliededAction3,
|
||||
cc.callFunc(() => {
|
||||
self.player.resume()
|
||||
}, self),
|
||||
self.onStunnedAnimPlayedSafeAction
|
||||
));
|
||||
|
||||
// NOTE: Use <cc.Animation>.on('stop', self.onStunnedAnimPlayedSafe) if necessary.
|
||||
}
|
||||
},
|
||||
|
||||
_canMoveBy(vecToMoveBy) {
|
||||
if (COLLISION_WITH_PLAYER_STATE.WALKING_COLLIDABLE_WITH_SELF_PLAYER_BUT_NOT_OTHER_PLAYER != this.collisionWithPlayerState && COLLISION_WITH_PLAYER_STATE.WALKING_COLLIDABLE != this.collisionWithPlayerState) {
|
||||
return false;
|
||||
}
|
||||
|
||||
const superRet = BasePlayer.prototype._canMoveBy.call(this, vecToMoveBy);
|
||||
const self = this;
|
||||
|
||||
const computedNewDifferentPosLocalToParentWithinCurrentFrame = self.node.position.add(vecToMoveBy);
|
||||
|
||||
const currentSelfColliderCircle = self.node.getComponent("cc.CircleCollider");
|
||||
let nextSelfColliderCircle = null;
|
||||
if (0 < self.contactedBarriers.length || 0 < self.contactedNPCPlayers.length || 0 < self.contactedControlledPlayers) {
|
||||
/* To avoid unexpected buckling. */
|
||||
const mutatedVecToMoveBy = vecToMoveBy.mul(2);
|
||||
nextSelfColliderCircle = {
|
||||
position: self.node.position.add(vecToMoveBy.mul(2)).add(currentSelfColliderCircle.offset),
|
||||
radius: currentSelfColliderCircle.radius,
|
||||
};
|
||||
} else {
|
||||
nextSelfColliderCircle = {
|
||||
position: computedNewDifferentPosLocalToParentWithinCurrentFrame.add(currentSelfColliderCircle.offset),
|
||||
radius: currentSelfColliderCircle.radius,
|
||||
};
|
||||
}
|
||||
|
||||
for (let aCircleCollider of self.contactedControlledPlayers) {
|
||||
let contactedCircleLocalToParentWithinCurrentFrame = {
|
||||
position: aCircleCollider.node.position.add(aCircleCollider.offset),
|
||||
radius: aCircleCollider.radius,
|
||||
};
|
||||
if (cc.Intersection.circleCircle(contactedCircleLocalToParentWithinCurrentFrame, nextSelfColliderCircle)) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
return superRet;
|
||||
},
|
||||
|
||||
update(dt) {
|
||||
BasePlayer.prototype.update.call(this, dt);
|
||||
},
|
||||
|
||||
onCollisionEnter(other, self) {
|
||||
BasePlayer.prototype.onCollisionEnter.call(this, other, self);
|
||||
const playerScriptIns = self.getComponent(self.node.name);
|
||||
switch (other.node.name) {
|
||||
case "SelfPlayer":
|
||||
playerScriptIns._addContactedControlledPlayers(other);
|
||||
if (1 == playerScriptIns.contactedControlledPlayers.length) {
|
||||
// When "SelfPlayer" comes into proximity area.
|
||||
if (!STILL_SHOULD_NOT_PLAY_STUNNED_ANIM_SET.has(playerScriptIns.collisionWithPlayerState)) {
|
||||
playerScriptIns.collisionWithPlayerState = transitToPlayingStunnedAnim(playerScriptIns.collisionWithPlayerState, true, false);
|
||||
playerScriptIns.playStunnedAnim();
|
||||
} else {
|
||||
playerScriptIns.collisionWithPlayerState = transitDuringPlayingStunnedAnim(playerScriptIns.collisionWithPlayerState, true, false);
|
||||
}
|
||||
}
|
||||
break;
|
||||
case "NPCPlayer":
|
||||
if (1 == playerScriptIns.contactedNPCPlayers.length) {
|
||||
// When one of the other "OtherPlayer"s comes into proximity area.
|
||||
if (!STILL_SHOULD_NOT_PLAY_STUNNED_ANIM_SET.has(playerScriptIns.collisionWithPlayerState)) {
|
||||
const oldState = playerScriptIns.collisionWithPlayerState;
|
||||
playerScriptIns.collisionWithPlayerState = transitToPlayingStunnedAnim(oldState, false, true);
|
||||
if (playerScriptIns.collisionWithPlayerState != oldState) {
|
||||
playerScriptIns.playStunnedAnim();
|
||||
}
|
||||
} else {
|
||||
playerScriptIns.collisionWithPlayerState = transitDuringPlayingStunnedAnim(playerScriptIns.collisionWithPlayerState, false, true);
|
||||
}
|
||||
}
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
},
|
||||
|
||||
onCollisionStay(other, self) {
|
||||
// TBD.
|
||||
},
|
||||
|
||||
onCollisionExit(other, self) {
|
||||
BasePlayer.prototype.onCollisionExit.call(this, other, self);
|
||||
const playerScriptIns = self.getComponent(self.node.name);
|
||||
switch (other.node.name) {
|
||||
case "SelfPlayer":
|
||||
playerScriptIns._removeContactedControlledPlayer(other);
|
||||
if (0 == playerScriptIns.contactedControlledPlayers.length) {
|
||||
// Special release step.
|
||||
if (STILL_NEAR_SELF_PLAYER_STATE_SET.has(playerScriptIns.collisionWithPlayerState)) {
|
||||
playerScriptIns.collisionWithPlayerState = transitUponSelfPlayerLeftProximityArea(playerScriptIns.collisionWithPlayerState);
|
||||
}
|
||||
}
|
||||
if (0 == playerScriptIns.contactedControlledPlayers.length && 0 == playerScriptIns.contactedNPCPlayers.length) {
|
||||
transitDueToNoBodyInProximityArea(playerScriptIns.collisionWithPlayerState);
|
||||
}
|
||||
break;
|
||||
case "NPCPlayer":
|
||||
if (0 == playerScriptIns.contactedControlledPlayers.length && 0 == playerScriptIns.contactedNPCPlayers.length) {
|
||||
transitDueToNoBodyInProximityArea(playerScriptIns.collisionWithPlayerState);
|
||||
}
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
},
|
||||
});
|
@@ -17,11 +17,47 @@ cc.Class({
|
||||
console.warn("+++++++ Map onDestroy()");
|
||||
},
|
||||
|
||||
spawnPlayerNode(joinIndex, vx, vy, playerRichInfo) {
|
||||
const self = this;
|
||||
const newPlayerNode = cc.instantiate(self.controlledCharacterPrefab)
|
||||
const playerScriptIns = newPlayerNode.getComponent("ControlledCharacter");
|
||||
const wpos = self.virtualGridToWorldPos(vx, vy);
|
||||
|
||||
newPlayerNode.setPosition(cc.v2(wpos[0], wpos[1]));
|
||||
|
||||
playerScriptIns.mapNode = self.node;
|
||||
const cpos = self.virtualGridToPlayerColliderPos(vx, vy, playerRichInfo);
|
||||
const d = playerRichInfo.colliderRadius * 2,
|
||||
x0 = cpos[0],
|
||||
y0 = cpos[1];
|
||||
let pts = [[0, 0], [d, 0], [d, d], [0, d]];
|
||||
|
||||
const newPlayerCollider = self.collisionSys.createPolygon(x0, y0, pts);
|
||||
const collisionPlayerIndex = self.collisionPlayerIndexPrefix + joinIndex;
|
||||
self.collisionSysMap.set(collisionPlayerIndex, newPlayerCollider);
|
||||
|
||||
safelyAddChild(self.node, newPlayerNode);
|
||||
setLocalZOrder(newPlayerNode, 5);
|
||||
|
||||
newPlayerNode.active = true;
|
||||
playerScriptIns.scheduleNewDirection({
|
||||
dx: playerRichInfo.dir.dx,
|
||||
dy: playerRichInfo.dir.dy
|
||||
}, true);
|
||||
|
||||
return [newPlayerNode, playerScriptIns];
|
||||
},
|
||||
|
||||
onLoad() {
|
||||
const self = this;
|
||||
window.mapIns = self;
|
||||
|
||||
self.mainCameraNode = canvasNode.getChildByName("Main Camera");
|
||||
cc.director.getCollisionManager().enabled = false;
|
||||
|
||||
const mapNode = self.node;
|
||||
const canvasNode = mapNode.parent;
|
||||
|
||||
self.mainCameraNode = self.canvasNode.getChildByName("Main Camera");
|
||||
self.mainCamera = self.mainCameraNode.getComponent(cc.Camera);
|
||||
for (let child of self.mainCameraNode.children) {
|
||||
child.setScale(1 / self.mainCamera.zoomRatio);
|
||||
@@ -31,37 +67,27 @@ cc.Class({
|
||||
|
||||
/** Init required prefab ended. */
|
||||
|
||||
self.inputDelayFrames = parsedBattleColliderInfo.inputDelayFrames;
|
||||
self.inputScaleFrames = parsedBattleColliderInfo.inputScaleFrames;
|
||||
self.inputFrameUpsyncDelayTolerance = parsedBattleColliderInfo.inputFrameUpsyncDelayTolerance;
|
||||
self.inputDelayFrames = 8;
|
||||
self.inputScaleFrames = 2;
|
||||
self.inputFrameUpsyncDelayTolerance = 2;
|
||||
|
||||
self.battleDurationNanos = parsedBattleColliderInfo.battleDurationNanos;
|
||||
self.rollbackEstimatedDt = parsedBattleColliderInfo.rollbackEstimatedDt;
|
||||
self.rollbackEstimatedDtMillis = parsedBattleColliderInfo.rollbackEstimatedDtMillis;
|
||||
self.rollbackEstimatedDtNanos = parsedBattleColliderInfo.rollbackEstimatedDtNanos;
|
||||
self.maxChasingRenderFramesPerUpdate = parsedBattleColliderInfo.maxChasingRenderFramesPerUpdate;
|
||||
self.rollbackEstimatedDt = 0.016667;
|
||||
self.rollbackEstimatedDtMillis = 16.667;
|
||||
self.rollbackEstimatedDtNanos = 16666666;
|
||||
self.maxChasingRenderFramesPerUpdate = 5;
|
||||
|
||||
self.worldToVirtualGridRatio = parsedBattleColliderInfo.worldToVirtualGridRatio;
|
||||
self.virtualGridToWorldRatio = parsedBattleColliderInfo.virtualGridToWorldRatio;
|
||||
self.worldToVirtualGridRatio = 1000;
|
||||
self.virtualGridToWorldRatio = 1.0 / self.worldToVirtualGridRatio;
|
||||
|
||||
const tiledMapIns = self.node.getComponent(cc.TiledMap);
|
||||
|
||||
// It's easier to just use the "barrier"s extracted by the backend (all anchor points in world coordinates), but I'd like to verify frontend tmx parser logic as well.
|
||||
const fullPathOfTmxFile = cc.js.formatStr("map/%s/map", parsedBattleColliderInfo.stageName);
|
||||
const fullPathOfTmxFile = cc.js.formatStr("map/%s/map", "dungeon");
|
||||
cc.loader.loadRes(fullPathOfTmxFile, cc.TiledMapAsset, (err, tmxAsset) => {
|
||||
if (null != err) {
|
||||
console.error(err);
|
||||
return;
|
||||
}
|
||||
|
||||
/*
|
||||
[WARNING]
|
||||
|
||||
- The order of the following statements is important, because we should have finished "_resetCurrentMatch" before the first "RoomDownsyncFrame".
|
||||
- It's important to assign new "tmxAsset" before "extractBoundaryObjects", to ensure that the correct tilesets are used.
|
||||
- To ensure clearance, put destruction of the "cc.TiledMap" component preceding that of "mapNode.destroyAllChildren()".
|
||||
*/
|
||||
|
||||
tiledMapIns.tmxAsset = null;
|
||||
mapNode.removeAllChildren();
|
||||
self._resetCurrentMatch();
|
||||
@@ -71,15 +97,6 @@ cc.Class({
|
||||
const newTileSize = tiledMapIns.getTileSize();
|
||||
self.node.setContentSize(newMapSize.width * newTileSize.width, newMapSize.height * newTileSize.height);
|
||||
self.node.setPosition(cc.v2(0, 0));
|
||||
/*
|
||||
* Deliberately hiding "ImageLayer"s. This dirty fix is specific to "CocosCreator v2.2.1", where it got back the rendering capability of "ImageLayer of Tiled", yet made incorrectly. In this game our "markers of ImageLayers" are rendered by dedicated prefabs with associated colliders.
|
||||
*
|
||||
* -- YFLu, 2020-01-23
|
||||
*/
|
||||
const existingImageLayers = tiledMapIns.getObjectGroups();
|
||||
for (let singleImageLayer of existingImageLayers) {
|
||||
singleImageLayer.node.opacity = 0;
|
||||
}
|
||||
|
||||
let barrierIdCounter = 0;
|
||||
const boundaryObjs = tileCollisionManager.extractBoundaryObjects(self.node);
|
||||
@@ -127,6 +144,34 @@ cc.Class({
|
||||
const collisionBarrierIndex = (self.collisionBarrierIndexPrefix + barrierIdCounter);
|
||||
self.collisionSysMap.set(collisionBarrierIndex, newBarrier);
|
||||
}
|
||||
|
||||
const startRdf = {
|
||||
id: window.MAGIC_ROOM_DOWNSYNC_FRAME_ID.BATTLE_START,
|
||||
players: {
|
||||
10: {
|
||||
id: 10,
|
||||
virtualGridX: 0,
|
||||
virtualGridY: 0,
|
||||
speed: 2*self.worldToVirtualGridRatio,
|
||||
dir: {
|
||||
dx: 0,
|
||||
dy: 0
|
||||
}
|
||||
},
|
||||
},
|
||||
playerMetas: {
|
||||
10: {
|
||||
colliderRadius: 12,
|
||||
},
|
||||
}
|
||||
};
|
||||
self.selfPlayerInfo = {
|
||||
id: 10
|
||||
};
|
||||
self._initPlayerRichInfoDict(startRdf.players, startRdf.playerMetas);
|
||||
self.onRoomDownsyncFrame(startRdf);
|
||||
|
||||
self.battleState = ALL_BATTLE_STATES.IN_BATTLE;
|
||||
});
|
||||
|
||||
},
|
||||
|
@@ -1,13 +0,0 @@
|
||||
const Bullet = require("./Bullet");
|
||||
|
||||
cc.Class({
|
||||
extends: Bullet,
|
||||
// LIFE-CYCLE CALLBACKS:
|
||||
properties: {
|
||||
},
|
||||
|
||||
onLoad() {
|
||||
Bullet.prototype.onLoad.call(this);
|
||||
},
|
||||
|
||||
});
|
@@ -1,9 +0,0 @@
|
||||
{
|
||||
"ver": "1.0.5",
|
||||
"uuid": "c3bb6519-af90-4641-bb5e-5abbbcdfa6da",
|
||||
"isPlugin": false,
|
||||
"loadPluginInWeb": true,
|
||||
"loadPluginInNative": true,
|
||||
"loadPluginInEditor": false,
|
||||
"subMetas": {}
|
||||
}
|
@@ -1,26 +0,0 @@
|
||||
window.LOW_SCORE_TREASURE_TYPE = 1;
|
||||
window.HIGH_SCORE_TREASURE_TYPE = 2;
|
||||
|
||||
window.LOW_SCORE_TREASURE_SCORE = 100;
|
||||
window.HIGH_SCORE_TREASURE_SCORE = 200;
|
||||
|
||||
cc.Class({
|
||||
extends: cc.Component,
|
||||
|
||||
properties: {
|
||||
},
|
||||
|
||||
setData (treasureInfo) {
|
||||
const self = this;
|
||||
this.score = treasureInfo.score;
|
||||
this.type = treasureInfo.type;
|
||||
|
||||
this.treasureInfo = treasureInfo;
|
||||
|
||||
const spriteComponent = this.node.getComponent(cc.Sprite);
|
||||
const targetGid = (window.LOW_SCORE_TREASURE_TYPE == treasureInfo.type ? window.battleEntityTypeNameToGlobalGid["LowScoreTreasure"] : window.battleEntityTypeNameToGlobalGid["HighScoreTreasure"])
|
||||
spriteComponent.spriteFrame = window.getOrCreateSpriteFrameForGid(targetGid).spriteFrame;
|
||||
},
|
||||
|
||||
start() {},
|
||||
})
|
@@ -1,9 +0,0 @@
|
||||
{
|
||||
"ver": "1.0.5",
|
||||
"uuid": "5eea6ce5-0343-4776-80a4-fccd69bd099b",
|
||||
"isPlugin": false,
|
||||
"loadPluginInWeb": true,
|
||||
"loadPluginInNative": true,
|
||||
"loadPluginInEditor": false,
|
||||
"subMetas": {}
|
||||
}
|
@@ -1,84 +0,0 @@
|
||||
cc.Class({
|
||||
extends: cc.Component,
|
||||
|
||||
properties: {
|
||||
pickedUpAnimNode: {
|
||||
type: cc.Node,
|
||||
default: null
|
||||
},
|
||||
durationMillis: {
|
||||
default: 0
|
||||
},
|
||||
binglingAnimNode: {
|
||||
type: cc.Node,
|
||||
default: null
|
||||
},
|
||||
binglingAnimDurationMillis: {
|
||||
default: 0
|
||||
},
|
||||
scoreLabelNode: {
|
||||
type: cc.Node,
|
||||
default: null
|
||||
}
|
||||
|
||||
},
|
||||
|
||||
|
||||
setData (treasureInfo) {
|
||||
const self = this;
|
||||
this.score = treasureInfo.score ? treasureInfo.score : 100 ;
|
||||
this.type = treasureInfo.type ? treasureInfo.type : 1;
|
||||
this.scoreLabelNode.getComponent(cc.Label).string = this.score;
|
||||
const spriteComponent = this.pickedUpAnimNode.getComponent(cc.Sprite);
|
||||
//hardcode treasurePNG's path.
|
||||
cc.loader.loadRes("textures/treasures/"+ this.type, cc.SpriteFrame, function (err, frame) {
|
||||
if(err){
|
||||
cc.warn(err);
|
||||
return;
|
||||
}
|
||||
spriteComponent.spriteFrame = frame;
|
||||
})
|
||||
},
|
||||
|
||||
// LIFE-CYCLE CALLBACKS:
|
||||
update (dt) {
|
||||
const changingNode = this.pickedUpAnimNode;
|
||||
const elapsedMillis = Date.now() - this.startedAtMillis;
|
||||
if(elapsedMillis >= this.binglingAnimDurationMillis && null != this.binglingAnimNode && true == this.binglingAnimNode.active) {
|
||||
this.binglingAnimNode.active = false;
|
||||
this.startedAtMillis = Date.now();
|
||||
}
|
||||
if(this.binglingAnimNode.active)
|
||||
return;
|
||||
if (elapsedMillis > this.durationMillis) {
|
||||
this.node.destroy();
|
||||
return;
|
||||
}
|
||||
if (elapsedMillis <= this.firstDurationMillis) {
|
||||
let posDiff = cc.v2(0, dt * this.yIncreaseSpeed);
|
||||
changingNode.setPosition(changingNode.position.add(posDiff));
|
||||
this.scoreLabelNode.setPosition(this.scoreLabelNode.position.add(posDiff));
|
||||
changingNode.scale += (this.scaleIncreaseSpeed*dt);
|
||||
} else {
|
||||
let posDiff = cc.v2(dt * this.xIncreaseSpeed , ( -1 *dt * this.yDecreaseSpeed));
|
||||
changingNode.setPosition(changingNode.position.add(posDiff));
|
||||
this.scoreLabelNode.setPosition(this.scoreLabelNode.position.add(posDiff));
|
||||
changingNode.opacity -= dt * this.opacityDegradeSpeed;
|
||||
this.scoreLabelNode.opacity -= dt * this.opacityDegradeSpeed;
|
||||
}
|
||||
},
|
||||
|
||||
onLoad() {
|
||||
this.pickedUpAnimNode.scale = 0;
|
||||
this.startedAtMillis = Date.now();
|
||||
|
||||
this.firstDurationMillis = (0.8*this.durationMillis);
|
||||
this.yIncreaseSpeed = (200 *1000/this.firstDurationMillis);
|
||||
this.scaleIncreaseSpeed = (2 * 1000/this.firstDurationMillis);
|
||||
|
||||
this.scondDurationMillis = (0.2 * this.durationMillis );
|
||||
this.opacityDegradeSpeed = (255*1000/this.scondDurationMillis);
|
||||
this.yDecreaseSpeed = (30*1000/this.scondDurationMillis);
|
||||
this.xIncreaseSpeed = (20*1000/this.scondDurationMillis);
|
||||
}
|
||||
});
|
@@ -1,9 +0,0 @@
|
||||
{
|
||||
"ver": "1.0.5",
|
||||
"uuid": "697ef72c-27ee-4184-9ae3-885808d58153",
|
||||
"isPlugin": false,
|
||||
"loadPluginInWeb": true,
|
||||
"loadPluginInNative": true,
|
||||
"loadPluginInEditor": false,
|
||||
"subMetas": {}
|
||||
}
|
@@ -1,28 +0,0 @@
|
||||
const BasePlayer = require("./BasePlayer");
|
||||
|
||||
cc.Class({
|
||||
extends: BasePlayer,
|
||||
|
||||
// LIFE-CYCLE CALLBACKS:
|
||||
start() {
|
||||
BasePlayer.prototype.start.call(this);
|
||||
},
|
||||
|
||||
onLoad() {
|
||||
BasePlayer.prototype.onLoad.call(this);
|
||||
this.clips = {
|
||||
'01': 'FlatHeadSisterRunTop',
|
||||
'0-1': 'FlatHeadSisterRunBottom',
|
||||
'-20': 'FlatHeadSisterRunLeft',
|
||||
'20': 'FlatHeadSisterRunRight',
|
||||
'-21': 'FlatHeadSisterRunTopLeft',
|
||||
'21': 'FlatHeadSisterRunTopRight',
|
||||
'-2-1': 'FlatHeadSisterRunBottomLeft',
|
||||
'2-1': 'FlatHeadSisterRunBottomRight'
|
||||
};
|
||||
},
|
||||
|
||||
update(dt) {
|
||||
},
|
||||
|
||||
});
|
@@ -1,9 +0,0 @@
|
||||
{
|
||||
"ver": "1.0.5",
|
||||
"uuid": "233a1795-0de3-4d7c-9ce6-c5736ade723f",
|
||||
"isPlugin": false,
|
||||
"loadPluginInWeb": true,
|
||||
"loadPluginInNative": true,
|
||||
"loadPluginInEditor": false,
|
||||
"subMetas": {}
|
||||
}
|
Reference in New Issue
Block a user