diff --git a/.classpath b/.classpath new file mode 100644 index 0000000..39abf1c --- /dev/null +++ b/.classpath @@ -0,0 +1,49 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/.project b/.project new file mode 100644 index 0000000..3bb65b3 --- /dev/null +++ b/.project @@ -0,0 +1,34 @@ + + + DanmakuProject + + + + + + org.eclipse.jdt.core.javabuilder + + + + + org.eclipse.m2e.core.maven2Builder + + + + + + org.eclipse.jdt.core.javanature + org.eclipse.m2e.core.maven2Nature + + + + 1640019058211 + + 30 + + org.eclipse.core.resources.regexFilterMatcher + node_modules|.git|__CREATED_BY_JAVA_LANGUAGE_SERVER__ + + + + diff --git a/.settings/org.eclipse.core.resources.prefs b/.settings/org.eclipse.core.resources.prefs new file mode 100644 index 0000000..abdea9a --- /dev/null +++ b/.settings/org.eclipse.core.resources.prefs @@ -0,0 +1,4 @@ +eclipse.preferences.version=1 +encoding//src/main/java=UTF-8 +encoding//src/main/resources=UTF-8 +encoding/=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