|
|
@ -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;
|
|
|
|
}
|
|
|
|
}
|
|
|
|