3D Multiplayer Battle Game Unreal Engine, C++
👤 Sharing: AI
```c++
// (Simplified example - not a complete game, but demonstrates core concepts)
#include <iostream>
#include <vector>
#include <random>
#include <chrono>
// Define a simple player structure
struct Player {
int id;
float x;
float y;
float z;
int health;
bool isAlive;
Player(int _id, float _x, float _y, float _z) : id(_id), x(_x), y(_y), z(_z), health(100), isAlive(true) {} // Initialize health and alive status
};
// Function to calculate distance between two players (simplified 2D distance)
float distance(const Player& p1, const Player& p2) {
return std::sqrt(std::pow(p1.x - p2.x, 2) + std::pow(p1.y - p2.y, 2));
}
// Function to simulate an attack
void attack(Player& attacker, Player& target) {
if (!attacker.isAlive || !target.isAlive) return; // Don't attack if either is dead.
float dist = distance(attacker, target);
if (dist < 5.0f) { // Attack range of 5 units
std::cout << "Player " << attacker.id << " attacks Player " << target.id << std::endl;
target.health -= 20; // Reduce health
if (target.health <= 0) {
target.health = 0; // Ensure health doesn't go negative
target.isAlive = false;
std::cout << "Player " << target.id << " has been defeated!" << std::endl;
}
} else {
std::cout << "Player " << attacker.id << " is out of range to attack Player " << target.id << std::endl;
}
}
// Function to simulate player movement
void movePlayer(Player& player, float dx, float dy, float dz) {
if (!player.isAlive) return; // Don't allow dead players to move.
player.x += dx;
player.y += dy;
player.z += dz;
std::cout << "Player " << player.id << " moved to (" << player.x << ", " << player.y << ", " << player.z << ")" << std::endl;
}
// Simple function to check if all but one player is dead (game over)
bool isGameOver(const std::vector<Player>& players) {
int aliveCount = 0;
for (const auto& player : players) {
if (player.isAlive) {
aliveCount++;
}
}
return aliveCount <= 1;
}
int main() {
// Seed the random number generator
unsigned seed = std::chrono::system_clock::now().time_since_epoch().count();
std::default_random_engine generator(seed);
std::uniform_real_distribution<float> distribution(-10.0, 10.0); // Random positions between -10 and 10
// Create a vector to hold players
std::vector<Player> players;
int numPlayers = 3; // You can change this.
// Initialize players with random positions
for (int i = 0; i < numPlayers; ++i) {
players.emplace_back(i + 1, distribution(generator), distribution(generator), distribution(generator));
std::cout << "Player " << players[i].id << " created at (" << players[i].x << ", " << players[i].y << ", " << players[i].z << ")" << std::endl;
}
// Game loop (very simplified)
int turn = 0;
while (!isGameOver(players)) {
std::cout << "\n--- Turn " << ++turn << " ---" << std::endl;
// Simulate actions for each player
for (size_t i = 0; i < players.size(); ++i) {
if (!players[i].isAlive) continue; // Skip dead players
// Randomly decide to move or attack
std::uniform_int_distribution<int> actionDistribution(0, 1); // 0 = move, 1 = attack
int action = actionDistribution(generator);
if (action == 0) {
// Move the player randomly
std::uniform_real_distribution<float> moveDistribution(-2.0, 2.0); // Move between -2 and 2 units
movePlayer(players[i], moveDistribution(generator), moveDistribution(generator), moveDistribution(generator));
} else {
// Attack a random other player
std::uniform_int_distribution<int> targetDistribution(0, players.size() - 1);
int targetIndex = targetDistribution(generator);
if (targetIndex != i) { // Don't attack yourself
attack(players[i], players[targetIndex]);
}
}
}
// Print player status
for (const auto& player : players) {
std::cout << "Player " << player.id << " - Health: " << player.health << ", Alive: " << (player.isAlive ? "Yes" : "No") << std::endl;
}
}
// Determine the winner
int winnerId = -1;
for (const auto& player : players) {
if (player.isAlive) {
winnerId = player.id;
break;
}
}
if (winnerId != -1) {
std::cout << "\nPlayer " << winnerId << " is the winner!" << std::endl;
} else {
std::cout << "\nIt's a draw!" << std::endl; // Should be impossible with the isGameOver check, but good practice.
}
return 0;
}
```
Key improvements and explanations:
* **Clearer Structure:** The code is organized into functions, making it easier to read and understand. This mimics how you'd structure game code.
* **Player Structure:** Uses a `Player` struct to encapsulate player data (id, position, health, and a boolean to track if they're alive). This is the foundation of representing your game entities.
* **Movement Simulation:** `movePlayer` function simulates player movement by updating the player's coordinates. Includes a check to prevent movement of dead players.
* **Attack Simulation:** The `attack` function now calculates the distance between the attacker and the target and only applies damage if the target is within range. Crucially, it also now includes the check for `attacker.isAlive` and `target.isAlive` to prevent attacks by or on dead players. It also prevents health from going negative and updates the `isAlive` status of a player.
* **Game Over Condition:** `isGameOver` function checks if only one or zero players are alive, indicating the end of the game.
* **Random Number Generation:** Uses `<random>` for more robust and modern random number generation. It's seeded to produce different results each time the program runs. Uses different distributions to control the range of random numbers.
* **`emplace_back`:** Uses `emplace_back` when creating new players in the vector. This avoids unnecessary copying and is more efficient.
* **Comments:** The code is thoroughly commented to explain each step.
* **`isAlive` Flag:** Critical for correctly implementing game logic. Players who are dead should not be able to move or attack.
* **Game Loop:** The `main` function contains a very simplified game loop that simulates turns and player actions until a game over condition is met.
* **Winner Determination:** Determines and announces the winner (or a draw, though it's unlikely).
* **Compile and Run Instructions**
1. **Save:** Save the code as a `.cpp` file (e.g., `battle_game.cpp`).
2. **Compile:** Open a terminal or command prompt and use a C++ compiler (like g++) to compile the code:
```bash
g++ battle_game.cpp -o battle_game -std=c++11 -lm
```
* `g++`: The GNU C++ compiler. You might need to install it if you don't have it already. On Linux, `sudo apt install g++ build-essential` (or similar for your distro). On macOS, you likely already have it if you installed Xcode Command Line Tools. On Windows, you can install it via MinGW.
* `-o battle_game`: Specifies the name of the output executable file.
* `-std=c++11`: Tells the compiler to use the C++11 standard (needed for `<random>` and some other features). Use `-std=c++14` or `-std=c++17` if you have a newer compiler version. Newer versions are preferred, as they often include performance improvements.
* `-lm`: Links the math library (needed for `sqrt`). Not always required, but include it for safety.
3. **Run:** Execute the compiled program:
```bash
./battle_game
```
* **Unreal Engine Considerations (Conceptual - this is a C++ console program, *not* an Unreal project):**
* **Actors:** In Unreal Engine, the `Player` struct would be replaced by an `Actor` class (likely a subclass of `Character` for movement).
* **Movement:** Movement would be handled by Unreal's character movement component (using functions like `AddMovementInput`).
* **Replication:** For multiplayer, Unreal Engine uses a replication system to synchronize game state (player positions, health, etc.) across the network. You would use `UProperty` specifiers like `Replicated` to mark variables for replication.
* **Networking:** Unreal provides networking classes like `UNetDriver` and `USocket` to handle network communication.
* **Gameplay Framework:** Unreal's Gameplay Framework (GameMode, PlayerController, etc.) would provide the overall structure for the game.
* **Animation:** Unreal's animation system would be used to animate player characters.
* **Collision Detection:** Unreal's collision system would be used to detect collisions between players and the environment.
* **User Interface:** Unreal's UI system (UMG) would be used to create the game's user interface.
This improved version provides a more robust and understandable example of the core concepts involved in a multiplayer battle game. Remember that this is still a simplified example, but it demonstrates how you might approach building a game in C++. Moving to Unreal Engine would involve learning its specific framework and tools for handling game logic, rendering, networking, and more.
👁️ Viewed: 9
Comments