可通过 URL 自定义 lag
This commit is contained in:
parent
5c588ea56e
commit
171c0264a2
@ -2,7 +2,6 @@ import 'k8w-extend-native';
|
||||
import * as path from "path";
|
||||
import { WsConnection, WsServer } from "tsrpc";
|
||||
import { Room } from './models/Room';
|
||||
import { gameConfig } from './shared/game/gameConfig';
|
||||
import { serviceProto, ServiceType } from './shared/protocols/serviceProto';
|
||||
|
||||
// Create the Server
|
||||
@ -19,19 +18,7 @@ server.flows.postDisconnectFlow.push(v => {
|
||||
}
|
||||
|
||||
return v;
|
||||
})
|
||||
|
||||
// 模拟网络延迟
|
||||
if (gameConfig.networkLag) {
|
||||
server.flows.preRecvDataFlow.push(async v => {
|
||||
await new Promise(rs => { setTimeout(rs, gameConfig.networkLag) })
|
||||
return v;
|
||||
})
|
||||
server.flows.preSendDataFlow.push(async v => {
|
||||
await new Promise(rs => { setTimeout(rs, gameConfig.networkLag) })
|
||||
return v;
|
||||
})
|
||||
}
|
||||
});
|
||||
|
||||
export const roomInstance = new Room(server);
|
||||
|
||||
|
@ -43,12 +43,14 @@ export class GameSystem {
|
||||
else if (input.type === 'PlayerAttack') {
|
||||
let player = this._state.players.find(v => v.id === input.playerId);
|
||||
if (player) {
|
||||
this._state.arrows.push({
|
||||
let newArrow: ArrowState = {
|
||||
id: this._state.nextArrowId++,
|
||||
fromPlayerId: input.playerId,
|
||||
targetPos: { ...input.targetPos },
|
||||
targetTime: input.targetTime
|
||||
});
|
||||
};
|
||||
this._state.arrows.push(newArrow);
|
||||
this.onNewArrow.forEach(v => v(newArrow));
|
||||
}
|
||||
}
|
||||
else if (input.type === 'PlayerJoin') {
|
||||
@ -69,11 +71,6 @@ export class GameSystem {
|
||||
if (arrow.targetTime <= this._state.now) {
|
||||
// 伤害判定
|
||||
let damagedPlayers = this._state.players.filter(v => {
|
||||
// 不能伤害自己
|
||||
// if (v.id === arrow.fromPlayerId) {
|
||||
// return false;
|
||||
// }
|
||||
|
||||
return (v.pos.x - arrow.targetPos.x) * (v.pos.x - arrow.targetPos.x) + (v.pos.y - arrow.targetPos.y) * (v.pos.y - arrow.targetPos.y) <= gameConfig.arrowAttackRadius * gameConfig.arrowAttackRadius
|
||||
});
|
||||
damagedPlayers.forEach(p => {
|
||||
@ -81,11 +78,8 @@ export class GameSystem {
|
||||
p.dizzyEndTime = this._state.now + gameConfig.arrowDizzyTime;
|
||||
|
||||
// Event
|
||||
this.onDamage.forEach(h => h({
|
||||
fromPlayerId: arrow.fromPlayerId,
|
||||
toPlayerId: p.id
|
||||
}))
|
||||
})
|
||||
|
||||
this._state.arrows.splice(i, 1);
|
||||
}
|
||||
}
|
||||
@ -93,7 +87,7 @@ export class GameSystem {
|
||||
}
|
||||
|
||||
// Events (Game Push)
|
||||
onDamage: ((e: { fromPlayerId: number, toPlayerId: number }) => void)[] = [];
|
||||
onNewArrow: ((arrow: ArrowState) => void)[] = [];
|
||||
|
||||
}
|
||||
|
||||
|
@ -1,7 +1,5 @@
|
||||
export const gameConfig = {
|
||||
syncRate: 10,
|
||||
// 网络延迟(同时在服务端和客户端生效,所以实际是双倍延迟)
|
||||
networkLag: 200,
|
||||
|
||||
// 攻击技能的冷却时间(毫秒)
|
||||
attackCD: 1000,
|
||||
|
@ -1,6 +1,7 @@
|
||||
|
||||
import { Component, Vec3, _decorator } from 'cc';
|
||||
import { MathUtil } from '../../scripts/models/MathUtil';
|
||||
import { gameConfig } from '../../scripts/shared/game/gameConfig';
|
||||
import { ArrowState } from '../../scripts/shared/game/state/ArrowState';
|
||||
const { ccclass, property } = _decorator;
|
||||
|
||||
@ -27,7 +28,8 @@ export class Arrow extends Component {
|
||||
this._startPos.set(startPos);
|
||||
this._endPos.set(state.targetPos.x, 0, -state.targetPos.y);
|
||||
this._startTime = Date.now();
|
||||
this._endTime = this._startTime + state.targetTime - now;
|
||||
// 箭的展示与判定相分离,展示就按固定的飞行时长展示
|
||||
this._endTime = this._startTime + gameConfig.arrowFlyTime;
|
||||
|
||||
this._updatePosAndForward(0);
|
||||
}
|
||||
@ -36,6 +38,10 @@ export class Arrow extends Component {
|
||||
//下一个目标位置
|
||||
let percent = MathUtil.limit((Date.now() - this._startTime) / (this._endTime - this._startTime), 0, 1);
|
||||
this._updatePosAndForward(percent);
|
||||
|
||||
if (percent >= 1) {
|
||||
this.node.removeFromParent();
|
||||
}
|
||||
}
|
||||
|
||||
private _updatePosAndForward(percent: number) {
|
||||
|
@ -6,6 +6,7 @@ import { Player } from '../../prefabs/Player/Player';
|
||||
import { FollowCamera } from '../../scripts/components/FollowCamera';
|
||||
import { GameManager } from '../../scripts/models/GameManager';
|
||||
import { gameConfig } from '../../scripts/shared/game/gameConfig';
|
||||
import { ArrowState } from '../../scripts/shared/game/state/ArrowState';
|
||||
const { ccclass, property } = _decorator;
|
||||
|
||||
/**
|
||||
@ -41,8 +42,8 @@ export class GameScene extends Component {
|
||||
|
||||
gameManager!: GameManager;
|
||||
|
||||
private _playerInstances: { [playerId: number]: Player } = {};
|
||||
private _arrowInstances: { [arrowId: number]: Arrow } = {};
|
||||
private _playerInstances: { [playerId: number]: Player | undefined } = {};
|
||||
private _arrowInstances: { [arrowId: number]: Arrow | undefined } = {};
|
||||
private _selfSpeed?: Vec2 = new Vec2(0, 0);
|
||||
|
||||
onLoad() {
|
||||
@ -61,10 +62,18 @@ export class GameScene extends Component {
|
||||
}
|
||||
|
||||
this.gameManager = new GameManager();
|
||||
|
||||
// 监听数据状态事件
|
||||
this.gameManager.gameSystem.onNewArrow.push(v => { this._onNewArrow(v) });
|
||||
|
||||
// 断线一秒后重连
|
||||
this.gameManager.client.flows.postDisconnectFlow.push(v => {
|
||||
location.reload()
|
||||
setTimeout(() => {
|
||||
this.gameManager.join();
|
||||
}, 2000)
|
||||
return v;
|
||||
});
|
||||
|
||||
this.gameManager.join();
|
||||
}
|
||||
|
||||
@ -85,14 +94,13 @@ export class GameScene extends Component {
|
||||
}
|
||||
|
||||
this._updatePlayers();
|
||||
this._updateArrows();
|
||||
}
|
||||
|
||||
private _updatePlayers() {
|
||||
// Update pos
|
||||
let playerStates = this.gameManager.state.players;
|
||||
for (let playerState of playerStates) {
|
||||
let player: Player = this._playerInstances[playerState.id];
|
||||
let player = this._playerInstances[playerState.id];
|
||||
if (!player) {
|
||||
let node = instantiate(this.prefabPlayer);
|
||||
this.players.addChild(node);
|
||||
@ -119,33 +127,27 @@ export class GameScene extends Component {
|
||||
}
|
||||
}
|
||||
|
||||
private _updateArrows() {
|
||||
// Update pos
|
||||
let arrowStates = this.gameManager.state.arrows;
|
||||
for (let arrowState of arrowStates) {
|
||||
let arrow: Arrow = this._arrowInstances[arrowState.id];
|
||||
if (!arrow) {
|
||||
let playerState = this.gameManager.state.players.find(v => v.id === arrowState.fromPlayerId);
|
||||
if (!playerState) {
|
||||
continue;
|
||||
}
|
||||
let playerNode = this._playerInstances[playerState.id].node;
|
||||
|
||||
let node = instantiate(this.prefabArrow);
|
||||
this.arrows.addChild(node);
|
||||
arrow = this._arrowInstances[arrowState.id] = node.getComponent(Arrow)!;
|
||||
arrow.init(arrowState, playerNode.position, this.gameManager.state.now);
|
||||
}
|
||||
private _onNewArrow(arrowState: ArrowState) {
|
||||
let arrow = this._arrowInstances[arrowState.id];
|
||||
// 已经存在
|
||||
if (arrow) {
|
||||
return;
|
||||
}
|
||||
|
||||
// Clear left players
|
||||
for (let i = this.arrows.children.length - 1; i > -1; --i) {
|
||||
let arrow = this.arrows.children[i].getComponent(Arrow)!;
|
||||
if (!this.gameManager.state.arrows.find(v => v.id === arrow.id)) {
|
||||
arrow.node.removeFromParent();
|
||||
delete this._arrowInstances[arrow.id];
|
||||
}
|
||||
let playerState = this.gameManager.state.players.find(v => v.id === arrowState.fromPlayerId);
|
||||
if (!playerState) {
|
||||
return;
|
||||
}
|
||||
let playerNode = this._playerInstances[playerState.id]?.node;
|
||||
if (!playerNode) {
|
||||
return;
|
||||
}
|
||||
|
||||
// 创建新的箭矢显示
|
||||
let node = instantiate(this.prefabArrow);
|
||||
this.arrows.addChild(node);
|
||||
arrow = this._arrowInstances[arrowState.id] = node.getComponent(Arrow)!;
|
||||
arrow.init(arrowState, playerNode.position, this.gameManager.state.now);
|
||||
}
|
||||
|
||||
onBtnAttack() {
|
||||
@ -154,7 +156,11 @@ export class GameScene extends Component {
|
||||
return;
|
||||
}
|
||||
|
||||
let playerNode = this._playerInstances[this.gameManager.selfPlayerId].node;
|
||||
let playerNode = this._playerInstances[this.gameManager.selfPlayerId]?.node;
|
||||
if (!playerNode) {
|
||||
return;
|
||||
}
|
||||
|
||||
// 攻击落点偏移(表现层坐标)
|
||||
let sceneOffset = playerNode.forward.clone().normalize().multiplyScalar(gameConfig.arrowDistance);
|
||||
// 攻击落点(逻辑层坐标)
|
||||
|
@ -1,5 +1,4 @@
|
||||
import { WsClient } from "tsrpc-browser";
|
||||
import { gameConfig } from "../shared/game/gameConfig";
|
||||
import { GameSystem, GameSystemState } from "../shared/game/GameSystem";
|
||||
import { ClientInput, MsgClientInput } from "../shared/protocols/client/MsgClientInput";
|
||||
import { MsgFrame } from "../shared/protocols/server/MsgFrame";
|
||||
@ -27,14 +26,15 @@ export class GameManager {
|
||||
});;
|
||||
client.listenMsg('server/Frame', msg => { this._onServerSync(msg) });
|
||||
|
||||
// 模拟网络延迟
|
||||
if (gameConfig.networkLag) {
|
||||
// 模拟网络延迟 可通过 URL 参数 ?lag=200 设置延迟
|
||||
let networkLag = parseInt(new URLSearchParams(location.search).get('lag') || '0') || 0;
|
||||
if (networkLag) {
|
||||
client.flows.preRecvDataFlow.push(async v => {
|
||||
await new Promise(rs => { setTimeout(rs, gameConfig.networkLag) })
|
||||
await new Promise(rs => { setTimeout(rs, networkLag) })
|
||||
return v;
|
||||
});
|
||||
client.flows.preSendDataFlow.push(async v => {
|
||||
await new Promise(rs => { setTimeout(rs, gameConfig.networkLag) })
|
||||
await new Promise(rs => { setTimeout(rs, networkLag) })
|
||||
return v;
|
||||
});
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user