diff --git a/app/.DS_Store b/app/.DS_Store new file mode 100644 index 0000000000000000000000000000000000000000..07c07a7402284903c2fd221e2d57358eb43a3034 Binary files /dev/null and b/app/.DS_Store differ diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml index eb1b9d482d24410f51ffcd53e98e2deba36f3ece..0b049e65611136a3c348b13c652b4e7b8ab67140 100644 --- a/app/src/main/AndroidManifest.xml +++ b/app/src/main/AndroidManifest.xml @@ -11,6 +11,9 @@ android:supportsRtl="true" android:theme="@style/Theme.8bitInvader" tools:targetApi="31"> + diff --git a/app/src/main/java/com/example/a8_bitinvader/Background.java b/app/src/main/java/com/example/a8_bitinvader/Background.java new file mode 100644 index 0000000000000000000000000000000000000000..862f29dbc7378b4df91c81ed69745697b58349b2 --- /dev/null +++ b/app/src/main/java/com/example/a8_bitinvader/Background.java @@ -0,0 +1,20 @@ +package com.example.a8_bitinvader; + +import android.content.res.Resources; +import android.graphics.Bitmap; +import android.graphics.BitmapFactory; + +public class Background { + + int xPos = 0, yPos = 0; + Bitmap background; + + /* + * Creates background from 'background1.jpeg' in res/drawable directory + */ + Background(int screenWidth, int screenHeight, Resources res) { + background = BitmapFactory.decodeResource(res, R.drawable.background); + background = Bitmap.createScaledBitmap(background, screenWidth, screenHeight, false); + } + +} diff --git a/app/src/main/java/com/example/a8_bitinvader/GameActivity.java b/app/src/main/java/com/example/a8_bitinvader/GameActivity.java new file mode 100644 index 0000000000000000000000000000000000000000..0cc2d6a695b8c1e6623faedbce5b30b490822a0e --- /dev/null +++ b/app/src/main/java/com/example/a8_bitinvader/GameActivity.java @@ -0,0 +1,40 @@ +package com.example.a8_bitinvader; + +import androidx.appcompat.app.AppCompatActivity; +import android.os.Bundle; + +import android.graphics.Point; // necessary to get ScreenWidth and ScreenHeight +import android.view.WindowManager; + +public class GameActivity extends AppCompatActivity { + + private GameView gameView; + + @Override + protected void onCreate(Bundle savedInstanceState) { + super.onCreate(savedInstanceState); + + // puts app into fullscreen when GameActivity is running + getWindow().setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN, WindowManager.LayoutParams.FLAG_FULLSCREEN); + + + Point point = new Point(); + getWindowManager().getDefaultDisplay().getSize(point); + + gameView = new GameView(this, point.x, point.y); + + setContentView(gameView); + } + + @Override + protected void onPause() { + super.onPause(); + gameView.pause(); + } + + @Override + protected void onResume() { + super.onResume(); + gameView.resume(); + } +} diff --git a/app/src/main/java/com/example/a8_bitinvader/GameView.java b/app/src/main/java/com/example/a8_bitinvader/GameView.java new file mode 100644 index 0000000000000000000000000000000000000000..0ab2ab625dca4812ecbf57cd3e49eb13196f86f8 --- /dev/null +++ b/app/src/main/java/com/example/a8_bitinvader/GameView.java @@ -0,0 +1,111 @@ +package com.example.a8_bitinvader; + +import android.content.Context; +import android.view.SurfaceView; +import android.graphics.Canvas; +import android.graphics.Paint; // necessary when drawing Bitmaps with Canvas objects + +public class GameView extends SurfaceView implements Runnable{ + + private Thread thread; + private boolean isRunning; + private int screenWidth, screenHeight; + private float screenRatioWidth, screenRatioHeight; + private Background background1, background2; + private Paint paint; + + public GameView(Context context, int screenWidth, int screenHeight) { + super(context); + + this.screenWidth = screenWidth; + this.screenHeight = screenHeight; + + screenRatioWidth = 1080f / screenWidth; + screenRatioHeight = 1920f / screenHeight; + + background1 = new Background(screenWidth, screenHeight, getResources()); + background2 = new Background(screenWidth, screenHeight, getResources()); + + background2.yPos = -screenHeight; + + paint = new Paint(); + } + + /* + * Continuously loops through update(), draw(), and sleep() if the app is running + * Overrides from Runnable class, which Thread automatically calls once resume() initializes said Thread + */ + @Override + public void run() { + + while(isRunning) { + update(); + draw(); + + // creates 30 millisecond delay in between draw() and update() + try { + Thread.sleep(30); + } catch (InterruptedException e) { + throw new RuntimeException(e); + } + } + } + + /* + * updates position of backgrounds. + * checks if either background is offscreen. If so, it places that background above the other + * giving the illusion of an infinitely moving background. + */ + private void update() { + background1.yPos += 5 * (int) screenRatioHeight; + background2.yPos += 5 * (int) screenRatioHeight; + + if(background1.yPos > screenHeight) { + background1.yPos = -screenHeight; + } + + if(background2.yPos > screenHeight) { + background2.yPos = -screenHeight; + } + } + + /* + * draws both backgrounds onto the screen given their initialized + */ + private void draw() { + if(getHolder().getSurface().isValid()){ + Canvas canvas = getHolder().lockCanvas(); + canvas.drawBitmap(background1.background, background1.xPos, background1.yPos, paint); + canvas.drawBitmap(background2.background, background2.xPos, background2.yPos, paint); + + getHolder().unlockCanvasAndPost(canvas); + } + } + + /* + * https://developer.android.com/reference/java/lang/Thread#start() + * initializes a thread and starts it, automatically calling the overridden run() method above. + */ + public void resume() { + + isRunning = true; + thread = new Thread(this); + thread.start(); + + } + + /* + * https://developer.android.com/reference/java/lang/Thread#join() + * waits for thread to die if game is paused + */ + public void pause() { + + try { + isRunning = false; + thread.join(); + } catch (InterruptedException e) { + throw new RuntimeException(e); + } + + } +} \ No newline at end of file diff --git a/app/src/main/java/com/example/a8_bitinvader/MainActivity.java b/app/src/main/java/com/example/a8_bitinvader/MainActivity.java index 0985510f8714ae9fc1ac5f19f606b47a52bbb225..76b509eb1757cc64efc4284ec855452557d18d4b 100644 --- a/app/src/main/java/com/example/a8_bitinvader/MainActivity.java +++ b/app/src/main/java/com/example/a8_bitinvader/MainActivity.java @@ -2,7 +2,9 @@ package com.example.a8_bitinvader; import androidx.appcompat.app.AppCompatActivity; +import android.content.Intent; import android.os.Bundle; +import android.view.View; public class MainActivity extends AppCompatActivity { @@ -10,5 +12,43 @@ public class MainActivity extends AppCompatActivity { protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); + + // Creates new Intent and starts GameActivity if 'play' is pressed on MainActivity screen. + findViewById(R.id.play).setOnClickListener(new View.OnClickListener() { + @Override + public void onClick(View view) { + startActivity(new Intent(MainActivity.this, GameActivity.class)); + } + }); + } + + @Override + protected void onStart() { + super.onStart(); + } + + @Override + protected void onResume() { + super.onResume(); + } + + @Override + protected void onPause() { + super.onPause(); + } + + @Override + protected void onStop() { + super.onStop(); + } + + @Override + protected void onDestroy() { + super.onDestroy(); + } + + @Override + protected void onRestart() { + super.onRestart(); } } \ No newline at end of file diff --git a/app/src/main/res/drawable/background.jpeg b/app/src/main/res/drawable/background.jpeg new file mode 100644 index 0000000000000000000000000000000000000000..62b70aa2b3d9f59132c499b61d33c69292e0c4df Binary files /dev/null and b/app/src/main/res/drawable/background.jpeg differ diff --git a/app/src/main/res/layout/activity_main.xml b/app/src/main/res/layout/activity_main.xml index 34078b96274433c0f3a8dd1a3665d1cfaac43449..0913d9cf6ab8f6fa8a350d8fecb077d373ac288d 100644 --- a/app/src/main/res/layout/activity_main.xml +++ b/app/src/main/res/layout/activity_main.xml @@ -1,7 +1,18 @@ - \ No newline at end of file + tools:context=".MainActivity"> + + + + \ No newline at end of file diff --git a/local.properties b/local.properties index 57adf34a81c345438a31567cdaab47d07f7ca7ef..662502f18976c148294add2336d3a3b094a5b090 100644 --- a/local.properties +++ b/local.properties @@ -1,10 +1,8 @@ -## This file is automatically generated by Android Studio. -# Do not modify this file -- YOUR CHANGES WILL BE ERASED! -# -# This file should *NOT* be checked into Version Control Systems, +## This file must *NOT* be checked into Version Control Systems, # as it contains information specific to your local configuration. # # Location of the SDK. This is only used by Gradle. # For customization when using a Version Control System, please read the # header note. -sdk.dir=/Users/krish/Library/Android/sdk \ No newline at end of file +#Tue Apr 11 22:33:32 EDT 2023 +sdk.dir=/Users/thomas/Library/Android/sdk