├── .gitignore ├── README.md ├── app ├── .gitignore ├── build.gradle ├── proguard-rules.pro └── src │ ├── androidTest │ └── java │ │ └── com │ │ └── example │ │ └── androidstudio2dgamedevelopment │ │ └── ExampleInstrumentedTest.java │ ├── main │ ├── AndroidManifest.xml │ ├── java │ │ └── com │ │ │ └── example │ │ │ └── androidstudio2dgamedevelopment │ │ │ ├── Game.java │ │ │ ├── GameDisplay.java │ │ │ ├── GameLoop.java │ │ │ ├── MainActivity.java │ │ │ ├── Utils.java │ │ │ ├── gameobject │ │ │ ├── Circle.java │ │ │ ├── Enemy.java │ │ │ ├── GameObject.java │ │ │ ├── Player.java │ │ │ ├── PlayerState.java │ │ │ └── Spell.java │ │ │ ├── gamepanel │ │ │ ├── GameOver.java │ │ │ ├── HealthBar.java │ │ │ ├── Joystick.java │ │ │ └── Performance.java │ │ │ ├── graphics │ │ │ ├── Animator.java │ │ │ ├── Sprite.java │ │ │ └── SpriteSheet.java │ │ │ └── map │ │ │ ├── GrassTile.java │ │ │ ├── GroundTile.java │ │ │ ├── LavaTile.java │ │ │ ├── MapLayout.java │ │ │ ├── Tile.java │ │ │ ├── Tilemap.java │ │ │ ├── TreeTile.java │ │ │ └── WaterTile.java │ └── res │ │ ├── drawable-v24 │ │ ├── ic_launcher_foreground.xml │ │ └── sprite_sheet.png │ │ ├── drawable │ │ └── ic_launcher_background.xml │ │ ├── layout │ │ └── activity_main.xml │ │ ├── mipmap-anydpi-v26 │ │ ├── ic_launcher.xml │ │ └── ic_launcher_round.xml │ │ ├── mipmap-hdpi │ │ ├── ic_launcher.png │ │ └── ic_launcher_round.png │ │ ├── mipmap-mdpi │ │ ├── ic_launcher.png │ │ └── ic_launcher_round.png │ │ ├── mipmap-xhdpi │ │ ├── ic_launcher.png │ │ └── ic_launcher_round.png │ │ ├── mipmap-xxhdpi │ │ ├── ic_launcher.png │ │ └── ic_launcher_round.png │ │ ├── mipmap-xxxhdpi │ │ ├── ic_launcher.png │ │ └── ic_launcher_round.png │ │ └── values │ │ ├── colors.xml │ │ ├── strings.xml │ │ └── styles.xml │ └── test │ └── java │ └── com │ └── example │ └── androidstudio2dgamedevelopment │ └── ExampleUnitTest.java ├── build.gradle ├── gradle.properties ├── gradle └── wrapper │ ├── gradle-wrapper.jar │ └── gradle-wrapper.properties ├── gradlew ├── gradlew.bat └── settings.gradle /.gitignore: -------------------------------------------------------------------------------- 1 | *.iml 2 | .gradle 3 | /local.properties 4 | /.idea/caches 5 | /.idea/libraries 6 | /.idea/modules.xml 7 | /.idea/workspace.xml 8 | /.idea/navEditor.xml 9 | /.idea/assetWizardSettings.xml 10 | .DS_Store 11 | /build 12 | /captures 13 | .externalNativeBuild 14 | /.idea/ 15 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # AndroidStudio2DGameDevelopment 2 | This repo aims to build a realtime 2D Game for Android. 3 | 4 | The Game will be a multiplayer battleground game, where players can create and join game servers, and use spells and attacks to kill eachother. 5 | 6 | Primarily, this game is used for teaching game programming concepts from scrtch, and video tutorials can be found at: https://www.youtube.com/watch?v=GIc2GRCUI8s&list=PL2EfDMM6n_LYJdzaOQ5jZZ3Dj5L4tbAuM 7 | -------------------------------------------------------------------------------- /app/.gitignore: -------------------------------------------------------------------------------- 1 | /build 2 | -------------------------------------------------------------------------------- /app/build.gradle: -------------------------------------------------------------------------------- 1 | apply plugin: 'com.android.application' 2 | 3 | android { 4 | compileSdkVersion 28 5 | defaultConfig { 6 | applicationId "com.example.androidstudio2dgamedevelopment" 7 | minSdkVersion 22 8 | targetSdkVersion 28 9 | versionCode 1 10 | versionName "1.0" 11 | testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner" 12 | } 13 | buildTypes { 14 | release { 15 | minifyEnabled false 16 | proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro' 17 | } 18 | } 19 | } 20 | 21 | dependencies { 22 | implementation fileTree(dir: 'libs', include: ['*.jar']) 23 | implementation 'com.android.support:appcompat-v7:28.0.0' 24 | implementation 'com.android.support.constraint:constraint-layout:1.1.3' 25 | testImplementation 'junit:junit:4.12' 26 | androidTestImplementation 'com.android.support.test:runner:1.0.2' 27 | androidTestImplementation 'com.android.support.test.espresso:espresso-core:3.0.2' 28 | } 29 | -------------------------------------------------------------------------------- /app/proguard-rules.pro: -------------------------------------------------------------------------------- 1 | # Add project specific ProGuard rules here. 2 | # You can control the set of applied configuration files using the 3 | # proguardFiles setting in build.gradle. 4 | # 5 | # For more details, see 6 | # http://developer.android.com/guide/developing/tools/proguard.html 7 | 8 | # If your project uses WebView with JS, uncomment the following 9 | # and specify the fully qualified class name to the JavaScript interface 10 | # class: 11 | #-keepclassmembers class fqcn.of.javascript.interface.for.webview { 12 | # public *; 13 | #} 14 | 15 | # Uncomment this to preserve the line number information for 16 | # debugging stack traces. 17 | #-keepattributes SourceFile,LineNumberTable 18 | 19 | # If you keep the line number information, uncomment this to 20 | # hide the original source file name. 21 | #-renamesourcefileattribute SourceFile 22 | -------------------------------------------------------------------------------- /app/src/androidTest/java/com/example/androidstudio2dgamedevelopment/ExampleInstrumentedTest.java: -------------------------------------------------------------------------------- 1 | package com.example.androidstudio2dgamedevelopment; 2 | 3 | import android.content.Context; 4 | import android.support.test.InstrumentationRegistry; 5 | import android.support.test.runner.AndroidJUnit4; 6 | 7 | import org.junit.Test; 8 | import org.junit.runner.RunWith; 9 | 10 | import static org.junit.Assert.*; 11 | 12 | /** 13 | * Instrumented test, which will execute on an Android device. 14 | * 15 | * @see Testing documentation 16 | */ 17 | @RunWith(AndroidJUnit4.class) 18 | public class ExampleInstrumentedTest { 19 | @Test 20 | public void useAppContext() { 21 | // Context of the app under test. 22 | Context appContext = InstrumentationRegistry.getTargetContext(); 23 | 24 | assertEquals("com.example.androidstudio2dgamedevelopment", appContext.getPackageName()); 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /app/src/main/AndroidManifest.xml: -------------------------------------------------------------------------------- 1 | 2 | 4 | 5 | 12 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | -------------------------------------------------------------------------------- /app/src/main/java/com/example/androidstudio2dgamedevelopment/Game.java: -------------------------------------------------------------------------------- 1 | package com.example.androidstudio2dgamedevelopment; 2 | 3 | import android.app.Activity; 4 | import android.content.Context; 5 | import android.graphics.Canvas; 6 | import android.util.DisplayMetrics; 7 | import android.util.Log; 8 | import android.view.Display; 9 | import android.view.MotionEvent; 10 | import android.view.SurfaceHolder; 11 | import android.view.SurfaceView; 12 | 13 | import com.example.androidstudio2dgamedevelopment.gameobject.Circle; 14 | import com.example.androidstudio2dgamedevelopment.gameobject.Enemy; 15 | import com.example.androidstudio2dgamedevelopment.gameobject.Player; 16 | import com.example.androidstudio2dgamedevelopment.gameobject.Spell; 17 | import com.example.androidstudio2dgamedevelopment.gamepanel.GameOver; 18 | import com.example.androidstudio2dgamedevelopment.gamepanel.Joystick; 19 | import com.example.androidstudio2dgamedevelopment.gamepanel.Performance; 20 | import com.example.androidstudio2dgamedevelopment.graphics.Animator; 21 | import com.example.androidstudio2dgamedevelopment.graphics.SpriteSheet; 22 | import com.example.androidstudio2dgamedevelopment.map.Tilemap; 23 | 24 | import java.util.ArrayList; 25 | import java.util.Iterator; 26 | import java.util.List; 27 | 28 | /** 29 | * Game manages all objects in the game and is responsible for updating all states and render all 30 | * objects to the screen 31 | */ 32 | class Game extends SurfaceView implements SurfaceHolder.Callback { 33 | 34 | private final Tilemap tilemap; 35 | private int joystickPointerId = 0; 36 | private final Joystick joystick; 37 | private final Player player; 38 | private GameLoop gameLoop; 39 | private List enemyList = new ArrayList(); 40 | private List spellList = new ArrayList(); 41 | private int numberOfSpellsToCast = 0; 42 | private GameOver gameOver; 43 | private Performance performance; 44 | private GameDisplay gameDisplay; 45 | 46 | public Game(Context context) { 47 | super(context); 48 | 49 | // Get surface holder and add callback 50 | SurfaceHolder surfaceHolder = getHolder(); 51 | surfaceHolder.addCallback(this); 52 | 53 | gameLoop = new GameLoop(this, surfaceHolder); 54 | 55 | // Initialize game panels 56 | performance = new Performance(context, gameLoop); 57 | gameOver = new GameOver(context); 58 | joystick = new Joystick(275, 700, 70, 40); 59 | 60 | // Initialize game objects 61 | SpriteSheet spriteSheet = new SpriteSheet(context); 62 | Animator animator = new Animator(spriteSheet.getPlayerSpriteArray()); 63 | player = new Player(context, joystick, 2*500, 500, 32, animator); 64 | 65 | // Initialize display and center it around the player 66 | DisplayMetrics displayMetrics = new DisplayMetrics(); 67 | ((Activity) getContext()).getWindowManager().getDefaultDisplay().getMetrics(displayMetrics); 68 | gameDisplay = new GameDisplay(displayMetrics.widthPixels, displayMetrics.heightPixels, player); 69 | 70 | // Initialize Tilemap 71 | tilemap = new Tilemap(spriteSheet); 72 | 73 | setFocusable(true); 74 | } 75 | 76 | @Override 77 | public boolean onTouchEvent(MotionEvent event) { 78 | 79 | // Handle user input touch event actions 80 | switch (event.getActionMasked()) { 81 | case MotionEvent.ACTION_DOWN: 82 | case MotionEvent.ACTION_POINTER_DOWN: 83 | if (joystick.getIsPressed()) { 84 | // Joystick was pressed before this event -> cast spell 85 | numberOfSpellsToCast ++; 86 | } else if (joystick.isPressed((double) event.getX(), (double) event.getY())) { 87 | // Joystick is pressed in this event -> setIsPressed(true) and store pointer id 88 | joystickPointerId = event.getPointerId(event.getActionIndex()); 89 | joystick.setIsPressed(true); 90 | } else { 91 | // Joystick was not previously, and is not pressed in this event -> cast spell 92 | numberOfSpellsToCast ++; 93 | } 94 | return true; 95 | case MotionEvent.ACTION_MOVE: 96 | if (joystick.getIsPressed()) { 97 | // Joystick was pressed previously and is now moved 98 | joystick.setActuator((double) event.getX(), (double) event.getY()); 99 | } 100 | return true; 101 | 102 | case MotionEvent.ACTION_UP: 103 | case MotionEvent.ACTION_POINTER_UP: 104 | if (joystickPointerId == event.getPointerId(event.getActionIndex())) { 105 | // joystick pointer was let go off -> setIsPressed(false) and resetActuator() 106 | joystick.setIsPressed(false); 107 | joystick.resetActuator(); 108 | } 109 | return true; 110 | } 111 | 112 | return super.onTouchEvent(event); 113 | } 114 | 115 | @Override 116 | public void surfaceCreated(SurfaceHolder holder) { 117 | Log.d("Game.java", "surfaceCreated()"); 118 | if (gameLoop.getState().equals(Thread.State.TERMINATED)) { 119 | SurfaceHolder surfaceHolder = getHolder(); 120 | surfaceHolder.addCallback(this); 121 | gameLoop = new GameLoop(this, surfaceHolder); 122 | } 123 | gameLoop.startLoop(); 124 | } 125 | 126 | @Override 127 | public void surfaceChanged(SurfaceHolder holder, int format, int width, int height) { 128 | Log.d("Game.java", "surfaceChanged()"); 129 | } 130 | 131 | @Override 132 | public void surfaceDestroyed(SurfaceHolder holder) { 133 | Log.d("Game.java", "surfaceDestroyed()"); 134 | } 135 | 136 | @Override 137 | public void draw(Canvas canvas) { 138 | super.draw(canvas); 139 | 140 | // Draw Tilemap 141 | tilemap.draw(canvas, gameDisplay); 142 | 143 | // Draw game objects 144 | player.draw(canvas, gameDisplay); 145 | 146 | for (Enemy enemy : enemyList) { 147 | enemy.draw(canvas, gameDisplay); 148 | } 149 | 150 | for (Spell spell : spellList) { 151 | spell.draw(canvas, gameDisplay); 152 | } 153 | 154 | // Draw game panels 155 | joystick.draw(canvas); 156 | performance.draw(canvas); 157 | 158 | // Draw Game over if the player is dead 159 | if (player.getHealthPoint() <= 0) { 160 | gameOver.draw(canvas); 161 | } 162 | } 163 | 164 | public void update() { 165 | // Stop updating the game if the player is dead 166 | if (player.getHealthPoint() <= 0) { 167 | return; 168 | } 169 | 170 | // Update game state 171 | joystick.update(); 172 | player.update(); 173 | 174 | // Spawn enemy 175 | if(Enemy.readyToSpawn()) { 176 | enemyList.add(new Enemy(getContext(), player)); 177 | } 178 | 179 | // Update states of all enemies 180 | for (Enemy enemy : enemyList) { 181 | enemy.update(); 182 | } 183 | 184 | // Update states of all spells 185 | while (numberOfSpellsToCast > 0) { 186 | spellList.add(new Spell(getContext(), player)); 187 | numberOfSpellsToCast --; 188 | } 189 | for (Spell spell : spellList) { 190 | spell.update(); 191 | } 192 | 193 | // Iterate through enemyList and Check for collision between each enemy and the player and 194 | // spells in spellList. 195 | Iterator iteratorEnemy = enemyList.iterator(); 196 | while (iteratorEnemy.hasNext()) { 197 | Circle enemy = iteratorEnemy.next(); 198 | if (Circle.isColliding(enemy, player)) { 199 | // Remove enemy if it collides with the player 200 | iteratorEnemy.remove(); 201 | player.setHealthPoint(player.getHealthPoint() - 1); 202 | continue; 203 | } 204 | 205 | Iterator iteratorSpell = spellList.iterator(); 206 | while (iteratorSpell.hasNext()) { 207 | Circle spell = iteratorSpell.next(); 208 | // Remove enemy if it collides with a spell 209 | if (Circle.isColliding(spell, enemy)) { 210 | iteratorSpell.remove(); 211 | iteratorEnemy.remove(); 212 | break; 213 | } 214 | } 215 | } 216 | 217 | // Update gameDisplay so that it's center is set to the new center of the player's 218 | // game coordinates 219 | gameDisplay.update(); 220 | } 221 | 222 | public void pause() { 223 | gameLoop.stopLoop(); 224 | } 225 | } 226 | -------------------------------------------------------------------------------- /app/src/main/java/com/example/androidstudio2dgamedevelopment/GameDisplay.java: -------------------------------------------------------------------------------- 1 | package com.example.androidstudio2dgamedevelopment; 2 | 3 | import android.graphics.Rect; 4 | import android.view.Display; 5 | 6 | import com.example.androidstudio2dgamedevelopment.gameobject.GameObject; 7 | import com.example.androidstudio2dgamedevelopment.gameobject.Player; 8 | 9 | public class GameDisplay { 10 | public final Rect DISPLAY_RECT; 11 | private final int widthPixels; 12 | private final int heightPixels; 13 | private final GameObject centerObject; 14 | private final double displayCenterX; 15 | private final double displayCenterY; 16 | private double gameToDisplayCoordinatesOffsetX; 17 | private double gameToDisplayCoordinatesOffsetY; 18 | private double gameCenterX; 19 | private double gameCenterY; 20 | 21 | public GameDisplay(int widthPixels, int heightPixels, GameObject centerObject) { 22 | this.widthPixels = widthPixels; 23 | this.heightPixels = heightPixels; 24 | DISPLAY_RECT = new Rect(0, 0, widthPixels, heightPixels); 25 | 26 | this.centerObject = centerObject; 27 | 28 | displayCenterX = widthPixels/2.0; 29 | displayCenterY = heightPixels/2.0; 30 | 31 | update(); 32 | } 33 | 34 | public void update() { 35 | gameCenterX = centerObject.getPositionX(); 36 | gameCenterY = centerObject.getPositionY(); 37 | 38 | gameToDisplayCoordinatesOffsetX = displayCenterX - gameCenterX; 39 | gameToDisplayCoordinatesOffsetY = displayCenterY - gameCenterY; 40 | } 41 | 42 | public double gameToDisplayCoordinatesX(double x) { 43 | return x + gameToDisplayCoordinatesOffsetX; 44 | } 45 | 46 | public double gameToDisplayCoordinatesY(double y) { 47 | return y + gameToDisplayCoordinatesOffsetY; 48 | } 49 | 50 | public Rect getGameRect() { 51 | return new Rect( 52 | (int) (gameCenterX - widthPixels/2), 53 | (int) (gameCenterY - heightPixels/2), 54 | (int) (gameCenterX + widthPixels/2), 55 | (int) (gameCenterY + heightPixels/2) 56 | ); 57 | } 58 | } 59 | -------------------------------------------------------------------------------- /app/src/main/java/com/example/androidstudio2dgamedevelopment/GameLoop.java: -------------------------------------------------------------------------------- 1 | package com.example.androidstudio2dgamedevelopment; 2 | 3 | import android.graphics.Canvas; 4 | import android.util.Log; 5 | import android.view.SurfaceHolder; 6 | 7 | public class GameLoop extends Thread{ 8 | public static final double MAX_UPS = 30.0; 9 | private static final double UPS_PERIOD = 1E+3/MAX_UPS; 10 | 11 | private Game game; 12 | private SurfaceHolder surfaceHolder; 13 | 14 | private boolean isRunning = false; 15 | private double averageUPS; 16 | private double averageFPS; 17 | 18 | public GameLoop(Game game, SurfaceHolder surfaceHolder) { 19 | this.game = game; 20 | this.surfaceHolder = surfaceHolder; 21 | } 22 | 23 | public double getAverageUPS() { 24 | return averageUPS; 25 | } 26 | 27 | public double getAverageFPS() { 28 | return averageFPS; 29 | } 30 | 31 | public void startLoop() { 32 | Log.d("GameLoop.java", "startLoop()"); 33 | isRunning = true; 34 | start(); 35 | } 36 | 37 | @Override 38 | public void run() { 39 | Log.d("GameLoop.java", "run()"); 40 | super.run(); 41 | 42 | // Declare time and cycle count variables 43 | int updateCount = 0; 44 | int frameCount = 0; 45 | 46 | long startTime; 47 | long elapsedTime; 48 | long sleepTime; 49 | 50 | // Game loop 51 | Canvas canvas = null; 52 | startTime = System.currentTimeMillis(); 53 | while(isRunning) { 54 | 55 | // Try to update and render game 56 | try { 57 | canvas = surfaceHolder.lockCanvas(); 58 | synchronized (surfaceHolder) { 59 | game.update(); 60 | updateCount++; 61 | 62 | game.draw(canvas); 63 | } 64 | } catch (IllegalArgumentException e) { 65 | e.printStackTrace(); 66 | } finally { 67 | if(canvas != null) { 68 | try { 69 | surfaceHolder.unlockCanvasAndPost(canvas); 70 | frameCount++; 71 | } catch(Exception e) { 72 | e.printStackTrace(); 73 | } 74 | } 75 | } 76 | 77 | // Pause game loop to not exceed target UPS 78 | elapsedTime = System.currentTimeMillis() - startTime; 79 | sleepTime = (long) (updateCount*UPS_PERIOD - elapsedTime); 80 | if(sleepTime > 0) { 81 | try { 82 | sleep(sleepTime); 83 | } catch (InterruptedException e) { 84 | e.printStackTrace(); 85 | } 86 | } 87 | 88 | // Skip frames to keep up with target UPS 89 | while(sleepTime < 0 && updateCount < MAX_UPS-1) { 90 | game.update(); 91 | updateCount++; 92 | elapsedTime = System.currentTimeMillis() - startTime; 93 | sleepTime = (long) (updateCount*UPS_PERIOD - elapsedTime); 94 | } 95 | 96 | // Calculate average UPS and FPS 97 | elapsedTime = System.currentTimeMillis() - startTime; 98 | if(elapsedTime >= 1000) { 99 | averageUPS = updateCount / (1E-3 * elapsedTime); 100 | averageFPS = frameCount / (1E-3 * elapsedTime); 101 | updateCount = 0; 102 | frameCount = 0; 103 | startTime = System.currentTimeMillis(); 104 | } 105 | } 106 | } 107 | 108 | public void stopLoop() { 109 | Log.d("GameLoop.java", "stopLoop()"); 110 | isRunning = false; 111 | try { 112 | join(); 113 | } catch (InterruptedException e) { 114 | e.printStackTrace(); 115 | } 116 | } 117 | } 118 | -------------------------------------------------------------------------------- /app/src/main/java/com/example/androidstudio2dgamedevelopment/MainActivity.java: -------------------------------------------------------------------------------- 1 | package com.example.androidstudio2dgamedevelopment; 2 | 3 | import android.animation.Animator; 4 | import android.app.Activity; 5 | import android.os.Bundle; 6 | import android.util.Log; 7 | 8 | /** 9 | * MainActivity is the entry point to our application. 10 | */ 11 | public class MainActivity extends Activity { 12 | 13 | private Game game; 14 | 15 | @Override 16 | protected void onCreate(Bundle savedInstanceState) { 17 | Log.d("MainActivity.java", "onCreate()"); 18 | super.onCreate(savedInstanceState); 19 | 20 | // Set content view to game, so that objects in the Game class can be rendered to the screen 21 | game = new Game(this); 22 | setContentView(game); 23 | } 24 | 25 | @Override 26 | protected void onStart() { 27 | Log.d("MainActivity.java", "onStart()"); 28 | super.onStart(); 29 | } 30 | 31 | @Override 32 | protected void onResume() { 33 | Log.d("MainActivity.java", "onResume()"); 34 | super.onResume(); 35 | } 36 | 37 | @Override 38 | protected void onPause() { 39 | Log.d("MainActivity.java", "onPause()"); 40 | game.pause(); 41 | super.onPause(); 42 | } 43 | 44 | @Override 45 | protected void onStop() { 46 | Log.d("MainActivity.java", "onStop()"); 47 | super.onStop(); 48 | } 49 | 50 | @Override 51 | protected void onDestroy() { 52 | Log.d("MainActivity.java", "onDestroy()"); 53 | super.onDestroy(); 54 | } 55 | 56 | @Override 57 | public void onBackPressed() { 58 | // Comment out "super.onBackPressed()" to disable button 59 | //super.onBackPressed(); 60 | } 61 | } 62 | -------------------------------------------------------------------------------- /app/src/main/java/com/example/androidstudio2dgamedevelopment/Utils.java: -------------------------------------------------------------------------------- 1 | package com.example.androidstudio2dgamedevelopment; 2 | 3 | public class Utils { 4 | 5 | /** 6 | * getDistanceBetweenPoints returns the distance between 2d points p1 and p2 7 | * @param p1x 8 | * @param p1y 9 | * @param p2x 10 | * @param p2y 11 | * @return 12 | */ 13 | public static double getDistanceBetweenPoints(double p1x, double p1y, double p2x, double p2y) { 14 | return Math.sqrt(Math.pow(p1x - p2x, 2) + Math.pow(p1y - p2y, 2)); 15 | } 16 | } 17 | -------------------------------------------------------------------------------- /app/src/main/java/com/example/androidstudio2dgamedevelopment/gameobject/Circle.java: -------------------------------------------------------------------------------- 1 | package com.example.androidstudio2dgamedevelopment.gameobject; 2 | 3 | import android.content.Context; 4 | import android.graphics.Canvas; 5 | import android.graphics.Paint; 6 | 7 | import com.example.androidstudio2dgamedevelopment.GameDisplay; 8 | 9 | /** 10 | * Circle is an abstract class which implements a draw method from GameObject for drawing the object 11 | * as a circle. 12 | */ 13 | public abstract class Circle extends GameObject { 14 | protected double radius; 15 | protected Paint paint; 16 | 17 | public Circle(Context context, int color, double positionX, double positionY, double radius) { 18 | super(positionX, positionY); 19 | this.radius = radius; 20 | 21 | // Set colors of circle 22 | paint = new Paint(); 23 | paint.setColor(color); 24 | } 25 | 26 | /** 27 | * isColliding checks if two circle objects are colliding, based on their positions and radii. 28 | * @param obj1 29 | * @param obj2 30 | * @return 31 | */ 32 | public static boolean isColliding(Circle obj1, Circle obj2) { 33 | double distance = getDistanceBetweenObjects(obj1, obj2); 34 | double distanceToCollision = obj1.getRadius() + obj2.getRadius(); 35 | if (distance < distanceToCollision) 36 | return true; 37 | else 38 | return false; 39 | } 40 | 41 | public void draw(Canvas canvas, GameDisplay gameDisplay) { 42 | canvas.drawCircle( 43 | (float) gameDisplay.gameToDisplayCoordinatesX(positionX), 44 | (float) gameDisplay.gameToDisplayCoordinatesY(positionY), 45 | (float) radius, 46 | paint 47 | ); 48 | } 49 | 50 | public double getRadius() { 51 | return radius; 52 | } 53 | } -------------------------------------------------------------------------------- /app/src/main/java/com/example/androidstudio2dgamedevelopment/gameobject/Enemy.java: -------------------------------------------------------------------------------- 1 | package com.example.androidstudio2dgamedevelopment.gameobject; 2 | 3 | import android.content.Context; 4 | import android.support.v4.content.ContextCompat; 5 | 6 | import com.example.androidstudio2dgamedevelopment.GameLoop; 7 | import com.example.androidstudio2dgamedevelopment.R; 8 | 9 | /** 10 | * Enemy is a character which always moves in the direction of the player. 11 | * The Enemy class is an extension of a Circle, which is an extension of a GameObject 12 | */ 13 | public class Enemy extends Circle { 14 | 15 | private static final double SPEED_PIXELS_PER_SECOND = Player.SPEED_PIXELS_PER_SECOND*0.6; 16 | private static final double MAX_SPEED = SPEED_PIXELS_PER_SECOND / GameLoop.MAX_UPS; 17 | private static final double SPAWNS_PER_MINUTE = 20; 18 | private static final double SPAWNS_PER_SECOND = SPAWNS_PER_MINUTE/60.0; 19 | private static final double UPDATES_PER_SPAWN = GameLoop.MAX_UPS/SPAWNS_PER_SECOND; 20 | private static double updatesUntilNextSpawn = UPDATES_PER_SPAWN; 21 | private Player player; 22 | 23 | public Enemy(Context context, Player player, double positionX, double positionY, double radius) { 24 | super(context, ContextCompat.getColor(context, R.color.enemy), positionX, positionY, radius); 25 | this.player = player; 26 | } 27 | 28 | /** 29 | * Enemy is an overload constructor used for spawning enemies in random locations 30 | * @param context 31 | * @param player 32 | */ 33 | public Enemy(Context context, Player player) { 34 | super( 35 | context, 36 | ContextCompat.getColor(context, R.color.enemy), 37 | Math.random()*1000, 38 | Math.random()*1000, 39 | 30 40 | ); 41 | this.player = player; 42 | } 43 | 44 | /** 45 | * readyToSpawn checks if a new enemy should spawn, according to the decided number of spawns 46 | * per minute (see SPAWNS_PER_MINUTE at top) 47 | * @return 48 | */ 49 | public static boolean readyToSpawn() { 50 | if (updatesUntilNextSpawn <= 0) { 51 | updatesUntilNextSpawn += UPDATES_PER_SPAWN; 52 | return true; 53 | } else { 54 | updatesUntilNextSpawn --; 55 | return false; 56 | } 57 | } 58 | 59 | public void update() { 60 | // ========================================================================================= 61 | // Update velocity of the enemy so that the velocity is in the direction of the player 62 | // ========================================================================================= 63 | // Calculate vector from enemy to player (in x and y) 64 | double distanceToPlayerX = player.getPositionX() - positionX; 65 | double distanceToPlayerY = player.getPositionY() - positionY; 66 | 67 | // Calculate (absolute) distance between enemy (this) and player 68 | double distanceToPlayer = GameObject.getDistanceBetweenObjects(this, player); 69 | 70 | // Calculate direction from enemy to player 71 | double directionX = distanceToPlayerX/distanceToPlayer; 72 | double directionY = distanceToPlayerY/distanceToPlayer; 73 | 74 | // Set velocity in the direction to the player 75 | if(distanceToPlayer > 0) { // Avoid division by zero 76 | velocityX = directionX*MAX_SPEED; 77 | velocityY = directionY*MAX_SPEED; 78 | } else { 79 | velocityX = 0; 80 | velocityY = 0; 81 | } 82 | 83 | // ========================================================================================= 84 | // Update position of the enemy 85 | // ========================================================================================= 86 | positionX += velocityX; 87 | positionY += velocityY; 88 | } 89 | } 90 | 91 | -------------------------------------------------------------------------------- /app/src/main/java/com/example/androidstudio2dgamedevelopment/gameobject/GameObject.java: -------------------------------------------------------------------------------- 1 | package com.example.androidstudio2dgamedevelopment.gameobject; 2 | 3 | import android.graphics.Canvas; 4 | 5 | import com.example.androidstudio2dgamedevelopment.GameDisplay; 6 | 7 | /** 8 | * GameObject is an abstract class which is the foundation of all world objects in the game. 9 | */ 10 | public abstract class GameObject { 11 | protected double positionX, positionY = 0.0; 12 | protected double velocityX, velocityY = 0.0; 13 | protected double directionX = 1.0; 14 | protected double directionY = 0.0; 15 | 16 | public GameObject() { } 17 | 18 | public GameObject(double positionX, double positionY) { 19 | this.positionX = positionX; 20 | this.positionY = positionY; 21 | } 22 | 23 | public double getPositionX() { return positionX; } 24 | public double getPositionY() { return positionY; } 25 | 26 | public double getDirectionX() { return directionX; } 27 | public double getDirectionY() { return directionY; } 28 | 29 | public abstract void draw(Canvas canvas, GameDisplay gameDisplay); 30 | public abstract void update(); 31 | 32 | /** 33 | * getDistanceBetweenObjects returns the distance between two game objects 34 | * @param obj1 35 | * @param obj2 36 | * @return 37 | */ 38 | public static double getDistanceBetweenObjects(GameObject obj1, GameObject obj2) { 39 | return Math.sqrt( 40 | Math.pow(obj2.getPositionX() - obj1.getPositionX(), 2) + 41 | Math.pow(obj2.getPositionY() - obj1.getPositionY(), 2) 42 | ); 43 | } 44 | } 45 | -------------------------------------------------------------------------------- /app/src/main/java/com/example/androidstudio2dgamedevelopment/gameobject/Player.java: -------------------------------------------------------------------------------- 1 | package com.example.androidstudio2dgamedevelopment.gameobject; 2 | 3 | import android.content.Context; 4 | import android.graphics.Canvas; 5 | import android.support.v4.content.ContextCompat; 6 | 7 | import com.example.androidstudio2dgamedevelopment.GameDisplay; 8 | import com.example.androidstudio2dgamedevelopment.GameLoop; 9 | import com.example.androidstudio2dgamedevelopment.gamepanel.HealthBar; 10 | import com.example.androidstudio2dgamedevelopment.gamepanel.Joystick; 11 | import com.example.androidstudio2dgamedevelopment.R; 12 | import com.example.androidstudio2dgamedevelopment.Utils; 13 | import com.example.androidstudio2dgamedevelopment.graphics.Animator; 14 | import com.example.androidstudio2dgamedevelopment.graphics.Sprite; 15 | 16 | /** 17 | * Player is the main character of the game, which the user can control with a touch joystick. 18 | * The player class is an extension of a Circle, which is an extension of a GameObject 19 | */ 20 | public class Player extends Circle { 21 | public static final double SPEED_PIXELS_PER_SECOND = 400.0; 22 | private static final double MAX_SPEED = SPEED_PIXELS_PER_SECOND / GameLoop.MAX_UPS; 23 | public static final int MAX_HEALTH_POINTS = 5; 24 | private Joystick joystick; 25 | private HealthBar healthBar; 26 | private int healthPoints = MAX_HEALTH_POINTS; 27 | private Animator animator; 28 | private PlayerState playerState; 29 | 30 | public Player(Context context, Joystick joystick, double positionX, double positionY, double radius, Animator animator) { 31 | super(context, ContextCompat.getColor(context, R.color.player), positionX, positionY, radius); 32 | this.joystick = joystick; 33 | this.healthBar = new HealthBar(context, this); 34 | this.animator = animator; 35 | this.playerState = new PlayerState(this); 36 | } 37 | 38 | public void update() { 39 | 40 | // Update velocity based on actuator of joystick 41 | velocityX = joystick.getActuatorX()*MAX_SPEED; 42 | velocityY = joystick.getActuatorY()*MAX_SPEED; 43 | 44 | // Update position 45 | positionX += velocityX; 46 | positionY += velocityY; 47 | 48 | // Update direction 49 | if (velocityX != 0 || velocityY != 0) { 50 | // Normalize velocity to get direction (unit vector of velocity) 51 | double distance = Utils.getDistanceBetweenPoints(0, 0, velocityX, velocityY); 52 | directionX = velocityX/distance; 53 | directionY = velocityY/distance; 54 | } 55 | 56 | playerState.update(); 57 | } 58 | 59 | public void draw(Canvas canvas, GameDisplay gameDisplay) { 60 | animator.draw(canvas, gameDisplay, this); 61 | 62 | healthBar.draw(canvas, gameDisplay); 63 | } 64 | 65 | public int getHealthPoint() { 66 | return healthPoints; 67 | } 68 | 69 | public void setHealthPoint(int healthPoints) { 70 | // Only allow positive values 71 | if (healthPoints >= 0) 72 | this.healthPoints = healthPoints; 73 | } 74 | 75 | public PlayerState getPlayerState() { 76 | return playerState; 77 | } 78 | } 79 | -------------------------------------------------------------------------------- /app/src/main/java/com/example/androidstudio2dgamedevelopment/gameobject/PlayerState.java: -------------------------------------------------------------------------------- 1 | package com.example.androidstudio2dgamedevelopment.gameobject; 2 | 3 | public class PlayerState { 4 | 5 | public enum State { 6 | NOT_MOVING, 7 | STARED_MOVING, 8 | IS_MOVING 9 | } 10 | 11 | private Player player; 12 | private State state; 13 | 14 | public PlayerState(Player player) { 15 | this.player = player; 16 | this.state = State.NOT_MOVING; 17 | } 18 | 19 | public State getState() { 20 | return state; 21 | } 22 | 23 | public void update() { 24 | switch (state) { 25 | case NOT_MOVING: 26 | if (player.velocityX != 0 || player.velocityY != 0) 27 | state = State.STARED_MOVING; 28 | break; 29 | case STARED_MOVING: 30 | if (player.velocityX != 0 || player.velocityY != 0) 31 | state = State.IS_MOVING; 32 | break; 33 | case IS_MOVING: 34 | if (player.velocityX == 0 && player.velocityY == 0) 35 | state = State.NOT_MOVING; 36 | break; 37 | default: 38 | break; 39 | } 40 | } 41 | } 42 | -------------------------------------------------------------------------------- /app/src/main/java/com/example/androidstudio2dgamedevelopment/gameobject/Spell.java: -------------------------------------------------------------------------------- 1 | package com.example.androidstudio2dgamedevelopment.gameobject; 2 | 3 | import android.content.Context; 4 | import android.support.v4.content.ContextCompat; 5 | 6 | import com.example.androidstudio2dgamedevelopment.GameLoop; 7 | import com.example.androidstudio2dgamedevelopment.R; 8 | 9 | public class Spell extends Circle { 10 | public static final double SPEED_PIXELS_PER_SECOND = 800.0; 11 | private static final double MAX_SPEED = SPEED_PIXELS_PER_SECOND / GameLoop.MAX_UPS; 12 | 13 | public Spell(Context context, Player spellcaster) { 14 | super( 15 | context, 16 | ContextCompat.getColor(context, R.color.spell), 17 | spellcaster.getPositionX(), 18 | spellcaster.getPositionY(), 19 | 25 20 | ); 21 | velocityX = spellcaster.getDirectionX()*MAX_SPEED; 22 | velocityY = spellcaster.getDirectionY()*MAX_SPEED; 23 | } 24 | 25 | @Override 26 | public void update() { 27 | positionX = positionX + velocityX; 28 | positionY = positionY + velocityY; 29 | } 30 | } 31 | -------------------------------------------------------------------------------- /app/src/main/java/com/example/androidstudio2dgamedevelopment/gamepanel/GameOver.java: -------------------------------------------------------------------------------- 1 | package com.example.androidstudio2dgamedevelopment.gamepanel; 2 | 3 | import android.content.Context; 4 | import android.graphics.Canvas; 5 | import android.graphics.Paint; 6 | import android.support.v4.content.ContextCompat; 7 | 8 | import com.example.androidstudio2dgamedevelopment.R; 9 | 10 | 11 | /** 12 | * GameOver is a panel which draws the text Game Over to the screen. 13 | */ 14 | public class GameOver { 15 | 16 | private Context context; 17 | 18 | public GameOver(Context context) { 19 | this.context = context; 20 | } 21 | 22 | public void draw(Canvas canvas) { 23 | String text = "Game Over"; 24 | 25 | float x = 800; 26 | float y = 200; 27 | 28 | Paint paint = new Paint(); 29 | int color = ContextCompat.getColor(context, R.color.gameOver); 30 | paint.setColor(color); 31 | float textSize = 150; 32 | paint.setTextSize(textSize); 33 | 34 | canvas.drawText(text, x, y, paint); 35 | } 36 | } 37 | -------------------------------------------------------------------------------- /app/src/main/java/com/example/androidstudio2dgamedevelopment/gamepanel/HealthBar.java: -------------------------------------------------------------------------------- 1 | package com.example.androidstudio2dgamedevelopment.gamepanel; 2 | 3 | import android.content.Context; 4 | import android.graphics.Canvas; 5 | import android.graphics.Paint; 6 | import android.support.v4.content.ContextCompat; 7 | 8 | import com.example.androidstudio2dgamedevelopment.GameDisplay; 9 | import com.example.androidstudio2dgamedevelopment.R; 10 | import com.example.androidstudio2dgamedevelopment.gameobject.Player; 11 | 12 | /** 13 | * HealthBar display the players health to the screen 14 | */ 15 | public class HealthBar { 16 | private Player player; 17 | private Paint borderPaint, healthPaint; 18 | private int width, height, margin; // pixel value 19 | 20 | public HealthBar(Context context, Player player) { 21 | this.player = player; 22 | this.width = 100; 23 | this.height = 20; 24 | this.margin = 2; 25 | 26 | this.borderPaint = new Paint(); 27 | int borderColor = ContextCompat.getColor(context, R.color.healthBarBorder); 28 | borderPaint.setColor(borderColor); 29 | 30 | this.healthPaint = new Paint(); 31 | int healthColor = ContextCompat.getColor(context, R.color.healthBarHealth); 32 | healthPaint.setColor(healthColor); 33 | } 34 | 35 | public void draw(Canvas canvas, GameDisplay gameDisplay) { 36 | float x = (float) player.getPositionX(); 37 | float y = (float) player.getPositionY(); 38 | float distanceToPlayer = 30; 39 | float healthPointPercentage = (float) player.getHealthPoint()/player.MAX_HEALTH_POINTS; 40 | 41 | // Draw border 42 | float borderLeft, borderTop, borderRight, borderBottom; 43 | borderLeft = x - width/2; 44 | borderRight = x + width/2; 45 | borderBottom = y - distanceToPlayer; 46 | borderTop = borderBottom - height; 47 | canvas.drawRect( 48 | (float) gameDisplay.gameToDisplayCoordinatesX(borderLeft), 49 | (float) gameDisplay.gameToDisplayCoordinatesY(borderTop), 50 | (float) gameDisplay.gameToDisplayCoordinatesX(borderRight), 51 | (float) gameDisplay.gameToDisplayCoordinatesY(borderBottom), 52 | borderPaint); 53 | 54 | // Draw health 55 | float healthLeft, healthTop, healthRight, healthBottom, healthWidth, healthHeight; 56 | healthWidth = width - 2*margin; 57 | healthHeight = height - 2*margin; 58 | healthLeft = borderLeft + margin; 59 | healthRight = healthLeft + healthWidth*healthPointPercentage; 60 | healthBottom = borderBottom - margin; 61 | healthTop = healthBottom - healthHeight; 62 | canvas.drawRect( 63 | (float) gameDisplay.gameToDisplayCoordinatesX(healthLeft), 64 | (float) gameDisplay.gameToDisplayCoordinatesY(healthTop), 65 | (float) gameDisplay.gameToDisplayCoordinatesX(healthRight), 66 | (float) gameDisplay.gameToDisplayCoordinatesY(healthBottom), 67 | healthPaint); 68 | } 69 | } 70 | -------------------------------------------------------------------------------- /app/src/main/java/com/example/androidstudio2dgamedevelopment/gamepanel/Joystick.java: -------------------------------------------------------------------------------- 1 | package com.example.androidstudio2dgamedevelopment.gamepanel; 2 | 3 | import android.graphics.Canvas; 4 | import android.graphics.Color; 5 | import android.graphics.Paint; 6 | 7 | public class Joystick { 8 | 9 | private int outerCircleCenterPositionX; 10 | private int outerCircleCenterPositionY; 11 | private int innerCircleCenterPositionX; 12 | private int innerCircleCenterPositionY; 13 | 14 | private int outerCircleRadius; 15 | private int innerCircleRadius; 16 | 17 | private Paint innerCirclePaint; 18 | private Paint outerCirclePaint; 19 | private boolean isPressed = false; 20 | private double joystickCenterToTouchDistance; 21 | private double actuatorX; 22 | private double actuatorY; 23 | 24 | public Joystick(int centerPositionX, int centerPositionY, int outerCircleRadius, int innerCircleRadius) { 25 | 26 | // Outer and inner circle make up the joystick 27 | outerCircleCenterPositionX = centerPositionX; 28 | outerCircleCenterPositionY = centerPositionY; 29 | innerCircleCenterPositionX = centerPositionX; 30 | innerCircleCenterPositionY = centerPositionY; 31 | 32 | // Radii of circles 33 | this.outerCircleRadius = outerCircleRadius; 34 | this.innerCircleRadius = innerCircleRadius; 35 | 36 | // paint of circles 37 | outerCirclePaint = new Paint(); 38 | outerCirclePaint.setColor(Color.GRAY); 39 | outerCirclePaint.setStyle(Paint.Style.FILL_AND_STROKE); 40 | 41 | innerCirclePaint = new Paint(); 42 | innerCirclePaint.setColor(Color.BLUE); 43 | innerCirclePaint.setStyle(Paint.Style.FILL_AND_STROKE); 44 | } 45 | 46 | public void draw(Canvas canvas) { 47 | // Draw outer circle 48 | canvas.drawCircle( 49 | outerCircleCenterPositionX, 50 | outerCircleCenterPositionY, 51 | outerCircleRadius, 52 | outerCirclePaint 53 | ); 54 | 55 | // Draw inner circle 56 | canvas.drawCircle( 57 | innerCircleCenterPositionX, 58 | innerCircleCenterPositionY, 59 | innerCircleRadius, 60 | innerCirclePaint 61 | ); 62 | } 63 | 64 | public void update() { 65 | updateInnerCirclePosition(); 66 | } 67 | 68 | private void updateInnerCirclePosition() { 69 | innerCircleCenterPositionX = (int) (outerCircleCenterPositionX + actuatorX*outerCircleRadius); 70 | innerCircleCenterPositionY = (int) (outerCircleCenterPositionY + actuatorY*outerCircleRadius); 71 | } 72 | 73 | public void setActuator(double touchPositionX, double touchPositionY) { 74 | double deltaX = touchPositionX - outerCircleCenterPositionX; 75 | double deltaY = touchPositionY - outerCircleCenterPositionY; 76 | double deltaDistance = Math.sqrt(Math.pow(deltaX, 2) + Math.pow(deltaY, 2)); 77 | 78 | if(deltaDistance < outerCircleRadius) { 79 | actuatorX = deltaX/outerCircleRadius; 80 | actuatorY = deltaY/outerCircleRadius; 81 | } else { 82 | actuatorX = deltaX/deltaDistance; 83 | actuatorY = deltaY/deltaDistance; 84 | } 85 | } 86 | 87 | public boolean isPressed(double touchPositionX, double touchPositionY) { 88 | joystickCenterToTouchDistance = Math.sqrt( 89 | Math.pow(outerCircleCenterPositionX - touchPositionX, 2) + 90 | Math.pow(outerCircleCenterPositionY - touchPositionY, 2) 91 | ); 92 | return joystickCenterToTouchDistance < outerCircleRadius; 93 | } 94 | 95 | public boolean getIsPressed() { 96 | return isPressed; 97 | } 98 | 99 | public void setIsPressed(boolean isPressed) { 100 | this.isPressed = isPressed; 101 | } 102 | 103 | public double getActuatorX() { 104 | return actuatorX; 105 | } 106 | 107 | public double getActuatorY() { 108 | return actuatorY; 109 | } 110 | 111 | public void resetActuator() { 112 | actuatorX = 0; 113 | actuatorY = 0; 114 | } 115 | } 116 | -------------------------------------------------------------------------------- /app/src/main/java/com/example/androidstudio2dgamedevelopment/gamepanel/Performance.java: -------------------------------------------------------------------------------- 1 | package com.example.androidstudio2dgamedevelopment.gamepanel; 2 | 3 | import android.content.Context; 4 | import android.graphics.Canvas; 5 | import android.graphics.Paint; 6 | import android.support.v4.content.ContextCompat; 7 | 8 | import com.example.androidstudio2dgamedevelopment.GameLoop; 9 | import com.example.androidstudio2dgamedevelopment.R; 10 | 11 | public class Performance { 12 | private GameLoop gameLoop; 13 | private Context context; 14 | 15 | public Performance(Context context, GameLoop gameLoop) { 16 | this.context = context; 17 | this.gameLoop = gameLoop; 18 | } 19 | 20 | public void draw(Canvas canvas) { 21 | drawUPS(canvas); 22 | drawFPS(canvas); 23 | } 24 | public void drawUPS(Canvas canvas) { 25 | String averageUPS = Double.toString(gameLoop.getAverageUPS()); 26 | Paint paint = new Paint(); 27 | int color = ContextCompat.getColor(context, R.color.magenta); 28 | paint.setColor(color); 29 | paint.setTextSize(50); 30 | canvas.drawText("UPS: " + averageUPS, 100, 100, paint); 31 | } 32 | 33 | public void drawFPS(Canvas canvas) { 34 | String averageFPS = Double.toString(gameLoop.getAverageFPS()); 35 | Paint paint = new Paint(); 36 | int color = ContextCompat.getColor(context, R.color.magenta); 37 | paint.setColor(color); 38 | paint.setTextSize(50); 39 | canvas.drawText("FPS: " + averageFPS, 100, 200, paint); 40 | } 41 | } 42 | -------------------------------------------------------------------------------- /app/src/main/java/com/example/androidstudio2dgamedevelopment/graphics/Animator.java: -------------------------------------------------------------------------------- 1 | package com.example.androidstudio2dgamedevelopment.graphics; 2 | 3 | import android.graphics.Canvas; 4 | 5 | import com.example.androidstudio2dgamedevelopment.GameDisplay; 6 | import com.example.androidstudio2dgamedevelopment.gameobject.Player; 7 | import com.example.androidstudio2dgamedevelopment.gameobject.PlayerState; 8 | 9 | public class Animator { 10 | private Sprite[] playerSpriteArray; 11 | private int idxNotMovingFrame = 0; 12 | private int idxMovingFrame = 1; 13 | private int updatesBeforeNextMoveFrame; 14 | private static final int MAX_UPDATES_BEFORE_NEXT_MOVE_FRAME = 5; 15 | 16 | public Animator(Sprite[] playerSpriteArray) { 17 | this.playerSpriteArray = playerSpriteArray; 18 | } 19 | 20 | 21 | public void draw(Canvas canvas, GameDisplay gameDisplay, Player player) { 22 | switch (player.getPlayerState().getState()) { 23 | case NOT_MOVING: 24 | drawFrame(canvas, gameDisplay, player, playerSpriteArray[idxNotMovingFrame]); 25 | break; 26 | case STARED_MOVING: 27 | updatesBeforeNextMoveFrame = MAX_UPDATES_BEFORE_NEXT_MOVE_FRAME; 28 | drawFrame(canvas, gameDisplay, player, playerSpriteArray[idxMovingFrame]); 29 | break; 30 | case IS_MOVING: 31 | updatesBeforeNextMoveFrame--; 32 | if(updatesBeforeNextMoveFrame == 0) { 33 | updatesBeforeNextMoveFrame = MAX_UPDATES_BEFORE_NEXT_MOVE_FRAME; 34 | toggleIdxMovingFrame(); 35 | } 36 | drawFrame(canvas, gameDisplay, player, playerSpriteArray[idxMovingFrame]); 37 | break; 38 | default: 39 | break; 40 | } 41 | } 42 | 43 | private void toggleIdxMovingFrame() { 44 | if(idxMovingFrame == 1) 45 | idxMovingFrame = 2; 46 | else 47 | idxMovingFrame = 1; 48 | } 49 | 50 | public void drawFrame(Canvas canvas, GameDisplay gameDisplay, Player player, Sprite sprite) { 51 | sprite.draw( 52 | canvas, 53 | (int) gameDisplay.gameToDisplayCoordinatesX(player.getPositionX()) - sprite.getWidth()/2, 54 | (int) gameDisplay.gameToDisplayCoordinatesY(player.getPositionY()) - sprite.getHeight()/2 55 | ); 56 | } 57 | } 58 | -------------------------------------------------------------------------------- /app/src/main/java/com/example/androidstudio2dgamedevelopment/graphics/Sprite.java: -------------------------------------------------------------------------------- 1 | package com.example.androidstudio2dgamedevelopment.graphics; 2 | 3 | import android.graphics.Bitmap; 4 | import android.graphics.Canvas; 5 | import android.graphics.Rect; 6 | 7 | public class Sprite { 8 | 9 | private final SpriteSheet spriteSheet; 10 | private final Rect rect; 11 | 12 | public Sprite(SpriteSheet spriteSheet, Rect rect) { 13 | this.spriteSheet = spriteSheet; 14 | this.rect = rect; 15 | } 16 | 17 | public void draw(Canvas canvas, int x, int y) { 18 | canvas.drawBitmap( 19 | spriteSheet.getBitmap(), 20 | rect, 21 | new Rect(x, y, x+getWidth(), y+getHeight()), 22 | null 23 | ); 24 | } 25 | 26 | public int getWidth() { 27 | return rect.width(); 28 | } 29 | 30 | public int getHeight() { 31 | return rect.height(); 32 | } 33 | 34 | 35 | } 36 | -------------------------------------------------------------------------------- /app/src/main/java/com/example/androidstudio2dgamedevelopment/graphics/SpriteSheet.java: -------------------------------------------------------------------------------- 1 | package com.example.androidstudio2dgamedevelopment.graphics; 2 | 3 | import android.content.Context; 4 | import android.graphics.Bitmap; 5 | import android.graphics.BitmapFactory; 6 | import android.graphics.Rect; 7 | 8 | import com.example.androidstudio2dgamedevelopment.R; 9 | 10 | public class SpriteSheet { 11 | private static final int SPRITE_WIDTH_PIXELS = 64; 12 | private static final int SPRITE_HEIGHT_PIXELS = 64; 13 | private Bitmap bitmap; 14 | 15 | public SpriteSheet(Context context) { 16 | BitmapFactory.Options bitmapOptions = new BitmapFactory.Options(); 17 | bitmapOptions.inScaled = false; 18 | bitmap = BitmapFactory.decodeResource(context.getResources(), R.drawable.sprite_sheet, bitmapOptions); 19 | } 20 | 21 | public Sprite[] getPlayerSpriteArray() { 22 | Sprite[] spriteArray = new Sprite[3]; 23 | spriteArray[0] = new Sprite(this, new Rect(0*64, 0, 1*64, 64)); 24 | spriteArray[1] = new Sprite(this, new Rect(1*64, 0, 2*64, 64)); 25 | spriteArray[2] = new Sprite(this, new Rect(2*64, 0, 3*64, 64)); 26 | return spriteArray; 27 | } 28 | 29 | public Bitmap getBitmap() { 30 | return bitmap; 31 | } 32 | 33 | public Sprite getWaterSprite() { 34 | return getSpriteByIndex(1, 0); 35 | } 36 | 37 | public Sprite getLavaSprite() { 38 | return getSpriteByIndex(1, 1); 39 | } 40 | 41 | public Sprite getGroundSprite() { 42 | return getSpriteByIndex(1, 2); 43 | } 44 | 45 | public Sprite getGrassSprite() { 46 | return getSpriteByIndex(1, 3); 47 | } 48 | 49 | public Sprite getTreeSprite() { 50 | return getSpriteByIndex(1, 4); 51 | } 52 | 53 | 54 | private Sprite getSpriteByIndex(int idxRow, int idxCol) { 55 | return new Sprite(this, new Rect( 56 | idxCol*SPRITE_WIDTH_PIXELS, 57 | idxRow*SPRITE_HEIGHT_PIXELS, 58 | (idxCol + 1)*SPRITE_WIDTH_PIXELS, 59 | (idxRow + 1)*SPRITE_HEIGHT_PIXELS 60 | )); 61 | } 62 | } 63 | -------------------------------------------------------------------------------- /app/src/main/java/com/example/androidstudio2dgamedevelopment/map/GrassTile.java: -------------------------------------------------------------------------------- 1 | package com.example.androidstudio2dgamedevelopment.map; 2 | 3 | import android.graphics.Canvas; 4 | import android.graphics.Rect; 5 | 6 | import com.example.androidstudio2dgamedevelopment.graphics.Sprite; 7 | import com.example.androidstudio2dgamedevelopment.graphics.SpriteSheet; 8 | 9 | class GrassTile extends Tile { 10 | private final Sprite sprite; 11 | 12 | public GrassTile(SpriteSheet spriteSheet, Rect mapLocationRect) { 13 | super(mapLocationRect); 14 | sprite = spriteSheet.getGrassSprite(); 15 | } 16 | 17 | @Override 18 | public void draw(Canvas canvas) { 19 | sprite.draw(canvas, mapLocationRect.left, mapLocationRect.top); 20 | } 21 | } 22 | -------------------------------------------------------------------------------- /app/src/main/java/com/example/androidstudio2dgamedevelopment/map/GroundTile.java: -------------------------------------------------------------------------------- 1 | package com.example.androidstudio2dgamedevelopment.map; 2 | 3 | import android.graphics.Canvas; 4 | import android.graphics.Rect; 5 | 6 | import com.example.androidstudio2dgamedevelopment.graphics.Sprite; 7 | import com.example.androidstudio2dgamedevelopment.graphics.SpriteSheet; 8 | 9 | class GroundTile extends Tile { 10 | private final Sprite sprite; 11 | 12 | public GroundTile(SpriteSheet spriteSheet, Rect mapLocationRect) { 13 | super(mapLocationRect); 14 | sprite = spriteSheet.getGroundSprite(); 15 | } 16 | 17 | @Override 18 | public void draw(Canvas canvas) { 19 | sprite.draw(canvas, mapLocationRect.left, mapLocationRect.top); 20 | } 21 | } 22 | -------------------------------------------------------------------------------- /app/src/main/java/com/example/androidstudio2dgamedevelopment/map/LavaTile.java: -------------------------------------------------------------------------------- 1 | package com.example.androidstudio2dgamedevelopment.map; 2 | 3 | import android.graphics.Canvas; 4 | import android.graphics.Rect; 5 | 6 | import com.example.androidstudio2dgamedevelopment.graphics.Sprite; 7 | import com.example.androidstudio2dgamedevelopment.graphics.SpriteSheet; 8 | 9 | class LavaTile extends Tile { 10 | private final Sprite sprite; 11 | 12 | public LavaTile(SpriteSheet spriteSheet, Rect mapLocationRect) { 13 | super(mapLocationRect); 14 | sprite = spriteSheet.getLavaSprite(); 15 | } 16 | 17 | @Override 18 | public void draw(Canvas canvas) { 19 | sprite.draw(canvas, mapLocationRect.left, mapLocationRect.top); 20 | } 21 | } 22 | -------------------------------------------------------------------------------- /app/src/main/java/com/example/androidstudio2dgamedevelopment/map/MapLayout.java: -------------------------------------------------------------------------------- 1 | package com.example.androidstudio2dgamedevelopment.map; 2 | 3 | public class MapLayout { 4 | public static final int TILE_WIDTH_PIXELS = 64; 5 | public static final int TILE_HEIGHT_PIXELS = 64; 6 | public static final int NUMBER_OF_ROW_TILES = 60; 7 | public static final int NUMBER_OF_COLUMN_TILES = 60; 8 | 9 | private int[][] layout; 10 | 11 | public MapLayout() { 12 | initializeLayout(); 13 | } 14 | 15 | public int[][] getLayout() { 16 | return layout; 17 | } 18 | 19 | private void initializeLayout() { 20 | layout = new int[][] { 21 | {2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2}, 22 | {2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2}, 23 | {2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2}, 24 | {2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2}, 25 | {2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,4,3,3,4,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2}, 26 | {2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,4,3,3,4,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2}, 27 | {2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2}, 28 | {2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,0,0,2,2,0,0,2,2,2,1,1,1,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2}, 29 | {2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,0,0,2,2,0,0,2,2,2,1,1,1,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2}, 30 | {2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,0,0,2,2,0,0,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2}, 31 | {2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2}, 32 | {2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2}, 33 | {2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2}, 34 | {2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2}, 35 | {2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2}, 36 | {2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2}, 37 | {2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2}, 38 | {2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2}, 39 | {2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2}, 40 | {2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2}, 41 | {2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2}, 42 | {2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2}, 43 | {2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2}, 44 | {2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2}, 45 | {2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2}, 46 | {2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2}, 47 | {2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2}, 48 | {2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2}, 49 | {2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2}, 50 | {2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2}, 51 | {2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2}, 52 | {2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2}, 53 | {2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2}, 54 | {2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2}, 55 | {2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2}, 56 | {2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2}, 57 | {2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2}, 58 | {2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2}, 59 | {2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2}, 60 | {2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2}, 61 | {2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2}, 62 | {2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2}, 63 | {2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2}, 64 | {2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2}, 65 | {2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2}, 66 | {2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2}, 67 | {2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2}, 68 | {2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2}, 69 | {2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2}, 70 | {2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2}, 71 | {2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2}, 72 | {2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2}, 73 | {2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2}, 74 | {2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2}, 75 | {2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2}, 76 | {2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2}, 77 | {2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2}, 78 | {2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2}, 79 | {2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2}, 80 | {2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2} 81 | }; 82 | } 83 | } 84 | -------------------------------------------------------------------------------- /app/src/main/java/com/example/androidstudio2dgamedevelopment/map/Tile.java: -------------------------------------------------------------------------------- 1 | package com.example.androidstudio2dgamedevelopment.map; 2 | 3 | import android.graphics.Canvas; 4 | import android.graphics.Rect; 5 | 6 | import com.example.androidstudio2dgamedevelopment.graphics.SpriteSheet; 7 | 8 | abstract class Tile { 9 | 10 | protected final Rect mapLocationRect; 11 | 12 | public Tile(Rect mapLocationRect) { 13 | this.mapLocationRect = mapLocationRect; 14 | } 15 | 16 | public enum TileType { 17 | WATER_TILE, 18 | LAVA_TILE, 19 | GROUND_TILE, 20 | GRASS_TILE, 21 | TREE_TILE 22 | } 23 | 24 | public static Tile getTile(int idxTileType, SpriteSheet spriteSheet, Rect mapLocationRect) { 25 | 26 | switch(TileType.values()[idxTileType]) { 27 | 28 | case WATER_TILE: 29 | return new WaterTile(spriteSheet, mapLocationRect); 30 | case LAVA_TILE: 31 | return new LavaTile(spriteSheet, mapLocationRect); 32 | case GROUND_TILE: 33 | return new GroundTile(spriteSheet, mapLocationRect); 34 | case GRASS_TILE: 35 | return new GrassTile(spriteSheet, mapLocationRect); 36 | case TREE_TILE: 37 | return new TreeTile(spriteSheet, mapLocationRect); 38 | default: 39 | return null; 40 | } 41 | 42 | } 43 | 44 | public abstract void draw(Canvas canvas); 45 | } 46 | -------------------------------------------------------------------------------- /app/src/main/java/com/example/androidstudio2dgamedevelopment/map/Tilemap.java: -------------------------------------------------------------------------------- 1 | package com.example.androidstudio2dgamedevelopment.map; 2 | 3 | import android.graphics.Bitmap; 4 | import android.graphics.Canvas; 5 | import android.graphics.Rect; 6 | 7 | import com.example.androidstudio2dgamedevelopment.GameDisplay; 8 | import com.example.androidstudio2dgamedevelopment.graphics.SpriteSheet; 9 | 10 | import static com.example.androidstudio2dgamedevelopment.map.MapLayout.NUMBER_OF_COLUMN_TILES; 11 | import static com.example.androidstudio2dgamedevelopment.map.MapLayout.NUMBER_OF_ROW_TILES; 12 | import static com.example.androidstudio2dgamedevelopment.map.MapLayout.TILE_HEIGHT_PIXELS; 13 | import static com.example.androidstudio2dgamedevelopment.map.MapLayout.TILE_WIDTH_PIXELS; 14 | 15 | public class Tilemap { 16 | 17 | private final MapLayout mapLayout; 18 | private Tile[][] tilemap; 19 | private SpriteSheet spriteSheet; 20 | private Bitmap mapBitmap; 21 | 22 | public Tilemap(SpriteSheet spriteSheet) { 23 | mapLayout = new MapLayout(); 24 | this.spriteSheet = spriteSheet; 25 | initializeTilemap(); 26 | } 27 | 28 | private void initializeTilemap() { 29 | int[][] layout = mapLayout.getLayout(); 30 | tilemap = new Tile[NUMBER_OF_ROW_TILES][NUMBER_OF_COLUMN_TILES]; 31 | for (int iRow = 0; iRow < NUMBER_OF_ROW_TILES; iRow++) { 32 | for (int iCol = 0; iCol < NUMBER_OF_COLUMN_TILES; iCol++) { 33 | tilemap[iRow][iCol] = Tile.getTile( 34 | layout[iRow][iCol], 35 | spriteSheet, 36 | getRectByIndex(iRow, iCol) 37 | ); 38 | } 39 | } 40 | 41 | Bitmap.Config config = Bitmap.Config.ARGB_8888; 42 | mapBitmap = Bitmap.createBitmap( 43 | NUMBER_OF_COLUMN_TILES*TILE_WIDTH_PIXELS, 44 | NUMBER_OF_ROW_TILES*TILE_HEIGHT_PIXELS, 45 | config 46 | ); 47 | 48 | Canvas mapCanvas = new Canvas(mapBitmap); 49 | 50 | for (int iRow = 0; iRow < NUMBER_OF_ROW_TILES; iRow++) { 51 | for (int iCol = 0; iCol < NUMBER_OF_COLUMN_TILES; iCol++) { 52 | tilemap[iRow][iCol].draw(mapCanvas); 53 | } 54 | } 55 | 56 | } 57 | 58 | private Rect getRectByIndex(int idxRow, int idxCol) { 59 | return new Rect( 60 | idxCol*TILE_WIDTH_PIXELS, 61 | idxRow*TILE_HEIGHT_PIXELS, 62 | (idxCol + 1)*TILE_WIDTH_PIXELS, 63 | (idxRow + 1)*TILE_HEIGHT_PIXELS 64 | ); 65 | } 66 | 67 | public void draw(Canvas canvas, GameDisplay gameDisplay) { 68 | canvas.drawBitmap( 69 | mapBitmap, 70 | gameDisplay.getGameRect(), 71 | gameDisplay.DISPLAY_RECT, 72 | null 73 | ); 74 | } 75 | } 76 | -------------------------------------------------------------------------------- /app/src/main/java/com/example/androidstudio2dgamedevelopment/map/TreeTile.java: -------------------------------------------------------------------------------- 1 | package com.example.androidstudio2dgamedevelopment.map; 2 | 3 | import android.graphics.Canvas; 4 | import android.graphics.Rect; 5 | 6 | import com.example.androidstudio2dgamedevelopment.graphics.Sprite; 7 | import com.example.androidstudio2dgamedevelopment.graphics.SpriteSheet; 8 | 9 | class TreeTile extends Tile { 10 | private final Sprite grassSprite; 11 | private final Sprite treeSprite; 12 | 13 | public TreeTile(SpriteSheet spriteSheet, Rect mapLocationRect) { 14 | super(mapLocationRect); 15 | grassSprite = spriteSheet.getGrassSprite(); 16 | treeSprite = spriteSheet.getTreeSprite(); 17 | } 18 | 19 | @Override 20 | public void draw(Canvas canvas) { 21 | grassSprite.draw(canvas, mapLocationRect.left, mapLocationRect.top); 22 | treeSprite.draw(canvas, mapLocationRect.left, mapLocationRect.top); 23 | } 24 | } 25 | -------------------------------------------------------------------------------- /app/src/main/java/com/example/androidstudio2dgamedevelopment/map/WaterTile.java: -------------------------------------------------------------------------------- 1 | package com.example.androidstudio2dgamedevelopment.map; 2 | 3 | import android.graphics.Canvas; 4 | import android.graphics.Rect; 5 | 6 | import com.example.androidstudio2dgamedevelopment.graphics.Sprite; 7 | import com.example.androidstudio2dgamedevelopment.graphics.SpriteSheet; 8 | 9 | class WaterTile extends Tile { 10 | private final Sprite sprite; 11 | 12 | public WaterTile(SpriteSheet spriteSheet, Rect mapLocationRect) { 13 | super(mapLocationRect); 14 | sprite = spriteSheet.getWaterSprite(); 15 | } 16 | 17 | @Override 18 | public void draw(Canvas canvas) { 19 | sprite.draw(canvas, mapLocationRect.left, mapLocationRect.top); 20 | } 21 | } 22 | -------------------------------------------------------------------------------- /app/src/main/res/drawable-v24/ic_launcher_foreground.xml: -------------------------------------------------------------------------------- 1 | 7 | 12 | 13 | 19 | 22 | 25 | 26 | 27 | 28 | 34 | 35 | -------------------------------------------------------------------------------- /app/src/main/res/drawable-v24/sprite_sheet.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/bukkalexander/AndroidStudio2DGameDevelopment/6087a15491a9b9f685b9de1334336cb1a899ad9f/app/src/main/res/drawable-v24/sprite_sheet.png -------------------------------------------------------------------------------- /app/src/main/res/drawable/ic_launcher_background.xml: -------------------------------------------------------------------------------- 1 | 2 | 7 | 10 | 15 | 20 | 25 | 30 | 35 | 40 | 45 | 50 | 55 | 60 | 65 | 70 | 75 | 80 | 85 | 90 | 95 | 100 | 105 | 110 | 115 | 120 | 125 | 130 | 135 | 140 | 145 | 150 | 155 | 160 | 165 | 170 | 171 | -------------------------------------------------------------------------------- /app/src/main/res/layout/activity_main.xml: -------------------------------------------------------------------------------- 1 | 2 | 8 | 9 | 17 | 18 | -------------------------------------------------------------------------------- /app/src/main/res/mipmap-anydpi-v26/ic_launcher.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | -------------------------------------------------------------------------------- /app/src/main/res/mipmap-anydpi-v26/ic_launcher_round.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | -------------------------------------------------------------------------------- /app/src/main/res/mipmap-hdpi/ic_launcher.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/bukkalexander/AndroidStudio2DGameDevelopment/6087a15491a9b9f685b9de1334336cb1a899ad9f/app/src/main/res/mipmap-hdpi/ic_launcher.png -------------------------------------------------------------------------------- /app/src/main/res/mipmap-hdpi/ic_launcher_round.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/bukkalexander/AndroidStudio2DGameDevelopment/6087a15491a9b9f685b9de1334336cb1a899ad9f/app/src/main/res/mipmap-hdpi/ic_launcher_round.png -------------------------------------------------------------------------------- /app/src/main/res/mipmap-mdpi/ic_launcher.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/bukkalexander/AndroidStudio2DGameDevelopment/6087a15491a9b9f685b9de1334336cb1a899ad9f/app/src/main/res/mipmap-mdpi/ic_launcher.png -------------------------------------------------------------------------------- /app/src/main/res/mipmap-mdpi/ic_launcher_round.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/bukkalexander/AndroidStudio2DGameDevelopment/6087a15491a9b9f685b9de1334336cb1a899ad9f/app/src/main/res/mipmap-mdpi/ic_launcher_round.png -------------------------------------------------------------------------------- /app/src/main/res/mipmap-xhdpi/ic_launcher.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/bukkalexander/AndroidStudio2DGameDevelopment/6087a15491a9b9f685b9de1334336cb1a899ad9f/app/src/main/res/mipmap-xhdpi/ic_launcher.png -------------------------------------------------------------------------------- /app/src/main/res/mipmap-xhdpi/ic_launcher_round.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/bukkalexander/AndroidStudio2DGameDevelopment/6087a15491a9b9f685b9de1334336cb1a899ad9f/app/src/main/res/mipmap-xhdpi/ic_launcher_round.png -------------------------------------------------------------------------------- /app/src/main/res/mipmap-xxhdpi/ic_launcher.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/bukkalexander/AndroidStudio2DGameDevelopment/6087a15491a9b9f685b9de1334336cb1a899ad9f/app/src/main/res/mipmap-xxhdpi/ic_launcher.png -------------------------------------------------------------------------------- /app/src/main/res/mipmap-xxhdpi/ic_launcher_round.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/bukkalexander/AndroidStudio2DGameDevelopment/6087a15491a9b9f685b9de1334336cb1a899ad9f/app/src/main/res/mipmap-xxhdpi/ic_launcher_round.png -------------------------------------------------------------------------------- /app/src/main/res/mipmap-xxxhdpi/ic_launcher.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/bukkalexander/AndroidStudio2DGameDevelopment/6087a15491a9b9f685b9de1334336cb1a899ad9f/app/src/main/res/mipmap-xxxhdpi/ic_launcher.png -------------------------------------------------------------------------------- /app/src/main/res/mipmap-xxxhdpi/ic_launcher_round.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/bukkalexander/AndroidStudio2DGameDevelopment/6087a15491a9b9f685b9de1334336cb1a899ad9f/app/src/main/res/mipmap-xxxhdpi/ic_launcher_round.png -------------------------------------------------------------------------------- /app/src/main/res/values/colors.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | #008577 4 | #00574B 5 | #D81B60 6 | #FFFFFF 7 | #FF09FF 8 | #FF0000 9 | #00FFFF 10 | #FF9400 11 | #A0A0A0 12 | #00FF00 13 | #FC5245 14 | 15 | -------------------------------------------------------------------------------- /app/src/main/res/values/strings.xml: -------------------------------------------------------------------------------- 1 | 2 | AndroidStudio2DGameDevelopment 3 | 4 | -------------------------------------------------------------------------------- /app/src/main/res/values/styles.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 10 | 11 | 12 | -------------------------------------------------------------------------------- /app/src/test/java/com/example/androidstudio2dgamedevelopment/ExampleUnitTest.java: -------------------------------------------------------------------------------- 1 | package com.example.androidstudio2dgamedevelopment; 2 | 3 | import org.junit.Test; 4 | 5 | import static org.junit.Assert.*; 6 | 7 | /** 8 | * Example local unit test, which will execute on the development machine (host). 9 | * 10 | * @see Testing documentation 11 | */ 12 | public class ExampleUnitTest { 13 | @Test 14 | public void addition_isCorrect() { 15 | assertEquals(4, 2 + 2); 16 | } 17 | } -------------------------------------------------------------------------------- /build.gradle: -------------------------------------------------------------------------------- 1 | // Top-level build file where you can add configuration options common to all sub-projects/modules. 2 | 3 | buildscript { 4 | repositories { 5 | google() 6 | jcenter() 7 | 8 | } 9 | dependencies { 10 | classpath 'com.android.tools.build:gradle:3.6.2' 11 | 12 | // NOTE: Do not place your application dependencies here; they belong 13 | // in the individual module build.gradle files 14 | } 15 | } 16 | 17 | allprojects { 18 | repositories { 19 | google() 20 | jcenter() 21 | 22 | } 23 | } 24 | 25 | task clean(type: Delete) { 26 | delete rootProject.buildDir 27 | } 28 | -------------------------------------------------------------------------------- /gradle.properties: -------------------------------------------------------------------------------- 1 | # Project-wide Gradle settings. 2 | # IDE (e.g. Android Studio) users: 3 | # Gradle settings configured through the IDE *will override* 4 | # any settings specified in this file. 5 | # For more details on how to configure your build environment visit 6 | # http://www.gradle.org/docs/current/userguide/build_environment.html 7 | # Specifies the JVM arguments used for the daemon process. 8 | # The setting is particularly useful for tweaking memory settings. 9 | org.gradle.jvmargs=-Xmx1536m 10 | # When configured, Gradle will run in incubating parallel mode. 11 | # This option should only be used with decoupled projects. More details, visit 12 | # http://www.gradle.org/docs/current/userguide/multi_project_builds.html#sec:decoupled_projects 13 | # org.gradle.parallel=true 14 | 15 | 16 | -------------------------------------------------------------------------------- /gradle/wrapper/gradle-wrapper.jar: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/bukkalexander/AndroidStudio2DGameDevelopment/6087a15491a9b9f685b9de1334336cb1a899ad9f/gradle/wrapper/gradle-wrapper.jar -------------------------------------------------------------------------------- /gradle/wrapper/gradle-wrapper.properties: -------------------------------------------------------------------------------- 1 | #Mon Apr 06 21:48:45 CEST 2020 2 | distributionBase=GRADLE_USER_HOME 3 | distributionPath=wrapper/dists 4 | zipStoreBase=GRADLE_USER_HOME 5 | zipStorePath=wrapper/dists 6 | distributionUrl=https\://services.gradle.org/distributions/gradle-5.6.4-all.zip 7 | -------------------------------------------------------------------------------- /gradlew: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env sh 2 | 3 | ############################################################################## 4 | ## 5 | ## Gradle start up script for UN*X 6 | ## 7 | ############################################################################## 8 | 9 | # Attempt to set APP_HOME 10 | # Resolve links: $0 may be a link 11 | PRG="$0" 12 | # Need this for relative symlinks. 13 | while [ -h "$PRG" ] ; do 14 | ls=`ls -ld "$PRG"` 15 | link=`expr "$ls" : '.*-> \(.*\)$'` 16 | if expr "$link" : '/.*' > /dev/null; then 17 | PRG="$link" 18 | else 19 | PRG=`dirname "$PRG"`"/$link" 20 | fi 21 | done 22 | SAVED="`pwd`" 23 | cd "`dirname \"$PRG\"`/" >/dev/null 24 | APP_HOME="`pwd -P`" 25 | cd "$SAVED" >/dev/null 26 | 27 | APP_NAME="Gradle" 28 | APP_BASE_NAME=`basename "$0"` 29 | 30 | # Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. 31 | DEFAULT_JVM_OPTS="" 32 | 33 | # Use the maximum available, or set MAX_FD != -1 to use that value. 34 | MAX_FD="maximum" 35 | 36 | warn () { 37 | echo "$*" 38 | } 39 | 40 | die () { 41 | echo 42 | echo "$*" 43 | echo 44 | exit 1 45 | } 46 | 47 | # OS specific support (must be 'true' or 'false'). 48 | cygwin=false 49 | msys=false 50 | darwin=false 51 | nonstop=false 52 | case "`uname`" in 53 | CYGWIN* ) 54 | cygwin=true 55 | ;; 56 | Darwin* ) 57 | darwin=true 58 | ;; 59 | MINGW* ) 60 | msys=true 61 | ;; 62 | NONSTOP* ) 63 | nonstop=true 64 | ;; 65 | esac 66 | 67 | CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar 68 | 69 | # Determine the Java command to use to start the JVM. 70 | if [ -n "$JAVA_HOME" ] ; then 71 | if [ -x "$JAVA_HOME/jre/sh/java" ] ; then 72 | # IBM's JDK on AIX uses strange locations for the executables 73 | JAVACMD="$JAVA_HOME/jre/sh/java" 74 | else 75 | JAVACMD="$JAVA_HOME/bin/java" 76 | fi 77 | if [ ! -x "$JAVACMD" ] ; then 78 | die "ERROR: JAVA_HOME is set to an invalid directory: $JAVA_HOME 79 | 80 | Please set the JAVA_HOME variable in your environment to match the 81 | location of your Java installation." 82 | fi 83 | else 84 | JAVACMD="java" 85 | which java >/dev/null 2>&1 || die "ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. 86 | 87 | Please set the JAVA_HOME variable in your environment to match the 88 | location of your Java installation." 89 | fi 90 | 91 | # Increase the maximum file descriptors if we can. 92 | if [ "$cygwin" = "false" -a "$darwin" = "false" -a "$nonstop" = "false" ] ; then 93 | MAX_FD_LIMIT=`ulimit -H -n` 94 | if [ $? -eq 0 ] ; then 95 | if [ "$MAX_FD" = "maximum" -o "$MAX_FD" = "max" ] ; then 96 | MAX_FD="$MAX_FD_LIMIT" 97 | fi 98 | ulimit -n $MAX_FD 99 | if [ $? -ne 0 ] ; then 100 | warn "Could not set maximum file descriptor limit: $MAX_FD" 101 | fi 102 | else 103 | warn "Could not query maximum file descriptor limit: $MAX_FD_LIMIT" 104 | fi 105 | fi 106 | 107 | # For Darwin, add options to specify how the application appears in the dock 108 | if $darwin; then 109 | GRADLE_OPTS="$GRADLE_OPTS \"-Xdock:name=$APP_NAME\" \"-Xdock:icon=$APP_HOME/media/gradle.icns\"" 110 | fi 111 | 112 | # For Cygwin, switch paths to Windows format before running java 113 | if $cygwin ; then 114 | APP_HOME=`cygpath --path --mixed "$APP_HOME"` 115 | CLASSPATH=`cygpath --path --mixed "$CLASSPATH"` 116 | JAVACMD=`cygpath --unix "$JAVACMD"` 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 | # Escape application args 158 | save () { 159 | for i do printf %s\\n "$i" | sed "s/'/'\\\\''/g;1s/^/'/;\$s/\$/' \\\\/" ; done 160 | echo " " 161 | } 162 | APP_ARGS=$(save "$@") 163 | 164 | # Collect all arguments for the java command, following the shell quoting and substitution rules 165 | eval set -- $DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS "\"-Dorg.gradle.appname=$APP_BASE_NAME\"" -classpath "\"$CLASSPATH\"" org.gradle.wrapper.GradleWrapperMain "$APP_ARGS" 166 | 167 | # by default we should be in the correct project dir, but when run from Finder on Mac, the cwd is wrong 168 | if [ "$(uname)" = "Darwin" ] && [ "$HOME" = "$PWD" ]; then 169 | cd "$(dirname "$0")" 170 | fi 171 | 172 | exec "$JAVACMD" "$@" 173 | -------------------------------------------------------------------------------- /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 | set DIRNAME=%~dp0 12 | if "%DIRNAME%" == "" set DIRNAME=. 13 | set APP_BASE_NAME=%~n0 14 | set APP_HOME=%DIRNAME% 15 | 16 | @rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. 17 | set DEFAULT_JVM_OPTS= 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 Windows variants 50 | 51 | if not "%OS%" == "Windows_NT" goto win9xME_args 52 | 53 | :win9xME_args 54 | @rem Slurp the command line arguments. 55 | set CMD_LINE_ARGS= 56 | set _SKIP=2 57 | 58 | :win9xME_args_slurp 59 | if "x%~1" == "x" goto execute 60 | 61 | set CMD_LINE_ARGS=%* 62 | 63 | :execute 64 | @rem Setup the command line 65 | 66 | set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar 67 | 68 | @rem Execute Gradle 69 | "%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %CMD_LINE_ARGS% 70 | 71 | :end 72 | @rem End local scope for the variables with windows NT shell 73 | if "%ERRORLEVEL%"=="0" goto mainEnd 74 | 75 | :fail 76 | rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of 77 | rem the _cmd.exe /c_ return code! 78 | if not "" == "%GRADLE_EXIT_CONSOLE%" exit 1 79 | exit /b 1 80 | 81 | :mainEnd 82 | if "%OS%"=="Windows_NT" endlocal 83 | 84 | :omega 85 | -------------------------------------------------------------------------------- /settings.gradle: -------------------------------------------------------------------------------- 1 | include ':app' 2 | --------------------------------------------------------------------------------