diff --git a/Dockerfiles/Dockerfile-mysql b/Dockerfiles/Dockerfile-mysql new file mode 100644 index 0000000000000000000000000000000000000000..86d6a5ab30464ba3e5d38bdb9ba6c75cd7319edf --- /dev/null +++ b/Dockerfiles/Dockerfile-mysql @@ -0,0 +1,9 @@ +FROM mysql:8.0 + +ENV MYSQL_DATABASE=paint2win \ + MYSQL_ROOT_PASSWORD=Paint2Win \ + MYSQL_ROOT_HOST=% + +EXPOSE 3306 + +ADD ./Dockerfiles/schema.sql /docker-entrypoint-initdb.d \ No newline at end of file diff --git a/Dockerfiles/schema.sql b/Dockerfiles/schema.sql new file mode 100644 index 0000000000000000000000000000000000000000..0cc9d0c7cf93d6c9ec732ec341660240c5839d66 --- /dev/null +++ b/Dockerfiles/schema.sql @@ -0,0 +1,12 @@ +create user player identified by 'playerPass'; + +create table highscores +( + player_name varchar(16) not null + primary key, + time int not null, + map_name enum('DESERT', 'URBAN') not null +); + +grant alter, create, delete, create view, drop, index, insert, references, select, show view, trigger, update on table highscores to player; + diff --git a/android/AndroidManifest.xml b/android/AndroidManifest.xml index 73bd09761a441005d99b4293c7d64494395e5efe..d1c68529dad0d85875f1e2da131d380496efe20b 100644 --- a/android/AndroidManifest.xml +++ b/android/AndroidManifest.xml @@ -2,16 +2,19 @@ <manifest xmlns:android="http://schemas.android.com/apk/res/android" package="com.tdt4240.paint2win" > + <uses-permission android:name="android.permission.INTERNET"></uses-permission> + <application android:allowBackup="true" android:icon="@drawable/ic_launcher" android:isGame="true" android:appCategory="game" android:label="@string/app_name" - android:theme="@style/GdxTheme" > + android:theme="@style/GdxTheme" + android:usesCleartextTraffic="true"> <activity android:name="com.tdt4240.paint2win.AndroidLauncher" - android:label="@string/app_name" + android:label="@string/app_name" android:screenOrientation="landscape" android:configChanges="keyboard|keyboardHidden|navigation|orientation|screenSize|screenLayout"> <intent-filter> diff --git a/android/assets/FetchData.png b/android/assets/FetchData.png new file mode 100644 index 0000000000000000000000000000000000000000..31632df4d199092c6745d5dbb11cc72e97fc6ffb Binary files /dev/null and b/android/assets/FetchData.png differ diff --git a/android/assets/Left_Arrow.png b/android/assets/Left_Arrow.png new file mode 100644 index 0000000000000000000000000000000000000000..1761805cc946fdf856c589b8a56885a5c6109fe6 Binary files /dev/null and b/android/assets/Left_Arrow.png differ diff --git a/android/assets/Right_Arrow.png b/android/assets/Right_Arrow.png new file mode 100644 index 0000000000000000000000000000000000000000..7c319ecfe61876628072dbce01131ced68f6b587 Binary files /dev/null and b/android/assets/Right_Arrow.png differ diff --git a/android/assets/WinOrLose.png b/android/assets/WinOrLose.png new file mode 100644 index 0000000000000000000000000000000000000000..26235328df28cbb9a080b1418ffc4b8f7321564a Binary files /dev/null and b/android/assets/WinOrLose.png differ diff --git a/android/assets/badlogic.jpg b/android/assets/badlogic.jpg deleted file mode 100644 index 4390da6e0f6d041590c6313d2b4c978abc00a342..0000000000000000000000000000000000000000 Binary files a/android/assets/badlogic.jpg and /dev/null differ diff --git a/android/assets/create_game_header_X6.png b/android/assets/create_game_header_X6.png new file mode 100644 index 0000000000000000000000000000000000000000..ed8ce62209c245f029e23b1e7ad47cf49f5fb7f5 Binary files /dev/null and b/android/assets/create_game_header_X6.png differ diff --git a/android/assets/failSound.mp3 b/android/assets/failSound.mp3 new file mode 100644 index 0000000000000000000000000000000000000000..e065940376d03de3e443e9f97f9de83421f064ac Binary files /dev/null and b/android/assets/failSound.mp3 differ diff --git a/android/assets/fonts/Roboto/LICENSE.txt b/android/assets/fonts/Roboto/LICENSE.txt new file mode 100644 index 0000000000000000000000000000000000000000..d645695673349e3947e8e5ae42332d0ac3164cd7 --- /dev/null +++ b/android/assets/fonts/Roboto/LICENSE.txt @@ -0,0 +1,202 @@ + + Apache License + Version 2.0, January 2004 + http://www.apache.org/licenses/ + + TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION + + 1. Definitions. + + "License" shall mean the terms and conditions for use, reproduction, + and distribution as defined by Sections 1 through 9 of this document. + + "Licensor" shall mean the copyright owner or entity authorized by + the copyright owner that is granting the License. + + "Legal Entity" shall mean the union of the acting entity and all + other entities that control, are controlled by, or are under common + control with that entity. For the purposes of this definition, + "control" means (i) the power, direct or indirect, to cause the + direction or management of such entity, whether by contract or + otherwise, or (ii) ownership of fifty percent (50%) or more of the + outstanding shares, or (iii) beneficial ownership of such entity. + + "You" (or "Your") shall mean an individual or Legal Entity + exercising permissions granted by this License. + + "Source" form shall mean the preferred form for making modifications, + including but not limited to software source code, documentation + source, and configuration files. + + "Object" form shall mean any form resulting from mechanical + transformation or translation of a Source form, including but + not limited to compiled object code, generated documentation, + and conversions to other media types. + + "Work" shall mean the work of authorship, whether in Source or + Object form, made available under the License, as indicated by a + copyright notice that is included in or attached to the work + (an example is provided in the Appendix below). + + "Derivative Works" shall mean any work, whether in Source or Object + form, that is based on (or derived from) the Work and for which the + editorial revisions, annotations, elaborations, or other modifications + represent, as a whole, an original work of authorship. For the purposes + of this License, Derivative Works shall not include works that remain + separable from, or merely link (or bind by name) to the interfaces of, + the Work and Derivative Works thereof. + + "Contribution" shall mean any work of authorship, including + the original version of the Work and any modifications or additions + to that Work or Derivative Works thereof, that is intentionally + submitted to Licensor for inclusion in the Work by the copyright owner + or by an individual or Legal Entity authorized to submit on behalf of + the copyright owner. For the purposes of this definition, "submitted" + means any form of electronic, verbal, or written communication sent + to the Licensor or its representatives, including but not limited to + communication on electronic mailing lists, source code control systems, + and issue tracking systems that are managed by, or on behalf of, the + Licensor for the purpose of discussing and improving the Work, but + excluding communication that is conspicuously marked or otherwise + designated in writing by the copyright owner as "Not a Contribution." + + "Contributor" shall mean Licensor and any individual or Legal Entity + on behalf of whom a Contribution has been received by Licensor and + subsequently incorporated within the Work. + + 2. Grant of Copyright License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + copyright license to reproduce, prepare Derivative Works of, + publicly display, publicly perform, sublicense, and distribute the + Work and such Derivative Works in Source or Object form. + + 3. Grant of Patent License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + (except as stated in this section) patent license to make, have made, + use, offer to sell, sell, import, and otherwise transfer the Work, + where such license applies only to those patent claims licensable + by such Contributor that are necessarily infringed by their + Contribution(s) alone or by combination of their Contribution(s) + with the Work to which such Contribution(s) was submitted. If You + institute patent litigation against any entity (including a + cross-claim or counterclaim in a lawsuit) alleging that the Work + or a Contribution incorporated within the Work constitutes direct + or contributory patent infringement, then any patent licenses + granted to You under this License for that Work shall terminate + as of the date such litigation is filed. + + 4. Redistribution. You may reproduce and distribute copies of the + Work or Derivative Works thereof in any medium, with or without + modifications, and in Source or Object form, provided that You + meet the following conditions: + + (a) You must give any other recipients of the Work or + Derivative Works a copy of this License; and + + (b) You must cause any modified files to carry prominent notices + stating that You changed the files; and + + (c) You must retain, in the Source form of any Derivative Works + that You distribute, all copyright, patent, trademark, and + attribution notices from the Source form of the Work, + excluding those notices that do not pertain to any part of + the Derivative Works; and + + (d) If the Work includes a "NOTICE" text file as part of its + distribution, then any Derivative Works that You distribute must + include a readable copy of the attribution notices contained + within such NOTICE file, excluding those notices that do not + pertain to any part of the Derivative Works, in at least one + of the following places: within a NOTICE text file distributed + as part of the Derivative Works; within the Source form or + documentation, if provided along with the Derivative Works; or, + within a display generated by the Derivative Works, if and + wherever such third-party notices normally appear. The contents + of the NOTICE file are for informational purposes only and + do not modify the License. You may add Your own attribution + notices within Derivative Works that You distribute, alongside + or as an addendum to the NOTICE text from the Work, provided + that such additional attribution notices cannot be construed + as modifying the License. + + You may add Your own copyright statement to Your modifications and + may provide additional or different license terms and conditions + for use, reproduction, or distribution of Your modifications, or + for any such Derivative Works as a whole, provided Your use, + reproduction, and distribution of the Work otherwise complies with + the conditions stated in this License. + + 5. Submission of Contributions. Unless You explicitly state otherwise, + any Contribution intentionally submitted for inclusion in the Work + by You to the Licensor shall be under the terms and conditions of + this License, without any additional terms or conditions. + Notwithstanding the above, nothing herein shall supersede or modify + the terms of any separate license agreement you may have executed + with Licensor regarding such Contributions. + + 6. Trademarks. This License does not grant permission to use the trade + names, trademarks, service marks, or product names of the Licensor, + except as required for reasonable and customary use in describing the + origin of the Work and reproducing the content of the NOTICE file. + + 7. Disclaimer of Warranty. Unless required by applicable law or + agreed to in writing, Licensor provides the Work (and each + Contributor provides its Contributions) on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + implied, including, without limitation, any warranties or conditions + of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A + PARTICULAR PURPOSE. You are solely responsible for determining the + appropriateness of using or redistributing the Work and assume any + risks associated with Your exercise of permissions under this License. + + 8. Limitation of Liability. In no event and under no legal theory, + whether in tort (including negligence), contract, or otherwise, + unless required by applicable law (such as deliberate and grossly + negligent acts) or agreed to in writing, shall any Contributor be + liable to You for damages, including any direct, indirect, special, + incidental, or consequential damages of any character arising as a + result of this License or out of the use or inability to use the + Work (including but not limited to damages for loss of goodwill, + work stoppage, computer failure or malfunction, or any and all + other commercial damages or losses), even if such Contributor + has been advised of the possibility of such damages. + + 9. Accepting Warranty or Additional Liability. While redistributing + the Work or Derivative Works thereof, You may choose to offer, + and charge a fee for, acceptance of support, warranty, indemnity, + or other liability obligations and/or rights consistent with this + License. However, in accepting such obligations, You may act only + on Your own behalf and on Your sole responsibility, not on behalf + of any other Contributor, and only if You agree to indemnify, + defend, and hold each Contributor harmless for any liability + incurred by, or claims asserted against, such Contributor by reason + of your accepting any such warranty or additional liability. + + END OF TERMS AND CONDITIONS + + APPENDIX: How to apply the Apache License to your work. + + To apply the Apache License to your work, attach the following + boilerplate notice, with the fields enclosed by brackets "[]" + replaced with your own identifying information. (Don't include + the brackets!) The text should be enclosed in the appropriate + comment syntax for the file format. We also recommend that a + file or class name and description of purpose be included on the + same "printed page" as the copyright notice for easier + identification within third-party archives. + + Copyright [yyyy] [name of copyright owner] + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. diff --git a/android/assets/fonts/Roboto/Roboto-Black.ttf b/android/assets/fonts/Roboto/Roboto-Black.ttf new file mode 100644 index 0000000000000000000000000000000000000000..43a00e0df0d6183c8e88476c411d2060229ed967 Binary files /dev/null and b/android/assets/fonts/Roboto/Roboto-Black.ttf differ diff --git a/android/assets/fonts/Roboto/Roboto-BlackItalic.ttf b/android/assets/fonts/Roboto/Roboto-BlackItalic.ttf new file mode 100644 index 0000000000000000000000000000000000000000..5082cdc4e84fe18eb2e4983af0f6365878494421 Binary files /dev/null and b/android/assets/fonts/Roboto/Roboto-BlackItalic.ttf differ diff --git a/android/assets/fonts/Roboto/Roboto-Bold.ttf b/android/assets/fonts/Roboto/Roboto-Bold.ttf new file mode 100644 index 0000000000000000000000000000000000000000..3742457900d51ae5c34ed53657ed8a72f17f19c6 Binary files /dev/null and b/android/assets/fonts/Roboto/Roboto-Bold.ttf differ diff --git a/android/assets/fonts/Roboto/Roboto-BoldItalic.ttf b/android/assets/fonts/Roboto/Roboto-BoldItalic.ttf new file mode 100644 index 0000000000000000000000000000000000000000..e85e7fb9e31759763af6294c925f9c06a0f9e84a Binary files /dev/null and b/android/assets/fonts/Roboto/Roboto-BoldItalic.ttf differ diff --git a/android/assets/fonts/Roboto/Roboto-Italic.ttf b/android/assets/fonts/Roboto/Roboto-Italic.ttf new file mode 100644 index 0000000000000000000000000000000000000000..c9df607a4d373e3468599aaf6d96823459a4f6ec Binary files /dev/null and b/android/assets/fonts/Roboto/Roboto-Italic.ttf differ diff --git a/android/assets/fonts/Roboto/Roboto-Light.ttf b/android/assets/fonts/Roboto/Roboto-Light.ttf new file mode 100644 index 0000000000000000000000000000000000000000..0e977514ff6de041957632eabca77c2f59f6ea99 Binary files /dev/null and b/android/assets/fonts/Roboto/Roboto-Light.ttf differ diff --git a/android/assets/fonts/Roboto/Roboto-LightItalic.ttf b/android/assets/fonts/Roboto/Roboto-LightItalic.ttf new file mode 100644 index 0000000000000000000000000000000000000000..3ad14fa7c4c70ed7774d63b4d133a10c193c1cbe Binary files /dev/null and b/android/assets/fonts/Roboto/Roboto-LightItalic.ttf differ diff --git a/android/assets/fonts/Roboto/Roboto-Medium.ttf b/android/assets/fonts/Roboto/Roboto-Medium.ttf new file mode 100644 index 0000000000000000000000000000000000000000..e89b0b79a2910f0ac309a1845a9f733bcb568792 Binary files /dev/null and b/android/assets/fonts/Roboto/Roboto-Medium.ttf differ diff --git a/android/assets/fonts/Roboto/Roboto-MediumItalic.ttf b/android/assets/fonts/Roboto/Roboto-MediumItalic.ttf new file mode 100644 index 0000000000000000000000000000000000000000..a5a41d3d00295049c15eea2a84a10f9b22b38ca9 Binary files /dev/null and b/android/assets/fonts/Roboto/Roboto-MediumItalic.ttf differ diff --git a/android/assets/fonts/Roboto/Roboto-Regular.ttf b/android/assets/fonts/Roboto/Roboto-Regular.ttf new file mode 100644 index 0000000000000000000000000000000000000000..3d6861b42396c609e26f38f129383c558e332281 Binary files /dev/null and b/android/assets/fonts/Roboto/Roboto-Regular.ttf differ diff --git a/android/assets/fonts/Roboto/Roboto-Thin.ttf b/android/assets/fonts/Roboto/Roboto-Thin.ttf new file mode 100644 index 0000000000000000000000000000000000000000..7d084aed88451b9ace90558113db803815c14d3f Binary files /dev/null and b/android/assets/fonts/Roboto/Roboto-Thin.ttf differ diff --git a/android/assets/fonts/Roboto/Roboto-ThinItalic.ttf b/android/assets/fonts/Roboto/Roboto-ThinItalic.ttf new file mode 100644 index 0000000000000000000000000000000000000000..c17338960cfa6a6b5a056ab5bcab32d8db2d19a8 Binary files /dev/null and b/android/assets/fonts/Roboto/Roboto-ThinItalic.ttf differ diff --git a/android/assets/highscore.png b/android/assets/highscore.png new file mode 100644 index 0000000000000000000000000000000000000000..5e927f4f38f5acf14ab7070e563e6aba4cb99179 Binary files /dev/null and b/android/assets/highscore.png differ diff --git a/android/assets/hit_by_paintball.mp3 b/android/assets/hit_by_paintball.mp3 deleted file mode 100644 index 0c052ec72404a7a45e6f2d4397d6cc5fd2badf09..0000000000000000000000000000000000000000 Binary files a/android/assets/hit_by_paintball.mp3 and /dev/null differ diff --git a/android/assets/join_lobby.png b/android/assets/join_lobby.png new file mode 100644 index 0000000000000000000000000000000000000000..79025af1063e73c98a673459262ca77e2d4bd771 Binary files /dev/null and b/android/assets/join_lobby.png differ diff --git a/android/assets/lobby_header_X6.png b/android/assets/lobby_header_X6.png new file mode 100644 index 0000000000000000000000000000000000000000..0a2ad604ab1580bf9a48507953c0b8ea484d2670 Binary files /dev/null and b/android/assets/lobby_header_X6.png differ diff --git a/android/assets/page1.png b/android/assets/page1.png new file mode 100644 index 0000000000000000000000000000000000000000..8996fb4e72bd8cc4053d79f9e28c9ae86afc25eb Binary files /dev/null and b/android/assets/page1.png differ diff --git a/android/assets/page2.png b/android/assets/page2.png new file mode 100644 index 0000000000000000000000000000000000000000..55cd9ac460182db80f55b86416fc156149349cc2 Binary files /dev/null and b/android/assets/page2.png differ diff --git a/android/assets/page3.png b/android/assets/page3.png new file mode 100644 index 0000000000000000000000000000000000000000..f8f980da8c6533b6d1edb2aa5829b8e3800b4b57 Binary files /dev/null and b/android/assets/page3.png differ diff --git a/android/assets/page4.png b/android/assets/page4.png new file mode 100644 index 0000000000000000000000000000000000000000..61ddefb653522296cda51c32f40f0ca0c528a675 Binary files /dev/null and b/android/assets/page4.png differ diff --git a/android/assets/settings_header_X6.png b/android/assets/settings_header_X6.png new file mode 100644 index 0000000000000000000000000000000000000000..25ac2e97c5740cbc4e1f53704d4075fb8a7082cc Binary files /dev/null and b/android/assets/settings_header_X6.png differ diff --git a/android/assets/target.png b/android/assets/target.png new file mode 100644 index 0000000000000000000000000000000000000000..cc2ea6c4aa944df052a7820b1e29f252b1f52d33 Binary files /dev/null and b/android/assets/target.png differ diff --git a/android/assets/target_hit.mp3 b/android/assets/target_hit.mp3 new file mode 100644 index 0000000000000000000000000000000000000000..c43a4d2dc9346bba639df7b6a81d85dce045292b Binary files /dev/null and b/android/assets/target_hit.mp3 differ diff --git a/android/assets/winSound.mp3 b/android/assets/winSound.mp3 new file mode 100644 index 0000000000000000000000000000000000000000..e983c2d1b91df5e417b586973c05919287d1d534 Binary files /dev/null and b/android/assets/winSound.mp3 differ diff --git a/android/src/com/tdt4240/paint2win/AndroidLauncher.java b/android/src/com/tdt4240/paint2win/AndroidLauncher.java index c0019295c6440ec99c4f43bcf09f7c713ea5c44a..2dea9f752c9e70bb26834e921e3aed67439ada41 100644 --- a/android/src/com/tdt4240/paint2win/AndroidLauncher.java +++ b/android/src/com/tdt4240/paint2win/AndroidLauncher.java @@ -7,6 +7,10 @@ import com.badlogic.gdx.backends.android.AndroidApplicationConfiguration; import com.tdt4240.paint2win.Paint2Win; public class AndroidLauncher extends AndroidApplication { + + /** + * Initializes the game on android devices and opens the Paint2Win class in core + */ @Override protected void onCreate (Bundle savedInstanceState) { super.onCreate(savedInstanceState); diff --git a/build.gradle b/build.gradle index 1aced8073bae85e9d584565caa4186b268cf8282..7aaac67e362164fcc168e7e75461892bc54a0522 100644 --- a/build.gradle +++ b/build.gradle @@ -1,6 +1,5 @@ -buildscript { - +buildscript { repositories { mavenLocal() mavenCentral() @@ -12,13 +11,19 @@ buildscript { dependencies { classpath 'org.wisepersist:gwt-gradle-plugin:1.0.13' classpath 'org.gretty:gretty:3.0.2' - classpath 'com.android.tools.build:gradle:4.1.2' + classpath 'com.android.tools.build:gradle:4.1.3' classpath 'com.mobidevelop.robovm:robovm-gradle-plugin:2.3.12' } } +plugins { + id 'org.springframework.boot' version '2.4.5' + id 'io.spring.dependency-management' version '1.0.11.RELEASE' + id 'java' +} + allprojects { apply plugin: "eclipse" @@ -133,6 +138,20 @@ project(":core") { api "com.badlogicgames.gdx:gdx-box2d:$gdxVersion" api "com.badlogicgames.gdx:gdx-freetype:$gdxVersion" api "com.badlogicgames.ashley:ashley:$ashleyVersion" - + api "com.fasterxml.jackson.core:jackson-databind:2.12.2" + api "com.fasterxml.jackson.core:jackson-core:2.12.2" } } + +project(":rest") { + apply plugin: "java-library" + apply plugin: 'org.springframework.boot' + apply plugin: 'io.spring.dependency-management' + + dependencies { + implementation 'org.springframework.boot:spring-boot-starter-data-jpa' + implementation 'org.springframework.boot:spring-boot-starter-web' + runtimeOnly 'mysql:mysql-connector-java' + testImplementation 'org.springframework.boot:spring-boot-starter-test' + } +} \ No newline at end of file diff --git a/core/src/com/tdt4240/paint2win/Paint2Win.java b/core/src/com/tdt4240/paint2win/Paint2Win.java index 57444eaa756de4fb408bfdf56a25c8996c4c76b8..295f3804272d852c9bf72c65eb8a7d1404c724a5 100644 --- a/core/src/com/tdt4240/paint2win/Paint2Win.java +++ b/core/src/com/tdt4240/paint2win/Paint2Win.java @@ -1,58 +1,52 @@ package com.tdt4240.paint2win; import com.badlogic.gdx.Game; -import com.badlogic.gdx.audio.Music; import com.badlogic.gdx.graphics.GL20; import com.badlogic.gdx.graphics.g2d.SpriteBatch; +import com.tdt4240.paint2win.controller.managers.AudioManager; import com.tdt4240.paint2win.controller.states.GameStateManager; import com.tdt4240.paint2win.controller.states.MainMenu; import com.badlogic.gdx.Gdx; - -import static com.badlogic.gdx.Gdx.audio; +import com.tdt4240.paint2win.controller.managers.SoundAssets; public class Paint2Win extends Game { public static final int MAP_WIDTH = 3200; public static final int MAP_HEIGHT = 2400; public static final int MENU_WIDTH = 800; public static final int MENU_HEIGHT = 480; - private static float music_volume = 0.1f; - private static float sfx_volume = 0.1f; + public static final AudioManager AUDIO_MANAGER = AudioManager.getAudioManager(); + public static final int TARGETS_TO_HIT = 20; + public SoundAssets assets; private GameStateManager gsm; private SpriteBatch sb; + /** + * Creates a spriteBatch, gameStateManager and sets + * MainMenu as the current screen + */ @Override public void create () { + assets = new SoundAssets(); + assets.load(); //starts loading assets + while(!assets.assetManager.update()) { + float progress = assets.assetManager.getProgress(); + System.out.println("Loading ... " + progress * 100 + "%"); + } + sb = new SpriteBatch(); gsm = new GameStateManager(); gsm.push(new MainMenu(gsm)); } + /** + * Updates the delta time and rerenders the GameStateManager + */ @Override public void render () { Gdx.gl.glClear(GL20.GL_COLOR_BUFFER_BIT); gsm.update(Gdx.graphics.getDeltaTime()); gsm.render(sb); } - - @Override - public void dispose () { - super.dispose(); - } - - public static float getMusic_volume() { - return music_volume; - } - public static void setMusic_volume(float volume) { - music_volume = volume; - } - - public static float getSfx_volume() { - return sfx_volume; - } - - public static void setSfx_volume(float volume) { - Paint2Win.sfx_volume = volume; - } } diff --git a/core/src/com/tdt4240/paint2win/container/BulletsContainer.java b/core/src/com/tdt4240/paint2win/container/BulletsContainer.java index eaae52fd1625a054994e104ceeb0c0d4ae1c8efb..afb628542b0ad558e1fba54d2dff9d8d96771934 100644 --- a/core/src/com/tdt4240/paint2win/container/BulletsContainer.java +++ b/core/src/com/tdt4240/paint2win/container/BulletsContainer.java @@ -8,27 +8,56 @@ import java.util.List; public class BulletsContainer implements IContainer<Bullet> { private final List<Bullet> bullets; + /** + * List of all bullets on the map, implements IContainer + * Used to perform actions on all obstacles + */ public BulletsContainer() { this(new ArrayList<>()); } + /** + * List of all bullets on the map, implements IContainer + * Used to perform actions on all obstacles + * @param bullets + */ public BulletsContainer(List<Bullet> bullets) { this.bullets = bullets; } + /** + * Add a bullet to the list of bullets + * @param bullet + */ @Override public void add(Bullet bullet) { bullets.add(bullet); } + /** + * Returns all the current bullets + * @return list of bullets + */ @Override public List<Bullet> getAll() { return bullets; } + /** + * First checks if bullets should be removed. This is when the bullet is out of set range, out of map + * or has hit something. If the bullet is not removed, it get's a new position + * @param delta delta time used to make updating synchronized + */ @Override public void update(float delta) { bullets.removeIf(bullet -> !bullet.isInRange() || bullet.hasHitSomething() || bullet.isOutOfMap()); bullets.forEach(bullet -> bullet.move(delta)); } + + /** + * Disposes all the bullets in the conatiner + */ + public void dispose(){ + bullets.forEach(bullet -> bullet.dispose()); + } } diff --git a/core/src/com/tdt4240/paint2win/container/ObstacleContainer.java b/core/src/com/tdt4240/paint2win/container/ObstacleContainer.java index 8f143487d53ce5dbfa18195e02566893e906fa2d..7f66e60235360f3bde177dc1275664811586fef9 100644 --- a/core/src/com/tdt4240/paint2win/container/ObstacleContainer.java +++ b/core/src/com/tdt4240/paint2win/container/ObstacleContainer.java @@ -42,4 +42,8 @@ public class ObstacleContainer implements IContainer<Obstacle> { @Override public void update(float delta) { } + + public void dispose(){ + obstacles.forEach(obstacle -> obstacle.dispose()); + } } \ No newline at end of file diff --git a/core/src/com/tdt4240/paint2win/container/PlayersContainer.java b/core/src/com/tdt4240/paint2win/container/PlayersContainer.java index 15a6429c73671f7e25acd4da62e1520214abed78..536c5ce218a0526ff10b6296697c4e932f7d42e5 100644 --- a/core/src/com/tdt4240/paint2win/container/PlayersContainer.java +++ b/core/src/com/tdt4240/paint2win/container/PlayersContainer.java @@ -39,6 +39,10 @@ public class PlayersContainer implements IContainer<Player> { return players; } + /** + * Updates all the current players + * @param delta delta time used to make updating synchronized + */ @Override public void update(float delta) { players.forEach(player -> player.update()); @@ -59,4 +63,8 @@ public class PlayersContainer implements IContainer<Player> { public Stream<Bullet> obtainAndStreamBullets() { return streamShooters().map(Shooter::obtainBullet).filter(Optional::isPresent).map(Optional::get); } + + public void dispose(){ + players.forEach(player -> player.dispose()); + } } diff --git a/core/src/com/tdt4240/paint2win/controller/controls/DualJoysticks.java b/core/src/com/tdt4240/paint2win/controller/controls/DualJoysticks.java index fbbe9b5062b87186e7a298d3df3dccbf442d903b..0b6a2976a891ef58034eb8362599265c286ae06c 100644 --- a/core/src/com/tdt4240/paint2win/controller/controls/DualJoysticks.java +++ b/core/src/com/tdt4240/paint2win/controller/controls/DualJoysticks.java @@ -4,12 +4,12 @@ import com.badlogic.gdx.graphics.Texture; import com.badlogic.gdx.math.Vector2; import com.badlogic.gdx.scenes.scene2d.Stage; import com.badlogic.gdx.scenes.scene2d.ui.Skin; -import com.tdt4240.paint2win.utility.IJoystickObserver; import java.util.ArrayList; import java.util.List; -/**Represents both joysticks on the screen +/** + * Represents both joysticks on the screen * @author JLK */ public class DualJoysticks { @@ -17,7 +17,9 @@ public class DualJoysticks { private Joystick PosJoystick; private Joystick RotJoystick; - //List of observers that observes both jyosticks + /** + * List of observers that observes both joysticks + */ private List<IJoystickObserver> observers = new ArrayList<>(); public DualJoysticks(Stage stage){ @@ -30,8 +32,8 @@ public class DualJoysticks { RotJoystick.setBounds(stage.getWidth()-600, 450, 500, 500); } - /**Render method that need to be run every frame - * + /** + * Render method that need to be run every frame */ public void render(){ PosJoystick.render(); @@ -40,8 +42,8 @@ public class DualJoysticks { } - /**Sends info to observers of DualJoysticks - * + /** + * Sends info to observers of DualJoysticks * @param position sends PosJoysticks position with getJoystickCoordinates() * @param rotation send RotJoysticks rotation with getDegrees() * @param usingRotJoystick send a boolean true if the RotJoystick is beeing used @@ -52,17 +54,17 @@ public class DualJoysticks { } } - /** Add a observer to observer list of this class - * + /** + * Add a observer to observer list of this class * @param observer needs to be a observable object of IObserver */ public void addObserver(IJoystickObserver observer) { observers.add(observer); } - /**removers the observer from List + /** + * Removes the observer from List * should be done in desctructors to avoid index errors - * * @param observer needs to be a observable object of IObserver */ public void removeObserver(IJoystickObserver observer) { diff --git a/core/src/com/tdt4240/paint2win/utility/IJoystickObserver.java b/core/src/com/tdt4240/paint2win/controller/controls/IJoystickObserver.java similarity index 88% rename from core/src/com/tdt4240/paint2win/utility/IJoystickObserver.java rename to core/src/com/tdt4240/paint2win/controller/controls/IJoystickObserver.java index e88b5aef9f16150187f1c0f78068439fe7abbadb..a0c83a0c109107fa7d98431d6413726a0321d91f 100644 --- a/core/src/com/tdt4240/paint2win/utility/IJoystickObserver.java +++ b/core/src/com/tdt4240/paint2win/controller/controls/IJoystickObserver.java @@ -1,4 +1,4 @@ -package com.tdt4240.paint2win.utility; +package com.tdt4240.paint2win.controller.controls; import com.badlogic.gdx.math.Vector2; diff --git a/core/src/com/tdt4240/paint2win/controller/controls/Joystick.java b/core/src/com/tdt4240/paint2win/controller/controls/Joystick.java index ad79fedab073ee5551fe2db940a173da257dee20..82f1312039c417da5efdd675d07f02da61356373 100644 --- a/core/src/com/tdt4240/paint2win/controller/controls/Joystick.java +++ b/core/src/com/tdt4240/paint2win/controller/controls/Joystick.java @@ -61,7 +61,7 @@ public class Joystick { } /** - * the render method that needs to be run every frame + * The render method that needs to be run every frame */ public void render() { stage.act(Gdx.graphics.getDeltaTime()); @@ -84,7 +84,7 @@ public class Joystick { } /** - * joystick circle can be represented as a unit circle + * Joystick circle can be represented as a unit circle * @return coordinates th knob is set to on the unit circle */ public Vector2 getJoystickCoordinates(){return new Vector2(joystick.getKnobPercentX(),joystick.getKnobPercentY());} diff --git a/core/src/com/tdt4240/paint2win/controller/managers/AudioManager.java b/core/src/com/tdt4240/paint2win/controller/managers/AudioManager.java new file mode 100644 index 0000000000000000000000000000000000000000..292c6d109a951172e2254690de1af2e639c2d781 --- /dev/null +++ b/core/src/com/tdt4240/paint2win/controller/managers/AudioManager.java @@ -0,0 +1,103 @@ +package com.tdt4240.paint2win.controller.managers; + +import com.badlogic.gdx.audio.Music; +import com.badlogic.gdx.audio.Sound; + +public class AudioManager { + private static final AudioManager INSTANCE = new AudioManager(); + private static Music playingMusic; + private static Sound playingSound; + private static float music_volume = 0.1f; + private static float sfx_volume = 0.1f; + + // singleton: prevent instantiation from other classes + private AudioManager() { + } + + + public static AudioManager getAudioManager() { + return INSTANCE; + } + + /** + * Plays a sfx sound + * @param sound name of the sfx sound + */ + public void playSound (Sound sound) { + playingSound = sound; + playingSound.play(sfx_volume); + } + + /** + * Starts playing a song + * @param song name of the mp3 song + */ + public void playMusic (Music song) { + if(playingMusic != null){ + playingMusic.stop(); + } + playingMusic = song; + playingMusic.setLooping(true); + playingMusic.setVolume(music_volume); + playingMusic.play(); + } + + /** + * Stops the current sfx sound + */ + public void stopSfx(){ + if(playingSound != null){ + playingSound.stop(); + } + } + + /** + * Stops the current song + */ + public void stopMusic(){ + if(playingMusic != null){ + playingMusic.stop(); + } + } + + /** + * Returns the music volume + * @return float - music volume + */ + public static float getMusic_volume() { + return music_volume; + } + + /** + * Updates the music volume with float between 0 and 1 + * @param volume - float new volume + */ + public static void setMusic_volume(float volume) { + music_volume = volume; + if(playingMusic != null){ + playingMusic.setVolume(music_volume); + } + } + + /** + * Returns the sfx volume + * @return float - sfx volume + */ + public static float getSfx_volume() { + return sfx_volume; + } + + /** + * Updates the sfx volume with float between 0 and 1 + * @param volume - float new volume + */ + public static void setSfx_volume(float volume, Sound sound) { + sfx_volume = volume; + if(playingSound != null) { + playingSound.stop(); + } + playingSound = sound; + playingSound.play(sfx_volume); + } + +} diff --git a/core/src/com/tdt4240/paint2win/controller/managers/Collider.java b/core/src/com/tdt4240/paint2win/controller/managers/Collider.java index c1581aad954c65cb4c77d6744e14e5a829303cac..0de362a600641fd74e54bf73dfb82c654e39d1bc 100644 --- a/core/src/com/tdt4240/paint2win/controller/managers/Collider.java +++ b/core/src/com/tdt4240/paint2win/controller/managers/Collider.java @@ -3,11 +3,13 @@ package com.tdt4240.paint2win.controller.managers; import com.tdt4240.paint2win.container.BulletsContainer; import com.tdt4240.paint2win.container.ObstacleContainer; import com.tdt4240.paint2win.container.PlayersContainer; +import com.tdt4240.paint2win.model.Target; public class Collider { private final PlayersContainer playersContainer; private final BulletsContainer bulletsContainer; private final ObstacleContainer obstacleContainer; + private final Target target; /** * Manager to check if bullet and players collide (player get shoot), @@ -16,10 +18,11 @@ public class Collider { * @param bulletsContainer Container with bullets in the map * @param obstacleContainer Container with obstacles in the map */ - public Collider(PlayersContainer playersContainer, BulletsContainer bulletsContainer, ObstacleContainer obstacleContainer) { + public Collider(PlayersContainer playersContainer, BulletsContainer bulletsContainer, ObstacleContainer obstacleContainer, Target target) { this.playersContainer = playersContainer; this.bulletsContainer = bulletsContainer; this.obstacleContainer = obstacleContainer; + this.target = target; } /** @@ -27,12 +30,8 @@ public class Collider { * checks if bullet hits obstacle (removes bullet) */ public void checkCollisions() { - bulletsContainer.stream().forEach(bullet -> playersContainer.stream() - .filter(player -> player.getShooter().isPresent()) - .filter(player -> player.getShooter() - .get().collidesWith(bullet)) - .findFirst() - .ifPresent(player -> {player.noticeHit(); bullet.noticeHit();})); + bulletsContainer.stream().filter(bullet -> bullet.collidesWith(target)) + .findFirst().ifPresent(bullet -> {target.noticeHit(); bullet.noticeHit();}); bulletsContainer.stream().forEach(bullet -> obstacleContainer.stream() .filter(obstacle -> obstacle.collidesWith(bullet)) .findFirst() diff --git a/core/src/com/tdt4240/paint2win/controller/managers/Respawner.java b/core/src/com/tdt4240/paint2win/controller/managers/Respawner.java index e67bc6966e7755e17766f33f33195fd17bbfcd41..50e765b3fb185db3a70c6b6ad1a17144c35b4efa 100644 --- a/core/src/com/tdt4240/paint2win/controller/managers/Respawner.java +++ b/core/src/com/tdt4240/paint2win/controller/managers/Respawner.java @@ -43,7 +43,7 @@ public class Respawner { * @return random Vector2 from respawn points */ private Vector2 randomRespawnPoint(ObstacleContainer obstacleContainer) { - Circle tempCircle = new Circle(new Vector2(Shooter.SHOOTERWIDTH/1.5f, Shooter.SHOOTERHEIGHT/1.5f), new Vector2(0, 0)); + Circle tempCircle = new Circle(0,0, (float) Math.sqrt(Math.pow(Shooter.SHOOTERWIDTH, 2) + Math.pow(Shooter.SHOOTERHEIGHT, 2))); while(true) { Vector2 randomPos = new Vector2(random.nextInt((int)Math.floor(Paint2Win.MAP_WIDTH-Shooter.SHOOTERWIDTH)), random.nextInt((int) Math.floor(Paint2Win.MAP_HEIGHT-Shooter.SHOOTERHEIGHT))); @@ -52,7 +52,9 @@ public class Respawner { .filter(obstacle -> Intersector.overlaps(tempCircle,obstacle.getSprite().getBoundingRectangle())) .findAny(); if (!collidingObstacle.isPresent()) { - return randomPos; + //Returns position of where the lower left corner of the player-texture should be. Not the center of the circle + Vector2 lowerLeftCornerPos = new Vector2(randomPos.x - Shooter.SHOOTERWIDTH/2, randomPos.y - Shooter.SHOOTERHEIGHT/2); + return lowerLeftCornerPos; } } } diff --git a/core/src/com/tdt4240/paint2win/controller/managers/SoundAssets.java b/core/src/com/tdt4240/paint2win/controller/managers/SoundAssets.java new file mode 100644 index 0000000000000000000000000000000000000000..a637f2fb706b92dc25ac6c31a820d08bbaed050c --- /dev/null +++ b/core/src/com/tdt4240/paint2win/controller/managers/SoundAssets.java @@ -0,0 +1,42 @@ +package com.tdt4240.paint2win.controller.managers; + +import com.badlogic.gdx.assets.AssetDescriptor; + +import com.badlogic.gdx.assets.AssetManager; +import com.badlogic.gdx.audio.Music; +import com.badlogic.gdx.audio.Sound; +import com.badlogic.gdx.utils.Disposable; + +public class SoundAssets implements Disposable { + public AssetManager assetManager; + + public static final AssetDescriptor<Sound> failSound = new AssetDescriptor<Sound>("failSound.mp3", Sound.class); + public static final AssetDescriptor<Sound> target_hit = new AssetDescriptor<Sound>("target_hit.mp3", Sound.class); + public static final AssetDescriptor<Music> menu_soundtrack_1 = new AssetDescriptor<Music>("menu_soundtrack.mp3", Music.class); + public static final AssetDescriptor<Music> menu_soundtrack_2 = new AssetDescriptor<Music>("menu_soundtrack_2.mp3", Music.class); + public static final AssetDescriptor<Sound> paintball_sound = new AssetDescriptor<Sound>("paintball_sound.mp3", Sound.class); + public static final AssetDescriptor<Music> run_free = new AssetDescriptor<Music>("run_free.mp3", Music.class); + public static final AssetDescriptor<Sound> winSound = new AssetDescriptor<Sound>("winSound.mp3", Sound.class); + + public SoundAssets(){ + assetManager=new AssetManager(); + } + + /** + * Loads all sound and music files to the assets manager + */ + public void load() { + assetManager.load(failSound); + assetManager.load(target_hit); + assetManager.load(menu_soundtrack_1); + assetManager.load(menu_soundtrack_2); + assetManager.load(paintball_sound); + assetManager.load(run_free); + assetManager.load(winSound); + } + + @Override + public void dispose() { + assetManager.dispose(); + } +} diff --git a/core/src/com/tdt4240/paint2win/controller/states/CreateGame.java b/core/src/com/tdt4240/paint2win/controller/states/CreateGame.java index 99a9edc946eea7ba2c314d5a7babeab7a4b423cc..fd1213d4261392eb6d06e190250d12f07c332ab4 100644 --- a/core/src/com/tdt4240/paint2win/controller/states/CreateGame.java +++ b/core/src/com/tdt4240/paint2win/controller/states/CreateGame.java @@ -1,72 +1,186 @@ package com.tdt4240.paint2win.controller.states; import com.badlogic.gdx.Gdx; -import com.badlogic.gdx.audio.Music; +import com.badlogic.gdx.graphics.Color; +import com.badlogic.gdx.graphics.Colors; import com.badlogic.gdx.graphics.GL20; import com.badlogic.gdx.graphics.OrthographicCamera; import com.badlogic.gdx.graphics.Texture; import com.badlogic.gdx.graphics.g2d.SpriteBatch; -import com.badlogic.gdx.graphics.glutils.ShapeRenderer; import com.badlogic.gdx.math.Rectangle; import com.badlogic.gdx.math.Vector2; import com.badlogic.gdx.math.Vector3; +import com.badlogic.gdx.scenes.scene2d.Actor; +import com.badlogic.gdx.scenes.scene2d.Stage; +import com.badlogic.gdx.scenes.scene2d.ui.Label; +import com.badlogic.gdx.scenes.scene2d.ui.SelectBox; +import com.badlogic.gdx.scenes.scene2d.ui.Skin; +import com.badlogic.gdx.scenes.scene2d.ui.Table; +import com.badlogic.gdx.scenes.scene2d.ui.TextField; +import com.badlogic.gdx.scenes.scene2d.utils.ChangeListener; +import com.badlogic.gdx.utils.Align; +import com.badlogic.gdx.utils.viewport.StretchViewport; +import com.badlogic.gdx.utils.viewport.Viewport; import com.tdt4240.paint2win.Paint2Win; +import com.tdt4240.paint2win.controller.managers.SoundAssets; +import com.tdt4240.paint2win.model.maps.AbstractMap; -import static com.badlogic.gdx.Gdx.audio; import static com.tdt4240.paint2win.Paint2Win.MENU_HEIGHT; import static com.tdt4240.paint2win.Paint2Win.MENU_WIDTH; public class CreateGame extends State { - - private OrthographicCamera cam; private final Texture colorsImage; - private Music music; + private Texture header; private final Texture mainMenuButton; private final int mainMenuButtonXPosition; private final int mainMenuButtonYPosition; - + private final Texture startGameButton; + private final int startGameButtonXPosition; + private final int startGameButtonYPosition; + + private Viewport viewport; + private AbstractMap.valid_maps chosen_map; + private Stage stage; + private SelectBox<AbstractMap.valid_maps> selectMapBox; + TextField usernameTextField; + private String username; + private Color playerColor; + + /** + * Page for creating a new game. Let's the user select a map and then start + * a new lobby + * @param gsm + */ public CreateGame(GameStateManager gsm) { super(gsm); cam = new OrthographicCamera(); cam.setToOrtho(false, MENU_WIDTH, MENU_HEIGHT); - colorsImage = new Texture("colors.jpg"); + viewport = new StretchViewport(MENU_WIDTH, MENU_HEIGHT, cam); - music = audio.newMusic(Gdx.files.internal("menu_soundtrack_2.mp3")); - music.setLooping(true); - music.setVolume(Paint2Win.getMusic_volume()); - music.play(); + colorsImage = new Texture("colors.jpg"); + header = new Texture("create_game_header_X6.png"); + + Paint2Win.AUDIO_MANAGER.playMusic(((Paint2Win)Gdx.app.getApplicationListener()).assets.assetManager.get(SoundAssets.menu_soundtrack_2)); mainMenuButton = new Texture("main_menu.png"); - mainMenuButtonXPosition = MENU_WIDTH/2 - mainMenuButton.getWidth()/2; + mainMenuButtonXPosition = MENU_WIDTH/4 - mainMenuButton.getWidth()/2; mainMenuButtonYPosition = MENU_HEIGHT/4; - } - private void createGame(String name){ + startGameButton = new Texture("start.png"); + startGameButtonXPosition = 3* MENU_WIDTH /4 - startGameButton.getWidth()/2; + startGameButtonYPosition = MENU_HEIGHT /4; + chosen_map = AbstractMap.valid_maps.DESERT; + renderStageComponents(); } - private void toMainMenu(){ - gsm.set(new MainMenu(gsm)); + /** + * Function for rendering the stage components. Just implemented to make the code more readable + */ + private void renderStageComponents() { + Skin skin = new Skin(Gdx.files.internal("uiskin.json")); + stage = new Stage(viewport); + Gdx.input.setInputProcessor(stage); + Table table = new Table(); + + Label selectNameLabel = new Label("Enter name:", skin); + selectNameLabel.setColor(Color.BLACK); + selectNameLabel.setAlignment(Align.center); + + usernameTextField = new TextField(username, skin); + usernameTextField.setSize(100, 30); + usernameTextField.setMaxLength(8); + usernameTextField.setText("Player"); + + Label selectMapLabel = new Label("Choose map:", skin); + selectMapLabel.setColor(Color.BLACK); + selectMapLabel.setAlignment(Align.center); + + selectMapBox = new SelectBox<AbstractMap.valid_maps>(skin); + selectMapBox.addListener(new ChangeListener() { + public void changed(ChangeEvent event, Actor actor) { + chosen_map = selectMapBox.getSelected(); + } + }); + selectMapBox.setItems(AbstractMap.valid_maps.DESERT, AbstractMap.valid_maps.URBAN); + + Label selectColorLabel = new Label("Choose player color:", skin); + selectColorLabel.setColor(Color.BLACK); + selectColorLabel.setAlignment(Align.center); + + SelectBox<String> selectColorBox = new SelectBox<String>(skin); + selectColorBox.addListener(new ChangeListener() { + public void changed(ChangeEvent event, Actor actor) { + playerColor = Colors.get(selectColorBox.getSelected()); + } + }); + selectColorBox.setItems(Colors.getColors().keys().toArray()); + + table.add(selectNameLabel).width(135f).center().padRight(20); + table.add(selectColorLabel).width(135f).center().padRight(20); + table.add(selectMapLabel).width(135f).center(); + table.row(); + table.add(usernameTextField).width(135f).center().padRight(20); + table.add(selectColorBox).width(135f).center().padRight(20); + table.add(selectMapBox).width(135f).center(); + + table.setPosition((int) (MENU_WIDTH/2), (int) (5*MENU_HEIGHT/8)); + + stage.addActor(table); } + /** + * Function for going to start a game lobby + */ + private void playGame(){ + if(!username.trim().equals("")){ + gsm.set(new PlayState(gsm, chosen_map, username, playerColor)); + } + } + + /** + * Function for returning to the Main Menu + */ + private void toMainMenu(){ gsm.set(new MainMenu(gsm)); } + + /** + * Function for checking if one of the buttons have been pressed. + * What happens is that when the screen is touched it checks if the area pressed is + * inside the rectangle of one of the button, and fires the function assosiated with that button + * if that is the case. + */ private void checkIfPressedButton() { if(Gdx.input.justTouched()) { Vector3 tmp = new Vector3(new Vector2(Gdx.input.getX(), Gdx.input.getY()), 0); cam.unproject(tmp); Rectangle mainMenuBounds = new Rectangle(mainMenuButtonXPosition, mainMenuButtonYPosition, mainMenuButton.getWidth(), mainMenuButton.getHeight()); + Rectangle startGameBounds = new Rectangle(startGameButtonXPosition, startGameButtonYPosition, startGameButton.getWidth(), startGameButton.getHeight()); if(mainMenuBounds.contains(tmp.x,tmp.y)) { toMainMenu(); } + else if(startGameBounds.contains(tmp.x,tmp.y)) { playGame(); } } } + /** + * Updates the current state of the screen. + * Calls function to see if button was pressed + * @param dt + */ @Override public void update(float dt) { + if (username != usernameTextField.getText()) { + username = usernameTextField.getText(); + } checkIfPressedButton(); } + /** + * Rerenders the screen with updated values + * @param sb + */ @Override public void render(SpriteBatch sb) { Gdx.gl.glClearColor(0, 0, 0, 1); @@ -74,15 +188,29 @@ public class CreateGame extends State { sb.setProjectionMatrix(cam.combined); sb.begin(); sb.draw(colorsImage, 0,0, MENU_WIDTH, MENU_HEIGHT); + sb.draw(header, MENU_WIDTH/2 - header.getWidth()/2,3*MENU_HEIGHT/4); sb.draw(mainMenuButton, mainMenuButtonXPosition, mainMenuButtonYPosition); + sb.draw(startGameButton, startGameButtonXPosition, startGameButtonYPosition); sb.end(); + stage.draw(); + stage.act(); } + /** + * Disposes the page when leaving it + */ @Override public void dispose() { System.out.println("Disposed Create Game"); - music.dispose(); mainMenuButton.dispose(); + startGameButton.dispose(); + header.dispose(); colorsImage.dispose(); + stage.dispose(); + } + + @Override + public void resize(int width, int height) { + viewport.update(width, height); } } diff --git a/core/src/com/tdt4240/paint2win/controller/states/FinishedGame.java b/core/src/com/tdt4240/paint2win/controller/states/FinishedGame.java new file mode 100644 index 0000000000000000000000000000000000000000..105a5833b9a95a6c86a6192add8e3d280099dd42 --- /dev/null +++ b/core/src/com/tdt4240/paint2win/controller/states/FinishedGame.java @@ -0,0 +1,157 @@ +package com.tdt4240.paint2win.controller.states; + +import com.badlogic.gdx.Gdx; +import com.badlogic.gdx.graphics.Color; +import com.badlogic.gdx.graphics.GL20; +import com.badlogic.gdx.graphics.OrthographicCamera; +import com.badlogic.gdx.graphics.Texture; +import com.badlogic.gdx.graphics.g2d.BitmapFont; +import com.badlogic.gdx.graphics.g2d.GlyphLayout; +import com.badlogic.gdx.graphics.g2d.SpriteBatch; +import com.badlogic.gdx.graphics.g2d.freetype.FreeTypeFontGenerator; +import com.badlogic.gdx.math.Rectangle; +import com.badlogic.gdx.math.Vector2; +import com.badlogic.gdx.math.Vector3; +import com.badlogic.gdx.utils.viewport.StretchViewport; +import com.badlogic.gdx.utils.viewport.Viewport; +import com.tdt4240.paint2win.Paint2Win; +import com.tdt4240.paint2win.controller.managers.SoundAssets; +import com.tdt4240.paint2win.model.TimerWatch; + +import static com.tdt4240.paint2win.Paint2Win.MENU_HEIGHT; +import static com.tdt4240.paint2win.Paint2Win.MENU_WIDTH; + +public class FinishedGame extends State { + + private OrthographicCamera cam; + private final Texture backgroundImage; + private final Texture mainMenuButton; + private final int mainMenuButtonXPosition; + private final int mainMenuButtonYPosition; + private BitmapFont textRenderer; + private final int timeUsed; + private final int placement; + private final boolean newPR; + private final boolean postProblem; + private final Viewport viewport; + + public FinishedGame(GameStateManager gsm, boolean postProblem,int placement, boolean newPR, int timeUsed) { + super(gsm); + this.textRenderer = new BitmapFont(); + this.timeUsed = timeUsed; + this.newPR = newPR; + + FreeTypeFontGenerator generator = new FreeTypeFontGenerator(Gdx.files.internal("fonts/Roboto/Roboto-Bold.ttf")); + FreeTypeFontGenerator.FreeTypeFontParameter parameter = new FreeTypeFontGenerator.FreeTypeFontParameter(); + parameter.size = 60; + textRenderer = generator.generateFont(parameter); // font size 12 pixels + generator.dispose(); // don't forget to dispose to avoid memory leaks! + textRenderer.setColor(Color.WHITE); + cam = new OrthographicCamera(); + cam.setToOrtho(false, MENU_WIDTH, MENU_HEIGHT); + viewport = new StretchViewport(MENU_WIDTH, MENU_HEIGHT, cam); + backgroundImage = new Texture("WinOrLose.png"); + mainMenuButton = new Texture("main_menu.png"); + mainMenuButtonXPosition = MENU_WIDTH /2 - mainMenuButton.getWidth()/2; + mainMenuButtonYPosition = MENU_HEIGHT /6; + Paint2Win.AUDIO_MANAGER.stopMusic(); + this.placement = placement; + this.postProblem = postProblem; + + if(postProblem || newPR || placement<=10){ + Paint2Win.AUDIO_MANAGER.playSound(((Paint2Win)Gdx.app.getApplicationListener()).assets.assetManager.get(SoundAssets.winSound)); + } + else { + Paint2Win.AUDIO_MANAGER.playSound(((Paint2Win)Gdx.app.getApplicationListener()).assets.assetManager.get(SoundAssets.failSound)); + } + } + + /** + * Helper function to center the highscore list + * @param bitmapFont used for displaying text + * @param value the time used + * @return + */ + private static final float getPositionOffset(BitmapFont bitmapFont, String value) { + GlyphLayout glyphLayout = new GlyphLayout(); + glyphLayout.setText(bitmapFont, value); + return (MENU_WIDTH - glyphLayout.width)/2 ; + } + + + /** + * Function for checking if one of the buttons have been pressed. + * What happens is that when the screen is touched it checks if the area pressed is + * inside the rectangle of one of the button, and fires the function assosiated with that button + * if that is the case. + */ + private void checkIfPressedButton() { + if(Gdx.input.justTouched()) { + Vector3 tmp = new Vector3(new Vector2(Gdx.input.getX(), Gdx.input.getY()), 0); + cam.unproject(tmp); + Rectangle mainMenuBounds = new Rectangle(mainMenuButtonXPosition, mainMenuButtonYPosition, mainMenuButton.getWidth(), mainMenuButton.getHeight()); + + if(mainMenuBounds.contains(tmp.x,tmp.y)) { + Paint2Win.AUDIO_MANAGER.stopSfx(); + toMainMenu(); + } + } + } + + /** + * Function for returning to the Main Menu + */ + private void toMainMenu(){ + gsm.set(new MainMenu(gsm)); + } + + /** + * Updates the variables before the render function is called + * @param dt + */ + @Override + public void update(float dt) { + checkIfPressedButton(); + } + + /** + * Draws the screen and objects + * @param sb + */ + @Override + public void render(SpriteBatch sb) { + Gdx.gl.glClearColor(0, 0, 0, 1); + Gdx.gl.glClear(GL20.GL_COLOR_BUFFER_BIT); + sb.setProjectionMatrix(cam.combined); + sb.begin(); + sb.draw(backgroundImage, 0,0, MENU_WIDTH, MENU_HEIGHT); + textRenderer.setColor(Color.OLIVE); + if(postProblem){ + textRenderer.draw(sb, "Connection issue...\nRound wasn't recorded\nTime used: "+TimerWatch.fancyString(this.timeUsed), getPositionOffset(textRenderer,"Connection issue\nRound wasn't recorded\nTime: "+TimerWatch.fancyString(this.timeUsed)), MENU_HEIGHT /1.5f); + } + else if(newPR){ + textRenderer.draw(sb, "New personal best!\nYou placed: "+placement+"\nTime: "+TimerWatch.fancyString(this.timeUsed), getPositionOffset(textRenderer,"New personal best!\nYou placed: "+placement+"\nTime: "+TimerWatch.fancyString(this.timeUsed)), MENU_HEIGHT /1.5f); + } + else{ + textRenderer.draw(sb, "You placed: "+placement+"\nTime: "+TimerWatch.fancyString(this.timeUsed), getPositionOffset(textRenderer,"You placed: "+placement+"\nTime: "+TimerWatch.fancyString(this.timeUsed)),MENU_HEIGHT /1.5f); + } + sb.draw(mainMenuButton, mainMenuButtonXPosition, mainMenuButtonYPosition); + sb.end(); + } + + /** + * Disposes the page when leaving it + */ + @Override + public void dispose() { + System.out.println("Disposed finishedGame"); + backgroundImage.dispose(); + mainMenuButton.dispose(); + textRenderer.dispose(); + } + + @Override + public void resize(int width, int height) { + viewport.update(width, height); + } +} diff --git a/core/src/com/tdt4240/paint2win/controller/states/Highscore.java b/core/src/com/tdt4240/paint2win/controller/states/Highscore.java new file mode 100644 index 0000000000000000000000000000000000000000..ea61fa57a10f18a7e43224fb37de97c329d6f203 --- /dev/null +++ b/core/src/com/tdt4240/paint2win/controller/states/Highscore.java @@ -0,0 +1,198 @@ +package com.tdt4240.paint2win.controller.states; + +import com.badlogic.gdx.Gdx; +import com.badlogic.gdx.graphics.Color; +import com.badlogic.gdx.graphics.GL20; +import com.badlogic.gdx.graphics.OrthographicCamera; +import com.badlogic.gdx.graphics.Texture; +import com.badlogic.gdx.graphics.g2d.BitmapFont; +import com.badlogic.gdx.graphics.g2d.GlyphLayout; +import com.badlogic.gdx.graphics.g2d.SpriteBatch; +import com.badlogic.gdx.graphics.g2d.freetype.FreeTypeFontGenerator; +import com.badlogic.gdx.math.Rectangle; +import com.badlogic.gdx.math.Vector2; +import com.badlogic.gdx.math.Vector3; +import com.badlogic.gdx.utils.viewport.StretchViewport; +import com.badlogic.gdx.utils.viewport.Viewport; +import com.tdt4240.paint2win.Paint2Win; +import com.tdt4240.paint2win.controller.managers.SoundAssets; +import com.tdt4240.paint2win.model.TimerWatch; +import com.tdt4240.paint2win.model.maps.AbstractMap; +import com.tdt4240.paint2win.networking.DataTransfer; +import com.tdt4240.paint2win.networking.Dto.HighScoreRow; + +import java.io.IOException; +import java.util.List; + +import static com.tdt4240.paint2win.Paint2Win.MENU_HEIGHT; +import static com.tdt4240.paint2win.Paint2Win.MENU_WIDTH; + +public class Highscore extends State { + private OrthographicCamera cam; + + private final Texture mainMenuButton; + private final int mainMenuButtonXPosition; + private final int mainMenuButtonYPosition; + + private final Texture rightButton; + private final int rightButtonXPosition; + private final int rightButtonYPosition; + + private final Texture leftButton; + private final int leftButtonXPosition; + private final int leftButtonYPosition; + private final Viewport viewport; + + private final BitmapFont bitmapFont; + private AbstractMap.valid_maps mapType; + + private List<HighScoreRow> highscores; + + private static final float getPositionOffset(BitmapFont bitmapFont, String value) { + GlyphLayout glyphLayout = new GlyphLayout(); + glyphLayout.setText(bitmapFont, value); + return (MENU_WIDTH - glyphLayout.width)/2 ; + } + + private static final void renderHighScoreList(SpriteBatch sb, BitmapFont bitmapFont, List<HighScoreRow> highScoreRowList, AbstractMap.valid_maps mapType){ + String tmpString = "Highscore: "+mapType.toString()+"\n"; + int position = 1; + for (HighScoreRow row : highScoreRowList) { + if(position!=10){ + tmpString += position + ": Player: " + row.getPlayerName() + " Time: " + TimerWatch.fancyString(row.getTime())+"\n"; + } + else{ + //Just to make it pretty + tmpString += position + ": Player: " + row.getPlayerName() + " Time: " + TimerWatch.fancyString(row.getTime())+"\n"; + } + position++; + } + bitmapFont.draw(sb, tmpString,getPositionOffset(bitmapFont,tmpString),MENU_HEIGHT); + } + + private static final List<HighScoreRow> fetchHighScoreList(AbstractMap.valid_maps mapType){ + try{ + return DataTransfer.getHighscores(mapType); + } + catch (IOException e){ + return null; + } + } + + /** + * Constructor, includes all logic that only has to get rendered once. + * The Join Game let's the user join an already existing lobby + * @param gsm + */ + public Highscore(GameStateManager gsm) { + super(gsm); + cam = new OrthographicCamera(); + cam.setToOrtho(false, MENU_WIDTH, MENU_HEIGHT); + viewport = new StretchViewport(MENU_WIDTH, MENU_HEIGHT, cam); + + Paint2Win.AUDIO_MANAGER.playMusic(((Paint2Win)Gdx.app.getApplicationListener()).assets.assetManager.get(SoundAssets.menu_soundtrack_2)); + + mainMenuButton = new Texture("main_menu.png"); + mainMenuButtonXPosition = MENU_WIDTH /2 - mainMenuButton.getWidth()/2; + mainMenuButtonYPosition = MENU_HEIGHT /9; + + rightButton = new Texture("Right_Arrow.png"); + rightButtonXPosition = MENU_WIDTH - MENU_WIDTH /10 - rightButton.getWidth()/2; + rightButtonYPosition = MENU_HEIGHT /2; + + leftButton = new Texture("Left_Arrow.png"); + leftButtonXPosition = MENU_WIDTH /10 - rightButton.getWidth()/2; + leftButtonYPosition = MENU_HEIGHT /2; + + FreeTypeFontGenerator generator = new FreeTypeFontGenerator(Gdx.files.internal("fonts/Roboto/Roboto-Bold.ttf")); + FreeTypeFontGenerator.FreeTypeFontParameter parameter = new FreeTypeFontGenerator.FreeTypeFontParameter(); + parameter.size = 30; + this.bitmapFont = generator.generateFont(parameter); // font size 30 pixels + generator.dispose(); // Dispose to avoid memory leaks! + bitmapFont.setColor(Color.OLIVE); + + this.mapType = AbstractMap.valid_maps.URBAN; + this.highscores =fetchHighScoreList(mapType); + } + + /** + * Function for returning to the Main Menu + */ + private void toMainMenu(){ + gsm.set(new MainMenu(gsm)); + } + + /** + * Function for checking if one of the buttons have been pressed. + * What happens is that when the screen is touched it checks if the area pressed is + * inside the rectangle of one of the button, and fires the function assosiated with that button + * if that is the case. + */ + private void checkIfPressedButton() { + if(Gdx.input.justTouched()) { + Vector3 tmp = new Vector3(new Vector2(Gdx.input.getX(), Gdx.input.getY()), 0); + cam.unproject(tmp); + Rectangle mainMenuBounds = new Rectangle(mainMenuButtonXPosition, mainMenuButtonYPosition, mainMenuButton.getWidth(), mainMenuButton.getHeight()); + Rectangle rightBounds = new Rectangle(rightButtonXPosition, rightButtonYPosition, rightButton.getWidth(), rightButton.getHeight()); + Rectangle leftBounds = new Rectangle(leftButtonXPosition, leftButtonYPosition,leftButton.getWidth(), leftButton.getHeight()); + + if(mainMenuBounds.contains(tmp.x,tmp.y)) { toMainMenu(); } + else if(rightBounds.contains(tmp.x,tmp.y)) { + this.mapType = AbstractMap.valid_maps.DESERT; + this.highscores = fetchHighScoreList(mapType); + } + else if(leftBounds.contains(tmp.x,tmp.y)) { + this.mapType = AbstractMap.valid_maps.URBAN; + this.highscores = fetchHighScoreList(mapType); } + } + } + + /** + * Updates the current state of the screen. + * Calls function to see if button was pressed + * @param dt + */ + @Override + public void update(float dt) { + checkIfPressedButton(); + } + + /** + * Rerenders the screen with updated values + * @param sb + */ + @Override + public void render(SpriteBatch sb) { + Gdx.gl.glClearColor(1, 1, 1, 1); + Gdx.gl.glClear(GL20.GL_COLOR_BUFFER_BIT); + sb.setProjectionMatrix(cam.combined); + sb.begin(); + if(highscores != null){ + renderHighScoreList(sb,bitmapFont,highscores,mapType); + } + else{ + bitmapFont.draw(sb, "Error with fetching of scoreboard",getPositionOffset(bitmapFont, "Error with fetching scoreboard"), MENU_HEIGHT /1.5f); + } + sb.draw(mainMenuButton, mainMenuButtonXPosition, mainMenuButtonYPosition); + sb.draw(rightButton, rightButtonXPosition, rightButtonYPosition); + sb.draw(leftButton, leftButtonXPosition, leftButtonYPosition); + sb.end(); + } + + /** + * Disposes the page when leaving it + */ + @Override + public void dispose() { + System.out.println("Disposed Join Game"); + mainMenuButton.dispose(); + rightButton.dispose(); + leftButton.dispose(); + bitmapFont.dispose(); + } + + @Override + public void resize(int width, int height) { + viewport.update(width, height); + } +} diff --git a/core/src/com/tdt4240/paint2win/controller/states/JoinGame.java b/core/src/com/tdt4240/paint2win/controller/states/JoinGame.java deleted file mode 100644 index 74818b6b2f7fea4eac3132bd0143ec8f86549d6c..0000000000000000000000000000000000000000 --- a/core/src/com/tdt4240/paint2win/controller/states/JoinGame.java +++ /dev/null @@ -1,102 +0,0 @@ -package com.tdt4240.paint2win.controller.states; - -import com.badlogic.gdx.Gdx; -import com.badlogic.gdx.audio.Music; -import com.badlogic.gdx.graphics.GL20; -import com.badlogic.gdx.graphics.OrthographicCamera; -import com.badlogic.gdx.graphics.Texture; -import com.badlogic.gdx.graphics.g2d.SpriteBatch; -import com.badlogic.gdx.graphics.glutils.ShapeRenderer; -import com.badlogic.gdx.math.Rectangle; -import com.badlogic.gdx.math.Vector2; -import com.badlogic.gdx.math.Vector3; -import com.tdt4240.paint2win.Paint2Win; - -import static com.badlogic.gdx.Gdx.audio; -import static com.tdt4240.paint2win.Paint2Win.MENU_HEIGHT; -import static com.tdt4240.paint2win.Paint2Win.MENU_WIDTH; - -public class JoinGame extends State { - private OrthographicCamera cam; - private final Texture colorsImage; - private Music music; - private Texture header; - - private final Texture mainMenuButton; - private final int mainMenuButtonXPosition; - private final int mainMenuButtonYPosition; - - private final Texture toLobbyButton; - private final int toLobbyButtonXPosition; - private final int toLobbyButtonYPosition; - - public JoinGame(GameStateManager gsm) { - super(gsm); - cam = new OrthographicCamera(); - cam.setToOrtho(false, MENU_WIDTH, MENU_HEIGHT); - colorsImage = new Texture("colors.jpg"); - header = new Texture("join_game_header.png"); - - music = audio.newMusic(Gdx.files.internal("menu_soundtrack_2.mp3")); - music.setLooping(true); - music.setVolume(Paint2Win.getMusic_volume()); - music.play(); - - mainMenuButton = new Texture("main_menu.png"); - mainMenuButtonXPosition = MENU_WIDTH/4 - mainMenuButton.getWidth()/2; - mainMenuButtonYPosition = MENU_HEIGHT/4; - - toLobbyButton = new Texture("start.png"); - toLobbyButtonXPosition = 3*MENU_WIDTH/4 - toLobbyButton.getWidth()/2; - toLobbyButtonYPosition = MENU_HEIGHT/4; - } - - private void toMainMenu(){ - gsm.set(new MainMenu(gsm)); - } - - private void toLobby(String lobby){ - gsm.set(new PlayState(gsm)); - } - - private void checkIfPressedButton() { - if(Gdx.input.justTouched()) { - Vector3 tmp = new Vector3(new Vector2(Gdx.input.getX(), Gdx.input.getY()), 0); - cam.unproject(tmp); - Rectangle mainMenuBounds = new Rectangle(mainMenuButtonXPosition, mainMenuButtonYPosition, mainMenuButton.getWidth(), mainMenuButton.getHeight()); - Rectangle toLobbyBounds = new Rectangle(toLobbyButtonXPosition, toLobbyButtonYPosition, toLobbyButton.getWidth(), toLobbyButton.getHeight()); - - if(mainMenuBounds.contains(tmp.x,tmp.y)) { toMainMenu(); } - else if(toLobbyBounds.contains(tmp.x,tmp.y)) { toLobby("ID"); } - } - } - - - @Override - public void update(float dt) { - checkIfPressedButton(); - } - - @Override - public void render(SpriteBatch sb) { - Gdx.gl.glClearColor(0, 0, 0, 1); - Gdx.gl.glClear(GL20.GL_COLOR_BUFFER_BIT); - sb.setProjectionMatrix(cam.combined); - sb.begin(); - sb.draw(colorsImage, 0,0, MENU_WIDTH, MENU_HEIGHT); - sb.draw(header, MENU_WIDTH/2 - header.getWidth()/2,2*MENU_HEIGHT/4); - sb.draw(mainMenuButton, mainMenuButtonXPosition, mainMenuButtonYPosition); - sb.draw(toLobbyButton, toLobbyButtonXPosition, toLobbyButtonYPosition); - sb.end(); - } - - @Override - public void dispose() { - System.out.println("Disposed Join Game"); - music.dispose(); - mainMenuButton.dispose(); - toLobbyButton.dispose(); - header.dispose(); - colorsImage.dispose(); - } -} diff --git a/core/src/com/tdt4240/paint2win/controller/states/Lobby.java b/core/src/com/tdt4240/paint2win/controller/states/Lobby.java deleted file mode 100644 index 57c09dcd71d49f3627967e20c814548f03a66892..0000000000000000000000000000000000000000 --- a/core/src/com/tdt4240/paint2win/controller/states/Lobby.java +++ /dev/null @@ -1,37 +0,0 @@ -package com.tdt4240.paint2win.controller.states; - -import com.badlogic.gdx.graphics.g2d.SpriteBatch; -import com.badlogic.gdx.graphics.glutils.ShapeRenderer; -import com.tdt4240.paint2win.model.Player; - -import java.util.List; - -public class Lobby extends State { - - private boolean ready; - private List<Player> players; - - public Lobby(GameStateManager gsm) { - super(gsm); - } - - - private void toggleReady(){} - private void kickPlayer(String playerID){} - private void toMainMenu(){} - - @Override - public void update(float dt) { - - } - - @Override - public void render(SpriteBatch sb) { - - } - - @Override - public void dispose() { - - } -} diff --git a/core/src/com/tdt4240/paint2win/controller/states/MainMenu.java b/core/src/com/tdt4240/paint2win/controller/states/MainMenu.java index 64eaa433b7bd34b046c953cfd9f3084b04a5ad86..2c40b47975525e246e33f8e1cfdc5d36dab68874 100644 --- a/core/src/com/tdt4240/paint2win/controller/states/MainMenu.java +++ b/core/src/com/tdt4240/paint2win/controller/states/MainMenu.java @@ -1,8 +1,6 @@ package com.tdt4240.paint2win.controller.states; import com.badlogic.gdx.Gdx; -import com.badlogic.gdx.Screen; -import com.badlogic.gdx.audio.Music; import com.badlogic.gdx.graphics.GL20; import com.badlogic.gdx.graphics.OrthographicCamera; import com.badlogic.gdx.graphics.Texture; @@ -10,19 +8,11 @@ import com.badlogic.gdx.graphics.g2d.SpriteBatch; import com.badlogic.gdx.math.Rectangle; import com.badlogic.gdx.math.Vector2; import com.badlogic.gdx.math.Vector3; +import com.badlogic.gdx.utils.viewport.StretchViewport; +import com.badlogic.gdx.utils.viewport.Viewport; import com.tdt4240.paint2win.Paint2Win; -import com.badlogic.gdx.graphics.g2d.TextureRegion; -import com.badlogic.gdx.graphics.glutils.ShapeRenderer; -import com.badlogic.gdx.scenes.scene2d.Event; -import com.badlogic.gdx.scenes.scene2d.EventListener; -import com.badlogic.gdx.scenes.scene2d.Stage; -import com.badlogic.gdx.scenes.scene2d.ui.ImageButton; -import com.badlogic.gdx.scenes.scene2d.utils.TextureRegionDrawable; -import com.badlogic.gdx.utils.viewport.ScreenViewport; - -import static com.badlogic.gdx.Gdx.audio; -import static com.tdt4240.paint2win.Paint2Win.MAP_HEIGHT; -import static com.tdt4240.paint2win.Paint2Win.MAP_WIDTH; +import com.tdt4240.paint2win.controller.managers.SoundAssets; + import static com.tdt4240.paint2win.Paint2Win.MENU_HEIGHT; import static com.tdt4240.paint2win.Paint2Win.MENU_WIDTH; @@ -30,11 +20,10 @@ public class MainMenu extends State { private OrthographicCamera cam; private final Texture backgroundImage; private final Texture logo; - private Music music; - private final Texture joinGameButton; - private final int joinGameButtonXPosition; - private final int joinGameButtonYPosition; + private final Texture highscoreButton; + private final int highscoreButtonXPosition; + private final int highscoreButtonYPosition; private final Texture createGameButton; private final int createGameButtonXPosition; private final int createGameButtonYPosition; @@ -44,6 +33,7 @@ public class MainMenu extends State { private final Texture tutorialButton; private final int tutorialButtonXPosition; private final int tutorialButtonYPosition; + private final Viewport viewport; /** * Initiates Main Menu. Sets camera position. Also logic for placing the different buttons @@ -53,66 +43,91 @@ public class MainMenu extends State { super(gsm); cam = new OrthographicCamera(); cam.setToOrtho(false, MENU_WIDTH, MENU_HEIGHT); + viewport = new StretchViewport(MENU_WIDTH, MENU_HEIGHT, cam); backgroundImage = new Texture("paintball_players.png"); logo = new Texture("paint2win.png"); - music = audio.newMusic(Gdx.files.internal("menu_soundtrack.mp3")); - music.setLooping(true); - music.setVolume(Paint2Win.getMusic_volume()); - music.play(); + Paint2Win.AUDIO_MANAGER.playMusic(((Paint2Win)Gdx.app.getApplicationListener()).assets.assetManager.get(SoundAssets.menu_soundtrack_1)); - joinGameButton = new Texture("join_game.png"); - joinGameButtonXPosition = MENU_WIDTH/4 - joinGameButton.getWidth()/2; - joinGameButtonYPosition = MENU_HEIGHT/4; + highscoreButton = new Texture("highscore.png"); + highscoreButtonXPosition = MENU_WIDTH /4 - highscoreButton.getWidth()/2; + highscoreButtonYPosition = MENU_HEIGHT /4; createGameButton = new Texture("create_game.png"); - createGameButtonXPosition = 3*MENU_WIDTH/4 - createGameButton.getWidth()/2; - createGameButtonYPosition = MENU_HEIGHT/4; + createGameButtonXPosition = 3* MENU_WIDTH /4 - createGameButton.getWidth()/2; + createGameButtonYPosition = MENU_HEIGHT /4; settingsButton = new Texture("settings.png"); - settingsButtonXPosition = MENU_WIDTH/4 - settingsButton.getWidth()/2; - settingsButtonYPosition = 2*MENU_HEIGHT/4; + settingsButtonXPosition = MENU_WIDTH /4 - settingsButton.getWidth()/2; + settingsButtonYPosition = 2* MENU_HEIGHT /4; tutorialButton = new Texture("tutorial.png"); - tutorialButtonXPosition = 3*MENU_WIDTH/4 - tutorialButton.getWidth()/2; - tutorialButtonYPosition = 2*MENU_HEIGHT/4; + tutorialButtonXPosition = 3* MENU_WIDTH /4 - tutorialButton.getWidth()/2; + tutorialButtonYPosition = 2* MENU_HEIGHT /4; } - private void toJoinGame (){ - gsm.set(new JoinGame(gsm)); + /** + * Sends the user to the Join game page + */ + private void toHighScore (){ + gsm.set(new Highscore(gsm)); } + /** + * Sends the user to the Create game page + */ private void toCreateGame (){ gsm.set(new CreateGame(gsm)); } + /** + * Sends the user to the Settings page + */ private void toSettings (){ gsm.set(new Settings(gsm)); } + /** + * Sends the user to the Tutorial page + */ private void toTutorial (){ gsm.set(new Tutorial(gsm)); } + /** + * Function for checking if one of the buttons have been pressed. + * What happens is that when the screen is touched it checks if the area pressed is + * inside the rectangle of one of the button, and fires the function assosiated with that button + * if that is the case. + */ private void checkIfPressedButton() { if(Gdx.input.justTouched()) { Vector3 tmp = new Vector3(new Vector2(Gdx.input.getX(), Gdx.input.getY()), 0); cam.unproject(tmp); - Rectangle joinGameBounds = new Rectangle(joinGameButtonXPosition, joinGameButtonYPosition, joinGameButton.getWidth(), joinGameButton.getHeight()); + Rectangle joinGameBounds = new Rectangle(highscoreButtonXPosition, highscoreButtonYPosition, highscoreButton.getWidth(), highscoreButton.getHeight()); Rectangle createGameBounds = new Rectangle(createGameButtonXPosition, createGameButtonYPosition, createGameButton.getWidth(), createGameButton.getHeight()); Rectangle settingsBounds = new Rectangle(settingsButtonXPosition, settingsButtonYPosition, settingsButton.getWidth(), settingsButton.getHeight()); Rectangle tutorialBounds = new Rectangle(tutorialButtonXPosition, tutorialButtonYPosition, tutorialButton.getWidth(), tutorialButton.getHeight()); - if(joinGameBounds.contains(tmp.x,tmp.y)) { toJoinGame(); } + if(joinGameBounds.contains(tmp.x,tmp.y)) { toHighScore(); } else if(createGameBounds.contains(tmp.x,tmp.y)) { toCreateGame(); } else if(settingsBounds.contains(tmp.x,tmp.y)) { toSettings(); } else if(tutorialBounds.contains(tmp.x,tmp.y)) { toTutorial(); } } } + /** + * Updates the current state of the screen. + * Calls function to see if button was pressed + * @param dt + */ @Override public void update(float dt) { checkIfPressedButton(); } + /** + * Rerenders the screen with updated values + * @param sb + */ @Override public void render(SpriteBatch sb) { Gdx.gl.glClearColor(0, 0, 0, 1); @@ -120,23 +135,30 @@ public class MainMenu extends State { sb.setProjectionMatrix(cam.combined); sb.begin(); sb.draw(backgroundImage, 0,0, MENU_WIDTH, MENU_HEIGHT); - sb.draw(logo, MENU_WIDTH/2 - logo.getWidth()/2,3*MENU_HEIGHT/4); - sb.draw(joinGameButton, joinGameButtonXPosition, joinGameButtonYPosition); + sb.draw(logo, MENU_WIDTH /2 - logo.getWidth()/2,3* MENU_HEIGHT /4); + sb.draw(highscoreButton, highscoreButtonXPosition, highscoreButtonYPosition); sb.draw(createGameButton, createGameButtonXPosition, createGameButtonYPosition); sb.draw(settingsButton, settingsButtonXPosition, settingsButtonYPosition); sb.draw(tutorialButton, tutorialButtonXPosition, tutorialButtonYPosition); sb.end(); } + /** + * Disposes the page when leaving it + */ @Override public void dispose() { System.out.println("Disposed Main Menu"); - joinGameButton.dispose(); + highscoreButton.dispose(); createGameButton.dispose(); settingsButton.dispose(); tutorialButton.dispose(); logo.dispose(); backgroundImage.dispose(); - music.dispose(); + } + + @Override + public void resize(int width, int height) { + viewport.update(width, height); } } diff --git a/core/src/com/tdt4240/paint2win/controller/states/PassingData.java b/core/src/com/tdt4240/paint2win/controller/states/PassingData.java new file mode 100644 index 0000000000000000000000000000000000000000..b6736444a17dab0f69d4d78f487e04bf01e6baf0 --- /dev/null +++ b/core/src/com/tdt4240/paint2win/controller/states/PassingData.java @@ -0,0 +1,102 @@ +package com.tdt4240.paint2win.controller.states; + +import com.badlogic.gdx.Gdx; +import com.badlogic.gdx.graphics.GL20; +import com.badlogic.gdx.graphics.OrthographicCamera; +import com.badlogic.gdx.graphics.Texture; +import com.badlogic.gdx.graphics.g2d.SpriteBatch; +import com.badlogic.gdx.math.Rectangle; +import com.badlogic.gdx.math.Vector2; +import com.badlogic.gdx.math.Vector3; +import com.badlogic.gdx.utils.Array; +import com.badlogic.gdx.utils.viewport.StretchViewport; +import com.badlogic.gdx.utils.viewport.Viewport; +import com.tdt4240.paint2win.Paint2Win; +import com.tdt4240.paint2win.controller.managers.SoundAssets; +import com.tdt4240.paint2win.model.maps.AbstractMap; +import com.tdt4240.paint2win.networking.DataTransfer; +import com.tdt4240.paint2win.networking.Dto.Placement; + +import java.io.IOException; + +import static com.tdt4240.paint2win.Paint2Win.MENU_HEIGHT; +import static com.tdt4240.paint2win.Paint2Win.MENU_WIDTH; + +public class PassingData extends State { + + private Texture background; + private OrthographicCamera cam; + private Viewport viewport; + private String username; + private int time; + private AbstractMap mapType; + private boolean firstRun; + private boolean secondRun; + + public PassingData(GameStateManager gsm, String username, int time, AbstractMap mapType) { + super(gsm); + this.username = username; + this.time = time; + this.mapType = mapType; + cam = new OrthographicCamera(); + cam.setToOrtho(false, MENU_WIDTH, MENU_HEIGHT); + viewport = new StretchViewport(MENU_WIDTH, MENU_HEIGHT, cam); + Paint2Win.AUDIO_MANAGER.playMusic(((Paint2Win)Gdx.app.getApplicationListener()).assets.assetManager.get(SoundAssets.menu_soundtrack_2)); + this.background = new Texture("FetchData.png"); + this.firstRun = true; + this.secondRun = false; + } + + /** + * Updates the variables before the render function is called + * @param dt + */ + @Override + public void update(float dt) { + if(firstRun){ + //Used for drawing backround + firstRun=false; + secondRun=true; + } + else if(secondRun){ + //Used for making call to database + secondRun = false; + try{ + Placement placement = DataTransfer.SendTimeUsed(username,time,mapType); + gsm.set(new FinishedGame(gsm,false,placement.getPlacement(), placement.getNewPr(), time)); + } + catch (IOException e) { + //Database didn't record the placement + gsm.set(new FinishedGame(gsm,true, -1,false,time)); + } + } + } + + /** + * Draws the screen and objects + * @param sb + */ + @Override + public void render(SpriteBatch sb) { + Gdx.gl.glClearColor(0, 0, 0, 1); + Gdx.gl.glClear(GL20.GL_COLOR_BUFFER_BIT); + sb.setProjectionMatrix(cam.combined); + sb.begin(); + sb.draw(background, 0,0, MENU_WIDTH, MENU_HEIGHT); + sb.end(); + } + + /** + * Disposes the page when leaving it + */ + @Override + public void dispose() { + System.out.println("Disposed Tutorial"); + background.dispose(); + } + + @Override + public void resize(int width, int height) { + viewport.update(width, height); + } +} diff --git a/core/src/com/tdt4240/paint2win/controller/states/PlayState.java b/core/src/com/tdt4240/paint2win/controller/states/PlayState.java index 4a59441eaaa360cd92044e93b953f392faca8509..7ce4c3ecebf4a322a35e34ff8d9f6b89d1dff912 100644 --- a/core/src/com/tdt4240/paint2win/controller/states/PlayState.java +++ b/core/src/com/tdt4240/paint2win/controller/states/PlayState.java @@ -1,98 +1,115 @@ package com.tdt4240.paint2win.controller.states; import com.badlogic.gdx.Gdx; -import com.badlogic.gdx.audio.Music; import com.badlogic.gdx.graphics.Color; import com.badlogic.gdx.graphics.GL20; import com.badlogic.gdx.graphics.g2d.SpriteBatch; +import com.badlogic.gdx.graphics.g2d.freetype.FreeTypeFontGenerator; +import com.badlogic.gdx.math.Vector2; import com.badlogic.gdx.scenes.scene2d.Stage; -import com.badlogic.gdx.utils.viewport.FillViewport; +import com.badlogic.gdx.utils.viewport.StretchViewport; import com.badlogic.gdx.utils.viewport.Viewport; import com.tdt4240.paint2win.Paint2Win; import com.tdt4240.paint2win.container.BulletsContainer; -import com.tdt4240.paint2win.container.ObstacleContainer; import com.tdt4240.paint2win.container.PlayersContainer; import com.tdt4240.paint2win.controller.controls.DualJoysticks; import com.tdt4240.paint2win.controller.managers.Collider; import com.tdt4240.paint2win.controller.managers.Respawner; +import com.tdt4240.paint2win.controller.managers.SoundAssets; import com.tdt4240.paint2win.model.Bullet; import com.tdt4240.paint2win.model.GameMap; +import com.tdt4240.paint2win.model.Target; +import com.tdt4240.paint2win.model.TimerWatch; import com.tdt4240.paint2win.model.maps.AbstractMap; import com.tdt4240.paint2win.model.Obstacle; import com.tdt4240.paint2win.model.Player; import com.tdt4240.paint2win.model.Scoreboard; import com.tdt4240.paint2win.model.maps.desert_map; +import com.tdt4240.paint2win.model.maps.urban_map; +import com.tdt4240.paint2win.networking.DataTransfer; +import com.tdt4240.paint2win.networking.Dto.Placement; import com.tdt4240.paint2win.view.ContainerRenderer; import com.tdt4240.paint2win.view.PlayerCamera; import com.tdt4240.paint2win.view.PlayerRenderer; import com.tdt4240.paint2win.view.VisibleRenderer; import com.badlogic.gdx.graphics.g2d.BitmapFont; -import static com.badlogic.gdx.Gdx.audio; +import java.io.IOException; + + import static com.tdt4240.paint2win.Paint2Win.MAP_WIDTH; import static com.tdt4240.paint2win.Paint2Win.MAP_HEIGHT; public class PlayState extends State { - private Viewport viewport; - private GameMap gameMap; - private PlayersContainer playersContainer; - private BulletsContainer bulletsContainer; - private ObstacleContainer obstacleContainer; - private Respawner respawner; - private Collider collider; - private ContainerRenderer<Player> playersRenderer; - private ContainerRenderer<Bullet> bulletsRenderer; - private ContainerRenderer<Obstacle> obstacleRenderer; - private PlayerCamera playerCamera; - private Player mainplayer; - private Stage stage; - private DualJoysticks joysticks; - private Music music; - private AbstractMap map1; - private Scoreboard scoreboard; - private BitmapFont textrenderer; - /** - * Constructor, includes all logic that only has to get rendered once - private Scoreboard scoreboard; - private BitmapFont textrenderer; + + private final Viewport viewport; + private final GameMap gameMap; + private final PlayersContainer playersContainer; + private final BulletsContainer bulletsContainer; + private final Respawner respawner; + private final Collider collider; + private final ContainerRenderer<Player> playersRenderer; + private final ContainerRenderer<Bullet> bulletsRenderer; + private final ContainerRenderer<Obstacle> obstacleRenderer; + private final PlayerCamera playerCamera; + private final Player mainplayer; + private final Stage stage; + private final DualJoysticks joysticks; + private AbstractMap map; + private final Scoreboard scoreboard; + private final BitmapFont bitmapFont; + private final Target target; + private final TimerWatch timerWatch; + private final String username; /** * Constructor, includes all logic that only has to get rendered once - * * @param gsm */ - public PlayState(GameStateManager gsm) { + public PlayState(GameStateManager gsm, AbstractMap.valid_maps mapType, String username, Color playerColor) { super(gsm); - viewport = new FillViewport(MAP_WIDTH, MAP_HEIGHT); + this.username = username; + playerCamera = new PlayerCamera(); + viewport = new StretchViewport(MAP_WIDTH, MAP_HEIGHT); gameMap = new GameMap(MAP_WIDTH, MAP_HEIGHT); - obstacleContainer = new ObstacleContainer(); - map1 = new desert_map(obstacleContainer); - mainplayer = new Player(Color.CYAN,obstacleContainer); - Player player2 = new Player(Color.RED,obstacleContainer); + bulletsContainer = new BulletsContainer(); playersContainer = new PlayersContainer(); + chooseMap(mapType); + mainplayer = new Player(playerColor, map.getObstacleContainer()); playersContainer.add(mainplayer); - playersContainer.add(player2); - bulletsContainer = new BulletsContainer(); - respawner = new Respawner(playersContainer,obstacleContainer); - collider = new Collider(playersContainer, bulletsContainer,obstacleContainer); + respawner = new Respawner(playersContainer, map.getObstacleContainer()); + stage = new Stage(viewport); + scoreboard = new Scoreboard(Paint2Win.TARGETS_TO_HIT); + timerWatch = new TimerWatch(); + target = new Target(map.getObstacleContainer(), scoreboard); + collider = new Collider(playersContainer, bulletsContainer, map.getObstacleContainer(), target); playersRenderer = new ContainerRenderer<Player>(playersContainer, PlayerRenderer::new); bulletsRenderer = new ContainerRenderer<Bullet>(bulletsContainer, VisibleRenderer::new); - obstacleRenderer = new ContainerRenderer<Obstacle>(obstacleContainer, VisibleRenderer::new); - playerCamera = new PlayerCamera(); - stage = new Stage(viewport); + obstacleRenderer = new ContainerRenderer<Obstacle>(map.getObstacleContainer(), VisibleRenderer::new); joysticks = new DualJoysticks(stage); this.joysticks.addObserver(mainplayer); - //this.joysticks.addObserver(player2); - scoreboard = new Scoreboard(); - mainplayer.addObserver(scoreboard); - player2.addObserver(scoreboard); - this.textrenderer = new BitmapFont(); - textrenderer.setColor(Color.WHITE); - textrenderer.getData().setScale(8); - music = audio.newMusic(Gdx.files.internal("run_free.mp3")); - music.setLooping(true); - music.setVolume(Paint2Win.getMusic_volume()); - music.play(); + + FreeTypeFontGenerator generator = new FreeTypeFontGenerator(Gdx.files.internal("fonts/Roboto/Roboto-Medium.ttf")); + FreeTypeFontGenerator.FreeTypeFontParameter parameter = new FreeTypeFontGenerator.FreeTypeFontParameter(); + parameter.size = 120; + this.bitmapFont = generator.generateFont(parameter); // font size 120 pixels + generator.dispose(); // Dispose to avoid memory leaks! + this.bitmapFont.setColor(mainplayer.getColor()); + Paint2Win.AUDIO_MANAGER.playMusic(((Paint2Win)Gdx.app.getApplicationListener()).assets.assetManager.get(SoundAssets.run_free)); + timerWatch.start(); + } + + /** + * Updates the local variable map based on the map that was clicked + * @param chosenMap value of the clicked map + */ + private void chooseMap(AbstractMap.valid_maps chosenMap) { + if (chosenMap == AbstractMap.valid_maps.DESERT) { + map = new desert_map(); + } + else if (chosenMap == AbstractMap.valid_maps.URBAN) { + map = new urban_map(); + } } /** @@ -107,8 +124,8 @@ public class PlayState extends State { playersContainer.streamShooters().forEach(gameMap::ensurePlacementWithinBounds); playersContainer.obtainAndStreamBullets().forEach(bulletsContainer::add); bulletsContainer.update(delta); - obstacleContainer.update(delta); - obstacleContainer.stream().forEach(gameMap::ensurePlacementWithinBounds); + map.getObstacleContainer().update(delta); + map.getObstacleContainer().stream().forEach(gameMap::ensurePlacementWithinBounds); } /** @@ -119,31 +136,47 @@ public class PlayState extends State { public void render(SpriteBatch sb) { Gdx.gl.glClearColor(0, 0, 0, 1); Gdx.gl.glClear(GL20.GL_COLOR_BUFFER_BIT); - - viewport.apply(); + //Drawing with the passed common sprite batch. Used to draw map, player and bullets sb.begin(); - sb.setProjectionMatrix(playerCamera.updatedCamera(mainplayer.getPos().x,mainplayer.getPos().y).combined); + sb.setProjectionMatrix(playerCamera.updatedCamera(mainplayer.getPos().x, mainplayer.getPos().y).combined); sb.setColor(Color.WHITE); - sb.draw(map1.getBackGround(), 0,0,MAP_WIDTH,MAP_HEIGHT); + sb.draw(map.getBackGround(), 0,0,MAP_WIDTH,MAP_HEIGHT); playersRenderer.render(sb); bulletsRenderer.render(sb); obstacleRenderer.render(sb); + target.draw(sb); sb.end(); joysticks.render(); - scoreboard.setPosition(0,stage.getHeight()-10); - scoreboard.render(stage.getBatch(), textrenderer); + stage.getBatch().begin(); + scoreboard.render(new Vector2 (0,stage.getHeight()),stage.getBatch(), bitmapFont); + timerWatch.render(new Vector2(stage.getWidth()/1.5f,stage.getHeight()), stage.getBatch(), bitmapFont); + stage.getBatch().end(); + + if(scoreboard.isGoalReached()){ + gsm.set(new PassingData(gsm,username,timerWatch.getElapsedTime(),this.map)); + } + } @Override public void resize(int width, int height) { - viewport.update(width, height, true); + viewport.update(width, height, false); + playerCamera.resize(width, height); + stage.setViewport(viewport); } - //TODO: Find out what more that could be disposed to improve performance + /** + * Disposes the page when leaving it + */ @Override public void dispose() { System.out.println("Disposed Play State"); - music.dispose(); - map1.dispose(); + stage.dispose(); + map.dispose(); + bitmapFont.dispose(); + bulletsContainer.dispose(); + playersContainer.dispose(); + target.dispose(); } + } \ No newline at end of file diff --git a/core/src/com/tdt4240/paint2win/controller/states/Settings.java b/core/src/com/tdt4240/paint2win/controller/states/Settings.java index 1679eed2913ccc9c21028627227662cb40b7f2ea..10a7d825045c1791b1423976fbb16a4ad25092c2 100644 --- a/core/src/com/tdt4240/paint2win/controller/states/Settings.java +++ b/core/src/com/tdt4240/paint2win/controller/states/Settings.java @@ -1,14 +1,11 @@ package com.tdt4240.paint2win.controller.states; import com.badlogic.gdx.Gdx; -import com.badlogic.gdx.audio.Music; import com.badlogic.gdx.graphics.Color; import com.badlogic.gdx.graphics.GL20; import com.badlogic.gdx.graphics.OrthographicCamera; import com.badlogic.gdx.graphics.Texture; import com.badlogic.gdx.graphics.g2d.SpriteBatch; -import com.badlogic.gdx.graphics.glutils.ShapeRenderer; -import com.badlogic.gdx.math.MathUtils; import com.badlogic.gdx.math.Rectangle; import com.badlogic.gdx.math.Vector2; import com.badlogic.gdx.math.Vector3; @@ -20,80 +17,75 @@ import com.badlogic.gdx.scenes.scene2d.ui.Slider; import com.badlogic.gdx.scenes.scene2d.ui.Table; import com.badlogic.gdx.scenes.scene2d.utils.ChangeListener; import com.badlogic.gdx.utils.Align; -import com.badlogic.gdx.utils.viewport.ExtendViewport; -import com.badlogic.gdx.utils.viewport.FillViewport; -import com.badlogic.gdx.utils.viewport.FitViewport; +import com.badlogic.gdx.utils.viewport.StretchViewport; import com.badlogic.gdx.utils.viewport.Viewport; import com.tdt4240.paint2win.Paint2Win; -import com.tdt4240.paint2win.model.Player; +import com.tdt4240.paint2win.controller.managers.SoundAssets; import java.math.BigDecimal; import java.math.RoundingMode; -import java.util.List; -import static com.badlogic.gdx.Gdx.audio; -import static com.tdt4240.paint2win.Paint2Win.MAP_HEIGHT; -import static com.tdt4240.paint2win.Paint2Win.MAP_WIDTH; import static com.tdt4240.paint2win.Paint2Win.MENU_HEIGHT; import static com.tdt4240.paint2win.Paint2Win.MENU_WIDTH; public class Settings extends State { - private OrthographicCamera cam; - private Music music; - private Viewport viewport; + private final OrthographicCamera cam; + private final Viewport viewport; + private final Texture header; private final Texture colorsImage; - private final Texture mainMenuButton; private final int mainMenuButtonXPosition; private final int mainMenuButtonYPosition; private final Slider musicSlider; private final Slider sfxSlider; - private Stage stage; + private final Stage stage; + /** + * Constructor, includes all logic that only has to get rendered once. + * The settings page let's the user control music volume and sfx volume + * @param gsm + */ public Settings(GameStateManager gsm) { super(gsm); cam = new OrthographicCamera(); cam.setToOrtho(false, MENU_WIDTH, MENU_HEIGHT); + viewport = new StretchViewport(MENU_WIDTH, MENU_HEIGHT, cam); colorsImage = new Texture("colors.jpg"); - viewport = new ExtendViewport(MENU_WIDTH, MENU_HEIGHT); //Added viewport to make sliders scale on mobile devices + header = new Texture("settings_header_X6.png"); - music = audio.newMusic(Gdx.files.internal("menu_soundtrack_2.mp3")); - music.setLooping(true); - music.setVolume(Paint2Win.getMusic_volume()); - music.play(); + Paint2Win.AUDIO_MANAGER.playMusic(((Paint2Win)Gdx.app.getApplicationListener()).assets.assetManager.get(SoundAssets.menu_soundtrack_2)); mainMenuButton = new Texture("main_menu.png"); - mainMenuButtonXPosition = MENU_WIDTH/2 - mainMenuButton.getWidth()/2; - mainMenuButtonYPosition = MENU_HEIGHT/8; + mainMenuButtonXPosition = MENU_WIDTH /2 - mainMenuButton.getWidth()/2; + mainMenuButtonYPosition = MENU_HEIGHT /8; stage = new Stage(viewport); Skin skin = new Skin(Gdx.files.internal("uiskin.json")); - Table musicTable = new Table(); musicSlider = new Slider(0f,1f,0.1f,false, skin); - musicSlider.setValue(Paint2Win.getMusic_volume()); - Label musicLabel = new Label("Music volume: " + musicSlider.getValue(), skin); + musicSlider.setValue(Paint2Win.AUDIO_MANAGER.getMusic_volume()); + Label musicLabel = new Label("Music volume: " + roundDecimal(musicSlider.getValue()), skin); musicLabel.setColor(Color.BLACK); musicLabel.setAlignment(Align.center); musicTable.add(musicLabel); musicTable.row(); musicTable.add(musicSlider); - musicTable.setPosition(MENU_WIDTH/4 - musicSlider.getWidth()/2, -MENU_HEIGHT/6); + musicTable.setPosition(MENU_WIDTH /4 - musicSlider.getWidth()/2, -MENU_HEIGHT /6); musicTable.setFillParent(true); Table sfxTable = new Table(); sfxSlider = new Slider(0f,1f,0.1f,false, skin); - sfxSlider.setValue(Paint2Win.getSfx_volume()); - Label sfxLabel = new Label("Sfx volume: " + sfxSlider.getValue(), skin); + sfxSlider.setValue(Paint2Win.AUDIO_MANAGER.getSfx_volume()); + Label sfxLabel = new Label("Sfx volume: " + roundDecimal(sfxSlider.getValue()), skin); sfxLabel.setColor(Color.BLACK); sfxLabel.setAlignment(Align.center); sfxTable.add(sfxLabel); sfxTable.row(); sfxTable.add(sfxSlider); - sfxTable.setPosition(-MENU_WIDTH/4 + sfxSlider.getWidth()/2, -MENU_HEIGHT/6); + sfxTable.setPosition(-MENU_WIDTH /4 + sfxSlider.getWidth()/2, -MENU_HEIGHT /6); sfxTable.setFillParent(true); stage.addActor(musicTable); @@ -101,16 +93,17 @@ public class Settings extends State { musicSlider.addListener(new ChangeListener() { @Override public void changed(ChangeListener.ChangeEvent event, Actor actor) { - musicLabel.setText("Music volume: " + roundDecimal(musicSlider.getValue())); - Paint2Win.setMusic_volume(musicSlider.getValue()); - music.setVolume(musicSlider.getValue()); + float roundedDecimal = roundDecimal(musicSlider.getValue()); + musicLabel.setText("Music volume: " + roundedDecimal); + Paint2Win.AUDIO_MANAGER.setMusic_volume(roundedDecimal); } }); sfxSlider.addListener(new ChangeListener() { @Override public void changed(ChangeListener.ChangeEvent event, Actor actor) { - sfxLabel.setText("Sfx volume: " + roundDecimal(sfxSlider.getValue())); - Paint2Win.setSfx_volume(sfxSlider.getValue()); + float roundedDecimal = roundDecimal(sfxSlider.getValue()); + sfxLabel.setText("Sfx volume: " + roundedDecimal); + Paint2Win.AUDIO_MANAGER.setSfx_volume(roundedDecimal, ((Paint2Win)Gdx.app.getApplicationListener()).assets.assetManager.get(SoundAssets.paintball_sound)); } }); @@ -122,14 +115,23 @@ public class Settings extends State { * @param number * @return */ - private double roundDecimal(double number) { - return new BigDecimal(number).setScale(2, RoundingMode.HALF_UP).doubleValue(); + private float roundDecimal(double number) { + return new BigDecimal(number).setScale(2, RoundingMode.HALF_UP).floatValue(); } + /** + * Function for returning to the Main Menu + */ private void toMainMenu(){ gsm.set(new MainMenu(gsm)); } + /** + * Function for checking if one of the buttons have been pressed. + * What happens is that when the screen is touched it checks if the area pressed is + * inside the rectangle of one of the button, and fires the function assosiated with that button + * if that is the case. + */ private void checkIfPressedButton() { if(Gdx.input.justTouched()) { Vector3 tmp = new Vector3(new Vector2(Gdx.input.getX(), Gdx.input.getY()), 0); @@ -140,39 +142,48 @@ public class Settings extends State { } } - private void save(){ - - } - - public int[] getSettings(){ - return null; - } - + /** + * Updates the variables before the render function is called + * @param dt + */ @Override public void update(float dt) { checkIfPressedButton(); } + /** + * Draws the screen and objects again + * @param sb + */ @Override public void render(SpriteBatch sb) { Gdx.gl.glClearColor(0, 0, 0, 1); Gdx.gl.glClear(GL20.GL_COLOR_BUFFER_BIT); - sb.setProjectionMatrix(cam.combined); sb.begin(); sb.draw(colorsImage, 0,0, MENU_WIDTH, MENU_HEIGHT); + sb.draw(header, MENU_WIDTH/2 - header.getWidth()/2,2*MENU_HEIGHT/4); sb.draw(mainMenuButton, mainMenuButtonXPosition, mainMenuButtonYPosition); sb.end(); stage.draw(); stage.act(); } + /** + * Disposes the page when leaving it + */ @Override public void dispose() { System.out.println("Disposed Settings"); mainMenuButton.dispose(); - music.dispose(); colorsImage.dispose(); + header.dispose(); + stage.dispose(); + } + + @Override + public void resize(int width, int height) { + viewport.update(width, height); } } diff --git a/core/src/com/tdt4240/paint2win/controller/states/State.java b/core/src/com/tdt4240/paint2win/controller/states/State.java index 0fd19575d611aedd99e52b0b042f7925e923f6bc..b8d7698b0cb4979ba5cdac321d1376e86c5a937f 100644 --- a/core/src/com/tdt4240/paint2win/controller/states/State.java +++ b/core/src/com/tdt4240/paint2win/controller/states/State.java @@ -17,5 +17,6 @@ public abstract class State extends ScreenAdapter { public abstract void update(float dt); public abstract void render(SpriteBatch sb); public abstract void dispose(); + public abstract void resize (int width, int height); } diff --git a/core/src/com/tdt4240/paint2win/controller/states/Tutorial.java b/core/src/com/tdt4240/paint2win/controller/states/Tutorial.java index b9300a1072f7b7f7613b7bd58115f80e5fc02744..ed657c66b38a7272c4f758510098d932f4ffce0c 100644 --- a/core/src/com/tdt4240/paint2win/controller/states/Tutorial.java +++ b/core/src/com/tdt4240/paint2win/controller/states/Tutorial.java @@ -1,47 +1,68 @@ package com.tdt4240.paint2win.controller.states; import com.badlogic.gdx.Gdx; -import com.badlogic.gdx.audio.Music; import com.badlogic.gdx.graphics.GL20; import com.badlogic.gdx.graphics.OrthographicCamera; import com.badlogic.gdx.graphics.Texture; import com.badlogic.gdx.graphics.g2d.SpriteBatch; -import com.badlogic.gdx.graphics.glutils.ShapeRenderer; import com.badlogic.gdx.math.Rectangle; import com.badlogic.gdx.math.Vector2; import com.badlogic.gdx.math.Vector3; -import com.badlogic.gdx.scenes.scene2d.ui.Image; +import com.badlogic.gdx.utils.Array; +import com.badlogic.gdx.utils.viewport.StretchViewport; +import com.badlogic.gdx.utils.viewport.Viewport; import com.tdt4240.paint2win.Paint2Win; +import com.tdt4240.paint2win.controller.managers.SoundAssets; -import static com.badlogic.gdx.Gdx.audio; import static com.tdt4240.paint2win.Paint2Win.MENU_HEIGHT; import static com.tdt4240.paint2win.Paint2Win.MENU_WIDTH; public class Tutorial extends State { - private Image[] images; + private final Array<Texture> images; private int currentPicture; - private OrthographicCamera cam; - private Music music; + + private final OrthographicCamera cam; + private final Viewport viewport; private final Texture mainMenuButton; private final int mainMenuButtonXPosition; private final int mainMenuButtonYPosition; + private final Texture rightButton; + private final int rightButtonXPosition; + private final int rightButtonYPosition; + + private final Texture leftButton; + private final int leftButtonXPosition; + private final int leftButtonYPosition; public Tutorial(GameStateManager gsm) { super(gsm); cam = new OrthographicCamera(); cam.setToOrtho(false, MENU_WIDTH, MENU_HEIGHT); + viewport = new StretchViewport(MENU_WIDTH, MENU_HEIGHT, cam); - music = audio.newMusic(Gdx.files.internal("menu_soundtrack_2.mp3")); - music.setLooping(true); - music.setVolume(Paint2Win.getMusic_volume()); - music.play(); + Paint2Win.AUDIO_MANAGER.playMusic(((Paint2Win)Gdx.app.getApplicationListener()).assets.assetManager.get(SoundAssets.menu_soundtrack_2)); mainMenuButton = new Texture("main_menu.png"); mainMenuButtonXPosition = MENU_WIDTH/2 - mainMenuButton.getWidth()/2; - mainMenuButtonYPosition = MENU_HEIGHT/4; + mainMenuButtonYPosition = MENU_HEIGHT/10; + + rightButton = new Texture("Right_Arrow.png"); + rightButtonXPosition = MENU_WIDTH - rightButton.getWidth(); + rightButtonYPosition = MENU_HEIGHT/10; + + leftButton = new Texture("Left_Arrow.png"); + leftButtonXPosition = 0 ; + leftButtonYPosition = MENU_HEIGHT/10; + + this.currentPicture =0; + this.images = new Array<Texture>(); + images.add(new Texture("page1.png")); + images.add(new Texture("page2.png")); + images.add(new Texture("page3.png")); + images.add(new Texture("page4.png")); } private void checkIfPressedButton() { @@ -49,38 +70,79 @@ public class Tutorial extends State { Vector3 tmp = new Vector3(new Vector2(Gdx.input.getX(), Gdx.input.getY()), 0); cam.unproject(tmp); Rectangle mainMenuBounds = new Rectangle(mainMenuButtonXPosition, mainMenuButtonYPosition, mainMenuButton.getWidth(), mainMenuButton.getHeight()); + Rectangle leftButtonBounds = new Rectangle(leftButtonXPosition, leftButtonYPosition, leftButton.getWidth(), leftButton.getHeight()); + Rectangle rightButtonBounds = new Rectangle(rightButtonXPosition, rightButtonYPosition, rightButton.getWidth(), rightButton.getHeight()); if(mainMenuBounds.contains(tmp.x,tmp.y)) { toMainMenu(); } + if(leftButtonBounds.contains(tmp.x,tmp.y)){prevImage();} + if(rightButtonBounds.contains(tmp.x,tmp.y)){nextImage();} } } - private void nextImage(){}; + private void nextImage(){ + if(currentPicture == images.size - 1){ + currentPicture = 0; + return; + } + currentPicture++; + } - private void prevImage(){}; + private void prevImage() { + if (currentPicture == 0) { + currentPicture = images.size - 1; + return; + } + currentPicture--; + } + /** + * Function for returning to the Main Menu + */ private void toMainMenu(){ gsm.set(new MainMenu(gsm)); } + /** + * Updates the variables before the render function is called + * @param dt + */ @Override public void update(float dt) { checkIfPressedButton(); } + /** + * Draws the screen and objects + * @param sb + */ @Override public void render(SpriteBatch sb) { Gdx.gl.glClearColor(0, 0, 0, 1); Gdx.gl.glClear(GL20.GL_COLOR_BUFFER_BIT); sb.setProjectionMatrix(cam.combined); sb.begin(); + sb.draw(images.get(currentPicture), 0,0, MENU_WIDTH, MENU_HEIGHT); sb.draw(mainMenuButton, mainMenuButtonXPosition, mainMenuButtonYPosition); + sb.draw(leftButton, leftButtonXPosition, leftButtonYPosition); + sb.draw(rightButton, rightButtonXPosition, rightButtonYPosition); sb.end(); } + /** + * Disposes the page when leaving it + */ @Override public void dispose() { System.out.println("Disposed Tutorial"); - music.dispose(); mainMenuButton.dispose(); + rightButton.dispose(); + leftButton.dispose(); + images.forEach(Texture::dispose); + } + + @Override + public void resize(int width, int height) { + viewport.update(width, height); } } + diff --git a/core/src/com/tdt4240/paint2win/model/Bullet.java b/core/src/com/tdt4240/paint2win/model/Bullet.java index eb14ec92c76fb55ef1efbdc44aa8da7d18f78f73..13e5e04a6ef6d7ac30be7c1fb3c3c65fb77d8b8c 100644 --- a/core/src/com/tdt4240/paint2win/model/Bullet.java +++ b/core/src/com/tdt4240/paint2win/model/Bullet.java @@ -1,11 +1,11 @@ package com.tdt4240.paint2win.model; import com.badlogic.gdx.Gdx; -import com.badlogic.gdx.audio.Sound; import com.badlogic.gdx.graphics.Texture; import com.badlogic.gdx.graphics.g2d.Sprite; import com.badlogic.gdx.math.Vector2; import com.tdt4240.paint2win.Paint2Win; +import com.tdt4240.paint2win.controller.managers.SoundAssets; import com.tdt4240.paint2win.utility.Vectors; import java.util.UUID; @@ -14,7 +14,6 @@ public class Bullet implements IVisible, IIdentifiable { private static final float SPEED = 1000f; private static final float RANGE = 1000f; - private final Sound sound; private final Player player; private final Texture texture; private final Sprite sprite; @@ -22,6 +21,13 @@ public class Bullet implements IVisible, IIdentifiable { private boolean hasHitSomething; private final UUID uuid; + /** + * Creates a new bullet object. The bullet has a direction and + * contains which player that shot the bullet + * @param player + * @param startPosition + * @param rotation + */ public Bullet(Player player, Vector2 startPosition,float rotation) { this.uuid = UUID.randomUUID(); this.texture = new Texture("bullet.png"); @@ -31,28 +37,41 @@ public class Bullet implements IVisible, IIdentifiable { this.sprite.setOrigin(Shooter.WEAPON_X_DIRECTION_REPLACEMENT - Shooter.MIDDLE.x, -Shooter.MIDDLE.y); this.player = player; this.sprite.setColor(player.getColor()); - remainingRange = RANGE; - - this.sound = Gdx.audio.newSound(Gdx.files.internal("paintball_sound.mp3")); - sound.play(Paint2Win.getSfx_volume()); + this.remainingRange = RANGE; + Paint2Win.AUDIO_MANAGER.playSound(((Paint2Win) Gdx.app.getApplicationListener()).assets.assetManager.get(SoundAssets.paintball_sound)); } + /** + * Returns the bullet sprite + * @return + */ @Override public Sprite getSprite() { return sprite; } + /** + * Returns the current position of the bullet + * @return + */ @Override public Vector2 getPos() { return new Vector2(sprite.getX(), sprite.getY()); } - + /** + * Returns the width and height of the bullet texture + * @return + */ @Override public Vector2 getOriginalMeasures() { return new Vector2(sprite.getWidth(), sprite.getHeight()); } + /** + * Moves the bullet a fixed length in its current direction + * @param delta + */ public void move(float delta) { Vector2 direction = Vectors.getDirectionVector(sprite.getRotation()); Vector2 movement = new Vector2(direction.x * delta * SPEED, direction.y * delta * SPEED); @@ -60,18 +79,33 @@ public class Bullet implements IVisible, IIdentifiable { sprite.translate(movement.x, movement.y); } + /** + * Returns false if bullet is out of its fixed range + * @return + */ public boolean isInRange() { return remainingRange > 0; } + /** + * Updates hasHitSomething if bullet has hit an object + */ public void noticeHit() { hasHitSomething = true; } + /** + * Returns true if bullet has hit something + * @return + */ public boolean hasHitSomething() { return hasHitSomething; } + /** + * Returns true if the bullet is outside of the map area + * @return boolean + */ public boolean isOutOfMap(){ // Must use getBoundingRectangle since the position is not taking object rotation into account if (sprite.getBoundingRectangle().x < 0 || sprite.getBoundingRectangle().y < 0) return true; @@ -80,13 +114,17 @@ public class Bullet implements IVisible, IIdentifiable { return false; } + /** + * Disposes the bullet sound and texture + */ public void dispose(){ - this.sound.dispose(); - this.texture.dispose(); + texture.dispose(); } @Override public UUID getId() { return uuid; } + + public Player getPlayer(){return this.player;} } diff --git a/core/src/com/tdt4240/paint2win/model/Entity.java b/core/src/com/tdt4240/paint2win/model/Entity.java deleted file mode 100644 index 7843d55748c742767a2e3cea9e13b138227c7b3b..0000000000000000000000000000000000000000 --- a/core/src/com/tdt4240/paint2win/model/Entity.java +++ /dev/null @@ -1,23 +0,0 @@ -package com.tdt4240.paint2win.model; - -import com.badlogic.gdx.graphics.Texture; -import com.badlogic.gdx.math.Rectangle; -import com.badlogic.gdx.math.Vector2; -import com.tdt4240.paint2win.view.IRenderer; - -public abstract class Entity implements IRenderer{ - public Vector2 position; - public Rectangle bounds; - public Texture texture; - - - - public abstract void update(float dt); - public abstract boolean collides(Entity e); - public abstract void dispose(); - - - public Texture getTexture(){return texture;} - public Vector2 getPosition(){return position;} - -} diff --git a/core/src/com/tdt4240/paint2win/model/GameMap.java b/core/src/com/tdt4240/paint2win/model/GameMap.java index 75899423fe2f2ac96104eeab61ac63c22a4a313f..750fc50520aeba848d1437f6dc1d1c5c4b7e6004 100644 --- a/core/src/com/tdt4240/paint2win/model/GameMap.java +++ b/core/src/com/tdt4240/paint2win/model/GameMap.java @@ -3,12 +3,23 @@ package com.tdt4240.paint2win.model; import com.badlogic.gdx.math.Rectangle; public class GameMap { + private final Rectangle bounds; + /** + * Class that generates a rectangle with the dimensions of the map to + * check that no objects are placed outside of the map + * @param width + * @param height + */ public GameMap(int width, int height) { bounds = new Rectangle(0,0, width, height); } + /** + * If object tries to move outside of map it is moved the back onto the map + * @param visible + */ public void ensurePlacementWithinBounds(IVisible visible) { float x = visible.getSprite().getX(); float y = visible.getSprite().getY(); diff --git a/core/src/com/tdt4240/paint2win/model/IDeathObserver.java b/core/src/com/tdt4240/paint2win/model/IDeathObserver.java new file mode 100644 index 0000000000000000000000000000000000000000..cb5563b8da0fc55bead660eafdeec2b5a39d99c1 --- /dev/null +++ b/core/src/com/tdt4240/paint2win/model/IDeathObserver.java @@ -0,0 +1,12 @@ +package com.tdt4240.paint2win.model; + +import com.badlogic.gdx.graphics.Color; +import java.util.UUID; + +/** Observer pattern used to observe the death of player + * @author JLK + */ +public interface IDeathObserver { + void UpdateEvent(UUID ID, boolean dead, Color Color); + void UpdateEvent(UUID IdToGivePointsTo, Color Color); +} diff --git a/core/src/com/tdt4240/paint2win/model/IIdentifiable.java b/core/src/com/tdt4240/paint2win/model/IIdentifiable.java index 9ae2ea64dbe9f21ae9eb8ab3c0845f8f5b1bc3d9..2abeaaaefdcd80f25409ce67bd272e5e1e6511c2 100644 --- a/core/src/com/tdt4240/paint2win/model/IIdentifiable.java +++ b/core/src/com/tdt4240/paint2win/model/IIdentifiable.java @@ -2,9 +2,18 @@ package com.tdt4240.paint2win.model; import java.util.UUID; +/** + * Used to create ID different objects + */ public interface IIdentifiable { UUID getId(); - default boolean isIdEqual(UUID otherId) { + + /** + * Returns true if two IDs are equal + * @param otherId + * @return boolean + */ + default boolean isIdEqual(UUID otherId) { return getId().equals(otherId); } } diff --git a/core/src/com/tdt4240/paint2win/model/MovingEntity.java b/core/src/com/tdt4240/paint2win/model/MovingEntity.java deleted file mode 100644 index 6d4259b65151ffa6bcdd196cde508ed16131ed45..0000000000000000000000000000000000000000 --- a/core/src/com/tdt4240/paint2win/model/MovingEntity.java +++ /dev/null @@ -1,14 +0,0 @@ -package com.tdt4240.paint2win.model; - -import com.badlogic.gdx.math.Vector2; -import com.tdt4240.paint2win.view.Animation; - -public abstract class MovingEntity extends Entity { - - public int id; //burde defineres som egen type - public Vector2 velocity; - public Animation animation; - - public abstract void move(float x, float y); //skal denne brukes som setPosition()? - -} diff --git a/core/src/com/tdt4240/paint2win/model/Obstacle.java b/core/src/com/tdt4240/paint2win/model/Obstacle.java index 76532fd531fd3686a4bd52208a120a6e36f04d0b..31143f6763517950df21bd80b5d7dea0382ae390 100644 --- a/core/src/com/tdt4240/paint2win/model/Obstacle.java +++ b/core/src/com/tdt4240/paint2win/model/Obstacle.java @@ -31,17 +31,28 @@ public class Obstacle implements IVisible { shape.setPosition(position.x, position.y); } - + /** + * Returns the obstacle sprite + * @return + */ @Override public Sprite getSprite() { return sprite; } + /** + * Returns the obstacles position + * @return + */ @Override public Vector2 getPos() { return position; } + /** + * Returns the obsacles width and heigt + * @return Vector2(width, height) + */ @Override public Vector2 getOriginalMeasures() { return new Vector2(sprite.getWidth(), sprite.getHeight()); diff --git a/core/src/com/tdt4240/paint2win/model/Player.java b/core/src/com/tdt4240/paint2win/model/Player.java index fbff2c4488d36e9238e06154bbfe42e8d24ce803..f32c84cbf1ce99f4c072dcc372f92563ad2621e8 100644 --- a/core/src/com/tdt4240/paint2win/model/Player.java +++ b/core/src/com/tdt4240/paint2win/model/Player.java @@ -1,13 +1,12 @@ package com.tdt4240.paint2win.model; import com.badlogic.gdx.Gdx; -import com.badlogic.gdx.audio.Sound; import com.badlogic.gdx.graphics.Color; import com.badlogic.gdx.math.Vector2; import com.tdt4240.paint2win.Paint2Win; import com.tdt4240.paint2win.container.ObstacleContainer; -import com.tdt4240.paint2win.utility.IDeathObserver; -import com.tdt4240.paint2win.utility.IJoystickObserver; +import com.tdt4240.paint2win.controller.managers.SoundAssets; +import com.tdt4240.paint2win.controller.controls.IJoystickObserver; import java.util.ArrayList; import java.util.List; @@ -18,7 +17,6 @@ public class Player implements IJoystickObserver,IIdentifiable { private final Color color; private Optional<Shooter> shooter; private ObstacleContainer obstacleContainer; - private final Sound hitSound; private final UUID uuid; private List<IDeathObserver> observers = new ArrayList<>(); @@ -33,8 +31,7 @@ public class Player implements IJoystickObserver,IIdentifiable { this.color = color; this.shooter = Optional.empty(); this.obstacleContainer = obstacleContainer; - this.hitSound = Gdx.audio.newSound(Gdx.files.internal("hit_by_paintball.mp3")); - notifyObservers(1,false); //change ID!! + notifyObservers(uuid,false, this.color); } /** @@ -47,12 +44,13 @@ public class Player implements IJoystickObserver,IIdentifiable { /** * The player gets hit and shooter is removed - * TODO: Need to change the id + * */ - public void noticeHit() { + public void noticeHit(Player playerbullet) { + if (playerbullet==this) return; this.shooter = Optional.empty(); - hitSound.play(Paint2Win.getSfx_volume()); - notifyObservers(1,true); //change ID!! + notifyObservers(playerbullet.getId(), this.color); + Paint2Win.AUDIO_MANAGER.playSound(((Paint2Win) Gdx.app.getApplicationListener()).assets.assetManager.get(SoundAssets.target_hit)); } /** @@ -116,32 +114,45 @@ public class Player implements IJoystickObserver,IIdentifiable { }); } + + @Override public UUID getId() { return uuid; } - /**Sends info to observers of IDeathObserver - * + /** + * Sends info to observers of IDeathObserver */ - private void notifyObservers(int ID, boolean dead) { + private void notifyObservers(UUID ID, boolean dead, Color color) { for (IDeathObserver observer: this.observers){ - observer.UpdateEvent(ID, dead); + observer.UpdateEvent(ID, dead, color); } } - /** Add a observer to observer list of this class - * + /** + * Sends info to observers of IDeathObserver + */ + private void notifyObservers(UUID ID, Color color) { + for (IDeathObserver observer: this.observers){ + observer.UpdateEvent(ID, color); + } + } + + + + /** + * Add a observer to observer list of this class * @param observer needs to be a observable object of IDeathObserver */ public void addObserver(IDeathObserver observer) { observers.add(observer); - notifyObservers(1,false); //Cahnge ID!! + notifyObservers(uuid,false, color); } - /**removers the observer from List + /** + * Removes the observer from List * should be done in desctructors to avoid index errors - * * @param observer needs to be a observable object of IDeathObserver */ public void removeObserver(IDeathObserver observer) { @@ -149,7 +160,7 @@ public class Player implements IJoystickObserver,IIdentifiable { } public void dispose(){ - this.hitSound.dispose(); + shooter.ifPresent(Shooter::dispose); } } diff --git a/core/src/com/tdt4240/paint2win/model/PowerUp.java b/core/src/com/tdt4240/paint2win/model/PowerUp.java deleted file mode 100644 index ffd3d4e0d63da2230cf68e311d5caee890ab56da..0000000000000000000000000000000000000000 --- a/core/src/com/tdt4240/paint2win/model/PowerUp.java +++ /dev/null @@ -1,37 +0,0 @@ -package com.tdt4240.paint2win.model; - -import com.badlogic.gdx.graphics.g2d.SpriteBatch; -import com.badlogic.gdx.graphics.glutils.ShapeRenderer; -import com.tdt4240.paint2win.view.IRenderer; - -public class PowerUp extends Entity { - - int powerUpType; - - - public void addEffect(){ - - } - - @Override - public void update(float dt) { - /* - check if it is picked up? - */ - } - - @Override - public boolean collides(Entity e) { - return false; - } - - @Override - public void dispose() { - - } - - @Override - public void render(SpriteBatch sb) { - - } -} diff --git a/core/src/com/tdt4240/paint2win/model/Scoreboard.java b/core/src/com/tdt4240/paint2win/model/Scoreboard.java index d5f08cb18a08b2d6e31137d34b88910744c719f0..0088f9e3ab748032ee2b87c1427d2c084f33d545 100644 --- a/core/src/com/tdt4240/paint2win/model/Scoreboard.java +++ b/core/src/com/tdt4240/paint2win/model/Scoreboard.java @@ -2,91 +2,41 @@ package com.tdt4240.paint2win.model; import com.badlogic.gdx.graphics.g2d.Batch; import com.badlogic.gdx.graphics.g2d.BitmapFont; -import com.badlogic.gdx.graphics.g2d.SpriteBatch; -import com.tdt4240.paint2win.utility.IDeathObserver; -import com.tdt4240.paint2win.view.PlayerCamera; +import com.badlogic.gdx.math.Vector2; -import java.util.HashMap; -import java.util.Map; - -/** Scoreboard counts the mount of times the ID player gets hit - * @author JLK +/** + * Scoreboard counts the mount of times the Target gets hit */ -public class Scoreboard implements IDeathObserver { - private float posX; - private float posY; - - - private Map<Integer,Integer> ScoreTable; - - public Scoreboard(){ - this.ScoreTable = new HashMap<Integer,Integer>(); - posX=0; - posY=0; - } - +public class Scoreboard { + private int score; + private final int maxScore; - public void render(Batch sb, BitmapFont textrenderer){ - sb.begin(); - int i = 0; - for (Map.Entry mapElement : ScoreTable.entrySet()) { - int ID = (int)mapElement.getKey(); - int score = (int)mapElement.getValue(); - //System.out.println((String)(ID+ ":"+ score)); - textrenderer.draw(sb,(String)(ID+ ": "+score) ,posX ,posY-i); - i+=10; - } - sb.end(); + public Scoreboard(int maxScore) { + this.score = 0; + this.maxScore = maxScore; } - /**sets the position for the scoreboard to be drawn at - * - * @param x - * @param y + /** + * Render and update function need to ber run every frame + * @param sb spritebatch + * @param textRenderer bitmapfont */ - public void setPosition(float x, float y){ - posX=x;posY=y; + public void render(Vector2 position, Batch sb, BitmapFont textRenderer) { + textRenderer.draw(sb, "Targets hit: " + score + "/" + maxScore, position.x, position.y); } - /** Adds 1 to the score of the player with ID - * - * @param ID id of player + /** + * Is the goal reached of this scoreboard + * @return true if goal is reached */ - private void addScore(int ID){ - this.ScoreTable.put(ID,this.ScoreTable.get(ID)+1); + public boolean isGoalReached() { + return score == maxScore; } - /** adds an id object to tracked - * - * @param ID id of player + /** + * Adds one to the score */ - public void addScoreObject(int ID){ - if (!this.ScoreTable.containsKey(ID)){ - this.ScoreTable.put(ID,0); - } - else return; - } - - /** removes the id object from scoreboard - * - * @param ID id of player - */ - public void RemoveScoreObject(int ID){ - this.ScoreTable.remove(ID); - } - - @Override - public void UpdateEvent(Object ID, Object dead) { - if (this.ScoreTable.containsKey(ID) && (boolean)dead){ - addScore((int)ID); - } - else if (!this.ScoreTable.containsKey(ID) && (boolean)dead){ - addScoreObject((int)ID); - addScore((int)ID); - } - else if (!this.ScoreTable.containsKey(ID) && !(boolean)dead){ - addScoreObject((int)ID); - } - + public void increaseScore() { + this.score++; } -} +} \ No newline at end of file diff --git a/core/src/com/tdt4240/paint2win/model/Shooter.java b/core/src/com/tdt4240/paint2win/model/Shooter.java index 67fd872e967df72a4e7bbed5868e17be6ea1db44..ff7fd1cc116321106f45e0e7aa9c3a2bf81b2d75 100644 --- a/core/src/com/tdt4240/paint2win/model/Shooter.java +++ b/core/src/com/tdt4240/paint2win/model/Shooter.java @@ -5,8 +5,6 @@ import com.badlogic.gdx.graphics.g2d.Sprite; import com.badlogic.gdx.math.Circle; import com.badlogic.gdx.math.Intersector; import com.badlogic.gdx.math.Vector2; -import com.tdt4240.paint2win.utility.IDeathObserver; -import com.tdt4240.paint2win.utility.IJoystickObserver; import java.time.Duration; import java.time.Instant; @@ -52,9 +50,6 @@ public class Shooter implements IVisible, IIdentifiable { this.player = player; position = new Vector2(0, 0); lastShot = Instant.EPOCH; - - - } /** @@ -81,17 +76,27 @@ public class Shooter implements IVisible, IIdentifiable { return Optional.empty(); } + /** + * @return shooters sprite + */ @Override public Sprite getSprite() { return sprite; } - + /** + * Returns the width and height of the shooter when not rotated + * @return Vector2(SHOOTERWIDTH, SHOOTERHEIGHT) + */ @Override public Vector2 getOriginalMeasures() { return new Vector2(SHOOTERWIDTH, SHOOTERHEIGHT); } + /** + * Returns the bottom left corner postion of the shooter + * @return Vector2(x-value, y-value) + */ @Override public Vector2 getPos(){ return new Vector2(sprite.getX(),sprite.getY()); @@ -168,6 +173,10 @@ public class Shooter implements IVisible, IIdentifiable { */ public void setWantsToShoot(boolean b){this.wantsToShoot=b;} + /** + * Returns the players ID + * @return UUID + */ @Override public UUID getId() { return player.getId(); diff --git a/core/src/com/tdt4240/paint2win/model/Target.java b/core/src/com/tdt4240/paint2win/model/Target.java new file mode 100644 index 0000000000000000000000000000000000000000..0b58896510bb8ae773a97b13b7417014f34e8b49 --- /dev/null +++ b/core/src/com/tdt4240/paint2win/model/Target.java @@ -0,0 +1,108 @@ +package com.tdt4240.paint2win.model; + +import com.badlogic.gdx.Gdx; +import com.badlogic.gdx.graphics.Texture; +import com.badlogic.gdx.graphics.g2d.Sprite; +import com.badlogic.gdx.graphics.g2d.SpriteBatch; +import com.badlogic.gdx.math.Intersector; +import com.badlogic.gdx.math.Rectangle; +import com.badlogic.gdx.math.Vector2; +import com.tdt4240.paint2win.Paint2Win; +import com.tdt4240.paint2win.container.ObstacleContainer; +import com.tdt4240.paint2win.controller.managers.SoundAssets; + +import java.util.Optional; +import java.util.Random; + +public class Target implements IVisible { + + private static final Random random = new Random(); + public static final int TARGETWIDTH = 155; + public static final int TARGETHEIGHT = 155; + public static final Vector2 MIDDLE = new Vector2(TARGETWIDTH/2, TARGETHEIGHT/2); + private final Texture texture; + private final Sprite sprite; + private Vector2 position; + private final ObstacleContainer obstacleContainer; + private final Scoreboard scoreboard; + + public Target(ObstacleContainer obstacleContainer, + Scoreboard scoreboard){ + this.texture = new Texture("target.png"); + this.sprite = new Sprite(texture, TARGETWIDTH, TARGETHEIGHT); + this.sprite.setOrigin(MIDDLE.x, MIDDLE.y); + this.obstacleContainer = obstacleContainer; + this.position = randomRespawnPoint(this.obstacleContainer); + this.sprite.setPosition(this.position.x,this.position.y); + this.scoreboard = scoreboard; + } + + @Override + public Sprite getSprite() { + return this.sprite; + } + + @Override + public Vector2 getPos() { + return this.position; + } + + @Override + public Vector2 getOriginalMeasures() { + return new Vector2(TARGETWIDTH, TARGETHEIGHT); + } + + /** + * Sets the position of the target + * @param position Vector2(x,y) + */ + public void setPos(Vector2 position){ + this.position=position; + this.sprite.setPosition(position.x,position.y); + } + + /** + * The target gets hit and is placed random + */ + public void noticeHit() { + this.setPos(randomRespawnPoint(obstacleContainer)); + this.scoreboard.increaseScore(); + Paint2Win.AUDIO_MANAGER.playSound(((Paint2Win) Gdx.app.getApplicationListener()).assets.assetManager.get(SoundAssets.target_hit)); + + } + + /** + * Generates a target the does not collide with any of the obstacles + * @param obstacleContainer contains all obstacles on the map + * @return Vector2(randomX, randomY) + */ + private Vector2 randomRespawnPoint(ObstacleContainer obstacleContainer) { + Rectangle tempRectangel = this.sprite.getBoundingRectangle(); + while(true) { + Vector2 randomPos = new Vector2(random.nextInt((int)Math.floor(Paint2Win.MAP_WIDTH-TARGETWIDTH)), + random.nextInt((int) Math.floor(Paint2Win.MAP_HEIGHT-TARGETHEIGHT))); + tempRectangel.setPosition(randomPos); + Optional<Obstacle> collidingObstacle = obstacleContainer.stream() + .filter(obstacle -> Intersector.overlaps(tempRectangel,obstacle.getSprite().getBoundingRectangle())) + .findAny(); + if (!collidingObstacle.isPresent()) { + return randomPos; + } + } + } + + /** + * Draws the target on the spritebatch + * @param sb spritebatch + */ + public void draw(SpriteBatch sb) { + sb.draw(this.sprite.getTexture(),position.x,position.y); + } + + /** + * Disposes the used objects + */ + public void dispose(){ + texture.dispose(); + } +} diff --git a/core/src/com/tdt4240/paint2win/model/TimerWatch.java b/core/src/com/tdt4240/paint2win/model/TimerWatch.java new file mode 100644 index 0000000000000000000000000000000000000000..03f5271712563a96fa8b825685ac2e07867536ac --- /dev/null +++ b/core/src/com/tdt4240/paint2win/model/TimerWatch.java @@ -0,0 +1,77 @@ +package com.tdt4240.paint2win.model; + +import com.badlogic.gdx.graphics.g2d.Batch; +import com.badlogic.gdx.graphics.g2d.BitmapFont; +import com.badlogic.gdx.math.Vector2; + +public class TimerWatch { + + private long startTime; + private long stopTime; + private boolean running; + + public TimerWatch (){ + this.startTime = 0; + this.stopTime = 0; + this.running = false; + } + + /** + * Returns a string format of the elapsed time + * @param elapsedTime elapsed time in milliseconds + * @return String on the form: min + ":" + sec + ":" + milli + */ + public static final String fancyString(int elapsedTime) { + int millisec = elapsedTime % 1000; + int seconds = (elapsedTime / 1000) % 60 ; + int minutes = ((elapsedTime / (1000*60)) % 60); + String milli = millisec + ""; + String sec = seconds + ""; + String min = minutes + ""; + if (millisec<100) { + milli = "0" + milli; + } + if (millisec<10) { + milli = "0" + milli; + } + if (seconds<10) { + sec = "0" + sec; + } + if (minutes<10) { + min = "0" + min; + } + return min + ":" + sec + ":" + milli; + } + + /** + * Starts the timer clock + */ + public void start() { + this.startTime = System.currentTimeMillis(); + this.running = true; + } + + /** + * Returns the elapsed time in milliseconds + * @return (Int) elapsed time + */ + public int getElapsedTime() { + long elapsed; + if (running) { + elapsed = (System.currentTimeMillis() - startTime); + } else { + elapsed = (stopTime - startTime); + } + return (int)elapsed; + } + + /** + * Renders the timer text + * @param position placement on screen + * @param sb spritebatch + * @param textRenderer textrenderer + */ + public void render(Vector2 position, Batch sb, BitmapFont textRenderer) { + textRenderer.draw(sb, "Time: " +fancyString(this.getElapsedTime()), position.x, position.y); + } +} \ No newline at end of file diff --git a/core/src/com/tdt4240/paint2win/model/maps/AbstractMap.java b/core/src/com/tdt4240/paint2win/model/maps/AbstractMap.java index 5590125aef655395616d3bc72fb38f99b19b7b77..7bef03fef8a14ea26b9e7f50c10bac1bd191d4f3 100644 --- a/core/src/com/tdt4240/paint2win/model/maps/AbstractMap.java +++ b/core/src/com/tdt4240/paint2win/model/maps/AbstractMap.java @@ -1,6 +1,7 @@ package com.tdt4240.paint2win.model.maps; import com.badlogic.gdx.graphics.Texture; +import com.tdt4240.paint2win.container.ObstacleContainer; import com.tdt4240.paint2win.model.IIdentifiable; import java.util.UUID; @@ -9,22 +10,44 @@ public abstract class AbstractMap implements IIdentifiable { private Texture backGround; private UUID uuid; + protected ObstacleContainer obstacleContainer; + public enum valid_maps {DESERT, URBAN } + + /** + * Create a new map with a background image + * @param backGround + */ public AbstractMap(Texture backGround) { this.backGround = backGround; this.uuid = UUID.randomUUID(); + this.obstacleContainer = new ObstacleContainer(); } + /** + * Returns background image + * @return + */ public Texture getBackGround() { return backGround; } + /** + * Disposes the background + */ public void dispose(){ backGround.dispose(); + obstacleContainer.dispose(); } @Override public UUID getId() { return uuid; } + + public ObstacleContainer getObstacleContainer(){ + return this.obstacleContainer; + } + + public abstract String toString(); } diff --git a/core/src/com/tdt4240/paint2win/model/maps/desert_map.java b/core/src/com/tdt4240/paint2win/model/maps/desert_map.java index 1ace029f25d0edbcd9c95336795403eda94c88f6..27babfaed6da9e61077b217b806378650753d20c 100644 --- a/core/src/com/tdt4240/paint2win/model/maps/desert_map.java +++ b/core/src/com/tdt4240/paint2win/model/maps/desert_map.java @@ -7,7 +7,10 @@ import com.tdt4240.paint2win.model.Obstacle; public class desert_map extends AbstractMap { - public desert_map(ObstacleContainer obstacleContainer) { + /** + * Creates a map designed to look like a desert environment + */ + public desert_map() { super(new Texture("sand_bg.png")); Texture texture_container = new Texture("dark_container.png"); Texture texture_medic_car = new Texture("medic_car.png"); @@ -23,4 +26,14 @@ public class desert_map extends AbstractMap { obstacleContainer.add(new Obstacle(new Vector2(2640,300), texture_rock)); obstacleContainer.add(new Obstacle(new Vector2(450,1900), texture_rock)); } + + @Override + public String toString() { + return "desert"; + } + + @Override + public void dispose() { + super.dispose(); + } } \ No newline at end of file diff --git a/core/src/com/tdt4240/paint2win/model/maps/urban_map.java b/core/src/com/tdt4240/paint2win/model/maps/urban_map.java index 4ab7e276a3d5932937a468bc1c8849b51ab41f9d..a022d8e20434917e597c47b277ddfc51d0e7e2bc 100644 --- a/core/src/com/tdt4240/paint2win/model/maps/urban_map.java +++ b/core/src/com/tdt4240/paint2win/model/maps/urban_map.java @@ -7,7 +7,10 @@ import com.tdt4240.paint2win.model.Obstacle; public class urban_map extends AbstractMap { - public urban_map(ObstacleContainer obstacleContainer) { + /** + * Creates a map designed to look like an urban environment + */ + public urban_map() { super(new Texture("background.png")); Texture texture = new Texture("Crate.png"); Texture texture_2 = new Texture("Iron_crate.png"); @@ -25,4 +28,13 @@ public class urban_map extends AbstractMap { obstacleContainer.add(new Obstacle(new Vector2(2413,280), texture_7)); } + @Override + public String toString() { + return "urban"; + } + + @Override + public void dispose() { + super.dispose(); + } } diff --git a/core/src/com/tdt4240/paint2win/networking/DataTransfer.java b/core/src/com/tdt4240/paint2win/networking/DataTransfer.java new file mode 100644 index 0000000000000000000000000000000000000000..8eec23a06d71322fafd3afa305596aa5d42139ff --- /dev/null +++ b/core/src/com/tdt4240/paint2win/networking/DataTransfer.java @@ -0,0 +1,78 @@ +package com.tdt4240.paint2win.networking; + +import com.tdt4240.paint2win.model.maps.AbstractMap; +import com.tdt4240.paint2win.networking.Dto.Dto; +import com.tdt4240.paint2win.networking.Dto.HighScoreRow; +import com.tdt4240.paint2win.networking.Dto.Placement; + +import java.io.BufferedReader; +import java.io.IOException; +import java.io.InputStreamReader; +import java.io.OutputStream; +import java.net.HttpURLConnection; +import java.net.URL; +import java.util.List; + +public class DataTransfer { + + private final static String domain = "http://46.101.118.152:"; + private final static String port = "8080"; + + /** + * Based on https://www.baeldung.com/httpurlconnection-post + * Used for sending time used on a round + * @param playerName name of the player + * @param mapType + * @throws IOException + */ + public static final Placement SendTimeUsed(String playerName, int timeInMilliSec, AbstractMap mapType) throws IOException { + URL url = new URL(domain+port+"/highscores/"); + HttpURLConnection con = (HttpURLConnection)url.openConnection(); + con.setRequestMethod("POST"); + con.setRequestProperty("Content-Type", "application/json; utf-8"); + con.setRequestProperty("User-Agent", "Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.11 (KHTML, like Gecko) Chrome/23.0.1271.95 Safari/537.11"); + con.setRequestProperty("Accept", "application/json"); + con.setDoOutput(true); + String jsonInputString = new HighScoreRow(playerName,timeInMilliSec,mapType.toString().toUpperCase()).toJsonString(); + try(OutputStream os = con.getOutputStream()) { + byte[] input = jsonInputString.getBytes("utf-8"); + os.write(input, 0, input.length); + } + try(BufferedReader br = new BufferedReader( + new InputStreamReader(con.getInputStream(), "utf-8"))) { + StringBuilder response = new StringBuilder(); + String responseLine = null; + while ((responseLine = br.readLine()) != null) { + response.append(responseLine.trim()); + } + return Dto.fromJsonString(response.toString(), Placement.class); + } + } + + /** + * Used for getting list of highscores + * @param mapType which map to get data from + * @throws IOException + * @returns list of highScoreRows or throws + */ + public static final List<HighScoreRow> getHighscores(AbstractMap.valid_maps mapType) throws IOException { + URL url = new URL(domain+port+"/highscores/"+mapType.toString().toLowerCase()); + HttpURLConnection con = (HttpURLConnection)url.openConnection(); + con.setRequestMethod("GET"); + con.setRequestProperty("Content-Type", "application/json; utf-8"); + con.setRequestProperty("User-Agent", "Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.11 (KHTML, like Gecko) Chrome/23.0.1271.95 Safari/537.11"); + int responseCode = con.getResponseCode(); + if (responseCode == HttpURLConnection.HTTP_OK) { // success + try(BufferedReader br = new BufferedReader( + new InputStreamReader(con.getInputStream(), "utf-8"))) { + StringBuilder response = new StringBuilder(); + String responseLine = null; + while ((responseLine = br.readLine()) != null) { + response.append(responseLine.trim()); + } + return Dto.fromArryWithJsonString(response.toString(),HighScoreRow.class); + } + } + throw new IOException("Response code was not OK"); + } +} diff --git a/core/src/com/tdt4240/paint2win/networking/Dto/Dto.java b/core/src/com/tdt4240/paint2win/networking/Dto/Dto.java new file mode 100644 index 0000000000000000000000000000000000000000..14479bfb53e63d4d307ca8b68627b955ad8c7afd --- /dev/null +++ b/core/src/com/tdt4240/paint2win/networking/Dto/Dto.java @@ -0,0 +1,55 @@ +package com.tdt4240.paint2win.networking.Dto; + +import com.fasterxml.jackson.core.JsonProcessingException; +import com.fasterxml.jackson.databind.ObjectMapper; + +import java.util.List; + + +public interface Dto { + + ObjectMapper objectMapper = new ObjectMapper(); + + /** + * Converts object to json for network transfer. + * @throws RuntimeException When object can't be converted to JSON. + * @return Object as JSON-string + */ + default String toJsonString(){ + try { + return objectMapper.writeValueAsString(this); + } catch (JsonProcessingException e) { + throw new RuntimeException("Error converting to JSON: ", e); + } + } + + /** + * Parses json and creates object. + * @param json JSON-string to be parsed. + * @param dtoTypeClass Class of object that's sent. + * @throws RuntimeException When object JSON can't be parsed. + * @return Object parsed. + */ + static <DtoType extends Dto> DtoType fromJsonString(String json, Class<DtoType> dtoTypeClass){ + try { + return objectMapper.readValue(json, dtoTypeClass); + } catch (JsonProcessingException e) { + throw new RuntimeException("Error parsing JSON to Object: ", e); + } + } + + /** + * Parses json objects in and array and creates a list of objects. + * @param json JSON-string to be parsed. + * @param dtoTypeClass Class of object that's sent. + * @throws RuntimeException When object JSON can't be parsed. + * @return Object parsed. + */ + static <DtoType extends Dto> List<DtoType> fromArryWithJsonString(String json, Class<DtoType> dtoTypeClass){ + try { + return objectMapper.readValue(json, objectMapper.getTypeFactory().constructCollectionType(List.class, dtoTypeClass)); + } catch (JsonProcessingException e) { + throw new RuntimeException("Error parsing JSON to Object: ", e); + } + } +} diff --git a/core/src/com/tdt4240/paint2win/networking/Dto/HighScoreRow.java b/core/src/com/tdt4240/paint2win/networking/Dto/HighScoreRow.java new file mode 100644 index 0000000000000000000000000000000000000000..51faf075a9e4cb2aca8f5cae14dd71ae156b15d4 --- /dev/null +++ b/core/src/com/tdt4240/paint2win/networking/Dto/HighScoreRow.java @@ -0,0 +1,40 @@ +package com.tdt4240.paint2win.networking.Dto; + +import com.fasterxml.jackson.annotation.JsonCreator; +import com.fasterxml.jackson.annotation.JsonProperty; + +public class HighScoreRow implements Dto { + + private final String playerName; + private final int time; + private final String mapName; + + /** + * Data Transfer Object for posting time used + * @param playerName name of the player + * @param time time in millisec + * @param mapName map + */ + @JsonCreator + public HighScoreRow( + @JsonProperty("playerName") String playerName, + @JsonProperty("time") int time , + @JsonProperty("mapName") String mapName) { + this.playerName = playerName; + this.time = time; + this.mapName = mapName; + } + + // GETTERS used in Dto by objectMapper.readValue + public String getPlayerName() { + return playerName; + } + + public int getTime() { + return time; + } + + public String getMapName(){ + return mapName; + } +} diff --git a/core/src/com/tdt4240/paint2win/networking/Dto/Placement.java b/core/src/com/tdt4240/paint2win/networking/Dto/Placement.java new file mode 100644 index 0000000000000000000000000000000000000000..94191e61dfa45594d9b6af5e39139fd84cb932b1 --- /dev/null +++ b/core/src/com/tdt4240/paint2win/networking/Dto/Placement.java @@ -0,0 +1,28 @@ +package com.tdt4240.paint2win.networking.Dto; + +import com.fasterxml.jackson.annotation.JsonCreator; +import com.fasterxml.jackson.annotation.JsonProperty; + +public class Placement implements Dto { + private final int placement; + private final boolean newPr; + + /** + * Data Transfer Object for posting time used + * @param placement placement from 1-10 and where -1 is not on highscore board + */ + @JsonCreator + public Placement( + @JsonProperty("placement") int placement, + @JsonProperty("newPr") boolean newPr + ) { + this.placement = placement; + this.newPr = newPr; + } + + // GETTERS used in Dto by objectMapper.readValue + public int getPlacement() { + return placement; + } + public boolean getNewPr() {return newPr; } +} diff --git a/core/src/com/tdt4240/paint2win/networking/IClient.java b/core/src/com/tdt4240/paint2win/networking/IClient.java deleted file mode 100644 index 30b52f057d405f5873cf79b4b36830d24af186c9..0000000000000000000000000000000000000000 --- a/core/src/com/tdt4240/paint2win/networking/IClient.java +++ /dev/null @@ -1,14 +0,0 @@ -package com.tdt4240.paint2win.networking; - -public interface IClient { - - public void connect(); - public void onConnected(); - public void onOtherPlayerConnected(); - public void onOtherPlayerDisconnected(); - public void onGameStateReceived(); - public void sendControls(); - public boolean isConnected(); - - -} diff --git a/core/src/com/tdt4240/paint2win/networking/SocketIoClient.java b/core/src/com/tdt4240/paint2win/networking/SocketIoClient.java deleted file mode 100644 index 0c5034898927187696c2b447ad6083ee9ed36434..0000000000000000000000000000000000000000 --- a/core/src/com/tdt4240/paint2win/networking/SocketIoClient.java +++ /dev/null @@ -1,47 +0,0 @@ -package com.tdt4240.paint2win.networking; - -public class SocketIoClient /*implements IClient*/ { - /* - Socket socket; - - public void setupEvents(){} - public void on(Socket socket, Event event){} - public void emit(Socket socket, Event event){} - - @Override - public void connect() { - - } - - @Override - public void onConnected() { - - } - - @Override - public void onOtherPlayerConnected() { - - } - - @Override - public void onOtherPlayerDisconnected() { - - } - - @Override - public void onGameStateReceived() { - - } - - @Override - public void sendControls() { - - } - - @Override - public boolean isConnected() { - return false; - } - - */ -} diff --git a/core/src/com/tdt4240/paint2win/utility/Colors.java b/core/src/com/tdt4240/paint2win/utility/Colors.java new file mode 100644 index 0000000000000000000000000000000000000000..e23c3711a884ec750ee12c584a457715bc33b9d5 --- /dev/null +++ b/core/src/com/tdt4240/paint2win/utility/Colors.java @@ -0,0 +1,76 @@ +package com.tdt4240.paint2win.utility; + +import com.badlogic.gdx.graphics.Color; +import com.badlogic.gdx.utils.ObjectMap; + +public final class Colors { + + private static final ObjectMap<String, Color> map = new ObjectMap<String, Color>(); + + /** + * Fills the hashmap with objects + */ + static { + reset(); + } + + /** Convenience method to lookup a color by {@code name}. The invocation of this method is equivalent to the expression + * {@code Colors.getColors().get(name)} + * + * @param name the name of the color + * @return the color to which the specified {@code name} is mapped, or {@code null} if there was no mapping for {@code name} + * . */ + public static Color get(String name) { + return map.get(name); + } + + /** Resets the color map to the predefined colors. */ + public static void reset () { + map.clear(); + map.put("CLEAR", Color.CLEAR); + map.put("BLACK", Color.BLACK); + + map.put("WHITE", Color.WHITE); + map.put("LIGHT_GRAY", Color.LIGHT_GRAY); + map.put("GRAY", Color.GRAY); + map.put("DARK_GRAY", Color.DARK_GRAY); + + map.put("BLUE", Color.BLUE); + map.put("NAVY", Color.NAVY); + map.put("ROYAL", Color.ROYAL); + map.put("SLATE", Color.SLATE); + map.put("SKY", Color.SKY); + map.put("CYAN", Color.CYAN); + map.put("TEAL", Color.TEAL); + + map.put("GREEN", Color.GREEN); + map.put("CHARTREUSE", Color.CHARTREUSE); + map.put("LIME", Color.LIME); + map.put("FOREST", Color.FOREST); + map.put("OLIVE", Color.OLIVE); + + map.put("YELLOW", Color.YELLOW); + map.put("GOLD", Color.GOLD); + map.put("GOLDENROD", Color.GOLDENROD); + map.put("ORANGE", Color.ORANGE); + + map.put("BROWN", Color.BROWN); + map.put("TAN", Color.TAN); + map.put("FIREBRICK", Color.FIREBRICK); + + map.put("RED", Color.RED); + map.put("SCARLET", Color.SCARLET); + map.put("CORAL", Color.CORAL); + map.put("SALMON", Color.SALMON); + map.put("PINK", Color.PINK); + map.put("MAGENTA", Color.MAGENTA); + + map.put("PURPLE", Color.PURPLE); + map.put("VIOLET", Color.VIOLET); + map.put("MAROON", Color.MAROON); + } + + private Colors () { + } + +} diff --git a/core/src/com/tdt4240/paint2win/utility/IDeathObserver.java b/core/src/com/tdt4240/paint2win/utility/IDeathObserver.java deleted file mode 100644 index 34cc0c4bad017c1a4bd432b1a619c75776ef971d..0000000000000000000000000000000000000000 --- a/core/src/com/tdt4240/paint2win/utility/IDeathObserver.java +++ /dev/null @@ -1,11 +0,0 @@ -package com.tdt4240.paint2win.utility; - -import com.badlogic.gdx.math.Vector2; -import com.tdt4240.paint2win.model.Obstacle; - -/** Observer pattern used to observ the death of player so Scoreboard can count it - * @author JLK - */ -public interface IDeathObserver { - void UpdateEvent(Object ID, Object dead); -} diff --git a/core/src/com/tdt4240/paint2win/utility/Vectors.java b/core/src/com/tdt4240/paint2win/utility/Vectors.java index 545347bdd8f9fa09f2e0e3b07a847a2b1d23a27e..8fd37c2d5df3d4d1e68d424a136013e8d66846e1 100644 --- a/core/src/com/tdt4240/paint2win/utility/Vectors.java +++ b/core/src/com/tdt4240/paint2win/utility/Vectors.java @@ -3,6 +3,10 @@ package com.tdt4240.paint2win.utility; import com.badlogic.gdx.math.Vector2; public class Vectors { + /** + * @param rotation + * @return a Vector2 pointed in a direction according to the rotation + */ public static Vector2 getDirectionVector(float rotation) { return new Vector2(-(float)Math.sin(Math.toRadians(rotation)), (float)Math.cos(Math.toRadians(rotation))); } diff --git a/core/src/com/tdt4240/paint2win/view/Animation.java b/core/src/com/tdt4240/paint2win/view/Animation.java deleted file mode 100644 index 25620c1bde423a061ba0a12912b12c9f7dcc04c7..0000000000000000000000000000000000000000 --- a/core/src/com/tdt4240/paint2win/view/Animation.java +++ /dev/null @@ -1,21 +0,0 @@ -package com.tdt4240.paint2win.view; - -import com.badlogic.gdx.graphics.g2d.TextureRegion; -import com.badlogic.gdx.utils.Array; - -public class Animation { - Array<TextureRegion> frames; - float maxFrameTime; - float currentFrameTime; - int frameCount; - int frame; - - public void update(){ - /* - updates the displaying texture - */ - } - public TextureRegion getFrame(){ return frames.get(frame);} - - -} diff --git a/core/src/com/tdt4240/paint2win/view/ContainerRenderer.java b/core/src/com/tdt4240/paint2win/view/ContainerRenderer.java index 72aa773a47bb1c5b1c72494f37e0c9372c4911b3..8b516478a84dd8a4583f43f56b7bdb559acfc826 100644 --- a/core/src/com/tdt4240/paint2win/view/ContainerRenderer.java +++ b/core/src/com/tdt4240/paint2win/view/ContainerRenderer.java @@ -1,7 +1,6 @@ package com.tdt4240.paint2win.view; import com.badlogic.gdx.graphics.g2d.SpriteBatch; -import com.badlogic.gdx.graphics.glutils.ShapeRenderer; import com.tdt4240.paint2win.container.IContainer; import java.util.Map; @@ -20,11 +19,20 @@ public class ContainerRenderer<T> implements IRenderer{ this.cache = cache; } + /** + * A generic renderer for the playerRenderer and visibleRenderer + * @param container + * @param rendererFactory + */ public ContainerRenderer(IContainer<T> container, Function<T, IRenderer> rendererFactory) { this(container, rendererFactory, new WeakHashMap<>()); } + /** + * Renders all container-objects if not already rendered + * @param sb + */ @Override public void render(SpriteBatch sb) { container.stream().forEach(thing -> cache diff --git a/core/src/com/tdt4240/paint2win/view/IRenderer.java b/core/src/com/tdt4240/paint2win/view/IRenderer.java index b64d3019a0ab98de8e37d1eb7760fb2ac5d1dd8f..68a12d5ebe35d1e8f5080f8281b0b1f6bc6cd476 100644 --- a/core/src/com/tdt4240/paint2win/view/IRenderer.java +++ b/core/src/com/tdt4240/paint2win/view/IRenderer.java @@ -5,7 +5,9 @@ import com.badlogic.gdx.graphics.glutils.ShapeRenderer; public interface IRenderer { + /** + * Should render objects to the spritebatch + * @param sb + */ void render(SpriteBatch sb); - //void render(ShapeRenderer shapeRenderer); - } diff --git a/core/src/com/tdt4240/paint2win/view/PlayerCamera.java b/core/src/com/tdt4240/paint2win/view/PlayerCamera.java index c23014bd86531b8b8c14c86f1a7f46c69cb01488..39c1752afa3f918ba681f024878b8ebc1a4fbaf3 100644 --- a/core/src/com/tdt4240/paint2win/view/PlayerCamera.java +++ b/core/src/com/tdt4240/paint2win/view/PlayerCamera.java @@ -7,11 +7,20 @@ import com.badlogic.gdx.graphics.OrthographicCamera; public class PlayerCamera { private final OrthographicCamera cam; + /** + * Creates a Camera + */ public PlayerCamera() { this.cam = new OrthographicCamera(); - cam.setToOrtho(false, Paint2Win.MAP_WIDTH,Paint2Win.MAP_HEIGHT); + cam.setToOrtho(false, Paint2Win.MAP_WIDTH/1.5f,Paint2Win.MAP_HEIGHT/1.5f); } + /** + * Updates the camera position and returns the updated camera + * @param x x-position + * @param y y-position + * @return Camera + */ public Camera updatedCamera(float x, float y){ cam.position.x = x; cam.position.y = y; @@ -19,8 +28,14 @@ public class PlayerCamera { return cam; } - public Camera getCamera(){ - return cam; + /** + * Resize when screen is resized + * @param width width of screen + * @param height height of screen + */ + public void resize(int width, int height) { + cam.viewportWidth=width; + cam.viewportHeight=height; + cam.update(); } - } diff --git a/core/src/com/tdt4240/paint2win/view/PlayerRenderer.java b/core/src/com/tdt4240/paint2win/view/PlayerRenderer.java index d94f7e7ab22a2df87bba7af0f05c9f17390fe4d9..7667631c21a94501933e7936cfee1a3c3e9dbe01 100644 --- a/core/src/com/tdt4240/paint2win/view/PlayerRenderer.java +++ b/core/src/com/tdt4240/paint2win/view/PlayerRenderer.java @@ -18,10 +18,20 @@ public class PlayerRenderer implements IRenderer{ this.cache = cache; } + /** + * Logic for rendering player. Remember that a players shooter can change and at times be unavailable. + * Needs a VisibleRenderer for current Shooter and renderers to hold on to previous shooters to be garbage collected. + * WeakHashMap will discard entries dedicated for Shooters that do not exist anymore. + * @param player + */ public PlayerRenderer(Player player) { this(player, new WeakHashMap<>()); } + /** + * Renders all existing shooters to the spritebatch + * @param sb + */ @Override public void render(SpriteBatch sb) { player.getShooter().ifPresent(shooter -> cache.computeIfAbsent(shooter, VisibleRenderer::new).render(sb)); diff --git a/core/src/com/tdt4240/paint2win/view/VisibleRenderer.java b/core/src/com/tdt4240/paint2win/view/VisibleRenderer.java index 2e27190b20d6321b70ddfbe14a299db693f5ae60..f8eba8d78280caf71e1731e4e9c0fbe0420a0118 100644 --- a/core/src/com/tdt4240/paint2win/view/VisibleRenderer.java +++ b/core/src/com/tdt4240/paint2win/view/VisibleRenderer.java @@ -1,16 +1,24 @@ package com.tdt4240.paint2win.view; import com.badlogic.gdx.graphics.g2d.SpriteBatch; -import com.badlogic.gdx.graphics.glutils.ShapeRenderer; import com.tdt4240.paint2win.model.IVisible; public class VisibleRenderer implements IRenderer{ private final IVisible visible; + /** + * Render every object/class that implements IVisible, + * as we can directly obtain all the information needed to render it directly from IVisible itself. + * @param visible + */ public VisibleRenderer(IVisible visible) { this.visible = visible; } + /** + * Draws all visible objects on spritebatch + * @param sb + */ @Override public void render(SpriteBatch sb) { visible.getSprite().draw(sb); diff --git a/docker-compose.yml b/docker-compose.yml new file mode 100644 index 0000000000000000000000000000000000000000..f97072773179b22f5fc1d4040184de31c22bf95f --- /dev/null +++ b/docker-compose.yml @@ -0,0 +1,8 @@ +version: "3.9" # optional since v1.27.0 +services: + db: + build: + context: ./ + dockerfile: ./Dockerfiles/Dockerfile-mysql + ports: + - "3306:3306" diff --git a/rest/.gitignore b/rest/.gitignore new file mode 100644 index 0000000000000000000000000000000000000000..42afabfd2abebf31384ca7797186a27a4b7dbee8 --- /dev/null +++ b/rest/.gitignore @@ -0,0 +1 @@ +/build \ No newline at end of file diff --git a/rest/assets/application.properties b/rest/assets/application.properties new file mode 100644 index 0000000000000000000000000000000000000000..6cd2a66f76f16e0b2bf8d823d5475cb2c6dd61fa --- /dev/null +++ b/rest/assets/application.properties @@ -0,0 +1,4 @@ +spring.datasource.url=jdbc:mysql://46.101.118.152:3306/paint2win +spring.datasource.username=player +spring.datasource.password=playerPass +spring.jpa.database-platform=org.hibernate.dialect.MySQL8Dialect \ No newline at end of file diff --git a/rest/build.gradle b/rest/build.gradle new file mode 100644 index 0000000000000000000000000000000000000000..4c6bc324eb63d17e4aaff0b69aae26eb3813bd7a --- /dev/null +++ b/rest/build.gradle @@ -0,0 +1,54 @@ +sourceCompatibility = 1.8 +sourceSets.main.java.srcDirs = [ "src/" ] +sourceSets.main.resources.srcDirs = ["./assets"] + +project.ext.mainClassName = "com.tdt4240.paint2win.rest.RESTApiServer" +project.ext.assetsDir = new File("./assets") + + +task run(dependsOn: classes, type: JavaExec) { + main = project.mainClassName + classpath = sourceSets.main.runtimeClasspath + standardInput = System.in + workingDir = project.assetsDir + ignoreExitValue = true +} + +task debug(dependsOn: classes, type: JavaExec) { + main = project.mainClassName + classpath = sourceSets.main.runtimeClasspath + standardInput = System.in + workingDir = project.assetsDir + ignoreExitValue = true + debug = true +} + +configurations { + extraLibs +} + +task dist(type: Jar) { + manifest { + attributes 'Main-Class': project.mainClassName + } + dependsOn configurations.runtimeClasspath + dependsOn configurations.extraLibs + from { + configurations.runtimeClasspath.collect { it.isDirectory() ? it : zipTree(it) } + } + with jar +} + + +dist.dependsOn classes + +eclipse.project.name = appName + "-rest" + +dependencies { + implementation 'org.springframework.boot:spring-boot-starter-data-jpa:2.4.5' + implementation 'org.springframework.boot:spring-boot-starter-web:2.4.5' + runtimeOnly 'mysql:mysql-connector-java:8.0.23' + testImplementation 'org.springframework.boot:spring-boot-starter-test:2.4.5' + configurations.extraLibs.extendsFrom(configurations.implementation) + configurations.extraLibs.extendsFrom(configurations.runtimeOnly) +} \ No newline at end of file diff --git a/rest/src/com/tdt4240/paint2win/rest/RESTApiServer.java b/rest/src/com/tdt4240/paint2win/rest/RESTApiServer.java new file mode 100644 index 0000000000000000000000000000000000000000..f16e2b97f7f152f63e8682c6ebe3bd5643d9681c --- /dev/null +++ b/rest/src/com/tdt4240/paint2win/rest/RESTApiServer.java @@ -0,0 +1,11 @@ +package com.tdt4240.paint2win.rest; + +import org.springframework.boot.SpringApplication; +import org.springframework.boot.autoconfigure.SpringBootApplication; + +@SpringBootApplication +public class RESTApiServer { + public static void main(String[] args) { + SpringApplication.run(RESTApiServer.class, args); + } +} \ No newline at end of file diff --git a/rest/src/com/tdt4240/paint2win/rest/controller/HighscoreEntryController.java b/rest/src/com/tdt4240/paint2win/rest/controller/HighscoreEntryController.java new file mode 100644 index 0000000000000000000000000000000000000000..5dd0fd472001403c0c48d84a302bacc6e87d34be --- /dev/null +++ b/rest/src/com/tdt4240/paint2win/rest/controller/HighscoreEntryController.java @@ -0,0 +1,103 @@ +package com.tdt4240.paint2win.rest.controller; + +import com.tdt4240.paint2win.rest.model.HighscoreEntry; +import com.tdt4240.paint2win.rest.service.HighscoreEntryService; + +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.http.HttpStatus; +import org.springframework.http.ResponseEntity; +import org.springframework.web.bind.annotation.*; + +import java.util.ArrayList; +import java.util.List; +import java.util.Map; +import java.util.stream.Collectors; + +@RestController +@RequestMapping("/highscores") +public class HighscoreEntryController { + @Autowired + HighscoreEntryService highscoreEntryService; + + /** + * GET top 10 results for a map + * @param mapName Map to get highscores from, "desert" or "urban". + * @return A sorted highscore list / top 10. + */ + @GetMapping("/{mapName}") + public List<HighscoreEntry> list(@PathVariable String mapName){ + return highscoreEntryService.highscoreList() + .stream() + .filter(entry -> entry.getMapName().equals(mapName.toUpperCase())) + .sorted((a, b) -> a.getTime() - b.getTime()) + .limit(10) + .collect(Collectors.toList()); + } + + /** + * POST new highscoreEntry to database + * @param highscoreEntry Entry of current attempt + * @return JSON-String "placement": $int:placementOfAttempt, "newPr": $bool:attemptIsNewPersonalBest" + */ + @PostMapping("/") + public ResponseEntity<?> add(@RequestBody HighscoreEntry highscoreEntry){ + List<HighscoreEntry> highscoreEntryList = highscoreEntryService.highscoreList(); + + // To compensate for delay in highscoreEntryService.updateHighScoreEntry, + // we create a local map, add the new entry, and then sort to find placement. + Map<String, HighscoreEntry> highscoreEntryMap = highscoreEntryList.stream() + .filter(entry -> entry.getMapName().equals(highscoreEntry.getMapName())) + .collect(Collectors.toMap(HighscoreEntry::getPlayerName, entry -> entry)); + + HighscoreEntry previousBest = highscoreEntryMap.get(highscoreEntry.getPlayerName()); + // Adding underscores will ensure that the key will be unique, as it is longer than + // the column length in the database. + // If it's stupid, but it works, then it ain't stupid. + highscoreEntryMap.put(highscoreEntry.getPlayerName() + "______________", highscoreEntry); + highscoreEntryList = new ArrayList<>(highscoreEntryMap.values()); + highscoreEntryList.sort((a, b)->a.getTime() - b.getTime()); + + int placement = highscoreEntryList.indexOf(highscoreEntry) + 1; + + boolean newPr = false; + + // IF new personal best OR first entry -> update score + if (previousBest == null || highscoreEntry.getTime() < previousBest.getTime()){ + highscoreEntryService.updateHighscoreEntry(highscoreEntry); + newPr = true; + } + + // @TODO: add newPr boolean + return new ResponseEntity<>("{\"placement\":" + placement + ", \"newPr\":" + newPr + "}", HttpStatus.OK); + } + + /** + * POST list of highscoreentries, used for populating database in development + * @param highscoreEntries List of entries to upload to insert to Database + * @return String with info about how many entries that were inserted. + */ + @PostMapping("/fill") + public ResponseEntity<?> add(@RequestBody List<HighscoreEntry> highscoreEntries){ + + highscoreEntries.forEach(entry -> { + highscoreEntryService.updateHighscoreEntry(entry); + }); + int entriesLength = highscoreEntries.size(); + + return new ResponseEntity<>("Added " + entriesLength + " entries.", HttpStatus.OK); + } + + /** + * DELETE all entries from database. FOR DEVELOPMENT ONLY. + * @return + */ + @DeleteMapping("/wipeDatabase") + public ResponseEntity<?> delete() { + highscoreEntryService.highscoreList().forEach(entry -> + { + highscoreEntryService.deleteHighscoreEntry(entry.getPlayerName()); + }); + return new ResponseEntity<>("Wiped database.", HttpStatus.OK); + } + +} diff --git a/rest/src/com/tdt4240/paint2win/rest/model/HighscoreEntry.java b/rest/src/com/tdt4240/paint2win/rest/model/HighscoreEntry.java new file mode 100644 index 0000000000000000000000000000000000000000..25c08bfe1cefcb5aa047d7e0730f7cd68fe721f6 --- /dev/null +++ b/rest/src/com/tdt4240/paint2win/rest/model/HighscoreEntry.java @@ -0,0 +1,58 @@ +package com.tdt4240.paint2win.rest.model; + +import javax.persistence.Entity; +import javax.persistence.Id; +import javax.persistence.Table; + +import com.tdt4240.paint2win.rest.utils.MapName; + + +@Entity +@Table(name = "highscores") +public class HighscoreEntry { + private String playerName; + private int time; + private String mapName; + + public HighscoreEntry(){ + + } + + public HighscoreEntry(String playerName, int time, String mapName){ + this.playerName = playerName; + this.time = time; + this.mapName = mapName; + } + + public HighscoreEntry(String playerName, int time, MapName mapName) { + this(playerName, time, mapName.toString()); + } + + @Id + public String getPlayerName() { + return playerName; + } + + public int getTime() { + return time; + } + + public void setPlayerName(String playerName) { + this.playerName = playerName; + } + + public void setTime(int time) { + this.time = time; + } + + public String getMapName() { + return this.mapName; + } + + public void setMapName(MapName mapName) { + this.mapName = mapName.toString(); + } + public void setMapName(String mapName) { + this.mapName = mapName; + } +} diff --git a/rest/src/com/tdt4240/paint2win/rest/repository/HighscoreEntryRepository.java b/rest/src/com/tdt4240/paint2win/rest/repository/HighscoreEntryRepository.java new file mode 100644 index 0000000000000000000000000000000000000000..8973e2df7d0ed86f870cfab8e9182ccc64862639 --- /dev/null +++ b/rest/src/com/tdt4240/paint2win/rest/repository/HighscoreEntryRepository.java @@ -0,0 +1,8 @@ +package com.tdt4240.paint2win.rest.repository; + +import com.tdt4240.paint2win.rest.model.HighscoreEntry; + +import org.springframework.data.jpa.repository.JpaRepository; + +public interface HighscoreEntryRepository extends JpaRepository<HighscoreEntry, String> { +} diff --git a/rest/src/com/tdt4240/paint2win/rest/service/HighscoreEntryService.java b/rest/src/com/tdt4240/paint2win/rest/service/HighscoreEntryService.java new file mode 100644 index 0000000000000000000000000000000000000000..e29b69b00f14f167858d7db54872e91990b18dbc --- /dev/null +++ b/rest/src/com/tdt4240/paint2win/rest/service/HighscoreEntryService.java @@ -0,0 +1,37 @@ +package com.tdt4240.paint2win.rest.service; + + +import com.tdt4240.paint2win.rest.model.HighscoreEntry; +import com.tdt4240.paint2win.rest.repository.HighscoreEntryRepository; + +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Service; +import org.springframework.transaction.annotation.Transactional; + +import java.util.List; + +@Service +@Transactional +public class HighscoreEntryService { + @Autowired + private HighscoreEntryRepository highscoreEntryRepository; + + public List<HighscoreEntry> highscoreList(){ + List<HighscoreEntry> highscoreEntries = highscoreEntryRepository.findAll(); + highscoreEntries.sort((a, b)-> a.getTime() - b.getTime()); + return highscoreEntries; + } + + public HighscoreEntry getHighscoreEntry(String playerName){ + return highscoreEntryRepository.findById(playerName).orElse(null); + } + + public void updateHighscoreEntry(HighscoreEntry highscoreEntry){ + highscoreEntryRepository.save(highscoreEntry); + } + + public void deleteHighscoreEntry(String playerName){ + highscoreEntryRepository.deleteById(playerName); + } + +} diff --git a/rest/src/com/tdt4240/paint2win/rest/utils/MapName.java b/rest/src/com/tdt4240/paint2win/rest/utils/MapName.java new file mode 100644 index 0000000000000000000000000000000000000000..8233051bf2af5088cc407bb2fc84a592e84507fb --- /dev/null +++ b/rest/src/com/tdt4240/paint2win/rest/utils/MapName.java @@ -0,0 +1,6 @@ +package com.tdt4240.paint2win.rest.utils; + +public enum MapName { + DESERT, + URBAN +} diff --git a/settings.gradle b/settings.gradle index 965b6a3a01179f9bcad6a74d8fa428ae2cd2e795..a5456d0b96b8f58c251ccd47ce8fbf3ea151cc4b 100644 --- a/settings.gradle +++ b/settings.gradle @@ -1 +1,2 @@ +include ':rest' include 'desktop', 'android', 'ios', 'html', 'core' \ No newline at end of file