Skip to content

Commit 5683624

Browse files
committed
Added mouse tracked highlighted tile
1 parent 4a37d20 commit 5683624

File tree

6 files changed

+157
-74
lines changed

6 files changed

+157
-74
lines changed

src/com/redomar/game/Game.java

Lines changed: 33 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -40,35 +40,34 @@ public class Game extends Canvas implements Runnable {
4040
private static final String game_Version = "v1.8.6 Alpha";
4141
private static final int SCALE = 100;
4242
private static final int WIDTH = 3 * SCALE;
43+
private static final int SCREEN_WIDTH = WIDTH * 2;
4344
private static final int HEIGHT = (2 * SCALE);
44-
private static final int SCREEN_WIDTH = WIDTH*2;
45-
private static final int SCREEN_HEIGHT = (HEIGHT*2)+30;
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"));
4647
private static final String NAME = "Game"; // The name of the JFrame panel
4748
private static final Time time = new Time(); // Represents the calendar's time value, in hh:mm:ss
4849
private static final boolean[] alternateCols = new boolean[2]; // Boolean array describing shirt and face colour
49-
5050
private static Game game;
51-
5251
// The properties of the player, npc, and fps/tps
5352
private static boolean changeLevel = false; // Determines whether the player teleports to another level
5453
private static boolean npc = false; // Non-player character (NPC) initialized to non-existing
5554
private static int map = 0; // Map of the level, initialized to map default map
5655
private static int shirtCol; // The colour of the character's shirt
57-
private static int faceCol; // The colour (ethnicity) of the character (their face)
56+
private static int faceCol; // The colour (ethnicizty) of the character (their face)
5857
private static int fps; // The frame rate (frames per second), frequency at which images are displayed on the canvas
5958
private static int tps; // The ticks (ticks per second), unit measure of time for one iteration of the game logic loop.
6059
private static int steps;
6160
private static boolean devMode; // Determines whether the game is in developer mode
6261
private static boolean closingMode; // Determines whether the game will exit
63-
62+
private static int tileX = 0;
63+
private static int tileY = 0;
6464
// Audio, input, and mouse handler objects
6565
private static JFrame frame;
6666
private static AudioHandler backgroundMusic;
6767
private static boolean running = false; // Determines whether the game is currently in process
6868
private static InputHandler input; // Accepts keyboard input and follows the appropriate actions
6969
private static MouseHandler mouse; // Tracks mouse movement and clicks, and follows the appropriate actions
7070
private static InputContext context; // Provides methods to control text input facilities
71-
7271
// Graphics
7372
private final BufferedImage image = new BufferedImage(WIDTH, HEIGHT, BufferedImage.TYPE_INT_RGB);
7473
private final int[] pixels = ((DataBufferInt) image.getRaster().getDataBuffer()).getData(); // Array of red, green and blue values for each pixel
@@ -78,7 +77,6 @@ public class Game extends Canvas implements Runnable {
7877
private final Printer printer = new Printer();
7978
boolean musicPlaying = false;
8079
private int tickCount = 0;
81-
private static final Screen screen = new Screen(WIDTH, HEIGHT, new SpriteSheet("/sprite_sheet.png"));
8280
private LevelHandler level; // Loads and renders levels along with tiles, entities, projectiles and more.
8381
//The entities of the game
8482
private Player player;
@@ -293,6 +291,28 @@ public static void setClosing(boolean closing) {
293291
Game.closingMode = closing;
294292
}
295293

294+
private static void mousePositionTracker() {
295+
MouseHandler mouseHandler = Game.getMouse();
296+
int mouseX = mouseHandler.getX();
297+
int mouseY = mouseHandler.getY();
298+
299+
// Adjust mouse coordinates based on the current offset and scale of the game world
300+
tileX = ((mouseX + 4 + screen.getxOffset()) / (8 * 2)) + screen.getxOffset() / 16;
301+
tileY = ((mouseY + 4 + screen.getyOffset()) / (8 * 2)) + screen.getyOffset() / 16;
302+
}
303+
304+
public static int getTileX() {
305+
return tileX;
306+
}
307+
308+
public static int getTileY() {
309+
return tileY;
310+
}
311+
312+
public static Screen getScreen() {
313+
return screen;
314+
}
315+
296316
/*
297317
* This method initializes the game once it starts. It populates the colour array with actual colours (6 shades each of RGB).
298318
* This method also builds the initial game level (custom_level), spawns a new vendor NPC, and begins accepting keyboard and mouse input/tracking.
@@ -394,14 +414,8 @@ public void run() {
394414
* This method updates the logic of the game.
395415
*/
396416
public void tick() {
397-
boolean beforeMusic = musicPlaying;
398417
setTickCount(getTickCount() + 1);
399-
Either<Exception, Boolean> musicKeyAction = input.toggleActionWithCheckedRunnable(
400-
input.getM_KEY(),
401-
musicPlaying,
402-
() -> Game.getBackgroundMusic().play(),
403-
() -> Game.getBackgroundMusic().stop()
404-
);
418+
Either<Exception, Boolean> musicKeyAction = input.toggleActionWithCheckedRunnable(input.getM_KEY(), musicPlaying, () -> Game.getBackgroundMusic().play(), () -> Game.getBackgroundMusic().stop());
405419
musicKeyAction.either(exception -> {
406420
printer.cast().print("Failed to play music", PrintTypes.MUSIC);
407421
printer.exception(exception.toString());
@@ -412,11 +426,9 @@ public void tick() {
412426
input.overWriteKey(input.getM_KEY(), false);
413427
}
414428
});
415-
416429
level.tick();
417430
}
418431

419-
420432
/**
421433
* This method displays the current state of the game.
422434
*/
@@ -524,8 +536,7 @@ private void status(Graphics2D g, boolean TerminalMode, boolean TerminalQuit) {
524536
g.drawString("Mouse: " + getMouse().getX() + "x |" + getMouse().getY() + "y", 0, 70);
525537
g.drawString("Mouse: " + (getMouse().getX() - 639 / 2d) + "x |" + (getMouse().getY() - 423 / 2d) + "y", 0, 85);
526538
if (getMouse().getButton() != -1) g.drawString("Button: " + getMouse().getButton(), 0, 100);
527-
g.setColor(Color.WHITE);
528-
g.fillRect(getMouse().getX() - 12, getMouse().getY() - 12, 16, 16);
539+
mousePositionTracker();
529540
g.drawString("Player: " + (int) player.getX() + "x |" + (int) player.getY() + "y", 0, 115);
530541
double angle = Math.atan2(getMouse().getY() - player.getPlayerAbsY(), getMouse().getX() - player.getPlayerAbsX()) * (180.0 / Math.PI);
531542
g.drawString("Angle: " + angle, 0, 130);
@@ -539,9 +550,9 @@ private void status(Graphics2D g, boolean TerminalMode, boolean TerminalQuit) {
539550
g.setColor(Color.GREEN); // Green for the new line from the player's origin
540551
g.drawLine(player.getPlayerAbsX(), player.getPlayerAbsY(), getMouse().getX(), getMouse().getY()); // Draw the line from the player's origin to the cursor
541552
g.setColor(Color.DARK_GRAY);
542-
g.drawLine(getWidth()/2+8, getHeight()/2-8, getMouse().getX(), getMouse().getY()); // Draw the line from the player's origin to the cursor
543-
g.drawLine(getWidth()/2+8, 0, getWidth()/2+8, getHeight()-30);
544-
g.drawLine(0, getHeight()/2-8, getWidth(), getHeight()/2-8);
553+
g.drawLine(getWidth() / 2 + 8, getHeight() / 2 - 8, getMouse().getX(), getMouse().getY()); // Draw the line from the player's origin to the cursor
554+
g.drawLine(getWidth() / 2 + 8, 0, getWidth() / 2 + 8, getHeight() - 30);
555+
g.drawLine(0, getHeight() / 2 - 8, getWidth(), getHeight() / 2 - 8);
545556
g.setColor(Color.yellow);
546557
g.fillRect(player.getPlayerAbsX(), player.getPlayerAbsY(), 1, 1);
547558

@@ -573,8 +584,4 @@ public Vendor getVendor() {
573584
public void setVendor(Vendor vendor) {
574585
this.vendor = vendor;
575586
}
576-
577-
public static Screen getScreen() {
578-
return screen;
579-
}
580587
}

src/com/redomar/game/gfx/Colours.java

Lines changed: 44 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -12,10 +12,51 @@ private static int get(int colour) {
1212
return 255;
1313
}
1414

15-
int r = colour / 100 % 10;
16-
int g = colour / 10 % 10;
17-
int b = colour % 10;
15+
int r = Math.min(Math.abs((colour / 100 % 10)), 5);
16+
int g = Math.min(Math.abs((colour / 10 % 10)), 5);
17+
int b = Math.min(Math.abs((colour % 10)), 5);
1818

1919
return r * 36 + g * 6 + b;
2020
}
21+
22+
public static int highlight(int colour) {
23+
24+
if (colour < 0) {
25+
return 255;
26+
}
27+
28+
int r = Math.min(Math.abs((colour / 100 % 10) + 1), 5);
29+
int g = Math.min(Math.abs((colour / 10 % 10) + 1), 5);
30+
int b = Math.min(Math.abs((colour % 10) + 1), 5);
31+
32+
return r * 36 + g * 6 + b;
33+
}
34+
35+
public static int[] getColours(int packedColours) {
36+
int[] colours = new int[4];
37+
38+
// Extract each colour component
39+
colours[3] = reverseGet((packedColours >> 24) & 0xFF); // colour4
40+
colours[2] = reverseGet((packedColours >> 16) & 0xFF); // colour3
41+
colours[1] = reverseGet((packedColours >> 8) & 0xFF); // colour2
42+
colours[0] = reverseGet(packedColours & 0xFF); // colour1
43+
44+
return colours;
45+
}
46+
47+
private static int reverseGet(int colour) {
48+
if (colour == 255) {
49+
return -1; // Original colour was less than 0
50+
}
51+
52+
int r = colour / 36;
53+
int g = (colour / 6) % 6;
54+
int b = colour % 6;
55+
56+
return r * 100 + g * 10 + b;
57+
}
58+
59+
public static int highlight(int colour, int colour1, int colour2, int colour3) {
60+
return (highlight(colour3) << 24) + (highlight(colour2) << 16) + (highlight(colour1) << 8) + (highlight(colour));
61+
}
2162
}

src/com/redomar/game/gfx/lighting/Night.java

Lines changed: 11 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
package com.redomar.game.gfx.lighting;
22

3+
import com.redomar.game.Game;
34
import com.redomar.game.gfx.Screen;
45

56
import java.awt.*;
@@ -20,10 +21,18 @@ public void render(int playerX, int playerY) {
2021
double size = 160;
2122

2223
g.setColor(new Color(0f, 0f, 0f, 0.8f));
23-
Shape shape = new Rectangle(0, 0, screen.getViewPortWidth(), screen.getViewPortHeight() - 30);
24+
Shape rectangle = new Rectangle(0, 0, screen.getViewPortWidth(), screen.getViewPortHeight() - 30);
2425
Shape circle = new Ellipse2D.Double(playerX - size / 2, playerY - size / 2, size, size);
25-
Area area = new Area(shape);
26+
int mouseX = Game.getMouse().getX();
27+
int mouseY = Game.getMouse().getY();
28+
29+
// Adjust mouse coordinates based on the current offset and scale of the game world
30+
int tileX = ((mouseX) / (8 * 2));
31+
int tileY = ((mouseY) / (8 * 2));
32+
Shape smallRectangle = new Rectangle(tileX * 16 - 16, tileY * 16 - 16, 48, 48);
33+
Area area = new Area(rectangle);
2634
area.subtract(new Area(circle));
35+
area.subtract(new Area(smallRectangle));
2736
g.fill(area);
2837
}
2938
}

src/com/redomar/game/level/LevelHandler.java

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,10 @@
1313
import java.awt.image.BufferedImage;
1414
import java.io.File;
1515
import java.io.IOException;
16-
import java.util.*;
16+
import java.util.ArrayList;
17+
import java.util.Comparator;
18+
import java.util.List;
19+
import java.util.Objects;
1720
import java.util.logging.Level;
1821

1922
public class LevelHandler {

src/com/redomar/game/level/tiles/BasicTile.java

Lines changed: 12 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,14 @@
11
package com.redomar.game.level.tiles;
22

3+
import com.redomar.game.Game;
4+
import com.redomar.game.gfx.Colours;
35
import com.redomar.game.gfx.Screen;
46
import com.redomar.game.level.LevelHandler;
57

68
public class BasicTile extends Tile {
79

8-
protected int tileId;
910
protected final int tileColour;
11+
protected int tileId;
1012

1113
public BasicTile(int id, int x, int y, int tileColour, int levelColour) {
1214
super(id, false, false, levelColour);
@@ -21,7 +23,15 @@ public void tick() {
2123

2224
@Override
2325
public void render(Screen screen, LevelHandler level, int x, int y) {
24-
screen.render(x, y, tileId, tileColour, 0x00, 1);
26+
int[] colours = Colours.getColours(tileColour);
27+
int mouseOverTileX = Game.getTileX();
28+
int mouseOverTileY = Game.getTileY();
29+
30+
if (mouseOverTileX == x / 8 && mouseOverTileY == y / 8) {
31+
screen.render(x, y, tileId, Colours.highlight(colours[0], colours[1], colours[2], colours[3]), 0x00, 1);
32+
} else {
33+
screen.render(x, y, tileId, Colours.get(colours[0], colours[1], colours[2], colours[3]), 0x00, 1);
34+
}
2535
}
2636

2737
}

src/com/redomar/game/level/tiles/Tile.java

Lines changed: 53 additions & 40 deletions
Original file line numberDiff line numberDiff line change
@@ -9,61 +9,55 @@
99
public abstract class Tile {
1010

1111
private static final Tile[] tiles = new Tile[256];
12+
1213
static {
13-
/* VOID */ tiles[0] = new SolidTile(0, 0, 0, Colours.get(0, -1, -1, -1), 0xFF000000);
14-
/* STONE */ tiles[1] = new SolidTile(1, 1, 0, Colours.get(-1, 444, 333, -1), 0xFF555555);
15-
/* CHISELED_stone */ tiles[2] = new BasicTile(2, 2, 0, Colours.get(-1, 333, 222, -1), 0xFF666666);
16-
/* GRASS */ tiles[3] = new BasicTile(3, 3, 0, Colours.get(-1, 131, 141, -1), 0xFF00FF00);
17-
/* WATER */ tiles[4] = new AnimatedTile(4, new int[][] { { 0, 5 }, { 1, 5 }, { 2, 5 }, { 1, 5 } }, Colours.get(-1, 004, 115, -1), 0xFF0000FF, 1000);
18-
/* FLOWER_rose */ tiles[5] = new BasicTile(5, 4, 0, Colours.get(131, 151, 510, 553), 0xFFCCFF33);
19-
/* FLOWER_dandelion */ tiles[6] = new BasicTile(6, 4, 0, Colours.get(131, 151, 553, 510), 0xFFFFCC33);
20-
/* SAND */ tiles[7] = new BasicTile(7, 5, 0, Colours.get(-1, 553, 554, 555), 0xFFFFFF99);
21-
/* CHEST_a */ tiles[8] = new SolidTile(8, 0, 1, Colours.get(333, 111, 420, 000), 0xFFFF0001);
22-
/* CHEST_b */ tiles[9] = new SolidTile(9, 1, 1, Colours.get(333, 111, 420, 000), 0xFFFF0002);
23-
/* CARPET_red */ tiles[10] = new BasicTile(10, 5, 0, Colours.get(-1, 311, 411, 311), 0xFFAA3636);
24-
/* PORTAL */ tiles[11] = new AnimatedTile(11, new int[][] { { 3, 5 }, { 4, 5 }, { 5, 5 }, { 6, 5 }, { 7, 5 }, { 8, 5 }, { 9, 5 }, { 10, 5 } }, Colours.get(-1, 005, 305, -1), 0xFF00EAFF, 100);
25-
/* MAGMA */ tiles[12] = new AnimatedTile(12, new int[][] { { 0, 5 }, { 1, 5 }, { 2, 5 }, { 1, 5 } }, Colours.get(-1, 400, 511, -1), 0xFFF00F0F, 1000);
26-
/* DIRT */ tiles[13] = new BasicTile(13, 3, 0, Colours.get(0, 210, 321, -1), 0xFF442200);
27-
/* DIRT_WET */ tiles[14] = new AnimatedTile(14, new int[][] { { 1, 5 }, { 2, 5 } }, Colours.get(-1, 211, 322, -1), 0xFF663300, 1500);
14+
/* VOID */
15+
tiles[0] = new SolidTile(0, 0, 0, Colours.get(0, -1, -1, -1), 0xFF000000);
16+
/* STONE */
17+
tiles[1] = new SolidTile(1, 1, 0, Colours.get(-1, 444, 333, -1), 0xFF555555);
18+
/* CHISELED_stone */
19+
tiles[2] = new BasicTile(2, 2, 0, Colours.get(-1, 333, 222, -1), 0xFF666666);
20+
/* GRASS */
21+
tiles[3] = new BasicTile(3, 3, 0, Colours.get(-1, 131, 141, -1), 0xFF00FF00);
22+
/* WATER */
23+
tiles[4] = new AnimatedTile(4, new int[][]{{0, 5}, {1, 5}, {2, 5}, {1, 5}}, Colours.get(-1, 004, 115, -1), 0xFF0000FF, 1000);
24+
/* FLOWER_rose */
25+
tiles[5] = new BasicTile(5, 4, 0, Colours.get(131, 151, 510, 553), 0xFFCCFF33);
26+
/* FLOWER_dandelion */
27+
tiles[6] = new BasicTile(6, 4, 0, Colours.get(131, 151, 553, 510), 0xFFFFCC33);
28+
/* SAND */
29+
tiles[7] = new BasicTile(7, 5, 0, Colours.get(-1, 553, 554, 555), 0xFFFFFF99);
30+
/* CHEST_a */
31+
tiles[8] = new SolidTile(8, 0, 1, Colours.get(333, 111, 420, 000), 0xFFFF0001);
32+
/* CHEST_b */
33+
tiles[9] = new SolidTile(9, 1, 1, Colours.get(333, 111, 420, 000), 0xFFFF0002);
34+
/* CARPET_red */
35+
tiles[10] = new BasicTile(10, 5, 0, Colours.get(-1, 311, 411, 311), 0xFFAA3636);
36+
/* PORTAL */
37+
tiles[11] = new AnimatedTile(11, new int[][]{{3, 5}, {4, 5}, {5, 5}, {6, 5}, {7, 5}, {8, 5}, {9, 5}, {10, 5}}, Colours.get(-1, 005, 305, -1), 0xFF00EAFF, 100);
38+
/* MAGMA */
39+
tiles[12] = new AnimatedTile(12, new int[][]{{0, 5}, {1, 5}, {2, 5}, {1, 5}}, Colours.get(-1, 400, 511, -1), 0xFFF00F0F, 1000);
40+
/* DIRT */
41+
tiles[13] = new BasicTile(13, 3, 0, Colours.get(0, 210, 321, -1), 0xFF442200);
42+
/* DIRT_WET */
43+
tiles[14] = new AnimatedTile(14, new int[][]{{1, 5}, {2, 5}}, Colours.get(-1, 211, 322, -1), 0xFF663300, 1500);
2844
}
45+
2946
protected final byte id;
30-
protected boolean solid;
3147
protected final boolean emitter;
3248
protected final int levelColour;
49+
protected boolean solid;
3350

3451
protected Tile(int id, boolean solid, boolean emitter, int levelColour) {
3552
this.id = (byte) id;
3653
this.solid = solid;
3754
this.emitter = emitter;
3855
this.levelColour = levelColour;
3956

40-
if (tiles[id] != null) {
41-
throw new RuntimeException("Duplicate tile id: " + id);
42-
}
4357

4458
tiles[id] = this;
4559
}
4660

47-
public byte getId() {
48-
return id;
49-
}
50-
51-
public boolean isSolid() {
52-
return solid;
53-
}
54-
55-
public boolean isEmitter() {
56-
return emitter;
57-
}
58-
59-
public abstract void tick();
60-
61-
public abstract void render(Screen screen, LevelHandler level, int x, int y);
62-
63-
public int getLevelColour() {
64-
return levelColour;
65-
}
66-
6761
public static Tile getTile(int id) {
6862
return tiles[id];
6963
}
@@ -76,12 +70,31 @@ public static Tile getGrass() {
7670
return getTile(2);
7771
}
7872

79-
8073
public static Tile getVoid() {
8174
return getTile(0);
8275
}
8376

8477
public static Tile[] getTiles() {
8578
return tiles;
8679
}
80+
81+
public byte getId() {
82+
return id;
83+
}
84+
85+
public boolean isSolid() {
86+
return solid;
87+
}
88+
89+
public boolean isEmitter() {
90+
return emitter;
91+
}
92+
93+
public abstract void tick();
94+
95+
public abstract void render(Screen screen, LevelHandler level, int x, int y);
96+
97+
public int getLevelColour() {
98+
return levelColour;
99+
}
87100
}

0 commit comments

Comments
 (0)