├── .gitattributes ├── .gitignore ├── .gradle └── 2.4 │ └── taskArtifacts │ ├── cache.properties │ ├── cache.properties.lock │ ├── fileHashes.bin │ ├── outputFileStates.bin │ └── taskArtifacts.bin ├── .settings └── gradle │ ├── org.springsource.ide.eclipse.gradle.core.import.prefs │ └── org.springsource.ide.eclipse.gradle.core.prefs ├── README.md ├── bg-1.0.rar ├── build.gradle ├── core ├── .classpath ├── .project ├── .settings │ └── gradle │ │ ├── org.springsource.ide.eclipse.gradle.core.prefs │ │ └── org.springsource.ide.eclipse.gradle.refresh.prefs ├── assets │ ├── FinalScreen │ │ ├── wp1.png │ │ └── wp2.png │ ├── GameScreen │ │ ├── battle.mp3 │ │ ├── bg1.png │ │ ├── bg2.png │ │ ├── bg3.png │ │ ├── card.png │ │ ├── cbg1.png │ │ ├── health.png │ │ ├── indicator.png │ │ ├── legacy │ │ │ ├── bg1 - Copy.png │ │ │ ├── bg1.png │ │ │ ├── bg2.png │ │ │ ├── bg3.png │ │ │ ├── grid.png │ │ │ ├── p1-0.png │ │ │ └── temp.png │ │ ├── lose.wav │ │ ├── p1-0.png │ │ ├── p1-1-base.png │ │ ├── p1-1.png │ │ ├── p1-2.png │ │ ├── p1-3.png │ │ ├── p2-0.png │ │ ├── p2-1.png │ │ ├── p2-2.png │ │ ├── p2-3.png │ │ ├── shoot.wav │ │ ├── template.psd │ │ └── win.wav │ ├── General │ │ ├── background.png │ │ └── select.wav │ ├── SettingsScreen │ │ ├── wp1.png │ │ └── wp2.png │ ├── WelcomeScreen │ │ ├── template.psd │ │ ├── welcome.mp3 │ │ ├── wp1.png │ │ └── wp2.png │ └── tFrame.png ├── bin │ ├── BattleGrid.gwt.xml │ └── com │ │ └── battlegrid │ │ └── game │ │ ├── BattleAI.class │ │ ├── BattleGrid.class │ │ ├── Card.class │ │ ├── Deck.class │ │ ├── FadeInTransition.class │ │ ├── FadeOutTransition.class │ │ ├── FinalScreen.class │ │ ├── GameBoard.class │ │ ├── GameScreen.class │ │ ├── Player.class │ │ ├── ScreenshotFactory.class │ │ ├── SettingsScreen.class │ │ └── WelcomeScreen.class ├── build.gradle └── src │ ├── BattleGrid.gwt.xml │ └── com │ └── battlegrid │ └── game │ ├── BattleAI.java │ ├── BattleGrid.java │ ├── Card.java │ ├── Deck.java │ ├── FadeInTransition.java │ ├── FadeOutTransition.java │ ├── FinalScreen.java │ ├── GameBoard.java │ ├── GameScreen.java │ ├── Player.java │ ├── ScreenshotFactory.java │ ├── SettingsScreen.java │ └── WelcomeScreen.java ├── desktop ├── .classpath ├── .project ├── .settings │ └── gradle │ │ ├── org.springsource.ide.eclipse.gradle.core.prefs │ │ └── org.springsource.ide.eclipse.gradle.refresh.prefs ├── bin │ └── com │ │ └── battlegrid │ │ └── game │ │ └── desktop │ │ └── DesktopLauncher.class ├── build.gradle └── src │ └── com │ └── battlegrid │ └── game │ └── desktop │ └── DesktopLauncher.java ├── gradle.properties ├── gradle └── wrapper │ ├── gradle-wrapper.jar │ └── gradle-wrapper.properties ├── gradlew ├── gradlew.bat ├── html └── .settings │ └── gradle │ └── org.springsource.ide.eclipse.gradle.core.prefs └── settings.gradle /.gitattributes: -------------------------------------------------------------------------------- 1 | # Auto detect text files and perform LF normalization 2 | * text=auto 3 | 4 | # Custom for Visual Studio 5 | *.cs diff=csharp 6 | 7 | # Standard to msysgit 8 | *.doc diff=astextplain 9 | *.DOC diff=astextplain 10 | *.docx diff=astextplain 11 | *.DOCX diff=astextplain 12 | *.dot diff=astextplain 13 | *.DOT diff=astextplain 14 | *.pdf diff=astextplain 15 | *.PDF diff=astextplain 16 | *.rtf diff=astextplain 17 | *.RTF diff=astextplain 18 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | # Windows image file caches 2 | Thumbs.db 3 | ehthumbs.db 4 | 5 | # Folder config file 6 | Desktop.ini 7 | 8 | # Recycle Bin used on file shares 9 | $RECYCLE.BIN/ 10 | 11 | # Windows Installer files 12 | *.cab 13 | *.msi 14 | *.msm 15 | *.msp 16 | 17 | # Windows shortcuts 18 | *.lnk 19 | 20 | # ========================= 21 | # Operating System Files 22 | # ========================= 23 | 24 | # OSX 25 | # ========================= 26 | 27 | .DS_Store 28 | .AppleDouble 29 | .LSOverride 30 | 31 | # Thumbnails 32 | ._* 33 | 34 | # Files that might appear on external disk 35 | .Spotlight-V100 36 | .Trashes 37 | 38 | # Directories potentially created on remote AFP share 39 | .AppleDB 40 | .AppleDesktop 41 | Network Trash Folder 42 | Temporary Items 43 | .apdisk 44 | -------------------------------------------------------------------------------- /.gradle/2.4/taskArtifacts/cache.properties: -------------------------------------------------------------------------------- 1 | #Thu Nov 12 23:56:40 PST 2015 2 | -------------------------------------------------------------------------------- /.gradle/2.4/taskArtifacts/cache.properties.lock: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/and1hof/BattleGrid-Prototype/b42fa8457113953e4ecd7a7cd96e93a52c4e1865/.gradle/2.4/taskArtifacts/cache.properties.lock -------------------------------------------------------------------------------- /.gradle/2.4/taskArtifacts/fileHashes.bin: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/and1hof/BattleGrid-Prototype/b42fa8457113953e4ecd7a7cd96e93a52c4e1865/.gradle/2.4/taskArtifacts/fileHashes.bin -------------------------------------------------------------------------------- /.gradle/2.4/taskArtifacts/outputFileStates.bin: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/and1hof/BattleGrid-Prototype/b42fa8457113953e4ecd7a7cd96e93a52c4e1865/.gradle/2.4/taskArtifacts/outputFileStates.bin -------------------------------------------------------------------------------- /.gradle/2.4/taskArtifacts/taskArtifacts.bin: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/and1hof/BattleGrid-Prototype/b42fa8457113953e4ecd7a7cd96e93a52c4e1865/.gradle/2.4/taskArtifacts/taskArtifacts.bin -------------------------------------------------------------------------------- /.settings/gradle/org.springsource.ide.eclipse.gradle.core.import.prefs: -------------------------------------------------------------------------------- 1 | #org.springsource.ide.eclipse.gradle.core.preferences.GradleImportPreferences 2 | #Sat Nov 14 18:08:23 PST 2015 3 | addResourceFilters=true 4 | afterTasks=afterEclipseImport; 5 | beforeTasks=cleanEclipse;eclipse; 6 | enableAfterTasks=false 7 | enableBeforeTasks=false 8 | enableDependendencyManagement=true 9 | projects=core;desktop; 10 | -------------------------------------------------------------------------------- /.settings/gradle/org.springsource.ide.eclipse.gradle.core.prefs: -------------------------------------------------------------------------------- 1 | #org.springsource.ide.eclipse.gradle.core.preferences.GradleProjectPreferences 2 | #Wed Nov 11 10:53:36 PST 2015 3 | build.family.org.gradle.tooling.model.eclipse.HierarchicalEclipseProject=;core;desktop;html; 4 | org.springsource.ide.eclipse.gradle.rootprojectloc= 5 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # IMPORTANT! 2 | This was a prototype I built in about a day. 3 | I am working on a more modular game engine to accomplish the same gameplay style. 4 | Feel free to use this project as inspiration, or contact me if you are familiar with LibGDX / Networking or spriting and want to work on a larger-scale project with similar inspirations. 5 | 6 | # BattleGrid 7 | A clone of "Megaman Battle Network", a TGC/TPS/RTS hybrid released in the early 2000's. 8 | 9 | ### PREREQUISITES 10 | - Java 7+ 11 | - OpenGL 12 | - 512MB RAM 13 | 14 | ### GETTING STARTED 15 | Download the "bg-1.0.rar" file, unzip the folder and double click the "bg-1.0.jar" file. 16 | 17 | ### HOW TO PLAY 18 | 1. Click anywhere on welcome screen to start a match 19 | 2. Select your difficulty level (AI) 20 | 3. Select your hand order. Water -> Elec & Grass -> Fire = 2x damage. 21 | 4. Navigate grid, attacking and dodging. 22 | 5. Redraw a new hand every 15 seconds, a max of 6 times. 23 | 6. Win if AI hp reaches 0. 24 | 7. Lose if your HP reaches 0, or you draw 6 times (no more cards in deck). 25 | 26 | ### WHATS IMPLEMENTED 27 | - Player Controller 28 | - Basic AI Controllers 29 | - Game Board 30 | - UI 31 | - Basic Graphics & Animations 32 | 33 | ### TODO 34 | - Refactor code for added modularity (so more enemies can be implemented) 35 | - Refactor game board into "tiles" rather than one game board (so we can implement alternative tiles, ex. ice) 36 | - Improve heuristics algorithm for AI 37 | - Implement Megaman Battle Network Sprites & Animations 38 | - Bullet projectiles instead of hitscan 39 | - Implement actual MMBN assets rather than generic Megaman Assets (they are all spritesheets) 40 | 41 | ### CONTRIBUTE 42 | If you think you can improve the game, engine or graphics please feel free to make a branch followed by a pull request! 43 | 44 | ### SOURCES 45 | - Player & AI: Old Megaman sprites (CAPCOM) 46 | - Music: Megaman Battle Network (CAPCOM) 47 | - Background Screens: Assorted Megaman Sprites Edited into BG tiles (CAPCOM) 48 | 49 | ### LEGAL 50 | This is an in-progress open-source FAN GAME, not to be released commercially for profit. 51 | 52 | ### SCREENSHOTS 53 | ![Welcome Screen](http://i.imgur.com/52oushd.png) 54 | ![Difficulty](http://i.imgur.com/vCgPQ7g.png) 55 | ![Draw Phase](http://i.imgur.com/OC0kYB6.png) 56 | ![Battle Phase](http://i.imgur.com/Wbye5sZ.png) 57 | ![Game Over](http://i.imgur.com/5v4yD6V.png) 58 | -------------------------------------------------------------------------------- /bg-1.0.rar: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/and1hof/BattleGrid-Prototype/b42fa8457113953e4ecd7a7cd96e93a52c4e1865/bg-1.0.rar -------------------------------------------------------------------------------- /build.gradle: -------------------------------------------------------------------------------- 1 | buildscript { 2 | repositories { 3 | mavenCentral() 4 | maven { url "https://oss.sonatype.org/content/repositories/snapshots/" } 5 | jcenter() 6 | } 7 | dependencies { 8 | classpath 'de.richsource.gradle.plugins:gwt-gradle-plugin:0.6' 9 | } 10 | } 11 | 12 | allprojects { 13 | apply plugin: "eclipse" 14 | apply plugin: "idea" 15 | 16 | version = '1.0' 17 | ext { 18 | appName = "BattleGrid" 19 | gdxVersion = '1.7.0' 20 | roboVMVersion = '1.8.0' 21 | box2DLightsVersion = '1.4' 22 | ashleyVersion = '1.6.0' 23 | aiVersion = '1.6.0' 24 | } 25 | 26 | repositories { 27 | mavenCentral() 28 | maven { url "https://oss.sonatype.org/content/repositories/snapshots/" } 29 | maven { url "https://oss.sonatype.org/content/repositories/releases/" } 30 | } 31 | } 32 | 33 | project(":desktop") { 34 | apply plugin: "java" 35 | 36 | 37 | dependencies { 38 | compile project(":core") 39 | compile "com.badlogicgames.gdx:gdx-backend-lwjgl:$gdxVersion" 40 | compile "com.badlogicgames.gdx:gdx-platform:$gdxVersion:natives-desktop" 41 | compile "com.badlogicgames.gdx:gdx-box2d-platform:$gdxVersion:natives-desktop" 42 | compile "com.badlogicgames.gdx:gdx-tools:$gdxVersion" 43 | } 44 | } 45 | 46 | project(":html") { 47 | apply plugin: "gwt" 48 | apply plugin: "war" 49 | 50 | 51 | dependencies { 52 | compile project(":core") 53 | compile "com.badlogicgames.gdx:gdx-backend-gwt:$gdxVersion" 54 | compile "com.badlogicgames.gdx:gdx:$gdxVersion:sources" 55 | compile "com.badlogicgames.gdx:gdx-backend-gwt:$gdxVersion:sources" 56 | compile "com.badlogicgames.gdx:gdx-box2d:$gdxVersion:sources" 57 | compile "com.badlogicgames.gdx:gdx-box2d-gwt:$gdxVersion:sources" 58 | } 59 | } 60 | 61 | project(":core") { 62 | apply plugin: "java" 63 | 64 | 65 | dependencies { 66 | compile "com.badlogicgames.gdx:gdx:$gdxVersion" 67 | compile "com.badlogicgames.gdx:gdx-box2d:$gdxVersion" 68 | } 69 | } 70 | 71 | tasks.eclipse.doLast { 72 | delete ".project" 73 | } -------------------------------------------------------------------------------- /core/.classpath: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /core/.project: -------------------------------------------------------------------------------- 1 | 2 | 3 | BattleGrid-core 4 | 5 | 6 | 7 | 8 | 9 | org.eclipse.jdt.core.javabuilder 10 | 11 | 12 | 13 | 14 | 15 | org.springsource.ide.eclipse.gradle.core.nature 16 | org.eclipse.jdt.core.javanature 17 | 18 | 19 | -------------------------------------------------------------------------------- /core/.settings/gradle/org.springsource.ide.eclipse.gradle.core.prefs: -------------------------------------------------------------------------------- 1 | #org.springsource.ide.eclipse.gradle.core.preferences.GradleProjectPreferences 2 | #Wed Nov 11 10:53:46 PST 2015 3 | org.springsource.ide.eclipse.gradle.linkedresources= 4 | org.springsource.ide.eclipse.gradle.rootprojectloc=.. 5 | -------------------------------------------------------------------------------- /core/.settings/gradle/org.springsource.ide.eclipse.gradle.refresh.prefs: -------------------------------------------------------------------------------- 1 | #org.springsource.ide.eclipse.gradle.core.actions.GradleRefreshPreferences 2 | #Wed Nov 11 10:53:45 PST 2015 3 | addResourceFilters=true 4 | afterTasks=afterEclipseImport; 5 | beforeTasks=cleanEclipse;eclipse; 6 | enableAfterTasks=false 7 | enableBeforeTasks=false 8 | useHierarchicalNames=false 9 | -------------------------------------------------------------------------------- /core/assets/FinalScreen/wp1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/and1hof/BattleGrid-Prototype/b42fa8457113953e4ecd7a7cd96e93a52c4e1865/core/assets/FinalScreen/wp1.png -------------------------------------------------------------------------------- /core/assets/FinalScreen/wp2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/and1hof/BattleGrid-Prototype/b42fa8457113953e4ecd7a7cd96e93a52c4e1865/core/assets/FinalScreen/wp2.png -------------------------------------------------------------------------------- /core/assets/GameScreen/battle.mp3: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/and1hof/BattleGrid-Prototype/b42fa8457113953e4ecd7a7cd96e93a52c4e1865/core/assets/GameScreen/battle.mp3 -------------------------------------------------------------------------------- /core/assets/GameScreen/bg1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/and1hof/BattleGrid-Prototype/b42fa8457113953e4ecd7a7cd96e93a52c4e1865/core/assets/GameScreen/bg1.png -------------------------------------------------------------------------------- /core/assets/GameScreen/bg2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/and1hof/BattleGrid-Prototype/b42fa8457113953e4ecd7a7cd96e93a52c4e1865/core/assets/GameScreen/bg2.png -------------------------------------------------------------------------------- /core/assets/GameScreen/bg3.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/and1hof/BattleGrid-Prototype/b42fa8457113953e4ecd7a7cd96e93a52c4e1865/core/assets/GameScreen/bg3.png -------------------------------------------------------------------------------- /core/assets/GameScreen/card.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/and1hof/BattleGrid-Prototype/b42fa8457113953e4ecd7a7cd96e93a52c4e1865/core/assets/GameScreen/card.png -------------------------------------------------------------------------------- /core/assets/GameScreen/cbg1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/and1hof/BattleGrid-Prototype/b42fa8457113953e4ecd7a7cd96e93a52c4e1865/core/assets/GameScreen/cbg1.png -------------------------------------------------------------------------------- /core/assets/GameScreen/health.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/and1hof/BattleGrid-Prototype/b42fa8457113953e4ecd7a7cd96e93a52c4e1865/core/assets/GameScreen/health.png -------------------------------------------------------------------------------- /core/assets/GameScreen/indicator.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/and1hof/BattleGrid-Prototype/b42fa8457113953e4ecd7a7cd96e93a52c4e1865/core/assets/GameScreen/indicator.png -------------------------------------------------------------------------------- /core/assets/GameScreen/legacy/bg1 - Copy.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/and1hof/BattleGrid-Prototype/b42fa8457113953e4ecd7a7cd96e93a52c4e1865/core/assets/GameScreen/legacy/bg1 - Copy.png -------------------------------------------------------------------------------- /core/assets/GameScreen/legacy/bg1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/and1hof/BattleGrid-Prototype/b42fa8457113953e4ecd7a7cd96e93a52c4e1865/core/assets/GameScreen/legacy/bg1.png -------------------------------------------------------------------------------- /core/assets/GameScreen/legacy/bg2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/and1hof/BattleGrid-Prototype/b42fa8457113953e4ecd7a7cd96e93a52c4e1865/core/assets/GameScreen/legacy/bg2.png -------------------------------------------------------------------------------- /core/assets/GameScreen/legacy/bg3.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/and1hof/BattleGrid-Prototype/b42fa8457113953e4ecd7a7cd96e93a52c4e1865/core/assets/GameScreen/legacy/bg3.png -------------------------------------------------------------------------------- /core/assets/GameScreen/legacy/grid.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/and1hof/BattleGrid-Prototype/b42fa8457113953e4ecd7a7cd96e93a52c4e1865/core/assets/GameScreen/legacy/grid.png -------------------------------------------------------------------------------- /core/assets/GameScreen/legacy/p1-0.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/and1hof/BattleGrid-Prototype/b42fa8457113953e4ecd7a7cd96e93a52c4e1865/core/assets/GameScreen/legacy/p1-0.png -------------------------------------------------------------------------------- /core/assets/GameScreen/legacy/temp.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/and1hof/BattleGrid-Prototype/b42fa8457113953e4ecd7a7cd96e93a52c4e1865/core/assets/GameScreen/legacy/temp.png -------------------------------------------------------------------------------- /core/assets/GameScreen/lose.wav: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/and1hof/BattleGrid-Prototype/b42fa8457113953e4ecd7a7cd96e93a52c4e1865/core/assets/GameScreen/lose.wav -------------------------------------------------------------------------------- /core/assets/GameScreen/p1-0.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/and1hof/BattleGrid-Prototype/b42fa8457113953e4ecd7a7cd96e93a52c4e1865/core/assets/GameScreen/p1-0.png -------------------------------------------------------------------------------- /core/assets/GameScreen/p1-1-base.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/and1hof/BattleGrid-Prototype/b42fa8457113953e4ecd7a7cd96e93a52c4e1865/core/assets/GameScreen/p1-1-base.png -------------------------------------------------------------------------------- /core/assets/GameScreen/p1-1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/and1hof/BattleGrid-Prototype/b42fa8457113953e4ecd7a7cd96e93a52c4e1865/core/assets/GameScreen/p1-1.png -------------------------------------------------------------------------------- /core/assets/GameScreen/p1-2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/and1hof/BattleGrid-Prototype/b42fa8457113953e4ecd7a7cd96e93a52c4e1865/core/assets/GameScreen/p1-2.png -------------------------------------------------------------------------------- /core/assets/GameScreen/p1-3.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/and1hof/BattleGrid-Prototype/b42fa8457113953e4ecd7a7cd96e93a52c4e1865/core/assets/GameScreen/p1-3.png -------------------------------------------------------------------------------- /core/assets/GameScreen/p2-0.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/and1hof/BattleGrid-Prototype/b42fa8457113953e4ecd7a7cd96e93a52c4e1865/core/assets/GameScreen/p2-0.png -------------------------------------------------------------------------------- /core/assets/GameScreen/p2-1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/and1hof/BattleGrid-Prototype/b42fa8457113953e4ecd7a7cd96e93a52c4e1865/core/assets/GameScreen/p2-1.png -------------------------------------------------------------------------------- /core/assets/GameScreen/p2-2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/and1hof/BattleGrid-Prototype/b42fa8457113953e4ecd7a7cd96e93a52c4e1865/core/assets/GameScreen/p2-2.png -------------------------------------------------------------------------------- /core/assets/GameScreen/p2-3.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/and1hof/BattleGrid-Prototype/b42fa8457113953e4ecd7a7cd96e93a52c4e1865/core/assets/GameScreen/p2-3.png -------------------------------------------------------------------------------- /core/assets/GameScreen/shoot.wav: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/and1hof/BattleGrid-Prototype/b42fa8457113953e4ecd7a7cd96e93a52c4e1865/core/assets/GameScreen/shoot.wav -------------------------------------------------------------------------------- /core/assets/GameScreen/template.psd: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/and1hof/BattleGrid-Prototype/b42fa8457113953e4ecd7a7cd96e93a52c4e1865/core/assets/GameScreen/template.psd -------------------------------------------------------------------------------- /core/assets/GameScreen/win.wav: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/and1hof/BattleGrid-Prototype/b42fa8457113953e4ecd7a7cd96e93a52c4e1865/core/assets/GameScreen/win.wav -------------------------------------------------------------------------------- /core/assets/General/background.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/and1hof/BattleGrid-Prototype/b42fa8457113953e4ecd7a7cd96e93a52c4e1865/core/assets/General/background.png -------------------------------------------------------------------------------- /core/assets/General/select.wav: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/and1hof/BattleGrid-Prototype/b42fa8457113953e4ecd7a7cd96e93a52c4e1865/core/assets/General/select.wav -------------------------------------------------------------------------------- /core/assets/SettingsScreen/wp1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/and1hof/BattleGrid-Prototype/b42fa8457113953e4ecd7a7cd96e93a52c4e1865/core/assets/SettingsScreen/wp1.png -------------------------------------------------------------------------------- /core/assets/SettingsScreen/wp2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/and1hof/BattleGrid-Prototype/b42fa8457113953e4ecd7a7cd96e93a52c4e1865/core/assets/SettingsScreen/wp2.png -------------------------------------------------------------------------------- /core/assets/WelcomeScreen/template.psd: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/and1hof/BattleGrid-Prototype/b42fa8457113953e4ecd7a7cd96e93a52c4e1865/core/assets/WelcomeScreen/template.psd -------------------------------------------------------------------------------- /core/assets/WelcomeScreen/welcome.mp3: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/and1hof/BattleGrid-Prototype/b42fa8457113953e4ecd7a7cd96e93a52c4e1865/core/assets/WelcomeScreen/welcome.mp3 -------------------------------------------------------------------------------- /core/assets/WelcomeScreen/wp1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/and1hof/BattleGrid-Prototype/b42fa8457113953e4ecd7a7cd96e93a52c4e1865/core/assets/WelcomeScreen/wp1.png -------------------------------------------------------------------------------- /core/assets/WelcomeScreen/wp2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/and1hof/BattleGrid-Prototype/b42fa8457113953e4ecd7a7cd96e93a52c4e1865/core/assets/WelcomeScreen/wp2.png -------------------------------------------------------------------------------- /core/assets/tFrame.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/and1hof/BattleGrid-Prototype/b42fa8457113953e4ecd7a7cd96e93a52c4e1865/core/assets/tFrame.png -------------------------------------------------------------------------------- /core/bin/BattleGrid.gwt.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | -------------------------------------------------------------------------------- /core/bin/com/battlegrid/game/BattleAI.class: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/and1hof/BattleGrid-Prototype/b42fa8457113953e4ecd7a7cd96e93a52c4e1865/core/bin/com/battlegrid/game/BattleAI.class -------------------------------------------------------------------------------- /core/bin/com/battlegrid/game/BattleGrid.class: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/and1hof/BattleGrid-Prototype/b42fa8457113953e4ecd7a7cd96e93a52c4e1865/core/bin/com/battlegrid/game/BattleGrid.class -------------------------------------------------------------------------------- /core/bin/com/battlegrid/game/Card.class: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/and1hof/BattleGrid-Prototype/b42fa8457113953e4ecd7a7cd96e93a52c4e1865/core/bin/com/battlegrid/game/Card.class -------------------------------------------------------------------------------- /core/bin/com/battlegrid/game/Deck.class: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/and1hof/BattleGrid-Prototype/b42fa8457113953e4ecd7a7cd96e93a52c4e1865/core/bin/com/battlegrid/game/Deck.class -------------------------------------------------------------------------------- /core/bin/com/battlegrid/game/FadeInTransition.class: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/and1hof/BattleGrid-Prototype/b42fa8457113953e4ecd7a7cd96e93a52c4e1865/core/bin/com/battlegrid/game/FadeInTransition.class -------------------------------------------------------------------------------- /core/bin/com/battlegrid/game/FadeOutTransition.class: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/and1hof/BattleGrid-Prototype/b42fa8457113953e4ecd7a7cd96e93a52c4e1865/core/bin/com/battlegrid/game/FadeOutTransition.class -------------------------------------------------------------------------------- /core/bin/com/battlegrid/game/FinalScreen.class: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/and1hof/BattleGrid-Prototype/b42fa8457113953e4ecd7a7cd96e93a52c4e1865/core/bin/com/battlegrid/game/FinalScreen.class -------------------------------------------------------------------------------- /core/bin/com/battlegrid/game/GameBoard.class: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/and1hof/BattleGrid-Prototype/b42fa8457113953e4ecd7a7cd96e93a52c4e1865/core/bin/com/battlegrid/game/GameBoard.class -------------------------------------------------------------------------------- /core/bin/com/battlegrid/game/GameScreen.class: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/and1hof/BattleGrid-Prototype/b42fa8457113953e4ecd7a7cd96e93a52c4e1865/core/bin/com/battlegrid/game/GameScreen.class -------------------------------------------------------------------------------- /core/bin/com/battlegrid/game/Player.class: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/and1hof/BattleGrid-Prototype/b42fa8457113953e4ecd7a7cd96e93a52c4e1865/core/bin/com/battlegrid/game/Player.class -------------------------------------------------------------------------------- /core/bin/com/battlegrid/game/ScreenshotFactory.class: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/and1hof/BattleGrid-Prototype/b42fa8457113953e4ecd7a7cd96e93a52c4e1865/core/bin/com/battlegrid/game/ScreenshotFactory.class -------------------------------------------------------------------------------- /core/bin/com/battlegrid/game/SettingsScreen.class: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/and1hof/BattleGrid-Prototype/b42fa8457113953e4ecd7a7cd96e93a52c4e1865/core/bin/com/battlegrid/game/SettingsScreen.class -------------------------------------------------------------------------------- /core/bin/com/battlegrid/game/WelcomeScreen.class: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/and1hof/BattleGrid-Prototype/b42fa8457113953e4ecd7a7cd96e93a52c4e1865/core/bin/com/battlegrid/game/WelcomeScreen.class -------------------------------------------------------------------------------- /core/build.gradle: -------------------------------------------------------------------------------- 1 | apply plugin: "java" 2 | 3 | sourceCompatibility = 1.6 4 | [compileJava, compileTestJava]*.options*.encoding = 'UTF-8' 5 | 6 | sourceSets.main.java.srcDirs = [ "src/" ] 7 | 8 | 9 | eclipse.project { 10 | name = appName + "-core" 11 | } 12 | -------------------------------------------------------------------------------- /core/src/BattleGrid.gwt.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | -------------------------------------------------------------------------------- /core/src/com/battlegrid/game/BattleAI.java: -------------------------------------------------------------------------------- 1 | package com.battlegrid.game; 2 | 3 | import java.awt.Point; 4 | import java.util.ArrayList; 5 | import java.util.Collections; 6 | import java.util.Random; 7 | 8 | import com.badlogic.gdx.Gdx; 9 | import com.badlogic.gdx.audio.Sound; 10 | import com.badlogic.gdx.utils.TimeUtils; 11 | 12 | /* 13 | * This AI class controls the AI player. 14 | * There are three agents, each based on a a difficulty from 1-3. However, there is 15 | * room to implement harder (or easier) agents in the future. 16 | */ 17 | public class BattleAI { 18 | Player p2; 19 | int difficulty; 20 | GameBoard myBoard; 21 | private long step; 22 | private long time; 23 | Sound shootSound; 24 | Player p1; 25 | Point moveLog; 26 | int moveCount = 0; 27 | 28 | /* 29 | * The AI is a player object with extra control over what he does. 30 | * As a result, the AI needs to manage some extra variables. 31 | */ 32 | public BattleAI(Player thePlayer1, Player thePlayer2, int theD, GameBoard theBoard) { 33 | p1 = thePlayer1; 34 | p2 = thePlayer2; 35 | difficulty = theD; 36 | myBoard = theBoard; 37 | moveLog = new Point(); 38 | time = 0; 39 | shootSound = Gdx.audio.newSound(Gdx.files.internal("GameScreen/shoot.wav")); 40 | config(difficulty); 41 | } 42 | 43 | /* 44 | * I found that the most valuable heuristic to simulate a stronger AI agent 45 | * while keeping the AI looking "human-like" was to increase the speed at which the AI makes choices. 46 | * The step variable determines the rate at which the AI makes a new choice, in milliseconds. 47 | */ 48 | private void config(int d) { 49 | if (difficulty == 4) { 50 | step = 350; 51 | } else if (difficulty > 0) { 52 | step = 500; 53 | } else { 54 | step = 750; 55 | } 56 | } 57 | 58 | /* 59 | * For the draw phase of the game, the weakest agent pulls random cards. 60 | * Other agents perform maximization on all available cards, taking into account debuffs on the enemy, 61 | * card elements / bonus damage multipliers and card damage. This results in a optimal card order in terms 62 | * of potential damage output. 63 | */ 64 | public void draw() { 65 | p2.draw(); 66 | for (int i = 0; i < p2.random.size(); i++) { 67 | p2.myHand.add(p2.random.get(i)); 68 | } 69 | 70 | if (difficulty > 0) { 71 | p2.myHand = cardMax(p2.myHand); 72 | // pull optimal order rather than random 73 | } 74 | p2.random = new ArrayList(); // reset it 75 | 76 | } 77 | 78 | /* 79 | * Perform one "step", or choice. A step represents each time the AI thinks about what to do next. 80 | */ 81 | private void step() { 82 | time = TimeUtils.millis(); 83 | } 84 | 85 | /* 86 | * The think method just handles steps for agents, and ensures enough time has passed 87 | * for the agent to think about a move again. 88 | */ 89 | public void think(int theState) { 90 | if (TimeUtils.timeSinceMillis(time) > step && theState == 1) { 91 | // see if enough time has passed since last move 92 | // use agent of correct difficulty level 93 | if (difficulty == 0) { 94 | agentZero(); 95 | } else if (difficulty > 0 && difficulty < 4) { 96 | agentOne(); 97 | } else { 98 | agentTwo(); 99 | } 100 | step(); 101 | } 102 | } 103 | 104 | /* 105 | * A random agent for beginners. 106 | */ 107 | public void agentZero() { 108 | ArrayList moves = myBoard.moves(false, myBoard.clone()); 109 | Random r = new Random(); 110 | int r1 = r.nextInt(moves.size()); 111 | int r2 = r.nextInt(10); 112 | if (r2 > 7) { 113 | attack(); 114 | } else { 115 | myBoard.move(moves.get(r1), p2); // move 116 | animator(moves.get(r1)); 117 | } 118 | } 119 | 120 | /* 121 | * The intermediate agent performs maximization (similar to minimax) over 122 | * all cards during draw phase. As a result, he chooses an optimal pick order. 123 | * 124 | * He also has a moderate step speed, so he thinks pretty frequently. He will always attack first if possible, 125 | * and after that he requests the utility function to determine optimal movements. 126 | */ 127 | public void agentOne() { 128 | int[][] state = myBoard.clone(); 129 | ArrayList moves = myBoard.moves(false, deepClone(state)); 130 | int max = -1000; 131 | int move = moves.get(0); 132 | boolean attack = false; 133 | // attack first. 134 | if (p2.myHand.size() > 0) { 135 | Card next = p2.myHand.get(0); 136 | Point me = myBoard.findPlayer(false, state); 137 | Point them = myBoard.findPlayer(true, state); 138 | if (me.y == them.y && (me.x - them.x) <= next.range) { 139 | attack(); 140 | attack = true; 141 | } 142 | } 143 | for (int i = 0; i < moves.size(); i++) { 144 | int[][] nextState = predictState(false, deepClone(state), moves.get(i)); 145 | 146 | int temp = moveUtility(deepClone(nextState)); // calculate only this 147 | // turn. 148 | if (temp > max) { 149 | max = temp; 150 | move = moves.get(i); 151 | } 152 | } 153 | if (!attack) { 154 | Point temp = (Point) myBoard.findPlayer(false, myBoard.clone()).clone(); 155 | moveLog.x = temp.x; // record the choice 156 | moveLog.y = temp.y; 157 | myBoard.move(move, p2); 158 | animator(move); 159 | } 160 | 161 | } 162 | 163 | /* 164 | * This agent is the most difficult one, and is pretty tough. 165 | * In addition to validating his moves using the utility function 166 | * and performing maximization on card order, he has a faster movement speed 167 | * resulting in him being able to unload combos quite fast. He also has some added 168 | * features like wasting cards if the enemy is refusing to go in range to be hit. This 169 | * prevents him from being locked out of combat if he gets a sequence of 1 range draws while the enemy 170 | * (player) keeps getting 2-3 range draws. 171 | * 172 | * I built an alpha-beta pruning minimax so he could look several moves ahead, 173 | * but he ends up acting like a robot since the human never plays optimally. 174 | * He jumps between two or so squares, and it isn't much fun to play against. 175 | * I learned that in games like this, detailed heuristics provide a much better experience for 176 | * the player. 177 | */ 178 | public void agentTwo() { 179 | int[][] state = myBoard.clone(); 180 | ArrayList moves = myBoard.moves(false, deepClone(state)); 181 | int max = -1000; 182 | int move = moves.get(0); 183 | boolean attack = false; 184 | // attack first. 185 | if (p2.myHand.size() > 0) { 186 | Card next = p2.myHand.get(0); 187 | Point me = myBoard.findPlayer(false, state); 188 | Point them = myBoard.findPlayer(true, state); 189 | if (me.y == them.y && (me.x - them.x) <= next.range) { 190 | attack(); 191 | attack = true; 192 | } else if (next.range < 3) { 193 | moveCount++; 194 | 195 | if (moveCount % 15 == 0) { 196 | // waste low range cards if x seconds pass 197 | attack(); 198 | attack = true; 199 | moveCount = 0; 200 | } 201 | } 202 | } 203 | for (int i = 0; i < moves.size(); i++) { 204 | int[][] nextState = predictState(false, deepClone(state), moves.get(i)); 205 | int temp = moveUtility(deepClone(nextState)); 206 | if (temp > max) { 207 | max = temp; 208 | move = moves.get(i); 209 | } 210 | } 211 | if (!attack) { 212 | Point temp = (Point) myBoard.findPlayer(false, myBoard.clone()).clone(); 213 | moveLog.x = temp.x; // record the choice 214 | moveLog.y = temp.y; 215 | 216 | myBoard.move(move, p2); 217 | animator(move); 218 | } 219 | 220 | } 221 | 222 | /* 223 | * This is a minimax algorithm with alpha beta pruning that allows you to look several 224 | * game boards ahead. Unfortunately, it doesn't provide a very human-seeming AI because 225 | * this is not a game which is easily evaluated based on numbers. Using this algorithm, 226 | * the AI bunny hops between it's two favorite squares. 227 | */ 228 | private int miniMax(int[][] state, boolean isAI, int depth, int alpha, int beta) { 229 | if (depth <= 0) { 230 | return moveUtility(state); 231 | } 232 | if (isAI) { 233 | int currentAlpha = Integer.MIN_VALUE; 234 | ArrayList moves = myBoard.moves(false, deepClone(state)); 235 | for (int i = 0; i < moves.size(); i++) { 236 | int[][] nextState = deepClone(predictState(false, deepClone(state), moves.get(i))); 237 | currentAlpha = Math.max(currentAlpha, miniMax(deepClone(nextState), false, depth - 1, alpha, beta)); 238 | alpha = Math.max(alpha, currentAlpha); 239 | if (alpha >= beta) { 240 | return alpha; 241 | } 242 | } 243 | return currentAlpha; 244 | } 245 | int currentBeta = Integer.MAX_VALUE; 246 | ArrayList moves = myBoard.moves(true, deepClone(state)); 247 | for (int i = 0; i < moves.size(); i++) { 248 | int[][] nextState = deepClone(predictState(true, deepClone(state), moves.get(i))); 249 | currentBeta = Math.min(currentBeta, miniMax(deepClone(nextState), true, depth - 1, alpha, beta)); 250 | beta = Math.min(beta, currentBeta); 251 | if (beta <= alpha) { 252 | return beta; 253 | } 254 | } 255 | return currentBeta; 256 | } 257 | 258 | /* 259 | * This helper method just deep clones a 2d array of ints. 260 | */ 261 | public static int[][] deepClone(int[][] input) { 262 | if (input == null) 263 | return null; 264 | int[][] result = new int[input.length][]; 265 | for (int r = 0; r < input.length; r++) { 266 | result[r] = input[r].clone(); 267 | } 268 | return result; 269 | } 270 | 271 | /* 272 | * This helper method predicts a game board in the future 273 | * based on the current game board and a simulated move. 274 | */ 275 | public int[][] predictState(boolean playerOne, int[][] theState, int move) { 276 | int[][] result = deepClone(theState); 277 | int target = 1; 278 | if (!playerOne) { 279 | target = 2; 280 | } 281 | Point pos = myBoard.findPlayer(playerOne, result); 282 | ArrayList theMoves = myBoard.moves(playerOne, result); 283 | int x = pos.x; 284 | int y = pos.y; 285 | 286 | if (theMoves.indexOf(move) != -1) { 287 | if (move == 0) { 288 | result[x][y + 1] = target; 289 | result[x][y] = 0; 290 | } else if (move == 1) { 291 | result[x][y - 1] = target; 292 | result[x][y] = 0; 293 | } else if (move == 2) { 294 | result[x + 1][y] = target; 295 | result[x][y] = 0; 296 | } else if (move == 3) { 297 | result[x - 1][y] = target; 298 | result[x][y] = 0; 299 | } 300 | 301 | } 302 | 303 | return result; 304 | } 305 | 306 | /* 307 | * This utility function takes into a large number of heuristics to help the AI 308 | * figure out where to move to next. 309 | * 310 | * - The AI plays offensively while he has cards in his hand, but more defensively when he lacks cards. 311 | * - The AI also incorporates the range of enemy fire, so if he can get a shot off while not getting hit 312 | * - (e.x. AI has a 2 range and player has a 1 range) - he will optimize his position and fire from a safe location. 313 | * - In order to provide a more human-like experience, the AI will avoid the tile he was last on, this prevents most 314 | * bunny-hopping between two tiles. 315 | * - The AI will also factor in the damage of the enemie's card, so that he can determine if a trade is worth it or not 316 | * (e.x. AI deals 50 dmg, player deals 25 dmg, this is a good trade. If reversed it's a bad trade.) 317 | * - The AI also likes to dodge the player on the Y axis. This is a valid heuristics, since all cards shoot down the x 318 | * currently - but if cards with variable width (e.x. 3 wide, 1 long) are implemented it might need modified. 319 | */ 320 | public int moveUtility(int[][] state) { 321 | int util = 0; 322 | Point me = myBoard.findPlayer(false, deepClone(state)); 323 | Point meCurrent = myBoard.findPlayer(false, myBoard.clone()); 324 | Point them = myBoard.findPlayer(true, deepClone(state)); 325 | Point themCurrent = myBoard.findPlayer(true, myBoard.clone()); 326 | // DON'T PLAY SAME TILES 327 | if (me.x == moveLog.x && me.y == moveLog.y) { 328 | util--; 329 | } 330 | // PLAY OFFENSE WHILE CARDS REMAIN 331 | if (p2.myHand.size() > 0) { 332 | Card p2Next = p2.myHand.get(0); 333 | 334 | if (me.y == them.y) { 335 | 336 | util++; // we are on correct y square 337 | } 338 | // try to stay out of enemy fire, but close enough to step in for a 339 | // shot. 340 | if (p2Next.range == 1 && me.x == them.x + 1) { 341 | util++; 342 | } 343 | if (p2Next.range == 2 && me.x == them.x + 2) { 344 | util++; 345 | } 346 | if (p2Next.range == 3 && me.x == them.x + 3) { 347 | util++; 348 | } 349 | // don't let them win trade 350 | if (p1.myHand.size() > 0) { 351 | Card p1Next = p1.myHand.get(0); 352 | if (p1Next.range >= p2Next.range && (me.x - them.x) <= p1Next.range && (me.x - them.x) > p2Next.range) { 353 | util--; 354 | // avoid the trade we can't win. 355 | } 356 | if ((me.x - them.x) <= p1Next.range && (me.x - them.x) <= p2Next.range 357 | && p1Next.damage < p2Next.damage) { 358 | util = util + 2; 359 | ; 360 | // we will out damage them in a trade. 361 | } else if ((me.x - them.x) <= p1Next.range && (me.x - them.x) <= p2Next.range 362 | && p1Next.damage > p2Next.damage) { 363 | util--; 364 | // we won't out damage them in trade 365 | } 366 | } 367 | } 368 | // PLAY DEFENSE WHILE CARDS ARE GONE 369 | if (p2.myHand.size() == 0 && p1.myHand.size() > 0) { 370 | Card p1Next = p1.myHand.get(0); 371 | if ((me.x - them.x) <= p1Next.range) { 372 | util--; 373 | } 374 | if (me.y == them.y) { 375 | util = util - 2; 376 | // can't hit us if we dodge. 377 | } 378 | } 379 | 380 | return util; 381 | } 382 | 383 | /* 384 | * Iterates through all possible combinations of card hands and returns the 385 | * optimal one based on the cardUtility() function which takes into 386 | * consideration the elements of the cards, the damage of each card, and the 387 | * enemy's current status affliction. 388 | */ 389 | public ArrayList cardMax(ArrayList theCards) { 390 | int max = 0; 391 | ArrayList result = new ArrayList(theCards); 392 | 393 | for (int i = 0; i < theCards.size(); i++) { 394 | for (int k = 0; k < theCards.size(); k++) { 395 | if (k < theCards.size() - 1) { 396 | Collections.swap(theCards, k, k + 1); 397 | if (cardUtility(theCards) > max) { 398 | // System.out.println("PRed: " +cardUtility(theCards)); 399 | max = cardUtility(theCards); 400 | result = (ArrayList) theCards.clone(); 401 | } 402 | } 403 | } 404 | } 405 | 406 | return result; 407 | } 408 | 409 | /* 410 | * A utility function for determining correct pick order based on card 411 | * damage and elements. 5 cards, 5! 412 | * 413 | * This takes into account all active environment variables: player debuff status, 414 | * card element, card damage, and optimizes not only for bonus damage combos but for the 415 | * highest damage bonus damage combos in the correct order for maximium card hand damage. 416 | */ 417 | public int cardUtility(ArrayList theCards) { 418 | int enemyStatus = p2.status; 419 | int score = 0; 420 | 421 | for (int i = 0; i < theCards.size(); i++) { 422 | if (theCards.get(i).element == (enemyStatus + 1)) { 423 | score = score + (theCards.get(i).damage * 2); 424 | } else { 425 | score = score + theCards.get(i).damage; 426 | } 427 | enemyStatus = theCards.get(i).element; 428 | } 429 | return score; 430 | } 431 | 432 | /* 433 | * This is a helper method to keep the AI's 434 | * animations running when he moves since his movements 435 | * are tied to a variable step timer. 436 | */ 437 | public void animator(int move) { 438 | if (move == 0 || move == 1) { 439 | p2.setAnimFrame(2, 100); 440 | } 441 | if (move == 2 || move == 3) { 442 | p2.setAnimFrame(3, 100); 443 | } 444 | } 445 | 446 | /* 447 | * This method aids in performing attacks against the player. 448 | * An attack involves damage dealt (potentially), a sound clip played, 449 | * an animation of a few frames loading up, and a card being removed from the hand. 450 | * Also remember bonus damage multipliers. 451 | */ 452 | public void attack() { 453 | if (p2.myHand.size() > 0) { 454 | p2.setAnimFrame(1, 200); // shoot 455 | shootSound.play(); 456 | Card temp = p2.myHand.get(0); 457 | if (myBoard.checkShot(temp.range, true)) { 458 | if (p1.status == 1 && temp.element == 2) { 459 | p1.hp = p1.hp - (temp.damage * 2); 460 | // double damage multiplier if correct order cards 461 | } else if (p1.status == 3 && temp.element == 4) { 462 | p1.hp = p1.hp - (temp.damage * 2); 463 | } else { 464 | p1.hp = p1.hp - temp.damage; 465 | } 466 | p1.status = temp.element; 467 | } 468 | p2.myHand.remove(0); 469 | step(); 470 | } 471 | } 472 | } 473 | -------------------------------------------------------------------------------- /core/src/com/battlegrid/game/BattleGrid.java: -------------------------------------------------------------------------------- 1 | package com.battlegrid.game; 2 | 3 | import com.badlogic.gdx.Game; 4 | import com.badlogic.gdx.Gdx; 5 | import com.badlogic.gdx.graphics.g2d.BitmapFont; 6 | import com.badlogic.gdx.graphics.g2d.SpriteBatch; 7 | 8 | /* 9 | * This is the core game class. It acts as the game loop, and renders 10 | * screens whenever required. 11 | */ 12 | public class BattleGrid extends Game { 13 | public SpriteBatch myBatch; // renderer for graphics 14 | public BitmapFont myFont; // font for all game-generated text 15 | public float stateTime; // game clock 16 | public static ScreenshotFactory sc; // for recording pixels on screen 17 | 18 | /* 19 | * This method is called one time on application start. It loads the welcome 20 | * screen. 21 | */ 22 | public void create() { 23 | // initialize fields 24 | myBatch = new SpriteBatch(); 25 | myFont = new BitmapFont(); 26 | stateTime = 0; 27 | // load welcome screen 28 | this.setScreen(new WelcomeScreen(this)); 29 | } 30 | 31 | /* 32 | * Called 60 times per second. Requests frames to update via myBatch. 33 | */ 34 | public void render() { 35 | stateTime += Gdx.graphics.getDeltaTime(); // increment game clock 36 | super.render(); 37 | } 38 | 39 | /* 40 | * Removes variables from memory once game is finished. 41 | */ 42 | public void dispose() { 43 | myBatch.dispose(); 44 | myFont.dispose(); 45 | } 46 | } 47 | -------------------------------------------------------------------------------- /core/src/com/battlegrid/game/Card.java: -------------------------------------------------------------------------------- 1 | package com.battlegrid.game; 2 | 3 | /* 4 | * A card represents a single ability that the player can use. 5 | */ 6 | public class Card { 7 | public String name; 8 | public int damage; 9 | public int range; 10 | public int element; 11 | 12 | public Card(String theName, int theDamage, int theRange, int theElement) { 13 | name = theName; 14 | damage = theDamage; 15 | range = theRange; 16 | element = theElement; 17 | } 18 | 19 | public Card(Card theCard) { 20 | name = theCard.name; 21 | damage = theCard.damage; 22 | range = theCard.range; 23 | element = theCard.element; 24 | } 25 | } 26 | -------------------------------------------------------------------------------- /core/src/com/battlegrid/game/Deck.java: -------------------------------------------------------------------------------- 1 | package com.battlegrid.game; 2 | 3 | import java.util.Stack; 4 | 5 | /* 6 | * A deck consists of 30 cards. 7 | */ 8 | public class Deck { 9 | Stack myDeck; 10 | int remaining; 11 | 12 | public Deck() { 13 | // create new card deck 14 | myDeck = new Stack(); 15 | addCards(); 16 | } 17 | 18 | /* 19 | * Fill the initial deck with random cards. 20 | */ 21 | private void addCards() { 22 | for (int i = 0; i < 30; i++) { 23 | int range = Math.max(1, (int) (Math.random() * 4)); 24 | int damage = Math.max(50, (int) (Math.random() * 150)); 25 | int element = Math.max(1, (int) (Math.random() * 5)); 26 | myDeck.push(new Card(getElem(element) + ": " + damage + "x" + range, damage, range, element)); 27 | } 28 | } 29 | 30 | public String getElem(int element) { 31 | String ret = "Grass"; // base case 32 | if (element == 2) { 33 | ret = "Fire"; 34 | } else if (element == 3) { 35 | ret = "Water"; 36 | } else if (element == 4) { 37 | ret = "Elec"; 38 | } 39 | return ret; 40 | } 41 | 42 | public Card draw() { 43 | // draw from top of deck 44 | Card ret = myDeck.pop(); 45 | return ret; 46 | } 47 | 48 | public int size() { 49 | return myDeck.size(); 50 | } 51 | } 52 | -------------------------------------------------------------------------------- /core/src/com/battlegrid/game/FadeInTransition.java: -------------------------------------------------------------------------------- 1 | package com.battlegrid.game; 2 | 3 | import com.badlogic.gdx.utils.TimeUtils; 4 | 5 | /* 6 | * Perform a controlled fade in for a given game screen. 7 | */ 8 | public class FadeInTransition { 9 | // CORE GAME 10 | private BattleGrid myGame; 11 | public long duration; 12 | public long alphaState; 13 | private float alpha; 14 | 15 | public FadeInTransition(BattleGrid theGame) { 16 | // SAVE SCREEN STATE 17 | myGame = theGame; 18 | duration = TimeUtils.millis(); // record current time in milliseconds 19 | alphaState = TimeUtils.millis(); // time of last darken 20 | alpha = 0.1f; 21 | myGame.myBatch.setColor(1f, 1f, 1f, alpha); 22 | } 23 | 24 | /* 25 | * Modify the batch renderer's alpha by incrementing .1f every 1/20th of a 26 | * second 27 | */ 28 | public void incrementAlpha() { 29 | if (TimeUtils.timeSinceMillis(alphaState) > 50) { 30 | // check for alpha change 31 | alpha = alpha + 0.1f; 32 | myGame.myBatch.setColor(1f, 1f, 1f, alpha); 33 | alphaState = TimeUtils.millis(); 34 | } 35 | if (TimeUtils.timeSinceMillis(duration) > 900) { 36 | // animation is a bit under a half second 37 | myGame.myBatch.setColor(1f, 1f, 1f, 1f); 38 | // reset alpha 39 | } 40 | } 41 | 42 | public void reset() { 43 | alpha = 0.1f; 44 | duration = TimeUtils.millis(); 45 | alphaState = TimeUtils.millis(); 46 | } 47 | } 48 | -------------------------------------------------------------------------------- /core/src/com/battlegrid/game/FadeOutTransition.java: -------------------------------------------------------------------------------- 1 | package com.battlegrid.game; 2 | 3 | import com.badlogic.gdx.Gdx; 4 | import com.badlogic.gdx.Screen; 5 | import com.badlogic.gdx.graphics.GL20; 6 | import com.badlogic.gdx.graphics.OrthographicCamera; 7 | import com.badlogic.gdx.graphics.Texture; 8 | import com.badlogic.gdx.graphics.g2d.TextureRegion; 9 | import com.badlogic.gdx.utils.TimeUtils; 10 | 11 | /* 12 | * The transition screen fades to black and than fades to white providing a nice clean 13 | * transition between two game states. 14 | */ 15 | public class FadeOutTransition implements Screen { 16 | // CORE GAME 17 | private OrthographicCamera myCamera; 18 | private Screen myScreen; 19 | private BattleGrid myGame; 20 | public long duration; 21 | public long alphaState; 22 | private TextureRegion bg; 23 | private float alpha; 24 | private int scale; 25 | 26 | public FadeOutTransition(BattleGrid theGame, Screen theScreen, int theDur) { 27 | // SAVE SCREEN STATE 28 | myScreen = theScreen; 29 | myGame = theGame; 30 | scale = theDur; 31 | myGame.sc.saveScreenshot(); // record last frame of last screen 32 | duration = TimeUtils.millis(); // record current time in milliseconds 33 | alphaState = TimeUtils.millis(); // time of last darken 34 | 35 | // CONFIGURE CAMERA 36 | myCamera = new OrthographicCamera(); 37 | myCamera.setToOrtho(false, 800, 480); 38 | 39 | // CONFIGURE TRANSITION ASSETS 40 | bg = new TextureRegion(new Texture("tFrame.png")); 41 | alpha = 1f; 42 | } 43 | 44 | @Override 45 | public void show() { 46 | // TODO Auto-generated method stub 47 | 48 | } 49 | 50 | @Override 51 | public void render(float delta) { 52 | 53 | // ask openGL to clear the screen of any previously set pixels 54 | Gdx.gl.glClearColor(0, 0, 0.2f, 1); 55 | Gdx.gl.glClear(GL20.GL_COLOR_BUFFER_BIT); 56 | 57 | // tell the camera to check what its looking at every time a new frame 58 | // renders 59 | myCamera.update(); 60 | myGame.myBatch.setProjectionMatrix(myCamera.combined); 61 | 62 | // Darken tFrame every 1/20th of a second 63 | if (TimeUtils.timeSinceMillis(alphaState) > 50 * scale) { 64 | alpha = alpha - 0.1f; 65 | alphaState = TimeUtils.millis(); 66 | } 67 | 68 | myGame.myBatch.setColor(1f, 1f, 1f, alpha); 69 | myGame.myBatch.begin(); 70 | myGame.myBatch.draw(bg, 0, 0); 71 | myGame.myBatch.end(); 72 | 73 | if (TimeUtils.timeSinceMillis(duration) > 450 * scale) { 74 | // animation is a bit under a half second 75 | myGame.myBatch.setColor(1f, 1f, 1f, 1f); // reset alpha 76 | myGame.setScreen(myScreen); // jump to next screen 77 | dispose(); 78 | } 79 | 80 | } 81 | 82 | @Override 83 | public void resize(int width, int height) {} 84 | 85 | @Override 86 | public void pause() {} 87 | 88 | @Override 89 | public void resume() {} 90 | 91 | @Override 92 | public void hide() {} 93 | 94 | @Override 95 | public void dispose() { 96 | myCamera = null; 97 | bg = null; 98 | 99 | } 100 | 101 | } 102 | -------------------------------------------------------------------------------- /core/src/com/battlegrid/game/FinalScreen.java: -------------------------------------------------------------------------------- 1 | package com.battlegrid.game; 2 | 3 | import com.badlogic.gdx.Gdx; 4 | import com.badlogic.gdx.Screen; 5 | import com.badlogic.gdx.audio.Sound; 6 | import com.badlogic.gdx.graphics.GL20; 7 | import com.badlogic.gdx.graphics.OrthographicCamera; 8 | import com.badlogic.gdx.graphics.Texture; 9 | import com.badlogic.gdx.graphics.g2d.Animation; 10 | import com.badlogic.gdx.graphics.g2d.TextureRegion; 11 | 12 | /* 13 | * Displays the win and loss screens. 14 | */ 15 | public class FinalScreen implements Screen { 16 | 17 | // CORE GAME 18 | private final BattleGrid myGame; 19 | private OrthographicCamera myCamera; 20 | // ART ASSETS 21 | TextureRegion wp1; // wallpaper frame 1 22 | TextureRegion wp2; // wallpaper frame 2 23 | Animation wpAnim; // animated wallpaper 24 | TextureRegion currentFrame; // current wallpaper frame 25 | // AUDIO ASSETS 26 | Sound selectSound; 27 | // difficulty setting 28 | boolean win; 29 | String credits = "github.com/andhofmt/BattleGrid"; 30 | int pos = 0 - credits.length() * 8; 31 | int pos2 = 800; 32 | 33 | public FinalScreen(final BattleGrid theGame, boolean isWin) { 34 | // COPY GAME STATE 35 | myGame = theGame; 36 | win = isWin; 37 | 38 | // CONFIGURE CAMERA 39 | myCamera = new OrthographicCamera(); 40 | myCamera.setToOrtho(false, 800, 480); 41 | 42 | // CONFIGURE ART ASSETS 43 | wp1 = new TextureRegion(new Texture("FinalScreen/wp1.png")); 44 | wp2 = new TextureRegion(new Texture("FinalScreen/wp2.png")); 45 | wpAnim = new Animation(0.6f, wp1, wp2); // swap frames every .4 seconds 46 | 47 | // CONFIGURE SFX 48 | selectSound = Gdx.audio.newSound(Gdx.files.internal("General/select.wav")); 49 | } 50 | 51 | @Override 52 | public void show() {} 53 | 54 | @Override 55 | public void render(float delta) { 56 | // ask openGL to clear the screen of any previously set pixels 57 | Gdx.gl.glClearColor(0, 0, 0.2f, 1); 58 | Gdx.gl.glClear(GL20.GL_COLOR_BUFFER_BIT); 59 | 60 | // tell the camera to check what its looking at every time a new frame 61 | // renders 62 | myCamera.update(); 63 | myGame.myBatch.setProjectionMatrix(myCamera.combined); 64 | 65 | // load in current animation frame 66 | currentFrame = wpAnim.getKeyFrame(myGame.stateTime, true); 67 | // render the welcome screen 68 | String gg = "YOU LOSE!"; 69 | if (win) { 70 | gg = "YOU WIN!"; 71 | } 72 | 73 | myGame.myBatch.begin(); 74 | myGame.myBatch.draw(currentFrame, 0, 0); 75 | myGame.myFont.draw(myGame.myBatch, gg, pos2, 352); 76 | myGame.myFont.draw(myGame.myBatch, credits.toUpperCase(), pos, 147); 77 | pos++; 78 | pos2--; 79 | myGame.myBatch.end(); 80 | if (pos >= 800) { 81 | pos = 0 - credits.length() * 8; 82 | } 83 | if (pos2 <= 0 - (gg.length() * 8)) { 84 | pos2 = 800; 85 | } 86 | 87 | // Transition to the game 88 | if (Gdx.input.isTouched()) { 89 | System.exit(0); 90 | dispose(); 91 | } 92 | 93 | } 94 | 95 | @Override 96 | public void resize(int width, int height) {} 97 | 98 | @Override 99 | public void pause() {} 100 | 101 | @Override 102 | public void resume() {} 103 | 104 | @Override 105 | public void hide() {} 106 | 107 | @Override 108 | public void dispose() { 109 | wp1 = null; 110 | wp2 = null; 111 | wpAnim = null; 112 | currentFrame = null; 113 | selectSound = null; 114 | } 115 | 116 | } 117 | -------------------------------------------------------------------------------- /core/src/com/battlegrid/game/GameBoard.java: -------------------------------------------------------------------------------- 1 | package com.battlegrid.game; 2 | 3 | import java.awt.Point; 4 | import java.util.ArrayList; 5 | 6 | /* 7 | * Represents the game board that the players play on. 8 | */ 9 | public class GameBoard { 10 | public int[][] board = { { 0, 0, 0 }, { 0, 1, 0 }, { 0, 0, 0 }, { 0, 0, 0 }, { 0, 2, 0 }, { 0, 0, 0 } }; 11 | public Player p1; 12 | public Player p2; 13 | 14 | public GameBoard(Player one, Player two) { 15 | p1 = one; 16 | p2 = two; 17 | } 18 | 19 | /* 20 | * Find player's location on the board. 21 | */ 22 | public Point findPlayer(boolean p1, int[][] theBoard) { 23 | int y = -1; 24 | int x = -1; 25 | int target = 1; // p1 is represented as a 1 on game board 26 | if (!p1) { 27 | target = 2; // p2 is represented as a 2 on game board 28 | } 29 | for (int i = 0; i < theBoard.length; i++) { 30 | for (int k = 0; k < theBoard[i].length; k++) { 31 | if (theBoard[i][k] == target) { 32 | x = i; 33 | y = k; 34 | break; 35 | } 36 | } 37 | } 38 | return new Point(x, y); 39 | } 40 | 41 | public boolean move(int move, Player thePlayer) { 42 | boolean moved = false; 43 | boolean isP1 = !thePlayer.AI; 44 | Point pos = this.findPlayer(isP1, board); 45 | int x = pos.x; 46 | int y = pos.y; 47 | int target = 1; 48 | if (!isP1) { 49 | target = 2; 50 | } 51 | ArrayList theMoves = moves(isP1, board); 52 | if (theMoves.indexOf(move) != -1) { 53 | if (move == 0) { 54 | board[x][y + 1] = target; 55 | board[x][y] = 0; 56 | } else if (move == 1) { 57 | board[x][y - 1] = target; 58 | board[x][y] = 0; 59 | } else if (move == 2) { 60 | board[x + 1][y] = target; 61 | board[x][y] = 0; 62 | } else if (move == 3) { 63 | board[x - 1][y] = target; 64 | board[x][y] = 0; 65 | } 66 | moved = true; 67 | } 68 | return moved; 69 | } 70 | 71 | public ArrayList moves(boolean p1, int[][] theBoard) { 72 | ArrayList theMoves = new ArrayList(); 73 | Point player = findPlayer(p1, theBoard); 74 | int x = player.x; 75 | int y = player.y; 76 | 77 | // up 78 | if (isValid(x, y + 1, p1)) { 79 | theMoves.add(0); 80 | } 81 | // down 82 | if (isValid(x, y - 1, p1)) { 83 | theMoves.add(1); 84 | } 85 | // right 86 | if (isValid(x + 1, y, p1)) { 87 | theMoves.add(2); 88 | } 89 | // left 90 | if (isValid(x - 1, y, p1)) { 91 | theMoves.add(3); 92 | } 93 | return theMoves; 94 | } 95 | 96 | /* 97 | * Checks if a board location is valid. 98 | */ 99 | public boolean isValid(int x, int y, boolean playerOne) { 100 | if (playerOne) { 101 | if (x >= 0 && x <= 2 && y >= 0 && y <= 2) { 102 | return true; 103 | } 104 | } else { 105 | if (x >= 3 && x <= 5 && y >= 0 && y <= 2) { 106 | return true; 107 | } 108 | } 109 | return false; 110 | } 111 | 112 | public boolean checkShot(int range, boolean playerOne) { 113 | Point p1 = findPlayer(playerOne, board); 114 | Point p2 = findPlayer(!playerOne, board); 115 | 116 | if (Math.abs(p1.x - p2.x) <= range && p1.y == p2.y) { 117 | return true; 118 | } 119 | return false; 120 | } 121 | 122 | public int[][] clone() { 123 | int[][] input = board; 124 | if (input == null) 125 | return null; 126 | int[][] result = new int[input.length][]; 127 | for (int r = 0; r < input.length; r++) { 128 | result[r] = input[r].clone(); 129 | } 130 | return result; 131 | } 132 | } 133 | -------------------------------------------------------------------------------- /core/src/com/battlegrid/game/GameScreen.java: -------------------------------------------------------------------------------- 1 | package com.battlegrid.game; 2 | 3 | import java.awt.Point; 4 | import java.util.ArrayList; 5 | 6 | import com.badlogic.gdx.Gdx; 7 | import com.badlogic.gdx.Input.Keys; 8 | import com.badlogic.gdx.audio.Music; 9 | import com.badlogic.gdx.audio.Sound; 10 | import com.badlogic.gdx.Screen; 11 | import com.badlogic.gdx.graphics.Color; 12 | import com.badlogic.gdx.graphics.GL20; 13 | import com.badlogic.gdx.graphics.OrthographicCamera; 14 | import com.badlogic.gdx.graphics.Texture; 15 | import com.badlogic.gdx.graphics.g2d.Animation; 16 | import com.badlogic.gdx.graphics.g2d.TextureRegion; 17 | import com.badlogic.gdx.utils.TimeUtils; 18 | 19 | /* 20 | * The game screen manages a single battle between the player and the AI. 21 | */ 22 | public class GameScreen implements Screen { 23 | // CORE GAME 24 | private final BattleGrid myGame; 25 | private OrthographicCamera myCamera; 26 | public Player p1; 27 | public Player p2; 28 | public BattleAI ai; 29 | public GameBoard myBoard; 30 | public int gameState; 31 | // ART ASSETS 32 | // ART: BACKGROUND FRAMES 33 | TextureRegion bg1; 34 | TextureRegion bg2; 35 | TextureRegion bg3; 36 | TextureRegion cbg1; 37 | TextureRegion card; 38 | TextureRegion health; 39 | // ART: PLAYER AND AI FRAMES 40 | Animation p1Idle; 41 | Animation p2Idle; 42 | Animation p1Shoot; 43 | Animation p2Shoot; 44 | Animation p1Move; 45 | Animation p2Move; 46 | // ANIMATION ASSETS 47 | // ANIMATION: BACKGROUND 48 | Animation bgAnim; 49 | TextureRegion currentFrame; 50 | FadeInTransition inT; 51 | TextureRegion b1; 52 | TextureRegion b2; 53 | TextureRegion b3; 54 | TextureRegion indicator; 55 | Animation bAnim; 56 | // AUDIO: MUSIC 57 | Music battleTheme; 58 | Sound shootSound; 59 | Sound selectSound; 60 | Sound winSound; 61 | Sound loseSound; 62 | int draws = 1; 63 | 64 | public GameScreen(final BattleGrid theGame, int difficulty) { 65 | // copy game state 66 | myGame = theGame; 67 | // configure camera to match our desktop configuration 68 | myCamera = new OrthographicCamera(); 69 | myCamera.setToOrtho(false, 800, 480); 70 | inT = new FadeInTransition(myGame); 71 | // set up the game 72 | p1 = new Player(500, false); 73 | p2 = new Player(500, true); // this player is AI 74 | myBoard = new GameBoard(p1, p2); 75 | ai = new BattleAI(p1, p2, difficulty, myBoard); 76 | gameState = 0; // 0 is draw. 1 is battle. 77 | // configure art assets 78 | 79 | // BACKGROUND 80 | bg1 = new TextureRegion(new Texture("GameScreen/bg1.png")); 81 | bg2 = new TextureRegion(new Texture("GameScreen/bg2.png")); 82 | bg3 = new TextureRegion(new Texture("GameScreen/bg3.png")); 83 | cbg1 = new TextureRegion(new Texture("GameScreen/cbg1.png")); 84 | card = new TextureRegion(new Texture("GameScreen/card.png")); 85 | health = new TextureRegion(new Texture("GameScreen/health.png")); 86 | indicator = new TextureRegion(new Texture("GameScreen/indicator.png")); 87 | bgAnim = new Animation(0.35f, bg1, bg2, bg3, bg2); 88 | bgAnim.setPlayMode(Animation.PlayMode.LOOP); 89 | // PLAYER AND AI 90 | p1Idle = getAnim("GameScreen/p1-0.png", 1, 4, .6f); 91 | p2Idle = getAnim("GameScreen/p2-0.png", 1, 4, .6f); 92 | p1Shoot = getAnim("GameScreen/p1-1.png", 1, 5, .04f); 93 | p2Shoot = getAnim("GameScreen/p2-1.png", 1, 5, .04f); 94 | p1Move = getAnim("GameScreen/p1-2.png", 1, 4, .025f); 95 | p2Move = getAnim("GameScreen/p2-2.png", 1, 4, .025f); 96 | // p2Shoot = getAnim("GameScreen/p2-1.png", 1, 5, .3f); 97 | // CONFIGURE MUSIC 98 | battleTheme = Gdx.audio.newMusic(Gdx.files.internal("GameScreen/battle.mp3")); 99 | battleTheme.setLooping(true); 100 | battleTheme.play(); 101 | // CONFIGURE SFX 102 | shootSound = Gdx.audio.newSound(Gdx.files.internal("GameScreen/shoot.wav")); 103 | winSound = Gdx.audio.newSound(Gdx.files.internal("GameScreen/win.wav")); 104 | loseSound = Gdx.audio.newSound(Gdx.files.internal("GameScreen/lose.wav")); 105 | selectSound = Gdx.audio.newSound(Gdx.files.internal("General/select.wav")); 106 | } 107 | 108 | @Override 109 | public void show() { 110 | // TODO Auto-generated method stub 111 | 112 | } 113 | 114 | @Override 115 | public void render(float delta) { 116 | if (gameState == 0) { 117 | drawPhase(); 118 | } else if (gameState == 1) { 119 | battlePhase(); 120 | } 121 | } 122 | 123 | public void drawPhase() { 124 | /* 125 | * GENERAL 126 | */ 127 | Gdx.gl.glClearColor(0, 0, 0.2f, 1); 128 | Gdx.gl.glClear(GL20.GL_COLOR_BUFFER_BIT); 129 | myCamera.update(); 130 | myGame.myBatch.setProjectionMatrix(myCamera.combined); 131 | 132 | /* 133 | * GAMEPLAY 134 | */ 135 | if (!p1.hasDrawn) { 136 | p1.myHand = new ArrayList(); 137 | p2.myHand = new ArrayList(); 138 | p1.draw(); 139 | ai.draw(); 140 | } 141 | getDrawInput(p1); 142 | 143 | /* 144 | * BEGIN RENDERING CYCLE 145 | */ 146 | myGame.myBatch.begin(); 147 | myGame.myBatch.draw(cbg1, 0, 0); 148 | for (int i = 0; i < p1.random.size(); i++) { 149 | myGame.myBatch.draw(card, 50 + 150 * i, 180, 105, 125); 150 | myGame.myFont.setColor(Color.BLACK); 151 | Card next = p1.random.get(i); 152 | String elem = p1.myDeck.getElem(next.element); 153 | myGame.myFont.draw(myGame.myBatch, "ELE: " + elem.toUpperCase(), 60 + 120 * i + (30 * i), 240); 154 | myGame.myFont.draw(myGame.myBatch, "DMG: " + next.damage, 60 + 120 * i + (30 * i), 225); 155 | myGame.myFont.draw(myGame.myBatch, "RNG: " + next.range, 60 + 120 * i + (30 * i), 210); 156 | } 157 | myGame.myFont.setColor(Color.WHITE); 158 | myGame.myBatch.end(); 159 | 160 | if (p1.random.size() == 0) { 161 | p1.hasDrawn = false; 162 | p1.lastDraw = TimeUtils.millis(); 163 | gameState = 1; // all cards now in hand. move to battle state! 164 | } 165 | 166 | } 167 | 168 | private void getDrawInput(Player p1) { 169 | if (Gdx.input.justTouched()) { 170 | int x = Gdx.input.getX(); 171 | /* 172 | * Allow the player to choose his own "card pick order" so he can 173 | * optimize ranges and elements. 174 | */ 175 | for (int i = 0; i < p1.random.size(); i++) { 176 | if (x > 50 + 150 * i && x < 150 + 150 * i) { 177 | selectSound.play(); 178 | p1.myHand.add(new Card(p1.random.get(i))); 179 | p1.random.remove(i); 180 | } 181 | } 182 | } 183 | 184 | } 185 | 186 | public void battlePhase() { 187 | /* 188 | * GENERAL 189 | */ 190 | Gdx.gl.glClearColor(0, 0, 0.2f, 1); 191 | Gdx.gl.glClear(GL20.GL_COLOR_BUFFER_BIT); 192 | myCamera.update(); 193 | myGame.myBatch.setProjectionMatrix(myCamera.combined); 194 | p1.checkFrame(); 195 | p2.checkFrame(); 196 | ai.think(gameState); 197 | /* 198 | * GAMEPLAY 199 | */ 200 | getBattleInput(p1); 201 | 202 | // update sprites 203 | currentFrame = bgAnim.getKeyFrame(myGame.stateTime, true); 204 | 205 | /* 206 | * BEGIN RENDERING CYCLE 207 | */ 208 | myGame.myBatch.begin(); 209 | 210 | // RENDER: BACKGROUND 211 | myGame.myBatch.draw(currentFrame, 0, 0); // render game board 212 | 213 | // RENDER: PLAYER AND AI 214 | int[] p1Draw = animState(p1); // collect coordinates for player 215 | int[] p2Draw = animState(p2); // collect coordinates for AI 216 | 217 | drawUI(); 218 | // TARGET INDICATORS 219 | if (p1.myHand.size() > 0) { 220 | int[] p1Indi = animIndi(p1); 221 | myGame.myBatch.draw(indicator, p1Indi[0], p1Indi[1], p1Indi[2] + 2, 69); 222 | } 223 | 224 | int width = 100; 225 | int p2Width = 100; 226 | int p2Spawn = p2Draw[0]; 227 | if (p1.animFrame == 1) { 228 | width = 200; 229 | } 230 | if (p2.animFrame == 1) { 231 | p2Width = 200; 232 | p2Spawn = p2Spawn - 75; 233 | } 234 | Animation p1Anim = getAvatar(p1); 235 | Animation p2Anim = getAvatar(p2); 236 | TextureRegion p1Frame = p1Anim.getKeyFrame(myGame.stateTime, true); 237 | TextureRegion p2Frame = p2Anim.getKeyFrame(myGame.stateTime, true); 238 | myGame.myBatch.draw(p1Frame, p1Draw[0], p1Draw[1], width, 125); // player 239 | myGame.myBatch.draw(p2Frame, p2Spawn, p2Draw[1], p2Width, 125); 240 | myGame.myBatch.end(); 241 | 242 | if (p1.hp < 1) { 243 | loseSound.play(); 244 | myGame.setScreen(new FadeOutTransition(myGame, new FinalScreen(myGame, false), 8)); 245 | dispose(); 246 | } 247 | if (p2.hp < 1) { 248 | winSound.play(); 249 | myGame.setScreen(new FadeOutTransition(myGame, new FinalScreen(myGame, true), 8)); 250 | dispose(); 251 | } 252 | if (TimeUtils.timeSinceMillis(p1.lastDraw) > 15000 && p1.myDeck.size() > 0) { 253 | gameState = 0; 254 | draws++; 255 | } else if (TimeUtils.timeSinceMillis(p1.lastDraw) > 15000 && p1.myDeck.size() == 0) { 256 | loseSound.play(); 257 | myGame.setScreen(new FadeOutTransition(myGame, new FinalScreen(myGame, false), 8)); 258 | dispose(); 259 | } 260 | } 261 | 262 | /* 263 | * Draws UI text components on the screen. 264 | */ 265 | public void drawUI() { 266 | String c1; 267 | String c2; 268 | if (p1.myHand.size() > 0) { 269 | c1 = p1.myHand.get(0).name; 270 | } else { 271 | c1 = "EMPTY HAND"; 272 | } 273 | if (p2.myHand.size() > 0) { 274 | c2 = p2.myHand.get(0).name; 275 | } else { 276 | c2 = "EMPTY HAND"; 277 | } 278 | // RENDER UI COMPONENTS 279 | String dtext = "Next Draw: "; 280 | if (draws == 6) { 281 | dtext = "Game Over: "; 282 | } 283 | 284 | long tilNextDraw = ((15000 - TimeUtils.timeSinceMillis(p1.lastDraw)) / 1000); 285 | myGame.myBatch.draw(health, 0, 420, 165, 60); 286 | myGame.myBatch.draw(health, 635, 420, 165, 60); 287 | myGame.myFont.draw(myGame.myBatch, "HP: " + p1.hp, 10, 470); 288 | myGame.myFont.draw(myGame.myBatch, "HP: " + p2.hp, 645, 470); 289 | myGame.myFont.draw(myGame.myBatch, c1, 10, 455); 290 | myGame.myFont.draw(myGame.myBatch, c2, 645, 455); 291 | myGame.myFont.draw(myGame.myBatch, dtext + tilNextDraw, 10, 440); 292 | myGame.myFont.draw(myGame.myBatch, dtext + tilNextDraw, 645, 440); 293 | myGame.myFont.draw(myGame.myBatch, "(" + p1.myHand.size() + ")", 140, 470); 294 | myGame.myFont.draw(myGame.myBatch, "(" + p2.myHand.size() + ")", 775, 470); 295 | } 296 | 297 | /* 298 | * Get and return avatar for player or AI based on game state. 299 | */ 300 | private Animation getAvatar(Player thePlayer) { 301 | boolean isP1 = !thePlayer.AI; 302 | 303 | if (isP1) { 304 | if (p1.animFrame == 1) { 305 | return p1Shoot; 306 | } else if (p1.animFrame == 2 || p1.animFrame == 3) { 307 | return p1Move; 308 | } 309 | return p1Idle; 310 | } 311 | if (p2.animFrame == 1) { 312 | return p2Shoot; 313 | } else if (p2.animFrame == 2 || p2.animFrame == 3) { 314 | return p2Move; 315 | } 316 | return p2Idle; 317 | } 318 | 319 | /* 320 | * Check for keyboard input from the human player. 321 | */ 322 | private void getBattleInput(Player thePlayer) { 323 | if (Gdx.input.isKeyJustPressed(Keys.DPAD_UP)) { 324 | myBoard.move(0, thePlayer); 325 | thePlayer.setAnimFrame(2, 100); 326 | } else if (Gdx.input.isKeyJustPressed(Keys.DPAD_DOWN)) { 327 | myBoard.move(1, thePlayer); 328 | thePlayer.setAnimFrame(2, 100); 329 | } else if (Gdx.input.isKeyJustPressed(Keys.DPAD_LEFT)) { 330 | myBoard.move(3, thePlayer); 331 | thePlayer.setAnimFrame(3, 100); 332 | } else if (Gdx.input.isKeyJustPressed(Keys.DPAD_RIGHT)) { 333 | myBoard.move(2, thePlayer); 334 | thePlayer.setAnimFrame(3, 100); 335 | } else if (Gdx.input.isKeyJustPressed(Keys.SPACE)) { 336 | if (p1.myHand.size() > 0) { 337 | thePlayer.setAnimFrame(1, 200); // shoot 338 | shootSound.play(); 339 | attack(); 340 | } 341 | } 342 | } 343 | 344 | /* 345 | * Attempt to attack the enemy. Remove card from hand after attack. Apply 346 | * status based on card element. 347 | */ 348 | public void attack() { 349 | Card temp = p1.myHand.get(0); 350 | if (myBoard.checkShot(temp.range, true)) { 351 | if (p2.status == 1 && temp.element == 2) { 352 | p2.hp = p2.hp - (temp.damage * 2); // double damage multiplier 353 | // if correct order cards 354 | } else if (p2.status == 3 && temp.element == 4) { 355 | p2.hp = p2.hp - (temp.damage * 2); 356 | } else { 357 | p2.hp = p2.hp - temp.damage; 358 | } 359 | p2.status = temp.element; 360 | } 361 | p1.myHand.remove(0); 362 | } 363 | 364 | /* 365 | * Return an array of coordinates, of where to render the player and AI on 366 | * the game board. 367 | */ 368 | public int[] animState(Player thePlayer) { 369 | int[] result = { 0, 0, 0, 0 }; // x, y, scaleX, scaleY 370 | // grab player position data from game board 371 | boolean isP1 = !thePlayer.AI; 372 | Point pos = myBoard.findPlayer(isP1, myBoard.clone()); 373 | int x = pos.x; 374 | int y = pos.y; 375 | 376 | if (isP1) { // calculate P1's coordinates 377 | result[0] = 10 + 133 * x; 378 | result[1] = 75 + 70 * y; 379 | } else { // calculate AI's coordinates 380 | result[0] = 10 + 133 * x; 381 | result[1] = 75 + 70 * y; 382 | } 383 | return result; 384 | } 385 | 386 | /* 387 | * Scale the targetting indicators for the game board. 388 | */ 389 | public int[] animIndi(Player thePlayer) { 390 | int[] result = { 0, 0, 0, 0 }; // x, y, scaleX, scaleY 391 | // grab player position data from game board 392 | boolean isP1 = !thePlayer.AI; 393 | Point pos = myBoard.findPlayer(isP1, myBoard.clone()); 394 | int x = pos.x; 395 | int y = pos.y; 396 | 397 | if (isP1 && p1.myHand.size() > 0) { // calculate P1's coordinates 398 | Card next = p1.myHand.get(0); 399 | 400 | result[0] = 133 * x; 401 | result[1] = 50 + 70 * y; 402 | result[2] = 133 * (next.range + 1); 403 | } else { // calculate AI's coordinates 404 | // unused right now 405 | } 406 | return result; 407 | } 408 | 409 | /* 410 | * Return the correct player sprite to be rendered. 411 | */ 412 | public Animation getAnim(String sheet, int row, int col, float flip) { 413 | Animation myAnim; 414 | Texture mySheet; 415 | TextureRegion[] myFrames; 416 | 417 | mySheet = new Texture(sheet); 418 | TextureRegion[][] temp = TextureRegion.split(mySheet, mySheet.getWidth() / col, mySheet.getHeight() / row); // cols, 419 | // rows 420 | myFrames = new TextureRegion[col * row]; // columns times rows 421 | int index = 0; 422 | for (int i = 0; i < row; i++) { 423 | for (int j = 0; j < col; j++) { 424 | myFrames[index++] = temp[i][j]; 425 | } 426 | } 427 | myAnim = new Animation(flip, myFrames); 428 | 429 | return myAnim; 430 | } 431 | 432 | @Override 433 | public void resize(int width, int height) {} 434 | 435 | @Override 436 | public void pause() {} 437 | 438 | @Override 439 | public void resume() {} 440 | 441 | @Override 442 | public void hide() {} 443 | 444 | @Override 445 | public void dispose() { 446 | // TODO Auto-generated method stub 447 | battleTheme.stop(); 448 | battleTheme = null; 449 | 450 | } 451 | 452 | } 453 | -------------------------------------------------------------------------------- /core/src/com/battlegrid/game/Player.java: -------------------------------------------------------------------------------- 1 | package com.battlegrid.game; 2 | 3 | import java.util.ArrayList; 4 | 5 | import com.badlogic.gdx.utils.TimeUtils; 6 | 7 | /* 8 | * Represents a player on the game board. 9 | */ 10 | public class Player { 11 | // either player 12 | public int hp; 13 | public int status; 14 | public Deck myDeck; 15 | public int animFrame; // state of animation 16 | public long animTimer; 17 | public int theDuration; 18 | long lastDraw; // time of last draw 19 | public ArrayList myHand; 20 | public ArrayList random; 21 | public boolean hasDrawn; 22 | public boolean drawing; 23 | // ai only 24 | public boolean AI; 25 | 26 | public Player(int theHP, boolean isAI) { 27 | hp = theHP; 28 | AI = isAI; 29 | animFrame = 0; // idle 30 | animTimer = 0; 31 | theDuration = 0; 32 | lastDraw = 0; 33 | myDeck = new Deck(); 34 | myHand = new ArrayList(); 35 | random = new ArrayList(); 36 | drawing = false; 37 | hasDrawn = false; 38 | } 39 | 40 | public void setAnimFrame(int state, int duration) { 41 | animFrame = state; 42 | theDuration = duration; 43 | animTimer = TimeUtils.millis(); 44 | 45 | } 46 | 47 | public void resetFrame() { 48 | animFrame = 0; 49 | } 50 | 51 | public void draw() { 52 | for (int i = 0; i < 5; i++) { 53 | random.add(myDeck.draw()); 54 | } 55 | hasDrawn = true; 56 | } 57 | 58 | /* 59 | * Reset animation frames. 60 | */ 61 | public void checkFrame() { 62 | if (animFrame != 0 && TimeUtils.timeSinceMillis(animTimer) > theDuration) { 63 | resetFrame(); 64 | } 65 | } 66 | 67 | } 68 | -------------------------------------------------------------------------------- /core/src/com/battlegrid/game/ScreenshotFactory.java: -------------------------------------------------------------------------------- 1 | package com.battlegrid.game; 2 | 3 | import java.io.File; 4 | import java.nio.ByteBuffer; 5 | 6 | import com.badlogic.gdx.Gdx; 7 | import com.badlogic.gdx.files.FileHandle; 8 | import com.badlogic.gdx.graphics.Pixmap; 9 | import com.badlogic.gdx.graphics.PixmapIO; 10 | import com.badlogic.gdx.utils.ScreenUtils; 11 | 12 | /* 13 | * Saves the pixels on the screen, so they can be used in a TransitionScreen. 14 | */ 15 | public class ScreenshotFactory { 16 | 17 | /* 18 | * Save pixels to disk in PNG format. (root directory of game). 19 | */ 20 | public static void saveScreenshot() { 21 | try { 22 | FileHandle fh; 23 | do { 24 | File legacy = new File("tFrame.png"); 25 | legacy.delete(); // delete if already exists 26 | fh = new FileHandle("tFrame" + ".png"); 27 | } while (fh.exists()); 28 | Pixmap pixmap = getScreenshot(0, 0, Gdx.graphics.getWidth(), Gdx.graphics.getHeight(), true); 29 | PixmapIO.writePNG(fh, pixmap); 30 | pixmap.dispose(); 31 | } catch (Exception e) { 32 | } 33 | } 34 | 35 | /* 36 | * Collect pixels from screen. 37 | */ 38 | private static Pixmap getScreenshot(int x, int y, int w, int h, boolean yDown) { 39 | final Pixmap pixmap = ScreenUtils.getFrameBufferPixmap(x, y, w, h); 40 | 41 | if (yDown) { 42 | // Flip on vertical depending on configuration. 43 | ByteBuffer pixels = pixmap.getPixels(); 44 | int numBytes = w * h * 4; 45 | byte[] lines = new byte[numBytes]; 46 | int numBytesPerLine = w * 4; 47 | for (int i = 0; i < h; i++) { 48 | pixels.position((h - i - 1) * numBytesPerLine); 49 | pixels.get(lines, i * numBytesPerLine, numBytesPerLine); 50 | } 51 | pixels.clear(); 52 | pixels.put(lines); 53 | pixels.clear(); 54 | } 55 | 56 | return pixmap; 57 | } 58 | } -------------------------------------------------------------------------------- /core/src/com/battlegrid/game/SettingsScreen.java: -------------------------------------------------------------------------------- 1 | package com.battlegrid.game; 2 | 3 | import com.badlogic.gdx.Gdx; 4 | import com.badlogic.gdx.Screen; 5 | import com.badlogic.gdx.audio.Sound; 6 | import com.badlogic.gdx.graphics.GL20; 7 | import com.badlogic.gdx.graphics.OrthographicCamera; 8 | import com.badlogic.gdx.graphics.Texture; 9 | import com.badlogic.gdx.graphics.g2d.Animation; 10 | import com.badlogic.gdx.graphics.g2d.TextureRegion; 11 | 12 | /* 13 | * Displays an animated settings screen, giving the player 14 | * choice of difficulty on three levels (easy, medium, hard). 15 | */ 16 | public class SettingsScreen implements Screen { 17 | // CORE GAME 18 | private final BattleGrid myGame; 19 | private OrthographicCamera myCamera; 20 | int difficulty; 21 | // ART ASSETS 22 | TextureRegion wp1; // wallpaper frame 1 23 | TextureRegion wp2; // wallpaper frame 2 24 | Animation wpAnim; // animated wallpaper 25 | TextureRegion currentFrame; // current wallpaper frame 26 | // AUDIO ASSETS 27 | Sound selectSound; 28 | 29 | public SettingsScreen(final BattleGrid theGame, int theDifficulty) { 30 | // COPY GAME STATE 31 | myGame = theGame; 32 | difficulty = theDifficulty; // default is 0 33 | 34 | // CONFIGURE CAMERA 35 | myCamera = new OrthographicCamera(); 36 | myCamera.setToOrtho(false, 800, 480); 37 | 38 | // CONFIGURE ART ASSETS 39 | wp1 = new TextureRegion(new Texture("SettingsScreen/wp1.png")); 40 | wp2 = new TextureRegion(new Texture("SettingsScreen/wp2.png")); 41 | wpAnim = new Animation(0.6f, wp1, wp2); // swap frames every .4 seconds 42 | 43 | // CONFIGURE SFX 44 | selectSound = Gdx.audio.newSound(Gdx.files.internal("General/select.wav")); 45 | } 46 | 47 | @Override 48 | public void show() {} 49 | 50 | @Override 51 | public void render(float delta) { 52 | // ask openGL to clear the screen of any previously set pixels 53 | Gdx.gl.glClearColor(0, 0, 0.2f, 1); 54 | Gdx.gl.glClear(GL20.GL_COLOR_BUFFER_BIT); 55 | 56 | // tell the camera to check what its looking at every time a new frame renders 57 | myCamera.update(); 58 | myGame.myBatch.setProjectionMatrix(myCamera.combined); 59 | 60 | // load in current animation frame 61 | currentFrame = wpAnim.getKeyFrame(myGame.stateTime, true); 62 | // render the welcome screen 63 | myGame.myBatch.begin(); 64 | myGame.myBatch.draw(currentFrame, 0, 0); 65 | myGame.myBatch.end(); 66 | 67 | // Transition to the game 68 | if (Gdx.input.isTouched()) { 69 | int x = Gdx.input.getX(); 70 | 71 | if (x < 185) { // only check x coordinate. 72 | difficulty = 0; 73 | } else if (x > 185 && x < 400) { 74 | difficulty = 1; 75 | } else { 76 | difficulty = 4; 77 | } 78 | selectSound.play(); 79 | myGame.setScreen(new FadeOutTransition(myGame, new GameScreen(myGame, difficulty), 1)); 80 | dispose(); 81 | } 82 | 83 | } 84 | 85 | @Override 86 | public void resize(int width, int height) {} 87 | 88 | @Override 89 | public void pause() {} 90 | 91 | @Override 92 | public void resume() {} 93 | 94 | @Override 95 | public void hide() {} 96 | 97 | @Override 98 | public void dispose() { 99 | wp1 = null; 100 | wp2 = null; 101 | wpAnim = null; 102 | currentFrame = null; 103 | selectSound = null; 104 | } 105 | 106 | } 107 | -------------------------------------------------------------------------------- /core/src/com/battlegrid/game/WelcomeScreen.java: -------------------------------------------------------------------------------- 1 | package com.battlegrid.game; 2 | 3 | import com.badlogic.gdx.Gdx; 4 | import com.badlogic.gdx.Screen; 5 | import com.badlogic.gdx.audio.Music; 6 | import com.badlogic.gdx.audio.Sound; 7 | import com.badlogic.gdx.graphics.GL20; 8 | import com.badlogic.gdx.graphics.OrthographicCamera; 9 | import com.badlogic.gdx.graphics.Texture; 10 | import com.badlogic.gdx.graphics.g2d.Animation; 11 | import com.badlogic.gdx.graphics.g2d.TextureRegion; 12 | 13 | /* 14 | * Displays an animated welcome screen, prompting the user 15 | * to start a new match or view the credits, etc. 16 | */ 17 | public class WelcomeScreen implements Screen { 18 | // CORE GAME 19 | private final BattleGrid myGame; 20 | private OrthographicCamera myCamera; 21 | // ART ASSETS 22 | TextureRegion wp1; // wallpaper frame 1 23 | TextureRegion wp2; // wallpaper frame 2 24 | Animation wpAnim; // animated wallpaper 25 | TextureRegion currentFrame; // current wallpaper frame 26 | // AUDIO ASSETS 27 | Music welcomeTheme; 28 | Sound selectSound; 29 | 30 | public WelcomeScreen(final BattleGrid theGame) { 31 | // COPY GAME STATE 32 | myGame = theGame; 33 | 34 | // CONFIGURE CAMERA 35 | myCamera = new OrthographicCamera(); 36 | myCamera.setToOrtho(false, 800, 480); 37 | 38 | // CONFIGURE ART ASSETS 39 | wp1 = new TextureRegion(new Texture("WelcomeScreen/wp1.png")); 40 | wp2 = new TextureRegion(new Texture("WelcomeScreen/wp2.png")); 41 | wpAnim = new Animation(0.4f, wp1, wp2); // swap frames every .4 seconds 42 | 43 | // CONFIGURE MUSIC 44 | welcomeTheme = Gdx.audio.newMusic(Gdx.files.internal("WelcomeScreen/welcome.mp3")); 45 | welcomeTheme.setLooping(true); 46 | welcomeTheme.play(); 47 | 48 | // CONFIGURE SFX 49 | selectSound = Gdx.audio.newSound(Gdx.files.internal("General/select.wav")); 50 | } 51 | 52 | @Override 53 | public void show() {} 54 | 55 | @Override 56 | public void render(float delta) { 57 | // ask openGL to clear the screen of any previously set pixels 58 | Gdx.gl.glClearColor(0, 0, 0.2f, 1); 59 | Gdx.gl.glClear(GL20.GL_COLOR_BUFFER_BIT); 60 | 61 | // tell the camera to check what its looking at every time a new frame renders 62 | myCamera.update(); 63 | myGame.myBatch.setProjectionMatrix(myCamera.combined); 64 | 65 | // load in current animation frame 66 | currentFrame = wpAnim.getKeyFrame(myGame.stateTime, true); 67 | // render the welcome screen 68 | myGame.myBatch.begin(); 69 | myGame.myBatch.draw(currentFrame, 0, 0); 70 | myGame.myBatch.end(); 71 | // Transition to the game 72 | if (Gdx.input.isTouched()) { 73 | selectSound.play(); 74 | //myGame.setScreen(new FadeOutTransition(myGame, new GameScreen(myGame, 1))); 75 | myGame.setScreen(new FadeOutTransition(myGame, new SettingsScreen(myGame, 1), 1)); 76 | dispose(); 77 | } 78 | 79 | } 80 | 81 | @Override 82 | public void resize(int width, int height) {} 83 | 84 | @Override 85 | public void pause() {} 86 | 87 | @Override 88 | public void resume() {} 89 | 90 | @Override 91 | public void hide() {} 92 | 93 | @Override 94 | public void dispose() { 95 | wp1 = null; 96 | wp2 = null; 97 | wpAnim = null; 98 | currentFrame = null; 99 | welcomeTheme.stop(); 100 | welcomeTheme = null; 101 | selectSound = null; 102 | } 103 | 104 | } 105 | -------------------------------------------------------------------------------- /desktop/.classpath: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /desktop/.project: -------------------------------------------------------------------------------- 1 | 2 | 3 | BattleGrid-desktop 4 | 5 | 6 | 7 | 8 | 9 | org.eclipse.jdt.core.javabuilder 10 | 11 | 12 | 13 | 14 | 15 | org.springsource.ide.eclipse.gradle.core.nature 16 | org.eclipse.jdt.core.javanature 17 | 18 | 19 | 20 | assets 21 | 2 22 | PARENT-1-PROJECT_LOC/core/assets 23 | 24 | 25 | 26 | -------------------------------------------------------------------------------- /desktop/.settings/gradle/org.springsource.ide.eclipse.gradle.core.prefs: -------------------------------------------------------------------------------- 1 | #org.springsource.ide.eclipse.gradle.core.preferences.GradleProjectPreferences 2 | #Wed Nov 11 10:53:48 PST 2015 3 | org.springsource.ide.eclipse.gradle.linkedresources=assets/; 4 | org.springsource.ide.eclipse.gradle.rootprojectloc=.. 5 | -------------------------------------------------------------------------------- /desktop/.settings/gradle/org.springsource.ide.eclipse.gradle.refresh.prefs: -------------------------------------------------------------------------------- 1 | #org.springsource.ide.eclipse.gradle.core.actions.GradleRefreshPreferences 2 | #Wed Nov 11 10:53:48 PST 2015 3 | addResourceFilters=true 4 | afterTasks=afterEclipseImport; 5 | beforeTasks=cleanEclipse;eclipse; 6 | enableAfterTasks=false 7 | enableBeforeTasks=false 8 | useHierarchicalNames=false 9 | -------------------------------------------------------------------------------- /desktop/bin/com/battlegrid/game/desktop/DesktopLauncher.class: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/and1hof/BattleGrid-Prototype/b42fa8457113953e4ecd7a7cd96e93a52c4e1865/desktop/bin/com/battlegrid/game/desktop/DesktopLauncher.class -------------------------------------------------------------------------------- /desktop/build.gradle: -------------------------------------------------------------------------------- 1 | apply plugin: "java" 2 | 3 | sourceCompatibility = 1.6 4 | sourceSets.main.java.srcDirs = [ "src/" ] 5 | 6 | project.ext.mainClassName = "com.battlegrid.game.desktop.DesktopLauncher" 7 | project.ext.assetsDir = new File("../core/assets"); 8 | 9 | task run(dependsOn: classes, type: JavaExec) { 10 | main = project.mainClassName 11 | classpath = sourceSets.main.runtimeClasspath 12 | standardInput = System.in 13 | workingDir = project.assetsDir 14 | ignoreExitValue = true 15 | } 16 | 17 | task dist(type: Jar) { 18 | from files(sourceSets.main.output.classesDir) 19 | from files(sourceSets.main.output.resourcesDir) 20 | from {configurations.compile.collect {zipTree(it)}} 21 | from files(project.assetsDir); 22 | 23 | manifest { 24 | attributes 'Main-Class': project.mainClassName 25 | } 26 | } 27 | 28 | dist.dependsOn classes 29 | 30 | eclipse { 31 | project { 32 | name = appName + "-desktop" 33 | linkedResource name: 'assets', type: '2', location: 'PARENT-1-PROJECT_LOC/core/assets' 34 | } 35 | } 36 | 37 | task afterEclipseImport(description: "Post processing after project generation", group: "IDE") { 38 | doLast { 39 | def classpath = new XmlParser().parse(file(".classpath")) 40 | new Node(classpath, "classpathentry", [ kind: 'src', path: 'assets' ]); 41 | def writer = new FileWriter(file(".classpath")) 42 | def printer = new XmlNodePrinter(new PrintWriter(writer)) 43 | printer.setPreserveWhitespace(true) 44 | printer.print(classpath) 45 | } 46 | } -------------------------------------------------------------------------------- /desktop/src/com/battlegrid/game/desktop/DesktopLauncher.java: -------------------------------------------------------------------------------- 1 | package com.battlegrid.game.desktop; 2 | 3 | import com.badlogic.gdx.Files.FileType; 4 | import com.badlogic.gdx.backends.lwjgl.LwjglApplication; 5 | import com.badlogic.gdx.backends.lwjgl.LwjglApplicationConfiguration; 6 | import com.battlegrid.game.BattleGrid; 7 | 8 | /* 9 | * For desktop-specific window configuration. 10 | * 11 | * -> Load in 480p by default. This is default "horizontal" resolution on most android devices. 12 | * -> Don't allow resizing because pixel art will get stretched. 13 | */ 14 | public class DesktopLauncher { 15 | public static void main (String[] arg) { 16 | LwjglApplicationConfiguration config = new LwjglApplicationConfiguration(); 17 | config.title = "BattleGrid"; 18 | config.width = 800; 19 | config.height = 480; 20 | config.resizable = false; 21 | new LwjglApplication(new BattleGrid(), config); 22 | } 23 | } 24 | -------------------------------------------------------------------------------- /gradle.properties: -------------------------------------------------------------------------------- 1 | org.gradle.daemon=true 2 | org.gradle.jvmargs=-Xms128m -Xmx512m 3 | org.gradle.configureondemand=true -------------------------------------------------------------------------------- /gradle/wrapper/gradle-wrapper.jar: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/and1hof/BattleGrid-Prototype/b42fa8457113953e4ecd7a7cd96e93a52c4e1865/gradle/wrapper/gradle-wrapper.jar -------------------------------------------------------------------------------- /gradle/wrapper/gradle-wrapper.properties: -------------------------------------------------------------------------------- 1 | #Sat Sep 21 13:08:26 CEST 2013 2 | distributionBase=GRADLE_USER_HOME 3 | distributionPath=wrapper/dists 4 | zipStoreBase=GRADLE_USER_HOME 5 | zipStorePath=wrapper/dists 6 | distributionUrl=http\://services.gradle.org/distributions/gradle-2.4-all.zip 7 | -------------------------------------------------------------------------------- /gradlew: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | 3 | ############################################################################## 4 | ## 5 | ## Gradle start up script for UN*X 6 | ## 7 | ############################################################################## 8 | 9 | # Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. 10 | DEFAULT_JVM_OPTS="" 11 | 12 | APP_NAME="Gradle" 13 | APP_BASE_NAME=`basename "$0"` 14 | 15 | # Use the maximum available, or set MAX_FD != -1 to use that value. 16 | MAX_FD="maximum" 17 | 18 | warn ( ) { 19 | echo "$*" 20 | } 21 | 22 | die ( ) { 23 | echo 24 | echo "$*" 25 | echo 26 | exit 1 27 | } 28 | 29 | # OS specific support (must be 'true' or 'false'). 30 | cygwin=false 31 | msys=false 32 | darwin=false 33 | case "`uname`" in 34 | CYGWIN* ) 35 | cygwin=true 36 | ;; 37 | Darwin* ) 38 | darwin=true 39 | ;; 40 | MINGW* ) 41 | msys=true 42 | ;; 43 | esac 44 | 45 | # For Cygwin, ensure paths are in UNIX format before anything is touched. 46 | if $cygwin ; then 47 | [ -n "$JAVA_HOME" ] && JAVA_HOME=`cygpath --unix "$JAVA_HOME"` 48 | fi 49 | 50 | # Attempt to set APP_HOME 51 | # Resolve links: $0 may be a link 52 | PRG="$0" 53 | # Need this for relative symlinks. 54 | while [ -h "$PRG" ] ; do 55 | ls=`ls -ld "$PRG"` 56 | link=`expr "$ls" : '.*-> \(.*\)$'` 57 | if expr "$link" : '/.*' > /dev/null; then 58 | PRG="$link" 59 | else 60 | PRG=`dirname "$PRG"`"/$link" 61 | fi 62 | done 63 | SAVED="`pwd`" 64 | cd "`dirname \"$PRG\"`/" >&- 65 | APP_HOME="`pwd -P`" 66 | cd "$SAVED" >&- 67 | 68 | CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar 69 | 70 | # Determine the Java command to use to start the JVM. 71 | if [ -n "$JAVA_HOME" ] ; then 72 | if [ -x "$JAVA_HOME/jre/sh/java" ] ; then 73 | # IBM's JDK on AIX uses strange locations for the executables 74 | JAVACMD="$JAVA_HOME/jre/sh/java" 75 | else 76 | JAVACMD="$JAVA_HOME/bin/java" 77 | fi 78 | if [ ! -x "$JAVACMD" ] ; then 79 | die "ERROR: JAVA_HOME is set to an invalid directory: $JAVA_HOME 80 | 81 | Please set the JAVA_HOME variable in your environment to match the 82 | location of your Java installation." 83 | fi 84 | else 85 | JAVACMD="java" 86 | which java >/dev/null 2>&1 || die "ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. 87 | 88 | Please set the JAVA_HOME variable in your environment to match the 89 | location of your Java installation." 90 | fi 91 | 92 | # Increase the maximum file descriptors if we can. 93 | if [ "$cygwin" = "false" -a "$darwin" = "false" ] ; then 94 | MAX_FD_LIMIT=`ulimit -H -n` 95 | if [ $? -eq 0 ] ; then 96 | if [ "$MAX_FD" = "maximum" -o "$MAX_FD" = "max" ] ; then 97 | MAX_FD="$MAX_FD_LIMIT" 98 | fi 99 | ulimit -n $MAX_FD 100 | if [ $? -ne 0 ] ; then 101 | warn "Could not set maximum file descriptor limit: $MAX_FD" 102 | fi 103 | else 104 | warn "Could not query maximum file descriptor limit: $MAX_FD_LIMIT" 105 | fi 106 | fi 107 | 108 | # For Darwin, add options to specify how the application appears in the dock 109 | if $darwin; then 110 | GRADLE_OPTS="$GRADLE_OPTS \"-Xdock:name=$APP_NAME\" \"-Xdock:icon=$APP_HOME/media/gradle.icns\"" 111 | fi 112 | 113 | # For Cygwin, switch paths to Windows format before running java 114 | if $cygwin ; then 115 | APP_HOME=`cygpath --path --mixed "$APP_HOME"` 116 | CLASSPATH=`cygpath --path --mixed "$CLASSPATH"` 117 | 118 | # We build the pattern for arguments to be converted via cygpath 119 | ROOTDIRSRAW=`find -L / -maxdepth 1 -mindepth 1 -type d 2>/dev/null` 120 | SEP="" 121 | for dir in $ROOTDIRSRAW ; do 122 | ROOTDIRS="$ROOTDIRS$SEP$dir" 123 | SEP="|" 124 | done 125 | OURCYGPATTERN="(^($ROOTDIRS))" 126 | # Add a user-defined pattern to the cygpath arguments 127 | if [ "$GRADLE_CYGPATTERN" != "" ] ; then 128 | OURCYGPATTERN="$OURCYGPATTERN|($GRADLE_CYGPATTERN)" 129 | fi 130 | # Now convert the arguments - kludge to limit ourselves to /bin/sh 131 | i=0 132 | for arg in "$@" ; do 133 | CHECK=`echo "$arg"|egrep -c "$OURCYGPATTERN" -` 134 | CHECK2=`echo "$arg"|egrep -c "^-"` ### Determine if an option 135 | 136 | if [ $CHECK -ne 0 ] && [ $CHECK2 -eq 0 ] ; then ### Added a condition 137 | eval `echo args$i`=`cygpath --path --ignore --mixed "$arg"` 138 | else 139 | eval `echo args$i`="\"$arg\"" 140 | fi 141 | i=$((i+1)) 142 | done 143 | case $i in 144 | (0) set -- ;; 145 | (1) set -- "$args0" ;; 146 | (2) set -- "$args0" "$args1" ;; 147 | (3) set -- "$args0" "$args1" "$args2" ;; 148 | (4) set -- "$args0" "$args1" "$args2" "$args3" ;; 149 | (5) set -- "$args0" "$args1" "$args2" "$args3" "$args4" ;; 150 | (6) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" ;; 151 | (7) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" ;; 152 | (8) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" ;; 153 | (9) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" "$args8" ;; 154 | esac 155 | fi 156 | 157 | # Split up the JVM_OPTS And GRADLE_OPTS values into an array, following the shell quoting and substitution rules 158 | function splitJvmOpts() { 159 | JVM_OPTS=("$@") 160 | } 161 | eval splitJvmOpts $DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS 162 | JVM_OPTS[${#JVM_OPTS[*]}]="-Dorg.gradle.appname=$APP_BASE_NAME" 163 | 164 | exec "$JAVACMD" "${JVM_OPTS[@]}" -classpath "$CLASSPATH" org.gradle.wrapper.GradleWrapperMain "$@" 165 | -------------------------------------------------------------------------------- /gradlew.bat: -------------------------------------------------------------------------------- 1 | @if "%DEBUG%" == "" @echo off 2 | @rem ########################################################################## 3 | @rem 4 | @rem Gradle startup script for Windows 5 | @rem 6 | @rem ########################################################################## 7 | 8 | @rem Set local scope for the variables with windows NT shell 9 | if "%OS%"=="Windows_NT" setlocal 10 | 11 | @rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. 12 | set DEFAULT_JVM_OPTS= 13 | 14 | set DIRNAME=%~dp0 15 | if "%DIRNAME%" == "" set DIRNAME=. 16 | set APP_BASE_NAME=%~n0 17 | set APP_HOME=%DIRNAME% 18 | 19 | @rem Find java.exe 20 | if defined JAVA_HOME goto findJavaFromJavaHome 21 | 22 | set JAVA_EXE=java.exe 23 | %JAVA_EXE% -version >NUL 2>&1 24 | if "%ERRORLEVEL%" == "0" goto init 25 | 26 | echo. 27 | echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. 28 | echo. 29 | echo Please set the JAVA_HOME variable in your environment to match the 30 | echo location of your Java installation. 31 | 32 | goto fail 33 | 34 | :findJavaFromJavaHome 35 | set JAVA_HOME=%JAVA_HOME:"=% 36 | set JAVA_EXE=%JAVA_HOME%/bin/java.exe 37 | 38 | if exist "%JAVA_EXE%" goto init 39 | 40 | echo. 41 | echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME% 42 | echo. 43 | echo Please set the JAVA_HOME variable in your environment to match the 44 | echo location of your Java installation. 45 | 46 | goto fail 47 | 48 | :init 49 | @rem Get command-line arguments, handling Windowz variants 50 | 51 | if not "%OS%" == "Windows_NT" goto win9xME_args 52 | if "%@eval[2+2]" == "4" goto 4NT_args 53 | 54 | :win9xME_args 55 | @rem Slurp the command line arguments. 56 | set CMD_LINE_ARGS= 57 | set _SKIP=2 58 | 59 | :win9xME_args_slurp 60 | if "x%~1" == "x" goto execute 61 | 62 | set CMD_LINE_ARGS=%* 63 | goto execute 64 | 65 | :4NT_args 66 | @rem Get arguments from the 4NT Shell from JP Software 67 | set CMD_LINE_ARGS=%$ 68 | 69 | :execute 70 | @rem Setup the command line 71 | 72 | set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar 73 | 74 | @rem Execute Gradle 75 | "%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %CMD_LINE_ARGS% 76 | 77 | :end 78 | @rem End local scope for the variables with windows NT shell 79 | if "%ERRORLEVEL%"=="0" goto mainEnd 80 | 81 | :fail 82 | rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of 83 | rem the _cmd.exe /c_ return code! 84 | if not "" == "%GRADLE_EXIT_CONSOLE%" exit 1 85 | exit /b 1 86 | 87 | :mainEnd 88 | if "%OS%"=="Windows_NT" endlocal 89 | 90 | :omega 91 | -------------------------------------------------------------------------------- /html/.settings/gradle/org.springsource.ide.eclipse.gradle.core.prefs: -------------------------------------------------------------------------------- 1 | #org.springsource.ide.eclipse.gradle.core.preferences.GradleProjectPreferences 2 | #Thu Nov 12 23:26:47 PST 2015 3 | org.springsource.ide.eclipse.gradle.rootprojectloc=.. 4 | -------------------------------------------------------------------------------- /settings.gradle: -------------------------------------------------------------------------------- 1 | include 'desktop', 'html', 'core' --------------------------------------------------------------------------------