diff --git a/res/levels/small_test_level.png b/res/levels/small_test_level.png new file mode 100644 index 0000000..9a3f3b7 Binary files /dev/null and b/res/levels/small_test_level.png differ diff --git a/res/levels/water_test_level.png b/res/levels/water_test_level.png new file mode 100644 index 0000000..530ec0b Binary files /dev/null and b/res/levels/water_test_level.png differ diff --git a/res/sprite_sheet.png b/res/sprite_sheet.png new file mode 100644 index 0000000..241972f Binary files /dev/null and b/res/sprite_sheet.png differ diff --git a/src/ca/vanzeben/game/Game.java b/src/ca/vanzeben/game/Game.java new file mode 100644 index 0000000..1dccad3 --- /dev/null +++ b/src/ca/vanzeben/game/Game.java @@ -0,0 +1,177 @@ +package ca.vanzeben.game; + +import java.awt.BorderLayout; +import java.awt.Canvas; +import java.awt.Dimension; +import java.awt.Graphics; +import java.awt.image.BufferStrategy; +import java.awt.image.BufferedImage; +import java.awt.image.DataBufferInt; + +import javax.swing.JFrame; +import javax.swing.JOptionPane; + +import ca.vanzeben.game.entities.Player; +import ca.vanzeben.game.gfx.Screen; +import ca.vanzeben.game.gfx.SpriteSheet; +import ca.vanzeben.game.level.Level; + +public class Game extends Canvas implements Runnable { + + private static final long serialVersionUID = 1L; + + public static final int WIDTH = 160; + public static final int HEIGHT = WIDTH / 12 * 9; + public static final int SCALE = 3; + public static final String NAME = "Game"; + + private JFrame frame; + + public boolean running = false; + public int tickCount = 0; + + private BufferedImage image = new BufferedImage(WIDTH, HEIGHT, BufferedImage.TYPE_INT_RGB); + private int[] pixels = ((DataBufferInt) image.getRaster().getDataBuffer()).getData(); + private int[] colours = new int[6 * 6 * 6]; + + private Screen screen; + public InputHandler input; + public Level level; + public Player player; + + public Game() { + setMinimumSize(new Dimension(WIDTH * SCALE, HEIGHT * SCALE)); + setMaximumSize(new Dimension(WIDTH * SCALE, HEIGHT * SCALE)); + setPreferredSize(new Dimension(WIDTH * SCALE, HEIGHT * SCALE)); + + frame = new JFrame(NAME); + + frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); + frame.setLayout(new BorderLayout()); + + frame.add(this, BorderLayout.CENTER); + frame.pack(); + + frame.setResizable(false); + frame.setLocationRelativeTo(null); + frame.setVisible(true); + } + + public void init() { + int index = 0; + for (int r = 0; r < 6; r++) { + for (int g = 0; g < 6; g++) { + for (int b = 0; b < 6; b++) { + int rr = (r * 255 / 5); + int gg = (g * 255 / 5); + int bb = (b * 255 / 5); + + colours[index++] = rr << 16 | gg << 8 | bb; + } + } + } + screen = new Screen(WIDTH, HEIGHT, new SpriteSheet("/sprite_sheet.png")); + input = new InputHandler(this); + level = new Level("/levels/water_test_level.png"); + player = new Player(level, 0, 0, input, JOptionPane.showInputDialog(this, "Please enter a username")); + level.addEntity(player); + } + + public synchronized void start() { + running = true; + new Thread(this).start(); + } + + public synchronized void stop() { + running = false; + } + + public void run() { + long lastTime = System.nanoTime(); + double nsPerTick = 1000000000D / 60D; + + int ticks = 0; + int frames = 0; + + long lastTimer = System.currentTimeMillis(); + double delta = 0; + + init(); + + while (running) { + long now = System.nanoTime(); + delta += (now - lastTime) / nsPerTick; + lastTime = now; + boolean shouldRender = true; + + while (delta >= 1) { + ticks++; + tick(); + delta -= 1; + shouldRender = true; + } + + try { + Thread.sleep(2); + } catch (InterruptedException e) { + e.printStackTrace(); + } + + if (shouldRender) { + frames++; + render(); + } + + if (System.currentTimeMillis() - lastTimer >= 1000) { + lastTimer += 1000; + System.out.println(ticks + " ticks, " + frames + " frames"); + frames = 0; + ticks = 0; + } + } + } + + public void tick() { + tickCount++; + level.tick(); + } + + public void render() { + BufferStrategy bs = getBufferStrategy(); + if (bs == null) { + createBufferStrategy(3); + return; + } + + int xOffset = player.x - (screen.width / 2); + int yOffset = player.y - (screen.height / 2); + + level.renderTiles(screen, xOffset, yOffset); + level.renderEntities(screen); + + for (int y = 0; y < screen.height; y++) { + for (int x = 0; x < screen.width; x++) { + int colourCode = screen.pixels[x + y * screen.width]; + if (colourCode < 255) + pixels[x + y * WIDTH] = colours[colourCode]; + } + } + + Graphics g = bs.getDrawGraphics(); + g.drawImage(image, 0, 0, getWidth(), getHeight(), null); + g.dispose(); + bs.show(); + } + + public static void main(String[] args) { + new Game().start(); + } + + public static long fact(int n) { + if (n <= 1) { + return 1; + } else { + return n * fact(n - 1); + } + } +} diff --git a/src/ca/vanzeben/game/InputHandler.java b/src/ca/vanzeben/game/InputHandler.java new file mode 100644 index 0000000..07f9160 --- /dev/null +++ b/src/ca/vanzeben/game/InputHandler.java @@ -0,0 +1,60 @@ +package ca.vanzeben.game; + +import java.awt.event.KeyEvent; +import java.awt.event.KeyListener; + +public class InputHandler implements KeyListener { + + public InputHandler(Game game) { + game.addKeyListener(this); + } + + public class Key { + private int numTimesPressed = 0; + private boolean pressed = false; + + public int getNumTimesPressed() { + return numTimesPressed; + } + + public boolean isPressed() { + return pressed; + } + + public void toggle(boolean isPressed) { + pressed = isPressed; + if (isPressed) numTimesPressed++; + } + } + + public Key up = new Key(); + public Key down = new Key(); + public Key left = new Key(); + public Key right = new Key(); + + public void keyPressed(KeyEvent e) { + toggleKey(e.getKeyCode(), true); + } + + public void keyReleased(KeyEvent e) { + toggleKey(e.getKeyCode(), false); + } + + public void keyTyped(KeyEvent e) { + } + + public void toggleKey(int keyCode, boolean isPressed) { + if (keyCode == KeyEvent.VK_W || keyCode == KeyEvent.VK_UP) { + up.toggle(isPressed); + } + if (keyCode == KeyEvent.VK_S || keyCode == KeyEvent.VK_DOWN) { + down.toggle(isPressed); + } + if (keyCode == KeyEvent.VK_A || keyCode == KeyEvent.VK_LEFT) { + left.toggle(isPressed); + } + if (keyCode == KeyEvent.VK_D || keyCode == KeyEvent.VK_RIGHT) { + right.toggle(isPressed); + } + } +} diff --git a/src/ca/vanzeben/game/entities/Entity.java b/src/ca/vanzeben/game/entities/Entity.java new file mode 100644 index 0000000..70551a3 --- /dev/null +++ b/src/ca/vanzeben/game/entities/Entity.java @@ -0,0 +1,22 @@ +package ca.vanzeben.game.entities; + +import ca.vanzeben.game.gfx.Screen; +import ca.vanzeben.game.level.Level; + +public abstract class Entity { + + public int x, y; + protected Level level; + + public Entity(Level level) { + init(level); + } + + public final void init(Level level) { + this.level = level; + } + + public abstract void tick(); + + public abstract void render(Screen screen); +} diff --git a/src/ca/vanzeben/game/entities/Mob.java b/src/ca/vanzeben/game/entities/Mob.java new file mode 100644 index 0000000..fcd70f6 --- /dev/null +++ b/src/ca/vanzeben/game/entities/Mob.java @@ -0,0 +1,63 @@ +package ca.vanzeben.game.entities; + +import ca.vanzeben.game.level.Level; +import ca.vanzeben.game.level.tiles.Tile; + +public abstract class Mob extends Entity { + + protected String name; + protected int speed; + protected int numSteps = 0; + protected boolean isMoving; + protected int movingDir = 1; + protected int scale = 1; + + public Mob(Level level, String name, int x, int y, int speed) { + super(level); + this.name = name; + this.x = x; + this.y = y; + this.speed = speed; + } + + public void move(int xa, int ya) { + if (xa != 0 && ya != 0) { + move(xa, 0); + move(0, ya); + numSteps--; + return; + } + numSteps++; + if (!hasCollided(xa, ya)) { + if (ya < 0) + movingDir = 0; + if (ya > 0) + movingDir = 1; + if (xa < 0) + movingDir = 2; + if (xa > 0) + movingDir = 3; + x += xa * speed; + y += ya * speed; + } + } + + public abstract boolean hasCollided(int xa, int ya); + + protected boolean isSolidTile(int xa, int ya, int x, int y) { + if (level == null) { + return false; + } + Tile lastTile = level.getTile((this.x + x) >> 3, (this.y + y) >> 3); + Tile newTile = level.getTile((this.x + x + xa) >> 3, (this.y + y + ya) >> 3); + if (!lastTile.equals(newTile) && newTile.isSolid()) { + return true; + } + return false; + } + + public String getName() { + return name; + } + +} diff --git a/src/ca/vanzeben/game/entities/Player.java b/src/ca/vanzeben/game/entities/Player.java new file mode 100644 index 0000000..2757cf2 --- /dev/null +++ b/src/ca/vanzeben/game/entities/Player.java @@ -0,0 +1,133 @@ +package ca.vanzeben.game.entities; + +import ca.vanzeben.game.InputHandler; +import ca.vanzeben.game.gfx.Colours; +import ca.vanzeben.game.gfx.Font; +import ca.vanzeben.game.gfx.Screen; +import ca.vanzeben.game.level.Level; + +public class Player extends Mob { + + private InputHandler input; + private int colour = Colours.get(-1, 111, 145, 543); + private int scale = 1; + protected boolean isSwimming = false; + private int tickCount = 0; + private String username; + + public Player(Level level, int x, int y, InputHandler input, String username) { + super(level, "Player", x, y, 1); + this.input = input; + this.username = username; + } + + public void tick() { + int xa = 0; + int ya = 0; + + if (input.up.isPressed()) { + ya--; + } + if (input.down.isPressed()) { + ya++; + } + if (input.left.isPressed()) { + xa--; + } + if (input.right.isPressed()) { + xa++; + } + + if (xa != 0 || ya != 0) { + move(xa, ya); + isMoving = true; + } else { + isMoving = false; + } + if (level.getTile(this.x >> 3, this.y >> 3).getId() == 3) { + isSwimming = true; + } + if (isSwimming && level.getTile(this.x >> 3, this.y >> 3).getId() != 3) { + isSwimming = false; + } + tickCount++; + } + + public void render(Screen screen) { + int xTile = 0; + int yTile = 28; + int walkingSpeed = 4; + int flipTop = (numSteps >> walkingSpeed) & 1; + int flipBottom = (numSteps >> walkingSpeed) & 1; + + if (movingDir == 1) { + xTile += 2; + } else if (movingDir > 1) { + xTile += 4 + ((numSteps >> walkingSpeed) & 1) * 2; + flipTop = (movingDir - 1) % 2; + } + + int modifier = 8 * scale; + int xOffset = x - modifier / 2; + int yOffset = y - modifier / 2 - 4; + if (isSwimming) { + int waterColour = 0; + yOffset += 4; + if (tickCount % 60 < 15) { + waterColour = Colours.get(-1, -1, 225, -1); + } else if (15 <= tickCount % 60 && tickCount % 60 < 30) { + yOffset -= 1; + waterColour = Colours.get(-1, 225, 115, -1); + } else if (30 <= tickCount % 60 && tickCount % 60 < 45) { + waterColour = Colours.get(-1, 115, -1, 225); + } else { + yOffset -= 1; + waterColour = Colours.get(-1, 225, 115, -1); + } + screen.render(xOffset, yOffset + 3, 0 + 27 * 32, waterColour, 0x00, 1); + screen.render(xOffset + 8, yOffset + 3, 0 + 27 * 32, waterColour, 0x01, 1); + } + screen.render(xOffset + (modifier * flipTop), yOffset, xTile + yTile * 32, colour, flipTop, scale); + screen.render(xOffset + modifier - (modifier * flipTop), yOffset, (xTile + 1) + yTile * 32, colour, flipTop, + scale); + + if (!isSwimming) { + screen.render(xOffset + (modifier * flipBottom), yOffset + modifier, xTile + (yTile + 1) * 32, colour, + flipBottom, scale); + screen.render(xOffset + modifier - (modifier * flipBottom), yOffset + modifier, (xTile + 1) + (yTile + 1) + * 32, colour, flipBottom, scale); + } + if (username != null) { + Font.render(username, screen, xOffset - ((username.length() - 1) / 2 * 8), yOffset - 10, + Colours.get(-1, -1, -1, 555), 1); + } + } + + public boolean hasCollided(int xa, int ya) { + int xMin = 0; + int xMax = 7; + int yMin = 3; + int yMax = 7; + for (int x = xMin; x < xMax; x++) { + if (isSolidTile(xa, ya, x, yMin)) { + return true; + } + } + for (int x = xMin; x < xMax; x++) { + if (isSolidTile(xa, ya, x, yMax)) { + return true; + } + } + for (int y = yMin; y < yMax; y++) { + if (isSolidTile(xa, ya, xMin, y)) { + return true; + } + } + for (int y = yMin; y < yMax; y++) { + if (isSolidTile(xa, ya, xMax, y)) { + return true; + } + } + return false; + } +} diff --git a/src/ca/vanzeben/game/gfx/Colours.java b/src/ca/vanzeben/game/gfx/Colours.java new file mode 100644 index 0000000..ff737b3 --- /dev/null +++ b/src/ca/vanzeben/game/gfx/Colours.java @@ -0,0 +1,16 @@ +package ca.vanzeben.game.gfx; + +public class Colours { + + public static int get(int colour1, int colour2, int colour3, int colour4) { + return (get(colour4) << 24) + (get(colour3) << 16) + (get(colour2) << 8) + get(colour1); + } + + private static int get(int colour) { + if (colour < 0) return 255; + int r = colour / 100 % 10; + int g = colour / 10 % 10; + int b = colour % 10; + return r * 36 + g * 6 + b; + } +} diff --git a/src/ca/vanzeben/game/gfx/Font.java b/src/ca/vanzeben/game/gfx/Font.java new file mode 100644 index 0000000..bef06b1 --- /dev/null +++ b/src/ca/vanzeben/game/gfx/Font.java @@ -0,0 +1,16 @@ +package ca.vanzeben.game.gfx; + +public class Font { + + private static String chars = "" + "ABCDEFGHIJKLMNOPQRSTUVWXYZ " + "0123456789.,:;'\"!?$%()-=+/ "; + + public static void render(String msg, Screen screen, int x, int y, int colour, int scale) { + msg = msg.toUpperCase(); + + for (int i = 0; i < msg.length(); i++) { + int charIndex = chars.indexOf(msg.charAt(i)); + if (charIndex >= 0) + screen.render(x + (i * 8), y, charIndex + 30 * 32, colour, 0x00, scale); + } + } +} diff --git a/src/ca/vanzeben/game/gfx/Screen.java b/src/ca/vanzeben/game/gfx/Screen.java new file mode 100644 index 0000000..fc738b9 --- /dev/null +++ b/src/ca/vanzeben/game/gfx/Screen.java @@ -0,0 +1,72 @@ +package ca.vanzeben.game.gfx; + +public class Screen { + + public static final int MAP_WIDTH = 64; + public static final int MAP_WIDTH_MASK = MAP_WIDTH - 1; + + public static final byte BIT_MIRROR_X = 0x01; + public static final byte BIT_MIRROR_Y = 0x02; + + public int[] pixels; + + public int xOffset = 0; + public int yOffset = 0; + + public int width; + public int height; + + public SpriteSheet sheet; + + public Screen(int width, int height, SpriteSheet sheet) { + this.width = width; + this.height = height; + this.sheet = sheet; + + pixels = new int[width * height]; + } + + public void render(int xPos, int yPos, int tile, int colour, int mirrorDir, int scale) { + xPos -= xOffset; + yPos -= yOffset; + + boolean mirrorX = (mirrorDir & BIT_MIRROR_X) > 0; + boolean mirrorY = (mirrorDir & BIT_MIRROR_Y) > 0; + + int scaleMap = scale - 1; + int xTile = tile % 32; + int yTile = tile / 32; + int tileOffset = (xTile << 3) + (yTile << 3) * sheet.width; + for (int y = 0; y < 8; y++) { + int ySheet = y; + if (mirrorY) + ySheet = 7 - y; + + int yPixel = y + yPos + (y * scaleMap) - ((scaleMap << 3) / 2); + + for (int x = 0; x < 8; x++) { + int xSheet = x; + if (mirrorX) + xSheet = 7 - x; + int xPixel = x + xPos + (x * scaleMap) - ((scaleMap << 3) / 2); + int col = (colour >> (sheet.pixels[xSheet + ySheet * sheet.width + tileOffset] * 8)) & 255; + if (col < 255) { + for (int yScale = 0; yScale < scale; yScale++) { + if (yPixel + yScale < 0 || yPixel + yScale >= height) + continue; + for (int xScale = 0; xScale < scale; xScale++) { + if (xPixel + xScale < 0 || xPixel + xScale >= width) + continue; + pixels[(xPixel + xScale) + (yPixel + yScale) * width] = col; + } + } + } + } + } + } + + public void setOffset(int xOffset, int yOffset) { + this.xOffset = xOffset; + this.yOffset = yOffset; + } +} diff --git a/src/ca/vanzeben/game/gfx/SpriteSheet.java b/src/ca/vanzeben/game/gfx/SpriteSheet.java new file mode 100644 index 0000000..23a1626 --- /dev/null +++ b/src/ca/vanzeben/game/gfx/SpriteSheet.java @@ -0,0 +1,36 @@ +package ca.vanzeben.game.gfx; + +import java.awt.image.BufferedImage; +import java.io.IOException; + +import javax.imageio.ImageIO; + +public class SpriteSheet { + + public String path; + public int width; + public int height; + + public int[] pixels; + + public SpriteSheet(String path) { + BufferedImage image = null; + try { + image = ImageIO.read(SpriteSheet.class.getResourceAsStream(path)); + } catch (IOException e) { + e.printStackTrace(); + } + + if (image == null) { return; } + + this.path = path; + this.width = image.getWidth(); + this.height = image.getHeight(); + + pixels = image.getRGB(0, 0, width, height, null, 0, width); + + for (int i = 0; i < pixels.length; i++) { + pixels[i] = (pixels[i] & 0xff) / 64; + } + } +} diff --git a/src/ca/vanzeben/game/level/Level.java b/src/ca/vanzeben/game/level/Level.java new file mode 100644 index 0000000..9dff8ce --- /dev/null +++ b/src/ca/vanzeben/game/level/Level.java @@ -0,0 +1,135 @@ +package ca.vanzeben.game.level; + +import java.awt.image.BufferedImage; +import java.io.File; +import java.io.IOException; +import java.util.ArrayList; +import java.util.List; + +import javax.imageio.ImageIO; + +import ca.vanzeben.game.entities.Entity; +import ca.vanzeben.game.gfx.Screen; +import ca.vanzeben.game.level.tiles.Tile; + +public class Level { + + private byte[] tiles; + public int width; + public int height; + public List entities = new ArrayList(); + private String imagePath; + private BufferedImage image; + + public Level(String imagePath) { + if (imagePath != null) { + this.imagePath = imagePath; + this.loadLevelFromFile(); + } else { + this.width = 64; + this.height = 64; + tiles = new byte[width * height]; + this.generateLevel(); + } + } + + private void loadLevelFromFile() { + try { + this.image = ImageIO.read(Level.class.getResource(this.imagePath)); + this.width = image.getWidth(); + this.height = image.getHeight(); + tiles = new byte[width * height]; + this.loadTiles(); + } catch (IOException e) { + e.printStackTrace(); + } + } + + private void loadTiles() { + int[] tileColours = this.image.getRGB(0, 0, width, height, null, 0, width); + for (int y = 0; y < height; y++) { + for (int x = 0; x < width; x++) { + tileCheck: for (Tile t : Tile.tiles) { + if (t != null && t.getLevelColour() == tileColours[x + y * width]) { + this.tiles[x + y * width] = t.getId(); + break tileCheck; + } + } + } + } + } + + private void saveLevelToFile() { + try { + ImageIO.write(image, "png", new File(Level.class.getResource(this.imagePath).getFile())); + } catch (IOException e) { + e.printStackTrace(); + } + } + + public void alterTile(int x, int y, Tile newTile) { + this.tiles[x + y * width] = newTile.getId(); + image.setRGB(x, y, newTile.getLevelColour()); + } + + public void generateLevel() { + for (int y = 0; y < height; y++) { + for (int x = 0; x < width; x++) { + if (x * y % 10 < 7) { + tiles[x + y * width] = Tile.GRASS.getId(); + } else { + tiles[x + y * width] = Tile.STONE.getId(); + } + } + } + } + + public void tick() { + for (Entity e : entities) { + e.tick(); + } + + for (Tile t : Tile.tiles) { + if (t == null) { + break; + } + t.tick(); + } + } + + public void renderTiles(Screen screen, int xOffset, int yOffset) { + if (xOffset < 0) + xOffset = 0; + if (xOffset > ((width << 3) - screen.width)) + xOffset = ((width << 3) - screen.width); + if (yOffset < 0) + yOffset = 0; + if (yOffset > ((height << 3) - screen.height)) + yOffset = ((height << 3) - screen.height); + + screen.setOffset(xOffset, yOffset); + + for (int y = (yOffset >> 3); y < (yOffset + screen.height >> 3) + 1; y++) { + for (int x = (xOffset >> 3); x < (xOffset + screen.width >> 3) + 1; x++) { + getTile(x, y).render(screen, this, x << 3, y << 3); + } + } + } + + public void renderEntities(Screen screen) { + for (Entity e : entities) { + e.render(screen); + } + } + + public Tile getTile(int x, int y) { + if (0 > x || x >= width || 0 > y || y >= height) + return Tile.VOID; + return Tile.tiles[tiles[x + y * width]]; + } + + public void addEntity(Entity entity) { + this.entities.add(entity); + } + +} diff --git a/src/ca/vanzeben/game/level/tiles/AnimatedTile.java b/src/ca/vanzeben/game/level/tiles/AnimatedTile.java new file mode 100644 index 0000000..f94c548 --- /dev/null +++ b/src/ca/vanzeben/game/level/tiles/AnimatedTile.java @@ -0,0 +1,25 @@ +package ca.vanzeben.game.level.tiles; + +public class AnimatedTile extends BasicTile { + + private int[][] animationTileCoords; + private int currentAnimationIndex; + private long lastIterationTime; + private int animationSwitchDelay; + + public AnimatedTile(int id, int[][] animationCoords, int tileColour, int levelColour, int animationSwitchDelay) { + super(id, animationCoords[0][0], animationCoords[0][1], tileColour, levelColour); + this.animationTileCoords = animationCoords; + this.currentAnimationIndex = 0; + this.lastIterationTime = System.currentTimeMillis(); + this.animationSwitchDelay = animationSwitchDelay; + } + + public void tick() { + if ((System.currentTimeMillis() - lastIterationTime) >= (animationSwitchDelay)) { + lastIterationTime = System.currentTimeMillis(); + currentAnimationIndex = (currentAnimationIndex + 1) % animationTileCoords.length; + this.tileId = (animationTileCoords[currentAnimationIndex][0] + (animationTileCoords[currentAnimationIndex][1] * 32)); + } + } +} diff --git a/src/ca/vanzeben/game/level/tiles/BasicSolidTile.java b/src/ca/vanzeben/game/level/tiles/BasicSolidTile.java new file mode 100644 index 0000000..883af29 --- /dev/null +++ b/src/ca/vanzeben/game/level/tiles/BasicSolidTile.java @@ -0,0 +1,10 @@ +package ca.vanzeben.game.level.tiles; + +public class BasicSolidTile extends BasicTile { + + public BasicSolidTile(int id, int x, int y, int tileColour, int levelColour) { + super(id, x, y, tileColour, levelColour); + this.solid = true; + } + +} diff --git a/src/ca/vanzeben/game/level/tiles/BasicTile.java b/src/ca/vanzeben/game/level/tiles/BasicTile.java new file mode 100644 index 0000000..3dc07e0 --- /dev/null +++ b/src/ca/vanzeben/game/level/tiles/BasicTile.java @@ -0,0 +1,24 @@ +package ca.vanzeben.game.level.tiles; + +import ca.vanzeben.game.gfx.Screen; +import ca.vanzeben.game.level.Level; + +public class BasicTile extends Tile { + + protected int tileId; + protected int tileColour; + + public BasicTile(int id, int x, int y, int tileColour, int levelColour) { + super(id, false, false, levelColour); + this.tileId = x + y * 32; + this.tileColour = tileColour; + } + + public void tick() { + } + + public void render(Screen screen, Level level, int x, int y) { + screen.render(x, y, tileId, tileColour, 0x00, 1); + } + +} diff --git a/src/ca/vanzeben/game/level/tiles/Tile.java b/src/ca/vanzeben/game/level/tiles/Tile.java new file mode 100644 index 0000000..71c963b --- /dev/null +++ b/src/ca/vanzeben/game/level/tiles/Tile.java @@ -0,0 +1,49 @@ +package ca.vanzeben.game.level.tiles; + +import ca.vanzeben.game.gfx.Colours; +import ca.vanzeben.game.gfx.Screen; +import ca.vanzeben.game.level.Level; + +public abstract class Tile { + + public static final Tile[] tiles = new Tile[256]; + public static final Tile VOID = new BasicSolidTile(0, 0, 0, Colours.get(000, -1, -1, -1), 0xFF000000); + public static final Tile STONE = new BasicSolidTile(1, 1, 0, Colours.get(-1, 333, -1, -1), 0xFF555555); + public static final Tile GRASS = new BasicTile(2, 2, 0, Colours.get(-1, 131, 141, -1), 0xFF00FF00); + public static final Tile WATER = new AnimatedTile(3, new int[][] { { 0, 5 }, { 1, 5 }, { 2, 5 }, { 1, 5 } }, + Colours.get(-1, 004, 115, -1), 0xFF0000FF, 1000); + protected byte id; + protected boolean solid; + protected boolean emitter; + private int levelColour; + + public Tile(int id, boolean isSolid, boolean isEmitter, int levelColour) { + this.id = (byte) id; + if (tiles[id] != null) + throw new RuntimeException("Duplicate tile id on " + id); + this.solid = isSolid; + this.emitter = isEmitter; + this.levelColour = levelColour; + tiles[id] = this; + } + + public byte getId() { + return id; + } + + public boolean isSolid() { + return solid; + } + + public boolean isEmitter() { + return emitter; + } + + public int getLevelColour() { + return levelColour; + } + + public abstract void tick(); + + public abstract void render(Screen screen, Level level, int x, int y); +}