From aabcfd164dc4a9d6002a0f88ac15d4da6cb655b2 Mon Sep 17 00:00:00 2001
From: g5-chappell <gareth2.chappell@live.uwe.ac.uk>
Date: Mon, 18 Jul 2022 01:25:04 +0000
Subject: [PATCH] Upload New File

---
 assignment/assignment.cpp | 415 ++++++++++++++++++++++++++++++++++++++
 1 file changed, 415 insertions(+)
 create mode 100644 assignment/assignment.cpp

diff --git a/assignment/assignment.cpp b/assignment/assignment.cpp
new file mode 100644
index 0000000..70526fd
--- /dev/null
+++ b/assignment/assignment.cpp
@@ -0,0 +1,415 @@
+// Included with assignment
+#include <iostream>
+#include <iomanip>
+#include <vector>
+#include <cstring>
+#include <tuple>
+
+// Included by 21015407 GARETH CHAPPELL
+// For rand() function
+#include <stdlib.h>
+
+// For time value
+#include <time.h>
+
+// Included with assignment
+// Accessing other files
+#include <context.hpp>
+#include <app.hpp>
+
+using namespace std;
+
+// NOTE:
+// I *still* can't get the batch files to work, and I don't know why.
+
+// Init values used to determine the width/
+// Modified the window dimension values from what was assigned by the assignment, so they're easier to work with in setting up UI and math stuff.
+const int width = 800;
+const int height = 600;
+
+// GAME SCREENS
+
+// 1. Title Screen - The player starts on the title screen. When they press A or D, the title screen closes, and the gameplay begins.
+
+// 2. Gameplay - The player controls a paddle with the A/D keys. The player must keep hitting a moving ball with the paddle
+// to prevent it from hitting the bottom of the screen, which ends the gameplay and displays the game over screen. A timer is displayed on the
+// top left of the screen, indicating the player's score.
+
+// 3. Game Over - When the player fails at the gameplay, the game over screen is displayed, showing their time score. Player can then press A or D
+// to play again.
+
+class MyApp: public uwe::App
+{
+
+private:
+
+// Init int value for generating random numbers
+int random_x;
+
+// Init values for top left of ball
+int ball_x_topleft;
+int ball_y_topleft;
+
+// Init value for top left of paddle
+int paddle_x_topleft;
+
+// Init int values for ball X/Y co-ordinates
+int ball_x;
+int ball_y;
+
+// Init int values for ball X/Y gradient values
+// These values are incremented/decremented every minute, increasing the difficulty over time.
+int ball_gradient_x;
+int ball_gradient_y;
+
+// Init int value for paddle X co-ordinates
+// Paddle Y is always 650
+int paddle_x;
+
+// Init boolean flags for game screens
+bool title_active = true;
+bool gameplay_active = false;
+bool gameover_active = false;
+
+// Init int value for timer, in seconds and minutes, and a counter to add 1 second per 60 frames.
+int counter;
+int time_seconds;
+int time_minutes;
+
+public:
+    MyApp(int width, int height, std::string title);
+    ~MyApp();
+
+    void begin() override;
+    void update() override;
+    void draw() override;
+
+    void key_pressed(uwe::Scancode scancode, bool repeat) override;
+
+    void mouse_pressed(int x, int y, uwe::Button button) override;
+    void mouse_released(int x, int y, uwe::Button button) override;
+    void mouse_moved(int x, int y) override;
+};
+
+MyApp::MyApp(int width, int height, std::string title)
+{
+    init(width, height, title);
+}
+
+MyApp::~MyApp()
+{
+
+}
+
+void MyApp::begin()
+{
+	// Init the random number seed with the time value.
+	srand (time(NULL));
+
+	// Init the font used for UI text.
+	UI_font = create_font("./assets/fonts/FreeSans.ttf", 15, uwe::Colour::white());
+	
+	// Adjust ball X/Y values
+	ball_x = 400;
+	ball_y = 600;
+	
+	// Randomise the X gradient for the start.
+	random_x = rand() % 1 - 2;
+	
+	switch (random_x)
+	{
+		case 1:
+		ball_gradient_x = -1;
+		break;
+		
+		case 2:
+		ball_gradient_x = 1;
+		break;
+	}
+	
+	// Set the Y gradient for the ball.
+	ball_gradient_y = -1;
+	
+}
+
+// This functions occur every frame (60 times per second)
+void MyApp::update()
+{
+	if (gameplay_active == true)
+	{
+		// Update paddle topleft
+		paddle_x_topleft = paddle_x - 25;
+		
+		// Update ball topleft
+		ball_x_topleft = ball_x - 10;
+		ball_y_topleft = ball_y - 10;
+		
+		// Update ball X/Y
+		ball_x = ball_x + ball_gradient_x;
+		ball_y = ball_y + ball_gradient_y;
+		
+		// If counter value is 60
+		// (i.e Every second)
+		if (counter == 60)
+		{
+			// Increment seconds timer, reset counter
+			timer_seconds++;
+			counter = 0;
+
+			// Adjust the gradients (in other words, the speed of the ball)
+			// Increment ball gradient X if positive
+			if (ball_gradient_x > 0)
+			{
+				ball_gradient_x++;
+			}
+
+			// Decrement ball gradient X if positive
+			if (ball_gradient_x < 0)
+			{
+				ball_gradient_x--;
+			}
+
+			// Increment ball gradient Y if positive
+			if (ball_gradient_y > 0)
+			{
+				ball_gradient_y++;
+			}
+
+			// Decrement ball gradient Y if positive
+			if (ball_gradient_y < 0)
+			{
+				ball_gradient_y--;
+			}
+		}
+
+		// If timer seconds value is 60
+		if (timer_seconds == 60)
+		{
+
+			// Increment minute timer, reset seconds
+			timer_minutes++;
+			timer_seconds = 0;
+		}
+
+		// If timer minutes is greater than 99, which would cause a minor visual error.
+		if (timer_minutes > 99)
+		{
+			timer_seconds = 0;
+			timer_minutes = 0;
+		}
+
+		// If ball is touching either left wall and right wall, and not touching the top or bottom wall.
+		if ((ball_x == 120 || ball_x == 680) && (ball_y != 680 && ball_y != 120))
+		{
+			// Multiply the X gradient by -1 to 'invert' the X gradient
+			// (i.e If the X gradient is 1, it is now -1. If the X gradient is -1, it is now 1.)
+			ball_gradient_x = ball_gradient_x * -1;
+		}
+
+		// If ball is not touching either the left or right wall, and touching the top wall.
+		if ((ball_x != 120 && ball_x != 680) && ball_y == 120)
+		{
+			// Multiply the Y gradient by -1 to invert the Y gradient.
+			// (i.e If the Y gradient is 1, it is now -1. If the Y gradient is -1, it is now 1.
+			ball_gradient_y = ball_gradient_y * -1;
+
+			// 50% chance to invert the X gradient.
+			random_x = rand() % 1 - 2;
+
+			switch (random_x)
+			{
+				case 1:
+				ball_gradient_x = ball_gradient_x * -1;
+				break;
+
+				case 2:
+				break;
+			}
+		}
+
+		// If the ball is touching the left or right wall, and is touching the top wall (i.e a perfect corner shot)
+		if ((ball_x == 120 || ball_x == 680) && ball_y == 120)
+		{
+			// Invert both gradients
+			ball_gradient_x = ball_gradient_x * -1;
+			ball_gradient_y = ball_gradient_y * -1;
+		}
+
+		// If the ball is touching the bottom wall (game over)
+		if (ball_y == 680)
+		{
+			gameplay_active = false;
+			gameover_active = true;
+		}
+
+		// If ball is touching the top of the paddle, and within the X co-ordinate of the paddle
+		if (ball_y == 630 && (ball_x > paddle_x - 50) && (ball_x < paddle_x + 50))
+		{
+			// Invert the Y gradient
+			ball_gradient_y = ball_gradient_y * -1;
+
+			// 50% chance to invert the X gradient, introducing a degree of randomness to the game
+			random_x = rand() % 1 - 2;
+
+			switch (random_x)
+			{
+				case 1:
+				ball_gradient_x = ball_gradient_x * -1;
+				break;
+
+				case 2:
+				break;
+			}
+
+		}
+
+
+	}
+}
+
+// When a key is pressed, this function is called.
+void MyApp::key_pressed(uwe::Scancode scancode, bool repeat)
+{
+    switch (scancode)
+	{
+		// If 'A' key is pressed
+		case uwe::Scancode::A:
+		{
+			// If title active
+			if (title_active == true)
+			{
+				gameplay_active = true;
+				title_active = false;
+			}
+
+			// If gameplay active and the paddle isn't touching the left wall
+			if (gameplay_active == true && paddle_x != 125)
+			{
+				paddle_x--;
+			}
+
+			// If gameover active
+			if (gameover_active == true)
+			{
+				gameplay_active = true;
+				gameover_active = false;
+			}
+
+		}
+
+		// If 'D' key is pressed
+		case uwe::Scancode::D:
+		{
+			// If title active
+			if (title_active == true)
+			{
+				gameplay_active = true;
+				title_active = false;
+			}
+
+			// If gameplay active and the paddle isn't touching the right wall
+			if (gameplay_active == true && paddle_x != 675)
+			{
+				paddle_x++;
+			}
+
+			// If gameover active
+			if (gameover_active == true)
+			{
+				gameplay_active = true;
+				gameover_active = false;
+			}
+		}
+
+         default:
+		{
+            // nothing see here
+        }
+    }
+}
+
+// When the mouse button is pressed, this function is called.
+void MyApp::mouse_pressed(int x, int y, uwe::Button button)
+{
+	// Unused.
+}
+
+// When the mouse button is released, this function is called.
+void MyApp::mouse_released(int x, int y, uwe::Button button)
+{
+	// Unused.
+}
+
+// When the mouse is moved, this function is called.
+void MyApp::mouse_moved(int x, int y)
+{
+	// Unused.
+}
+
+// This function is called per frame, to draw the contents of the window.
+void MyApp::draw()
+{
+	// Cover the screen in black
+	// This happens with every frame to avoid visual cluttering.
+    clear(uwe::Colour::black());
+
+	// Set the draw colour as white
+	set_draw_color(uwe::Colour(255,255,255,255));
+
+	// Title Screen
+	if (title_active == true)
+	{
+		
+		// Draw text
+		draw_font(UI_Font, "Bouncy Ball Game!", 100, 100);
+		draw_font(UI_Font, "Instructions:", 100, 125);
+		draw_font(UI_Font, "> Keep the ball away from the bottom of the screen for as long as possible. Hit it with your paddle!", 100, 150);
+		draw_font(UI_Font, "> Use the A and D keys to move the paddle left and right.", 100, 175);
+		draw_font(UI_Font, "> Good luck!", 100, 200);
+		
+	}
+
+	// Gameplay
+	if (gameplay_active == true)
+	{
+		
+		// Timer
+		draw_font(UI_Font, timer_minutes, 100, 50);
+		draw_font(UI_Font, ":", 130, 50);
+		draw_font(UI_Font, timer_seconds, 100, 50);
+		
+		// Boundary
+		draw_line(100, 100, 700, 100); // Top left to top right
+		draw_line(700, 100, 700, 700); // Top right to bottom right
+		draw_line(700, 700, 100, 700); // Bottom right to bottom left
+		draw_line(100, 700, 100, 100); // Bottom left to top left
+		
+		// Ball
+		draw_rect(ball_x_topleft, ball_y_topleft, 20, 20);
+		
+		// Paddle
+		draw_rect(paddle_x_topleft, 650, 50, 10);
+		
+	}
+
+	if (gameover_active == true)
+	{
+		
+		// Draw text
+		draw_font(UI_Font, "Game over!", 100, 100);
+		draw_font(UI_Font, "Score:", 100, 125);
+		draw_font(UI_Font, timer_minutes, 100, 150);
+		draw_font(UI_Font, "minutes!", 145, 150);
+		draw_font(UI_Font, "Press A or D to restart!", 100, 175);
+		
+	}
+
+}
+
+int main(int argc, char *argv[]) {
+    uwe::App* app = new MyApp{width, height, "21015407 Assignment RESIT - BOUNCY BALL"};
+
+    app->run();
+
+    return 0;
+}
-- 
GitLab