Skip to content

Commit 985fc8e

Browse files
authored
Merge pull request #31 from redomar/develop
Update to 1.8.7: JDK Upgrade and Improve rendering
2 parents d3c9bfa + 777a722 commit 985fc8e

File tree

17 files changed

+453
-174
lines changed

17 files changed

+453
-174
lines changed

.github/workflows/maven.yml

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -11,10 +11,10 @@ jobs:
1111

1212
steps:
1313
- uses: actions/checkout@v3
14-
- name: Set up JDK 8
14+
- name: Set up JDK 21
1515
uses: actions/setup-java@v3
1616
with:
17-
java-version: '8'
17+
java-version: '21'
1818
distribution: 'temurin'
1919
cache: maven
2020
- name: Build with Maven - Install

pom.xml

Lines changed: 16 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,9 @@
55
<modelVersion>4.0.0</modelVersion>
66
<groupId>com.redomar.game</groupId>
77
<artifactId>javagame</artifactId>
8-
<version>Alpha 1.8.6</version>
8+
<version>Alpha 1.8.7</version>
9+
<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>
10+
<url>https://github.com/redomar/JavaGame</url>
911
<inceptionYear>2013</inceptionYear>
1012
<licenses>
1113
<license>
@@ -24,12 +26,12 @@
2426
<dependency>
2527
<groupId>org.apache.commons</groupId>
2628
<artifactId>commons-text</artifactId>
27-
<version>1.10.0</version>
29+
<version>1.11.0</version>
2830
</dependency>
2931
<dependency>
3032
<groupId>org.apache.commons</groupId>
3133
<artifactId>commons-lang3</artifactId>
32-
<version>3.12.0</version>
34+
<version>3.14.0</version>
3335
</dependency>
3436
<dependency>
3537
<groupId>org.jetbrains</groupId>
@@ -49,8 +51,8 @@
4951
</dependency>
5052
</dependencies>
5153
<properties>
52-
<maven.compiler.source>8</maven.compiler.source>
53-
<maven.compiler.target>8</maven.compiler.target>
54+
<maven.compiler.source>21</maven.compiler.source>
55+
<maven.compiler.target>21</maven.compiler.target>
5456
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
5557
<project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
5658
</properties>
@@ -68,7 +70,7 @@
6870
<plugin>
6971
<groupId>org.apache.maven.plugins</groupId>
7072
<artifactId>maven-resources-plugin</artifactId>
71-
<version>2.6</version>
73+
<version>3.3.1</version>
7274
<configuration>
7375
<useDefaultDelimiters>false</useDefaultDelimiters>
7476
<delimiters>
@@ -81,7 +83,7 @@
8183
<plugin>
8284
<groupId>org.apache.maven.plugins</groupId>
8385
<artifactId>maven-dependency-plugin</artifactId>
84-
<version>3.3.0</version>
86+
<version>3.6.1</version>
8587
<executions>
8688
<execution>
8789
<id>copy-dependencies</id>
@@ -102,7 +104,7 @@
102104
<!-- Build an executable JAR -->
103105
<groupId>org.apache.maven.plugins</groupId>
104106
<artifactId>maven-jar-plugin</artifactId>
105-
<version>2.4</version>
107+
<version>3.3.0</version>
106108
<configuration>
107109

108110
<archive>
@@ -124,13 +126,12 @@
124126
<plugin>
125127
<groupId>org.apache.maven.plugins</groupId>
126128
<artifactId>maven-install-plugin</artifactId>
127-
<version>2.4</version>
129+
<version>3.1.1</version>
128130
<executions>
129131
<execution>
130132
<id>install-external-non-maven-jar-MWS-Client-into-local-maven-repo</id>
131133
<phase>clean</phase>
132134
<configuration>
133-
<repositoryLayout>default</repositoryLayout>
134135
<groupId>com.thehowtotutorial.splashscreen</groupId>
135136
<artifactId>JSplashScreen</artifactId>
136137
<version>1.0</version>
@@ -144,6 +145,11 @@
144145
</execution>
145146
</executions>
146147
</plugin>
148+
<plugin>
149+
<groupId>org.apache.maven.plugins</groupId>
150+
<artifactId>maven-project-info-reports-plugin</artifactId>
151+
<version>3.5.0</version>
152+
</plugin>
147153
</plugins>
148154
</build>
149155
</project>

src/com/redomar/game/Game.java

Lines changed: 108 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@
99
import com.redomar.game.event.MouseHandler;
1010
import com.redomar.game.gfx.Screen;
1111
import com.redomar.game.gfx.SpriteSheet;
12+
import com.redomar.game.gfx.lighting.Night;
1213
import com.redomar.game.level.LevelHandler;
1314
import com.redomar.game.lib.Either;
1415
import com.redomar.game.lib.Font;
@@ -23,6 +24,7 @@
2324
import java.awt.image.BufferStrategy;
2425
import java.awt.image.BufferedImage;
2526
import java.awt.image.DataBufferInt;
27+
import java.io.Serial;
2628

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

3537
// Setting the size and name of the frame/canvas
38+
@Serial
3639
private static final long serialVersionUID = 1L;
37-
private static final String game_Version = "v1.8.6 Alpha";
38-
private static final int WIDTH = 160;
39-
private static final int HEIGHT = (WIDTH / 3 * 2);
40-
private static final int SCALE = 3;
40+
private static final String game_Version = "v1.8.7 Alpha";
41+
private static final int SCALE = 100;
42+
private static final int WIDTH = 3 * SCALE;
43+
private static final int SCREEN_WIDTH = WIDTH * 2;
44+
private static final int HEIGHT = (2 * SCALE);
45+
private static final int SCREEN_HEIGHT = (HEIGHT * 2) + 30;
46+
private static final Screen screen = new Screen(WIDTH, HEIGHT, new SpriteSheet("/sprite_sheet.png"));
47+
private static final Screen screen2 = new Screen(WIDTH, HEIGHT, new SpriteSheet("/sprite_sheet.png"));
4148
private static final String NAME = "Game"; // The name of the JFrame panel
4249
private static final Time time = new Time(); // Represents the calendar's time value, in hh:mm:ss
4350
private static final boolean[] alternateCols = new boolean[2]; // Boolean array describing shirt and face colour
44-
4551
private static Game game;
46-
4752
// The properties of the player, npc, and fps/tps
4853
private static boolean changeLevel = false; // Determines whether the player teleports to another level
4954
private static boolean npc = false; // Non-player character (NPC) initialized to non-existing
@@ -55,25 +60,26 @@ public class Game extends Canvas implements Runnable {
5560
private static int steps;
5661
private static boolean devMode; // Determines whether the game is in developer mode
5762
private static boolean closingMode; // Determines whether the game will exit
58-
63+
private static int tileX = 0;
64+
private static int tileY = 0;
5965
// Audio, input, and mouse handler objects
6066
private static JFrame frame;
6167
private static AudioHandler backgroundMusic;
6268
private static boolean running = false; // Determines whether the game is currently in process
6369
private static InputHandler input; // Accepts keyboard input and follows the appropriate actions
6470
private static MouseHandler mouse; // Tracks mouse movement and clicks, and follows the appropriate actions
6571
private static InputContext context; // Provides methods to control text input facilities
66-
6772
// Graphics
68-
private final BufferedImage image = new BufferedImage(WIDTH, HEIGHT, BufferedImage.TYPE_INT_RGB);
73+
private final BufferedImage image = new BufferedImage(WIDTH, HEIGHT, BufferedImage.TYPE_INT_ARGB);
74+
private final BufferedImage image3 = new BufferedImage(WIDTH, HEIGHT, BufferedImage.TYPE_INT_ARGB);
6975
private final int[] pixels = ((DataBufferInt) image.getRaster().getDataBuffer()).getData(); // Array of red, green and blue values for each pixel
76+
private final int[] pixels3 = ((DataBufferInt) image3.getRaster().getDataBuffer()).getData(); // Array of red, green and blue values for each pixel
7077
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)
7178
private final BufferedImage image2 = new BufferedImage(WIDTH, HEIGHT - 30, BufferedImage.TYPE_INT_RGB);
7279
private final Font font = new Font(); // Font object capable of displaying 2 fonts: Arial and Segoe UI
7380
private final Printer printer = new Printer();
7481
boolean musicPlaying = false;
7582
private int tickCount = 0;
76-
private Screen screen;
7783
private LevelHandler level; // Loads and renders levels along with tiles, entities, projectiles and more.
7884
//The entities of the game
7985
private Player player;
@@ -87,9 +93,9 @@ public Game() {
8793
context = InputContext.getInstance();
8894

8995
// The game can only be played in one distinct window size
90-
setMinimumSize(new Dimension(WIDTH * SCALE, HEIGHT * SCALE));
91-
setMaximumSize(new Dimension(WIDTH * SCALE, HEIGHT * SCALE));
92-
setPreferredSize(new Dimension(WIDTH * SCALE, HEIGHT * SCALE));
96+
setMinimumSize(new Dimension(SCREEN_WIDTH, SCREEN_HEIGHT));
97+
setMaximumSize(new Dimension(SCREEN_WIDTH, SCREEN_HEIGHT));
98+
setPreferredSize(new Dimension(SCREEN_WIDTH, SCREEN_HEIGHT));
9399

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

297+
private static void mousePositionTracker() {
298+
MouseHandler mouseHandler = Game.getMouse();
299+
int mouseX = mouseHandler.getX();
300+
int mouseY = mouseHandler.getY();
301+
302+
// Adjust mouse coordinates based on the current offset and scale of the game world
303+
tileX = ((mouseX + 4 + screen.getxOffset()) / (8 * 2)) + screen.getxOffset() / 16;
304+
tileY = ((mouseY + 4 + screen.getyOffset()) / (8 * 2)) + screen.getyOffset() / 16;
305+
}
306+
307+
public static int getTileX() {
308+
return tileX;
309+
}
310+
311+
public static int getTileY() {
312+
return tileY;
313+
}
314+
315+
public static Screen getScreen() {
316+
return screen;
317+
}
318+
291319
/*
292320
* This method initializes the game once it starts. It populates the colour array with actual colours (6 shades each of RGB).
293321
* This method also builds the initial game level (custom_level), spawns a new vendor NPC, and begins accepting keyboard and mouse input/tracking.
@@ -301,12 +329,18 @@ public void init() {
301329
int rr = (r * 255 / 5); // Split all 256 colours into 6 shades (0, 51, 102 ... 255)
302330
int gg = (g * 255 / 5);
303331
int bb = (b * 255 / 5);
304-
colours[index++] = rr << 16 | gg << 8 | bb; // All colour values (RGB) are placed into one 32-bit integer, populating the colour array
332+
// All colour values (RGB) are placed into one 32-bit integer, populating the colour array
333+
// The first 8 bits are for alpha, the next 8 for red, the next 8 for green, and the last 8 for blue
334+
// 0xFF000000 is ignored in BufferedImage.TYPE_INT_RGB, but is used in BufferedImage.TYPE_INT_ARGB
335+
colours[index++] = 0xFF << 24 | rr << 16 | gg << 8 | bb;
305336
}
306337
}
307338
}
308339

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

351-
long lastTimer = System.currentTimeMillis(); // Used for updating ticks and frames once every second
386+
long lastTimer = System.nanoTime(); // Used for updating ticks and frames once every second
352387
double delta = 0;
353388

354389
init(); // Initialize the game environment
@@ -371,8 +406,8 @@ public void run() {
371406
render();
372407
}
373408

374-
if (System.currentTimeMillis() - lastTimer >= 1000) { // If elapsed time is greater than or equal to 1 second, update
375-
lastTimer += 1000; // Updates in another second
409+
if (System.nanoTime() - lastTimer >= nsPerS) { // If elapsed time is greater than or equal to 1 second, update
410+
lastTimer += nsPerS; // Updates in another second
376411
getFrame().setTitle("JavaGame - Version " + WordUtils.capitalize(game_Version).substring(1, game_Version.length()));
377412
fps = frames;
378413
tps = ticks;
@@ -393,12 +428,15 @@ public void tick() {
393428
printer.cast().print("Failed to play music", PrintTypes.MUSIC);
394429
printer.exception(exception.toString());
395430
musicPlaying = false;
396-
}, isPlaying -> musicPlaying = isPlaying);
397-
431+
}, isPlaying -> {
432+
musicPlaying = isPlaying;
433+
if (musicPlaying && !Game.getBackgroundMusic().getActive()) {
434+
input.overWriteKey(input.getM_KEY(), false);
435+
}
436+
});
398437
level.tick();
399438
}
400439

401-
402440
/**
403441
* This method displays the current state of the game.
404442
*/
@@ -425,6 +463,16 @@ public void render() {
425463
}
426464
}
427465
}
466+
for (int y = 0; y < screen2.getHeight(); y++) {
467+
for (int x = 0; x < screen2.getWidth(); x++) {
468+
int colourCode = screen2.getPixels()[x + y * screen2.getWidth()];
469+
if (colourCode < 1){
470+
pixels3[x + y * WIDTH] = 0xff0000;
471+
} else if (colourCode < 255) {
472+
pixels3[x + y * WIDTH] = colours[colourCode];
473+
}
474+
}
475+
}
428476

429477
if (isChangeLevel() && getTickCount() % 60 == 0) {
430478
Game.setChangeLevel(true);
@@ -452,10 +500,10 @@ public void render() {
452500
changeLevel = false;
453501
}
454502

455-
Graphics g = bs.getDrawGraphics();
456-
g.drawRect(0, 0, getWidth(), getHeight());
503+
Graphics2D g = (Graphics2D) bs.getDrawGraphics();
457504
g.drawImage(image, 0, 0, getWidth(), getHeight() - 30, null);
458505
status(g, isDevMode(), isClosing());
506+
overlayRender(g);
459507
g.drawImage(image2, 0, getHeight() - 30, getWidth(), getHeight(), null);
460508
g.setColor(Color.WHITE);
461509
g.setFont(font.getSegoe());
@@ -484,12 +532,24 @@ public void render() {
484532
bs.show();
485533
}
486534

535+
/**
536+
* This method renders the overlay of the game, which is a transparent layer that is drawn over the game.
537+
*/
538+
private void overlayRender(Graphics2D g) {
539+
g.setColor(new Color(0f, 0f, 0f, 0f)); // Transparent color
540+
g.fillRect(0, 0, getWidth(), getHeight()-30);
541+
}
542+
487543
/*
488544
* This method displays information regarding various aspects/stats of the game, dependent upon
489545
* whether it is running in developer mode, or if the application is closing.
490546
*/
491-
private void status(Graphics g, boolean TerminalMode, boolean TerminalQuit) {
547+
private void status(Graphics2D g, boolean TerminalMode, boolean TerminalQuit) {
492548
if (TerminalMode) {
549+
new Night(g, screen).render(player.getPlayerAbsX(), player.getPlayerAbsY());
550+
// make the background transparent
551+
g.setColor(new Color(0, 0, 0, 100));
552+
g.fillRect(0, 0, 195, 165);
493553
g.setColor(Color.CYAN);
494554
g.drawString("JavaGame Stats", 0, 10);
495555
g.drawString("FPS/TPS: " + fps + "/" + tps, 0, 25);
@@ -499,9 +559,29 @@ private void status(Graphics g, boolean TerminalMode, boolean TerminalQuit) {
499559
g.drawString("Foot Steps: " + steps, 0, 40);
500560
g.drawString("NPC: " + WordUtils.capitalize(String.valueOf(isNpc())), 0, 55);
501561
g.drawString("Mouse: " + getMouse().getX() + "x |" + getMouse().getY() + "y", 0, 70);
502-
if (getMouse().getButton() != -1) g.drawString("Button: " + getMouse().getButton(), 0, 85);
503-
g.setColor(Color.CYAN);
504-
g.fillRect(getMouse().getX() - 12, getMouse().getY() - 12, 24, 24);
562+
g.drawString("Mouse: " + (getMouse().getX() - 639 / 2d) + "x |" + (getMouse().getY() - 423 / 2d) + "y", 0, 85);
563+
if (getMouse().getButton() != -1) g.drawString("Button: " + getMouse().getButton(), 0, 100);
564+
mousePositionTracker();
565+
g.drawString("Player: " + (int) player.getX() + "x |" + (int) player.getY() + "y", 0, 115);
566+
double angle = Math.atan2(getMouse().getY() - player.getPlayerAbsY(), getMouse().getX() - player.getPlayerAbsX()) * (180.0 / Math.PI);
567+
g.drawString("Angle: " + angle, 0, 130);
568+
569+
g.setColor(Color.cyan);
570+
g.drawString("Player: \t\t\t\t\t\t\t\t\t\t\t\t" + player.getPlayerAbsX() + "x |" + player.getPlayerAbsY() + "y", 0, 145);
571+
g.drawString("Player Offset: \t" + screen.getxOffset() + "x |" + screen.getyOffset() + "y", 0, 160);
572+
573+
// Set a different color for the player-origin line
574+
g.setStroke(new BasicStroke(1));
575+
g.setColor(Color.GREEN); // Green for the new line from the player's origin
576+
g.drawLine(player.getPlayerAbsX(), player.getPlayerAbsY(), getMouse().getX(), getMouse().getY()); // Draw the line from the player's origin to the cursor
577+
g.setColor(Color.DARK_GRAY);
578+
g.drawLine(getWidth() / 2 + 8, getHeight() / 2 - 8, getMouse().getX(), getMouse().getY()); // Draw the line from the player's origin to the cursor
579+
g.drawLine(getWidth() / 2 + 8, 0, getWidth() / 2 + 8, getHeight() - 30);
580+
g.drawLine(0, getHeight() / 2 - 8, getWidth(), getHeight() / 2 - 8);
581+
g.setColor(Color.yellow);
582+
g.fillRect(player.getPlayerAbsX(), player.getPlayerAbsY(), 1, 1);
583+
584+
505585
}
506586
// If the game is shutting off
507587
if (!TerminalQuit) {
@@ -529,5 +609,4 @@ public Vendor getVendor() {
529609
public void setVendor(Vendor vendor) {
530610
this.vendor = vendor;
531611
}
532-
533612
}

0 commit comments

Comments
 (0)