From 0396079e34733f6d6ef754733997a22866948fca Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tim=20Wei=C3=9Fker?= Date: Sun, 19 Mar 2023 17:51:22 +0100 Subject: [PATCH 01/15] Replace deprecated setColor functions on texts by setFillColor. --- game/src/Game.cpp | 24 ++++++++++++------------ game/src/Player.cpp | 2 +- 2 files changed, 13 insertions(+), 13 deletions(-) diff --git a/game/src/Game.cpp b/game/src/Game.cpp index 81fb3ad..5529ba0 100644 --- a/game/src/Game.cpp +++ b/game/src/Game.cpp @@ -206,22 +206,22 @@ void Game::renderTime(sf::RenderWindow* window) if (pointsRedTeam_ > pointsBlueTeam_) { - goalTextOne_.setColor(sf::Color(255,0,0)); + goalTextOne_.setFillColor(sf::Color(255,0,0)); goalTextOne_.setString("red wins"); - goalTextTwo_.setColor(sf::Color(255,0,0)); + goalTextTwo_.setFillColor(sf::Color(255,0,0)); } else if (pointsBlueTeam_ > pointsRedTeam_) { - goalTextOne_.setColor(sf::Color(0,0,255)); + goalTextOne_.setFillColor(sf::Color(0,0,255)); goalTextOne_.setString("blue wins"); - goalTextTwo_.setColor(sf::Color(0,0,255)); + goalTextTwo_.setFillColor(sf::Color(0,0,255)); } else { - goalTextOne_.setColor(sf::Color(0,0,0)); + goalTextOne_.setFillColor(sf::Color(0,0,0)); goalTextOne_.setString("draw"); - goalTextTwo_.setColor(sf::Color(0,0,0)); + goalTextTwo_.setFillColor(sf::Color(0,0,0)); } goalTextTwo_.setString(std::to_string(pointsBlueTeam_) + " to " + std::to_string(pointsRedTeam_)); @@ -247,11 +247,11 @@ void Game::renderTime(sf::RenderWindow* window) if (remainingSeconds <= 10) { - time_.setColor(sf::Color(255,255,0)); + time_.setFillColor(sf::Color(255,255,0)); } else { - time_.setColor(sf::Color(255,255,255)); + time_.setFillColor(sf::Color(255,255,255)); } if (inEndAnimation_) @@ -461,8 +461,8 @@ void Game::checkForGoal() ball_->setColor(sf::Color(0,0,0)); goalTextOne_.setString(ball_->getLastPlayerTouchName() + " scores"); - goalTextOne_.setColor(sf::Color(255, 0, 0)); - goalTextTwo_.setColor(sf::Color(255, 0, 0)); + goalTextOne_.setFillColor(sf::Color(255, 0, 0)); + goalTextTwo_.setFillColor(sf::Color(255, 0, 0)); celebratingTeam_ = sf::Color(255,0,0); goalTextTwo_.setString(std::to_string(pointsRedTeam_-1)); @@ -477,8 +477,8 @@ void Game::checkForGoal() ball_->setColor(sf::Color(0,0,0)); goalTextOne_.setString(ball_->getLastPlayerTouchName() + " scores"); - goalTextOne_.setColor(sf::Color(0, 0, 255)); - goalTextTwo_.setColor(sf::Color(0, 0, 255)); + goalTextOne_.setFillColor(sf::Color(0, 0, 255)); + goalTextTwo_.setFillColor(sf::Color(0, 0, 255)); celebratingTeam_ = sf::Color(0,0,255); goalTextTwo_.setString(std::to_string(pointsBlueTeam_-1)); diff --git a/game/src/Player.cpp b/game/src/Player.cpp index fbe4ded..3df9e19 100644 --- a/game/src/Player.cpp +++ b/game/src/Player.cpp @@ -33,7 +33,7 @@ Player::Player(int startX, int startY, sf::Color border, sf::Color center, std:: nameText_.setFont(font_); nameText_.setString(name_); - nameText_.setColor(sf::Color(0,0,0)); + nameText_.setFillColor(sf::Color(0,0,0)); nameText_.setCharacterSize(6.0/7.0 * radius_); } From 6a0f1327be8cb280b8353a3d0264a7275747102c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tim=20Wei=C3=9Fker?= Date: Sun, 19 Mar 2023 17:52:14 +0100 Subject: [PATCH 02/15] Prevent warning in InputHandler::removeDevice as not all branches returned a result. --- game/src/InputHandler.cpp | 1 + 1 file changed, 1 insertion(+) diff --git a/game/src/InputHandler.cpp b/game/src/InputHandler.cpp index 664a06a..9d32641 100644 --- a/game/src/InputHandler.cpp +++ b/game/src/InputHandler.cpp @@ -234,6 +234,7 @@ std::map::iterator InputHandler::removeDevice(int deviceID) currentInputDevicesMutex_.unlock(); return nextIterator; } + return currentInputDevices_.end(); } void InputHandler::processAddRemoveQueries() From fc562dabcf995eb0886b98587c7e35cc293988ff Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tim=20Wei=C3=9Fker?= Date: Sun, 19 Mar 2023 19:25:03 +0100 Subject: [PATCH 03/15] Make FPS display less conspicuous. --- game/include/Game.hpp | 2 ++ game/src/Game.cpp | 7 +++++-- 2 files changed, 7 insertions(+), 2 deletions(-) diff --git a/game/include/Game.hpp b/game/include/Game.hpp index de981f6..78312eb 100644 --- a/game/include/Game.hpp +++ b/game/include/Game.hpp @@ -4,7 +4,9 @@ #include #include #include +#include #include +#include #include #include #include diff --git a/game/src/Game.cpp b/game/src/Game.cpp index 5529ba0..0450e4b 100644 --- a/game/src/Game.cpp +++ b/game/src/Game.cpp @@ -188,7 +188,9 @@ void Game::renderScoreLine(sf::RenderWindow* window) void Game::renderFpsDisplay(sf::RenderWindow* window, float value) { - fpsString_.setString(std::to_string(value) + " fps"); + std::stringstream stream; + stream << std::fixed << std::setprecision(2) << value; + fpsString_.setString(stream.str() + " fps"); window->draw(fpsString_); } @@ -818,8 +820,9 @@ void Game::createFpsDisplay() fpsString_.setFont(font_); fpsString_.setCharacterSize(screenHeight_*0.03); + fpsString_.setFillColor(sf::Color(50,50,50)); - fpsString_.move(0.85*screenWidth_,0.94*screenHeight_); + fpsString_.move(0.88*screenWidth_,0.94*screenHeight_); } From efccb4e4f495c1cde346c8f9dbe1c6a0a9a78d13 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tim=20Wei=C3=9Fker?= Date: Sun, 19 Mar 2023 19:42:28 +0100 Subject: [PATCH 04/15] Adjust file path handling such that the console's working directory cannot prevent the application from working. --- backend/dictionary_builder/create_dictionary.py | 4 +++- game/include/Player.hpp | 3 ++- game/src/Game.cpp | 2 +- game/src/Player.cpp | 6 +++--- 4 files changed, 9 insertions(+), 6 deletions(-) diff --git a/backend/dictionary_builder/create_dictionary.py b/backend/dictionary_builder/create_dictionary.py index 4e158e4..f813367 100644 --- a/backend/dictionary_builder/create_dictionary.py +++ b/backend/dictionary_builder/create_dictionary.py @@ -1,3 +1,4 @@ +import os import sys # Command line parameters @@ -9,6 +10,7 @@ def start(): # get filenames and load files config_file_name = sys.argv[1] + config_file_abs_path = os.path.abspath(config_file_name) output_file_name = sys.argv[2] config_file = open(config_file_name, 'r') @@ -25,7 +27,7 @@ def start(): output_file.write('#include \n') output_file.write('\n') output_file.write('const std::string configuration_file("' + - config_file_name + '");\n') + config_file_abs_path + '");\n') output_file.write('std::map eventDictionary;\n') output_file.write('\n') output_file.write('void fillDictionary()\n') diff --git a/game/include/Player.hpp b/game/include/Player.hpp index 5c688db..5021b50 100644 --- a/game/include/Player.hpp +++ b/game/include/Player.hpp @@ -15,7 +15,7 @@ class Player : public PhysicalCircle { public: - Player(int startX, int startY, sf::Color border, sf::Color center, std::string const& name, int number); + Player(int startX, int startY, sf::Color border, sf::Color center, std::string const& name, int number, std::string resourcesPath); /* virtual */ void render(sf::RenderWindow* window) const; /* virtual */ void frameUpdate(); @@ -54,6 +54,7 @@ class Player : public PhysicalCircle int startX_; int startY_; + std::string resourcesPath_; sf::Text numberText_; sf::Text nameText_; sf::Font font_; diff --git a/game/src/Game.cpp b/game/src/Game.cpp index 0450e4b..86a47e1 100644 --- a/game/src/Game.cpp +++ b/game/src/Game.cpp @@ -83,7 +83,7 @@ Player* Game::addNewPlayer(std::string const& name) redNumbersInUse_[number] = true; } - Player* newPlayer = new Player(spawnPosition.x, spawnPosition.y, sf::Color(0,0,0), teamColor, name, number); + Player* newPlayer = new Player(spawnPosition.x, spawnPosition.y, sf::Color(0,0,0), teamColor, name, number, resourcesPath_); //adjust player radius to other players float newRadius; diff --git a/game/src/Player.cpp b/game/src/Player.cpp index 3df9e19..ce6cefd 100644 --- a/game/src/Player.cpp +++ b/game/src/Player.cpp @@ -1,8 +1,8 @@ #include "Player.hpp" -Player::Player(int startX, int startY, sf::Color border, sf::Color center, std::string const& name, int number) : +Player::Player(int startX, int startY, sf::Color border, sf::Color center, std::string const& name, int number, std::string resourcesPath) : PhysicalCircle(10.2, startX, startY, 35.0, 1.0), borderColor_(border), centerColor_(center), - blockShootFrames_(0), startX_(startX), startY_(startY), name_(name), shirtNumber_(number) + blockShootFrames_(0), startX_(startX), startY_(startY), resourcesPath_(resourcesPath), name_(name), shirtNumber_(number) { shootCircleRadius_ = computeShootCircleRadius(); @@ -22,7 +22,7 @@ Player::Player(int startX, int startY, sf::Color border, sf::Color center, std:: shootCircle_.setOrigin(shootCircleRadius_, shootCircleRadius_); shootCircle_.setPosition(startX, startY); - if (!font_.loadFromFile("resources/font.ttf")) + if (!font_.loadFromFile(resourcesPath_ + std::string("/font.ttf"))) { std::cout << "[Player.cpp] Error loading font." << std::endl; } From ffaf51e692bd9d1b89199e1a1ec8fe55eac9d154 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tim=20Wei=C3=9Fker?= Date: Sun, 19 Mar 2023 20:11:49 +0100 Subject: [PATCH 05/15] Update readme file with new instructions. --- README.md | 19 +------------------ 1 file changed, 1 insertion(+), 18 deletions(-) diff --git a/README.md b/README.md index 67a3c74..29b0677 100644 --- a/README.md +++ b/README.md @@ -3,7 +3,7 @@ The Massive Mobile Multiuser Framework is a software platform designed to enable # Setup and Installation - - Install necessary dependencies on server: SFML2, python3; if you use a Raspberry Pi, a special fork of SFML2 (e.g https://github.com/mickelson/sfml) needs to be compiled + - Install necessary dependencies on server: SFML, python3. If you use a Raspberry Pi, you previously needed a special fork of SFML (e.g https://github.com/mickelson/sfml), which is now no longer necessary by installing it from the official package repositories: ```sudo apt install libsfml-dev``` - Install a web server and make its root directory point to the www_root symlink in the project's root directory - Connect the server to a network from which it is reachable for client devices, or open a Wifi network yourself (see troubleshooting section for hints) - Paste the server's IP address to the frontend WebSocket configuration file: frontend/configuration/configuration.js @@ -21,23 +21,6 @@ The Massive Mobile Multiuser Framework is a software platform designed to enable - T. Weißker, A. Berst, J. Hartmann, and F. Echtler. 2016. The Massive Mobile Multiuser Framework: Enabling Ad-hoc Realtime Interaction on Public Displays with Mobile Devices. In Proceedings of the 5th International Symposium on Pervasive Displays (PerDis '16). ACM, New York, NY, USA, 168-174. DOI: http://dx.doi.org/10.1145/2914920.2915004 # Troubleshooting -## Compilation of mickelson's version of SFML -As outline by mickelson himself, the following steps need to be executed in order to get the Raspberry-Pi-version of SFML running. - -Install necessary dependencies: -``` -sudo apt-get install cmake libx11-dev libx11-xcb-dev libflac-dev libogg-dev libvorbis-dev libopenal-dev libjpeg8-dev libfreetype6-dev libxcb-randr0-dev libxcb-image0-dev libxcb-util0-dev libxcb-ewmh-dev libxcb-keysyms1-dev libxcb-icccm4-dev libudev-dev libavutil-dev libavcodec-dev libavformat-dev libavfilter-dev libswscale-dev libavresample-dev libfontconfig1-dev -``` - -Configure and compile SFML: -``` -git clone -b rpi https://github.com/mickelson/SFML sfml-pi -mkdir sfml-pi/build;cd sfml-pi/build -cmake -DEGL_INCLUDE_DIR=/opt/vc/include -DEGL_LIBRARY=/opt/vc/lib/libEGL.so -DFREETYPE_INCLUDE_DIR_freetype2=/usr/include -DFREETYPE_INCLUDE_DIR_ft2build=/usr/include/freetype2 -DGLES_INCLUDE_DIR=/opt/vc/include -DGLES_LIBRARY=/opt/vc/lib/libGLESv1_CM.so -DSFML_BCMHOST=1 .. -sudo make install -sudo ldconfig -``` - ## Wireless network and DHCP server We have used and tested two platforms on which we opened a Wifi network and assigned IP addresses to the connecting client devices. Therefore, we assigned the IP address 29.4.93.1 to the respective server and gave out an address range of 29.4.93.10 to 29.4.93.254 to connecting client devices. From 04e661eb45f21c5936e58370a97018c250b99ae8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tim=20Wei=C3=9Fker?= Date: Mon, 20 Mar 2023 21:15:32 +0100 Subject: [PATCH 06/15] Rework controller frontend and number ranges for improved controls. --- frontend/controller.html | 1 - frontend/js/controller.js | 194 ++++++++++++++++++++------------------ frontend/style.css | 2 +- game/src/InputDevice.cpp | 5 +- 4 files changed, 104 insertions(+), 98 deletions(-) diff --git a/frontend/controller.html b/frontend/controller.html index 4b52084..577266e 100644 --- a/frontend/controller.html +++ b/frontend/controller.html @@ -14,7 +14,6 @@
-
diff --git a/frontend/js/controller.js b/frontend/js/controller.js index 1c618bb..e7cad26 100644 --- a/frontend/js/controller.js +++ b/frontend/js/controller.js @@ -9,10 +9,8 @@ window.addEventListener('load', function(){ button = document.getElementById('button'); wrapper = document.getElementById('canvas-wrap'); canvas = document.getElementById('sadstick'); - circle = document.getElementById('circle'); hint = document.getElementById('mmmturn'); - colorbase = 'grey'; idletimer = setTimeout(logout, 3000000); context = null; socket = null; @@ -20,17 +18,25 @@ window.addEventListener('load', function(){ starty = null; socket = null; + stickRadius = 40; + stickMaxDistance = 3 * stickRadius; + teamColor = '#bbbbbb'; + stickIsDragged = false; + stickDraggingColor = "black"; + inputMaxValue = 255; + initSocket(); - initView(); - window.addEventListener('resize', updateBasicView, false); + window.addEventListener('resize', onWindowResize, false); + onWindowResize(); button.addEventListener('touchstart', pushButton, false); button.addEventListener('touchend', releaseButton, false); - circle.addEventListener('touchstart', pushCircle, false); - circle.addEventListener('touchmove', moveCircle, false); - circle.addEventListener('touchend', releaseCircle, false); + canvas.addEventListener('touchstart', touchCanvas, false); + canvas.addEventListener('touchmove', moveTouchOnCanvas, false); + canvas.addEventListener('touchend', releaseCanvasTouch, false); + }, false) @@ -39,46 +45,33 @@ window.addEventListener('load', function(){ Controller Basic View, Functions ****************************************************************************************************************/ - function isLandscape() { - var width = window.innerWidth; - var height = window.innerHeight; - - if (width < height) { - hint.style.display="block"; - button.style.display="none"; - circle.style.display="none"; - canvas.style.display="none"; - socketSend(socket, 'V * '+ 0 + ' ' + 0); - } else { - hint.style.display="none"; - button.style.display="inline"; - circle.style.display="block"; - canvas.style.display="inline"; - } - - + var width = window.innerWidth; + var height = window.innerHeight; + + if (width < height) { + hint.style.display="block"; + button.style.display="none"; + canvas.style.display="none"; + socketSend(socket, 'V * '+ 0 + ' ' + 0); + } else { + hint.style.display="none"; + button.style.display="inline"; + canvas.style.display="inline"; + } } -function initView() { - isLandscape(); - context = canvas.getContext('2d'); - canvas.width = window.innerWidth/2; - canvas.height = window.innerHeight; - var canvasCenterX = canvas.width /2; - var canvasCenterY = canvas.height /2; - circle.style.left = canvasCenterX - circle.offsetWidth/2; - circle.style.top = canvasCenterY - circle.offsetHeight/2; +function onWindowResize() { + isLandscape(); + setCanvasSize(); + clearCanvas(); } -function updateBasicView() { - isLandscape(); - canvas.width = window.innerWidth/2; - canvas.height = window.innerHeight; - var canvasCenterX = canvas.width /2; - var canvasCenterY = canvas.height /2; - circle.style.left = canvasCenterX - circle.offsetWidth/2; - circle.style.top = canvasCenterY - circle.offsetHeight/2; +function setCanvasSize() { + context = canvas.getContext('2d'); + canvas.width = window.innerWidth/2; + canvas.height = window.innerHeight; + canvasCenter = [canvas.width/2, canvas.height/2]; } function colorBackground(object, color) { @@ -93,36 +86,36 @@ function resetTimer() { /**************************************************************************************************************** Canvas Draw ****************************************************************************************************************/ -function drawControllerStick(currx, curry) { - clearCanvas(); - drawLineFromCenterTo(currx, curry); - drawCircleAtPos(currx,curry); +function drawControllerStick(pos, color) { + clearCanvas(); + drawLineFromCenterTo(pos); + drawCircleAtPos(pos, stickRadius, color); } -function drawLineFromCenterTo(currx, curry) { - var canvasCenterX = canvas.width /2; - var canvasCenterY = canvas.height /2; - context.beginPath(); - context.moveTo(canvasCenterX ,canvasCenterY); - context.lineTo(currx, curry); - context.closePath(); - context.stroke(); +function drawLineFromCenterTo(pos) { + context.beginPath(); + context.moveTo(canvasCenter[0],canvasCenter[1]); + context.lineTo(pos[0], pos[1]); + context.closePath(); + context.stroke(); } -function drawCircleAtPos(currx, curry) { - context.beginPath(); - context.arc(currx, curry, 50, 0, 2 * Math.PI, false); - context.fillStyle = 'black'; - context.fill(); - context.lineWidth = 5; - context.closePath(); - context.stroke(); +function drawCircleAtPos(pos, radius, color) { + context.beginPath(); + context.arc(pos[0], pos[1], radius, 0, 2 * Math.PI, false); + context.fillStyle = color; + context.fill(); + context.lineWidth = 3; + context.closePath(); + context.stroke(); } function clearCanvas() { - context.clearRect(0, 0, canvas.width, canvas.height); - context.lineWidth = 4; - context.shadowColor = "transparent"; + context.clearRect(0, 0, canvas.width, canvas.height); + context.lineWidth = 4; + context.shadowColor = "transparent"; + drawCircleAtPos(canvasCenter, stickRadius, teamColor); + drawCircleAtPos(canvasCenter, stickMaxDistance, "transparent"); } @@ -139,42 +132,57 @@ function pushButton(e) { } function releaseButton() { - colorBackground(button, colorbase); + colorBackground(button, teamColor); } -function pushCircle(e) { +function touchCanvas(e) { e.preventDefault(); var touchobj = e.changedTouches[0]; - startx = parseInt(touchobj.clientX); - starty = parseInt(touchobj.clientX); - circle.style.display ="none"; - - var canvasCenterX = canvas.width /2; - var canvasCenterY = canvas.height /2; - drawControllerStick(canvasCenterX,canvasCenterY); + var touchCoords = [parseInt(touchobj.clientX), parseInt(touchobj.clientY)]; + var touchToCenter = [canvasCenter[0]-touchCoords[0], canvasCenter[1]-touchCoords[1]]; + var touchDistance = Math.sqrt(touchToCenter[0]*touchToCenter[0] + touchToCenter[1]*touchToCenter[1]); + + if (touchDistance < stickRadius) + { + stickIsDragged = true; + stickDraggingOffset = touchToCenter; + drawControllerStick(canvasCenter, stickDraggingColor); + socketSend(socket, 'V * '+ 0 + ' ' + 0); + } - socketSend(socket, 'V * '+ 0 + ' ' + 0); resetTimer(); } -function moveCircle(e) { - e.preventDefault(); - var touchobj = e.changedTouches[0]; - var currx = parseInt(touchobj.clientX); - var curry = parseInt(touchobj.clientY); - drawControllerStick(currx,curry); +function moveTouchOnCanvas(e) { - diffx = currx - startx; - diffy = curry - starty; + if (stickIsDragged) + { + var touchobj = e.changedTouches[0]; + var touchCoords = [parseInt(touchobj.clientX), parseInt(touchobj.clientY)]; + var stickCoords = [touchCoords[0]+stickDraggingOffset[0], touchCoords[1]+stickDraggingOffset[1]]; + var centerToStick = [stickCoords[0]-canvasCenter[0], stickCoords[1]-canvasCenter[1]]; + var centerToStickMag = Math.sqrt(centerToStick[0]*centerToStick[0] + centerToStick[1]*centerToStick[1]); + + if (centerToStickMag > stickMaxDistance) + { + var shorteningFactor = stickMaxDistance/centerToStickMag; + centerToStick = [centerToStick[0]*shorteningFactor, centerToStick[1]*shorteningFactor]; + centerToStickMag = stickMaxDistance; + stickCoords = [canvasCenter[0]+centerToStick[0], canvasCenter[1]+centerToStick[1]]; + } + drawControllerStick(stickCoords, stickDraggingColor); + var normalizedStickCoords = [centerToStick[0]/stickMaxDistance, centerToStick[1]/stickMaxDistance]; + var inputToSend = [Math.round(normalizedStickCoords[0]*inputMaxValue), Math.round(normalizedStickCoords[1]*inputMaxValue)]; + socketSend(socket, 'V * '+ inputToSend[0] + ' ' + inputToSend[1]); + } resetTimer(); - socketSend(socket, 'V * '+ diffx + ' ' + diffy); } -function releaseCircle(e) { - circle.style.display = ""; - clearCanvas(); +function releaseCanvasTouch(e) { + stickIsDragged = false; socketSend(socket, 'V * '+ 0 + ' ' + 0); + clearCanvas(); } /**************************************************************************************************************** @@ -200,20 +208,18 @@ function initSocket() { window.sessionStorage.setItem("number", splitted_string[2]); if(sessionStorage.getItem('team') == "RED") { - colorbase = 'red'; - button.style.backgroundColor = colorbase; - circle.style.backgroundColor = colorbase; - + teamColor = 'red'; + button.style.backgroundColor = teamColor; } else if(sessionStorage.getItem('team') == "BLUE") { - colorbase = 'blue'; - button.style.backgroundColor = colorbase; - circle.style.backgroundColor = colorbase; + teamColor = 'blue'; + button.style.backgroundColor = teamColor; } } } function socketSend(socket, message) { messageToSend = '^' + message + '$'; + //console.log(messageToSend); if (socket.readyState == 1) { socket.send(messageToSend); } diff --git a/frontend/style.css b/frontend/style.css index d287b5d..6c9e50b 100644 --- a/frontend/style.css +++ b/frontend/style.css @@ -159,7 +159,7 @@ body { position: relative; top: 50; left: 50; - background: red; + background: #cccccc; border-radius: 50%; padding: 20%; -moz-user-select: none; diff --git a/game/src/InputDevice.cpp b/game/src/InputDevice.cpp index cfcd8ce..b726f06 100644 --- a/game/src/InputDevice.cpp +++ b/game/src/InputDevice.cpp @@ -83,8 +83,9 @@ void InputDevice::mapValuesAndApply() { if (inputValueX_ != 0 || inputValueY_ != 0) { - double inputToVelFactor = 12.0; - playerFigure_->addVelocityOffset(inputValueX_ * inputToVelFactor, inputValueY_ * inputToVelFactor); + double inputToVelFactor = 6.0 / 255.0; + //playerFigure_->addVelocityOffset(inputValueX_ * inputToVelFactor, inputValueY_ * inputToVelFactor); + playerFigure_->setVelocity(inputValueX_ * inputToVelFactor, inputValueY_ * inputToVelFactor); } if (inputButtonA_) From 42fdc44b08dcd7d8d9edae076ac948ae0ee30bdd Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tim=20Wei=C3=9Fker?= Date: Mon, 20 Mar 2023 21:26:53 +0100 Subject: [PATCH 07/15] Improve controller appearance. --- frontend/js/controller.js | 17 ++++++++++------- 1 file changed, 10 insertions(+), 7 deletions(-) diff --git a/frontend/js/controller.js b/frontend/js/controller.js index e7cad26..4d6228c 100644 --- a/frontend/js/controller.js +++ b/frontend/js/controller.js @@ -22,9 +22,11 @@ window.addEventListener('load', function(){ stickMaxDistance = 3 * stickRadius; teamColor = '#bbbbbb'; stickIsDragged = false; - stickDraggingColor = "black"; inputMaxValue = 255; + ////// + teamColor = "blue"; + initSocket(); window.addEventListener('resize', onWindowResize, false); @@ -114,7 +116,8 @@ function clearCanvas() { context.clearRect(0, 0, canvas.width, canvas.height); context.lineWidth = 4; context.shadowColor = "transparent"; - drawCircleAtPos(canvasCenter, stickRadius, teamColor); + drawCircleAtPos(canvasCenter, stickRadius*0.25, '#bbbbbb'); + if (!stickIsDragged) drawCircleAtPos(canvasCenter, stickRadius, teamColor); drawCircleAtPos(canvasCenter, stickMaxDistance, "transparent"); } @@ -146,7 +149,7 @@ function touchCanvas(e) { { stickIsDragged = true; stickDraggingOffset = touchToCenter; - drawControllerStick(canvasCenter, stickDraggingColor); + drawControllerStick(canvasCenter, teamColor); socketSend(socket, 'V * '+ 0 + ' ' + 0); } @@ -170,7 +173,7 @@ function moveTouchOnCanvas(e) { centerToStickMag = stickMaxDistance; stickCoords = [canvasCenter[0]+centerToStick[0], canvasCenter[1]+centerToStick[1]]; } - drawControllerStick(stickCoords, stickDraggingColor); + drawControllerStick(stickCoords, teamColor); var normalizedStickCoords = [centerToStick[0]/stickMaxDistance, centerToStick[1]/stickMaxDistance]; var inputToSend = [Math.round(normalizedStickCoords[0]*inputMaxValue), Math.round(normalizedStickCoords[1]*inputMaxValue)]; @@ -193,7 +196,7 @@ function initSocket() { socket = new WebSocket('ws://' + configuration.server_ip + ':' + configuration.server_port) socket.onerror = function(error) { - window.location.href = './goodbye.html'; + //window.location.href = './goodbye.html'; }; socket.onopen = function() { @@ -236,7 +239,7 @@ function closeSocket() { ****************************************************************************************************************/ function checkLogin() { if(sessionStorage.getItem('playername') === null) { - window.location.href = './goodbye.html'; + //window.location.href = './goodbye.html'; } } @@ -244,5 +247,5 @@ function logout(){ window.sessionStorage.removeItem('team'); window.sessionStorage.removeItem('number'); closeSocket(); - window.location.href = './goodbye.html'; + //window.location.href = './goodbye.html'; } From 8375833c57e4245b415aaa92e4b98ed5ecdaef29 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tim=20Wei=C3=9Fker?= Date: Tue, 21 Mar 2023 18:24:23 +0100 Subject: [PATCH 08/15] Reset game when pressing R. --- game/include/Game.hpp | 1 + game/main.cpp | 9 +++++++-- game/src/Game.cpp | 15 ++++++++++----- 3 files changed, 18 insertions(+), 7 deletions(-) diff --git a/game/include/Game.hpp b/game/include/Game.hpp index 78312eb..5ee3aac 100644 --- a/game/include/Game.hpp +++ b/game/include/Game.hpp @@ -54,6 +54,7 @@ class Game //game logic methods void performEndOfGameAnimation(); + void resetGame(); void resetScore(); void checkForGoal(); void resetPlayers(); diff --git a/game/main.cpp b/game/main.cpp index 8ed90c7..a7fabb6 100644 --- a/game/main.cpp +++ b/game/main.cpp @@ -7,7 +7,7 @@ #include "InputHandler.hpp" #include "Game.hpp" -#define INSERT_KEYBOARD_DEBUG_PLAYER false +#define INSERT_KEYBOARD_DEBUG_PLAYER true int main(int argc, char* argv[]) { @@ -16,7 +16,7 @@ int main(int argc, char* argv[]) sf::RenderWindow window(sf::VideoMode(sf::VideoMode::getDesktopMode().width,sf::VideoMode::getDesktopMode().width,20), "MMMBall", sf::Style::Fullscreen); //sf::RenderWindow window(sf::VideoMode(sf::VideoMode::getDesktopMode().width,sf::VideoMode::getDesktopMode().width,20), "MMMBall"); - window.setVerticalSyncEnabled(true); + //window.setVerticalSyncEnabled(true); std::string programName(argv[0]); std::string programDirectory(programName.substr(0, programName.find_last_of("/"))); @@ -182,6 +182,11 @@ int main(int argc, char* argv[]) // input handling inputHandler.processAddRemoveQueries(); inputHandler.processDeviceInputs(); + + if (sf::Keyboard::isKeyPressed(sf::Keyboard::R)) + { + game->resetGame(); + } // application logic diff --git a/game/src/Game.cpp b/game/src/Game.cpp index 86a47e1..8153954 100644 --- a/game/src/Game.cpp +++ b/game/src/Game.cpp @@ -413,11 +413,7 @@ void Game::performEndOfGameAnimation() if (elapsedMilliseconds > END_ANIMATION_DURATION_SEC * 1000) { - ball_->resetToStart(); - resetPlayers(); - resetScore(); - clock_.restart(); - inEndAnimation_ = false; + resetGame(); } else { @@ -444,6 +440,15 @@ void Game::performEndOfGameAnimation() } } +void Game::resetGame() +{ + ball_->resetToStart(); + resetPlayers(); + resetScore(); + clock_.restart(); + inEndAnimation_ = false; +} + void Game::resetScore() { From 054f91ad60d79f09aa438b28492beb8a9c2d9d92 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tim=20Wei=C3=9Fker?= Date: Tue, 21 Mar 2023 18:26:34 +0100 Subject: [PATCH 09/15] Make physical circle movements independent of framerate. --- game/include/PhysicalCircle.hpp | 8 +++++++- game/src/PhysicalCircle.cpp | 14 +++++++++----- 2 files changed, 16 insertions(+), 6 deletions(-) diff --git a/game/include/PhysicalCircle.hpp b/game/include/PhysicalCircle.hpp index e66bc58..a6d8b42 100644 --- a/game/include/PhysicalCircle.hpp +++ b/game/include/PhysicalCircle.hpp @@ -3,9 +3,13 @@ #include #include +#include #include #include +typedef std::chrono::high_resolution_clock Clock; +typedef std::chrono::milliseconds milliseconds; + #define MAX_SPEED 6.0 class PhysicalCircle @@ -15,7 +19,7 @@ class PhysicalCircle virtual ~PhysicalCircle(); virtual void render(sf::RenderWindow* window) const; - virtual void frameFrictionUpdate(); + virtual void frameFrictionUpdate(float timeFactor); virtual void frameUpdate(); virtual void setPosition(float x, float y); virtual void clampPosition() = 0; @@ -45,6 +49,8 @@ class PhysicalCircle float mass_; float radius_; float frictionCoefficient_; + + Clock::time_point lastFrameTime_; }; #endif //PHYSICAL_CIRCLE_HPP diff --git a/game/src/PhysicalCircle.cpp b/game/src/PhysicalCircle.cpp index ddb9314..84b7033 100644 --- a/game/src/PhysicalCircle.cpp +++ b/game/src/PhysicalCircle.cpp @@ -1,7 +1,7 @@ #include "PhysicalCircle.hpp" PhysicalCircle::PhysicalCircle(float mass, float posX, float posY, float radius, float frictionCoefficient) : - mass_(mass), posX_(posX), posY_(posY), velX_(0.0), velY_(0.0), radius_(radius), frictionCoefficient_(frictionCoefficient) {} + mass_(mass), posX_(posX), posY_(posY), velX_(0.0), velY_(0.0), radius_(radius), frictionCoefficient_(frictionCoefficient), lastFrameTime_(Clock::now()) {} /* virtual */ PhysicalCircle::~PhysicalCircle() {} @@ -10,9 +10,9 @@ PhysicalCircle::PhysicalCircle(float mass, float posX, float posY, float radius, window->draw(shape_); } -/* virtual */ void PhysicalCircle::frameFrictionUpdate() +/* virtual */ void PhysicalCircle::frameFrictionUpdate(float timeFactor) { - float frictionDecrement = frictionCoefficient_; + float frictionDecrement = frictionCoefficient_ * timeFactor; float currentSpeed = computeCurrentSpeed(); @@ -35,8 +35,12 @@ PhysicalCircle::PhysicalCircle(float mass, float posX, float posY, float radius, /* virtual */ void PhysicalCircle::frameUpdate() { - frameFrictionUpdate(); - setPosition(posX_ + velX_, posY_ + velY_); + Clock::time_point nowTime = Clock::now(); + int elapsedMilliseconds = (std::chrono::duration_cast(nowTime - lastFrameTime_)).count(); + float timeFactor = (elapsedMilliseconds/1000.0)*100.0; + frameFrictionUpdate(timeFactor); + setPosition(posX_ + velX_ * timeFactor, posY_ + velY_ * timeFactor); + lastFrameTime_ = nowTime; } /* virtual */ void PhysicalCircle::setPosition(float x, float y) From a4971af6dcd101a3e56a015ab8de91f8739032cf Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tim=20Wei=C3=9Fker?= Date: Tue, 21 Mar 2023 18:27:37 +0100 Subject: [PATCH 10/15] Add boolean switches in controller interface to prevent redirects for debugging. --- frontend/js/controller.js | 14 ++++++-------- 1 file changed, 6 insertions(+), 8 deletions(-) diff --git a/frontend/js/controller.js b/frontend/js/controller.js index 4d6228c..bf3e3c0 100644 --- a/frontend/js/controller.js +++ b/frontend/js/controller.js @@ -22,10 +22,8 @@ window.addEventListener('load', function(){ stickMaxDistance = 3 * stickRadius; teamColor = '#bbbbbb'; stickIsDragged = false; - inputMaxValue = 255; - - ////// - teamColor = "blue"; + sendInputMaxValue = 255; + redirectOnError = false; initSocket(); @@ -176,7 +174,7 @@ function moveTouchOnCanvas(e) { drawControllerStick(stickCoords, teamColor); var normalizedStickCoords = [centerToStick[0]/stickMaxDistance, centerToStick[1]/stickMaxDistance]; - var inputToSend = [Math.round(normalizedStickCoords[0]*inputMaxValue), Math.round(normalizedStickCoords[1]*inputMaxValue)]; + var inputToSend = [Math.round(normalizedStickCoords[0]*sendInputMaxValue), Math.round(normalizedStickCoords[1]*sendInputMaxValue)]; socketSend(socket, 'V * '+ inputToSend[0] + ' ' + inputToSend[1]); } resetTimer(); @@ -196,7 +194,7 @@ function initSocket() { socket = new WebSocket('ws://' + configuration.server_ip + ':' + configuration.server_port) socket.onerror = function(error) { - //window.location.href = './goodbye.html'; + if (redirectOnError) window.location.href = './goodbye.html'; }; socket.onopen = function() { @@ -239,7 +237,7 @@ function closeSocket() { ****************************************************************************************************************/ function checkLogin() { if(sessionStorage.getItem('playername') === null) { - //window.location.href = './goodbye.html'; + if (redirectOnError) window.location.href = './goodbye.html'; } } @@ -247,5 +245,5 @@ function logout(){ window.sessionStorage.removeItem('team'); window.sessionStorage.removeItem('number'); closeSocket(); - //window.location.href = './goodbye.html'; + if (redirectOnError) window.location.href = './goodbye.html'; } From 559388e02fd6b465779b13a76a53bf728ed8e957 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tim=20Wei=C3=9Fker?= Date: Tue, 21 Mar 2023 18:58:54 +0100 Subject: [PATCH 11/15] Remove debug players. --- game/main.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/game/main.cpp b/game/main.cpp index a7fabb6..c07ef21 100644 --- a/game/main.cpp +++ b/game/main.cpp @@ -7,7 +7,7 @@ #include "InputHandler.hpp" #include "Game.hpp" -#define INSERT_KEYBOARD_DEBUG_PLAYER true +#define INSERT_KEYBOARD_DEBUG_PLAYER false int main(int argc, char* argv[]) { From bbd5a0d989ad0b97ba4a23ac38a5463245fe142d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tim=20Wei=C3=9Fker?= Date: Tue, 21 Mar 2023 18:59:28 +0100 Subject: [PATCH 12/15] Add status text to controller interface. --- frontend/js/controller.js | 14 +++++++------- frontend/style.css | 13 +++++++++++++ 2 files changed, 20 insertions(+), 7 deletions(-) diff --git a/frontend/js/controller.js b/frontend/js/controller.js index bf3e3c0..4b928e7 100644 --- a/frontend/js/controller.js +++ b/frontend/js/controller.js @@ -1,6 +1,7 @@ /**************************************************************************************************************** OnLoad ****************************************************************************************************************/ +redirectOnError = false; checkLogin(); window.addEventListener('load', function(){ @@ -19,11 +20,10 @@ window.addEventListener('load', function(){ socket = null; stickRadius = 40; - stickMaxDistance = 3 * stickRadius; + stickMaxDistance = 2 * stickRadius; teamColor = '#bbbbbb'; stickIsDragged = false; sendInputMaxValue = 255; - redirectOnError = false; initSocket(); @@ -36,8 +36,6 @@ window.addEventListener('load', function(){ canvas.addEventListener('touchstart', touchCanvas, false); canvas.addEventListener('touchmove', moveTouchOnCanvas, false); canvas.addEventListener('touchend', releaseCanvasTouch, false); - - }, false) @@ -126,7 +124,7 @@ function clearCanvas() { function pushButton(e) { e.preventDefault(); - colorBackground(button,'#000000'); + colorBackground(button,'#ffffff'); resetTimer(); socketSend(socket, 'K A 1'); socketSend(socket, 'K A 0'); @@ -199,7 +197,6 @@ function initSocket() { socket.onopen = function() { socketSend(socket, 'NAME '+sessionStorage.getItem('playername')); - window.sessionStorage.removeItem('playername'); } socket.onmessage = function(evt) { @@ -214,7 +211,10 @@ function initSocket() { } else if(sessionStorage.getItem('team') == "BLUE") { teamColor = 'blue'; button.style.backgroundColor = teamColor; - } + } + + button.innerHTML = "
Name: " + sessionStorage.getItem('playername') + "

Number: " + sessionStorage.getItem('number') + "
"; + clearCanvas(); } } diff --git a/frontend/style.css b/frontend/style.css index 6c9e50b..04df175 100644 --- a/frontend/style.css +++ b/frontend/style.css @@ -128,6 +128,19 @@ body { -o-user-select: none; } +.status-text +{ + font-size: medium; + text-align: center; + color: white; + margin: 5%; +} + +#bold +{ + font-weight: bold; +} + #sadstick { position:absolute; width: 100%; From d4b5cca3cc25ccd97cd3bcffe6f861e45b4ecf78 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tim=20Wei=C3=9Fker?= Date: Tue, 21 Mar 2023 19:07:24 +0100 Subject: [PATCH 13/15] Reset configuration. --- frontend/configuration/configuration.js | 4 ++-- frontend/js/controller.js | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/frontend/configuration/configuration.js b/frontend/configuration/configuration.js index 294deeb..7e78ec1 100644 --- a/frontend/configuration/configuration.js +++ b/frontend/configuration/configuration.js @@ -1,5 +1,5 @@ var configuration = { - server_ip: '29.4.93.1', // the IP adress to open the WebSocket connection to + server_ip: '29.4.29.1', // the IP adress to open the WebSocket connection to server_port: '53000' // the port to use for the WebSocket connection // if you didn't change anything in backend/, the default is 53000 -} \ No newline at end of file +} diff --git a/frontend/js/controller.js b/frontend/js/controller.js index 4b928e7..7fb60c7 100644 --- a/frontend/js/controller.js +++ b/frontend/js/controller.js @@ -1,7 +1,7 @@ /**************************************************************************************************************** OnLoad ****************************************************************************************************************/ -redirectOnError = false; +redirectOnError = true; checkLogin(); window.addEventListener('load', function(){ From e35abbdf37a2e1c0ef6173879201d2c3cd99298a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tim=20Wei=C3=9Fker?= Date: Tue, 21 Mar 2023 20:54:53 +0100 Subject: [PATCH 14/15] Make frontend socket sending time-dependent. --- backend/main.cpp | 4 +++- frontend/js/controller.js | 19 +++++++++++++++---- game/main.cpp | 4 ++-- 3 files changed, 20 insertions(+), 7 deletions(-) diff --git a/backend/main.cpp b/backend/main.cpp index 59152e8..e7a0d96 100644 --- a/backend/main.cpp +++ b/backend/main.cpp @@ -251,6 +251,7 @@ int main() { //parse message formats: EVENT_TYPE EVENT_CODE VALUE // [EV_ABS | EV_REL] VALUE1 VALUE2 VALUE3 ... + //std::cout << message << std::endl; std::stringstream messageStream(message); std::string typeString; @@ -299,7 +300,8 @@ int main() else { //illegal use of multiple values - std::cout << "[Server] Multiple values only allowed for EV_ABS and EV_REL." << std::endl; + std::cout << message << std::endl; + std::cout << "[Server] Multiple values only allowed for EV_ABS and EV_REL." << std::endl; } } else diff --git a/frontend/js/controller.js b/frontend/js/controller.js index 7fb60c7..e836d07 100644 --- a/frontend/js/controller.js +++ b/frontend/js/controller.js @@ -1,7 +1,7 @@ /**************************************************************************************************************** OnLoad ****************************************************************************************************************/ -redirectOnError = true; +redirectOnError = false; checkLogin(); window.addEventListener('load', function(){ @@ -18,6 +18,7 @@ window.addEventListener('load', function(){ startx = null; starty = null; socket = null; + normalizedStickCoords = [0.0, 0.0]; stickRadius = 40; stickMaxDistance = 2 * stickRadius; @@ -36,6 +37,9 @@ window.addEventListener('load', function(){ canvas.addEventListener('touchstart', touchCanvas, false); canvas.addEventListener('touchmove', moveTouchOnCanvas, false); canvas.addEventListener('touchend', releaseCanvasTouch, false); + + socketSendRate = 50; // updates per second + window.setInterval(intervalUpdate, (1.0/socketSendRate)*1000); }, false) @@ -171,19 +175,26 @@ function moveTouchOnCanvas(e) { } drawControllerStick(stickCoords, teamColor); - var normalizedStickCoords = [centerToStick[0]/stickMaxDistance, centerToStick[1]/stickMaxDistance]; - var inputToSend = [Math.round(normalizedStickCoords[0]*sendInputMaxValue), Math.round(normalizedStickCoords[1]*sendInputMaxValue)]; - socketSend(socket, 'V * '+ inputToSend[0] + ' ' + inputToSend[1]); + normalizedStickCoords = [centerToStick[0]/stickMaxDistance, centerToStick[1]/stickMaxDistance]; } resetTimer(); } function releaseCanvasTouch(e) { stickIsDragged = false; + normalizedStickCoords = [0.0, 0.0]; socketSend(socket, 'V * '+ 0 + ' ' + 0); clearCanvas(); } +function intervalUpdate() { + if (stickIsDragged) + { + var inputToSend = [Math.round(normalizedStickCoords[0]*sendInputMaxValue), Math.round(normalizedStickCoords[1]*sendInputMaxValue)]; + socketSend(socket, 'V * ' + inputToSend[0] + ' ' + inputToSend[1]); + } +} + /**************************************************************************************************************** Socket ****************************************************************************************************************/ diff --git a/game/main.cpp b/game/main.cpp index c07ef21..b99f284 100644 --- a/game/main.cpp +++ b/game/main.cpp @@ -14,9 +14,9 @@ int main(int argc, char* argv[]) srand (time(NULL)); sf::Clock Clock; - sf::RenderWindow window(sf::VideoMode(sf::VideoMode::getDesktopMode().width,sf::VideoMode::getDesktopMode().width,20), "MMMBall", sf::Style::Fullscreen); //sf::RenderWindow window(sf::VideoMode(sf::VideoMode::getDesktopMode().width,sf::VideoMode::getDesktopMode().width,20), "MMMBall"); - //window.setVerticalSyncEnabled(true); + sf::RenderWindow window(sf::VideoMode(sf::VideoMode::getDesktopMode().width,sf::VideoMode::getDesktopMode().width,20), "MMMBall", sf::Style::Fullscreen); + window.setVerticalSyncEnabled(true); std::string programName(argv[0]); std::string programDirectory(programName.substr(0, programName.find_last_of("/"))); From f49205640ab9e577c5ee169631383bd686b86d45 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tim=20Wei=C3=9Fker?= Date: Tue, 21 Mar 2023 20:55:21 +0100 Subject: [PATCH 15/15] Reenable error forwarding. --- frontend/js/controller.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/frontend/js/controller.js b/frontend/js/controller.js index e836d07..5633b60 100644 --- a/frontend/js/controller.js +++ b/frontend/js/controller.js @@ -1,7 +1,7 @@ /**************************************************************************************************************** OnLoad ****************************************************************************************************************/ -redirectOnError = false; +redirectOnError = true; checkLogin(); window.addEventListener('load', function(){