Created
September 12, 2014 14:02
-
-
Save foolish314159/e0a5afd27f01e22dc4f4 to your computer and use it in GitHub Desktop.
DailyProgrammer Challenge 179 Intermediate - Dogelike
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| package dp179i; | |
| import java.awt.event.KeyEvent; | |
| import java.awt.event.KeyListener; | |
| import java.awt.event.MouseEvent; | |
| import java.awt.event.MouseMotionListener; | |
| import java.io.IOException; | |
| import javax.swing.JFrame; | |
| import javax.swing.WindowConstants; | |
| import dp179i.Level.Direction; | |
| public class Game implements KeyListener, MouseMotionListener { | |
| public static final int WINDOW_WIDTH = 800; | |
| public static final int WINDOW_HEIGHT = 800; | |
| public static final int FOOTER_HEIGHT = 20; | |
| private JFrame mFrame; | |
| private Level mLevel; | |
| public void start() throws IOException { | |
| // Setup frame | |
| mFrame = new JFrame(); | |
| mFrame.setUndecorated(true); | |
| mFrame.setBounds(50, 50, WINDOW_WIDTH, WINDOW_HEIGHT + FOOTER_HEIGHT); | |
| mFrame.setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE); | |
| mFrame.addKeyListener(this); | |
| mFrame.addMouseMotionListener(this); | |
| mFrame.setVisible(true); | |
| // Load level | |
| mLevel = new Level(mFrame); | |
| mLevel.draw(mFrame); | |
| } | |
| public static void main(String[] args) { | |
| Game game = new Game(); | |
| try { | |
| game.start(); | |
| } catch (IOException e) { | |
| e.printStackTrace(); | |
| } | |
| } | |
| @Override | |
| public void keyPressed(KeyEvent e) { | |
| Direction dir = null; | |
| switch (e.getKeyCode()) { | |
| case KeyEvent.VK_W: | |
| dir = Direction.UP; | |
| break; | |
| case KeyEvent.VK_A: | |
| dir = Direction.LEFT; | |
| break; | |
| case KeyEvent.VK_S: | |
| dir = Direction.DOWN; | |
| break; | |
| case KeyEvent.VK_D: | |
| dir = Direction.RIGHT; | |
| break; | |
| case KeyEvent.VK_R: | |
| try { | |
| mLevel = new Level(mFrame); | |
| } catch (IOException ex) { | |
| ex.printStackTrace(); | |
| } | |
| mLevel.draw(mFrame); | |
| break; | |
| case KeyEvent.VK_ESCAPE: | |
| mFrame.setVisible(false); | |
| mFrame.dispose(); | |
| return; | |
| } | |
| mLevel.movePlayer(dir); | |
| mLevel.draw(mFrame); | |
| } | |
| @Override | |
| public void mouseDragged(MouseEvent e) { | |
| e.getComponent().setLocation(e.getXOnScreen(), e.getYOnScreen()); | |
| } | |
| @Override | |
| public void mouseMoved(MouseEvent e) { | |
| } | |
| @Override | |
| public void keyReleased(KeyEvent arg0) { | |
| } | |
| @Override | |
| public void keyTyped(KeyEvent arg0) { | |
| } | |
| } |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| package dp179i; | |
| import java.awt.Color; | |
| import java.awt.Font; | |
| import java.awt.FontMetrics; | |
| import java.awt.Graphics; | |
| import java.awt.Graphics2D; | |
| import java.awt.image.BufferedImage; | |
| import java.io.IOException; | |
| import java.util.Arrays; | |
| import java.util.Random; | |
| import javax.imageio.ImageIO; | |
| import javax.swing.JFrame; | |
| import javax.swing.JPanel; | |
| public class Level { | |
| public enum Direction { | |
| UP, DOWN, LEFT, RIGHT; | |
| } | |
| public enum Tile { | |
| Empty, Player, Coin, Wall, Food, LevelLoader; | |
| } | |
| public static final int LEVEL_WIDTH = 20; | |
| public static final int LEVEL_HEIGHT = 20; | |
| private Tile[][] mTiles = new Tile[LEVEL_WIDTH][LEVEL_HEIGHT]; | |
| private DrawPane mPane; | |
| private int mPlayerX = 5; | |
| private int mPlayerY = 5; | |
| private int mMovementPoints = 100; | |
| private int mScore = 0; | |
| private BufferedImage mCoin = null; | |
| private BufferedImage mPlayer = null; | |
| private BufferedImage mFood = null; | |
| private int levelId; | |
| private static int idCounter = 0; | |
| private JFrame mFrame; | |
| public Level(JFrame frame, int points, int score, int x, int y, | |
| Direction side) throws IOException { | |
| this(frame); | |
| mMovementPoints = points; | |
| mScore = score; | |
| } | |
| public Level(JFrame frame) throws IOException { | |
| levelId = idCounter++; | |
| mFrame = frame; | |
| mCoin = ImageIO.read(getClass().getResourceAsStream("/dogecoin_s.png")); | |
| mPlayer = ImageIO.read(getClass() | |
| .getResourceAsStream("/dogeface_s.png")); | |
| mFood = ImageIO.read(getClass().getResourceAsStream("/dogefood_s.png")); | |
| initTiles(); | |
| initDraw(mFrame); | |
| } | |
| private void initDraw(JFrame frame) { | |
| mPane = new DrawPane(); | |
| frame.setContentPane(mPane); | |
| frame.setVisible(true); | |
| } | |
| private void initTiles() { | |
| // Init Empty | |
| for (Tile[] row : mTiles) { | |
| Arrays.fill(row, Tile.Empty); | |
| } | |
| Random rand = new Random(); | |
| // Init Player Position | |
| mPlayerX = rand.nextInt(LEVEL_WIDTH - 2) + 1; | |
| mPlayerY = rand.nextInt(LEVEL_HEIGHT - 2) + 1; | |
| mTiles[mPlayerX][mPlayerY] = Tile.Player; | |
| // Coins | |
| for (int i = 0; i < 100; i++) { | |
| int x = rand.nextInt(LEVEL_WIDTH); | |
| int y = rand.nextInt(LEVEL_HEIGHT); | |
| if (mTiles[x][y] == Tile.Empty) { | |
| mTiles[x][y] = Tile.Coin; | |
| } | |
| } | |
| // Food | |
| for (int i = 0; i < 5; i++) { | |
| int x = rand.nextInt(LEVEL_WIDTH); | |
| int y = rand.nextInt(LEVEL_HEIGHT); | |
| if (mTiles[x][y] == Tile.Empty || mTiles[x][y] == Tile.Coin) { | |
| mTiles[x][y] = Tile.Food; | |
| } | |
| } | |
| // Walls | |
| for (int i = 0; i < LEVEL_WIDTH; i++) { | |
| mTiles[i][0] = Tile.Wall; | |
| mTiles[i][LEVEL_HEIGHT - 1] = Tile.Wall; | |
| } | |
| for (int i = 0; i < LEVEL_HEIGHT; i++) { | |
| mTiles[0][i] = Tile.Wall; | |
| mTiles[LEVEL_WIDTH - 1][i] = Tile.Wall; | |
| } | |
| // // LevelLoader | |
| // mTiles[LEVEL_WIDTH / 2][0] = mTiles[LEVEL_WIDTH / 2 - 1][0] = | |
| // Tile.LevelLoader; | |
| } | |
| public boolean movePlayer(Direction dir) { | |
| if (dir == null || mMovementPoints <= 0) { | |
| return false; | |
| } | |
| int newX, newY; | |
| switch (dir) { | |
| case UP: | |
| newX = mPlayerX; | |
| newY = mPlayerY - 1; | |
| break; | |
| case LEFT: | |
| newX = mPlayerX - 1; | |
| newY = mPlayerY; | |
| break; | |
| case DOWN: | |
| newX = mPlayerX; | |
| newY = mPlayerY + 1; | |
| break; | |
| case RIGHT: | |
| newX = mPlayerX + 1; | |
| newY = mPlayerY; | |
| break; | |
| default: | |
| newX = mPlayerX; | |
| newY = mPlayerY; | |
| break; | |
| } | |
| if (newX < 0 || newX >= LEVEL_WIDTH || newY < 0 || newY >= LEVEL_HEIGHT) { | |
| return false; | |
| } else if (mTiles[newX][newY] == Tile.Wall) { | |
| return false; | |
| } | |
| if (mTiles[newX][newY] == Tile.Coin) { | |
| mScore += new Random().nextInt(100); | |
| } else if (mTiles[newX][newY] == Tile.Food) { | |
| mMovementPoints += 5; | |
| } else if (mTiles[newX][newY] == Tile.LevelLoader) { | |
| initTiles(); | |
| initDraw(mFrame); | |
| } | |
| mTiles[mPlayerX][mPlayerY] = Tile.Empty; | |
| mPlayerX = newX; | |
| mPlayerY = newY; | |
| mTiles[mPlayerX][mPlayerY] = Tile.Player; | |
| mMovementPoints--; | |
| return true; | |
| } | |
| public void draw(JFrame frame) { | |
| mPane.invalidate(); | |
| mPane.repaint(); | |
| } | |
| private class DrawPane extends JPanel { | |
| private void init(Graphics g) { | |
| g.setColor(Color.BLACK); | |
| g.fillRect(0, 0, Game.WINDOW_WIDTH, Game.WINDOW_HEIGHT | |
| + Game.FOOTER_HEIGHT); | |
| } | |
| private void drawFooter(Graphics g) { | |
| g.setColor(Color.GRAY); | |
| g.drawLine(1, Game.WINDOW_HEIGHT, Game.WINDOW_WIDTH - 3, | |
| Game.WINDOW_HEIGHT); | |
| g.drawString("Movement points: " + mMovementPoints + " | Score: " | |
| + mScore, 5, Game.WINDOW_HEIGHT + 14); | |
| g.drawString("Press ESC to exit, R to restart", | |
| Game.WINDOW_WIDTH - 170, Game.WINDOW_HEIGHT + 14); | |
| } | |
| private void drawBorder(Graphics g) { | |
| g.setColor(Color.GRAY); | |
| g.drawRect(1, 1, Game.WINDOW_WIDTH - 3, Game.WINDOW_HEIGHT | |
| + Game.FOOTER_HEIGHT - 3); | |
| } | |
| private void drawLevel(Graphics g) { | |
| Graphics2D g2d = (Graphics2D) g; | |
| for (int x = 0; x < LEVEL_WIDTH; x++) { | |
| for (int y = 0; y < LEVEL_HEIGHT; y++) { | |
| drawTile(g2d, mTiles[x][y], x, y); | |
| } | |
| } | |
| } | |
| private Color colorByTile(Tile t) { | |
| switch (t) { | |
| case Player: | |
| return Color.RED; | |
| case Coin: | |
| return Color.YELLOW; | |
| case Wall: | |
| return Color.DARK_GRAY; | |
| case Food: | |
| return Color.BLUE; | |
| default: | |
| return Color.BLACK; | |
| } | |
| } | |
| private void drawTile(Graphics2D g2d, Tile t, int x, int y) { | |
| g2d.setColor(colorByTile(mTiles[x][y])); | |
| switch (mTiles[x][y]) { | |
| case Coin: | |
| // g2d.fillOval(x * (Game.WINDOW_WIDTH / LEVEL_WIDTH) + 10, y | |
| // * (Game.WINDOW_HEIGHT / LEVEL_HEIGHT) + 10, | |
| // Game.WINDOW_WIDTH / LEVEL_WIDTH - 20, | |
| // Game.WINDOW_HEIGHT / LEVEL_HEIGHT - 20); | |
| g2d.drawImage(mCoin, x * (Game.WINDOW_WIDTH / LEVEL_WIDTH) + 2, | |
| y * (Game.WINDOW_HEIGHT / LEVEL_HEIGHT) + 2, null); | |
| break; | |
| case Player: | |
| // g2d.fillOval(x * (Game.WINDOW_WIDTH / LEVEL_WIDTH) + 5, y | |
| // * (Game.WINDOW_HEIGHT / LEVEL_HEIGHT) + 5, | |
| // Game.WINDOW_WIDTH / LEVEL_WIDTH - 10, | |
| // Game.WINDOW_HEIGHT / LEVEL_HEIGHT - 10); | |
| g2d.drawImage(mPlayer, x * (Game.WINDOW_WIDTH / LEVEL_WIDTH), y | |
| * (Game.WINDOW_HEIGHT / LEVEL_HEIGHT), null); | |
| break; | |
| case Wall: | |
| g2d.fillRoundRect(x * (Game.WINDOW_WIDTH / LEVEL_WIDTH) + 3, y | |
| * (Game.WINDOW_HEIGHT / LEVEL_HEIGHT) + 3, | |
| Game.WINDOW_WIDTH / LEVEL_WIDTH - 6, Game.WINDOW_HEIGHT | |
| / LEVEL_HEIGHT - 6, 15, 15); | |
| break; | |
| case Food: | |
| // g2d.fillOval(x * (Game.WINDOW_WIDTH / LEVEL_WIDTH) + 10, y | |
| // * (Game.WINDOW_HEIGHT / LEVEL_HEIGHT) + 10, | |
| // Game.WINDOW_WIDTH / LEVEL_WIDTH - 20, | |
| // Game.WINDOW_HEIGHT / LEVEL_HEIGHT - 20); | |
| g2d.drawImage(mFood, x * (Game.WINDOW_WIDTH / LEVEL_WIDTH), y | |
| * (Game.WINDOW_HEIGHT / LEVEL_HEIGHT), null); | |
| break; | |
| default: | |
| g2d.fillRect(x * (Game.WINDOW_WIDTH / LEVEL_WIDTH), y | |
| * (Game.WINDOW_HEIGHT / LEVEL_HEIGHT), | |
| Game.WINDOW_WIDTH / LEVEL_WIDTH, Game.WINDOW_HEIGHT | |
| / LEVEL_HEIGHT); | |
| break; | |
| } | |
| } | |
| private void drawGameover(Graphics g) { | |
| String message = "Game Over - Score: " + mScore; | |
| Font font = new Font(Font.SANS_SERIF, Font.PLAIN, 40); | |
| FontMetrics metrics = g.getFontMetrics(font); | |
| g.setColor(Color.RED); | |
| g.setFont(font); | |
| g.drawString(message, | |
| Game.WINDOW_WIDTH / 2 - metrics.stringWidth(message) / 2, | |
| Game.WINDOW_HEIGHT / 2); | |
| } | |
| @Override | |
| protected void paintComponent(Graphics g) { | |
| super.paintComponent(g); | |
| init(g); | |
| drawLevel(g); | |
| drawFooter(g); | |
| drawBorder(g); | |
| if (mMovementPoints <= 0) { | |
| drawGameover(g); | |
| } | |
| } | |
| } | |
| } |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment