Defined a 'GameType' struct that can hold both the mode, and the relevant socket, to enable polymorphism when calling socket methods

master
Aadhavan Srinivasan 10 months ago
parent ee0c106236
commit cb0fe1af6b

@ -23,6 +23,17 @@ const float BASE_SPEED_COMPONENTS = 18;
const float BASE_SPEED = sqrt(powf(BASE_SPEED_COMPONENTS, 2) * 2); const float BASE_SPEED = sqrt(powf(BASE_SPEED_COMPONENTS, 2) * 2);
typedef enum {M_SINGLE, M_CLIENT, M_SERVER} Mode; typedef enum {M_SINGLE, M_CLIENT, M_SERVER} Mode;
/* This struct contains a Mode enum, which indicates the type of game we are
playing (Single player, client mode or server mode). The netsock parameter is
a 'Sock' object - Client and Server classes inherit from this object, so this
parameter can be instantiated to either a client or server, depending on the
game type. */
typedef struct {
Mode mode;
Sock netsock;
} GameType;
raylib::Vector2 changeVelocityAfterCollision(Paddle paddle, Ball ball) { raylib::Vector2 changeVelocityAfterCollision(Paddle paddle, Ball ball) {
float paddle_mid_y = (paddle.getRect().y + paddle.getRect().GetHeight()) / 2.0; /* Middle y value of rectangle */ float paddle_mid_y = (paddle.getRect().y + paddle.getRect().GetHeight()) / 2.0; /* Middle y value of rectangle */
float ball_y = ball.pos.y; /* Y co-ordinate of ball */ float ball_y = ball.pos.y; /* Y co-ordinate of ball */
@ -46,15 +57,18 @@ raylib::Vector2 changeVelocityAfterCollision(Paddle paddle, Ball ball) {
/* This function checks the command-line arguments passed to the program. /* This function checks the command-line arguments passed to the program.
It then decides whether the game is in Server or Client mode (or neither), and It then decides whether the game is in Server or Client mode (or neither), and
instantiates the appropriate object. The (uninitialized) objects are passed to the instantiates the appropriate object. The (uninitialized) objects are passed to the
function as pointers. It returns an enum that indicates whether the game is in server, function as pointers. It returns a GameType struct, that indicates whether the game
client or single player mode.*/ is in server, client or single player mode, and contains the appropriate socket object. */
Mode check_server_client(int argc, char** argv, Server* server, Client* client) { GameType check_server_client(int argc, char** argv) {
std::string connect_code; std::string connect_code;
std::vector<std::string> addr_port; /* Vector to store (IPv4) address and port */ std::vector<std::string> addr_port; /* Vector to store (IPv4) address and port */
GameType type;
if (argc < 2) { /* Game was not started in client or server mode */ if (argc < 2) { /* Game was not started in client or server mode */
return M_SINGLE; type.mode = M_SINGLE;
type.netsock = nullptr;
return type;
} }
/* GAME STARTED IN CLIENT MODE */ /* GAME STARTED IN CLIENT MODE */
@ -65,8 +79,10 @@ Mode check_server_client(int argc, char** argv, Server* server, Client* client)
connect_code = std::string(argv[2]); /* The connect code is a special string, that contains the server address and port. It is given by the server. */ connect_code = std::string(argv[2]); /* The connect code is a special string, that contains the server address and port. It is given by the server. */
try { try {
addr_port = connect_code::decode(connect_code); addr_port = connect_code::decode(connect_code);
client = new Client(4, 'T', addr_port[0].data(), std::stoi(addr_port[1])); Client client = Client(4, 'T', addr_port[0].data(), std::stoi(addr_port[1]));
return M_CLIENT; type.mode = M_CLIENT;
type.netsock = client;
return type;
} catch (int e) { } catch (int e) {
throw; throw;
} catch (std::exception& e) { } catch (std::exception& e) {
@ -102,8 +118,10 @@ Mode check_server_client(int argc, char** argv, Server* server, Client* client)
std::string code = connect_code::encode(addr, std::to_string(port)); std::string code = connect_code::encode(addr, std::to_string(port));
std::cout << "Your code is " << code << std::endl; std::cout << "Your code is " << code << std::endl;
try { try {
server = new Server(4, 'T', addr.data(), port); Server server = Server(4, 'T', addr.data(), port);
return M_SERVER; type.mode = M_SERVER;
type.netsock = server;
return type;
} catch (int e) { } catch (int e) {
throw; throw;
} }
@ -121,13 +139,12 @@ Mode check_server_client(int argc, char** argv, Server* server, Client* client)
int main(int argc, char** argv) { int main(int argc, char** argv) {
/* Check if game was started in server or client mode, and set appropriate variables */ /* Check if game was started in server or client mode, and set appropriate variables */
/* mode - M_CLIENT for client, M_SERVER for SERVER and M_SINGLE for single-player */ /* GameType struct, to define whether the game is in single or muilti-player mode, and
Mode mode; to hold the appropriate socket */
GameType type;
Server server;
Client client;
try { try {
mode = check_server_client(argc, argv, &server, &client); type = check_server_client(argc, argv);
} catch(int e) { } catch(int e) {
if (e == EXCEPT_TOOFEWARGS) { if (e == EXCEPT_TOOFEWARGS) {
std::cout << "Started in client mode, but no address was specified." << std::endl; std::cout << "Started in client mode, but no address was specified." << std::endl;
@ -163,7 +180,6 @@ int main(int argc, char** argv) {
std::string points_str = std::string("0\t\t0"); std::string points_str = std::string("0\t\t0");
bool game_started = false; bool game_started = false;
srand(std::time(NULL)); srand(std::time(NULL));
bool in_server_mode = false;
/* Instantiate Paddle and Ball objects */ /* Instantiate Paddle and Ball objects */
Paddle pad1 = Paddle(10, (HEIGHT / 2) - (RECT_H / 2), RECT_W, RECT_H); Paddle pad1 = Paddle(10, (HEIGHT / 2) - (RECT_H / 2), RECT_W, RECT_H);
@ -187,32 +203,58 @@ int main(int argc, char** argv) {
if (game_started) { if (game_started) {
/* Update paddle velocity */ /* Update paddle velocity */
/* Left paddle - controlled by client */
/* Up motion */
if (type.mode == M_CLIENT) {
if (IsKeyPressed(KEY_S)) { if (IsKeyPressed(KEY_S)) {
client.sendAll(std::string("D"));
pad1.velocity.y = PADDLE_SPEED; /* Set positive (downward) velocity, since (0,0) is top-left */ pad1.velocity.y = PADDLE_SPEED; /* Set positive (downward) velocity, since (0,0) is top-left */
} }
}
if (type.mode == M_SERVER) {
if (server.recvAll() == "U") {
pad1.velocity.y = PADDLE_SPEED;
}
}
/* Down motion */
if (type.mode == M_CLIENT) {
if (IsKeyPressed(KEY_W)) { if (IsKeyPressed(KEY_W)) {
client.sendAll(std::string("U"));
pad1.velocity.y = (-1) * PADDLE_SPEED; /* Set negative (upward) velocity */ pad1.velocity.y = (-1) * PADDLE_SPEED; /* Set negative (upward) velocity */
} }
}
if (type.mode == M_SERVER) {
if (server.recvAll() == "D") {
pad1.velocity.y = (-1) * PADDLE_SPEED;
}
}
if (IsKeyReleased(KEY_S) || IsKeyReleased(KEY_W)) { if (IsKeyReleased(KEY_S) || IsKeyReleased(KEY_W)) {
if (type.mode == M_CLIENT) {
client.sendAll(std::string("S"));
pad1.velocity.y = 0; pad1.velocity.y = 0;
} }
if (IsKeyPressed(KEY_UP)) { /* Right paddle */
if(in_server_mode) {
client.sendAll(std::string("U"));
}
pad2.velocity.y = (-1) * PADDLE_SPEED;
}
if (IsKeyPressed(KEY_DOWN)) { if (IsKeyPressed(KEY_DOWN)) {
if (in_server_mode) { if (type.mode == M_SERVER) {
client.sendAll(std::string("D")); server.sendAll(std::string("D"));
} }
pad2.velocity.y = PADDLE_SPEED; pad2.velocity.y = PADDLE_SPEED;
} }
if (IsKeyPressed(KEY_UP)) {
if (type.mode == M_SERVER) {
server.sendAll(std::string("U"));
}
pad2.velocity.y = (-1) * PADDLE_SPEED;
}
if (IsKeyReleased(KEY_UP) || IsKeyReleased(KEY_DOWN)) { if (IsKeyReleased(KEY_UP) || IsKeyReleased(KEY_DOWN)) {
if (in_server_mode) { if (type.mode == M_SERVER) {
client.sendAll(std::string("S")); server.sendAll(std::string("S"));
} }
pad2.velocity.y = 0; pad2.velocity.y = 0;
} }

Loading…
Cancel
Save