├── Chapter 01
├── AndroidManifest.xml
└── java
│ └── SubHunter.java
├── Chapter 02
├── AndroidManifest.xml
└── java
│ └── SubHunter.java
├── Chapter 03
├── AndroidManifest.xml
└── java
│ └── SubHunter.java
├── Chapter 04
├── AndroidManifest.xml
├── Method Overloading
│ └── MainActivity.java
└── java
│ └── SubHunter.java
├── Chapter 05
├── AndroidManifest.xml
├── Canvas Demo
│ └── MainActivity.java
└── java
│ └── SubHunter.java
├── Chapter 06
├── AndroidManifest.xml
└── java
│ └── SubHunter.java
├── Chapter 07
├── AndroidManifest.xml
└── java
│ └── SubHunter.java
├── Chapter 08
├── Access Scope This And Static
│ └── AccessScopeThisAndStatic
│ │ ├── AlienShip.java
│ │ └── MainActivity.java
├── Basic Classes
│ ├── MainActivity.java
│ └── Soldier.java
├── C8Pong
│ ├── AndroidManifest.xml
│ ├── Ball.java
│ ├── Bat.java
│ ├── PongActivity.java
│ └── PongGame.java
└── InheritanceExample
│ └── InheritanceExample
│ ├── AlienShip.java
│ ├── Bomber.java
│ ├── Fighter.java
│ └── MainActivity.java
├── Chapter 09
├── AndroidManifest.xml
└── java
│ ├── Ball.java
│ ├── Bat.java
│ ├── PongActivity.java
│ └── PongGame.java
├── Chapter 10
├── AndroidManifest.xml
└── java
│ ├── Ball.java
│ ├── Bat.java
│ ├── PongActivity.java
│ └── PongGame.java
├── Chapter 11
├── AndroidManifest.xml
├── assets
│ ├── beep.ogg
│ ├── boop.ogg
│ ├── bop.ogg
│ └── miss.ogg
└── java
│ ├── Ball.java
│ ├── Bat.java
│ ├── PongActivity.java
│ └── PongGame.java
├── Chapter 12
├── C12BulletHell
│ ├── AndroidManifest.xml
│ └── java
│ │ ├── Bob.java
│ │ ├── Bullet.java
│ │ ├── BulletHellActivity.java
│ │ └── BulletHellGame.java
├── Dynamic Array Example
│ └── MainActivity.java
├── Multidimensional Array Example
│ └── MainActivity.java
└── Simple Array Example
│ └── MainActivity.java
├── Chapter 13
├── AndroidManifest.xml
├── assets
│ ├── beep.ogg
│ └── teleport.ogg
├── drawable
│ ├── bob.png
│ └── ic_launcher_background.xml
└── java
│ ├── Bob.java
│ ├── Bullet.java
│ ├── BulletHellActivity.java
│ └── BulletHellGame.java
├── Chapter 14
├── AndroidManifest.xml
├── assets
│ ├── get_apple.ogg
│ └── snake_death.ogg
└── java
│ ├── Apple.java
│ ├── Snake.java
│ ├── SnakeActivity.java
│ └── SnakeGame.java
├── Chapter 15
├── AndroidManifest.xml
├── assets
│ ├── get_apple.ogg
│ └── snake_death.ogg
├── java
│ ├── Apple.java
│ ├── Snake.java
│ ├── SnakeActivity.java
│ └── SnakeGame.java
├── values-de
│ └── strings.xml
├── values-es
│ └── strings.xml
└── values
│ ├── colors.xml
│ ├── strings.xml
│ └── styles.xml
├── Chapter 16
├── AndroidManifest.xml
├── assets
│ ├── get_apple.ogg
│ └── snake_death.ogg
├── drawable
│ ├── apple.png
│ ├── body.png
│ └── head.png
└── java
│ ├── Apple.java
│ ├── Snake.java
│ ├── SnakeActivity.java
│ └── SnakeGame.java
├── Chapter 17
├── AndroidManifest.xml
├── assets
│ ├── get_apple.ogg
│ └── snake_death.ogg
├── drawable
│ ├── apple.png
│ ├── body.png
│ └── head.png
└── java
│ ├── Apple.java
│ ├── Snake.java
│ ├── SnakeActivity.java
│ └── SnakeGame.java
├── Chapter 18
├── AndroidManifest.xml
├── assets
│ ├── alien_explosion.ogg
│ ├── player_explosion.ogg
│ └── shoot.ogg
└── java
│ ├── GameActivity.java
│ ├── GameEngine.java
│ ├── GameStarter.java
│ ├── GameState.java
│ ├── HUD.java
│ ├── Renderer.java
│ └── SoundEngine.java
├── Chapter 19
├── AndroidManifest.xml
├── assets
│ ├── alien_explosion.ogg
│ ├── player_explosion.ogg
│ └── shoot.ogg
└── java
│ ├── GameActivity.java
│ ├── GameEngine.java
│ ├── GameEngineBroadcaster.java
│ ├── GameStarter.java
│ ├── GameState.java
│ ├── HUD.java
│ ├── InputObserver.java
│ ├── Particle.java
│ ├── ParticleSystem.java
│ ├── PhysicsEngine.java
│ ├── Renderer.java
│ ├── SoundEngine.java
│ └── UIController.java
├── Chapter 20
├── assets
│ ├── alien_explosion.ogg
│ ├── player_explosion.ogg
│ └── shoot.ogg
├── drawable
│ ├── alien_laser.png
│ ├── alien_ship1.png
│ ├── alien_ship2.png
│ ├── alien_ship3.png
│ ├── background.png
│ ├── player_laser.png
│ └── player_ship.png
└── java
│ ├── AlienChaseSpec.java
│ ├── AlienDiverSpec.java
│ ├── AlienLaserSpec.java
│ ├── AlienPatrolSpec.java
│ ├── BackgroundGraphicsComponent.java
│ ├── BackgroundMovementComponent.java
│ ├── BackgroundSpawnComponent.java
│ ├── BackgroundSpec.java
│ ├── GameActivity.java
│ ├── GameEngine.java
│ ├── GameEngineBroadcaster.java
│ ├── GameObject.java
│ ├── GameObjectFactory.java
│ ├── GameStarter.java
│ ├── GameState.java
│ ├── GraphicsComponent.java
│ ├── HUD.java
│ ├── InputComponent.java
│ ├── InputObserver.java
│ ├── LaserMovementComponent.java
│ ├── LaserSpawnComponent.java
│ ├── Level.java
│ ├── MovementComponent.java
│ ├── ObjectSpec.java
│ ├── Particle.java
│ ├── ParticleSystem.java
│ ├── PhysicsEngine.java
│ ├── PlayerInputComponent.java
│ ├── PlayerLaserSpawner.java
│ ├── PlayerLaserSpec.java
│ ├── PlayerMovementComponent.java
│ ├── PlayerSpawnComponent.java
│ ├── PlayerSpec.java
│ ├── Renderer.java
│ ├── SoundEngine.java
│ ├── SpawnComponent.java
│ ├── StdGraphicsComponent.java
│ ├── Transform.java
│ └── UIController.java
├── Chapter 21
├── assets
│ ├── alien_explosion.ogg
│ ├── player_explosion.ogg
│ └── shoot.ogg
├── drawable
│ ├── alien_laser.png
│ ├── alien_ship1.png
│ ├── alien_ship2.png
│ ├── alien_ship3.png
│ ├── background.png
│ ├── ic_launcher_background.xml
│ ├── player_laser.png
│ └── player_ship.png
└── java
│ ├── AlienChaseMovementComponent.java
│ ├── AlienChaseSpec.java
│ ├── AlienDiverMovementComponent.java
│ ├── AlienDiverSpec.java
│ ├── AlienHorizontalSpawnComponent.java
│ ├── AlienLaserSpawner.java
│ ├── AlienLaserSpec.java
│ ├── AlienPatrolMovementComponent.java
│ ├── AlienPatrolSpec.java
│ ├── AlienVerticalSpawnComponent.java
│ ├── BackgroundGraphicsComponent.java
│ ├── BackgroundMovementComponent.java
│ ├── BackgroundSpawnComponent.java
│ ├── BackgroundSpec.java
│ ├── GameActivity.java
│ ├── GameEngine.java
│ ├── GameEngineBroadcaster.java
│ ├── GameObject.java
│ ├── GameObjectFactory.java
│ ├── GameStarter.java
│ ├── GameState.java
│ ├── GraphicsComponent.java
│ ├── HUD.java
│ ├── InputComponent.java
│ ├── InputObserver.java
│ ├── LaserMovementComponent.java
│ ├── LaserSpawnComponent.java
│ ├── Level.java
│ ├── MovementComponent.java
│ ├── ObjectSpec.java
│ ├── Particle.java
│ ├── ParticleSystem.java
│ ├── PhysicsEngine.java
│ ├── PlayerInputComponent.java
│ ├── PlayerLaserSpawner.java
│ ├── PlayerLaserSpec.java
│ ├── PlayerMovementComponent.java
│ ├── PlayerSpawnComponent.java
│ ├── PlayerSpec.java
│ ├── Renderer.java
│ ├── SoundEngine.java
│ ├── SpawnComponent.java
│ ├── StdGraphicsComponent.java
│ ├── Transform.java
│ └── UIController.java
├── LICENSE
└── README.md
/Chapter 01/AndroidManifest.xml:
--------------------------------------------------------------------------------
1 |
2 |
4 |
5 |
12 |
14 | >
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
--------------------------------------------------------------------------------
/Chapter 01/java/SubHunter.java:
--------------------------------------------------------------------------------
1 | package com.gamecodeschool.subhunter;
2 |
3 | import android.app.Activity;
4 | import android.view.Window;
5 |
6 | import android.os.Bundle;
7 |
8 |
9 | public class SubHunter extends Activity {
10 |
11 | @Override
12 | protected void onCreate(Bundle savedInstanceState) {
13 | super.onCreate(savedInstanceState);
14 |
15 | requestWindowFeature(Window.FEATURE_NO_TITLE);
16 |
17 | }
18 | }
19 |
20 |
21 |
22 |
23 |
--------------------------------------------------------------------------------
/Chapter 02/AndroidManifest.xml:
--------------------------------------------------------------------------------
1 |
2 |
4 |
5 |
12 |
14 | >
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
--------------------------------------------------------------------------------
/Chapter 02/java/SubHunter.java:
--------------------------------------------------------------------------------
1 | // This is our package
2 | // If you are copy & pasting the code then this line will probably be different to yours
3 | // If so, keep YOUR line- not this one
4 | package com.gamecodeschool.c2subhunter;
5 |
6 | // These are all the classes of other people's
7 | // (Android) code that we use in Sub Hunt
8 | import android.app.Activity;
9 | import android.view.Window;
10 |
11 | import android.os.Bundle;
12 | import android.view.MotionEvent;
13 | import android.util.Log;
14 | import android.graphics.Bitmap;
15 | import android.graphics.Canvas;
16 | import android.graphics.Color;
17 | import android.graphics.Paint;
18 | import android.graphics.Point;
19 | import android.view.Display;
20 | import android.widget.ImageView;
21 | import java.util.Random;
22 |
23 |
24 | public class SubHunter extends Activity {
25 |
26 | /*
27 | Android runs this code just before
28 | the app is seen by the player.
29 | This makes it a good place to add
30 | the code that is needed for
31 | the one-time setup.
32 | */
33 |
34 | @Override
35 | protected void onCreate(Bundle savedInstanceState) {
36 | super.onCreate(savedInstanceState);
37 |
38 | requestWindowFeature(Window.FEATURE_NO_TITLE);
39 |
40 | Log.d("Debugging", "In onCreate");
41 | newGame();
42 | draw();
43 | }
44 |
45 | /*
46 | This code will execute when a new
47 | game needs to be started. It will
48 | happen when the app is first started
49 | and after the player wins a game.
50 | */
51 | void newGame(){
52 | Log.d("Debugging", "In newGame");
53 |
54 | }
55 |
56 | /*
57 | Here we will do all the drawing.
58 | The grid lines, the HUD and
59 | the touch indicator
60 | */
61 | void draw() {
62 | Log.d("Debugging", "In draw");
63 | }
64 |
65 | /*
66 | This part of the code will
67 | handle detecting that the player
68 | has tapped the screen
69 | */
70 | @Override
71 | public boolean onTouchEvent(MotionEvent motionEvent) {
72 | Log.d("Debugging", "In onTouchEvent");
73 | takeShot();
74 |
75 | return true;
76 | }
77 |
78 |
79 | /*
80 | The code here will execute when
81 | the player taps the screen It will
82 | calculate distance from the sub'
83 | and determine a hit or miss
84 | */
85 | void takeShot(){
86 | Log.d("Debugging", "In takeShot");
87 | draw();
88 | }
89 |
90 | // This code says "BOOM!"
91 | void boom(){
92 |
93 | }
94 |
95 | // This code prints the debugging text
96 | void printDebuggingText(){
97 |
98 | }
99 | }
100 |
--------------------------------------------------------------------------------
/Chapter 03/AndroidManifest.xml:
--------------------------------------------------------------------------------
1 |
2 |
4 |
5 |
12 |
14 | >
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
--------------------------------------------------------------------------------
/Chapter 04/AndroidManifest.xml:
--------------------------------------------------------------------------------
1 |
2 |
4 |
5 |
12 |
14 | >
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
--------------------------------------------------------------------------------
/Chapter 04/Method Overloading/MainActivity.java:
--------------------------------------------------------------------------------
1 | package com.gamecodeschool.exploringmethodoverloading;
2 |
3 | import android.app.Activity;
4 | import android.os.Bundle;
5 | import android.util.Log;
6 |
7 | public class MainActivity extends Activity {
8 |
9 | @Override
10 | protected void onCreate(Bundle savedInstanceState) {
11 | super.onCreate(savedInstanceState);
12 |
13 | // Declare and initialize a String and an int
14 | int anInt = 10;
15 | String aString = "I am a string";
16 |
17 | // Now call the different versions of printStuff
18 | // The name stays the same, only the parameters vary
19 | printStuff(anInt);
20 | printStuff(aString);
21 | printStuff(anInt, aString);
22 |
23 | }
24 |
25 | void printStuff(int myInt){
26 | Log.i("info", "This is the int only version");
27 | Log.i("info", "myInt = "+ myInt);
28 | }
29 |
30 | void printStuff(String myString){
31 | Log.i("info", "This is the String only version");
32 | Log.i("info", "myString = "+ myString);
33 | }
34 |
35 | void printStuff(int myInt, String myString){
36 | Log.i("info", "This is the combined int and String version");
37 | Log.i("info", "myInt = "+ myInt);
38 | Log.i("info", "myString = "+ myString);
39 | }
40 |
41 | }
42 |
--------------------------------------------------------------------------------
/Chapter 05/AndroidManifest.xml:
--------------------------------------------------------------------------------
1 |
2 |
4 |
5 |
12 |
14 | >
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
--------------------------------------------------------------------------------
/Chapter 05/Canvas Demo/MainActivity.java:
--------------------------------------------------------------------------------
1 | package com.gamecodeschool.canvasdemo;
2 |
3 | import android.app.Activity;
4 | import android.graphics.Bitmap;
5 | import android.graphics.Canvas;
6 | import android.graphics.Color;
7 | import android.graphics.Paint;
8 | import android.os.Bundle;
9 | import android.widget.ImageView;
10 |
11 | public class MainActivity extends Activity {
12 |
13 | // Here are all the objects(instances)
14 | // of classes that we need to do some drawing
15 | ImageView myImageView;
16 | Bitmap myBlankBitmap;
17 | Canvas myCanvas;
18 | Paint myPaint;
19 |
20 |
21 | @Override
22 | protected void onCreate(Bundle savedInstanceState) {
23 | super.onCreate(savedInstanceState);
24 |
25 | // Initialize all the objects ready for drawing
26 | // We will do this inside the onCreate method
27 | int widthInPixels = 800;
28 | int heightInPixels = 600;
29 |
30 | // Create a new Bitmap
31 | myBlankBitmap = Bitmap.createBitmap(widthInPixels,
32 | heightInPixels,
33 | Bitmap.Config.ARGB_8888);
34 |
35 | // Initialize the Canvas and asociate it
36 | // with the Bitmap to draw on
37 | myCanvas = new Canvas(myBlankBitmap);
38 |
39 | // Initialize the ImageView and the Paint
40 | myImageView = new ImageView(this);
41 | myPaint = new Paint();
42 |
43 |
44 | // Draw on the Bitmap
45 | // Wipe the Bitmap with a blue color
46 | myCanvas.drawColor(Color.argb(255, 0, 0, 255));
47 |
48 | // Re-size the text
49 | myPaint.setTextSize(100);
50 | // Change the paint to white
51 | myPaint.setColor(Color.argb(255, 255, 255, 255));
52 | // Actually draw the text
53 | myCanvas.drawText("Hello World!",100, 100, myPaint);
54 |
55 | // Change the paint to yellow
56 | myPaint.setColor(Color.argb(255, 212, 207, 62));
57 | // Draw a circle
58 | myCanvas.drawCircle(400,250, 100, myPaint);
59 |
60 | // Associate the drawn upon Bitmap with the ImageView
61 | myImageView.setImageBitmap(myBlankBitmap);
62 | // Tell Android to set our drawing
63 | // as the view for this app
64 | // via the ImageView
65 | setContentView(myImageView);
66 |
67 |
68 | }
69 | }
70 |
--------------------------------------------------------------------------------
/Chapter 06/AndroidManifest.xml:
--------------------------------------------------------------------------------
1 |
2 |
4 |
5 |
12 |
14 | >
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
--------------------------------------------------------------------------------
/Chapter 07/AndroidManifest.xml:
--------------------------------------------------------------------------------
1 |
2 |
4 |
5 |
12 |
14 | >
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
--------------------------------------------------------------------------------
/Chapter 08/Access Scope This And Static/AccessScopeThisAndStatic/AlienShip.java:
--------------------------------------------------------------------------------
1 | package com.gamecodeschool.accessscopethisandstatic;
2 |
3 | import android.util.Log;
4 |
5 | public class AlienShip {
6 | private static int numShips;
7 | private int shieldStrength;
8 | public String shipName;
9 |
10 | public AlienShip(){
11 | numShips++;
12 | //Can call private methods from here because I am part
13 | //of the class
14 | //If didn't have "this" then this call might be less clear
15 | //But this "this" isn't strictly necessary
16 | this.setShieldStrength(100);
17 | //Because of "this" I am sure I am setting the correct shieldStrength
18 | }
19 |
20 | public static int getNumShips(){
21 | return numShips;
22 |
23 | }
24 |
25 | private void setShieldStrength(int shieldStrength){
26 | //"this" distinguishes between the member variable shieldStrength
27 | //And the local variable/paramater of the same name
28 | this.shieldStrength = shieldStrength;
29 | }
30 |
31 |
32 | public int getShieldStrength(){
33 | return this.shieldStrength;
34 | }
35 |
36 | public void hitDetected(){
37 |
38 | shieldStrength -=25;
39 | Log.i("Incomiming: ","Bam!!");
40 | if (shieldStrength == 0){
41 | destroyShip();
42 | }
43 |
44 | }
45 |
46 | private void destroyShip(){
47 | numShips--;
48 | Log.i("Explosion: ", ""+this.shipName + " destroyed");
49 | }
50 | }
51 |
--------------------------------------------------------------------------------
/Chapter 08/Access Scope This And Static/AccessScopeThisAndStatic/MainActivity.java:
--------------------------------------------------------------------------------
1 | package com.gamecodeschool.accessscopethisandstatic;
2 |
3 | import androidx.appcompat.app.AppCompatActivity;
4 |
5 | import android.os.Bundle;
6 | import android.util.Log;
7 |
8 | public class MainActivity extends AppCompatActivity {
9 |
10 | @Override
11 | protected void onCreate(Bundle savedInstanceState) {
12 | super.onCreate(savedInstanceState);
13 | setContentView(R.layout.activity_main);
14 |
15 | //every time we do this the constructor runs
16 | AlienShip girlShip = new AlienShip();
17 | AlienShip boyShip = new AlienShip();
18 |
19 | //Look no objects but using the static method
20 | Log.i("numShips: ", "" + AlienShip.getNumShips());
21 |
22 | //This works because shipName is public
23 | girlShip.shipName = "Corrine Yu";
24 | boyShip.shipName = "Andre LaMothe";
25 |
26 | //This won't work because shieldStrenth is private
27 | //girlship.shieldStrength = 999;
28 |
29 | //But we have a public getter
30 | Log.i("girlShip shieldStrngth:", "" + girlShip.getShieldStrength());
31 | Log.i("boyShip shieldStrngth: ", "" + boyShip.getShieldStrength());
32 |
33 | //But we can't do this because it's private
34 | //boyship.setShieldStrength(1000000);
35 |
36 | //lets shoot some ships
37 | girlShip.hitDetected();
38 | Log.i("girlShip shieldStrngth:", "" + girlShip.getShieldStrength());
39 | Log.i("boyShip shieldStrngth: ", "" + boyShip.getShieldStrength());
40 | boyShip.hitDetected();
41 | boyShip.hitDetected();
42 | boyShip.hitDetected();
43 | Log.i("girlShip shieldStrngth:", "" + girlShip.getShieldStrength());
44 | Log.i("boyShip shieldStrngth: ", "" + boyShip.getShieldStrength());
45 | boyShip.hitDetected();//ahhh
46 | Log.i("girlShip shieldStrngth:", "" + girlShip.getShieldStrength());
47 | Log.i("boyShip shieldStrngth: ", "" + boyShip.getShieldStrength());
48 | Log.i("numShips: ", "" + AlienShip.getNumShips());
49 | }
50 | }
--------------------------------------------------------------------------------
/Chapter 08/Basic Classes/MainActivity.java:
--------------------------------------------------------------------------------
1 | package com.gamecodeschool.basicclasses;
2 |
3 | import androidx.appcompat.app.AppCompatActivity;
4 |
5 | import android.os.Bundle;
6 | import android.util.Log;
7 |
8 | public class MainActivity extends AppCompatActivity {
9 |
10 | @Override
11 | protected void onCreate(Bundle savedInstanceState) {
12 | super.onCreate(savedInstanceState);
13 |
14 | // first we make an object of type soldier
15 | Soldier rambo = new Soldier();
16 | rambo.soldierType = "Green Beret";
17 | rambo.health = 150;
18 | // It takes allot to kill Rambo
19 |
20 | // Now we make another Soldier object
21 | Soldier vassily = new Soldier();
22 | vassily.soldierType = "Sniper";
23 | vassily.health = 50;
24 | // Snipers have less health
25 |
26 | // And one more Soldier object
27 | Soldier wellington = new Soldier();
28 | wellington.soldierType = "Sailor";
29 | wellington.health = 100;
30 | // He's tough but no green beret
31 |
32 | //setContentView(R.layout.activity_main);
33 |
34 | Log.i("Rambo's health = ", "" + rambo.health);
35 | Log.i("Vassily's health = ", "" + vassily.health);
36 | Log.i("Wellington's health = ", "" + wellington.health);
37 |
38 | rambo.shootEnemy();
39 | vassily.shootEnemy();
40 | wellington.shootEnemy();
41 |
42 | }
43 | }
--------------------------------------------------------------------------------
/Chapter 08/Basic Classes/Soldier.java:
--------------------------------------------------------------------------------
1 | package com.gamecodeschool.basicclasses;
2 |
3 | import android.util.Log;
4 |
5 | public class Soldier {
6 | int health;
7 | String soldierType;
8 |
9 | void shootEnemy(){
10 | //let's print which type of soldier is shooting
11 | Log.d(soldierType, " is shooting");
12 | }
13 |
14 | }
15 |
--------------------------------------------------------------------------------
/Chapter 08/C8Pong/AndroidManifest.xml:
--------------------------------------------------------------------------------
1 |
2 |
4 |
5 |
12 |
16 |
17 | >
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
26 |
--------------------------------------------------------------------------------
/Chapter 08/C8Pong/Ball.java:
--------------------------------------------------------------------------------
1 | package com.gamecodeschool.pong;
2 |
3 | public class Ball {
4 | }
5 |
--------------------------------------------------------------------------------
/Chapter 08/C8Pong/Bat.java:
--------------------------------------------------------------------------------
1 | package com.gamecodeschool.pong;
2 |
3 | public class Bat {
4 | }
5 |
--------------------------------------------------------------------------------
/Chapter 08/C8Pong/PongActivity.java:
--------------------------------------------------------------------------------
1 | package com.gamecodeschool.pong;
2 |
3 | import android.app.Activity;
4 | import android.view.Window;
5 |
6 | import android.os.Bundle;
7 |
8 | public class PongActivity extends Activity {
9 |
10 | @Override
11 | protected void onCreate(Bundle savedInstanceState) {
12 | super.onCreate(savedInstanceState);
13 |
14 | requestWindowFeature(Window.FEATURE_NO_TITLE);
15 | getWindow().setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN, WindowManager.LayoutParams.FLAG_FULLSCREEN);
16 | }
17 | }
18 |
--------------------------------------------------------------------------------
/Chapter 08/C8Pong/PongGame.java:
--------------------------------------------------------------------------------
1 | package com.gamecodeschool.pong;
2 |
3 | public class PongGame {
4 | }
5 |
--------------------------------------------------------------------------------
/Chapter 08/InheritanceExample/InheritanceExample/AlienShip.java:
--------------------------------------------------------------------------------
1 | package com.gamecodeschool.inheritanceexample.app;
2 |
3 | import android.util.Log;
4 |
5 | public abstract class AlienShip {
6 | private static int numShips;
7 | private int shieldStrength;
8 | public String shipName;
9 |
10 | public AlienShip(int shieldStrength){
11 | Log.i("Location: ", "AlienShip constructor");
12 | numShips++;
13 | setShieldStrength(shieldStrength);
14 | }
15 |
16 | public abstract void fireWeapon();//Ahh my body
17 |
18 | public static int getNumShips(){
19 | return numShips;
20 | }
21 |
22 | private void setShieldStrength(int shieldStrength){
23 | this.shieldStrength = shieldStrength;
24 | }
25 |
26 |
27 | public int getShieldStrength(){
28 | return this.shieldStrength;
29 | }
30 |
31 | public void hitDetected(){
32 | shieldStrength -=25;
33 | Log.i("Incomiming: ", "Bam!!");
34 | if (shieldStrength == 0){
35 | destroyShip();
36 | }
37 |
38 | }
39 |
40 | private void destroyShip(){
41 | numShips--;
42 | Log.i("Explosion: ", ""+this.shipName + " destroyed");
43 | }
44 |
45 | }
46 |
--------------------------------------------------------------------------------
/Chapter 08/InheritanceExample/InheritanceExample/Bomber.java:
--------------------------------------------------------------------------------
1 | package com.gamecodeschool.inheritanceexample.app;
2 |
3 | import android.util.Log;
4 |
5 | public class Bomber extends AlienShip {
6 |
7 | public Bomber(){
8 | super(100);
9 | //Weak shields for a bomber
10 | Log.i("Location: ", "Bomber constructor");
11 | }
12 |
13 | public void fireWeapon(){
14 | Log.i("Firing weapon: ", "bombs away");
15 | }
16 | }
17 |
--------------------------------------------------------------------------------
/Chapter 08/InheritanceExample/InheritanceExample/Fighter.java:
--------------------------------------------------------------------------------
1 | package com.gamecodeschool.inheritanceexample.app;
2 |
3 | import android.util.Log;
4 |
5 | public class Fighter extends AlienShip{
6 |
7 | public Fighter(){
8 | super(400);
9 | //Strong shields for a fighter
10 | Log.i("Location: ", "Fighter constructor");
11 | }
12 |
13 | public void fireWeapon(){
14 | Log.i("Firing weapon: ", "lasers firing");
15 | }
16 |
17 | }
18 |
--------------------------------------------------------------------------------
/Chapter 08/InheritanceExample/InheritanceExample/MainActivity.java:
--------------------------------------------------------------------------------
1 | package com.gamecodeschool.inheritanceexample.app;
2 |
3 | import androidx.appcompat.app.AppCompatActivity;
4 |
5 | import android.os.Bundle;
6 | import android.util.Log;
7 |
8 | public class MainActivity extends AppCompatActivity {
9 |
10 | @Override
11 | protected void onCreate(Bundle savedInstanceState) {
12 | super.onCreate(savedInstanceState);
13 | setContentView(R.layout.activity_main);
14 |
15 | Fighter aFighter = new Fighter();
16 | Bomber aBomber = new Bomber();
17 |
18 | //Can't do this AlienShip is abstract -
19 | //Literally speaking as well as in code
20 | //AlienShip alienShip = new AlienShip(500);
21 |
22 | //But our objects of the subclasses can still do
23 | //everything the AlienShip is meant to do
24 | aBomber.shipName = "Newell Bomber";
25 | aFighter.shipName = "Meier Fighter";
26 |
27 | //And because of the overiden constructor
28 | //That still calls the super constructor
29 | //They have unique properties
30 | Log.i("aFighter Shield:", ""+ aFighter.getShieldStrength());
31 | Log.i("aBomber Shield:", ""+ aBomber.getShieldStrength());
32 |
33 | //As well as certain things in certain ways
34 | //That are unique to the subclass
35 | aBomber.fireWeapon();
36 | aFighter.fireWeapon();
37 |
38 | //Take down those alien ships
39 | //Focus on the bomber it has a weaker shield
40 | aBomber.hitDetected();
41 | aBomber.hitDetected();
42 | aBomber.hitDetected();
43 | aBomber.hitDetected();
44 | }
45 |
46 | }
47 |
--------------------------------------------------------------------------------
/Chapter 09/AndroidManifest.xml:
--------------------------------------------------------------------------------
1 |
2 |
4 |
5 |
12 |
16 |
17 | >
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
26 |
--------------------------------------------------------------------------------
/Chapter 09/java/Ball.java:
--------------------------------------------------------------------------------
1 | package com.gamecodeschool.pong;
2 |
3 | public class Ball {
4 | }
5 |
--------------------------------------------------------------------------------
/Chapter 09/java/Bat.java:
--------------------------------------------------------------------------------
1 | package com.gamecodeschool.pong;
2 |
3 | public class Bat {
4 | }
5 |
--------------------------------------------------------------------------------
/Chapter 09/java/PongActivity.java:
--------------------------------------------------------------------------------
1 | package com.gamecodeschool.pong;
2 |
3 | import android.app.Activity;
4 | import android.view.Window;
5 |
6 | import android.os.Bundle;
7 |
8 | import android.graphics.Point;
9 | import android.view.Display;
10 |
11 |
12 | public class PongActivity extends Activity {
13 |
14 | private PongGame mPongGame;
15 |
16 | @Override
17 | protected void onCreate(Bundle savedInstanceState) {
18 | super.onCreate(savedInstanceState);
19 |
20 | requestWindowFeature(Window.FEATURE_NO_TITLE);
21 | getWindow().setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN, WindowManager.LayoutParams.FLAG_FULLSCREEN);
22 |
23 | Display display = getWindowManager().getDefaultDisplay();
24 | Point size = new Point();
25 | display.getSize(size);
26 |
27 | mPongGame = new PongGame(this, size.x, size.y);
28 | setContentView(mPongGame);
29 |
30 | }
31 |
32 |
33 | @Override
34 | protected void onResume() {
35 | super.onResume();
36 |
37 | // More code here later in the chapter
38 | mPongGame.resume();
39 | }
40 |
41 | @Override
42 | protected void onPause() {
43 | super.onPause();
44 |
45 | // More code here later in the chapter
46 | mPongGame.pause();
47 | }
48 |
49 |
50 | }
51 |
--------------------------------------------------------------------------------
/Chapter 10/AndroidManifest.xml:
--------------------------------------------------------------------------------
1 |
2 |
4 |
5 |
12 |
16 |
17 | >
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
26 |
--------------------------------------------------------------------------------
/Chapter 10/java/Bat.java:
--------------------------------------------------------------------------------
1 | package com.gamecodeschool.pong;
2 |
3 | import android.graphics.RectF;
4 |
5 | public class Bat {
6 | // These are the member variables (fields)
7 | // They all have the m prefix
8 | // They are all private
9 | // because direct access is not required
10 | private RectF mRect;
11 | private float mLength;
12 | private float mXCoord;
13 | private float mBatSpeed;
14 | private int mScreenX;
15 |
16 | // These variables are public and final
17 | // They can be directly accessed by
18 | // the instance (in PongGame)
19 | // because they are part of the same
20 | // package but cannot be changed
21 | final int STOPPED = 0;
22 | final int LEFT = 1;
23 | final int RIGHT = 2;
24 |
25 | // Keeps track of if an how the ball is moving
26 | // Starting with STOPPED
27 | private int mBatMoving = STOPPED;
28 |
29 | Bat(int sx, int sy){
30 |
31 | // Bat needs to know the screen
32 | // horizontal resolution
33 | // Outside of this method
34 | mScreenX = sx;
35 |
36 | // Configure the size of the bat based on
37 | // the screen resolution
38 | // One eighth the screen width
39 | mLength = mScreenX / 8;
40 | // One fortieth the screen height
41 | float height = sy / 40;
42 |
43 | // Configure the starting location of the bat
44 | // Roughly the middle horizontally
45 | mXCoord = mScreenX / 2;
46 | // The height of the bat
47 | // off the bottom of the screen
48 | float mYCoord = sy - height;
49 |
50 | // Initialize mRect based on the size and position
51 | mRect = new RectF(mXCoord, mYCoord,
52 | mXCoord + mLength,
53 | mYCoord + height);
54 |
55 | // Configure the speed of the bat
56 | // This code means the bat can cover the
57 | // width of the screen in 1 second
58 | mBatSpeed = mScreenX;
59 | }
60 |
61 | // Return a reference to the mRect object
62 | RectF getRect(){
63 | return mRect;
64 | }
65 |
66 | // Update the movement state passed
67 | // in by the onTouchEvent method
68 | void setMovementState(int state){
69 | mBatMoving = state;
70 | }
71 |
72 | // Update the bat- Called each frame/loop
73 | void update(long fps){
74 |
75 | // Move the bat based on the mBatMoving variable
76 | // and the speed of the previous frame
77 | if(mBatMoving == LEFT){
78 | mXCoord = mXCoord - mBatSpeed / fps;
79 | }
80 |
81 | if(mBatMoving == RIGHT){
82 | mXCoord = mXCoord + mBatSpeed / fps;
83 | }
84 |
85 | // Stop the bat going off the screen
86 | if(mXCoord < 0){
87 | mXCoord = 0;
88 | }
89 |
90 | else if(mXCoord + mLength > mScreenX){
91 | mXCoord = mScreenX - mLength;
92 | }
93 |
94 | // Update mRect based on the results from
95 | // the previous code in update
96 | mRect.left = mXCoord;
97 | mRect.right = mXCoord + mLength;
98 | }
99 |
100 |
101 |
102 | }
103 |
--------------------------------------------------------------------------------
/Chapter 10/java/PongActivity.java:
--------------------------------------------------------------------------------
1 | package com.gamecodeschool.pong;
2 |
3 | import android.app.Activity;
4 | import android.view.Window;
5 |
6 | import android.os.Bundle;
7 |
8 | import android.graphics.Point;
9 | import android.view.Display;
10 |
11 |
12 | public class PongActivity extends Activity {
13 |
14 | private PongGame mPongGame;
15 |
16 | @Override
17 | protected void onCreate(Bundle savedInstanceState) {
18 | super.onCreate(savedInstanceState);
19 |
20 | requestWindowFeature(Window.FEATURE_NO_TITLE);
21 | getWindow().setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN, WindowManager.LayoutParams.FLAG_FULLSCREEN);
22 |
23 | Display display = getWindowManager().getDefaultDisplay();
24 | Point size = new Point();
25 | display.getSize(size);
26 |
27 | mPongGame = new PongGame(this, size.x, size.y);
28 | setContentView(mPongGame);
29 |
30 | }
31 |
32 |
33 | @Override
34 | protected void onResume() {
35 | super.onResume();
36 |
37 | // More code here later in the chapter
38 | mPongGame.resume();
39 | }
40 |
41 | @Override
42 | protected void onPause() {
43 | super.onPause();
44 |
45 | // More code here later in the chapter
46 | mPongGame.pause();
47 | }
48 |
49 |
50 | }
51 |
--------------------------------------------------------------------------------
/Chapter 11/AndroidManifest.xml:
--------------------------------------------------------------------------------
1 |
2 |
4 |
5 |
12 |
16 |
17 | >
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
26 |
--------------------------------------------------------------------------------
/Chapter 11/assets/beep.ogg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/PacktPublishing/Learning-Java-by-Building-Android-Games-Third-Edition/9e56a97be80dcca7c697937a046b4a43b250e29f/Chapter 11/assets/beep.ogg
--------------------------------------------------------------------------------
/Chapter 11/assets/boop.ogg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/PacktPublishing/Learning-Java-by-Building-Android-Games-Third-Edition/9e56a97be80dcca7c697937a046b4a43b250e29f/Chapter 11/assets/boop.ogg
--------------------------------------------------------------------------------
/Chapter 11/assets/bop.ogg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/PacktPublishing/Learning-Java-by-Building-Android-Games-Third-Edition/9e56a97be80dcca7c697937a046b4a43b250e29f/Chapter 11/assets/bop.ogg
--------------------------------------------------------------------------------
/Chapter 11/assets/miss.ogg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/PacktPublishing/Learning-Java-by-Building-Android-Games-Third-Edition/9e56a97be80dcca7c697937a046b4a43b250e29f/Chapter 11/assets/miss.ogg
--------------------------------------------------------------------------------
/Chapter 11/java/Bat.java:
--------------------------------------------------------------------------------
1 | package com.gamecodeschool.pong;
2 |
3 | import android.graphics.RectF;
4 |
5 | public class Bat {
6 | // These are the member variables (fields)
7 | // They all have the m prefix
8 | // They are all private
9 | // because direct access is not required
10 | private RectF mRect;
11 | private float mLength;
12 | private float mXCoord;
13 | private float mBatSpeed;
14 | private int mScreenX;
15 |
16 | // These variables are public and final
17 | // They can be directly accessed by
18 | // the instance (in PongGame)
19 | // because they are part of the same
20 | // package but cannot be changed
21 | final int STOPPED = 0;
22 | final int LEFT = 1;
23 | final int RIGHT = 2;
24 |
25 | // Keeps track of if an how the ball is moving
26 | // Starting with STOPPED
27 | private int mBatMoving = STOPPED;
28 |
29 | Bat(int sx, int sy){
30 |
31 | // Bat needs to know the screen
32 | // horizontal resolution
33 | // Outside of this method
34 | mScreenX = sx;
35 |
36 | // Configure the size of the bat based on
37 | // the screen resolution
38 | // One eighth the screen width
39 | mLength = mScreenX / 8;
40 | // One fortieth the screen height
41 | float height = sy / 40;
42 |
43 | // Configure the starting location of the bat
44 | // Roughly the middle horizontally
45 | mXCoord = mScreenX / 2;
46 | // The height of the bat
47 | // off the bottom of the screen
48 | float mYCoord = sy - height;
49 |
50 | // Initialize mRect based on the size and position
51 | mRect = new RectF(mXCoord, mYCoord,
52 | mXCoord + mLength,
53 | mYCoord + height);
54 |
55 | // Configure the speed of the bat
56 | // This code means the bat can cover the
57 | // width of the screen in 1 second
58 | mBatSpeed = mScreenX;
59 | }
60 |
61 | // Return a reference to the mRect object
62 | RectF getRect(){
63 | return mRect;
64 | }
65 |
66 | // Update the movement state passed
67 | // in by the onTouchEvent method
68 | void setMovementState(int state){
69 | mBatMoving = state;
70 | }
71 |
72 | // Update the bat- Called each frame/loop
73 | void update(long fps){
74 |
75 | // Move the bat based on the mBatMoving variable
76 | // and the speed of the previous frame
77 | if(mBatMoving == LEFT){
78 | mXCoord = mXCoord - mBatSpeed / fps;
79 | }
80 |
81 | if(mBatMoving == RIGHT){
82 | mXCoord = mXCoord + mBatSpeed / fps;
83 | }
84 |
85 | // Stop the bat going off the screen
86 | if(mXCoord < 0){
87 | mXCoord = 0;
88 | }
89 |
90 | else if(mXCoord + mLength > mScreenX){
91 | mXCoord = mScreenX - mLength;
92 | }
93 |
94 | // Update mRect based on the results from
95 | // the previous code in update
96 | mRect.left = mXCoord;
97 | mRect.right = mXCoord + mLength;
98 | }
99 |
100 |
101 |
102 | }
103 |
--------------------------------------------------------------------------------
/Chapter 11/java/PongActivity.java:
--------------------------------------------------------------------------------
1 | package com.gamecodeschool.pong;
2 |
3 | import android.app.Activity;
4 | import android.view.Window;
5 |
6 | import android.os.Bundle;
7 |
8 | import android.graphics.Point;
9 | import android.view.Display;
10 |
11 |
12 | public class PongActivity extends Activity {
13 |
14 | private PongGame mPongGame;
15 |
16 | @Override
17 | protected void onCreate(Bundle savedInstanceState) {
18 | super.onCreate(savedInstanceState);
19 |
20 | requestWindowFeature(Window.FEATURE_NO_TITLE);
21 |
22 | Display display = getWindowManager().getDefaultDisplay();
23 | Point size = new Point();
24 | display.getSize(size);
25 |
26 | mPongGame = new PongGame(this, size.x, size.y);
27 | setContentView(mPongGame);
28 |
29 | }
30 |
31 |
32 | @Override
33 | protected void onResume() {
34 | super.onResume();
35 |
36 | // More code here later in the chapter
37 | mPongGame.resume();
38 | }
39 |
40 | @Override
41 | protected void onPause() {
42 | super.onPause();
43 |
44 | // More code here later in the chapter
45 | mPongGame.pause();
46 | }
47 |
48 |
49 | }
--------------------------------------------------------------------------------
/Chapter 12/C12BulletHell/AndroidManifest.xml:
--------------------------------------------------------------------------------
1 |
2 |
4 |
5 |
12 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
26 |
27 |
--------------------------------------------------------------------------------
/Chapter 12/C12BulletHell/java/Bob.java:
--------------------------------------------------------------------------------
1 | package com.gamecodeschool.bullethell;
2 |
3 | public class Bob {
4 | }
5 |
--------------------------------------------------------------------------------
/Chapter 12/C12BulletHell/java/Bullet.java:
--------------------------------------------------------------------------------
1 | package com.gamecodeschool.bullethell;
2 |
3 | import android.graphics.RectF;
4 |
5 | class Bullet {
6 |
7 | // A RectF to represent the size and location of the bullet
8 | private RectF mRect;
9 |
10 | // How fast is the bullet traveling?
11 | private float mXVelocity;
12 | private float mYVelocity;
13 |
14 | // How big is a bullet
15 | private float mWidth;
16 | private float mHeight;
17 |
18 |
19 |
20 | // The constructor
21 | Bullet(int screenX){
22 |
23 | // Configure the bullet based on
24 | // the screen width in pixels
25 | mWidth = screenX / 100;
26 | mHeight = screenX / 100;
27 | mRect = new RectF();
28 | mYVelocity = (screenX / 5);
29 | mXVelocity = (screenX / 5);
30 | }
31 |
32 | // Return a reference to the RectF
33 | RectF getRect(){
34 | return mRect;
35 | }
36 |
37 | // Move the bullet based on the speed and the frame rate
38 | void update(long fps){
39 | // Update the left and top coordinates
40 | // based on the velocity and current frame rate
41 | mRect.left = mRect.left + (mXVelocity / fps);
42 | mRect.top = mRect.top + (mYVelocity / fps);
43 |
44 | mRect.right = mRect.left + mWidth;
45 | mRect.bottom = mRect.top - mHeight;
46 | }
47 |
48 | // Reverse the bullets vertical direction
49 | void reverseYVelocity(){
50 | mYVelocity = -mYVelocity;
51 | }
52 |
53 | // Reverse the bullets horizontal direction
54 | void reverseXVelocity(){
55 | mXVelocity = -mXVelocity;
56 | }
57 |
58 | // Spawn a new bullet
59 | void spawn(int pX, int pY, int vX, int vY){
60 |
61 | // Spawn the bullet at the location
62 | // passed in as parameters
63 | mRect.left = pX;
64 | mRect.top = pY;
65 | mRect.right = pX + mWidth;
66 | mRect.bottom = pY + mHeight;
67 |
68 | // Head away from the player
69 | // It's only fair
70 | mXVelocity = mXVelocity * vX;
71 | mYVelocity = mYVelocity * vY;
72 |
73 |
74 | }
75 |
76 |
77 | }
78 |
--------------------------------------------------------------------------------
/Chapter 12/C12BulletHell/java/BulletHellActivity.java:
--------------------------------------------------------------------------------
1 | package com.gamecodeschool.bullethell;
2 |
3 | import android.app.Activity;
4 | import android.view.Window;
5 | import android.graphics.Point;
6 | import android.os.Bundle;
7 | import android.view.Display;
8 |
9 |
10 | // This class is almost exactly
11 | // the same as the Pong project
12 | public class BulletHellActivity extends Activity {
13 |
14 | // An instance of the main class of this project
15 | private BulletHellGame mBHGame;
16 |
17 | @Override
18 | protected void onCreate(Bundle savedInstanceState) {
19 | super.onCreate(savedInstanceState);
20 | requestWindowFeature(Window.FEATURE_NO_TITLE);
21 |
22 |
23 | // Get the screen resolution
24 | Display display = getWindowManager().
25 | getDefaultDisplay();
26 | Point size = new Point();
27 | display.getSize(size);
28 |
29 | // Call the constructor(initialize)
30 | // the BulletHellGame instance
31 | mBHGame = new BulletHellGame(this, size.x, size.y);
32 | setContentView(mBHGame);
33 | }
34 |
35 | @Override
36 | // Start the main game thread
37 | // when the game is launched
38 | protected void onResume() {
39 | super.onResume();
40 |
41 | mBHGame.resume();
42 | }
43 |
44 | @Override
45 | // Stop the thread when the player quits
46 | protected void onPause() {
47 | super.onPause();
48 |
49 | mBHGame.pause();
50 | }
51 | }
52 |
--------------------------------------------------------------------------------
/Chapter 12/Dynamic Array Example/MainActivity.java:
--------------------------------------------------------------------------------
1 | package com.packtpub.dynamicarrayexample.dynamicarrayexample;
2 |
3 | import android.app.Activity;
4 | import android.os.Bundle;
5 | import android.util.Log;
6 |
7 |
8 | public class MainActivity extends Activity {
9 |
10 | @Override
11 | protected void onCreate(Bundle savedInstanceState) {
12 | super.onCreate(savedInstanceState);
13 | setContentView(R.layout.activity_main);
14 |
15 | //Declaring and allocating in one step
16 | int[] ourArray = new int[1000];
17 |
18 | //Let's initialize ourArray using a for loop
19 | //Because more than a few variables is allot of typing!
20 | for(int i = 0; i < 1000; i++){
21 | //Put the value of ourValue into our array
22 | //At the position determined by i.
23 | ourArray[i] = i*5;
24 |
25 | //Output what is going on
26 | Log.i("info", "i = " + i);
27 | Log.i("info", "ourArray[i] = " + ourArray[i]);
28 | }
29 | }
30 |
31 | }
32 |
--------------------------------------------------------------------------------
/Chapter 12/Multidimensional Array Example/MainActivity.java:
--------------------------------------------------------------------------------
1 | package com.packtpub.dynamicarrayexample.dynamicarrayexample;
2 |
3 | import android.app.Activity;
4 |
5 | import android.os.Bundle;
6 | import android.util.Log;
7 |
8 | import java.util.Random;
9 |
10 | public class MainActivity extends Activity {
11 |
12 | @Override
13 | protected void onCreate(Bundle savedInstanceState) {
14 | super.onCreate(savedInstanceState);
15 | // Random object for generating question numbers
16 | Random randInt = new Random();
17 | // a variable to hold the random value generated
18 | int questionNumber;// Declare and allocate in separate stages for clarity
19 | // but we don't have to
20 | String[][] countriesAndCities;
21 | // Now we have a 2-dimensional array
22 |
23 | countriesAndCities = new String[5][2];
24 | // 5 arrays with 2 elements each
25 | // Perfect for 5 "What's the capital city" questions
26 |
27 | // Now we load the questions and answers into our arrays
28 | // You could do this with less questions to save typing
29 | // But don't do more or you will get an exception
30 | countriesAndCities [0][0] = "United Kingdom";
31 | countriesAndCities [0][1] = "London";
32 |
33 | countriesAndCities [1][0] = "USA";
34 | countriesAndCities [1][1] = "Washington";
35 |
36 | countriesAndCities [2][0] = "India";
37 | countriesAndCities [2][1] = "New Delhi";
38 |
39 | countriesAndCities [3][0] = "Brazil";
40 | countriesAndCities [3][1] = "Brasilia";
41 |
42 | countriesAndCities [4][0] = "Kenya";
43 | countriesAndCities [4][1] = "Nairobi";
44 | /*
45 | Now we know that the country is stored at element 0
46 | The matching capital at element 1
47 | Here are two variables that reflect this
48 | */
49 | final int COUNTRY = 0;
50 | final int CAPITAL = 1;
51 |
52 | // A quick for loop to ask 3 questions
53 | for(int i = 0; i < 3; i++){
54 | // get a random question number between 0 and 4
55 | questionNumber = randInt.nextInt(5);
56 |
57 | // and ask the question and in this case just
58 | // give the answer for the sake of brevity
59 | Log.d("info", "The capital of "
60 | +countriesAndCities[questionNumber][COUNTRY]);
61 |
62 | Log.d("info", "is "
63 | +countriesAndCities[questionNumber][CAPITAL]);
64 |
65 | } // end of for loop
66 |
67 |
68 | }
69 | }
70 |
--------------------------------------------------------------------------------
/Chapter 12/Simple Array Example/MainActivity.java:
--------------------------------------------------------------------------------
1 | package com.packtpub.simplearrayexample.simplearrayexample;
2 |
3 | import android.app.Activity;
4 | import android.os.Bundle;
5 | import android.util.Log;
6 |
7 |
8 | public class MainActivity extends Activity {
9 |
10 | @Override
11 | protected void onCreate(Bundle savedInstanceState) {
12 | super.onCreate(savedInstanceState);
13 | setContentView(R.layout.activity_main);
14 |
15 | //Declaring an array
16 | int[] ourArray;
17 |
18 | //Allocate memory for a maximum size of 5 elements
19 | ourArray = new int[5];
20 |
21 | //Initialize ourArray with values
22 | //The values are arbitrary as long as they are int
23 | //The indexes are not arbitrary 0 through 4 or crash!
24 | ourArray[0] = 25;
25 | ourArray[1] = 50;
26 | ourArray[2] = 125;
27 | ourArray[3] = 68;
28 | ourArray[4] = 47;
29 |
30 | //Output all the stored values
31 | Log.i("info", "Here is ourArray:");
32 | Log.i("info", "[0] = "+ourArray[0]);
33 | Log.i("info", "[1] = "+ourArray[1]);
34 | Log.i("info", "[2] = "+ourArray[2]);
35 | Log.i("info", "[3] = "+ourArray[3]);
36 | Log.i("info", "[4] = "+ourArray[4]);
37 |
38 | //We can do any calculation with an array element
39 | //As long as it is appropriate to the contained type
40 | //Like this:
41 | int answer = ourArray[0] +
42 | ourArray[1] +
43 | ourArray[2] +
44 | ourArray[3] +
45 | ourArray[4];
46 |
47 | Log.i("info", "Answer = "+answer);
48 | }
49 |
50 |
51 |
52 | }
53 |
--------------------------------------------------------------------------------
/Chapter 13/AndroidManifest.xml:
--------------------------------------------------------------------------------
1 |
2 |
4 |
5 |
12 |
16 |
17 | >
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
26 |
--------------------------------------------------------------------------------
/Chapter 13/assets/beep.ogg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/PacktPublishing/Learning-Java-by-Building-Android-Games-Third-Edition/9e56a97be80dcca7c697937a046b4a43b250e29f/Chapter 13/assets/beep.ogg
--------------------------------------------------------------------------------
/Chapter 13/assets/teleport.ogg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/PacktPublishing/Learning-Java-by-Building-Android-Games-Third-Edition/9e56a97be80dcca7c697937a046b4a43b250e29f/Chapter 13/assets/teleport.ogg
--------------------------------------------------------------------------------
/Chapter 13/drawable/bob.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/PacktPublishing/Learning-Java-by-Building-Android-Games-Third-Edition/9e56a97be80dcca7c697937a046b4a43b250e29f/Chapter 13/drawable/bob.png
--------------------------------------------------------------------------------
/Chapter 13/java/Bob.java:
--------------------------------------------------------------------------------
1 | package com.gamecodeschool.bullethell;
2 |
3 | import android.content.Context;
4 | import android.graphics.Bitmap;
5 | import android.graphics.BitmapFactory;
6 | import android.graphics.RectF;
7 |
8 | class Bob {
9 |
10 | RectF mRect;
11 | float mBobHeight;
12 | float mBobWidth;
13 | boolean mTeleporting = false;
14 |
15 | Bitmap mBitmap;
16 |
17 | public Bob(Context context, float screenX, float screenY){
18 | mBobHeight = screenY / 10;
19 | mBobWidth = mBobHeight / 2;
20 |
21 | mRect = new RectF(screenX / 2,
22 | screenY / 2,
23 | (screenX / 2) + mBobWidth,
24 | (screenY / 2) + mBobHeight);
25 |
26 | // Prepare the bitmap
27 | // Load Bob from his .png file
28 | // Bob practices responsible encapsulation
29 | // looking after his own resources
30 | mBitmap = BitmapFactory.decodeResource
31 | (context.getResources(), R.drawable.bob);
32 | }
33 |
34 | boolean teleport(float newX, float newY){
35 |
36 | // Did Bob manage to teleport?
37 | boolean success = false;
38 |
39 | // Move Bob to the new position
40 | // If not already teleporting
41 | if(!mTeleporting){
42 |
43 | // Make him roughly central to the touch
44 | mRect.left = newX - mBobWidth / 2;
45 | mRect.top = newY - mBobHeight / 2;
46 | mRect.bottom = mRect.top + mBobHeight;
47 | mRect.right = mRect.left + mBobWidth;
48 |
49 | mTeleporting = true;
50 |
51 | // Notify BulletHellGame that teleport
52 | // attempt was successful
53 | success = true;
54 | }
55 |
56 | return success;
57 | }
58 |
59 | void setTelePortAvailable(){
60 | mTeleporting = false;
61 | }
62 |
63 | // Return a reference to mRect
64 | RectF getRect(){
65 | return mRect;
66 | }
67 |
68 | // Return a reference to bitmap
69 | Bitmap getBitmap(){
70 | return mBitmap;
71 | }
72 | }
73 |
--------------------------------------------------------------------------------
/Chapter 13/java/Bullet.java:
--------------------------------------------------------------------------------
1 | package com.gamecodeschool.bullethell;
2 |
3 | import android.graphics.RectF;
4 |
5 | class Bullet {
6 |
7 | // A RectF to represent the size and location of the bullet
8 | private RectF mRect;
9 |
10 | // How fast is the bullet traveling?
11 | private float mXVelocity;
12 | private float mYVelocity;
13 |
14 | // How big is a bullet
15 | private float mWidth;
16 | private float mHeight;
17 |
18 |
19 |
20 | // The constructor
21 | Bullet(int screenX){
22 |
23 | // Configure the bullet based on
24 | // the screen width in pixels
25 | mWidth = screenX / 100;
26 | mHeight = screenX / 100;
27 | mRect = new RectF();
28 | mYVelocity = (screenX / 5);
29 | mXVelocity = (screenX / 5);
30 | }
31 |
32 | // Return a reference to the RectF
33 | RectF getRect(){
34 | return mRect;
35 | }
36 |
37 | // Move the bullet based on the speed and the frame rate
38 | void update(long fps){
39 | // Update the left and top coordinates
40 | // based on the velocity and current frame rate
41 | mRect.left = mRect.left + (mXVelocity / fps);
42 | mRect.top = mRect.top + (mYVelocity / fps);
43 |
44 | mRect.right = mRect.left + mWidth;
45 | mRect.bottom = mRect.top - mHeight;
46 | }
47 |
48 | // Reverse the bullets vertical direction
49 | void reverseYVelocity(){
50 | mYVelocity = -mYVelocity;
51 | }
52 |
53 | // Reverse the bullets horizontal direction
54 | void reverseXVelocity(){
55 | mXVelocity = -mXVelocity;
56 | }
57 |
58 | // Spawn a new bullet
59 | void spawn(int pX, int pY, int vX, int vY){
60 |
61 | // Spawn the bullet at the location
62 | // passed in as parameters
63 | mRect.left = pX;
64 | mRect.top = pY;
65 | mRect.right = pX + mWidth;
66 | mRect.bottom = pY + mHeight;
67 |
68 | // Head away from the player
69 | // It's only fair
70 | mXVelocity = mXVelocity * vX;
71 | mYVelocity = mYVelocity * vY;
72 |
73 |
74 | }
75 |
76 |
77 | }
78 |
--------------------------------------------------------------------------------
/Chapter 13/java/BulletHellActivity.java:
--------------------------------------------------------------------------------
1 | package com.gamecodeschool.bullethell;
2 |
3 | import android.app.Activity;
4 | import android.view.Window;
5 | import android.graphics.Point;
6 | import android.os.Bundle;
7 | import android.view.Display;
8 |
9 |
10 | // This class is almost exactly
11 | // the same as the Pong project
12 | public class BulletHellActivity extends Activity {
13 |
14 | // An instance of the main class of this project
15 | private BulletHellGame mBHGame;
16 |
17 | @Override
18 | protected void onCreate(Bundle savedInstanceState) {
19 | super.onCreate(savedInstanceState);
20 | requestWindowFeature(Window.FEATURE_NO_TITLE);
21 |
22 |
23 | // Get the screen resolution
24 | Display display = getWindowManager().
25 | getDefaultDisplay();
26 | Point size = new Point();
27 | display.getSize(size);
28 |
29 | // Call the constructor(initialize)
30 | // the BulletHellGame instance
31 | mBHGame = new BulletHellGame(this, size.x, size.y);
32 | setContentView(mBHGame);
33 | }
34 |
35 | @Override
36 | // Start the main game thread
37 | // when the game is launched
38 | protected void onResume() {
39 | super.onResume();
40 |
41 | mBHGame.resume();
42 | }
43 |
44 | @Override
45 | // Stop the thread when the player quits
46 | protected void onPause() {
47 | super.onPause();
48 |
49 | mBHGame.pause();
50 | }
51 | }
52 |
--------------------------------------------------------------------------------
/Chapter 14/AndroidManifest.xml:
--------------------------------------------------------------------------------
1 |
2 |
4 |
5 |
12 |
16 |
17 |
18 | >
19 |
20 |
21 |
22 |
23 |
24 |
25 |
26 |
27 |
--------------------------------------------------------------------------------
/Chapter 14/assets/get_apple.ogg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/PacktPublishing/Learning-Java-by-Building-Android-Games-Third-Edition/9e56a97be80dcca7c697937a046b4a43b250e29f/Chapter 14/assets/get_apple.ogg
--------------------------------------------------------------------------------
/Chapter 14/assets/snake_death.ogg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/PacktPublishing/Learning-Java-by-Building-Android-Games-Third-Edition/9e56a97be80dcca7c697937a046b4a43b250e29f/Chapter 14/assets/snake_death.ogg
--------------------------------------------------------------------------------
/Chapter 14/java/Apple.java:
--------------------------------------------------------------------------------
1 | package com.gamecodeschool.snake;
2 |
3 | public class Apple {
4 | }
5 |
--------------------------------------------------------------------------------
/Chapter 14/java/Snake.java:
--------------------------------------------------------------------------------
1 | package com.gamecodeschool.snake;
2 |
3 | public class Snake {
4 | }
5 |
--------------------------------------------------------------------------------
/Chapter 14/java/SnakeActivity.java:
--------------------------------------------------------------------------------
1 | package com.gamecodeschool.snake;
2 |
3 | import android.app.Activity;
4 | import android.graphics.Point;
5 | import android.os.Bundle;
6 | import android.view.Display;
7 | import android.view.Window;
8 |
9 | public class SnakeActivity extends Activity {
10 |
11 | // Declare an instance of SnakeGame
12 | SnakeGame mSnakeGame;
13 |
14 | // Set the game up
15 | @Override
16 | protected void onCreate(Bundle savedInstanceState) {
17 |
18 | super.onCreate(savedInstanceState);
19 | requestWindowFeature(Window.FEATURE_NO_TITLE);
20 |
21 | // Get the pixel dimensions of the screen
22 | Display display = getWindowManager().getDefaultDisplay();
23 |
24 | // Initialize the result into a Point object
25 | Point size = new Point();
26 | display.getSize(size);
27 |
28 | // Create a new instance of the SnakeEngine class
29 | mSnakeGame = new SnakeGame(this, size);
30 |
31 | // Make snakeEngine the view of the Activity
32 | setContentView(mSnakeGame);
33 | }
34 |
35 | // Start the thread in snakeEngine
36 | @Override
37 | protected void onResume() {
38 | super.onResume();
39 | mSnakeGame.resume();
40 | }
41 |
42 | // Stop the thread in snakeEngine
43 | @Override
44 | protected void onPause() {
45 | super.onPause();
46 | mSnakeGame.pause();
47 | }
48 | }
49 |
--------------------------------------------------------------------------------
/Chapter 15/AndroidManifest.xml:
--------------------------------------------------------------------------------
1 |
2 |
4 |
5 |
12 |
16 |
17 |
18 | >
19 |
20 |
21 |
22 |
23 |
24 |
25 |
26 |
27 |
--------------------------------------------------------------------------------
/Chapter 15/assets/get_apple.ogg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/PacktPublishing/Learning-Java-by-Building-Android-Games-Third-Edition/9e56a97be80dcca7c697937a046b4a43b250e29f/Chapter 15/assets/get_apple.ogg
--------------------------------------------------------------------------------
/Chapter 15/assets/snake_death.ogg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/PacktPublishing/Learning-Java-by-Building-Android-Games-Third-Edition/9e56a97be80dcca7c697937a046b4a43b250e29f/Chapter 15/assets/snake_death.ogg
--------------------------------------------------------------------------------
/Chapter 15/java/Apple.java:
--------------------------------------------------------------------------------
1 | package com.gamecodeschool.snake;
2 |
3 | public class Apple {
4 | }
5 |
--------------------------------------------------------------------------------
/Chapter 15/java/Snake.java:
--------------------------------------------------------------------------------
1 | package com.gamecodeschool.snake;
2 |
3 | public class Snake {
4 | }
5 |
--------------------------------------------------------------------------------
/Chapter 15/java/SnakeActivity.java:
--------------------------------------------------------------------------------
1 | package com.gamecodeschool.snake;
2 |
3 | import android.app.Activity;
4 | import android.graphics.Point;
5 | import android.os.Bundle;
6 | import android.view.Display;
7 | import android.view.Window;
8 |
9 | public class SnakeActivity extends Activity {
10 |
11 | // Declare an instance of SnakeGame
12 | SnakeGame mSnakeGame;
13 |
14 | // Set the game up
15 | @Override
16 | protected void onCreate(Bundle savedInstanceState) {
17 |
18 | super.onCreate(savedInstanceState);
19 | requestWindowFeature(Window.FEATURE_NO_TITLE);
20 |
21 | // Get the pixel dimensions of the screen
22 | Display display = getWindowManager().getDefaultDisplay();
23 |
24 | // Initialize the result into a Point object
25 | Point size = new Point();
26 | display.getSize(size);
27 |
28 | // Create a new instance of the SnakeEngine class
29 | mSnakeGame = new SnakeGame(this, size);
30 |
31 | // Make snakeEngine the view of the Activity
32 | setContentView(mSnakeGame);
33 | }
34 |
35 | // Start the thread in snakeEngine
36 | @Override
37 | protected void onResume() {
38 | super.onResume();
39 | mSnakeGame.resume();
40 | }
41 |
42 | // Stop the thread in snakeEngine
43 | @Override
44 | protected void onPause() {
45 | super.onPause();
46 | mSnakeGame.pause();
47 | }
48 | }
49 |
--------------------------------------------------------------------------------
/Chapter 15/values-de/strings.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 | Tippen Sie, um zu spielen!
4 |
5 |
--------------------------------------------------------------------------------
/Chapter 15/values-es/strings.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 | Toque para jugar!
4 |
5 |
--------------------------------------------------------------------------------
/Chapter 15/values/colors.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 | #6200EE
4 | #3700B3
5 | #03DAC5
6 |
--------------------------------------------------------------------------------
/Chapter 15/values/strings.xml:
--------------------------------------------------------------------------------
1 |
2 | Snake
3 | Tap To Play!
4 |
5 |
--------------------------------------------------------------------------------
/Chapter 15/values/styles.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
9 |
10 |
--------------------------------------------------------------------------------
/Chapter 16/AndroidManifest.xml:
--------------------------------------------------------------------------------
1 |
2 |
4 |
5 |
12 |
16 |
17 |
18 | >
19 |
20 |
21 |
22 |
23 |
24 |
25 |
26 |
27 |
--------------------------------------------------------------------------------
/Chapter 16/assets/get_apple.ogg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/PacktPublishing/Learning-Java-by-Building-Android-Games-Third-Edition/9e56a97be80dcca7c697937a046b4a43b250e29f/Chapter 16/assets/get_apple.ogg
--------------------------------------------------------------------------------
/Chapter 16/assets/snake_death.ogg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/PacktPublishing/Learning-Java-by-Building-Android-Games-Third-Edition/9e56a97be80dcca7c697937a046b4a43b250e29f/Chapter 16/assets/snake_death.ogg
--------------------------------------------------------------------------------
/Chapter 16/drawable/apple.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/PacktPublishing/Learning-Java-by-Building-Android-Games-Third-Edition/9e56a97be80dcca7c697937a046b4a43b250e29f/Chapter 16/drawable/apple.png
--------------------------------------------------------------------------------
/Chapter 16/drawable/body.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/PacktPublishing/Learning-Java-by-Building-Android-Games-Third-Edition/9e56a97be80dcca7c697937a046b4a43b250e29f/Chapter 16/drawable/body.png
--------------------------------------------------------------------------------
/Chapter 16/drawable/head.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/PacktPublishing/Learning-Java-by-Building-Android-Games-Third-Edition/9e56a97be80dcca7c697937a046b4a43b250e29f/Chapter 16/drawable/head.png
--------------------------------------------------------------------------------
/Chapter 16/java/Apple.java:
--------------------------------------------------------------------------------
1 | package com.gamecodeschool.snake;
2 |
3 | import android.content.Context;
4 | import android.graphics.Bitmap;
5 | import android.graphics.BitmapFactory;
6 | import android.graphics.Canvas;
7 | import android.graphics.Paint;
8 | import android.graphics.Point;
9 | import java.util.Random;
10 |
11 | class Apple {
12 |
13 | // The location of the apple on the grid
14 | // Not in pixels
15 | private Point mLocation = new Point();
16 |
17 | // The range of values we can choose from
18 | // to spawn an apple
19 | private Point mSpawnRange;
20 | private int mSize;
21 |
22 | // An image to represent the apple
23 | private Bitmap mBitmapApple;
24 |
25 | /// Set up the apple in the constructor
26 | Apple(Context context, Point sr, int s){
27 |
28 | // Make a note of the passed in spawn range
29 | mSpawnRange = sr;
30 | // Make a note of the size of an apple
31 | mSize = s;
32 | // Hide the apple off-screen until the game starts
33 | mLocation.x = -10;
34 |
35 | // Load the image to the bitmap
36 | mBitmapApple = BitmapFactory
37 | .decodeResource(context.getResources(),
38 | R.drawable.apple);
39 |
40 | // Resize the bitmap
41 | mBitmapApple = Bitmap
42 | .createScaledBitmap(mBitmapApple, s, s, false);
43 | }
44 |
45 | // This is called every time an apple is eaten
46 | void spawn(){
47 | // Choose two random values and place the apple
48 | Random random = new Random();
49 | mLocation.x = random.nextInt(mSpawnRange.x) + 1;
50 | mLocation.y = random.nextInt(mSpawnRange.y - 1) + 1;
51 | }
52 |
53 | // Let SnakeGame know where the apple is
54 | // SnakeGame can share this with the snake
55 | Point getLocation(){
56 | return mLocation;
57 | }
58 |
59 | // Draw the apple
60 | void draw(Canvas canvas, Paint paint){
61 | canvas.drawBitmap(mBitmapApple,
62 | mLocation.x * mSize, mLocation.y * mSize, paint);
63 |
64 | }
65 |
66 |
67 |
68 | }
69 |
--------------------------------------------------------------------------------
/Chapter 16/java/Snake.java:
--------------------------------------------------------------------------------
1 | package com.gamecodeschool.snake;
2 |
3 | public class Snake {
4 | }
5 |
--------------------------------------------------------------------------------
/Chapter 16/java/SnakeActivity.java:
--------------------------------------------------------------------------------
1 | package com.gamecodeschool.snake;
2 |
3 | import android.app.Activity;
4 | import android.graphics.Point;
5 | import android.os.Bundle;
6 | import android.view.Display;
7 | import android.view.Window;
8 |
9 | public class SnakeActivity extends Activity {
10 |
11 | // Declare an instance of SnakeGame
12 | SnakeGame mSnakeGame;
13 |
14 | // Set the game up
15 | @Override
16 | protected void onCreate(Bundle savedInstanceState) {
17 |
18 | super.onCreate(savedInstanceState);
19 | requestWindowFeature(Window.FEATURE_NO_TITLE);
20 |
21 | // Get the pixel dimensions of the screen
22 | Display display = getWindowManager().getDefaultDisplay();
23 |
24 | // Initialize the result into a Point object
25 | Point size = new Point();
26 | display.getSize(size);
27 |
28 | // Create a new instance of the SnakeEngine class
29 | mSnakeGame = new SnakeGame(this, size);
30 |
31 | // Make snakeEngine the view of the Activity
32 | setContentView(mSnakeGame);
33 | }
34 |
35 | // Start the thread in snakeEngine
36 | @Override
37 | protected void onResume() {
38 | super.onResume();
39 | mSnakeGame.resume();
40 | }
41 |
42 | // Stop the thread in snakeEngine
43 | @Override
44 | protected void onPause() {
45 | super.onPause();
46 | mSnakeGame.pause();
47 | }
48 | }
49 |
--------------------------------------------------------------------------------
/Chapter 17/AndroidManifest.xml:
--------------------------------------------------------------------------------
1 |
2 |
4 |
5 |
12 |
16 |
17 |
18 | >
19 |
20 |
21 |
22 |
23 |
24 |
25 |
26 |
27 |
--------------------------------------------------------------------------------
/Chapter 17/assets/get_apple.ogg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/PacktPublishing/Learning-Java-by-Building-Android-Games-Third-Edition/9e56a97be80dcca7c697937a046b4a43b250e29f/Chapter 17/assets/get_apple.ogg
--------------------------------------------------------------------------------
/Chapter 17/assets/snake_death.ogg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/PacktPublishing/Learning-Java-by-Building-Android-Games-Third-Edition/9e56a97be80dcca7c697937a046b4a43b250e29f/Chapter 17/assets/snake_death.ogg
--------------------------------------------------------------------------------
/Chapter 17/drawable/apple.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/PacktPublishing/Learning-Java-by-Building-Android-Games-Third-Edition/9e56a97be80dcca7c697937a046b4a43b250e29f/Chapter 17/drawable/apple.png
--------------------------------------------------------------------------------
/Chapter 17/drawable/body.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/PacktPublishing/Learning-Java-by-Building-Android-Games-Third-Edition/9e56a97be80dcca7c697937a046b4a43b250e29f/Chapter 17/drawable/body.png
--------------------------------------------------------------------------------
/Chapter 17/drawable/head.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/PacktPublishing/Learning-Java-by-Building-Android-Games-Third-Edition/9e56a97be80dcca7c697937a046b4a43b250e29f/Chapter 17/drawable/head.png
--------------------------------------------------------------------------------
/Chapter 17/java/Apple.java:
--------------------------------------------------------------------------------
1 | package com.gamecodeschool.snake;
2 |
3 | import android.content.Context;
4 | import android.graphics.Bitmap;
5 | import android.graphics.BitmapFactory;
6 | import android.graphics.Canvas;
7 | import android.graphics.Paint;
8 | import android.graphics.Point;
9 | import java.util.Random;
10 |
11 | class Apple {
12 |
13 | // The location of the apple on the grid
14 | // Not in pixels
15 | private Point mLocation = new Point();
16 |
17 | // The range of values we can choose from
18 | // to spawn an apple
19 | private Point mSpawnRange;
20 | private int mSize;
21 |
22 | // An image to represent the apple
23 | private Bitmap mBitmapApple;
24 |
25 | /// Set up the apple in the constructor
26 | Apple(Context context, Point sr, int s){
27 |
28 | // Make a note of the passed in spawn range
29 | mSpawnRange = sr;
30 | // Make a note of the size of an apple
31 | mSize = s;
32 | // Hide the apple off-screen until the game starts
33 | mLocation.x = -10;
34 |
35 | // Load the image to the bitmap
36 | mBitmapApple = BitmapFactory
37 | .decodeResource(context.getResources(),
38 | R.drawable.apple);
39 |
40 | // Resize the bitmap
41 | mBitmapApple = Bitmap
42 | .createScaledBitmap(mBitmapApple, s, s, false);
43 | }
44 |
45 | // This is called every time an apple is eaten
46 | void spawn(){
47 | // Choose two random values and place the apple
48 | Random random = new Random();
49 | mLocation.x = random.nextInt(mSpawnRange.x) + 1;
50 | mLocation.y = random.nextInt(mSpawnRange.y - 1) + 1;
51 | }
52 |
53 | // Let SnakeGame know where the apple is
54 | // SnakeGame can share this with the snake
55 | Point getLocation(){
56 | return mLocation;
57 | }
58 |
59 | // Draw the apple
60 | void draw(Canvas canvas, Paint paint){
61 | canvas.drawBitmap(mBitmapApple,
62 | mLocation.x * mSize, mLocation.y * mSize, paint);
63 |
64 | }
65 |
66 |
67 |
68 | }
69 |
--------------------------------------------------------------------------------
/Chapter 17/java/SnakeActivity.java:
--------------------------------------------------------------------------------
1 | package com.gamecodeschool.snake;
2 |
3 | import android.app.Activity;
4 | import android.graphics.Point;
5 | import android.os.Bundle;
6 | import android.view.Display;
7 | import android.view.Window;
8 |
9 | public class SnakeActivity extends Activity {
10 |
11 | // Declare an instance of SnakeGame
12 | SnakeGame mSnakeGame;
13 |
14 | // Set the game up
15 | @Override
16 | protected void onCreate(Bundle savedInstanceState) {
17 |
18 | super.onCreate(savedInstanceState);
19 | requestWindowFeature(Window.FEATURE_NO_TITLE);
20 |
21 | // Get the pixel dimensions of the screen
22 | Display display = getWindowManager().getDefaultDisplay();
23 |
24 | // Initialize the result into a Point object
25 | Point size = new Point();
26 | display.getSize(size);
27 |
28 | // Create a new instance of the SnakeEngine class
29 | mSnakeGame = new SnakeGame(this, size);
30 |
31 | // Make snakeEngine the view of the Activity
32 | setContentView(mSnakeGame);
33 | }
34 |
35 | // Start the thread in snakeEngine
36 | @Override
37 | protected void onResume() {
38 | super.onResume();
39 | mSnakeGame.resume();
40 | }
41 |
42 | // Stop the thread in snakeEngine
43 | @Override
44 | protected void onPause() {
45 | super.onPause();
46 | mSnakeGame.pause();
47 | }
48 | }
49 |
--------------------------------------------------------------------------------
/Chapter 18/AndroidManifest.xml:
--------------------------------------------------------------------------------
1 |
2 |
4 |
5 |
12 |
15 | >
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
--------------------------------------------------------------------------------
/Chapter 18/assets/alien_explosion.ogg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/PacktPublishing/Learning-Java-by-Building-Android-Games-Third-Edition/9e56a97be80dcca7c697937a046b4a43b250e29f/Chapter 18/assets/alien_explosion.ogg
--------------------------------------------------------------------------------
/Chapter 18/assets/player_explosion.ogg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/PacktPublishing/Learning-Java-by-Building-Android-Games-Third-Edition/9e56a97be80dcca7c697937a046b4a43b250e29f/Chapter 18/assets/player_explosion.ogg
--------------------------------------------------------------------------------
/Chapter 18/assets/shoot.ogg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/PacktPublishing/Learning-Java-by-Building-Android-Games-Third-Edition/9e56a97be80dcca7c697937a046b4a43b250e29f/Chapter 18/assets/shoot.ogg
--------------------------------------------------------------------------------
/Chapter 18/java/GameActivity.java:
--------------------------------------------------------------------------------
1 | package com.gamecodeschool.scrollingshooter;
2 |
3 | import android.app.Activity;
4 | import android.graphics.Point;
5 | import android.os.Bundle;
6 | import android.view.Display;
7 | import android.view.Window;
8 |
9 | public class GameActivity extends Activity {
10 |
11 | GameEngine mGameEngine;
12 |
13 | @Override
14 | protected void onCreate(Bundle savedInstanceState) {
15 | super.onCreate(savedInstanceState);
16 | requestWindowFeature(Window.FEATURE_NO_TITLE);
17 |
18 | Display display = getWindowManager()
19 | .getDefaultDisplay();
20 |
21 | Point size = new Point();
22 | display.getSize(size);
23 | mGameEngine = new GameEngine(this, size);
24 | setContentView(mGameEngine);
25 | }
26 |
27 | @Override
28 | protected void onResume() {
29 | super.onResume();
30 | mGameEngine.startThread();
31 | }
32 |
33 | @Override
34 | protected void onPause() {
35 | super.onPause();
36 | mGameEngine.stopThread();
37 | }
38 | }
39 |
--------------------------------------------------------------------------------
/Chapter 18/java/GameEngine.java:
--------------------------------------------------------------------------------
1 | package com.gamecodeschool.scrollingshooter;
2 |
3 | import android.content.Context;
4 | import android.graphics.Point;
5 | import android.util.Log;
6 | import android.view.MotionEvent;
7 | import android.view.SurfaceView;
8 |
9 | class GameEngine extends SurfaceView implements Runnable, GameStarter {
10 | private Thread mThread = null;
11 | private long mFPS;
12 |
13 | private GameState mGameState;
14 | private SoundEngine mSoundEngine;
15 | HUD mHUD;
16 | Renderer mRenderer;
17 |
18 |
19 | public GameEngine(Context context, Point size) {
20 | super(context);
21 |
22 | mGameState = new GameState(this, context);
23 | mSoundEngine = new SoundEngine(context);
24 | mHUD = new HUD(size);
25 | mRenderer = new Renderer(this);
26 |
27 | }
28 |
29 | @Override
30 | public void run() {
31 | while (mGameState.getThreadRunning()) {
32 | long frameStartTime = System.currentTimeMillis();
33 |
34 | if (!mGameState.getPaused()) {
35 | // Update all the game objects here
36 | // in a new way
37 | }
38 |
39 |
40 | // Draw all the game objects here
41 | // in a new way
42 | mRenderer.draw(mGameState, mHUD);
43 |
44 | // Measure the frames per second in the usual way
45 | long timeThisFrame = System.currentTimeMillis()
46 | - frameStartTime;
47 | if (timeThisFrame >= 1) {
48 | final int MILLIS_IN_SECOND = 1000;
49 | mFPS = MILLIS_IN_SECOND / timeThisFrame;
50 | }
51 | }
52 | }
53 |
54 | @Override
55 | public boolean onTouchEvent(MotionEvent motionEvent) {
56 | // Handle the player's input here
57 | // But in a new way
58 |
59 | return true;
60 | }
61 |
62 | public void stopThread() {
63 | // New code here soon
64 | mGameState.stopEverything();
65 | try {
66 | mThread.join();
67 | } catch (InterruptedException e) {
68 | Log.e("Exception","stopThread()"
69 | + e.getMessage());
70 | }
71 | }
72 |
73 | public void startThread() {
74 | // New code here soon
75 | mGameState.startThread();
76 | mThread = new Thread(this);
77 | mThread.start();
78 | }
79 |
80 | public void deSpawnReSpawn() {
81 | // Eventually this will despawn
82 | // and then respawn all the game objects
83 | }
84 |
85 |
86 | }
87 |
--------------------------------------------------------------------------------
/Chapter 18/java/GameStarter.java:
--------------------------------------------------------------------------------
1 | package com.gamecodeschool.scrollingshooter;
2 |
3 | public interface GameStarter {
4 | // This allows the State class to
5 | // spawn and despawn objects via the game engine
6 |
7 | public void deSpawnReSpawn();
8 |
9 | }
10 |
--------------------------------------------------------------------------------
/Chapter 18/java/GameState.java:
--------------------------------------------------------------------------------
1 | package com.gamecodeschool.scrollingshooter;
2 |
3 | import android.content.Context;
4 | import android.content.SharedPreferences;
5 |
6 | final class GameState {
7 | private static volatile boolean mThreadRunning = false;
8 | private static volatile boolean mPaused = true;
9 | private static volatile boolean mGameOver = true;
10 | private static volatile boolean mDrawing = false;
11 |
12 | // This object will have access to the deSpawnReSpawn method
13 | // in GameEngine- once it is initialized
14 | private GameStarter gameStarter;
15 |
16 | private int mScore;
17 | private int mHighScore;
18 | private int mNumShips;
19 |
20 | // This is how we will make all the high scores persist
21 | private SharedPreferences.Editor mEditor;
22 |
23 | GameState(GameStarter gs, Context context){
24 | // This initializes the gameStarter reference
25 | gameStarter = gs;
26 |
27 | // Get the current high score
28 | SharedPreferences prefs;
29 | prefs = context.getSharedPreferences("HiScore",
30 | Context.MODE_PRIVATE);
31 |
32 | // Initialize the mEditor ready
33 | mEditor = prefs.edit();
34 |
35 | // Load high score from a entry in the file
36 | // labeled "hiscore"
37 | // if not available highscore set to zero 0
38 | mHighScore = prefs.getInt("hi_score", 0);
39 | }
40 |
41 | private void endGame(){
42 | mGameOver = true;
43 | mPaused = true;
44 | if(mScore > mHighScore){
45 | mHighScore = mScore;
46 | // Save high score
47 | mEditor.putInt("hi_score", mHighScore);
48 | mEditor.commit();
49 | }
50 | }
51 |
52 | void startNewGame(){
53 | mScore = 0;
54 | mNumShips = 3;
55 | // Don't want to be drawing objects
56 | // while deSpawnReSpawn is
57 | // clearing them and spawning them again
58 | stopDrawing();
59 | gameStarter.deSpawnReSpawn();
60 | resume();
61 |
62 | // Now we can draw again
63 | startDrawing();
64 | }
65 |
66 |
67 | void loseLife(SoundEngine se){
68 | mNumShips--;
69 | se.playPlayerExplode();
70 | if(mNumShips == 0){
71 | pause();
72 | endGame();
73 | }
74 | }
75 |
76 | int getNumShips(){
77 | return mNumShips;
78 | }
79 |
80 | void increaseScore(){
81 | mScore++;
82 | }
83 |
84 | int getScore(){
85 | return mScore;
86 | }
87 |
88 | int getHighScore(){
89 | return mHighScore;
90 | }
91 |
92 | void pause(){
93 | mPaused = true;
94 | }
95 |
96 | void resume(){
97 | mGameOver = false;
98 | mPaused = false;
99 | }
100 |
101 | void stopEverything(){
102 | mPaused = true;
103 | mGameOver = true;
104 | mThreadRunning = false;
105 | }
106 |
107 | boolean getThreadRunning(){
108 | return mThreadRunning;
109 | }
110 |
111 | void startThread(){
112 | mThreadRunning = true;
113 | }
114 |
115 | private void stopDrawing(){
116 | mDrawing = false;
117 | }
118 |
119 | private void startDrawing(){
120 | mDrawing = true;
121 | }
122 |
123 | boolean getDrawing() {
124 | return mDrawing;
125 | }
126 |
127 | boolean getPaused(){
128 | return mPaused;
129 | }
130 |
131 | boolean getGameOver(){
132 | return mGameOver;
133 | }
134 |
135 |
136 |
137 | }
--------------------------------------------------------------------------------
/Chapter 18/java/Renderer.java:
--------------------------------------------------------------------------------
1 | package com.gamecodeschool.scrollingshooter;
2 |
3 | import android.graphics.Canvas;
4 | import android.graphics.Color;
5 | import android.graphics.Paint;
6 | import android.view.SurfaceHolder;
7 | import android.view.SurfaceView;
8 |
9 | import java.util.ArrayList;
10 |
11 | class Renderer {
12 | private Canvas mCanvas;
13 | private SurfaceHolder mSurfaceHolder;
14 | private Paint mPaint;
15 |
16 | Renderer(SurfaceView sh){
17 | mSurfaceHolder = sh.getHolder();
18 | mPaint = new Paint();
19 | }
20 |
21 | void draw(GameState gs, HUD hud) {
22 | if (mSurfaceHolder.getSurface().isValid()) {
23 | mCanvas = mSurfaceHolder.lockCanvas();
24 | mCanvas.drawColor(Color.argb(255, 0, 0, 0));
25 |
26 | if (gs.getDrawing()) {
27 | // Draw all the game objects here
28 | }
29 |
30 | if(gs.getGameOver()) {
31 | // Draw a background graphic here
32 | }
33 |
34 | // Draw a particle system explosion here
35 |
36 | // Now we draw the HUD on top of everything else
37 | hud.draw(mCanvas, mPaint, gs);
38 |
39 | mSurfaceHolder.unlockCanvasAndPost(mCanvas);
40 | }
41 | }
42 |
43 | }
44 |
--------------------------------------------------------------------------------
/Chapter 18/java/SoundEngine.java:
--------------------------------------------------------------------------------
1 | package com.gamecodeschool.scrollingshooter;
2 |
3 | import android.content.Context;
4 | import android.content.res.AssetFileDescriptor;
5 | import android.content.res.AssetManager;
6 | import android.media.AudioAttributes;
7 | import android.media.AudioManager;
8 | import android.media.SoundPool;
9 | import android.os.Build;
10 |
11 | import java.io.IOException;
12 |
13 | class SoundEngine {
14 | // for playing sound effects
15 | private SoundPool mSP;
16 | private int mShoot_ID = -1;
17 | private int mAlien_Explode_ID = -1;
18 | private int mPlayer_explode_ID = -1;
19 |
20 | SoundEngine(Context c){
21 | // Initialize the SoundPool
22 | if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
23 | AudioAttributes audioAttributes =
24 | new AudioAttributes.Builder()
25 | .setUsage(AudioAttributes.USAGE_MEDIA)
26 | .setContentType(AudioAttributes
27 | .CONTENT_TYPE_SONIFICATION)
28 | .build();
29 |
30 | mSP = new SoundPool.Builder()
31 | .setMaxStreams(5)
32 | .setAudioAttributes(audioAttributes)
33 | .build();
34 | } else {
35 | mSP = new SoundPool(5, AudioManager.STREAM_MUSIC, 0);
36 | }
37 | try {
38 | AssetManager assetManager = c.getAssets();
39 | AssetFileDescriptor descriptor;
40 |
41 | // Prepare the sounds in memory
42 | descriptor = assetManager.openFd("shoot.ogg");
43 | mShoot_ID = mSP.load(descriptor, 0);
44 |
45 | descriptor = assetManager.openFd("alien_explosion.ogg");
46 | mAlien_Explode_ID = mSP.load(descriptor, 0);
47 |
48 | descriptor =
49 | assetManager.openFd("player_explosion.ogg");
50 |
51 | mPlayer_explode_ID = mSP.load(descriptor, 0);
52 |
53 | } catch (IOException e) {
54 | // Error
55 | }
56 |
57 | }
58 |
59 | void playShoot(){
60 | mSP.play(mShoot_ID,1, 1, 0, 0, 1);
61 | }
62 |
63 | void playAlienExplode(){
64 | mSP.play(mAlien_Explode_ID,1, 1, 0, 0, 1);
65 | }
66 |
67 | void playPlayerExplode(){
68 | mSP.play(mPlayer_explode_ID,1, 1, 0, 0, 1);
69 | }
70 |
71 |
72 | }
73 |
--------------------------------------------------------------------------------
/Chapter 19/AndroidManifest.xml:
--------------------------------------------------------------------------------
1 |
2 |
4 |
5 |
12 |
15 | >
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
--------------------------------------------------------------------------------
/Chapter 19/assets/alien_explosion.ogg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/PacktPublishing/Learning-Java-by-Building-Android-Games-Third-Edition/9e56a97be80dcca7c697937a046b4a43b250e29f/Chapter 19/assets/alien_explosion.ogg
--------------------------------------------------------------------------------
/Chapter 19/assets/player_explosion.ogg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/PacktPublishing/Learning-Java-by-Building-Android-Games-Third-Edition/9e56a97be80dcca7c697937a046b4a43b250e29f/Chapter 19/assets/player_explosion.ogg
--------------------------------------------------------------------------------
/Chapter 19/assets/shoot.ogg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/PacktPublishing/Learning-Java-by-Building-Android-Games-Third-Edition/9e56a97be80dcca7c697937a046b4a43b250e29f/Chapter 19/assets/shoot.ogg
--------------------------------------------------------------------------------
/Chapter 19/java/GameActivity.java:
--------------------------------------------------------------------------------
1 | package com.gamecodeschool.scrollingshooter;
2 |
3 | import android.app.Activity;
4 | import android.graphics.Point;
5 | import android.os.Bundle;
6 | import android.view.Display;
7 | import android.view.Window;
8 |
9 | public class GameActivity extends Activity {
10 |
11 | GameEngine mGameEngine;
12 |
13 | @Override
14 | protected void onCreate(Bundle savedInstanceState) {
15 | super.onCreate(savedInstanceState);
16 | requestWindowFeature(Window.FEATURE_NO_TITLE);
17 |
18 | Display display = getWindowManager()
19 | .getDefaultDisplay();
20 |
21 | Point size = new Point();
22 | display.getSize(size);
23 | mGameEngine = new GameEngine(this, size);
24 | setContentView(mGameEngine);
25 | }
26 |
27 | @Override
28 | protected void onResume() {
29 | super.onResume();
30 | mGameEngine.startThread();
31 | }
32 |
33 | @Override
34 | protected void onPause() {
35 | super.onPause();
36 | mGameEngine.stopThread();
37 | }
38 | }
39 |
--------------------------------------------------------------------------------
/Chapter 19/java/GameEngineBroadcaster.java:
--------------------------------------------------------------------------------
1 | package com.gamecodeschool.scrollingshooter;
2 |
3 | public interface GameEngineBroadcaster {
4 | void addObserver(InputObserver o);
5 | }
6 |
--------------------------------------------------------------------------------
/Chapter 19/java/GameStarter.java:
--------------------------------------------------------------------------------
1 | package com.gamecodeschool.scrollingshooter;
2 |
3 | public interface GameStarter {
4 | // This allows the State class to
5 | // spawn and despawn objects via the game engine
6 |
7 | public void deSpawnReSpawn();
8 |
9 | }
10 |
--------------------------------------------------------------------------------
/Chapter 19/java/GameState.java:
--------------------------------------------------------------------------------
1 | package com.gamecodeschool.scrollingshooter;
2 |
3 | import android.content.Context;
4 | import android.content.SharedPreferences;
5 |
6 | final class GameState {
7 | private static volatile boolean mThreadRunning = false;
8 | private static volatile boolean mPaused = true;
9 | private static volatile boolean mGameOver = true;
10 | private static volatile boolean mDrawing = false;
11 |
12 | // This object will have access to the deSpawnReSpawn method
13 | // in GameEngine- once it is initialized
14 | private GameStarter gameStarter;
15 |
16 | private int mScore;
17 | private int mHighScore;
18 | private int mNumShips;
19 |
20 | // This is how we will make all the high scores persist
21 | private SharedPreferences.Editor mEditor;
22 |
23 | GameState(GameStarter gs, Context context){
24 | // This initializes the gameStarter reference
25 | gameStarter = gs;
26 |
27 | // Get the current high score
28 | SharedPreferences prefs;
29 | prefs = context.getSharedPreferences("HiScore",
30 | Context.MODE_PRIVATE);
31 |
32 | // Initialize the mEditor ready
33 | mEditor = prefs.edit();
34 |
35 | // Load high score from a entry in the file
36 | // labeled "hiscore"
37 | // if not available highscore set to zero 0
38 | mHighScore = prefs.getInt("hi_score", 0);
39 | }
40 |
41 | private void endGame(){
42 | mGameOver = true;
43 | mPaused = true;
44 | if(mScore > mHighScore){
45 | mHighScore = mScore;
46 | // Save high score
47 | mEditor.putInt("hi_score", mHighScore);
48 | mEditor.commit();
49 | }
50 | }
51 |
52 | void startNewGame(){
53 | mScore = 0;
54 | mNumShips = 3;
55 | // Don't want to be drawing objects
56 | // while deSpawnReSpawn is
57 | // clearing them and spawning them again
58 | stopDrawing();
59 | gameStarter.deSpawnReSpawn();
60 | resume();
61 |
62 | // Now we can draw again
63 | startDrawing();
64 | }
65 |
66 |
67 | void loseLife(SoundEngine se){
68 | mNumShips--;
69 | se.playPlayerExplode();
70 | if(mNumShips == 0){
71 | pause();
72 | endGame();
73 | }
74 | }
75 |
76 | int getNumShips(){
77 | return mNumShips;
78 | }
79 |
80 | void increaseScore(){
81 | mScore++;
82 | }
83 |
84 | int getScore(){
85 | return mScore;
86 | }
87 |
88 | int getHighScore(){
89 | return mHighScore;
90 | }
91 |
92 | void pause(){
93 | mPaused = true;
94 | }
95 |
96 | void resume(){
97 | mGameOver = false;
98 | mPaused = false;
99 | }
100 |
101 | void stopEverything(){
102 | mPaused = true;
103 | mGameOver = true;
104 | mThreadRunning = false;
105 | }
106 |
107 | boolean getThreadRunning(){
108 | return mThreadRunning;
109 | }
110 |
111 | void startThread(){
112 | mThreadRunning = true;
113 | }
114 |
115 | private void stopDrawing(){
116 | mDrawing = false;
117 | }
118 |
119 | private void startDrawing(){
120 | mDrawing = true;
121 | }
122 |
123 | boolean getDrawing() {
124 | return mDrawing;
125 | }
126 |
127 | boolean getPaused(){
128 | return mPaused;
129 | }
130 |
131 | boolean getGameOver(){
132 | return mGameOver;
133 | }
134 |
135 |
136 |
137 | }
--------------------------------------------------------------------------------
/Chapter 19/java/InputObserver.java:
--------------------------------------------------------------------------------
1 | package com.gamecodeschool.scrollingshooter;
2 |
3 | import android.graphics.Rect;
4 | import android.view.MotionEvent;
5 | import java.util.ArrayList;
6 |
7 | interface InputObserver {
8 |
9 | void handleInput(MotionEvent event, GameState gs,
10 | ArrayList controls);
11 | }
12 |
--------------------------------------------------------------------------------
/Chapter 19/java/Particle.java:
--------------------------------------------------------------------------------
1 | package com.gamecodeschool.scrollingshooter;
2 |
3 | import android.graphics.PointF;
4 |
5 | class Particle {
6 |
7 | PointF mVelocity;
8 | PointF mPosition;
9 |
10 | Particle(PointF direction)
11 | {
12 | mVelocity = new PointF();
13 | mPosition = new PointF();
14 |
15 | // Determine the direction
16 | mVelocity.x = direction.x;
17 | mVelocity.y = direction.y;
18 |
19 | }
20 |
21 | void update()
22 | {
23 | // Move the particle
24 | mPosition.x += mVelocity.x;
25 | mPosition.y += mVelocity.y;
26 | }
27 |
28 | void setPosition(PointF position)
29 | {
30 | mPosition.x = position.x;
31 | mPosition.y = position.y;
32 | }
33 |
34 | PointF getPosition()
35 | {
36 | return mPosition;
37 | }
38 |
39 | }
40 |
41 |
--------------------------------------------------------------------------------
/Chapter 19/java/ParticleSystem.java:
--------------------------------------------------------------------------------
1 | package com.gamecodeschool.scrollingshooter;
2 |
3 | import android.graphics.Canvas;
4 | import android.graphics.Paint;
5 | import android.graphics.PointF;
6 |
7 | import java.util.ArrayList;
8 | import java.util.Random;
9 |
10 | class ParticleSystem {
11 |
12 | float mDuration;
13 |
14 | ArrayList mParticles;
15 | Random random = new Random();
16 | boolean mIsRunning = false;
17 |
18 | void init(int numParticles){
19 |
20 | mParticles = new ArrayList<>();
21 | // Create the particles
22 |
23 | for (int i = 0; i < numParticles; i++) {
24 | float angle = (random.nextInt(360)) ;
25 | angle = angle * 3.14f / 180.f;
26 | float speed = (random.nextInt(20)+1);
27 |
28 | PointF direction;
29 |
30 | direction = new PointF((float)Math.cos(angle) * speed,
31 | (float)Math.sin(angle) * speed);
32 |
33 | mParticles.add(new Particle(direction));
34 | }
35 | }
36 | void update(long fps){
37 |
38 | mDuration -= (1f/fps);
39 |
40 | for(Particle p : mParticles){
41 | p.update();
42 | }
43 |
44 | if (mDuration < 0)
45 | {
46 | mIsRunning = false;
47 | }
48 | }
49 |
50 | void emitParticles(PointF startPosition){
51 |
52 | mIsRunning = true;
53 | mDuration = 1f;
54 |
55 | for(Particle p : mParticles){
56 | p.setPosition(startPosition);
57 | }
58 | }
59 |
60 | void draw(Canvas canvas, Paint paint){
61 |
62 | for (Particle p : mParticles) {
63 |
64 | paint.setARGB(255,
65 | random.nextInt(256),
66 | random.nextInt(256),
67 | random.nextInt(256));
68 |
69 | // Uncomment the next line to have plain white particles
70 | //paint.setColor(Color.argb(255,255,255,255));
71 | canvas.drawRect(p.getPosition().x,
72 | p.getPosition().y,
73 | p.getPosition().x+25,
74 | p.getPosition().y+25, paint);
75 | }
76 | }
77 | }
78 |
79 |
--------------------------------------------------------------------------------
/Chapter 19/java/PhysicsEngine.java:
--------------------------------------------------------------------------------
1 | package com.gamecodeschool.scrollingshooter;
2 |
3 | class PhysicsEngine {
4 |
5 | // This signature and much more will
6 | //change later in the project
7 | boolean update(long fps, ParticleSystem ps){
8 |
9 | if(ps.mIsRunning){
10 | ps.update(fps);
11 | }
12 |
13 | return false;
14 | }
15 |
16 | // Collision detection method will go here
17 |
18 | }
19 |
20 |
--------------------------------------------------------------------------------
/Chapter 19/java/Renderer.java:
--------------------------------------------------------------------------------
1 | package com.gamecodeschool.scrollingshooter;
2 |
3 | import android.graphics.Canvas;
4 | import android.graphics.Color;
5 | import android.graphics.Paint;
6 | import android.view.SurfaceHolder;
7 | import android.view.SurfaceView;
8 |
9 | import java.util.ArrayList;
10 |
11 | class Renderer {
12 | private Canvas mCanvas;
13 | private SurfaceHolder mSurfaceHolder;
14 | private Paint mPaint;
15 |
16 | Renderer(SurfaceView sh){
17 | mSurfaceHolder = sh.getHolder();
18 | mPaint = new Paint();
19 | }
20 |
21 | void draw(GameState gs, HUD hud, ParticleSystem ps) {
22 | if (mSurfaceHolder.getSurface().isValid()) {
23 | mCanvas = mSurfaceHolder.lockCanvas();
24 | mCanvas.drawColor(Color.argb(255, 0, 0, 0));
25 |
26 | if (gs.getDrawing()) {
27 | // Draw all the game objects here
28 | }
29 |
30 | if(gs.getGameOver()) {
31 | // Draw a background graphic here
32 | }
33 |
34 | // Draw a particle system explosion here
35 | if(ps.mIsRunning){
36 | ps.draw(mCanvas, mPaint);
37 | }
38 |
39 |
40 | // Now we draw the HUD on top of everything else
41 | hud.draw(mCanvas, mPaint, gs);
42 |
43 | mSurfaceHolder.unlockCanvasAndPost(mCanvas);
44 | }
45 | }
46 |
47 | }
48 |
--------------------------------------------------------------------------------
/Chapter 19/java/SoundEngine.java:
--------------------------------------------------------------------------------
1 | package com.gamecodeschool.scrollingshooter;
2 |
3 | import android.content.Context;
4 | import android.content.res.AssetFileDescriptor;
5 | import android.content.res.AssetManager;
6 | import android.media.AudioAttributes;
7 | import android.media.AudioManager;
8 | import android.media.SoundPool;
9 | import android.os.Build;
10 |
11 | import java.io.IOException;
12 |
13 | class SoundEngine {
14 | // for playing sound effects
15 | private SoundPool mSP;
16 | private int mShoot_ID = -1;
17 | private int mAlien_Explode_ID = -1;
18 | private int mPlayer_explode_ID = -1;
19 |
20 | SoundEngine(Context c){
21 | // Initialize the SoundPool
22 | if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
23 | AudioAttributes audioAttributes =
24 | new AudioAttributes.Builder()
25 | .setUsage(AudioAttributes.USAGE_MEDIA)
26 | .setContentType(AudioAttributes
27 | .CONTENT_TYPE_SONIFICATION)
28 | .build();
29 |
30 | mSP = new SoundPool.Builder()
31 | .setMaxStreams(5)
32 | .setAudioAttributes(audioAttributes)
33 | .build();
34 | } else {
35 | mSP = new SoundPool(5, AudioManager.STREAM_MUSIC, 0);
36 | }
37 | try {
38 | AssetManager assetManager = c.getAssets();
39 | AssetFileDescriptor descriptor;
40 |
41 | // Prepare the sounds in memory
42 | descriptor = assetManager.openFd("shoot.ogg");
43 | mShoot_ID = mSP.load(descriptor, 0);
44 |
45 | descriptor = assetManager.openFd("alien_explosion.ogg");
46 | mAlien_Explode_ID = mSP.load(descriptor, 0);
47 |
48 | descriptor =
49 | assetManager.openFd("player_explosion.ogg");
50 |
51 | mPlayer_explode_ID = mSP.load(descriptor, 0);
52 |
53 | } catch (IOException e) {
54 | // Error
55 | }
56 |
57 | }
58 |
59 | void playShoot(){
60 | mSP.play(mShoot_ID,1, 1, 0, 0, 1);
61 | }
62 |
63 | void playAlienExplode(){
64 | mSP.play(mAlien_Explode_ID,1, 1, 0, 0, 1);
65 | }
66 |
67 | void playPlayerExplode(){
68 | mSP.play(mPlayer_explode_ID,1, 1, 0, 0, 1);
69 | }
70 |
71 |
72 | }
73 |
--------------------------------------------------------------------------------
/Chapter 19/java/UIController.java:
--------------------------------------------------------------------------------
1 | package com.gamecodeschool.scrollingshooter;
2 | import android.graphics.Point;
3 | import android.graphics.Rect;
4 | import android.view.MotionEvent;
5 |
6 | import java.util.ArrayList;
7 |
8 | class UIController implements InputObserver {
9 |
10 | public UIController(GameEngineBroadcaster b){
11 | b.addObserver(this);
12 | }
13 |
14 | @Override
15 | public void handleInput(MotionEvent event, GameState gameState, ArrayList buttons) {
16 |
17 | int i = event.getActionIndex();
18 | int x = (int) event.getX(i);
19 | int y = (int) event.getY(i);
20 |
21 | int eventType = event.getAction() & MotionEvent.ACTION_MASK;
22 |
23 | if(eventType == MotionEvent.ACTION_UP ||
24 | eventType == MotionEvent.ACTION_POINTER_UP) {
25 |
26 |
27 | if (buttons.get(HUD.PAUSE).contains(x, y)){
28 | // Player pressed the pause button
29 | // Respond differently depending
30 | // upon the game's state
31 |
32 | // If the game is not paused
33 | if (!gameState.getPaused()) {
34 | // Pause the game
35 | gameState.pause();
36 | }
37 |
38 | // If game is over start a new game
39 | else if (gameState.getGameOver()) {
40 |
41 | gameState.startNewGame();
42 | }
43 |
44 | // Paused and not game over
45 | else if (gameState.getPaused()
46 | && !gameState.getGameOver()) {
47 |
48 | gameState.resume();
49 | }
50 | }
51 | }
52 | }
53 |
54 | }
55 |
--------------------------------------------------------------------------------
/Chapter 20/assets/alien_explosion.ogg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/PacktPublishing/Learning-Java-by-Building-Android-Games-Third-Edition/9e56a97be80dcca7c697937a046b4a43b250e29f/Chapter 20/assets/alien_explosion.ogg
--------------------------------------------------------------------------------
/Chapter 20/assets/player_explosion.ogg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/PacktPublishing/Learning-Java-by-Building-Android-Games-Third-Edition/9e56a97be80dcca7c697937a046b4a43b250e29f/Chapter 20/assets/player_explosion.ogg
--------------------------------------------------------------------------------
/Chapter 20/assets/shoot.ogg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/PacktPublishing/Learning-Java-by-Building-Android-Games-Third-Edition/9e56a97be80dcca7c697937a046b4a43b250e29f/Chapter 20/assets/shoot.ogg
--------------------------------------------------------------------------------
/Chapter 20/drawable/alien_laser.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/PacktPublishing/Learning-Java-by-Building-Android-Games-Third-Edition/9e56a97be80dcca7c697937a046b4a43b250e29f/Chapter 20/drawable/alien_laser.png
--------------------------------------------------------------------------------
/Chapter 20/drawable/alien_ship1.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/PacktPublishing/Learning-Java-by-Building-Android-Games-Third-Edition/9e56a97be80dcca7c697937a046b4a43b250e29f/Chapter 20/drawable/alien_ship1.png
--------------------------------------------------------------------------------
/Chapter 20/drawable/alien_ship2.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/PacktPublishing/Learning-Java-by-Building-Android-Games-Third-Edition/9e56a97be80dcca7c697937a046b4a43b250e29f/Chapter 20/drawable/alien_ship2.png
--------------------------------------------------------------------------------
/Chapter 20/drawable/alien_ship3.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/PacktPublishing/Learning-Java-by-Building-Android-Games-Third-Edition/9e56a97be80dcca7c697937a046b4a43b250e29f/Chapter 20/drawable/alien_ship3.png
--------------------------------------------------------------------------------
/Chapter 20/drawable/background.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/PacktPublishing/Learning-Java-by-Building-Android-Games-Third-Edition/9e56a97be80dcca7c697937a046b4a43b250e29f/Chapter 20/drawable/background.png
--------------------------------------------------------------------------------
/Chapter 20/drawable/player_laser.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/PacktPublishing/Learning-Java-by-Building-Android-Games-Third-Edition/9e56a97be80dcca7c697937a046b4a43b250e29f/Chapter 20/drawable/player_laser.png
--------------------------------------------------------------------------------
/Chapter 20/drawable/player_ship.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/PacktPublishing/Learning-Java-by-Building-Android-Games-Third-Edition/9e56a97be80dcca7c697937a046b4a43b250e29f/Chapter 20/drawable/player_ship.png
--------------------------------------------------------------------------------
/Chapter 20/java/AlienChaseSpec.java:
--------------------------------------------------------------------------------
1 | package com.gamecodeschool.scrollingshooter;
2 |
3 | import android.graphics.PointF;
4 |
5 | class AlienChaseSpec extends ObjectSpec {
6 | // This is all the unique specifications
7 | // for an alien that chases the player
8 | private static final String tag = "Alien";
9 | private static final String bitmapName = "alien_ship1";
10 | private static final float speed = 4f;
11 | private static final PointF relativeScale =
12 | new PointF(15f, 15f);
13 |
14 | private static final String[] components = new String [] {
15 | "StdGraphicsComponent",
16 | "AlienChaseMovementComponent",
17 | "AlienHorizontalSpawnComponent"};
18 |
19 | AlienChaseSpec(){
20 | super(tag, bitmapName,
21 | speed, relativeScale,
22 | components);
23 | }
24 | }
25 |
--------------------------------------------------------------------------------
/Chapter 20/java/AlienDiverSpec.java:
--------------------------------------------------------------------------------
1 | package com.gamecodeschool.scrollingshooter;
2 |
3 | import android.graphics.PointF;
4 |
5 | class AlienDiverSpec extends ObjectSpec {
6 | // This is all the unique specifications
7 | // for an alien that dives
8 | private static final String tag = "Alien";
9 | private static final String bitmapName = "alien_ship3";
10 | private static final float speed = 4f;
11 | private static final PointF relativeScale =
12 | new PointF(60f, 30f);
13 |
14 | private static final String[] components = new String [] {
15 | "StdGraphicsComponent",
16 | "AlienDiverMovementComponent",
17 | "AlienVerticalSpawnComponent"};
18 |
19 | AlienDiverSpec(){
20 | super(tag, bitmapName,
21 | speed, relativeScale,
22 | components);
23 | }
24 | }
25 |
--------------------------------------------------------------------------------
/Chapter 20/java/AlienLaserSpec.java:
--------------------------------------------------------------------------------
1 | package com.gamecodeschool.scrollingshooter;
2 |
3 | import android.graphics.PointF;
4 |
5 | class AlienLaserSpec extends ObjectSpec {
6 | // This is all the unique specifications
7 | // for an alien laser
8 | private static final String tag = "Alien Laser";
9 | private static final String bitmapName = "alien_laser";
10 | private static final float speed = .75f;
11 | private static final PointF relativeScale =
12 | new PointF(14f, 160f);
13 |
14 | private static final String[] components = new String [] {
15 | "StdGraphicsComponent",
16 | "LaserMovementComponent",
17 | "LaserSpawnComponent"};
18 |
19 | AlienLaserSpec(){
20 | super(tag, bitmapName,
21 | speed, relativeScale,
22 | components);
23 | }
24 | }
25 |
26 |
--------------------------------------------------------------------------------
/Chapter 20/java/AlienPatrolSpec.java:
--------------------------------------------------------------------------------
1 | package com.gamecodeschool.scrollingshooter;
2 |
3 | import android.graphics.PointF;
4 |
5 | class AlienPatrolSpec extends ObjectSpec {
6 | // This is all the unique specifications
7 | // for a patrolling alien
8 | private static final String tag = "Alien";
9 | private static final String bitmapName = "alien_ship2";
10 | private static final float speed = 5f;
11 | private static final PointF relativeScale =
12 | new PointF(15f, 15f);
13 |
14 | private static final String[] components = new String [] {
15 | "StdGraphicsComponent",
16 | "AlienPatrolMovementComponent",
17 | "AlienHorizontalSpawnComponent"};
18 |
19 | AlienPatrolSpec(){
20 | super(tag, bitmapName,
21 | speed, relativeScale,
22 | components);
23 | }
24 | }
25 |
26 |
--------------------------------------------------------------------------------
/Chapter 20/java/BackgroundGraphicsComponent.java:
--------------------------------------------------------------------------------
1 | package com.gamecodeschool.scrollingshooter;
2 |
3 | import android.content.Context;
4 | import android.graphics.Bitmap;
5 | import android.graphics.BitmapFactory;
6 | import android.graphics.Canvas;
7 | import android.graphics.Matrix;
8 | import android.graphics.Paint;
9 | import android.graphics.PointF;
10 | import android.graphics.Rect;
11 |
12 | class BackgroundGraphicsComponent implements GraphicsComponent {
13 |
14 | private Bitmap mBitmap;
15 | private Bitmap mBitmapReversed;
16 |
17 | @Override
18 | public void initialize(Context c,
19 | ObjectSpec s,
20 | PointF objectSize) {
21 |
22 | // Make a resource id out of the string of the file name
23 | int resID = c.getResources()
24 | .getIdentifier(s.getBitmapName(),
25 | "drawable", c.getPackageName());
26 |
27 | // Load the bitmap using the id
28 | mBitmap = BitmapFactory
29 | .decodeResource(c.getResources(), resID);
30 |
31 | // Resize the bitmap
32 | mBitmap = Bitmap
33 | .createScaledBitmap(mBitmap,
34 | (int)objectSize.x,
35 | (int)objectSize.y,
36 | false);
37 |
38 | // Create a mirror image of the bitmap
39 | Matrix matrix = new Matrix();
40 | matrix.setScale(-1, 1);
41 | mBitmapReversed = Bitmap
42 | .createBitmap(mBitmap,
43 | 0, 0,
44 | mBitmap.getWidth(),
45 | mBitmap.getHeight(),
46 | matrix, true);
47 |
48 |
49 | }
50 |
51 | @Override
52 | public void draw(Canvas canvas,
53 | Paint paint,
54 | Transform t) {
55 |
56 | int xClip = t.getXClip();
57 | int width = mBitmap.getWidth();
58 | int height = mBitmap.getHeight();
59 | int startY = 0;
60 | int endY = (int)t.getmScreenSize().y +20;
61 |
62 | // For the regular bitmap
63 | Rect fromRect1 = new Rect(0, 0, width - xClip, height);
64 | Rect toRect1 = new Rect(xClip, startY, width, endY);
65 |
66 | // For the reversed background
67 | Rect fromRect2 = new Rect(width - xClip, 0, width, height);
68 | Rect toRect2 = new Rect(0, startY, xClip, endY);
69 |
70 | //draw the two background bitmaps
71 | if (!t.getReversedFirst()) {
72 | canvas.drawBitmap(mBitmap,
73 | fromRect1, toRect1, paint);
74 |
75 | canvas.drawBitmap(mBitmapReversed,
76 | fromRect2, toRect2, paint);
77 |
78 | } else {
79 | canvas.drawBitmap(mBitmap, fromRect2,
80 | toRect2, paint);
81 |
82 | canvas.drawBitmap(mBitmapReversed,
83 | fromRect1, toRect1, paint);
84 | }
85 |
86 |
87 | }
88 | }
89 |
90 |
--------------------------------------------------------------------------------
/Chapter 20/java/BackgroundMovementComponent.java:
--------------------------------------------------------------------------------
1 | package com.gamecodeschool.scrollingshooter;
2 |
3 | class BackgroundMovementComponent implements MovementComponent {
4 | @Override
5 | public boolean move(long fps,
6 | Transform t,
7 | Transform playerTransform) {
8 |
9 | int currentXClip = t.getXClip();
10 |
11 | if(playerTransform.getFacingRight()) {
12 | currentXClip -= t.getSpeed() / fps;
13 | t.setXClip(currentXClip);
14 | }
15 | else {
16 | currentXClip += t.getSpeed() / fps;
17 | t.setXClip(currentXClip);
18 | }
19 |
20 | if (currentXClip >= t.getSize().x) {
21 | t.setXClip(0);
22 | t.flipReversedFirst();
23 | }
24 | else if (currentXClip <= 0) {
25 | t.setXClip((int)t.getSize().x);
26 | t.flipReversedFirst();
27 | }
28 |
29 |
30 | return true;
31 | }
32 | }
33 |
--------------------------------------------------------------------------------
/Chapter 20/java/BackgroundSpawnComponent.java:
--------------------------------------------------------------------------------
1 | package com.gamecodeschool.scrollingshooter;
2 |
3 | class BackgroundSpawnComponent implements SpawnComponent {
4 | @Override
5 | public void spawn(Transform playerLTransform, Transform t) {
6 | // Place the background in the top left corner
7 | t.setLocation(0f,0f);
8 |
9 |
10 | }
11 | }
12 |
13 |
--------------------------------------------------------------------------------
/Chapter 20/java/BackgroundSpec.java:
--------------------------------------------------------------------------------
1 | package com.gamecodeschool.scrollingshooter;
2 |
3 | import android.graphics.PointF;
4 |
5 | class BackgroundSpec extends ObjectSpec {
6 | // This is all the unique specifications
7 | // for the background
8 | private static final String tag = "Background";
9 | private static final String bitmapName = "background";
10 | private static final float speed = 2f;
11 | private static final PointF relativeScale =
12 | new PointF(1f, 1f);
13 |
14 | private static final String[] components = new String [] {
15 | "BackgroundGraphicsComponent",
16 | "BackgroundMovementComponent",
17 | "BackgroundSpawnComponent"};
18 |
19 | BackgroundSpec() {
20 | super(tag, bitmapName,
21 | speed, relativeScale,
22 | components);
23 | }
24 | }
25 |
--------------------------------------------------------------------------------
/Chapter 20/java/GameActivity.java:
--------------------------------------------------------------------------------
1 | package com.gamecodeschool.scrollingshooter;
2 |
3 | import android.app.Activity;
4 | import android.graphics.Point;
5 | import android.os.Bundle;
6 | import android.view.Display;
7 | import android.view.Window;
8 |
9 | public class GameActivity extends Activity {
10 |
11 | GameEngine mGameEngine;
12 |
13 | @Override
14 | protected void onCreate(Bundle savedInstanceState) {
15 | super.onCreate(savedInstanceState);
16 | requestWindowFeature(Window.FEATURE_NO_TITLE);
17 |
18 | Display display = getWindowManager()
19 | .getDefaultDisplay();
20 |
21 | Point size = new Point();
22 | display.getSize(size);
23 | mGameEngine = new GameEngine(this, size);
24 | setContentView(mGameEngine);
25 | }
26 |
27 | @Override
28 | protected void onResume() {
29 | super.onResume();
30 | mGameEngine.startThread();
31 | }
32 |
33 | @Override
34 | protected void onPause() {
35 | super.onPause();
36 | mGameEngine.stopThread();
37 | }
38 | }
39 |
--------------------------------------------------------------------------------
/Chapter 20/java/GameEngineBroadcaster.java:
--------------------------------------------------------------------------------
1 | package com.gamecodeschool.scrollingshooter;
2 |
3 | public interface GameEngineBroadcaster {
4 | void addObserver(InputObserver o);
5 | }
6 |
--------------------------------------------------------------------------------
/Chapter 20/java/GameObject.java:
--------------------------------------------------------------------------------
1 | package com.gamecodeschool.scrollingshooter;
2 |
3 | import android.content.Context;
4 | import android.graphics.Canvas;
5 | import android.graphics.Paint;
6 | import android.graphics.PointF;
7 |
8 | class GameObject {
9 |
10 | private Transform mTransform;
11 | private boolean isActive = false;
12 | private String mTag;
13 |
14 | private GraphicsComponent graphicsComponent;
15 | private MovementComponent movementComponent;
16 | private SpawnComponent spawnComponent;
17 |
18 | void setSpawner(SpawnComponent s) {
19 | spawnComponent = s;
20 | }
21 |
22 | void setGraphics(GraphicsComponent g, Context c,
23 | ObjectSpec spec, PointF objectSize) {
24 |
25 | graphicsComponent = g;
26 | g.initialize(c, spec, objectSize);
27 | }
28 |
29 | void setMovement(MovementComponent m) {
30 | movementComponent = m;
31 | }
32 |
33 | void setInput(InputComponent s) {
34 | s.setTransform(mTransform);
35 | }
36 |
37 | void setmTag(String tag) {
38 | mTag = tag;
39 | }
40 |
41 | void setTransform(Transform t) {
42 | mTransform = t;
43 | }
44 |
45 | void draw(Canvas canvas, Paint paint) {
46 | graphicsComponent.draw(canvas, paint, mTransform);
47 | }
48 |
49 | void update(long fps, Transform playerTransform) {
50 | if (!(movementComponent.move(fps,
51 | mTransform, playerTransform))) {
52 | // Component returned false
53 | isActive = false;
54 | }
55 | }
56 |
57 | boolean spawn(Transform playerTransform) {
58 | // Only spawnComponent if not already active
59 | if (!isActive) {
60 | spawnComponent.spawn(playerTransform, mTransform);
61 | isActive = true;
62 | return true;
63 | }
64 | return false;
65 | }
66 |
67 | boolean checkActive() {
68 | return isActive;
69 | }
70 |
71 | String getTag() {
72 | return mTag;
73 | }
74 |
75 | void setInactive() {
76 | isActive = false;
77 | }
78 |
79 | Transform getTransform() {
80 | return mTransform;
81 | }
82 |
83 |
84 |
85 | }
86 |
87 |
--------------------------------------------------------------------------------
/Chapter 20/java/GameObjectFactory.java:
--------------------------------------------------------------------------------
1 | package com.gamecodeschool.scrollingshooter;
2 |
3 | import android.content.Context;
4 | import android.graphics.PointF;
5 |
6 | class GameObjectFactory {
7 | private Context mContext;
8 | private PointF mScreenSize;
9 | private GameEngine mGameEngineReference;
10 |
11 | GameObjectFactory(Context c, PointF screenSize,
12 | GameEngine gameEngine) {
13 |
14 | this.mContext = c;
15 | this.mScreenSize = screenSize;
16 | mGameEngineReference = gameEngine;
17 | }
18 |
19 | GameObject create(ObjectSpec spec) {
20 |
21 | GameObject object = new GameObject();
22 |
23 | int numComponents = spec.getComponents().length;
24 |
25 | final float HIDDEN = -2000f;
26 |
27 | object.setmTag(spec.getTag());
28 |
29 | // Configure the speed relative to the screen size
30 | float speed = mScreenSize.x / spec.getSpeed();
31 |
32 | // Configure the object size relative to screen size
33 | PointF objectSize =
34 | new PointF(mScreenSize.x / spec.getScale().x,
35 | mScreenSize.y / spec.getScale().y);
36 |
37 | // Set the location to somewhere off-screen
38 | PointF location = new PointF(HIDDEN, HIDDEN);
39 |
40 | object.setTransform(new Transform(speed, objectSize.x,
41 | objectSize.y, location, mScreenSize));
42 |
43 | // More code here next...
44 | // Loop through and add/initialize all the components
45 | for (int i = 0; i < numComponents; i++) {
46 | switch (spec.getComponents()[i]) {
47 | case "PlayerInputComponent":
48 | object.setInput(new PlayerInputComponent
49 | (mGameEngineReference));
50 | break;
51 | case "StdGraphicsComponent":
52 | object.setGraphics(new StdGraphicsComponent(),
53 | mContext, spec, objectSize);
54 | break;
55 | case "PlayerMovementComponent":
56 | object.setMovement(new PlayerMovementComponent());
57 | break;
58 | case "LaserMovementComponent":
59 | object.setMovement(new LaserMovementComponent());
60 | break;
61 | case "PlayerSpawnComponent":
62 | object.setSpawner(new PlayerSpawnComponent());
63 | break;
64 | case "LaserSpawnComponent":
65 | object.setSpawner(new LaserSpawnComponent());
66 | break;
67 | case "BackgroundGraphicsComponent":
68 | object.setGraphics(new BackgroundGraphicsComponent(),
69 | mContext, spec, objectSize);
70 | break;
71 | case "BackgroundMovementComponent":
72 | object.setMovement(new BackgroundMovementComponent());
73 | break;
74 | case "BackgroundSpawnComponent":
75 | object.setSpawner(new BackgroundSpawnComponent());
76 | break;
77 |
78 | default:
79 | // Error unidentified component
80 | break;
81 | }
82 | }
83 | // Return the completed GameObject to the Level class
84 | return object;
85 |
86 | }
87 |
88 | }
89 |
90 |
--------------------------------------------------------------------------------
/Chapter 20/java/GameStarter.java:
--------------------------------------------------------------------------------
1 | package com.gamecodeschool.scrollingshooter;
2 |
3 | public interface GameStarter {
4 | // This allows the State class to
5 | // spawn and despawn objects via the game engine
6 |
7 | public void deSpawnReSpawn();
8 |
9 | }
10 |
--------------------------------------------------------------------------------
/Chapter 20/java/GameState.java:
--------------------------------------------------------------------------------
1 | package com.gamecodeschool.scrollingshooter;
2 |
3 | import android.content.Context;
4 | import android.content.SharedPreferences;
5 |
6 | final class GameState {
7 | private static volatile boolean mThreadRunning = false;
8 | private static volatile boolean mPaused = true;
9 | private static volatile boolean mGameOver = true;
10 | private static volatile boolean mDrawing = false;
11 |
12 | // This object will have access to the deSpawnReSpawn method
13 | // in GameEngine- once it is initialized
14 | private GameStarter gameStarter;
15 |
16 | private int mScore;
17 | private int mHighScore;
18 | private int mNumShips;
19 |
20 | // This is how we will make all the high scores persist
21 | private SharedPreferences.Editor mEditor;
22 |
23 | GameState(GameStarter gs, Context context){
24 | // This initializes the gameStarter reference
25 | gameStarter = gs;
26 |
27 | // Get the current high score
28 | SharedPreferences prefs;
29 | prefs = context.getSharedPreferences("HiScore",
30 | Context.MODE_PRIVATE);
31 |
32 | // Initialize the mEditor ready
33 | mEditor = prefs.edit();
34 |
35 | // Load high score from a entry in the file
36 | // labeled "hiscore"
37 | // if not available highscore set to zero 0
38 | mHighScore = prefs.getInt("hi_score", 0);
39 | }
40 |
41 | private void endGame(){
42 | mGameOver = true;
43 | mPaused = true;
44 | if(mScore > mHighScore){
45 | mHighScore = mScore;
46 | // Save high score
47 | mEditor.putInt("hi_score", mHighScore);
48 | mEditor.commit();
49 | }
50 | }
51 |
52 | void startNewGame(){
53 | mScore = 0;
54 | mNumShips = 3;
55 | // Don't want to be drawing objects
56 | // while deSpawnReSpawn is
57 | // clearing them and spawning them again
58 | stopDrawing();
59 | gameStarter.deSpawnReSpawn();
60 | resume();
61 |
62 | // Now we can draw again
63 | startDrawing();
64 | }
65 |
66 |
67 | void loseLife(SoundEngine se){
68 | mNumShips--;
69 | se.playPlayerExplode();
70 | if(mNumShips == 0){
71 | pause();
72 | endGame();
73 | }
74 | }
75 |
76 | int getNumShips(){
77 | return mNumShips;
78 | }
79 |
80 | void increaseScore(){
81 | mScore++;
82 | }
83 |
84 | int getScore(){
85 | return mScore;
86 | }
87 |
88 | int getHighScore(){
89 | return mHighScore;
90 | }
91 |
92 | void pause(){
93 | mPaused = true;
94 | }
95 |
96 | void resume(){
97 | mGameOver = false;
98 | mPaused = false;
99 | }
100 |
101 | void stopEverything(){
102 | mPaused = true;
103 | mGameOver = true;
104 | mThreadRunning = false;
105 | }
106 |
107 | boolean getThreadRunning(){
108 | return mThreadRunning;
109 | }
110 |
111 | void startThread(){
112 | mThreadRunning = true;
113 | }
114 |
115 | private void stopDrawing(){
116 | mDrawing = false;
117 | }
118 |
119 | private void startDrawing(){
120 | mDrawing = true;
121 | }
122 |
123 | boolean getDrawing() {
124 | return mDrawing;
125 | }
126 |
127 | boolean getPaused(){
128 | return mPaused;
129 | }
130 |
131 | boolean getGameOver(){
132 | return mGameOver;
133 | }
134 |
135 |
136 |
137 | }
--------------------------------------------------------------------------------
/Chapter 20/java/GraphicsComponent.java:
--------------------------------------------------------------------------------
1 | package com.gamecodeschool.scrollingshooter;
2 |
3 | import android.content.Context;
4 | import android.graphics.Canvas;
5 | import android.graphics.Paint;
6 | import android.graphics.PointF;
7 |
8 | interface GraphicsComponent {
9 |
10 | void initialize(Context c,
11 | ObjectSpec s,
12 | PointF screensize);
13 |
14 | void draw(Canvas canvas,
15 | Paint paint,
16 | Transform t);
17 | }
18 |
--------------------------------------------------------------------------------
/Chapter 20/java/InputComponent.java:
--------------------------------------------------------------------------------
1 | package com.gamecodeschool.scrollingshooter;
2 |
3 | interface InputComponent {
4 |
5 | void setTransform(Transform t);
6 | }
7 |
8 |
--------------------------------------------------------------------------------
/Chapter 20/java/InputObserver.java:
--------------------------------------------------------------------------------
1 | package com.gamecodeschool.scrollingshooter;
2 |
3 | import android.graphics.Rect;
4 | import android.view.MotionEvent;
5 | import java.util.ArrayList;
6 |
7 | interface InputObserver {
8 |
9 | void handleInput(MotionEvent event, GameState gs,
10 | ArrayList controls);
11 | }
12 |
--------------------------------------------------------------------------------
/Chapter 20/java/LaserMovementComponent.java:
--------------------------------------------------------------------------------
1 | package com.gamecodeschool.scrollingshooter;
2 |
3 | import android.graphics.PointF;
4 |
5 | class LaserMovementComponent implements MovementComponent {
6 |
7 | @Override
8 | public boolean move(long fps,
9 | Transform t,
10 | Transform playerTransform) {
11 |
12 | // Laser can only travel two screen widths
13 | float range = t.getmScreenSize().x * 2;
14 |
15 | // Where is the laser
16 | PointF location = t.getLocation();
17 |
18 | // How fast is it going
19 | float speed = t.getSpeed();
20 |
21 | if(t.headingRight()){
22 | location.x += speed / fps;
23 | }
24 | else if(t.headingLeft()){
25 | location.x -= speed / fps;
26 | }
27 |
28 | // Has the laser gone out of range
29 | if(location.x < - range || location.x > range){
30 | // disable the laser
31 | return false;
32 | }
33 |
34 | t.updateCollider();
35 |
36 |
37 | return true;
38 | }
39 | }
40 |
--------------------------------------------------------------------------------
/Chapter 20/java/LaserSpawnComponent.java:
--------------------------------------------------------------------------------
1 | package com.gamecodeschool.scrollingshooter;
2 |
3 | import android.graphics.PointF;
4 |
5 | class LaserSpawnComponent implements SpawnComponent {
6 |
7 | @Override
8 | public void spawn(Transform playerTransform,
9 | Transform t) {
10 |
11 | PointF startPosition =
12 | playerTransform.getFiringLocation(t.getSize().x);
13 |
14 | t.setLocation((int)startPosition.x, (int)startPosition.y);
15 |
16 | if(playerTransform.getFacingRight()){
17 | t.headRight();
18 | }
19 | else{
20 | t.headLeft();
21 | }
22 |
23 |
24 | }
25 | }
26 |
27 |
--------------------------------------------------------------------------------
/Chapter 20/java/Level.java:
--------------------------------------------------------------------------------
1 | package com.gamecodeschool.scrollingshooter;
2 |
3 | import android.content.Context;
4 | import android.graphics.PointF;
5 |
6 | import java.util.ArrayList;
7 |
8 | class Level {
9 |
10 | // Keep track of specific types
11 | public static final int BACKGROUND_INDEX = 0;
12 | public static final int PLAYER_INDEX = 1;
13 | public static final int FIRST_PLAYER_LASER = 2;
14 | public static final int LAST_PLAYER_LASER = 4;
15 | public static int mNextPlayerLaser;
16 | public static final int FIRST_ALIEN = 5;
17 | public static final int SECOND_ALIEN = 6;
18 | public static final int THIRD_ALIEN = 7;
19 | public static final int FOURTH_ALIEN = 8;
20 | public static final int FIFTH_ALIEN = 9;
21 | public static final int SIXTH_ALIEN = 10;
22 | public static final int LAST_ALIEN = 10;
23 | public static final int FIRST_ALIEN_LASER = 11;
24 | public static final int LAST_ALIEN_LASER = 15;
25 | public static int mNextAlienLaser;
26 |
27 | // This will hold all the instances of GameObject
28 | private ArrayList objects;
29 | public Level(Context context,
30 | PointF mScreenSize,
31 | GameEngine ge){
32 |
33 | objects = new ArrayList<>();
34 | GameObjectFactory factory = new GameObjectFactory(
35 | context, mScreenSize, ge);
36 |
37 | buildGameObjects(factory);
38 | }
39 |
40 | ArrayList buildGameObjects(
41 | GameObjectFactory factory){
42 |
43 | objects.clear();
44 | objects.add(BACKGROUND_INDEX, factory
45 | .create(new BackgroundSpec()));
46 |
47 | objects.add(PLAYER_INDEX, factory
48 | .create(new PlayerSpec()));
49 |
50 | // Spawn the player's lasers
51 | for (int i = FIRST_PLAYER_LASER;
52 | i != LAST_PLAYER_LASER + 1; i++) {
53 |
54 | objects.add(i, factory
55 | .create(new PlayerLaserSpec()));
56 | }
57 |
58 | mNextPlayerLaser = FIRST_PLAYER_LASER;
59 |
60 | // Create some aliens
61 |
62 | // Create some alien lasers
63 |
64 | return objects;
65 | }
66 |
67 | ArrayList getGameObjects(){
68 | return objects;
69 | }
70 |
71 |
72 | }
73 |
--------------------------------------------------------------------------------
/Chapter 20/java/MovementComponent.java:
--------------------------------------------------------------------------------
1 | package com.gamecodeschool.scrollingshooter;
2 |
3 | interface MovementComponent {
4 |
5 | boolean move(long fps,
6 | Transform t,
7 | Transform playerTransform);
8 | }
9 |
--------------------------------------------------------------------------------
/Chapter 20/java/ObjectSpec.java:
--------------------------------------------------------------------------------
1 | package com.gamecodeschool.scrollingshooter;
2 |
3 | import android.graphics.PointF;
4 |
5 | abstract class ObjectSpec {
6 |
7 | private String mTag;
8 | private String mBitmapName;
9 | private float mSpeed;
10 | private PointF mSizeScale;
11 | private String[] mComponents;
12 |
13 | ObjectSpec(String tag, String bitmapName,
14 | float speed, PointF relativeScale,
15 | String[] components) {
16 |
17 | mTag = tag;
18 | mBitmapName = bitmapName;
19 | mSpeed = speed;
20 | mSizeScale = relativeScale;
21 | mComponents = components;
22 | }
23 |
24 | String getTag() {
25 | return mTag;
26 | }
27 |
28 | String getBitmapName() {
29 | return mBitmapName;
30 | }
31 |
32 | float getSpeed() {
33 | return mSpeed;
34 | }
35 |
36 | PointF getScale() {
37 | return mSizeScale;
38 | }
39 |
40 | String[] getComponents() {
41 | return mComponents;
42 | }
43 | }
44 |
--------------------------------------------------------------------------------
/Chapter 20/java/Particle.java:
--------------------------------------------------------------------------------
1 | package com.gamecodeschool.scrollingshooter;
2 |
3 | import android.graphics.PointF;
4 |
5 | class Particle {
6 |
7 | PointF mVelocity;
8 | PointF mPosition;
9 |
10 | Particle(PointF direction)
11 | {
12 | mVelocity = new PointF();
13 | mPosition = new PointF();
14 |
15 | // Determine the direction
16 | mVelocity.x = direction.x;
17 | mVelocity.y = direction.y;
18 |
19 | }
20 |
21 | void update()
22 | {
23 | // Move the particle
24 | mPosition.x += mVelocity.x;
25 | mPosition.y += mVelocity.y;
26 | }
27 |
28 | void setPosition(PointF position)
29 | {
30 | mPosition.x = position.x;
31 | mPosition.y = position.y;
32 | }
33 |
34 | PointF getPosition()
35 | {
36 | return mPosition;
37 | }
38 |
39 | }
40 |
41 |
--------------------------------------------------------------------------------
/Chapter 20/java/ParticleSystem.java:
--------------------------------------------------------------------------------
1 | package com.gamecodeschool.scrollingshooter;
2 |
3 | import android.graphics.Canvas;
4 | import android.graphics.Paint;
5 | import android.graphics.PointF;
6 |
7 | import java.util.ArrayList;
8 | import java.util.Random;
9 |
10 | class ParticleSystem {
11 |
12 | float mDuration;
13 |
14 | ArrayList mParticles;
15 | Random random = new Random();
16 | boolean mIsRunning = false;
17 |
18 | void init(int numParticles){
19 |
20 | mParticles = new ArrayList<>();
21 | // Create the particles
22 |
23 | for (int i = 0; i < numParticles; i++) {
24 | float angle = (random.nextInt(360)) ;
25 | angle = angle * 3.14f / 180.f;
26 | float speed = (random.nextInt(20)+1);
27 |
28 | PointF direction;
29 |
30 | direction = new PointF((float)Math.cos(angle) * speed,
31 | (float)Math.sin(angle) * speed);
32 |
33 | mParticles.add(new Particle(direction));
34 | }
35 | }
36 | void update(long fps){
37 |
38 | mDuration -= (1f/fps);
39 |
40 | for(Particle p : mParticles){
41 | p.update();
42 | }
43 |
44 | if (mDuration < 0)
45 | {
46 | mIsRunning = false;
47 | }
48 | }
49 |
50 | void emitParticles(PointF startPosition){
51 |
52 | mIsRunning = true;
53 | mDuration = 1f;
54 |
55 | for(Particle p : mParticles){
56 | p.setPosition(startPosition);
57 | }
58 | }
59 |
60 | void draw(Canvas canvas, Paint paint){
61 |
62 | for (Particle p : mParticles) {
63 |
64 | paint.setARGB(255,
65 | random.nextInt(256),
66 | random.nextInt(256),
67 | random.nextInt(256));
68 |
69 | // Uncomment the next line to have plain white particles
70 | //paint.setColor(Color.argb(255,255,255,255));
71 | canvas.drawRect(p.getPosition().x,
72 | p.getPosition().y,
73 | p.getPosition().x+25,
74 | p.getPosition().y+25, paint);
75 | }
76 | }
77 | }
78 |
79 |
--------------------------------------------------------------------------------
/Chapter 20/java/PhysicsEngine.java:
--------------------------------------------------------------------------------
1 | package com.gamecodeschool.scrollingshooter;
2 |
3 | import java.util.ArrayList;
4 |
5 | class PhysicsEngine {
6 |
7 | // This signature and much more will
8 | //change later in the project
9 | boolean update(long fps, ArrayList objects,
10 | GameState gs, SoundEngine se,
11 | ParticleSystem ps){
12 |
13 | // Update all the GameObjects
14 | for (GameObject object : objects) {
15 | if (object.checkActive()) {
16 | object.update(fps, objects .get(Level.PLAYER_INDEX)
17 | .getTransform());
18 | }
19 | }
20 |
21 | if(ps.mIsRunning){
22 | ps.update(fps);
23 | }
24 |
25 | return false;
26 | }
27 |
28 |
29 | // Collision detection method will go here
30 |
31 | }
32 |
33 |
--------------------------------------------------------------------------------
/Chapter 20/java/PlayerInputComponent.java:
--------------------------------------------------------------------------------
1 | package com.gamecodeschool.scrollingshooter;
2 |
3 | import android.graphics.Rect;
4 | import android.view.MotionEvent;
5 |
6 | import java.util.ArrayList;
7 |
8 | class PlayerInputComponent implements InputComponent,
9 | InputObserver {
10 |
11 | private Transform mTransform;
12 | private PlayerLaserSpawner mPLS;
13 |
14 | PlayerInputComponent(GameEngine ger) {
15 |
16 | ger.addObserver(this);
17 | mPLS = ger;
18 |
19 | }
20 |
21 | @Override
22 | public void setTransform(Transform transform) {
23 | mTransform = transform;
24 |
25 | }
26 |
27 | // Required method of InputObserver
28 | // interface called from the onTouchEvent method
29 | @Override
30 | public void handleInput(MotionEvent event,
31 | GameState gameState,
32 | ArrayList buttons) {
33 |
34 | int i = event.getActionIndex();
35 | int x = (int) event.getX(i);
36 | int y = (int) event.getY(i);
37 |
38 | switch (event.getAction() & MotionEvent.ACTION_MASK) {
39 |
40 | case MotionEvent.ACTION_UP:
41 | if (buttons.get(HUD.UP).contains(x,y)
42 | || buttons.get(HUD.DOWN).contains(x,y)) {
43 |
44 | // Player has released either up or down
45 | mTransform.stopVertical();
46 | }
47 | break;
48 |
49 | case MotionEvent.ACTION_DOWN:
50 | if (buttons.get(HUD.UP).contains(x,y)) {
51 | // Player has pressed up
52 | mTransform.headUp();
53 | } else if (buttons.get(HUD.DOWN).contains(x,y)) {
54 | // Player has pressed down
55 | mTransform.headDown();
56 | } else if (buttons.get(HUD.FLIP).contains(x,y)) {
57 | // Player has released the flip button
58 | mTransform.flip();
59 | } else if (buttons.get(HUD.SHOOT).contains(x,y)) {
60 | mPLS.spawnPlayerLaser(mTransform);
61 | }
62 | break;
63 |
64 | case MotionEvent.ACTION_POINTER_UP:
65 | if (buttons.get(HUD.UP).contains(x, y)
66 | ||
67 | buttons.get(HUD.DOWN).contains(x, y)) {
68 |
69 | // Player has released either up or down
70 | mTransform.stopVertical();
71 | }
72 | break;
73 |
74 | case MotionEvent.ACTION_POINTER_DOWN:
75 | if (buttons.get(HUD.UP).contains(x, y)) {
76 | // Player has pressed up
77 | mTransform.headUp();
78 | } else if (buttons.get(HUD.DOWN).contains(x, y)) {
79 | // Player has pressed down
80 | mTransform.headDown();
81 | } else if (buttons.get(HUD.FLIP).contains(x, y)) {
82 | // Player has released the flip button
83 | mTransform.flip();
84 | } else if (buttons.get(HUD.SHOOT).contains(x, y)) {
85 | mPLS.spawnPlayerLaser(mTransform);
86 | }
87 | break;
88 | }
89 |
90 |
91 | }
92 | }
93 |
--------------------------------------------------------------------------------
/Chapter 20/java/PlayerLaserSpawner.java:
--------------------------------------------------------------------------------
1 | package com.gamecodeschool.scrollingshooter;
2 |
3 | public interface PlayerLaserSpawner {
4 | boolean spawnPlayerLaser(Transform transform);
5 | }
6 |
--------------------------------------------------------------------------------
/Chapter 20/java/PlayerLaserSpec.java:
--------------------------------------------------------------------------------
1 | package com.gamecodeschool.scrollingshooter;
2 |
3 | import android.graphics.PointF;
4 |
5 | class PlayerLaserSpec extends ObjectSpec {
6 | // This is all the unique specifications
7 | // for a player laser
8 | private static final String tag = "Player Laser";
9 | private static final String bitmapName = "player_laser";
10 | private static final float speed = .65f;
11 | private static final PointF relativeScale =
12 | new PointF(8f, 160f);
13 |
14 | private static final String[] components = new String [] {
15 | "StdGraphicsComponent",
16 | "LaserMovementComponent",
17 | "LaserSpawnComponent"};
18 |
19 | PlayerLaserSpec(){
20 | super(tag, bitmapName,
21 | speed, relativeScale,
22 | components);
23 | }
24 | }
25 |
--------------------------------------------------------------------------------
/Chapter 20/java/PlayerMovementComponent.java:
--------------------------------------------------------------------------------
1 | package com.gamecodeschool.scrollingshooter;
2 |
3 | import android.graphics.PointF;
4 |
5 | class PlayerMovementComponent implements MovementComponent {
6 |
7 | @Override
8 | public boolean move(long fps, Transform t,
9 | Transform playerTransform){
10 | // How high is the screen?
11 | float screenHeight = t.getmScreenSize().y;
12 | // Where is the player?
13 | PointF location = t.getLocation();
14 | // How fast is it going
15 | float speed = t.getSpeed();
16 | // How tall is the ship
17 | float height = t.getObjectHeight();
18 |
19 | // Move the ship up or down if needed
20 | if(t.headingDown()){
21 | location.y += speed / fps;
22 | }
23 | else if(t.headingUp()){
24 | location.y -= speed / fps;
25 | }
26 |
27 | // Make sure the ship can't go off the screen
28 | if(location.y > screenHeight - height){
29 | location.y = screenHeight - height;
30 | }
31 | else if(location.y < 0){
32 | location.y = 0;
33 | }
34 |
35 | // Update the collider
36 | t.updateCollider();
37 |
38 |
39 | return true;
40 | }
41 | }
42 |
--------------------------------------------------------------------------------
/Chapter 20/java/PlayerSpawnComponent.java:
--------------------------------------------------------------------------------
1 | package com.gamecodeschool.scrollingshooter;
2 |
3 | class PlayerSpawnComponent implements SpawnComponent {
4 |
5 | @Override
6 | public void spawn(Transform playerTransform, Transform t) {
7 |
8 | // Spawn in the centre of the screen
9 | t.setLocation(
10 | t.getmScreenSize().x/2,
11 | t.getmScreenSize().y/2);
12 |
13 |
14 | }
15 | }
16 |
17 |
--------------------------------------------------------------------------------
/Chapter 20/java/PlayerSpec.java:
--------------------------------------------------------------------------------
1 | package com.gamecodeschool.scrollingshooter;
2 |
3 | import android.graphics.PointF;
4 |
5 | class PlayerSpec extends ObjectSpec {
6 | // This is all the unique specifications
7 | // for a player
8 | private static final String tag = "Player";
9 | private static final String bitmapName = "player_ship";
10 | private static final float speed = 1f;
11 | private static final PointF relativeScale =
12 | new PointF(15f, 15f);
13 |
14 | private static final String[] components = new String [] {
15 | "PlayerInputComponent",
16 | "StdGraphicsComponent",
17 | "PlayerMovementComponent",
18 | "PlayerSpawnComponent"};
19 |
20 | PlayerSpec() {
21 | super(tag, bitmapName,
22 | speed, relativeScale,
23 | components);
24 | }
25 | }
26 |
27 |
--------------------------------------------------------------------------------
/Chapter 20/java/Renderer.java:
--------------------------------------------------------------------------------
1 | package com.gamecodeschool.scrollingshooter;
2 |
3 | import android.graphics.Canvas;
4 | import android.graphics.Color;
5 | import android.graphics.Paint;
6 | import android.view.SurfaceHolder;
7 | import android.view.SurfaceView;
8 |
9 | import java.util.ArrayList;
10 |
11 | class Renderer {
12 | private Canvas mCanvas;
13 | private SurfaceHolder mSurfaceHolder;
14 | private Paint mPaint;
15 |
16 | Renderer(SurfaceView sh){
17 | mSurfaceHolder = sh.getHolder();
18 | mPaint = new Paint();
19 | }
20 |
21 | void draw(ArrayList objects, GameState gs,
22 | HUD hud, ParticleSystem ps) {
23 |
24 | if (mSurfaceHolder.getSurface().isValid()) {
25 | mCanvas = mSurfaceHolder.lockCanvas();
26 | mCanvas.drawColor(Color.argb(255, 0, 0, 0));
27 |
28 | if (gs.getDrawing()) {
29 | // Draw all the game objects here
30 | for (GameObject object : objects) {
31 | if(object.checkActive()) {
32 | object.draw(mCanvas, mPaint);
33 | }
34 | }
35 |
36 | }
37 |
38 | if(gs.getGameOver()) {
39 | // Draw just a background graphic here
40 | objects.get(Level.BACKGROUND_INDEX)
41 | .draw(mCanvas, mPaint);
42 |
43 | }
44 |
45 | // Draw a particle system explosion here
46 | if(ps.mIsRunning){
47 | ps.draw(mCanvas, mPaint);
48 | }
49 |
50 |
51 | // Now we draw the HUD on top of everything else
52 | hud.draw(mCanvas, mPaint, gs);
53 |
54 | mSurfaceHolder.unlockCanvasAndPost(mCanvas);
55 | }
56 | }
57 |
58 | }
59 |
--------------------------------------------------------------------------------
/Chapter 20/java/SoundEngine.java:
--------------------------------------------------------------------------------
1 | package com.gamecodeschool.scrollingshooter;
2 |
3 | import android.content.Context;
4 | import android.content.res.AssetFileDescriptor;
5 | import android.content.res.AssetManager;
6 | import android.media.AudioAttributes;
7 | import android.media.AudioManager;
8 | import android.media.SoundPool;
9 | import android.os.Build;
10 |
11 | import java.io.IOException;
12 |
13 | class SoundEngine {
14 | // for playing sound effects
15 | private SoundPool mSP;
16 | private int mShoot_ID = -1;
17 | private int mAlien_Explode_ID = -1;
18 | private int mPlayer_explode_ID = -1;
19 |
20 | SoundEngine(Context c){
21 | // Initialize the SoundPool
22 | if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
23 | AudioAttributes audioAttributes =
24 | new AudioAttributes.Builder()
25 | .setUsage(AudioAttributes.USAGE_MEDIA)
26 | .setContentType(AudioAttributes
27 | .CONTENT_TYPE_SONIFICATION)
28 | .build();
29 |
30 | mSP = new SoundPool.Builder()
31 | .setMaxStreams(5)
32 | .setAudioAttributes(audioAttributes)
33 | .build();
34 | } else {
35 | mSP = new SoundPool(5, AudioManager.STREAM_MUSIC, 0);
36 | }
37 | try {
38 | AssetManager assetManager = c.getAssets();
39 | AssetFileDescriptor descriptor;
40 |
41 | // Prepare the sounds in memory
42 | descriptor = assetManager.openFd("shoot.ogg");
43 | mShoot_ID = mSP.load(descriptor, 0);
44 |
45 | descriptor = assetManager.openFd("alien_explosion.ogg");
46 | mAlien_Explode_ID = mSP.load(descriptor, 0);
47 |
48 | descriptor =
49 | assetManager.openFd("player_explosion.ogg");
50 |
51 | mPlayer_explode_ID = mSP.load(descriptor, 0);
52 |
53 | } catch (IOException e) {
54 | // Error
55 | }
56 |
57 | }
58 |
59 | void playShoot(){
60 | mSP.play(mShoot_ID,1, 1, 0, 0, 1);
61 | }
62 |
63 | void playAlienExplode(){
64 | mSP.play(mAlien_Explode_ID,1, 1, 0, 0, 1);
65 | }
66 |
67 | void playPlayerExplode(){
68 | mSP.play(mPlayer_explode_ID,1, 1, 0, 0, 1);
69 | }
70 |
71 |
72 | }
73 |
--------------------------------------------------------------------------------
/Chapter 20/java/SpawnComponent.java:
--------------------------------------------------------------------------------
1 | package com.gamecodeschool.scrollingshooter;
2 |
3 | interface SpawnComponent {
4 | void spawn(Transform playerTransform, Transform t);
5 |
6 | }
--------------------------------------------------------------------------------
/Chapter 20/java/StdGraphicsComponent.java:
--------------------------------------------------------------------------------
1 | package com.gamecodeschool.scrollingshooter;
2 |
3 | import android.content.Context;
4 | import android.graphics.Bitmap;
5 | import android.graphics.BitmapFactory;
6 | import android.graphics.Canvas;
7 | import android.graphics.Matrix;
8 | import android.graphics.Paint;
9 | import android.graphics.PointF;
10 |
11 | class StdGraphicsComponent implements GraphicsComponent {
12 |
13 | private Bitmap mBitmap;
14 | private Bitmap mBitmapReversed;
15 |
16 | @Override
17 | public void initialize(Context context,
18 | ObjectSpec spec,
19 | PointF objectSize){
20 | // Make a resource id out of the string of the file name
21 | int resID = context.getResources()
22 | .getIdentifier(spec.getBitmapName(),
23 | "drawable",
24 | context.getPackageName());
25 |
26 | // Load the bitmap using the id
27 | mBitmap = BitmapFactory.decodeResource(
28 | context.getResources(), resID);
29 |
30 | // Resize the bitmap
31 | mBitmap = Bitmap
32 | .createScaledBitmap(mBitmap,
33 | (int)objectSize.x,
34 | (int)objectSize.y,
35 | false);
36 |
37 | // Create a mirror image of the bitmap if needed
38 | Matrix matrix = new Matrix();
39 | matrix.setScale(-1, 1);
40 | mBitmapReversed = Bitmap.createBitmap(mBitmap,
41 | 0, 0,
42 | mBitmap.getWidth(),
43 | mBitmap.getHeight(),
44 | matrix, true);
45 | }
46 |
47 | @Override
48 | public void draw(Canvas canvas,
49 | Paint paint,
50 | Transform t) {
51 |
52 | if(t.getFacingRight())
53 | canvas.drawBitmap(mBitmap,
54 | t.getLocation().x,
55 | t.getLocation().y,
56 | paint);
57 |
58 | else
59 | canvas.drawBitmap(mBitmapReversed,
60 | t.getLocation().x,
61 | t.getLocation().y,
62 | paint);
63 |
64 |
65 | }
66 | }
67 |
--------------------------------------------------------------------------------
/Chapter 20/java/UIController.java:
--------------------------------------------------------------------------------
1 | package com.gamecodeschool.scrollingshooter;
2 | import android.graphics.Point;
3 | import android.graphics.Rect;
4 | import android.view.MotionEvent;
5 |
6 | import java.util.ArrayList;
7 |
8 | class UIController implements InputObserver {
9 |
10 | public UIController(GameEngineBroadcaster b){
11 | b.addObserver(this);
12 | }
13 |
14 | @Override
15 | public void handleInput(MotionEvent event, GameState gameState, ArrayList buttons) {
16 |
17 | int i = event.getActionIndex();
18 | int x = (int) event.getX(i);
19 | int y = (int) event.getY(i);
20 |
21 | int eventType = event.getAction() & MotionEvent.ACTION_MASK;
22 |
23 | if(eventType == MotionEvent.ACTION_UP ||
24 | eventType == MotionEvent.ACTION_POINTER_UP) {
25 |
26 |
27 | if (buttons.get(HUD.PAUSE).contains(x, y)){
28 | // Player pressed the pause button
29 | // Respond differently depending
30 | // upon the game's state
31 |
32 | // If the game is not paused
33 | if (!gameState.getPaused()) {
34 | // Pause the game
35 | gameState.pause();
36 | }
37 |
38 | // If game is over start a new game
39 | else if (gameState.getGameOver()) {
40 |
41 | gameState.startNewGame();
42 | }
43 |
44 | // Paused and not game over
45 | else if (gameState.getPaused()
46 | && !gameState.getGameOver()) {
47 |
48 | gameState.resume();
49 | }
50 | }
51 | }
52 | }
53 |
54 | }
55 |
--------------------------------------------------------------------------------
/Chapter 21/assets/alien_explosion.ogg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/PacktPublishing/Learning-Java-by-Building-Android-Games-Third-Edition/9e56a97be80dcca7c697937a046b4a43b250e29f/Chapter 21/assets/alien_explosion.ogg
--------------------------------------------------------------------------------
/Chapter 21/assets/player_explosion.ogg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/PacktPublishing/Learning-Java-by-Building-Android-Games-Third-Edition/9e56a97be80dcca7c697937a046b4a43b250e29f/Chapter 21/assets/player_explosion.ogg
--------------------------------------------------------------------------------
/Chapter 21/assets/shoot.ogg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/PacktPublishing/Learning-Java-by-Building-Android-Games-Third-Edition/9e56a97be80dcca7c697937a046b4a43b250e29f/Chapter 21/assets/shoot.ogg
--------------------------------------------------------------------------------
/Chapter 21/drawable/alien_laser.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/PacktPublishing/Learning-Java-by-Building-Android-Games-Third-Edition/9e56a97be80dcca7c697937a046b4a43b250e29f/Chapter 21/drawable/alien_laser.png
--------------------------------------------------------------------------------
/Chapter 21/drawable/alien_ship1.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/PacktPublishing/Learning-Java-by-Building-Android-Games-Third-Edition/9e56a97be80dcca7c697937a046b4a43b250e29f/Chapter 21/drawable/alien_ship1.png
--------------------------------------------------------------------------------
/Chapter 21/drawable/alien_ship2.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/PacktPublishing/Learning-Java-by-Building-Android-Games-Third-Edition/9e56a97be80dcca7c697937a046b4a43b250e29f/Chapter 21/drawable/alien_ship2.png
--------------------------------------------------------------------------------
/Chapter 21/drawable/alien_ship3.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/PacktPublishing/Learning-Java-by-Building-Android-Games-Third-Edition/9e56a97be80dcca7c697937a046b4a43b250e29f/Chapter 21/drawable/alien_ship3.png
--------------------------------------------------------------------------------
/Chapter 21/drawable/background.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/PacktPublishing/Learning-Java-by-Building-Android-Games-Third-Edition/9e56a97be80dcca7c697937a046b4a43b250e29f/Chapter 21/drawable/background.png
--------------------------------------------------------------------------------
/Chapter 21/drawable/player_laser.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/PacktPublishing/Learning-Java-by-Building-Android-Games-Third-Edition/9e56a97be80dcca7c697937a046b4a43b250e29f/Chapter 21/drawable/player_laser.png
--------------------------------------------------------------------------------
/Chapter 21/drawable/player_ship.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/PacktPublishing/Learning-Java-by-Building-Android-Games-Third-Edition/9e56a97be80dcca7c697937a046b4a43b250e29f/Chapter 21/drawable/player_ship.png
--------------------------------------------------------------------------------
/Chapter 21/java/AlienChaseSpec.java:
--------------------------------------------------------------------------------
1 | package com.gamecodeschool.scrollingshooter;
2 |
3 | import android.graphics.PointF;
4 |
5 | class AlienChaseSpec extends ObjectSpec {
6 | // This is all the unique specifications
7 | // for an alien that chases the player
8 | private static final String tag = "Alien";
9 | private static final String bitmapName = "alien_ship1";
10 | private static final float speed = 4f;
11 | private static final PointF relativeScale =
12 | new PointF(15f, 15f);
13 |
14 | private static final String[] components = new String [] {
15 | "StdGraphicsComponent",
16 | "AlienChaseMovementComponent",
17 | "AlienHorizontalSpawnComponent"};
18 |
19 | AlienChaseSpec(){
20 | super(tag, bitmapName,
21 | speed, relativeScale,
22 | components);
23 | }
24 | }
25 |
--------------------------------------------------------------------------------
/Chapter 21/java/AlienDiverMovementComponent.java:
--------------------------------------------------------------------------------
1 | package com.gamecodeschool.scrollingshooter;
2 |
3 | import android.graphics.PointF;
4 | import java.util.Random;
5 |
6 | class AlienDiverMovementComponent implements MovementComponent {
7 |
8 | @Override
9 | public boolean move(long fps, Transform t, Transform playerTransform) {
10 |
11 | // Where is the ship?
12 | PointF location = t.getLocation();
13 | // How fast is the ship?
14 | float speed = t.getSpeed();
15 |
16 | // Relative speed difference with player
17 | float slowDownRelativeToPlayer = 1.8f;
18 |
19 | // Compensate for movement relative to player-
20 | // but only when in view.
21 | // Otherwise alien will disappear miles off to one side
22 | if(!playerTransform.getFacingRight()){
23 | location.x += speed * slowDownRelativeToPlayer / fps;
24 | } else{
25 | location.x -= speed * slowDownRelativeToPlayer / fps;
26 | }
27 |
28 | // Fall down then respawn at the top
29 | location.y += speed / fps;
30 |
31 | if(location.y > t.getmScreenSize().y){
32 | // Respawn at top
33 | Random random = new Random();
34 | location.y = random.nextInt(300) - t.getObjectHeight();
35 | location.x = random.nextInt((int)t.getmScreenSize().x);
36 | }
37 |
38 | // Update the collider
39 | t.updateCollider();
40 |
41 | return true;
42 | }
43 | }
44 |
--------------------------------------------------------------------------------
/Chapter 21/java/AlienDiverSpec.java:
--------------------------------------------------------------------------------
1 | package com.gamecodeschool.scrollingshooter;
2 |
3 | import android.graphics.PointF;
4 |
5 | class AlienDiverSpec extends ObjectSpec {
6 | // This is all the unique specifications
7 | // for an alien that dives
8 | private static final String tag = "Alien";
9 | private static final String bitmapName = "alien_ship3";
10 | private static final float speed = 4f;
11 | private static final PointF relativeScale =
12 | new PointF(60f, 30f);
13 |
14 | private static final String[] components = new String [] {
15 | "StdGraphicsComponent",
16 | "AlienDiverMovementComponent",
17 | "AlienVerticalSpawnComponent"};
18 |
19 | AlienDiverSpec(){
20 | super(tag, bitmapName,
21 | speed, relativeScale,
22 | components);
23 | }
24 | }
25 |
--------------------------------------------------------------------------------
/Chapter 21/java/AlienHorizontalSpawnComponent.java:
--------------------------------------------------------------------------------
1 | package com.gamecodeschool.scrollingshooter;
2 |
3 | import android.graphics.PointF;
4 | import java.util.Random;
5 |
6 | class AlienHorizontalSpawnComponent implements SpawnComponent {
7 | @Override
8 | public void spawn(Transform playerLTransform, Transform t) {
9 | // Get the screen size
10 | PointF ss = t.getmScreenSize();
11 |
12 | // Spawn just off screen randomly left or right
13 | Random random = new Random();
14 | boolean left = random.nextBoolean();
15 | // How far away?
16 | float distance = random.nextInt(2000)
17 | + t.getmScreenSize().x;
18 |
19 | // Generate a height to spawn at where
20 | // the entire ship is vertically on-screen
21 | float spawnHeight = random.nextFloat()
22 | * ss.y - t.getSize().y;
23 |
24 | // Spawn the ship
25 | if(left){
26 | t.setLocation(-distance, spawnHeight);
27 | t.headRight();
28 | }else{
29 | t.setLocation(distance, spawnHeight);
30 | t.headingLeft();
31 | }
32 |
33 | }
34 | }
35 |
--------------------------------------------------------------------------------
/Chapter 21/java/AlienLaserSpawner.java:
--------------------------------------------------------------------------------
1 | package com.gamecodeschool.scrollingshooter;
2 |
3 | // This allows an alien to communicate with the game engine
4 | // and spawn a laser
5 | interface AlienLaserSpawner {
6 | void spawnAlienLaser(Transform transform);
7 | }
8 |
--------------------------------------------------------------------------------
/Chapter 21/java/AlienLaserSpec.java:
--------------------------------------------------------------------------------
1 | package com.gamecodeschool.scrollingshooter;
2 |
3 | import android.graphics.PointF;
4 |
5 | class AlienLaserSpec extends ObjectSpec {
6 | // This is all the unique specifications
7 | // for an alien laser
8 | private static final String tag = "Alien Laser";
9 | private static final String bitmapName = "alien_laser";
10 | private static final float speed = .75f;
11 | private static final PointF relativeScale =
12 | new PointF(14f, 160f);
13 |
14 | private static final String[] components = new String [] {
15 | "StdGraphicsComponent",
16 | "LaserMovementComponent",
17 | "LaserSpawnComponent"};
18 |
19 | AlienLaserSpec(){
20 | super(tag, bitmapName,
21 | speed, relativeScale,
22 | components);
23 | }
24 | }
25 |
26 |
--------------------------------------------------------------------------------
/Chapter 21/java/AlienPatrolSpec.java:
--------------------------------------------------------------------------------
1 | package com.gamecodeschool.scrollingshooter;
2 |
3 | import android.graphics.PointF;
4 |
5 | class AlienPatrolSpec extends ObjectSpec {
6 | // This is all the unique specifications
7 | // for a patrolling alien
8 | private static final String tag = "Alien";
9 | private static final String bitmapName = "alien_ship2";
10 | private static final float speed = 5f;
11 | private static final PointF relativeScale =
12 | new PointF(15f, 15f);
13 |
14 | private static final String[] components = new String [] {
15 | "StdGraphicsComponent",
16 | "AlienPatrolMovementComponent",
17 | "AlienHorizontalSpawnComponent"};
18 |
19 | AlienPatrolSpec(){
20 | super(tag, bitmapName,
21 | speed, relativeScale,
22 | components);
23 | }
24 | }
25 |
26 |
--------------------------------------------------------------------------------
/Chapter 21/java/AlienVerticalSpawnComponent.java:
--------------------------------------------------------------------------------
1 | package com.gamecodeschool.scrollingshooter;
2 |
3 | import java.util.Random;
4 |
5 | class AlienVerticalSpawnComponent implements SpawnComponent {
6 |
7 | public void spawn(Transform playerLTransform, Transform t) {
8 |
9 | // Spawn just off screen randomly but
10 | // within the screen width
11 | Random random = new Random();
12 | float xPosition = random.nextInt((int)t
13 | .getmScreenSize().x);
14 |
15 | // Set the height to vertically
16 | // just above the visible game
17 | float spawnHeight = random
18 | .nextInt(300) - t.getObjectHeight();
19 |
20 | // Spawn the ship
21 | t.setLocation(xPosition, spawnHeight);
22 | // Always going dowm
23 | t.headDown();
24 | }
25 | }
26 |
--------------------------------------------------------------------------------
/Chapter 21/java/BackgroundGraphicsComponent.java:
--------------------------------------------------------------------------------
1 | package com.gamecodeschool.scrollingshooter;
2 |
3 | import android.content.Context;
4 | import android.graphics.Bitmap;
5 | import android.graphics.BitmapFactory;
6 | import android.graphics.Canvas;
7 | import android.graphics.Matrix;
8 | import android.graphics.Paint;
9 | import android.graphics.PointF;
10 | import android.graphics.Rect;
11 |
12 | class BackgroundGraphicsComponent implements GraphicsComponent {
13 |
14 | private Bitmap mBitmap;
15 | private Bitmap mBitmapReversed;
16 |
17 | @Override
18 | public void initialize(Context c,
19 | ObjectSpec s,
20 | PointF objectSize) {
21 |
22 | // Make a resource id out of the string of the file name
23 | int resID = c.getResources()
24 | .getIdentifier(s.getBitmapName(),
25 | "drawable", c.getPackageName());
26 |
27 | // Load the bitmap using the id
28 | mBitmap = BitmapFactory
29 | .decodeResource(c.getResources(), resID);
30 |
31 | // Resize the bitmap
32 | mBitmap = Bitmap
33 | .createScaledBitmap(mBitmap,
34 | (int)objectSize.x,
35 | (int)objectSize.y,
36 | false);
37 |
38 | // Create a mirror image of the bitmap
39 | Matrix matrix = new Matrix();
40 | matrix.setScale(-1, 1);
41 | mBitmapReversed = Bitmap
42 | .createBitmap(mBitmap,
43 | 0, 0,
44 | mBitmap.getWidth(),
45 | mBitmap.getHeight(),
46 | matrix, true);
47 |
48 |
49 | }
50 |
51 | @Override
52 | public void draw(Canvas canvas,
53 | Paint paint,
54 | Transform t) {
55 |
56 | int xClip = t.getXClip();
57 | int width = mBitmap.getWidth();
58 | int height = mBitmap.getHeight();
59 | int startY = 0;
60 | int endY = (int)t.getmScreenSize().y +20;
61 |
62 | // For the regular bitmap
63 | Rect fromRect1 = new Rect(0, 0, width - xClip, height);
64 | Rect toRect1 = new Rect(xClip, startY, width, endY);
65 |
66 | // For the reversed background
67 | Rect fromRect2 = new Rect(width - xClip, 0, width, height);
68 | Rect toRect2 = new Rect(0, startY, xClip, endY);
69 |
70 | //draw the two background bitmaps
71 | if (!t.getReversedFirst()) {
72 | canvas.drawBitmap(mBitmap,
73 | fromRect1, toRect1, paint);
74 |
75 | canvas.drawBitmap(mBitmapReversed,
76 | fromRect2, toRect2, paint);
77 |
78 | } else {
79 | canvas.drawBitmap(mBitmap, fromRect2,
80 | toRect2, paint);
81 |
82 | canvas.drawBitmap(mBitmapReversed,
83 | fromRect1, toRect1, paint);
84 | }
85 |
86 |
87 | }
88 | }
89 |
90 |
--------------------------------------------------------------------------------
/Chapter 21/java/BackgroundMovementComponent.java:
--------------------------------------------------------------------------------
1 | package com.gamecodeschool.scrollingshooter;
2 |
3 | class BackgroundMovementComponent implements MovementComponent {
4 | @Override
5 | public boolean move(long fps,
6 | Transform t,
7 | Transform playerTransform) {
8 |
9 | int currentXClip = t.getXClip();
10 |
11 | if(playerTransform.getFacingRight()) {
12 | currentXClip -= t.getSpeed() / fps;
13 | t.setXClip(currentXClip);
14 | }
15 | else {
16 | currentXClip += t.getSpeed() / fps;
17 | t.setXClip(currentXClip);
18 | }
19 |
20 | if (currentXClip >= t.getSize().x) {
21 | t.setXClip(0);
22 | t.flipReversedFirst();
23 | }
24 | else if (currentXClip <= 0) {
25 | t.setXClip((int)t.getSize().x);
26 | t.flipReversedFirst();
27 | }
28 |
29 |
30 | return true;
31 | }
32 | }
33 |
--------------------------------------------------------------------------------
/Chapter 21/java/BackgroundSpawnComponent.java:
--------------------------------------------------------------------------------
1 | package com.gamecodeschool.scrollingshooter;
2 |
3 | class BackgroundSpawnComponent implements SpawnComponent {
4 | @Override
5 | public void spawn(Transform playerLTransform, Transform t) {
6 | // Place the background in the top left corner
7 | t.setLocation(0f,0f);
8 |
9 |
10 | }
11 | }
12 |
13 |
--------------------------------------------------------------------------------
/Chapter 21/java/BackgroundSpec.java:
--------------------------------------------------------------------------------
1 | package com.gamecodeschool.scrollingshooter;
2 |
3 | import android.graphics.PointF;
4 |
5 | class BackgroundSpec extends ObjectSpec {
6 | // This is all the unique specifications
7 | // for the background
8 | private static final String tag = "Background";
9 | private static final String bitmapName = "background";
10 | private static final float speed = 2f;
11 | private static final PointF relativeScale =
12 | new PointF(1f, 1f);
13 |
14 | private static final String[] components = new String [] {
15 | "BackgroundGraphicsComponent",
16 | "BackgroundMovementComponent",
17 | "BackgroundSpawnComponent"};
18 |
19 | BackgroundSpec() {
20 | super(tag, bitmapName,
21 | speed, relativeScale,
22 | components);
23 | }
24 | }
25 |
--------------------------------------------------------------------------------
/Chapter 21/java/GameActivity.java:
--------------------------------------------------------------------------------
1 | package com.gamecodeschool.scrollingshooter;
2 |
3 | import android.app.Activity;
4 | import android.graphics.Point;
5 | import android.os.Bundle;
6 | import android.view.Display;
7 | import android.view.Window;
8 |
9 | public class GameActivity extends Activity {
10 |
11 | GameEngine mGameEngine;
12 |
13 | @Override
14 | protected void onCreate(Bundle savedInstanceState) {
15 | super.onCreate(savedInstanceState);
16 | requestWindowFeature(Window.FEATURE_NO_TITLE);
17 |
18 | Display display = getWindowManager()
19 | .getDefaultDisplay();
20 |
21 | Point size = new Point();
22 | display.getSize(size);
23 | mGameEngine = new GameEngine(this, size);
24 | setContentView(mGameEngine);
25 | }
26 |
27 | @Override
28 | protected void onResume() {
29 | super.onResume();
30 | mGameEngine.startThread();
31 | }
32 |
33 | @Override
34 | protected void onPause() {
35 | super.onPause();
36 | mGameEngine.stopThread();
37 | }
38 | }
39 |
--------------------------------------------------------------------------------
/Chapter 21/java/GameEngineBroadcaster.java:
--------------------------------------------------------------------------------
1 | package com.gamecodeschool.scrollingshooter;
2 |
3 | public interface GameEngineBroadcaster {
4 | void addObserver(InputObserver o);
5 | }
6 |
--------------------------------------------------------------------------------
/Chapter 21/java/GameObject.java:
--------------------------------------------------------------------------------
1 | package com.gamecodeschool.scrollingshooter;
2 |
3 | import android.content.Context;
4 | import android.graphics.Canvas;
5 | import android.graphics.Paint;
6 | import android.graphics.PointF;
7 |
8 | class GameObject {
9 |
10 | private Transform mTransform;
11 | private boolean isActive = false;
12 | private String mTag;
13 |
14 | private GraphicsComponent graphicsComponent;
15 | private MovementComponent movementComponent;
16 | private SpawnComponent spawnComponent;
17 |
18 | void setSpawner(SpawnComponent s) {
19 | spawnComponent = s;
20 | }
21 |
22 | void setGraphics(GraphicsComponent g, Context c,
23 | ObjectSpec spec, PointF objectSize) {
24 |
25 | graphicsComponent = g;
26 | g.initialize(c, spec, objectSize);
27 | }
28 |
29 | void setMovement(MovementComponent m) {
30 | movementComponent = m;
31 | }
32 |
33 | void setInput(InputComponent s) {
34 | s.setTransform(mTransform);
35 | }
36 |
37 | void setmTag(String tag) {
38 | mTag = tag;
39 | }
40 |
41 | void setTransform(Transform t) {
42 | mTransform = t;
43 | }
44 |
45 | void draw(Canvas canvas, Paint paint) {
46 | graphicsComponent.draw(canvas, paint, mTransform);
47 | }
48 |
49 | void update(long fps, Transform playerTransform) {
50 | if (!(movementComponent.move(fps,
51 | mTransform, playerTransform))) {
52 | // Component returned false
53 | isActive = false;
54 | }
55 | }
56 |
57 | boolean spawn(Transform playerTransform) {
58 | // Only spawnComponent if not already active
59 | if (!isActive) {
60 | spawnComponent.spawn(playerTransform, mTransform);
61 | isActive = true;
62 | return true;
63 | }
64 | return false;
65 | }
66 |
67 | boolean checkActive() {
68 | return isActive;
69 | }
70 |
71 | String getTag() {
72 | return mTag;
73 | }
74 |
75 | void setInactive() {
76 | isActive = false;
77 | }
78 |
79 | Transform getTransform() {
80 | return mTransform;
81 | }
82 |
83 |
84 |
85 | }
86 |
87 |
--------------------------------------------------------------------------------
/Chapter 21/java/GameStarter.java:
--------------------------------------------------------------------------------
1 | package com.gamecodeschool.scrollingshooter;
2 |
3 | public interface GameStarter {
4 | // This allows the State class to
5 | // spawn and despawn objects via the game engine
6 |
7 | public void deSpawnReSpawn();
8 |
9 | }
10 |
--------------------------------------------------------------------------------
/Chapter 21/java/GameState.java:
--------------------------------------------------------------------------------
1 | package com.gamecodeschool.scrollingshooter;
2 |
3 | import android.content.Context;
4 | import android.content.SharedPreferences;
5 |
6 | final class GameState {
7 | private static volatile boolean mThreadRunning = false;
8 | private static volatile boolean mPaused = true;
9 | private static volatile boolean mGameOver = true;
10 | private static volatile boolean mDrawing = false;
11 |
12 | // This object will have access to the deSpawnReSpawn method
13 | // in GameEngine- once it is initialized
14 | private GameStarter gameStarter;
15 |
16 | private int mScore;
17 | private int mHighScore;
18 | private int mNumShips;
19 |
20 | // This is how we will make all the high scores persist
21 | private SharedPreferences.Editor mEditor;
22 |
23 | GameState(GameStarter gs, Context context){
24 | // This initializes the gameStarter reference
25 | gameStarter = gs;
26 |
27 | // Get the current high score
28 | SharedPreferences prefs;
29 | prefs = context.getSharedPreferences("HiScore",
30 | Context.MODE_PRIVATE);
31 |
32 | // Initialize the mEditor ready
33 | mEditor = prefs.edit();
34 |
35 | // Load high score from a entry in the file
36 | // labeled "hiscore"
37 | // if not available highscore set to zero 0
38 | mHighScore = prefs.getInt("hi_score", 0);
39 | }
40 |
41 | private void endGame(){
42 | mGameOver = true;
43 | mPaused = true;
44 | if(mScore > mHighScore){
45 | mHighScore = mScore;
46 | // Save high score
47 | mEditor.putInt("hi_score", mHighScore);
48 | mEditor.commit();
49 | }
50 | }
51 |
52 | void startNewGame(){
53 | mScore = 0;
54 | mNumShips = 3;
55 | // Don't want to be drawing objects
56 | // while deSpawnReSpawn is
57 | // clearing them and spawning them again
58 | stopDrawing();
59 | gameStarter.deSpawnReSpawn();
60 | resume();
61 |
62 | // Now we can draw again
63 | startDrawing();
64 | }
65 |
66 |
67 | void loseLife(SoundEngine se){
68 | mNumShips--;
69 | se.playPlayerExplode();
70 | if(mNumShips == 0){
71 | pause();
72 | endGame();
73 | }
74 | }
75 |
76 | int getNumShips(){
77 | return mNumShips;
78 | }
79 |
80 | void increaseScore(){
81 | mScore++;
82 | }
83 |
84 | int getScore(){
85 | return mScore;
86 | }
87 |
88 | int getHighScore(){
89 | return mHighScore;
90 | }
91 |
92 | void pause(){
93 | mPaused = true;
94 | }
95 |
96 | void resume(){
97 | mGameOver = false;
98 | mPaused = false;
99 | }
100 |
101 | void stopEverything(){
102 | mPaused = true;
103 | mGameOver = true;
104 | mThreadRunning = false;
105 | }
106 |
107 | boolean getThreadRunning(){
108 | return mThreadRunning;
109 | }
110 |
111 | void startThread(){
112 | mThreadRunning = true;
113 | }
114 |
115 | private void stopDrawing(){
116 | mDrawing = false;
117 | }
118 |
119 | private void startDrawing(){
120 | mDrawing = true;
121 | }
122 |
123 | boolean getDrawing() {
124 | return mDrawing;
125 | }
126 |
127 | boolean getPaused(){
128 | return mPaused;
129 | }
130 |
131 | boolean getGameOver(){
132 | return mGameOver;
133 | }
134 |
135 |
136 |
137 | }
--------------------------------------------------------------------------------
/Chapter 21/java/GraphicsComponent.java:
--------------------------------------------------------------------------------
1 | package com.gamecodeschool.scrollingshooter;
2 |
3 | import android.content.Context;
4 | import android.graphics.Canvas;
5 | import android.graphics.Paint;
6 | import android.graphics.PointF;
7 |
8 | interface GraphicsComponent {
9 |
10 | void initialize(Context c,
11 | ObjectSpec s,
12 | PointF screensize);
13 |
14 | void draw(Canvas canvas,
15 | Paint paint,
16 | Transform t);
17 | }
18 |
--------------------------------------------------------------------------------
/Chapter 21/java/InputComponent.java:
--------------------------------------------------------------------------------
1 | package com.gamecodeschool.scrollingshooter;
2 |
3 | interface InputComponent {
4 |
5 | void setTransform(Transform t);
6 | }
7 |
8 |
--------------------------------------------------------------------------------
/Chapter 21/java/InputObserver.java:
--------------------------------------------------------------------------------
1 | package com.gamecodeschool.scrollingshooter;
2 |
3 | import android.graphics.Rect;
4 | import android.view.MotionEvent;
5 | import java.util.ArrayList;
6 |
7 | interface InputObserver {
8 |
9 | void handleInput(MotionEvent event, GameState gs,
10 | ArrayList controls);
11 | }
12 |
--------------------------------------------------------------------------------
/Chapter 21/java/LaserMovementComponent.java:
--------------------------------------------------------------------------------
1 | package com.gamecodeschool.scrollingshooter;
2 |
3 | import android.graphics.PointF;
4 |
5 | class LaserMovementComponent implements MovementComponent {
6 |
7 | @Override
8 | public boolean move(long fps,
9 | Transform t,
10 | Transform playerTransform) {
11 |
12 | // Laser can only travel two screen widths
13 | float range = t.getmScreenSize().x * 2;
14 |
15 | // Where is the laser
16 | PointF location = t.getLocation();
17 |
18 | // How fast is it going
19 | float speed = t.getSpeed();
20 |
21 | if(t.headingRight()){
22 | location.x += speed / fps;
23 | }
24 | else if(t.headingLeft()){
25 | location.x -= speed / fps;
26 | }
27 |
28 | // Has the laser gone out of range
29 | if(location.x < - range || location.x > range){
30 | // disable the laser
31 | return false;
32 | }
33 |
34 | t.updateCollider();
35 |
36 |
37 | return true;
38 | }
39 | }
40 |
--------------------------------------------------------------------------------
/Chapter 21/java/LaserSpawnComponent.java:
--------------------------------------------------------------------------------
1 | package com.gamecodeschool.scrollingshooter;
2 |
3 | import android.graphics.PointF;
4 |
5 | class LaserSpawnComponent implements SpawnComponent {
6 |
7 | @Override
8 | public void spawn(Transform playerTransform,
9 | Transform t) {
10 |
11 | PointF startPosition =
12 | playerTransform.getFiringLocation(t.getSize().x);
13 |
14 | t.setLocation((int)startPosition.x, (int)startPosition.y);
15 |
16 | if(playerTransform.getFacingRight()){
17 | t.headRight();
18 | }
19 | else{
20 | t.headLeft();
21 | }
22 |
23 |
24 | }
25 | }
26 |
27 |
--------------------------------------------------------------------------------
/Chapter 21/java/Level.java:
--------------------------------------------------------------------------------
1 | package com.gamecodeschool.scrollingshooter;
2 |
3 | import android.content.Context;
4 | import android.graphics.PointF;
5 |
6 | import java.util.ArrayList;
7 |
8 | class Level {
9 |
10 | // Keep track of specific types
11 | public static final int BACKGROUND_INDEX = 0;
12 | public static final int PLAYER_INDEX = 1;
13 | public static final int FIRST_PLAYER_LASER = 2;
14 | public static final int LAST_PLAYER_LASER = 4;
15 | public static int mNextPlayerLaser;
16 | public static final int FIRST_ALIEN = 5;
17 | public static final int SECOND_ALIEN = 6;
18 | public static final int THIRD_ALIEN = 7;
19 | public static final int FOURTH_ALIEN = 8;
20 | public static final int FIFTH_ALIEN = 9;
21 | public static final int SIXTH_ALIEN = 10;
22 | public static final int LAST_ALIEN = 10;
23 | public static final int FIRST_ALIEN_LASER = 11;
24 | public static final int LAST_ALIEN_LASER = 15;
25 | public static int mNextAlienLaser;
26 |
27 | // This will hold all the instances of GameObject
28 | private ArrayList objects;
29 | public Level(Context context,
30 | PointF mScreenSize,
31 | GameEngine ge){
32 |
33 | objects = new ArrayList<>();
34 | GameObjectFactory factory = new GameObjectFactory(
35 | context, mScreenSize, ge);
36 |
37 | buildGameObjects(factory);
38 | }
39 |
40 | ArrayList buildGameObjects(
41 | GameObjectFactory factory){
42 |
43 | objects.clear();
44 | objects.add(BACKGROUND_INDEX, factory
45 | .create(new BackgroundSpec()));
46 |
47 | objects.add(PLAYER_INDEX, factory
48 | .create(new PlayerSpec()));
49 |
50 | // Spawn the player's lasers
51 | for (int i = FIRST_PLAYER_LASER;
52 | i != LAST_PLAYER_LASER + 1; i++) {
53 |
54 | objects.add(i, factory
55 | .create(new PlayerLaserSpec()));
56 | }
57 |
58 | mNextPlayerLaser = FIRST_PLAYER_LASER;
59 |
60 | // Create some aliens
61 | objects.add(FIRST_ALIEN, factory
62 | .create(new AlienChaseSpec()));
63 | objects.add(SECOND_ALIEN, factory
64 | .create(new AlienPatrolSpec()));
65 | objects.add(THIRD_ALIEN, factory
66 | .create(new AlienPatrolSpec()));
67 | objects.add(FOURTH_ALIEN, factory
68 | .create(new AlienChaseSpec()));
69 | objects.add(FIFTH_ALIEN, factory
70 | .create(new AlienDiverSpec()));
71 | objects.add(SIXTH_ALIEN, factory
72 | .create(new AlienDiverSpec()));
73 |
74 | // Create some alien lasers
75 | for (int i = FIRST_ALIEN_LASER; i != LAST_ALIEN_LASER + 1; i++) {
76 | objects.add(i, factory
77 | .create(new AlienLaserSpec()));
78 | }
79 | mNextAlienLaser = FIRST_ALIEN_LASER;
80 |
81 |
82 | return objects;
83 | }
84 |
85 | ArrayList getGameObjects(){
86 | return objects;
87 | }
88 |
89 |
90 | }
91 |
--------------------------------------------------------------------------------
/Chapter 21/java/MovementComponent.java:
--------------------------------------------------------------------------------
1 | package com.gamecodeschool.scrollingshooter;
2 |
3 | interface MovementComponent {
4 |
5 | boolean move(long fps,
6 | Transform t,
7 | Transform playerTransform);
8 | }
9 |
--------------------------------------------------------------------------------
/Chapter 21/java/ObjectSpec.java:
--------------------------------------------------------------------------------
1 | package com.gamecodeschool.scrollingshooter;
2 |
3 | import android.graphics.PointF;
4 |
5 | abstract class ObjectSpec {
6 |
7 | private String mTag;
8 | private String mBitmapName;
9 | private float mSpeed;
10 | private PointF mSizeScale;
11 | private String[] mComponents;
12 |
13 | ObjectSpec(String tag, String bitmapName,
14 | float speed, PointF relativeScale,
15 | String[] components) {
16 |
17 | mTag = tag;
18 | mBitmapName = bitmapName;
19 | mSpeed = speed;
20 | mSizeScale = relativeScale;
21 | mComponents = components;
22 | }
23 |
24 | String getTag() {
25 | return mTag;
26 | }
27 |
28 | String getBitmapName() {
29 | return mBitmapName;
30 | }
31 |
32 | float getSpeed() {
33 | return mSpeed;
34 | }
35 |
36 | PointF getScale() {
37 | return mSizeScale;
38 | }
39 |
40 | String[] getComponents() {
41 | return mComponents;
42 | }
43 | }
44 |
--------------------------------------------------------------------------------
/Chapter 21/java/Particle.java:
--------------------------------------------------------------------------------
1 | package com.gamecodeschool.scrollingshooter;
2 |
3 | import android.graphics.PointF;
4 |
5 | class Particle {
6 |
7 | PointF mVelocity;
8 | PointF mPosition;
9 |
10 | Particle(PointF direction)
11 | {
12 | mVelocity = new PointF();
13 | mPosition = new PointF();
14 |
15 | // Determine the direction
16 | mVelocity.x = direction.x;
17 | mVelocity.y = direction.y;
18 |
19 | }
20 |
21 | void update()
22 | {
23 | // Move the particle
24 | mPosition.x += mVelocity.x;
25 | mPosition.y += mVelocity.y;
26 | }
27 |
28 | void setPosition(PointF position)
29 | {
30 | mPosition.x = position.x;
31 | mPosition.y = position.y;
32 | }
33 |
34 | PointF getPosition()
35 | {
36 | return mPosition;
37 | }
38 |
39 | }
40 |
41 |
--------------------------------------------------------------------------------
/Chapter 21/java/ParticleSystem.java:
--------------------------------------------------------------------------------
1 | package com.gamecodeschool.scrollingshooter;
2 |
3 | import android.graphics.Canvas;
4 | import android.graphics.Paint;
5 | import android.graphics.PointF;
6 |
7 | import java.util.ArrayList;
8 | import java.util.Random;
9 |
10 | class ParticleSystem {
11 |
12 | float mDuration;
13 |
14 | ArrayList mParticles;
15 | Random random = new Random();
16 | boolean mIsRunning = false;
17 |
18 | void init(int numParticles){
19 |
20 | mParticles = new ArrayList<>();
21 | // Create the particles
22 |
23 | for (int i = 0; i < numParticles; i++) {
24 | float angle = (random.nextInt(360)) ;
25 | angle = angle * 3.14f / 180.f;
26 | float speed = (random.nextInt(20)+1);
27 |
28 | PointF direction;
29 |
30 | direction = new PointF((float)Math.cos(angle) * speed,
31 | (float)Math.sin(angle) * speed);
32 |
33 | mParticles.add(new Particle(direction));
34 | }
35 | }
36 | void update(long fps){
37 |
38 | mDuration -= (1f/fps);
39 |
40 | for(Particle p : mParticles){
41 | p.update();
42 | }
43 |
44 | if (mDuration < 0)
45 | {
46 | mIsRunning = false;
47 | }
48 | }
49 |
50 | void emitParticles(PointF startPosition){
51 |
52 | mIsRunning = true;
53 | mDuration = 1f;
54 |
55 | for(Particle p : mParticles){
56 | p.setPosition(startPosition);
57 | }
58 | }
59 |
60 | void draw(Canvas canvas, Paint paint){
61 |
62 | for (Particle p : mParticles) {
63 |
64 | paint.setARGB(255,
65 | random.nextInt(256),
66 | random.nextInt(256),
67 | random.nextInt(256));
68 |
69 | // Uncomment the next line to have plain white particles
70 | //paint.setColor(Color.argb(255,255,255,255));
71 | canvas.drawRect(p.getPosition().x,
72 | p.getPosition().y,
73 | p.getPosition().x+25,
74 | p.getPosition().y+25, paint);
75 | }
76 | }
77 | }
78 |
79 |
--------------------------------------------------------------------------------
/Chapter 21/java/PhysicsEngine.java:
--------------------------------------------------------------------------------
1 | package com.gamecodeschool.scrollingshooter;
2 |
3 | import android.graphics.PointF;
4 | import android.graphics.RectF;
5 |
6 | import java.util.ArrayList;
7 |
8 | class PhysicsEngine {
9 |
10 | // This signature and much more will
11 | //change later in the project
12 | boolean update(long fps, ArrayList objects,
13 | GameState gs, SoundEngine se,
14 | ParticleSystem ps){
15 |
16 | // Update all the GameObjects
17 | for (GameObject object : objects) {
18 | if (object.checkActive()) {
19 | object.update(fps, objects .get(Level.PLAYER_INDEX)
20 | .getTransform());
21 | }
22 | }
23 |
24 | if(ps.mIsRunning){
25 | ps.update(fps);
26 | }
27 |
28 | return detectCollisions(gs, objects, se, ps);
29 | }
30 |
31 |
32 | // Collision detection method will go here
33 | private boolean detectCollisions(
34 | GameState mGameState,
35 | ArrayList objects,
36 | SoundEngine se,
37 | ParticleSystem ps ){
38 |
39 | boolean playerHit = false;
40 | for(GameObject go1 : objects) {
41 |
42 | if(go1.checkActive()){
43 | // The ist object is active
44 | // so worth checking
45 |
46 | for(GameObject go2 : objects) {
47 |
48 | if(go2.checkActive()){
49 |
50 | // The 2nd object is active
51 | // so worth checking
52 | if(RectF.intersects(
53 | go1.getTransform().getCollider(),
54 | go2.getTransform().getCollider())){
55 |
56 | // switch goes here
57 | // There has been a collision
58 | // - but does it matter
59 | switch (go1.getTag() + " with " + go2.getTag()){
60 | case "Player with Alien Laser":
61 | playerHit = true;
62 | mGameState.loseLife(se);
63 |
64 | break;
65 |
66 | case "Player with Alien":
67 | playerHit = true;
68 | mGameState.loseLife(se);
69 |
70 | break;
71 |
72 | case "Player Laser with Alien":
73 | mGameState.increaseScore();
74 | // Respawn the alien
75 | ps.emitParticles(
76 | new PointF(
77 | go2.getTransform().getLocation().x,
78 | go2.getTransform().getLocation().y
79 |
80 | )
81 | );
82 | go2.setInactive();
83 | go2.spawn(objects.get(Level
84 | .PLAYER_INDEX).getTransform());
85 |
86 | go1.setInactive();
87 | se.playAlienExplode();
88 |
89 | break;
90 |
91 | default:
92 | break;
93 | }
94 |
95 |
96 | }
97 | }
98 | }
99 | }
100 | }
101 | return playerHit;
102 | }
103 |
104 |
105 | }
106 |
107 |
--------------------------------------------------------------------------------
/Chapter 21/java/PlayerInputComponent.java:
--------------------------------------------------------------------------------
1 | package com.gamecodeschool.scrollingshooter;
2 |
3 | import android.graphics.Rect;
4 | import android.view.MotionEvent;
5 |
6 | import java.util.ArrayList;
7 |
8 | class PlayerInputComponent implements InputComponent,
9 | InputObserver {
10 |
11 | private Transform mTransform;
12 | private PlayerLaserSpawner mPLS;
13 |
14 | PlayerInputComponent(GameEngine ger) {
15 |
16 | ger.addObserver(this);
17 | mPLS = ger;
18 |
19 | }
20 |
21 | @Override
22 | public void setTransform(Transform transform) {
23 | mTransform = transform;
24 |
25 | }
26 |
27 | // Required method of InputObserver
28 | // interface called from the onTouchEvent method
29 | @Override
30 | public void handleInput(MotionEvent event,
31 | GameState gameState,
32 | ArrayList buttons) {
33 |
34 | int i = event.getActionIndex();
35 | int x = (int) event.getX(i);
36 | int y = (int) event.getY(i);
37 |
38 | switch (event.getAction() & MotionEvent.ACTION_MASK) {
39 |
40 | case MotionEvent.ACTION_UP:
41 | if (buttons.get(HUD.UP).contains(x,y)
42 | || buttons.get(HUD.DOWN).contains(x,y)) {
43 |
44 | // Player has released either up or down
45 | mTransform.stopVertical();
46 | }
47 | break;
48 |
49 | case MotionEvent.ACTION_DOWN:
50 | if (buttons.get(HUD.UP).contains(x,y)) {
51 | // Player has pressed up
52 | mTransform.headUp();
53 | } else if (buttons.get(HUD.DOWN).contains(x,y)) {
54 | // Player has pressed down
55 | mTransform.headDown();
56 | } else if (buttons.get(HUD.FLIP).contains(x,y)) {
57 | // Player has released the flip button
58 | mTransform.flip();
59 | } else if (buttons.get(HUD.SHOOT).contains(x,y)) {
60 | mPLS.spawnPlayerLaser(mTransform);
61 | }
62 | break;
63 |
64 | case MotionEvent.ACTION_POINTER_UP:
65 | if (buttons.get(HUD.UP).contains(x, y)
66 | ||
67 | buttons.get(HUD.DOWN).contains(x, y)) {
68 |
69 | // Player has released either up or down
70 | mTransform.stopVertical();
71 | }
72 | break;
73 |
74 | case MotionEvent.ACTION_POINTER_DOWN:
75 | if (buttons.get(HUD.UP).contains(x, y)) {
76 | // Player has pressed up
77 | mTransform.headUp();
78 | } else if (buttons.get(HUD.DOWN).contains(x, y)) {
79 | // Player has pressed down
80 | mTransform.headDown();
81 | } else if (buttons.get(HUD.FLIP).contains(x, y)) {
82 | // Player has released the flip button
83 | mTransform.flip();
84 | } else if (buttons.get(HUD.SHOOT).contains(x, y)) {
85 | mPLS.spawnPlayerLaser(mTransform);
86 | }
87 | break;
88 | }
89 |
90 |
91 | }
92 | }
93 |
--------------------------------------------------------------------------------
/Chapter 21/java/PlayerLaserSpawner.java:
--------------------------------------------------------------------------------
1 | package com.gamecodeschool.scrollingshooter;
2 |
3 | public interface PlayerLaserSpawner {
4 | boolean spawnPlayerLaser(Transform transform);
5 | }
6 |
--------------------------------------------------------------------------------
/Chapter 21/java/PlayerLaserSpec.java:
--------------------------------------------------------------------------------
1 | package com.gamecodeschool.scrollingshooter;
2 |
3 | import android.graphics.PointF;
4 |
5 | class PlayerLaserSpec extends ObjectSpec {
6 | // This is all the unique specifications
7 | // for a player laser
8 | private static final String tag = "Player Laser";
9 | private static final String bitmapName = "player_laser";
10 | private static final float speed = .65f;
11 | private static final PointF relativeScale =
12 | new PointF(8f, 160f);
13 |
14 | private static final String[] components = new String [] {
15 | "StdGraphicsComponent",
16 | "LaserMovementComponent",
17 | "LaserSpawnComponent"};
18 |
19 | PlayerLaserSpec(){
20 | super(tag, bitmapName,
21 | speed, relativeScale,
22 | components);
23 | }
24 | }
25 |
--------------------------------------------------------------------------------
/Chapter 21/java/PlayerMovementComponent.java:
--------------------------------------------------------------------------------
1 | package com.gamecodeschool.scrollingshooter;
2 |
3 | import android.graphics.PointF;
4 |
5 | class PlayerMovementComponent implements MovementComponent {
6 |
7 | @Override
8 | public boolean move(long fps, Transform t,
9 | Transform playerTransform){
10 | // How high is the screen?
11 | float screenHeight = t.getmScreenSize().y;
12 | // Where is the player?
13 | PointF location = t.getLocation();
14 | // How fast is it going
15 | float speed = t.getSpeed();
16 | // How tall is the ship
17 | float height = t.getObjectHeight();
18 |
19 | // Move the ship up or down if needed
20 | if(t.headingDown()){
21 | location.y += speed / fps;
22 | }
23 | else if(t.headingUp()){
24 | location.y -= speed / fps;
25 | }
26 |
27 | // Make sure the ship can't go off the screen
28 | if(location.y > screenHeight - height){
29 | location.y = screenHeight - height;
30 | }
31 | else if(location.y < 0){
32 | location.y = 0;
33 | }
34 |
35 | // Update the collider
36 | t.updateCollider();
37 |
38 |
39 | return true;
40 | }
41 | }
42 |
--------------------------------------------------------------------------------
/Chapter 21/java/PlayerSpawnComponent.java:
--------------------------------------------------------------------------------
1 | package com.gamecodeschool.scrollingshooter;
2 |
3 | class PlayerSpawnComponent implements SpawnComponent {
4 |
5 | @Override
6 | public void spawn(Transform playerTransform, Transform t) {
7 |
8 | // Spawn in the centre of the screen
9 | t.setLocation(
10 | t.getmScreenSize().x/2,
11 | t.getmScreenSize().y/2);
12 |
13 |
14 | }
15 | }
16 |
17 |
--------------------------------------------------------------------------------
/Chapter 21/java/PlayerSpec.java:
--------------------------------------------------------------------------------
1 | package com.gamecodeschool.scrollingshooter;
2 |
3 | import android.graphics.PointF;
4 |
5 | class PlayerSpec extends ObjectSpec {
6 | // This is all the unique specifications
7 | // for a player
8 | private static final String tag = "Player";
9 | private static final String bitmapName = "player_ship";
10 | private static final float speed = 1f;
11 | private static final PointF relativeScale =
12 | new PointF(15f, 15f);
13 |
14 | private static final String[] components = new String [] {
15 | "PlayerInputComponent",
16 | "StdGraphicsComponent",
17 | "PlayerMovementComponent",
18 | "PlayerSpawnComponent"};
19 |
20 | PlayerSpec() {
21 | super(tag, bitmapName,
22 | speed, relativeScale,
23 | components);
24 | }
25 | }
26 |
27 |
--------------------------------------------------------------------------------
/Chapter 21/java/Renderer.java:
--------------------------------------------------------------------------------
1 | package com.gamecodeschool.scrollingshooter;
2 |
3 | import android.graphics.Canvas;
4 | import android.graphics.Color;
5 | import android.graphics.Paint;
6 | import android.view.SurfaceHolder;
7 | import android.view.SurfaceView;
8 |
9 | import java.util.ArrayList;
10 |
11 | class Renderer {
12 | private Canvas mCanvas;
13 | private SurfaceHolder mSurfaceHolder;
14 | private Paint mPaint;
15 |
16 | Renderer(SurfaceView sh){
17 | mSurfaceHolder = sh.getHolder();
18 | mPaint = new Paint();
19 | }
20 |
21 | void draw(ArrayList objects, GameState gs,
22 | HUD hud, ParticleSystem ps) {
23 |
24 | if (mSurfaceHolder.getSurface().isValid()) {
25 | mCanvas = mSurfaceHolder.lockCanvas();
26 | mCanvas.drawColor(Color.argb(255, 0, 0, 0));
27 |
28 | if (gs.getDrawing()) {
29 | // Draw all the game objects here
30 | for (GameObject object : objects) {
31 | if(object.checkActive()) {
32 | object.draw(mCanvas, mPaint);
33 | }
34 | }
35 |
36 | }
37 |
38 | if(gs.getGameOver()) {
39 | // Draw just a background graphic here
40 | objects.get(Level.BACKGROUND_INDEX)
41 | .draw(mCanvas, mPaint);
42 |
43 | }
44 |
45 | // Draw a particle system explosion here
46 | if(ps.mIsRunning){
47 | ps.draw(mCanvas, mPaint);
48 | }
49 |
50 |
51 | // Now we draw the HUD on top of everything else
52 | hud.draw(mCanvas, mPaint, gs);
53 |
54 | mSurfaceHolder.unlockCanvasAndPost(mCanvas);
55 | }
56 | }
57 |
58 | }
59 |
--------------------------------------------------------------------------------
/Chapter 21/java/SoundEngine.java:
--------------------------------------------------------------------------------
1 | package com.gamecodeschool.scrollingshooter;
2 |
3 | import android.content.Context;
4 | import android.content.res.AssetFileDescriptor;
5 | import android.content.res.AssetManager;
6 | import android.media.AudioAttributes;
7 | import android.media.AudioManager;
8 | import android.media.SoundPool;
9 | import android.os.Build;
10 |
11 | import java.io.IOException;
12 |
13 | class SoundEngine {
14 | // for playing sound effects
15 | private SoundPool mSP;
16 | private int mShoot_ID = -1;
17 | private int mAlien_Explode_ID = -1;
18 | private int mPlayer_explode_ID = -1;
19 |
20 | SoundEngine(Context c){
21 | // Initialize the SoundPool
22 | if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
23 | AudioAttributes audioAttributes =
24 | new AudioAttributes.Builder()
25 | .setUsage(AudioAttributes.USAGE_MEDIA)
26 | .setContentType(AudioAttributes
27 | .CONTENT_TYPE_SONIFICATION)
28 | .build();
29 |
30 | mSP = new SoundPool.Builder()
31 | .setMaxStreams(5)
32 | .setAudioAttributes(audioAttributes)
33 | .build();
34 | } else {
35 | mSP = new SoundPool(5, AudioManager.STREAM_MUSIC, 0);
36 | }
37 | try {
38 | AssetManager assetManager = c.getAssets();
39 | AssetFileDescriptor descriptor;
40 |
41 | // Prepare the sounds in memory
42 | descriptor = assetManager.openFd("shoot.ogg");
43 | mShoot_ID = mSP.load(descriptor, 0);
44 |
45 | descriptor = assetManager.openFd("alien_explosion.ogg");
46 | mAlien_Explode_ID = mSP.load(descriptor, 0);
47 |
48 | descriptor =
49 | assetManager.openFd("player_explosion.ogg");
50 |
51 | mPlayer_explode_ID = mSP.load(descriptor, 0);
52 |
53 | } catch (IOException e) {
54 | // Error
55 | }
56 |
57 | }
58 |
59 | void playShoot(){
60 | mSP.play(mShoot_ID,1, 1, 0, 0, 1);
61 | }
62 |
63 | void playAlienExplode(){
64 | mSP.play(mAlien_Explode_ID,1, 1, 0, 0, 1);
65 | }
66 |
67 | void playPlayerExplode(){
68 | mSP.play(mPlayer_explode_ID,1, 1, 0, 0, 1);
69 | }
70 |
71 |
72 | }
73 |
--------------------------------------------------------------------------------
/Chapter 21/java/SpawnComponent.java:
--------------------------------------------------------------------------------
1 | package com.gamecodeschool.scrollingshooter;
2 |
3 | interface SpawnComponent {
4 | void spawn(Transform playerTransform, Transform t);
5 |
6 | }
--------------------------------------------------------------------------------
/Chapter 21/java/StdGraphicsComponent.java:
--------------------------------------------------------------------------------
1 | package com.gamecodeschool.scrollingshooter;
2 |
3 | import android.content.Context;
4 | import android.graphics.Bitmap;
5 | import android.graphics.BitmapFactory;
6 | import android.graphics.Canvas;
7 | import android.graphics.Matrix;
8 | import android.graphics.Paint;
9 | import android.graphics.PointF;
10 |
11 | class StdGraphicsComponent implements GraphicsComponent {
12 |
13 | private Bitmap mBitmap;
14 | private Bitmap mBitmapReversed;
15 |
16 | @Override
17 | public void initialize(Context context,
18 | ObjectSpec spec,
19 | PointF objectSize){
20 | // Make a resource id out of the string of the file name
21 | int resID = context.getResources()
22 | .getIdentifier(spec.getBitmapName(),
23 | "drawable",
24 | context.getPackageName());
25 |
26 | // Load the bitmap using the id
27 | mBitmap = BitmapFactory.decodeResource(
28 | context.getResources(), resID);
29 |
30 | // Resize the bitmap
31 | mBitmap = Bitmap
32 | .createScaledBitmap(mBitmap,
33 | (int)objectSize.x,
34 | (int)objectSize.y,
35 | false);
36 |
37 | // Create a mirror image of the bitmap if needed
38 | Matrix matrix = new Matrix();
39 | matrix.setScale(-1, 1);
40 | mBitmapReversed = Bitmap.createBitmap(mBitmap,
41 | 0, 0,
42 | mBitmap.getWidth(),
43 | mBitmap.getHeight(),
44 | matrix, true);
45 | }
46 |
47 | @Override
48 | public void draw(Canvas canvas,
49 | Paint paint,
50 | Transform t) {
51 |
52 | if(t.getFacingRight())
53 | canvas.drawBitmap(mBitmap,
54 | t.getLocation().x,
55 | t.getLocation().y,
56 | paint);
57 |
58 | else
59 | canvas.drawBitmap(mBitmapReversed,
60 | t.getLocation().x,
61 | t.getLocation().y,
62 | paint);
63 |
64 |
65 | }
66 | }
67 |
--------------------------------------------------------------------------------
/Chapter 21/java/UIController.java:
--------------------------------------------------------------------------------
1 | package com.gamecodeschool.scrollingshooter;
2 | import android.graphics.Point;
3 | import android.graphics.Rect;
4 | import android.view.MotionEvent;
5 |
6 | import java.util.ArrayList;
7 |
8 | class UIController implements InputObserver {
9 |
10 | public UIController(GameEngineBroadcaster b){
11 | b.addObserver(this);
12 | }
13 |
14 | @Override
15 | public void handleInput(MotionEvent event, GameState gameState, ArrayList buttons) {
16 |
17 | int i = event.getActionIndex();
18 | int x = (int) event.getX(i);
19 | int y = (int) event.getY(i);
20 |
21 | int eventType = event.getAction() & MotionEvent.ACTION_MASK;
22 |
23 | if(eventType == MotionEvent.ACTION_UP ||
24 | eventType == MotionEvent.ACTION_POINTER_UP) {
25 |
26 |
27 | if (buttons.get(HUD.PAUSE).contains(x, y)){
28 | // Player pressed the pause button
29 | // Respond differently depending
30 | // upon the game's state
31 |
32 | // If the game is not paused
33 | if (!gameState.getPaused()) {
34 | // Pause the game
35 | gameState.pause();
36 | }
37 |
38 | // If game is over start a new game
39 | else if (gameState.getGameOver()) {
40 |
41 | gameState.startNewGame();
42 | }
43 |
44 | // Paused and not game over
45 | else if (gameState.getPaused()
46 | && !gameState.getGameOver()) {
47 |
48 | gameState.resume();
49 | }
50 | }
51 | }
52 | }
53 |
54 | }
55 |
--------------------------------------------------------------------------------
/LICENSE:
--------------------------------------------------------------------------------
1 | MIT License
2 |
3 | Copyright (c) 2021 Packt
4 |
5 | Permission is hereby granted, free of charge, to any person obtaining a copy
6 | of this software and associated documentation files (the "Software"), to deal
7 | in the Software without restriction, including without limitation the rights
8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9 | copies of the Software, and to permit persons to whom the Software is
10 | furnished to do so, subject to the following conditions:
11 |
12 | The above copyright notice and this permission notice shall be included in all
13 | copies or substantial portions of the Software.
14 |
15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21 | SOFTWARE.
22 |
--------------------------------------------------------------------------------