Skip to content

Commit

Permalink
Merge pull request #31 from redomar/develop
Browse files Browse the repository at this point in the history
Update to 1.8.7: JDK Upgrade and Improve rendering
  • Loading branch information
redomar authored Feb 16, 2024
2 parents d3c9bfa + 777a722 commit 985fc8e
Show file tree
Hide file tree
Showing 17 changed files with 453 additions and 174 deletions.
4 changes: 2 additions & 2 deletions .github/workflows/maven.yml
Original file line number Diff line number Diff line change
Expand Up @@ -11,10 +11,10 @@ jobs:

steps:
- uses: actions/checkout@v3
- name: Set up JDK 8
- name: Set up JDK 21
uses: actions/setup-java@v3
with:
java-version: '8'
java-version: '21'
distribution: 'temurin'
cache: maven
- name: Build with Maven - Install
Expand Down
26 changes: 16 additions & 10 deletions pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,9 @@
<modelVersion>4.0.0</modelVersion>
<groupId>com.redomar.game</groupId>
<artifactId>javagame</artifactId>
<version>Alpha 1.8.6</version>
<version>Alpha 1.8.7</version>
<description>JavaGame is a game project that have been working on since May 2013. I have added many features to the game over the last year and I plan on adding even more features. This game is purely for my own sake to practice my skills in Java.</description>
<url>https://github.com/redomar/JavaGame</url>
<inceptionYear>2013</inceptionYear>
<licenses>
<license>
Expand All @@ -24,12 +26,12 @@
<dependency>
<groupId>org.apache.commons</groupId>
<artifactId>commons-text</artifactId>
<version>1.10.0</version>
<version>1.11.0</version>
</dependency>
<dependency>
<groupId>org.apache.commons</groupId>
<artifactId>commons-lang3</artifactId>
<version>3.12.0</version>
<version>3.14.0</version>
</dependency>
<dependency>
<groupId>org.jetbrains</groupId>
Expand All @@ -49,8 +51,8 @@
</dependency>
</dependencies>
<properties>
<maven.compiler.source>8</maven.compiler.source>
<maven.compiler.target>8</maven.compiler.target>
<maven.compiler.source>21</maven.compiler.source>
<maven.compiler.target>21</maven.compiler.target>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
</properties>
Expand All @@ -68,7 +70,7 @@
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-resources-plugin</artifactId>
<version>2.6</version>
<version>3.3.1</version>
<configuration>
<useDefaultDelimiters>false</useDefaultDelimiters>
<delimiters>
Expand All @@ -81,7 +83,7 @@
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-dependency-plugin</artifactId>
<version>3.3.0</version>
<version>3.6.1</version>
<executions>
<execution>
<id>copy-dependencies</id>
Expand All @@ -102,7 +104,7 @@
<!-- Build an executable JAR -->
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-jar-plugin</artifactId>
<version>2.4</version>
<version>3.3.0</version>
<configuration>

<archive>
Expand All @@ -124,13 +126,12 @@
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-install-plugin</artifactId>
<version>2.4</version>
<version>3.1.1</version>
<executions>
<execution>
<id>install-external-non-maven-jar-MWS-Client-into-local-maven-repo</id>
<phase>clean</phase>
<configuration>
<repositoryLayout>default</repositoryLayout>
<groupId>com.thehowtotutorial.splashscreen</groupId>
<artifactId>JSplashScreen</artifactId>
<version>1.0</version>
Expand All @@ -144,6 +145,11 @@
</execution>
</executions>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-project-info-reports-plugin</artifactId>
<version>3.5.0</version>
</plugin>
</plugins>
</build>
</project>
137 changes: 108 additions & 29 deletions src/com/redomar/game/Game.java
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@
import com.redomar.game.event.MouseHandler;
import com.redomar.game.gfx.Screen;
import com.redomar.game.gfx.SpriteSheet;
import com.redomar.game.gfx.lighting.Night;
import com.redomar.game.level.LevelHandler;
import com.redomar.game.lib.Either;
import com.redomar.game.lib.Font;
Expand All @@ -23,6 +24,7 @@
import java.awt.image.BufferStrategy;
import java.awt.image.BufferedImage;
import java.awt.image.DataBufferInt;
import java.io.Serial;

/*
* This module forms the core architecture of the JavaGame. It coordinates the various
Expand All @@ -33,17 +35,20 @@
public class Game extends Canvas implements Runnable {

// Setting the size and name of the frame/canvas
@Serial
private static final long serialVersionUID = 1L;
private static final String game_Version = "v1.8.6 Alpha";
private static final int WIDTH = 160;
private static final int HEIGHT = (WIDTH / 3 * 2);
private static final int SCALE = 3;
private static final String game_Version = "v1.8.7 Alpha";
private static final int SCALE = 100;
private static final int WIDTH = 3 * SCALE;
private static final int SCREEN_WIDTH = WIDTH * 2;
private static final int HEIGHT = (2 * SCALE);
private static final int SCREEN_HEIGHT = (HEIGHT * 2) + 30;
private static final Screen screen = new Screen(WIDTH, HEIGHT, new SpriteSheet("/sprite_sheet.png"));
private static final Screen screen2 = new Screen(WIDTH, HEIGHT, new SpriteSheet("/sprite_sheet.png"));
private static final String NAME = "Game"; // The name of the JFrame panel
private static final Time time = new Time(); // Represents the calendar's time value, in hh:mm:ss
private static final boolean[] alternateCols = new boolean[2]; // Boolean array describing shirt and face colour

private static Game game;

// The properties of the player, npc, and fps/tps
private static boolean changeLevel = false; // Determines whether the player teleports to another level
private static boolean npc = false; // Non-player character (NPC) initialized to non-existing
Expand All @@ -55,25 +60,26 @@ public class Game extends Canvas implements Runnable {
private static int steps;
private static boolean devMode; // Determines whether the game is in developer mode
private static boolean closingMode; // Determines whether the game will exit

private static int tileX = 0;
private static int tileY = 0;
// Audio, input, and mouse handler objects
private static JFrame frame;
private static AudioHandler backgroundMusic;
private static boolean running = false; // Determines whether the game is currently in process
private static InputHandler input; // Accepts keyboard input and follows the appropriate actions
private static MouseHandler mouse; // Tracks mouse movement and clicks, and follows the appropriate actions
private static InputContext context; // Provides methods to control text input facilities

// Graphics
private final BufferedImage image = new BufferedImage(WIDTH, HEIGHT, BufferedImage.TYPE_INT_RGB);
private final BufferedImage image = new BufferedImage(WIDTH, HEIGHT, BufferedImage.TYPE_INT_ARGB);
private final BufferedImage image3 = new BufferedImage(WIDTH, HEIGHT, BufferedImage.TYPE_INT_ARGB);
private final int[] pixels = ((DataBufferInt) image.getRaster().getDataBuffer()).getData(); // Array of red, green and blue values for each pixel
private final int[] pixels3 = ((DataBufferInt) image3.getRaster().getDataBuffer()).getData(); // Array of red, green and blue values for each pixel
private final int[] colours = new int[6 * 6 * 6]; // Array of 216 unique colours (6 shades of red, 6 of green, and 6 of blue)
private final BufferedImage image2 = new BufferedImage(WIDTH, HEIGHT - 30, BufferedImage.TYPE_INT_RGB);
private final Font font = new Font(); // Font object capable of displaying 2 fonts: Arial and Segoe UI
private final Printer printer = new Printer();
boolean musicPlaying = false;
private int tickCount = 0;
private Screen screen;
private LevelHandler level; // Loads and renders levels along with tiles, entities, projectiles and more.
//The entities of the game
private Player player;
Expand All @@ -87,9 +93,9 @@ public Game() {
context = InputContext.getInstance();

// The game can only be played in one distinct window size
setMinimumSize(new Dimension(WIDTH * SCALE, HEIGHT * SCALE));
setMaximumSize(new Dimension(WIDTH * SCALE, HEIGHT * SCALE));
setPreferredSize(new Dimension(WIDTH * SCALE, HEIGHT * SCALE));
setMinimumSize(new Dimension(SCREEN_WIDTH, SCREEN_HEIGHT));
setMaximumSize(new Dimension(SCREEN_WIDTH, SCREEN_HEIGHT));
setPreferredSize(new Dimension(SCREEN_WIDTH, SCREEN_HEIGHT));

setFrame(new JFrame(NAME)); // Creates the frame with a defined name
getFrame().setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); // Exits the program when user closes the frame
Expand Down Expand Up @@ -288,6 +294,28 @@ public static void setClosing(boolean closing) {
Game.closingMode = closing;
}

private static void mousePositionTracker() {
MouseHandler mouseHandler = Game.getMouse();
int mouseX = mouseHandler.getX();
int mouseY = mouseHandler.getY();

// Adjust mouse coordinates based on the current offset and scale of the game world
tileX = ((mouseX + 4 + screen.getxOffset()) / (8 * 2)) + screen.getxOffset() / 16;
tileY = ((mouseY + 4 + screen.getyOffset()) / (8 * 2)) + screen.getyOffset() / 16;
}

public static int getTileX() {
return tileX;
}

public static int getTileY() {
return tileY;
}

public static Screen getScreen() {
return screen;
}

/*
* This method initializes the game once it starts. It populates the colour array with actual colours (6 shades each of RGB).
* This method also builds the initial game level (custom_level), spawns a new vendor NPC, and begins accepting keyboard and mouse input/tracking.
Expand All @@ -301,12 +329,18 @@ public void init() {
int rr = (r * 255 / 5); // Split all 256 colours into 6 shades (0, 51, 102 ... 255)
int gg = (g * 255 / 5);
int bb = (b * 255 / 5);
colours[index++] = rr << 16 | gg << 8 | bb; // All colour values (RGB) are placed into one 32-bit integer, populating the colour array
// All colour values (RGB) are placed into one 32-bit integer, populating the colour array
// The first 8 bits are for alpha, the next 8 for red, the next 8 for green, and the last 8 for blue
// 0xFF000000 is ignored in BufferedImage.TYPE_INT_RGB, but is used in BufferedImage.TYPE_INT_ARGB
colours[index++] = 0xFF << 24 | rr << 16 | gg << 8 | bb;
}
}
}

screen = new Screen(WIDTH, HEIGHT, new SpriteSheet("/sprite_sheet.png"));
screen.setViewPortHeight(SCREEN_HEIGHT);
screen2.setViewPortHeight(SCREEN_HEIGHT);
screen.setViewPortWidth(SCREEN_WIDTH);
screen2.setViewPortWidth(SCREEN_WIDTH);
input = new InputHandler(this); // Input begins to record key presses
setMouse(new MouseHandler(this)); // Mouse tracking and clicking is now recorded
// setWindow(new WindowHandler(this));
Expand Down Expand Up @@ -343,12 +377,13 @@ public synchronized void stop() {
*/
public void run() {
long lastTime = System.nanoTime();
double nsPerTick = 1000000000D / 60D; // The number of nanoseconds in one tick (number of ticks limited to 60 per update)
int nsPerS = 1_000_000_000;
double nsPerTick = nsPerS / 60D; // The number of nanoseconds in one tick (number of ticks limited to 60 per update)
// 1 billion nanoseconds in one second
int ticks = 0;
int frames = 0;

long lastTimer = System.currentTimeMillis(); // Used for updating ticks and frames once every second
long lastTimer = System.nanoTime(); // Used for updating ticks and frames once every second
double delta = 0;

init(); // Initialize the game environment
Expand All @@ -371,8 +406,8 @@ public void run() {
render();
}

if (System.currentTimeMillis() - lastTimer >= 1000) { // If elapsed time is greater than or equal to 1 second, update
lastTimer += 1000; // Updates in another second
if (System.nanoTime() - lastTimer >= nsPerS) { // If elapsed time is greater than or equal to 1 second, update
lastTimer += nsPerS; // Updates in another second
getFrame().setTitle("JavaGame - Version " + WordUtils.capitalize(game_Version).substring(1, game_Version.length()));
fps = frames;
tps = ticks;
Expand All @@ -393,12 +428,15 @@ public void tick() {
printer.cast().print("Failed to play music", PrintTypes.MUSIC);
printer.exception(exception.toString());
musicPlaying = false;
}, isPlaying -> musicPlaying = isPlaying);

}, isPlaying -> {
musicPlaying = isPlaying;
if (musicPlaying && !Game.getBackgroundMusic().getActive()) {
input.overWriteKey(input.getM_KEY(), false);
}
});
level.tick();
}


/**
* This method displays the current state of the game.
*/
Expand All @@ -425,6 +463,16 @@ public void render() {
}
}
}
for (int y = 0; y < screen2.getHeight(); y++) {
for (int x = 0; x < screen2.getWidth(); x++) {
int colourCode = screen2.getPixels()[x + y * screen2.getWidth()];
if (colourCode < 1){
pixels3[x + y * WIDTH] = 0xff0000;
} else if (colourCode < 255) {
pixels3[x + y * WIDTH] = colours[colourCode];
}
}
}

if (isChangeLevel() && getTickCount() % 60 == 0) {
Game.setChangeLevel(true);
Expand Down Expand Up @@ -452,10 +500,10 @@ public void render() {
changeLevel = false;
}

Graphics g = bs.getDrawGraphics();
g.drawRect(0, 0, getWidth(), getHeight());
Graphics2D g = (Graphics2D) bs.getDrawGraphics();
g.drawImage(image, 0, 0, getWidth(), getHeight() - 30, null);
status(g, isDevMode(), isClosing());
overlayRender(g);
g.drawImage(image2, 0, getHeight() - 30, getWidth(), getHeight(), null);
g.setColor(Color.WHITE);
g.setFont(font.getSegoe());
Expand Down Expand Up @@ -484,12 +532,24 @@ public void render() {
bs.show();
}

/**
* This method renders the overlay of the game, which is a transparent layer that is drawn over the game.
*/
private void overlayRender(Graphics2D g) {
g.setColor(new Color(0f, 0f, 0f, 0f)); // Transparent color
g.fillRect(0, 0, getWidth(), getHeight()-30);
}

/*
* This method displays information regarding various aspects/stats of the game, dependent upon
* whether it is running in developer mode, or if the application is closing.
*/
private void status(Graphics g, boolean TerminalMode, boolean TerminalQuit) {
private void status(Graphics2D g, boolean TerminalMode, boolean TerminalQuit) {
if (TerminalMode) {
new Night(g, screen).render(player.getPlayerAbsX(), player.getPlayerAbsY());
// make the background transparent
g.setColor(new Color(0, 0, 0, 100));
g.fillRect(0, 0, 195, 165);
g.setColor(Color.CYAN);
g.drawString("JavaGame Stats", 0, 10);
g.drawString("FPS/TPS: " + fps + "/" + tps, 0, 25);
Expand All @@ -499,9 +559,29 @@ private void status(Graphics g, boolean TerminalMode, boolean TerminalQuit) {
g.drawString("Foot Steps: " + steps, 0, 40);
g.drawString("NPC: " + WordUtils.capitalize(String.valueOf(isNpc())), 0, 55);
g.drawString("Mouse: " + getMouse().getX() + "x |" + getMouse().getY() + "y", 0, 70);
if (getMouse().getButton() != -1) g.drawString("Button: " + getMouse().getButton(), 0, 85);
g.setColor(Color.CYAN);
g.fillRect(getMouse().getX() - 12, getMouse().getY() - 12, 24, 24);
g.drawString("Mouse: " + (getMouse().getX() - 639 / 2d) + "x |" + (getMouse().getY() - 423 / 2d) + "y", 0, 85);
if (getMouse().getButton() != -1) g.drawString("Button: " + getMouse().getButton(), 0, 100);
mousePositionTracker();
g.drawString("Player: " + (int) player.getX() + "x |" + (int) player.getY() + "y", 0, 115);
double angle = Math.atan2(getMouse().getY() - player.getPlayerAbsY(), getMouse().getX() - player.getPlayerAbsX()) * (180.0 / Math.PI);
g.drawString("Angle: " + angle, 0, 130);

g.setColor(Color.cyan);
g.drawString("Player: \t\t\t\t\t\t\t\t\t\t\t\t" + player.getPlayerAbsX() + "x |" + player.getPlayerAbsY() + "y", 0, 145);
g.drawString("Player Offset: \t" + screen.getxOffset() + "x |" + screen.getyOffset() + "y", 0, 160);

// Set a different color for the player-origin line
g.setStroke(new BasicStroke(1));
g.setColor(Color.GREEN); // Green for the new line from the player's origin
g.drawLine(player.getPlayerAbsX(), player.getPlayerAbsY(), getMouse().getX(), getMouse().getY()); // Draw the line from the player's origin to the cursor
g.setColor(Color.DARK_GRAY);
g.drawLine(getWidth() / 2 + 8, getHeight() / 2 - 8, getMouse().getX(), getMouse().getY()); // Draw the line from the player's origin to the cursor
g.drawLine(getWidth() / 2 + 8, 0, getWidth() / 2 + 8, getHeight() - 30);
g.drawLine(0, getHeight() / 2 - 8, getWidth(), getHeight() / 2 - 8);
g.setColor(Color.yellow);
g.fillRect(player.getPlayerAbsX(), player.getPlayerAbsY(), 1, 1);


}
// If the game is shutting off
if (!TerminalQuit) {
Expand Down Expand Up @@ -529,5 +609,4 @@ public Vendor getVendor() {
public void setVendor(Vendor vendor) {
this.vendor = vendor;
}

}
Loading

0 comments on commit 985fc8e

Please sign in to comment.