本篇将全面解构“水浒传”子游戏的服务端核心逻辑、帧同步机制、鱼群刷新规则、客户端命中表现与服务器计算之间的协同方式,聚焦于 C++ 与 Unity3D 跨端同步的真实实现过程。
一、水浒传捕鱼模块资源结构
该模块包含三部分核心目录:
子游戏/game_shuihuzhuan/
├── FishDefine.h // 鱼种类定义
├── FishManager.cpp // 鱼生成与路径控制
├── BulletManager.cpp // 子弹轨迹与发射控制
├── HitLogic.cpp // 命中判定与服务器广播
└── Config/ // 鱼概率配置表、路径曲线表
二、服务器帧同步设计(C++)
服务器采用固定 20ms 一帧逻辑更新,通过定时器广播当前房间状态:
void Room::UpdateFrame() {
for (auto& bullet : bullets_) bullet.Update();
for (auto& fish : fishes_) fish.Move();
BroadcastFrame();
}
void Room::BroadcastFrame() {
FrameData data;
data.bulletPos = bullets_; // 子弹位置包
data.fishPos = fishes_; // 鱼位置包
SendToAllPlayers(data);
}
三、鱼群生成逻辑
使用配置文件驱动鱼阵曲线轨迹:
{
"group_id": 102,
"curve": [ {"x":0,"y":0}, {"x":10,"y":50}, {"x":30,"y":90} ],
"spawn_count": 20,
"interval": 1500
}
生成逻辑 C++ 实现:
void FishManager::SpawnGroup(int groupId) {
FishGroup group = LoadGroup(groupId);
for (int i = 0; i < group.count; ++i) {
fishes_.push_back(CreateFish(group.curve, i * group.interval));
}
}
四、命中判定逻辑
服务器不信任客户端命中信息,而是根据服务器帧内坐标反推命中:
bool HitLogic::IsHit(Bullet b, Fish f) {
float dx = b.x - f.x;
float dy = b.y - f.y;
float dist = sqrt(dx*dx + dy*dy);
return dist < f.hitRadius;
}
void Room::OnHitCheck() {
for (auto& b : bullets_) {
for (auto& f : fishes_) {
if (IsHit(b, f)) {
KillFish(f);
break;
}
}
}
}
五、客户端表现与反馈机制(Unity)
客户端每帧根据服务器广播更新鱼与子弹坐标,不处理命中,仅播放动画。
void OnFrameSync(FrameData data) {
UpdateFishPositions(data.fishPos);
UpdateBulletPositions(data.bulletPos);
}
void PlayFishDeath(Fish fish) {
// 播放击杀特效
Instantiate(deathEffect, fish.Position, Quaternion.identity);
}
命中事件从服务器下发:
void OnFishDead(ServerKillData data) {
var fish = FindFish(data.fishId);
PlayFishDeath(fish);
ShowScore(data.score);
}
六、网络协议结构
服务器至客户端:
message FrameData {
repeated Bullet bullets = 1;
repeated Fish fishes = 2;
}
message ServerKillData {
required int32 fishId = 1;
required int32 score = 2;
}
七、小结
本篇通过服务器帧同步逻辑、鱼群生成、命中判定、客户端表现、通信协议等方面,拆解了水浒传捕鱼的完整联动机制。其帧同步思路具备较高参考价值,支持服务器绝对主导控制,适合高并发互动场景。下一篇将深入“拉霸机”子模块的物理滚轮实现与服务器开奖逻辑。