Игровая логика PvP: сервер (C++) + клиент (Quintus.js)
Сервер: Game — authoritative-тик 20 Гц через uSockets timer, движение/коллизии танков и пуль, разрушаемые кирпичные стены, respawn, победа/поражение/ничья, технический проигрыш при дисконнекте. game.ready запускает матч, когда оба игрока в pvp-комнате готовы. Клиент: заведён Quintus.js (MIT, vendored) — Tank/Bullet/Wall спрайты, рендер по снапшотам game.state, keyboard-инпут (WASD/стрелки/space), экран результата матча. Найден и исправлен use-after-free: колбэк onFinished_ синхронно удалял Game изнутри его же метода — перенесено на uWS::Loop::defer.
This commit is contained in:
@@ -1,6 +1,7 @@
|
||||
#pragma once
|
||||
|
||||
#include <App.h>
|
||||
#include <memory>
|
||||
#include <nlohmann/json.hpp>
|
||||
#include <string>
|
||||
#include <unordered_map>
|
||||
@@ -17,10 +18,13 @@ struct PerSocketData {
|
||||
|
||||
using WS = uWS::WebSocket<false, true, PerSocketData>;
|
||||
|
||||
class Game;
|
||||
|
||||
struct RoomPlayer {
|
||||
std::string player_id;
|
||||
std::string nickname;
|
||||
WS *ws;
|
||||
bool ready = false;
|
||||
};
|
||||
|
||||
struct Room {
|
||||
@@ -33,6 +37,9 @@ struct Room {
|
||||
// Лобби и реестр комнат (этап 3 из TZ.md). Игровая логика — этапы 4-5.
|
||||
class Lobby {
|
||||
public:
|
||||
Lobby();
|
||||
~Lobby();
|
||||
|
||||
void onOpen(WS *ws);
|
||||
void onMessage(WS *ws, std::string_view message);
|
||||
void onClose(WS *ws);
|
||||
@@ -41,6 +48,7 @@ private:
|
||||
static constexpr size_t kMaxPlayersPerRoom = 2;
|
||||
|
||||
std::unordered_map<std::string, Room> rooms_;
|
||||
std::unordered_map<std::string, std::unique_ptr<Game>> games_;
|
||||
std::unordered_set<WS *> sockets_;
|
||||
int next_player_id_ = 1;
|
||||
int next_room_id_ = 1;
|
||||
@@ -50,7 +58,11 @@ private:
|
||||
void handleCreateRoom(WS *ws, const json &payload);
|
||||
void handleJoinRoom(WS *ws, const json &payload);
|
||||
void handleLeaveRoom(WS *ws);
|
||||
void handleGameReady(WS *ws);
|
||||
void handleGameInput(WS *ws, const json &payload);
|
||||
void removePlayerFromRoom(WS *ws);
|
||||
void maybeStartGame(const std::string &room_id);
|
||||
void endActiveGameIfAny(const std::string &room_id, WS *leavingWs);
|
||||
|
||||
void broadcastRoomsToLobby();
|
||||
void broadcastRoomUpdated(const Room &room, WS *exclude = nullptr);
|
||||
|
||||
Reference in New Issue
Block a user