=UTF-8
diff --git a/.settings/org.eclipse.jdt.apt.core.prefs b/.settings/org.eclipse.jdt.apt.core.prefs
new file mode 100644
index 0000000..d4313d4
--- /dev/null
+++ b/.settings/org.eclipse.jdt.apt.core.prefs
@@ -0,0 +1,2 @@
+eclipse.preferences.version=1
+org.eclipse.jdt.apt.aptEnabled=false
diff --git a/.settings/org.eclipse.jdt.core.prefs b/.settings/org.eclipse.jdt.core.prefs
new file mode 100644
index 0000000..1b6e1ef
--- /dev/null
+++ b/.settings/org.eclipse.jdt.core.prefs
@@ -0,0 +1,9 @@
+eclipse.preferences.version=1
+org.eclipse.jdt.core.compiler.codegen.targetPlatform=1.8
+org.eclipse.jdt.core.compiler.compliance=1.8
+org.eclipse.jdt.core.compiler.problem.enablePreviewFeatures=disabled
+org.eclipse.jdt.core.compiler.problem.forbiddenReference=warning
+org.eclipse.jdt.core.compiler.problem.reportPreviewFeatures=ignore
+org.eclipse.jdt.core.compiler.processAnnotations=disabled
+org.eclipse.jdt.core.compiler.release=disabled
+org.eclipse.jdt.core.compiler.source=1.8
diff --git a/.settings/org.eclipse.m2e.core.prefs b/.settings/org.eclipse.m2e.core.prefs
new file mode 100644
index 0000000..f897a7f
--- /dev/null
+++ b/.settings/org.eclipse.m2e.core.prefs
@@ -0,0 +1,4 @@
+activeProfiles=
+eclipse.preferences.version=1
+resolveWorkspaceProjects=true
+version=1
diff --git a/README.md b/README.md
new file mode 100644
index 0000000..5db1d43
--- /dev/null
+++ b/README.md
@@ -0,0 +1,17 @@
+# DanmakuProject
+
+This is made for a school project. It uses SDL2 under Java using JNA library.
+The main bindings are from libjsdl which is an attempt to create an interface for SDL2 using JNA
+but it lacks documentation and demonstration (still a great project). Some SDL2_mixer bindings are
+also created using JNA, which is not part of the libjsdl. (see Audio.java)
+
+I hope this proves to be a good demonstration for using libjsdl and JNA.
+
+## Credits:
+* Furkan Mudanyalı (Code, planning, execution etc.)
+* graphLoom, (Music, assets)
+
+### Further Credits:
+* libjsdl contributors (especially shinedeveloper for a loot of bindings)
+* SDL2 contributors
+* SDL2_mixer contributors
\ No newline at end of file
diff --git a/assets/bullets/bullete-big.bmp b/assets/bullets/bullete-big.bmp
new file mode 100644
index 0000000..1c1fe77
Binary files /dev/null and b/assets/bullets/bullete-big.bmp differ
diff --git a/assets/bullets/bulletp-big.bmp b/assets/bullets/bulletp-big.bmp
new file mode 100644
index 0000000..d73a6d0
Binary files /dev/null and b/assets/bullets/bulletp-big.bmp differ
diff --git a/assets/bullets/bulletp.bmp b/assets/bullets/bulletp.bmp
new file mode 100644
index 0000000..6002cee
Binary files /dev/null and b/assets/bullets/bulletp.bmp differ
diff --git a/assets/enemies/guardian.bmp b/assets/enemies/guardian.bmp
new file mode 100644
index 0000000..5ec9116
Binary files /dev/null and b/assets/enemies/guardian.bmp differ
diff --git a/assets/enemies/guardianbig.bmp b/assets/enemies/guardianbig.bmp
new file mode 100644
index 0000000..51954c3
Binary files /dev/null and b/assets/enemies/guardianbig.bmp differ
diff --git a/assets/player.bmp b/assets/player.bmp
deleted file mode 100644
index f1851f2..0000000
Binary files a/assets/player.bmp and /dev/null differ
diff --git a/assets/shmap.bmp b/assets/shmap.bmp
index 96c7fc7..d7499d0 100644
Binary files a/assets/shmap.bmp and b/assets/shmap.bmp differ
diff --git a/assets/wallpaper.bmp b/assets/wallpaper.bmp
index b677e1c..710c8c2 100644
Binary files a/assets/wallpaper.bmp and b/assets/wallpaper.bmp differ
diff --git a/src/main/java/com/fmudanyali/Audio.java b/src/main/java/com/fmudanyali/Audio.java
index 750cec4..403b035 100644
--- a/src/main/java/com/fmudanyali/Audio.java
+++ b/src/main/java/com/fmudanyali/Audio.java
@@ -33,7 +33,7 @@ import javax.sound.sampled.AudioSystem;
/**
* Audio Class
*
- * This class is a native wrapper for SDL2_Mixer,
+ * This class is a native JNA wrapper for SDL2_Mixer,
* it also contains some additional methods
*
* @author Furkan Mudanyali
@@ -127,14 +127,21 @@ public class Audio {
public static int Mix_PlayChannel(int channel, Pointer chunk, int loops){
return Mix_PlayChannelTimed(channel, chunk, loops, -1);
}
+
// Methods
/**
+ * Returns WAV music length in milliseconds.
+ *
+ *
+ *
* Credits to mdma from stackoverflow
+ *
* https://stackoverflow.com/a/3009973
*
* @param filepath WAV file path
- * @return length in milliseconds
+ * @return length in milliseconds, -1 if can't
+ * open file.
*/
public static long getMusicLengthInMilliseconds(String filepath){
try {
diff --git a/src/main/java/com/fmudanyali/FileLoader.java b/src/main/java/com/fmudanyali/FileLoader.java
index 8040fca..794d059 100644
--- a/src/main/java/com/fmudanyali/FileLoader.java
+++ b/src/main/java/com/fmudanyali/FileLoader.java
@@ -21,10 +21,25 @@ import java.io.File;
import java.util.Objects;
/**
- * @param fileName filename to get path of
- * @return path to the asset in the assets folder.
+ *
File Loader Class
+ *
+ * A class that contains static methods for file path
+ * operations for SDL2. Since SDL2 cannot access the
+ * virtual filesystem inside the .jar package, SDL2 files
+ * must be kept in a seperate folder along with the .jar.
+ *
+ * @author Furkan Mudanyali
+ * @version 1.0.0
+ * @since 2021-12-01
*/
public class FileLoader {
+ /**
+ * Returns absolute path to the file from the assets folder.
+ *
+ * @param fileName filename to get path of
+ * @return path to the asset in the assets folder,
+ * null on any kind of I/O error.
+ */
public static String getFilePath(String fileName){
try{
String protocol = FileLoader.class.getResource("").getProtocol();
@@ -35,7 +50,7 @@ public class FileLoader {
}
return System.getProperty("user.dir") + "/assets/" + fileName;
} catch (Exception e){
- return "could not get filepath";
+ return null;
}
}
}
\ No newline at end of file
diff --git a/src/main/java/com/fmudanyali/Keyboard.java b/src/main/java/com/fmudanyali/Keyboard.java
index 7b1e2cc..baef431 100644
--- a/src/main/java/com/fmudanyali/Keyboard.java
+++ b/src/main/java/com/fmudanyali/Keyboard.java
@@ -20,13 +20,28 @@ package com.fmudanyali;
import static org.libsdl.api.keyboard.SdlKeyboard.*;
import com.sun.jna.ptr.ByteByReference;
+/**
+ * Keyboard Class
+ *
+ * A class to simplify keyboard functions.
+ *
+ * @author Furkan Mudanyali
+ * @version 1.0.0
+ * @since 2021-12-01
+ */
public class Keyboard {
+ // Basically array pointer
public static ByteByReference keyboard = new ByteByReference();
public static void getKeyboardState(){
keyboard = SDL_GetKeyboardState(null);
}
-
+ /**
+ * Checks if given index of the keyboard array is true or not.
+ *
+ * @param key Index of the key in the keyboard array.
+ * @return true if key is pressed, false if not.
+ */
public static boolean getKeyState(int key){
return keyboard.getPointer().getByte(key) == 1;
}
diff --git a/src/main/java/com/fmudanyali/Main.java b/src/main/java/com/fmudanyali/Main.java
index 29e0fb7..347aeea 100644
--- a/src/main/java/com/fmudanyali/Main.java
+++ b/src/main/java/com/fmudanyali/Main.java
@@ -21,23 +21,49 @@ import com.fmudanyali.scenes.*;
import java.util.Stack;
import org.libsdl.api.event.events.SDL_Event;
+/**
+ * Main Class
+ * This is the starting point of the application.
+ *
+ * @author Furkan Mudanyali
+ * @version 1.0.0
+ * @since 2021-12-01
+ */
public class Main {
public static SDL_Event e = new SDL_Event();
public static boolean exit = false;
public static Stack scenes = new Stack<>();
public static void main(String[] args) throws Exception{
+ /*
+ Restart JVM if on macOS and it hasn't been launched
+ with -XStartOnFirstThread arg. Needed for SDL to be
+ able to create a window and show it on macOS as macOS
+ ignores windows that are not opened by the first thread
+ of the application for safety measures. Took me days
+ to track the bug.
+ */
if (RestartJVM.restartJVM()) {
return;
}
+ // Open audio device with basic defaults.
Audio.Mix_OpenAudio(44100, Audio.MIX_DEFAULT_FORMAT, 2, 2048);
+ // Push main menu to the scenes stack.
scenes.push(new MainMenu());
+ // Each loop means a frame of the game.
while(!scenes.empty() && !exit){
+ // Calculate delta time, between last frame
+ // and this frame.
Time.Tick();
Keyboard.getKeyboardState();
+ // Call the loop function of the scene on the
+ // top of the scenes stack.
scenes.peek().loop();
}
+ // Exit is set to true manually to make sure the existing threads
+ // are stopped, not really necessary as System.exit should close
+ // those lingering threads but better be safe than sorry.
exit = true;
System.exit(0);
}
diff --git a/src/main/java/com/fmudanyali/Render.java b/src/main/java/com/fmudanyali/Render.java
index 7b91ea0..64a30e3 100644
--- a/src/main/java/com/fmudanyali/Render.java
+++ b/src/main/java/com/fmudanyali/Render.java
@@ -33,24 +33,50 @@ import static org.libsdl.api.hints.SdlHintsConst.*;
import static org.libsdl.api.hints.SdlHints.*;
import static org.libsdl.api.render.SdlRender.SDL_RenderSetLogicalSize;
+/**
+ * Render Class
+ * This class contains and initializes the SDL_Window and SDL_Renderer pointers,
+ * it also has a method to create a continuous background from given texture.
+ *
+ * @author Furkan Mudanyali
+ * @version 0.2.0
+ * @since 2021-12-01
+ */
public class Render {
public static SDL_Window window;
public static SDL_Renderer renderer;
public static int bgw, bgh;
+ // Initialize SDL_Window and SDL_Renderer
static {
+ // Create window
window = SDL_CreateWindow("DanmakuProject SDL2",
SDL_WINDOWPOS_CENTERED(), SDL_WINDOWPOS_CENTERED(),
WIDTH, HEIGHT, SDL_WINDOW_SHOWN | SDL_WINDOW_RESIZABLE | SDL_WINDOW_OPENGL);
+ // Hints for the renderer
SDL_SetHint(SDL_HINT_RENDER_DRIVER, "opengl");
SDL_SetHint(SDL_HINT_RENDER_SCALE_QUALITY, "0");
+ // Create renderer
renderer =
- SDL_CreateRenderer(Render.window, -1, SDL_RENDERER_ACCELERATED | SDL_RENDERER_PRESENTVSYNC);
+ SDL_CreateRenderer(window, -1, SDL_RENDERER_ACCELERATED | SDL_RENDERER_PRESENTVSYNC);
+ // Make content scale according to the window size while maintaining the aspect ratio.
SDL_RenderSetLogicalSize(renderer, Screen.WIDTH, Screen.HEIGHT);
}
+
+ /**
+ * Creates a new row x col texture
+ * from the given texture by stitching
+ * it together.
+ *
+ * @param renderer Renderer to be used
+ * @param texture Texture to be repeated
+ * @param cols How many columns of the texture
+ * @param rows How many rows of the texture
+ * @return
+ */
public static SDL_Texture createBackgroundFromTexture(
SDL_Renderer renderer, SDL_Texture texture, int cols, int rows
){
diff --git a/src/main/java/com/fmudanyali/RestartJVM.java b/src/main/java/com/fmudanyali/RestartJVM.java
index e81751a..9fdfb2b 100644
--- a/src/main/java/com/fmudanyali/RestartJVM.java
+++ b/src/main/java/com/fmudanyali/RestartJVM.java
@@ -25,10 +25,22 @@ import java.io.InputStreamReader;
import java.io.BufferedReader;
/**
- * Credits to kappa From
+ * RestartJVM Class
+ *
+ * Has a single function that restarts JVM on macOS
+ * if JVM is not launched with -XstartOnFirstThread arg
+ * and launches it with it.
+ *
+ *
+ *
+ * Credits to kappa from jvm-gaming.org
+ *
* https://jvm-gaming.org/t/starting-jvm-on-mac-with-xstartonfirstthread-programmatically/57547
+ *
+ * @author kappa
+ * @version 1.0.0
+ * @since 2016-08-26
*/
-
public class RestartJVM {
public static boolean restartJVM() {
diff --git a/src/main/java/com/fmudanyali/Screen.java b/src/main/java/com/fmudanyali/Screen.java
index b7b71e9..16d582d 100644
--- a/src/main/java/com/fmudanyali/Screen.java
+++ b/src/main/java/com/fmudanyali/Screen.java
@@ -27,6 +27,16 @@ import com.fmudanyali.characters.Player;
import static org.libsdl.api.render.SdlRender.*;
+/**
+ *
Screen Class
+ *
+ * This class contains information about the game screen
+ * It also has a method to set its background texture, and scroll it.
+ *
+ * @author Furkan Mudanyali
+ * @version 0.2.0
+ * @since 2021-12-08
+ */
public class Screen {
public static final int WIDTH = 960;
public static final int HEIGHT = 540;
@@ -38,6 +48,7 @@ public class Screen {
public static SDL_Texture tile, background, wallpaper;
public static SDL_Surface tempSurface;
+ // Calculate positions and load wallpaper image.
static {
canvas.x = 12;
canvas.y = 0;
@@ -54,6 +65,10 @@ public class Screen {
tempSurface = null;
}
+ /**
+ * Loads the given filepath to the background.
+ * @param filename file path of the image.
+ */
public static void makeBackground(String filename){
// Load tile
tempSurface = SDL_LoadBMP(FileLoader.getFilePath(filename));
@@ -64,6 +79,12 @@ public class Screen {
background = Render.createBackgroundFromTexture(Render.renderer, tile, 1, 2);
}
+ /**
+ * Scrolls the background vertically and horizontally.
+ * Horizontal scroll is based on the player position to
+ * create a parallax effect.
+ * @param player
+ */
public static void scroll(Player player){
canvas.y = Math.floorMod(canvas.y - (int)(Time.deltaTime * 0.1), Render.bgh - canvas.h);
canvas.x = (int)(12 + (player.position.x - 464)/13);
diff --git a/src/main/java/com/fmudanyali/Time.java b/src/main/java/com/fmudanyali/Time.java
index 803f086..df82df8 100644
--- a/src/main/java/com/fmudanyali/Time.java
+++ b/src/main/java/com/fmudanyali/Time.java
@@ -19,6 +19,16 @@ package com.fmudanyali;
import static org.libsdl.api.timer.SdlTimer.*;
+/**
+ * Time Class
+ *
+ * Calculates the time difference between this frame
+ * and last frame, deltatime.
+ *
+ * @author Furkan Mudanyali
+ * @version 1.0.0
+ * @since 2021-12-03
+ */
public class Time {
public static int lastTime = 0;
public static int currentTime = 0;
diff --git a/src/main/java/com/fmudanyali/bullets/PlayerBullet.java b/src/main/java/com/fmudanyali/bullets/PlayerBullet.java
index 14e2ba3..0eead9c 100644
--- a/src/main/java/com/fmudanyali/bullets/PlayerBullet.java
+++ b/src/main/java/com/fmudanyali/bullets/PlayerBullet.java
@@ -28,13 +28,27 @@ import org.libsdl.api.surface.SDL_Surface;
import static org.libsdl.api.surface.SdlSurface.*;
import static org.libsdl.api.render.SdlRender.*;
+/**
+ * PlayerBullet Class
+ *
+ * This class is for player made projectiles
+ * that advance forward in the screen and explode
+ * on enemy contact (to be implemented).
+ *
+ * @author Furkan Mudanyali
+ * @version 0.4.0
+ * @since 2021-12-22
+ */
public class PlayerBullet {
+ // Load the texture
public static SDL_Surface tempSurface = SDL_LoadBMP(FileLoader.getFilePath("player/bullet.bmp"));
public static SDL_Texture texture = SDL_CreateTextureFromSurface(Render.renderer, tempSurface);
public SDL_Rect position = new SDL_Rect();
public int width = 5;
public int height = 12;
+ // Set the bullet position relative to the player position and given
+ // offsets.
public PlayerBullet(SDL_Rect playerPos, int xOffset, int yOffset){
position.w = width;
position.h = height;
@@ -42,6 +56,9 @@ public class PlayerBullet {
position.y = playerPos.y - 6 - 3 - yOffset;
}
+ /**
+ * Advances the bullet on the screen.
+ */
public void fly(){
position.y = position.y - (int)(Time.deltaTime * 0.5);
}
diff --git a/src/main/java/com/fmudanyali/characters/Character.java b/src/main/java/com/fmudanyali/characters/Character.java
index e9a8490..325b6de 100644
--- a/src/main/java/com/fmudanyali/characters/Character.java
+++ b/src/main/java/com/fmudanyali/characters/Character.java
@@ -21,6 +21,16 @@ import org.libsdl.api.rect.SDL_Rect;
import org.libsdl.api.render.SDL_Texture;
import org.libsdl.api.surface.SDL_Surface;
+/**
+ * Character Superclass
+ *
+ * This class provides essentials that a character
+ * should require.
+ *
+ * @author Furkan Mudanyali
+ * @version 1.0.0
+ * @since 2021-12-08
+ */
public class Character {
public SDL_Rect position = new SDL_Rect();
public SDL_Texture texture = new SDL_Texture();
diff --git a/src/main/java/com/fmudanyali/characters/Enemy.java b/src/main/java/com/fmudanyali/characters/Enemy.java
index 4269a11..c776f90 100644
--- a/src/main/java/com/fmudanyali/characters/Enemy.java
+++ b/src/main/java/com/fmudanyali/characters/Enemy.java
@@ -18,5 +18,5 @@
package com.fmudanyali.characters;
public class Enemy extends Character {
-
+ // TODO: Implement
}
diff --git a/src/main/java/com/fmudanyali/characters/Player.java b/src/main/java/com/fmudanyali/characters/Player.java
index 2cf64c5..29b99bf 100644
--- a/src/main/java/com/fmudanyali/characters/Player.java
+++ b/src/main/java/com/fmudanyali/characters/Player.java
@@ -32,7 +32,19 @@ import static org.libsdl.api.surface.SdlSurface.*;
import static org.libsdl.api.render.SdlRender.*;
import static org.libsdl.api.scancode.SDL_Scancode.*;
+/**
+ * Player Class
+ *
+ * This class extends on the character class and has all the
+ * bells and whistles such as handling movement, shooting bullets,
+ * animated sprites etc.
+ *
+ * @author Furkan Mudanyali
+ * @version 0.9.0
+ * @since 2021-12-08
+ */
public class Player extends Character {
+ // Variables
public int lives;
public double speed;
public SDL_Texture propeller;
@@ -40,14 +52,16 @@ public class Player extends Character {
public int frame = 0;
public int roll = 0;
public int cooldown = 0;
-
+ // New position rectangles for additional parts
public SDL_Rect propellerPos = new SDL_Rect();
public SDL_Rect shooterPos = new SDL_Rect();
-
+ // These rectangles are used for shifting
+ // sprite animation.
public SDL_Rect shipFrame = new SDL_Rect();
public SDL_Rect propellerFrame = new SDL_Rect();
public SDL_Rect shooterFrame = new SDL_Rect();
-
+
+ // Load the textures and set the positions.
public Player(){
lives = 3;
tempSurface = SDL_LoadBMP(FileLoader.getFilePath("player/ship.bmp"));
@@ -167,7 +181,8 @@ public class Player extends Character {
propellerFrame.x = 10;
break;
}
-
+ // Not a switch as DeltaTime does not provide
+ // linear increase.
if(roll > 0){
shipFrame.x = shipFrame.y = 0;
} if(roll > 15){
@@ -178,17 +193,23 @@ public class Player extends Character {
} if(roll > 45){
shipFrame.x = 32;
}
-
+ // Frame is kept in 600 instead of 60
+ // to be accurate with the varying framerate
+ // animations.
frame = (frame+10)%600;
}
+ /**
+ * Changes positions depending on the keyboard state.
+ */
public void movement(){
+ // If shift is pressed, slow down the player.
if(Keyboard.getKeyState(SDL_SCANCODE_LSHIFT)){
speed = 1.5;
}else{
speed = 2;
}
-
+ // Bunch of mathematical mumbo jumbo.
if(Keyboard.getKeyState(SDL_SCANCODE_A) | Keyboard.getKeyState(SDL_SCANCODE_LEFT)){
position.x = Math.max(position.x - (int)(speed * Time.deltaTime * 0.1), Screen.canvasPos.x - 5);
shooterPos.x = Math.max(shooterPos.x - (int)(speed * Time.deltaTime * 0.1), Screen.canvasPos.x + 16 - 4 - 5);
@@ -227,7 +248,8 @@ public class Player extends Character {
Game.playerBullets.add(new PlayerBullet(position, 17, 0));
Game.playerBullets.add(new PlayerBullet(position, 21, 6));
Game.playerBullets.add(new PlayerBullet(position, 25, 9));
- cooldown = 1;
+ // Cooldown is used to prevent overshooting.
+ cooldown = 3;
}
cooldown = Math.max(cooldown -1, 0);
}
diff --git a/src/main/java/com/fmudanyali/scenes/Game.java b/src/main/java/com/fmudanyali/scenes/Game.java
index f5a68aa..f57c52f 100644
--- a/src/main/java/com/fmudanyali/scenes/Game.java
+++ b/src/main/java/com/fmudanyali/scenes/Game.java
@@ -33,51 +33,85 @@ import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
+/**
+ * Game Class
+ *
+ * This class extends on the Scene class and is mainly
+ * the core of the game.
+ *
+ * @author Furkan Mudanyali
+ * @version 0.1.0
+ * @since 2021-12-04
+ */
public class Game extends Scene {
+ // Variables
public static boolean escPressed = false;
int kek = 0;
private Player player = new Player();
+ // Keeping track of the shots fired
public static List playerBullets = new ArrayList<>();
+ // Thread for bg music
private static Thread thread;
+ // Create a runnable for the thread
private static Runnable runnable = new Runnable() {
public void run(){
try {
Mix_PlayMusic(Mix_LoadMUS(FileLoader.getFilePath("80-search-intro.wav")), 1);
+ // Sleeping for the duration of the intro instead of checking if it stopped on a
+ // loop saves a loooot of clock cycles.
Thread.sleep(getMusicLengthInMilliseconds(FileLoader.getFilePath("80-search-intro.wav")));
Mix_PlayMusic(Mix_LoadMUS(FileLoader.getFilePath("80-search-loop.wav")), -1);
+ // Kill self because the last music will loop forever
Thread.currentThread().interrupt();
return;
} catch(Exception e){
- // Will throw sleep interrupted, which is what we want.
+ // Will throw sleep interrupted, which is exactly what we want.
}
}
};
public Game(){
+ // Create the looping background
Screen.makeBackground("shmap.bmp");
+ // Set music volume to max
Mix_VolumeMusic(128);
+ // Try reading thread state, will throw exception for
+ // the first time as the thread will not be initialized
+ // at that time, which is perfectly expected.
try {
+ // Interrupt the thread if its running, this is needed
+ // to keep only one thread alive at a time because if
+ // the game is immediately quitted and a new game started,
+ // the music will not get confused.
if(thread.getState() != Thread.State.TERMINATED){
thread.interrupt();
}
} catch (Exception e){
- //
+ // Do nothing as I expect this behavior.
}
+ // Overwrite the the TERMINATED (or not initialized)
+ // thread with a new thread with our runnable.
thread = new Thread(runnable);
+ // Start the thread.
thread.start();
}
@Override
public void loop(){
+ // Handle events first
while(SDL_PollEvent(Main.e) != 0){
switch(Main.e.type){
+ // If close button on the window is pressed.
case SDL_QUIT:
Main.exit = true;
break;
+ // If a key is pressed
case SDL_KEYDOWN:
switch(Main.e.key.keysym.sym){
+ // If ESC is pressed, push pause menu to the scenes stack
case SDLK_ESCAPE:
+ // Needed to execute it only once per conventional key press
if(!escPressed){
Main.scenes.push(new PauseMenu());
Mix_VolumeMusic(30);
@@ -86,6 +120,7 @@ public class Game extends Scene {
break;
}
break;
+ // If a key is released
case SDL_KEYUP:
switch(Main.e.key.keysym.sym){
case SDLK_ESCAPE:
@@ -96,27 +131,31 @@ public class Game extends Scene {
}
}
+ // Do player movement thing and scroll the screen
player.movement();
Screen.scroll(player);
-
+ // Copying stuff to the renderer
SDL_RenderClear(renderer);
SDL_RenderCopy(renderer, Screen.wallpaper, null, null);
SDL_RenderCopy(renderer, Screen.background, Screen.canvas, Screen.canvasPos);
SDL_RenderCopy(renderer, player.texture, player.shipFrame, player.position);
SDL_RenderCopy(renderer, player.propeller, player.propellerFrame, player.propellerPos);
SDL_RenderCopy(renderer, player.shooter, player.shooterFrame, player.shooterPos);
-
+ // Iterate over the bullets on the screen
for(Iterator bulletIterator = playerBullets.iterator(); bulletIterator.hasNext();){
PlayerBullet b = bulletIterator.next();
+ // Move the bullet
b.fly();
+ // If the bullet is out of the screen, destroy it, else copy it to the renderer.
if(b.position.y < 30){
bulletIterator.remove();
} else {
SDL_RenderCopy(renderer, PlayerBullet.texture, null, b.position);
}
}
-
+ // Present the renderer to the window.
SDL_RenderPresent(renderer);
+ // Advance player sprite animation
player.shiftFrame();
}
}
\ No newline at end of file
diff --git a/src/main/java/com/fmudanyali/scenes/Scene.java b/src/main/java/com/fmudanyali/scenes/Scene.java
index 1c2ba21..de1a2ec 100644
--- a/src/main/java/com/fmudanyali/scenes/Scene.java
+++ b/src/main/java/com/fmudanyali/scenes/Scene.java
@@ -17,6 +17,20 @@
package com.fmudanyali.scenes;
+/**
+ * Scene Class
+ *
+ * This class is an abstract for other scenes and makes able to
+ * keep all the different kind of scenes on a single stack.
+ *
+ * @author Furkan Mudanyali
+ * @version 1.0.0
+ * @since 2021-12-04
+ */
public abstract class Scene {
+ /**
+ * By design, this function will be
+ * executed each game frame.
+ */
public abstract void loop();
}
\ No newline at end of file