Updates for fireball bullet.

This commit is contained in:
genxium
2023-01-11 18:09:18 +08:00
parent 9725fb9df2
commit 934a495d47
26 changed files with 9367 additions and 868 deletions

View File

@@ -0,0 +1,26 @@
cc.Class({
extends: cc.Component,
ctor() {
this.lastUsed = -1;
this.bulletLocalId = -1;
this.speciesName = null;
},
setSpecies(speciesName) {
if (speciesName == this.speciesName) return;
this.speciesName = speciesName;
this.effAnimNode = this.node.getChildByName(this.speciesName);
this.animComp = this.effAnimNode.getComponent(cc.Animation);
this.effAnimNode.active = true;
for (let k in this.children) {
const child = this.children[k];
if (!child.active) continue;
if (child == effAnimNode || child.name == speciesName) continue;
child.active = false;
}
},
onLoad() {
},
});

View File

@@ -1,6 +1,6 @@
{
"ver": "1.0.5",
"uuid": "247b7613-6c6e-4f01-b1d6-5f8f041b5688",
"uuid": "e66a2a91-9916-469e-a4b2-54cc0bcba3f0",
"isPlugin": false,
"loadPluginInWeb": true,
"loadPluginInNative": true,

View File

@@ -2,6 +2,7 @@ const i18n = require('LanguageData');
i18n.init(window.language); // languageID should be equal to the one we input in New Language ID input field
const RingBuffer = require('./RingBuffer');
const PriorityQueue = require("./PriorityQueue");
window.ALL_MAP_STATES = {
VISUAL: 0, // For free dragging & zooming.
@@ -44,6 +45,10 @@ cc.Class({
type: cc.Prefab,
default: null,
},
fireballPrefab: {
type: cc.Prefab,
default: null,
},
joystickInputControllerNode: {
type: cc.Node,
default: null
@@ -287,6 +292,30 @@ cc.Class({
self.playerRichInfoDict = new Map();
// Clearing previous info of all players. [ENDS]
// Clearing cached fireball rendering nodes [BEGINS]
if (null != self.cachedFireballs) {
while (!self.cachedFireballs.isEmpty()) {
const v = self.cachedFireballs.pop();
if (v && v.node && v.node.parent) {
v.node.parent.removeChild(v.node);
}
}
} else {
self.cachedFireballs = new PriorityQueue();
}
for (let k = 0; k < 1000; k++) {
const newFireballNode = cc.instantiate(self.fireballPrefab);
const newFireball = newFireballNode.getComponent("Fireball");
newFireballNode.setPosition(cc.v2(Number.MAX_VALUE, Number.MAX_VALUE));
safelyAddChild(self.node, newFireballNode);
setLocalZOrder(newFireballNode, 5);
newFireball.lastUsed = -1;
newFireball.bulletLocalId = -1;
const initLookupKey = -(k + 1); // there's definitely no suck "bulletLocalId"
self.cachedFireballs.push(newFireball.lastUsed, newFireball, initLookupKey);
}
// Clearing cached fireball rendering nodes [ENDS]
self.renderFrameId = 0; // After battle started
self.bulletBattleLocalIdCounter = 0;
self.lastAllConfirmedInputFrameId = -1;
@@ -590,7 +619,7 @@ cc.Class({
const jsFireballBulletsArr = new Array(pbRdf.fireballBullets.length).fill(null);
for (let k = 0; k < pbRdf.fireballBullets.length; ++k) {
const pbBullet = pbRdf.fireballBullets[k];
const jsFireballBullet = gopkgs.NewFireballBulletJs(pbBullet.bulletLocalId, pbBullet.originatedRenderFrameId, pbBullet.offenderJoinIndex, pbBullet.startupFrames, pbBullet.cancellableStFrame, pbBullet.cancellableEdFrame, pbBullet.activeFrames, pbBullet.hitStunFrames, pbBullet.blockStunFrames, pbBullet.pushbackVelX, pbBullet.pushbackVelY, pbBullet.damage, pbBullet.selfLockVelX, pbBullet.selfLockVelY, pbBullet.hitboxOffsetX, pbBullet.hitboxOffsetY, pbBullet.hitboxSizeX, pbBullet.hitboxSizeY, pbBullet.blowUp, pbBullet.teamId, pbBullet.virtualGridX, pbBullet.virtualGridY, pbBullet.dirX, pbBullet.dirY, pbBullet.velX, pbBullet.velY, pbBullet.speed);
const jsFireballBullet = gopkgs.NewFireballBulletJs(pbBullet.bulletLocalId, pbBullet.originatedRenderFrameId, pbBullet.offenderJoinIndex, pbBullet.startupFrames, pbBullet.cancellableStFrame, pbBullet.cancellableEdFrame, pbBullet.activeFrames, pbBullet.hitStunFrames, pbBullet.blockStunFrames, pbBullet.pushbackVelX, pbBullet.pushbackVelY, pbBullet.damage, pbBullet.selfLockVelX, pbBullet.selfLockVelY, pbBullet.hitboxOffsetX, pbBullet.hitboxOffsetY, pbBullet.hitboxSizeX, pbBullet.hitboxSizeY, pbBullet.blowUp, pbBullet.teamId, pbBullet.virtualGridX, pbBullet.virtualGridY, pbBullet.dirX, pbBullet.dirY, pbBullet.velX, pbBullet.velY, pbBullet.speed, pbBullet.speciesId);
jsFireballBulletsArr[k] = jsFireballBullet;
}
@@ -709,10 +738,9 @@ cc.Class({
equalMeleeBullets(lhs, rhs) {
if (null == lhs || null == rhs) return false;
if (lhs.battleLocalId != rhs.battleLocalId) return false;
if (lhs.offenderPlayerId != rhs.offenderPlayerId) return false;
if (lhs.offenderJoinIndex != rhs.offenderJoinIndex) return false;
if (lhs.originatedRenderFrameId != rhs.originatedRenderFrameId) return false;
if (lhs.BulletLocalId != rhs.BulletLocalId) return false;
if (lhs.OffenderJoinIndex != rhs.OffenderJoinIndex) return false;
if (lhs.OriginatedRenderFrameId != rhs.OriginatedRenderFrameId) return false;
return true;
},
@@ -1039,6 +1067,27 @@ othersForcedDownsyncRenderFrame=${JSON.stringify(othersForcedDownsyncRenderFrame
}
},
_renderFireballBullet(fireballBullet) {
const self = this;
let pqNode = self.cachedFireballs.popAny(fireballBullet.Bullet.BulletLocalId);
const speciesName = `Fireball${fireballBullet.SpeciesId}`;
if (null == pqNode) {
pqNode = self.cachedFireballs.pop();
} else {
console.log(`Using a cached fireball node for rendering for bulletLocalId=${fireballBullet.Bullet.BulletLocalId}`);
}
const cachedFireball = pqNode.value;
cachedFireball.setSpecies(speciesName);
cachedFireball.lastUsed = self.renderFrameId;
cachedFireball.bulletLocalId = fireballBullet.Bullet.BulletLocalId;
const [wx, wy] = gopkgs.VirtualGridToWorldPos(fireballBullet.VirtualGridX, fireballBullet.VirtualGridY);
cachedFireball.node.setPosition(cc.v2(wx, wy));
self.cachedFireballs.push(cachedFireball.lastUsed, cachedFireball, cachedFireball.bulletLocalId);
},
applyRoomDownsyncFrameDynamics(rdf, prevRdf) {
const self = this;
const playersArr = rdf.PlayersArr;
@@ -1053,6 +1102,18 @@ othersForcedDownsyncRenderFrame=${JSON.stringify(othersForcedDownsyncRenderFrame
playerRichInfo.scriptIns.updateCharacterAnim(currPlayerDownsync, prevRdfPlayer, false, chConfig);
}
// Move all to infinitely far away first
for (let k in self.cachedFireballs.list) {
const pqNode = self.cachedFireballs.list[k];
const fireball = pqNode.value;
fireball.node.setPosition(cc.v2(Number.MAX_VALUE, Number.MAX_VALUE));
}
const fireballBullets = rdf.FireballBullets;
for (let k in fireballBullets) {
const fireballBullet = fireballBullets[k];
self._renderFireballBullet(fireballBullet);
}
// Update countdown
self.countdownNanos = self.battleDurationNanos - self.renderFrameId * self.rollbackEstimatedDtNanos;
if (self.countdownNanos <= 0) {

View File

@@ -12,32 +12,15 @@ var BinaryHeap = function (customCompare) {
* @private
*/
this.list = [];
this.lookupKeyToIndex = {};
if (customCompare) {
this.compare = customCompare;
}
};
/**
* Builds a heap with the provided keys and values, this will discard the
* heap's current data.
*
* @param {Array} keys An array of keys.
* @param {Array} values An array of values. This must be the same size as the
* key array.
*/
BinaryHeap.prototype.buildHeap = function (keys, values) {
if (typeof values !== 'undefined' && values.length !== keys.length) {
throw new Error('Key array must be the same length as value array');
}
var nodeArray = [];
for (var i = 0; i < keys.length; i++) {
nodeArray.push(new Node(keys[i], values ? values[i] : undefined));
}
buildHeapFromNodeArray(this, nodeArray);
BinaryHeap.prototype.contains = function (lookupKey) {
return null != this.lookupKeyToIndex[lookupKey];
};
/**
@@ -45,6 +28,7 @@ BinaryHeap.prototype.buildHeap = function (keys, values) {
*/
BinaryHeap.prototype.clear = function () {
this.list.length = 0;
this.lookupKeyToIndex = null;
};
/**
@@ -53,15 +37,20 @@ BinaryHeap.prototype.clear = function () {
* @return {Node} node The heap's minimum node or undefined if the heap is
* empty.
*/
BinaryHeap.prototype.extractMinimum = function () {
if (!this.list.length) {
return undefined;
BinaryHeap.prototype.pop = function () {
if (0 == this.list.length) {
return null;
}
if (this.list.length === 1) {
if (1 == this.list.length) {
delete this.lookupKeyToIndex[Object.keys(this.lookupKeyToIndex)[0]];
return this.list.shift();
}
var min = this.list[0];
delete this.lookupKeyToIndex[min.lookupKey];
this.list[0] = this.list.pop();
this.lookupKeyToIndex[this.list[0].lookupKey] = 0;
heapify(this, 0);
return min;
};
@@ -72,8 +61,8 @@ BinaryHeap.prototype.extractMinimum = function () {
* @return {Node} node The heap's minimum node or undefined if the heap is
* empty.
*/
BinaryHeap.prototype.findMinimum = function () {
return this.isEmpty() ? undefined : this.list[0];
BinaryHeap.prototype.top = function () {
return this.isEmpty() ? null : this.list[0];
};
/**
@@ -83,25 +72,79 @@ BinaryHeap.prototype.findMinimum = function () {
* @param {Object} value The value to insert.
* @return {Node} node The inserted node.
*/
BinaryHeap.prototype.insert = function (key, value) {
BinaryHeap.prototype.push = function (key, value, lookupKey) {
var i = this.list.length;
var node = new Node(key, value);
var node = new Node(key, value, lookupKey);
this.list.push(node);
var parent = getParent(i);
while (typeof parent !== 'undefined' &&
this.compare(this.list[i], this.list[parent]) < 0) {
swap(this.list, i, parent);
i = parent;
parent = getParent(i);
this.lookupKeyToIndex[lookupKey] = i;
let u = getParent(i);
while (null != u && this.compare(this.list[i], this.list[u]) < 0) {
swap(this.list, i, u, this.lookupKeyToIndex);
i = u;
u = getParent(i);
}
return node;
};
BinaryHeap.prototype.update = function (lookupKey, newKey, newValue) {
if (null == this.lookupKeyToIndex[lookupKey]) return null;
var i = this.lookupKeyToIndex[lookupKey];
this.list[i].key = newKey;
this.list[i].value = newValue;
let u = getParent(i);
if (null != u && this.compare(this.list[i], this.list[u]) < 0) {
while (null != u && this.compare(this.list[i], this.list[u]) < 0) {
swap(this.list, i, u, this.lookupKeyToIndex);
i = u;
u = getParent(i);
}
} else {
heapify(this, i);
}
};
BinaryHeap.prototype.popAny = function (lookupKey) {
if (null == this.lookupKeyToIndex[lookupKey]) return null;
if (0 == this.list.length) {
return null;
}
if (1 == this.list.length) {
delete this.lookupKeyToIndex[Object.keys(this.lookupKeyToIndex)[0]];
return this.list.shift();
}
var i = this.lookupKeyToIndex[lookupKey];
var old = this.list[i];
delete this.lookupKeyToIndex[old.lookupKey];
this.list[i] = this.list.pop();
this.lookupKeyToIndex[this.list[i].lookupKey] = i;
let u = getParent(i);
if (null != u && this.compare(this.list[i], this.list[u]) < 0) {
while (null != u && this.compare(this.list[i], this.list[u]) < 0) {
swap(this.list, i, u, this.lookupKeyToIndex);
i = u;
u = getParent(i);
}
} else {
heapify(this, i);
}
return old;
};
/**
* @return {boolean} Whether the heap is empty.
*/
BinaryHeap.prototype.isEmpty = function () {
return !this.list.length;
return 0 == this.list.length;
};
/**
@@ -111,16 +154,6 @@ BinaryHeap.prototype.size = function () {
return this.list.length;
};
/**
* Joins another heap to this one.
*
* @param {BinaryHeap} otherHeap The other heap.
*/
BinaryHeap.prototype.union = function (otherHeap) {
var array = this.list.concat(otherHeap.list);
buildHeapFromNodeArray(this, array);
};
/**
* Compares two nodes with each other.
*
@@ -147,34 +180,27 @@ BinaryHeap.prototype.compare = function (a, b) {
* @param {number} i The index of the node to heapify.
*/
function heapify(heap, i) {
var l = getLeft(i);
var r = getRight(i);
var smallest = i;
if (l < heap.list.length &&
heap.compare(heap.list[l], heap.list[i]) < 0) {
smallest = l;
}
if (r < heap.list.length &&
heap.compare(heap.list[r], heap.list[smallest]) < 0) {
smallest = r;
}
if (smallest !== i) {
swap(heap.list, i, smallest);
heapify(heap, smallest);
}
}
let cur = i;
let smallest = -1;
while (cur != smallest) {
const l = getLeft(cur);
const r = getRight(cur);
smallest = cur;
if (l < heap.list.length &&
heap.compare(heap.list[l], heap.list[smallest]) < 0) {
smallest = l;
}
if (r < heap.list.length &&
heap.compare(heap.list[r], heap.list[smallest]) < 0) {
smallest = r;
}
/**
* Builds a heap from a node array, this will discard the heap's current data.
*
* @private
* @param {BinaryHeap} heap The heap to override.
* @param {Node[]} nodeArray The array of nodes for the new heap.
*/
function buildHeapFromNodeArray(heap, nodeArray) {
heap.list = nodeArray;
for (var i = Math.floor(heap.list.length / 2); i >= 0; i--) {
heapify(heap, i);
if (smallest !== cur) {
swap(heap.list, cur, smallest, heap.lookupKeyToIndex);
cur = smallest;
smallest = -1;
}
}
}
@@ -186,10 +212,16 @@ function buildHeapFromNodeArray(heap, nodeArray) {
* @param {number} a The index of the first element.
* @param {number} b The index of the second element.
*/
function swap(array, a, b) {
function swap(array, a, b, lookupKeyToIndex) {
var aLookupKey = array[a].lookupKey;
var bLookupKey = array[b].lookupKey;
var temp = array[a];
array[a] = array[b];
array[b] = temp;
lookupKeyToIndex[aLookupKey] = b;
lookupKeyToIndex[bLookupKey] = a;
}
/**
@@ -200,8 +232,8 @@ function swap(array, a, b) {
* @return {number} The index of the node's parent.
*/
function getParent(i) {
if (i === 0) {
return undefined;
if (0 == i) {
return null;
}
return Math.floor((i - 1) / 2);
}
@@ -235,9 +267,10 @@ function getRight(i) {
* @param {Object} key The key of the new node.
* @param {Object} value The value of the new node.
*/
function Node(key, value) {
function Node(key, value, lookupKey) {
this.key = key;
this.value = value;
this.lookupKey = lookupKey;
}
module.exports = BinaryHeap;

View File

@@ -0,0 +1,9 @@
{
"ver": "1.0.5",
"uuid": "20a75b4a-e220-42cd-bab4-9fc63a289b3f",
"isPlugin": false,
"loadPluginInWeb": true,
"loadPluginInNative": true,
"loadPluginInEditor": false,
"subMetas": {}
}

View File

@@ -1216,6 +1216,7 @@ $root.protos = (function() {
* @property {number|null} [framesInvinsible] PlayerDownsync framesInvinsible
* @property {number|null} [bulletTeamId] PlayerDownsync bulletTeamId
* @property {number|null} [chCollisionTeamId] PlayerDownsync chCollisionTeamId
* @property {boolean|null} [onWall] PlayerDownsync onWall
* @property {string|null} [name] PlayerDownsync name
* @property {string|null} [displayName] PlayerDownsync displayName
* @property {string|null} [avatar] PlayerDownsync avatar
@@ -1436,6 +1437,14 @@ $root.protos = (function() {
*/
PlayerDownsync.prototype.chCollisionTeamId = 0;
/**
* PlayerDownsync onWall.
* @member {boolean} onWall
* @memberof protos.PlayerDownsync
* @instance
*/
PlayerDownsync.prototype.onWall = false;
/**
* PlayerDownsync name.
* @member {string} name
@@ -1534,6 +1543,8 @@ $root.protos = (function() {
writer.uint32(/* id 24, wireType 0 =*/192).int32(message.bulletTeamId);
if (message.chCollisionTeamId != null && Object.hasOwnProperty.call(message, "chCollisionTeamId"))
writer.uint32(/* id 25, wireType 0 =*/200).int32(message.chCollisionTeamId);
if (message.onWall != null && Object.hasOwnProperty.call(message, "onWall"))
writer.uint32(/* id 26, wireType 0 =*/208).bool(message.onWall);
if (message.name != null && Object.hasOwnProperty.call(message, "name"))
writer.uint32(/* id 997, wireType 2 =*/7978).string(message.name);
if (message.displayName != null && Object.hasOwnProperty.call(message, "displayName"))
@@ -1674,6 +1685,10 @@ $root.protos = (function() {
message.chCollisionTeamId = reader.int32();
break;
}
case 26: {
message.onWall = reader.bool();
break;
}
case 997: {
message.name = reader.string();
break;
@@ -1796,6 +1811,9 @@ $root.protos = (function() {
if (message.chCollisionTeamId != null && message.hasOwnProperty("chCollisionTeamId"))
if (!$util.isInteger(message.chCollisionTeamId))
return "chCollisionTeamId: integer expected";
if (message.onWall != null && message.hasOwnProperty("onWall"))
if (typeof message.onWall !== "boolean")
return "onWall: boolean expected";
if (message.name != null && message.hasOwnProperty("name"))
if (!$util.isString(message.name))
return "name: string expected";
@@ -1870,6 +1888,8 @@ $root.protos = (function() {
message.bulletTeamId = object.bulletTeamId | 0;
if (object.chCollisionTeamId != null)
message.chCollisionTeamId = object.chCollisionTeamId | 0;
if (object.onWall != null)
message.onWall = Boolean(object.onWall);
if (object.name != null)
message.name = String(object.name);
if (object.displayName != null)
@@ -1918,6 +1938,7 @@ $root.protos = (function() {
object.framesInvinsible = 0;
object.bulletTeamId = 0;
object.chCollisionTeamId = 0;
object.onWall = false;
object.name = "";
object.displayName = "";
object.avatar = "";
@@ -1972,6 +1993,8 @@ $root.protos = (function() {
object.bulletTeamId = message.bulletTeamId;
if (message.chCollisionTeamId != null && message.hasOwnProperty("chCollisionTeamId"))
object.chCollisionTeamId = message.chCollisionTeamId;
if (message.onWall != null && message.hasOwnProperty("onWall"))
object.onWall = message.onWall;
if (message.name != null && message.hasOwnProperty("name"))
object.name = message.name;
if (message.displayName != null && message.hasOwnProperty("displayName"))
@@ -4759,6 +4782,7 @@ $root.protos = (function() {
* @property {boolean|null} [blowUp] FireballBullet blowUp
* @property {number|null} [teamId] FireballBullet teamId
* @property {number|null} [bulletLocalId] FireballBullet bulletLocalId
* @property {number|null} [speciesId] FireballBullet speciesId
* @property {number|null} [virtualGridX] FireballBullet virtualGridX
* @property {number|null} [virtualGridY] FireballBullet virtualGridY
* @property {number|null} [dirX] FireballBullet dirX
@@ -4943,6 +4967,14 @@ $root.protos = (function() {
*/
FireballBullet.prototype.bulletLocalId = 0;
/**
* FireballBullet speciesId.
* @member {number} speciesId
* @memberof protos.FireballBullet
* @instance
*/
FireballBullet.prototype.speciesId = 0;
/**
* FireballBullet virtualGridX.
* @member {number} virtualGridX
@@ -5063,6 +5095,8 @@ $root.protos = (function() {
writer.uint32(/* id 19, wireType 0 =*/152).int32(message.teamId);
if (message.bulletLocalId != null && Object.hasOwnProperty.call(message, "bulletLocalId"))
writer.uint32(/* id 20, wireType 0 =*/160).int32(message.bulletLocalId);
if (message.speciesId != null && Object.hasOwnProperty.call(message, "speciesId"))
writer.uint32(/* id 21, wireType 0 =*/168).int32(message.speciesId);
if (message.virtualGridX != null && Object.hasOwnProperty.call(message, "virtualGridX"))
writer.uint32(/* id 999, wireType 0 =*/7992).int32(message.virtualGridX);
if (message.virtualGridY != null && Object.hasOwnProperty.call(message, "virtualGridY"))
@@ -5191,6 +5225,10 @@ $root.protos = (function() {
message.bulletLocalId = reader.int32();
break;
}
case 21: {
message.speciesId = reader.int32();
break;
}
case 999: {
message.virtualGridX = reader.int32();
break;
@@ -5314,6 +5352,9 @@ $root.protos = (function() {
if (message.bulletLocalId != null && message.hasOwnProperty("bulletLocalId"))
if (!$util.isInteger(message.bulletLocalId))
return "bulletLocalId: integer expected";
if (message.speciesId != null && message.hasOwnProperty("speciesId"))
if (!$util.isInteger(message.speciesId))
return "speciesId: integer expected";
if (message.virtualGridX != null && message.hasOwnProperty("virtualGridX"))
if (!$util.isInteger(message.virtualGridX))
return "virtualGridX: integer expected";
@@ -5390,6 +5431,8 @@ $root.protos = (function() {
message.teamId = object.teamId | 0;
if (object.bulletLocalId != null)
message.bulletLocalId = object.bulletLocalId | 0;
if (object.speciesId != null)
message.speciesId = object.speciesId | 0;
if (object.virtualGridX != null)
message.virtualGridX = object.virtualGridX | 0;
if (object.virtualGridY != null)
@@ -5441,6 +5484,7 @@ $root.protos = (function() {
object.blowUp = false;
object.teamId = 0;
object.bulletLocalId = 0;
object.speciesId = 0;
object.virtualGridX = 0;
object.virtualGridY = 0;
object.dirX = 0;
@@ -5489,6 +5533,8 @@ $root.protos = (function() {
object.teamId = message.teamId;
if (message.bulletLocalId != null && message.hasOwnProperty("bulletLocalId"))
object.bulletLocalId = message.bulletLocalId;
if (message.speciesId != null && message.hasOwnProperty("speciesId"))
object.speciesId = message.speciesId;
if (message.virtualGridX != null && message.hasOwnProperty("virtualGridX"))
object.virtualGridX = message.virtualGridX;
if (message.virtualGridY != null && message.hasOwnProperty("virtualGridY"))