Moved struct definition to separate file, and added check for displaying GUI

I moved the GameType struct (and the Mode enum) to a separate file, as I will need
to use it in the check_server and check_client functions as well. I also added the
signum function (which was previously in sign.hpp) to this file, since it was the only
function in sign.hpp. Finally, I added a check, that will only display the GUI, if the
user didn't provide any command-line arguments.
master
Aadhavan Srinivasan 10 months ago
parent 788b334e7c
commit 352d3f26f1

@ -23,15 +23,14 @@
#define RAYGUI_IMPLEMENTATION
#include "includes/raygui/raygui.h"
#include "includes/raygui/style_dark.h"
#include "includes/paddle.hpp"
#include "includes/ball.hpp"
#include "includes/easysock.hpp"
#include "includes/sign.hpp"
#include "includes/connect_code.hpp"
#include "includes/easysock.hpp"
#include "includes/client.hpp"
#include "includes/server.hpp"
#include "includes/exception_consts.hpp"
#include "includes/check_input.hpp"
#include "includes/serialization.h"
#include "includes/timer.h"
@ -47,18 +46,12 @@ const float BASE_BOUNCE_RAD = (BASE_BOUNCE_DEG / 180.0) * M_PI;
const float BASE_SPEED_COMPONENTS = 15;
const float BASE_SPEED = sqrt(powf(BASE_SPEED_COMPONENTS, 2) * 2);
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;
/* Simple function to return 1 if a value is positive, and -1 if it is negative */
int signum(int num) {
int retval = 0;
(num > 0) ? retval = 1 : retval = -1;
return retval;
}
raylib::Vector2 changeVelocityAfterCollision(Paddle paddle, Ball ball) {
float paddle_mid_y = (paddle.getRect().y + paddle.getRect().GetHeight()) / 2.0; /* Middle y value of rectangle */
@ -223,93 +216,96 @@ int main(int argc, char** argv) {
bool game_started = false;
srand(std::time(NULL));
/* If there were no command-line arguments, the user is prompted in the GUI */
if (argc == 1) {
/* Display a drop-down menu, to allow user to pick between Single player, server and client. This section of the code uses the raygui library, and is written in C. */
GuiLoadStyleDark(); // Load the dark theme style
/* Modify the default style, by changing font size and spacing */
int font_size = 25;
int font_spacing = 2;
GuiSetStyle(DEFAULT, TEXT_SIZE, font_size);
GuiSetStyle(DEFAULT, TEXT_SPACING, font_spacing);
/* Set variables to position objects on screen */
int selected_item = 0; // variable to hold the index of the selected item
const char* text_to_display = "Select Game Mode"; // Text to display
/* Size of the label, drop down box and button */
Vector2 label_size = MeasureTextEx(GetFontDefault(), text_to_display, font_size, font_spacing); // Set the size based on the width of the string to print, the font size and the text spacing. I added 1 to font_size and font_spacing, to account for any possible rounding errors, since the function expects floats.
Vector2 box_size = Vector2{label_size.x, HEIGHT / 20};
bool is_being_edited = false; // Indicates whether the drop-down menu is being 'edited' i.e. whether an option is being selected
bool button_pressed = false; // Indicates whether the submit button has been pressed
/* Display a drop-down menu, to allow user to pick between Single player, server and client. This section of the code uses the raygui library, and is written in C. */
GuiLoadStyleDark(); // Load the dark theme style
/* Modify the default style, by changing font size and spacing */
int font_size = 25;
int font_spacing = 2;
GuiSetStyle(DEFAULT, TEXT_SIZE, font_size);
GuiSetStyle(DEFAULT, TEXT_SPACING, font_spacing);
/* Set variables to position objects on screen */
int selected_item = 0; // variable to hold the index of the selected item
const char* text_to_display = "Select Game Mode"; // Text to display
/* Size of the label, drop down box and button */
Vector2 label_size = MeasureTextEx(GetFontDefault(), text_to_display, font_size, font_spacing); // Set the size based on the width of the string to print, the font size and the text spacing. I added 1 to font_size and font_spacing, to account for any possible rounding errors, since the function expects floats.
Vector2 box_size = Vector2{label_size.x, HEIGHT / 20};
bool is_being_edited = false; // Indicates whether the drop-down menu is being 'edited' i.e. whether an option is being selected
bool button_pressed = false; // Indicates whether the submit button has been pressed
while (button_pressed == false) {
BeginDrawing();
ClearBackground(BLACK);
GuiLabel(Rectangle{(WIDTH/2)-(label_size.x/2), (HEIGHT/8), label_size.x, label_size.y}, text_to_display); // Label to display text on top
if (is_being_edited) {
GuiLock(); // If the drop-down menu is being 'edited', we need to prevent the user from modifying any other aspect of the UI
}
/* Button that allows user to proceed */
button_pressed = GuiButton(Rectangle{(WIDTH/2)-(box_size.x/2), (HEIGHT/2) + (HEIGHT/8), box_size.x, box_size.y}, "Continue");
/* Drop-down menu, that allows user to select game mode */
if (GuiDropdownBox(Rectangle{(WIDTH/2) - (box_size.x/2), (HEIGHT/2) - (HEIGHT/8), box_size.x, box_size.y}, "SINGLE;CLIENT;SERVER", &selected_item, is_being_edited)) { // This function returns != 0 if there was a mouse click inside the dropdown area
is_being_edited = !is_being_edited; // If the dropdown menu was selected, then it is being edited (or not being edited, if it previously was).
}
GuiUnlock();
EndDrawing();
}
/* Single player mode */
if (selected_item == M_SINGLE) {
GuiSetStyle(DEFAULT, TEXT_WRAP_MODE, TEXT_WRAP_WORD); // Enable text wrapping so that the long text, displayed below, will be wrapped
BeginDrawing();
ClearBackground(BLACK);
GuiLabel(Rectangle{(WIDTH/2)-(WIDTH/8), (HEIGHT/2)-(HEIGHT/8), WIDTH/4, HEIGHT/4}, "W and S control left paddle, Up and Down arrow keys control right paddle. Good luck!");
EndDrawing();
Timer timer = timer_init(5);
while (!timer_done(timer));
}
/* Server mode, ask user to input IP address and port */
if (selected_item == M_SERVER) {
button_pressed = false; // Whether submit button is pressed
char* ip_text = (char *)calloc(100, sizeof(char)); // Holds input of IP text box
char* port_text = (char *)calloc(20, sizeof(char)); // Holds input of port text box
const char* ip_label = "Local IP address";
const char* port_label = "Port number (1024 - 65535)";
int port_label_x_size = MeasureTextEx(GetFontDefault(), port_label, font_size, font_spacing).x; // Custom size for port label, because it's long
bool editing_ip = false; // Indicates whether the IP address text box is being edited
bool editing_port = false; // Indicates whether the port text box is being edited
while (button_pressed == false) {
BeginDrawing();
ClearBackground(BLACK);
/* Label and text box for IP address */
GuiLabel(Rectangle{(WIDTH/2)-(label_size.x/2), (HEIGHT/2) - (HEIGHT/6) - label_size.y - 10, label_size.x, label_size.y}, ip_label); // Label to display text on top
/* The reason this if statement exists, is largely the same as the reasoning for the drop-down menu. We want to make the text box editable
if it has been clicked. If it is already editable, we want to make it read-only if the user clicks outside the box. This functionality
is mostly handled in the GuiTextBox function. If the text box is in edit mode, this function returns nonzero if the user clicks INSIDE
the box. If the text box is in editable mode, this function returns nonzero if the user clicks OUTSIDE the box. */
if (GuiTextBox(Rectangle{(WIDTH/2) - (box_size.x/2), (HEIGHT/2) - (HEIGHT/6), box_size.x, box_size.y}, ip_text, 100, editing_ip)) {
editing_ip = !editing_ip;
GuiLabel(Rectangle{(WIDTH/2)-(label_size.x/2), (HEIGHT/8), label_size.x, label_size.y}, text_to_display); // Label to display text on top
if (is_being_edited) {
GuiLock(); // If the drop-down menu is being 'edited', we need to prevent the user from modifying any other aspect of the UI
}
/* Label and text box for port. See above for explanation of if statement. */
GuiLabel(Rectangle{(WIDTH/2)-(label_size.x/2), (HEIGHT/2) - label_size.y, port_label_x_size }, port_label); // Label to display text on top
if (GuiTextBox(Rectangle{(WIDTH/2) - (box_size.x/2), (HEIGHT/2), box_size.x, box_size.y}, port_text, 100, editing_port)) {
editing_port = !editing_port;
/* Button that allows user to proceed */
button_pressed = GuiButton(Rectangle{(WIDTH/2)-(box_size.x/2), (HEIGHT/2) + (HEIGHT/8), box_size.x, box_size.y}, "Continue");
/* Drop-down menu, that allows user to select game mode */
if (GuiDropdownBox(Rectangle{(WIDTH/2) - (box_size.x/2), (HEIGHT/2) - (HEIGHT/8), box_size.x, box_size.y}, "SINGLE;CLIENT;SERVER", &selected_item, is_being_edited)) { // This function returns != 0 if there was a mouse click inside the dropdown area
is_being_edited = !is_being_edited; // If the dropdown menu was selected, then it is being edited (or not being edited, if it previously was).
}
button_pressed = GuiButton(Rectangle{(WIDTH/2) - (box_size.x/2), (HEIGHT/2) + (HEIGHT/6), box_size.x, box_size.y}, "Start Server");
GuiUnlock();
EndDrawing();
}
/* Single player mode */
if (selected_item == M_SINGLE) {
GuiSetStyle(DEFAULT, TEXT_WRAP_MODE, TEXT_WRAP_WORD); // Enable text wrapping so that the long text, displayed below, will be wrapped
BeginDrawing();
ClearBackground(BLACK);
GuiLabel(Rectangle{(WIDTH/2)-(WIDTH/8), (HEIGHT/2)-(HEIGHT/8), WIDTH/4, HEIGHT/4}, "W and S control left paddle, Up and Down arrow keys control right paddle. Good luck!");
EndDrawing();
Timer timer = timer_init(5);
while (!timer_done(timer));
}
GameType type = check_server(ip_text, port_text);
/* Server mode, ask user to input IP address and port */
if (selected_item == M_SERVER) {
button_pressed = false; // Whether submit button is pressed
char* ip_text = (char *)calloc(100, sizeof(char)); // Holds input of IP text box
char* port_text = (char *)calloc(20, sizeof(char)); // Holds input of port text box
const char* ip_label = "Local IP address";
const char* port_label = "Port number (1024 - 65535)";
int port_label_x_size = MeasureTextEx(GetFontDefault(), port_label, font_size, font_spacing).x; // Custom size for port label, because it's long
bool editing_ip = false; // Indicates whether the IP address text box is being edited
bool editing_port = false; // Indicates whether the port text box is being edited
while (button_pressed == false) {
BeginDrawing();
ClearBackground(BLACK);
/* Label and text box for IP address */
GuiLabel(Rectangle{(WIDTH/2)-(label_size.x/2), (HEIGHT/2) - (HEIGHT/6) - label_size.y - 10, label_size.x, label_size.y}, ip_label); // Label to display text on top
/* The reason this if statement exists, is largely the same as the reasoning for the drop-down menu. We want to make the text box editable
if it has been clicked. If it is already editable, we want to make it read-only if the user clicks outside the box. This functionality
is mostly handled in the GuiTextBox function. If the text box is in edit mode, this function returns nonzero if the user clicks INSIDE
the box. If the text box is in editable mode, this function returns nonzero if the user clicks OUTSIDE the box. */
if (GuiTextBox(Rectangle{(WIDTH/2) - (box_size.x/2), (HEIGHT/2) - (HEIGHT/6), box_size.x, box_size.y}, ip_text, 100, editing_ip)) {
editing_ip = !editing_ip;
}
/* Label and text box for port. See above for explanation of if statement. */
GuiLabel(Rectangle{(WIDTH/2)-(label_size.x/2), (HEIGHT/2) - label_size.y, port_label_x_size }, port_label); // Label to display text on top
if (GuiTextBox(Rectangle{(WIDTH/2) - (box_size.x/2), (HEIGHT/2), box_size.x, box_size.y}, port_text, 100, editing_port)) {
editing_port = !editing_port;
}
button_pressed = GuiButton(Rectangle{(WIDTH/2) - (box_size.x/2), (HEIGHT/2) + (HEIGHT/6), box_size.x, box_size.y}, "Start Server");
EndDrawing();
}
type = check_server(ip_text, port_text);
free(ip_text);
free(port_text);
}
}
/* Variable to store the response given by the other player */

Loading…
Cancel
Save