package com.weem.epicinventor;
import com.weem.epicinventor.utility.*;
import javax.swing.*;
import java.awt.event.*;
import java.awt.*;
import javax.swing.event.MouseInputAdapter;
import java.awt.event.MouseWheelEvent;
import java.awt.event.MouseWheelListener;
import java.awt.image.*;
public class GamePanel extends JPanel implements Runnable {
private int pWidth;
private int pHeight;
private static final int NO_DELAYS_PER_YIELD = 16;
private static final int MAX_FRAME_SKIPS = 5;
private Thread animator;
private volatile boolean isRunning = false;
private volatile boolean isPaused = false;
private volatile boolean isMasterPaused = false;
private long period;
private Graphics dbg;
private Image dbImage = null;
private Container container;
private Game game;
private GameController gameController;
public volatile boolean keySpacePressed = false;
public volatile boolean keyRightPressed = false;
public volatile boolean keyLeftPressed = false;
private volatile boolean keyUpPressed = false;
private volatile boolean keyDownPressed = false;
public volatile boolean keyGatherPressed = false;
public volatile boolean keyRobotPressed = false;
private boolean[] keys = new boolean[65536];
public GamePanel(Game g, long period, int w, int h) {
game = g;
pWidth = w;
pHeight = h;
this.period = period;
gameController = new GameController(pWidth, pHeight, period, this);
setDoubleBuffered(false);
setBackground(Color.white);
setPreferredSize(new Dimension(pWidth - 10, pHeight - 6));
setFocusable(true);
requestFocus();
this.setFocusTraversalKeysEnabled(false);
addKeyListener(new KeyAdapter() {
@Override
public void keyPressed(KeyEvent e) {
processKeyPress(e);
}
@Override
public void keyReleased(KeyEvent e) {
processKeyRelease(e);
}
});
addMouseListener(new MouseAdapter() {
@Override
public void mousePressed(MouseEvent e) {
processMousePress(e);
}
@Override
public void mouseReleased(MouseEvent e) {
processMouseReleased(e);
}
});
addMouseMotionListener(new MouseInputAdapter() {
@Override
public void mouseMoved(MouseEvent e) {
gameController.getCurrentMousePosition().setLocation(e.getPoint());
}
@Override
public void mouseDragged(MouseEvent e) {
gameController.getCurrentMousePosition().setLocation(e.getPoint());
}
});
addMouseWheelListener(new MouseWheelListener() {
@Override
public void mouseWheelMoved(MouseWheelEvent e) {
processMouseWheelMove(e);
}
});
}
public void setContainer(Container c) {
container = c;
}
public boolean getKey(int k) {
return keys[k];
}
private void processKeyPress(KeyEvent e) {
int keyCode = e.getKeyCode();
keys[keyCode] = true;
if (gameController.isConsoleOpen()) {
gameController.consoleKey(keyCode, e.getKeyChar());
} else if (gameController.isKeysOpen()) {
gameController.settingsKey(keyCode, e.getKeyChar());
} else if (gameController.isNewCharacterOpen()) {
if (keyCode == KeyEvent.VK_TAB) {
gameController.newCharacterKey(keyCode, e.getKeyChar(), true);
} else {
gameController.newCharacterKey(keyCode, e.getKeyChar());
}
} else if (gameController.isMultiPlayerJoinOpen()) {
if (keyCode == KeyEvent.VK_TAB) {
gameController.multiPlayerJoinKey(keyCode, e.getKeyChar(), true);
} else {
gameController.multiPlayerJoinKey(keyCode, e.getKeyChar());
}
} else if (gameController.isMultiPlayerHostOpen()) {
if (keyCode == KeyEvent.VK_TAB) {
gameController.multiPlayerHostKey(keyCode, e.getKeyChar(), true);
} else {
gameController.multiPlayerHostKey(keyCode, e.getKeyChar());
}
} else if (keyCode == Settings.buttonPause && gameController.getIsInGame() && gameController.multiplayerMode == gameController.multiplayerMode.NONE) {
togglePaused();
} else if (keyCode == KeyEvent.VK_ESCAPE && gameController.getIsInGame()) {
gameController.togglePauseHUD();
} else {
if (gameController.getIsInGame()) {
if (keyCode == Settings.buttonInventory) {
gameController.toggleMasterHUD();
return;
}
}
if (!isPaused && !isMasterPaused) {
if (gameController.getIsInGame()) {
if (keyCode == Settings.buttonMoveLeft) {
if (!keyLeftPressed) {
keyLeftPressed = true;
keyRightPressed = false;
gameController.stopActions();
gameController.moveLeft();
}
} else if (keyCode == Settings.buttonMoveRight) {
if (!keyRightPressed) {
keyRightPressed = true;
keyLeftPressed = false;
gameController.stopActions();
gameController.moveRight();
}
} else if (keyCode == Settings.buttonJump) {
if (!keySpacePressed) {
keySpacePressed = true;
gameController.stopActions();
gameController.jump();
}
} else if (keyCode == Settings.buttonAction) {
if (!keyGatherPressed) {
keyGatherPressed = true;
gameController.stopActions();
gameController.startGather();
}
} else if (keyCode == Settings.buttonRobot) {
if (!keyRobotPressed) {
keyRobotPressed = true;
gameController.robotToggleActivated();
}
} else if (keyCode == KeyEvent.VK_ENTER) {
gameController.keyEnterPressed();
} else if (keyCode == KeyEvent.VK_SHIFT) {
gameController.shiftPressed();
} else if (keyCode == KeyEvent.VK_0) {
gameController.stopActions();
gameController.numPressed(0);
} else if (keyCode == KeyEvent.VK_1) {
gameController.stopActions();
gameController.numPressed(1);
} else if (keyCode == KeyEvent.VK_2) {
gameController.stopActions();
gameController.numPressed(2);
} else if (keyCode == KeyEvent.VK_3) {
gameController.stopActions();
gameController.numPressed(3);
} else if (keyCode == KeyEvent.VK_4) {
gameController.stopActions();
gameController.numPressed(4);
} else if (keyCode == KeyEvent.VK_5) {
gameController.stopActions();
gameController.numPressed(5);
} else if (keyCode == KeyEvent.VK_6) {
gameController.stopActions();
gameController.numPressed(6);
} else if (keyCode == KeyEvent.VK_7) {
gameController.stopActions();
gameController.numPressed(7);
} else if (keyCode == KeyEvent.VK_8) {
gameController.stopActions();
gameController.numPressed(8);
} else if (keyCode == KeyEvent.VK_9) {
gameController.stopActions();
gameController.numPressed(9);
}
}
}
}
}
private void processKeyRelease(KeyEvent e) {
int keyCode = e.getKeyCode();
keys[keyCode] = false;
if (gameController.isNewCharacterOpen()) {
} else if (keyCode == Settings.buttonMoveLeft) {
keyLeftPressed = false;
if (!keyRightPressed) {
gameController.stopXMove();
}
} else if (keyCode == Settings.buttonMoveRight) {
keyRightPressed = false;
if (!keyLeftPressed) {
gameController.stopXMove();
}
} else if (keyCode == Settings.buttonJump) {
keySpacePressed = false;
gameController.stopJump();
} else if (keyCode == Settings.buttonAction) {
keyGatherPressed = false;
gameController.stopActions();
} else if (keyCode == Settings.buttonRobot) {
keyRobotPressed = false;
} else if (keyCode == KeyEvent.VK_SHIFT) {
gameController.shiftRelease();
}
}
private void processMousePress(MouseEvent e) {
int buttonCode = e.getButton();
Point clickPoint = e.getPoint();
if (buttonCode == MouseEvent.BUTTON1) {
gameController.handleClick(clickPoint);
} else if (buttonCode == MouseEvent.BUTTON3) {
gameController.handleRightClick(clickPoint);
}
}
private void processMouseReleased(MouseEvent e) {
int buttonCode = e.getButton();
Point clickPoint = e.getPoint();
if (buttonCode == MouseEvent.BUTTON1) {
gameController.handleReleased(clickPoint);
}
}
private void processMouseWheelMove(MouseWheelEvent e) {
int steps = e.getWheelRotation();
gameController.handleMouseScroll(steps);
}
@Override
public void addNotify() {
super.addNotify(); // creates the peer
startGame(); // start the thread
}
private void startGame() {
if (animator == null || !isRunning) {
animator = new Thread(this);
animator.start();
}
}
public void setFullScreen(boolean f) {
game.setFullScreen(f);
}
public void resizePanel(int w, int h) {
if (w == 0 && h == 0) {
//full screen
Dimension dim = Toolkit.getDefaultToolkit().getScreenSize();
pWidth = dim.width;
pHeight = dim.height;
dbImage = null;
//resize the panel
this.setPreferredSize(new Dimension(pWidth, pHeight));
this.revalidate();
this.setFocusable(true);
this.requestFocus();
//resize the container
if (container != null) {
container.setPreferredSize(new Dimension(pWidth, pHeight));
container.validate();
}
} else {
pWidth = w;
pHeight = h;
dbImage = null;
game.setFullScreen(false);
//resize the panel
this.setPreferredSize(new Dimension(pWidth - 10, pHeight - 6));
this.revalidate();
this.setFocusable(true);
this.requestFocus();
//resize the container
if (container != null) {
container.setPreferredSize(new Dimension(pWidth - 10, pHeight - 6));
container.validate();
}
}
//resize the frame
game.pack();
game.setLocationRelativeTo(null);
if (w == 0 && h == 0) {
//full screen
game.setFullScreen(true);
}
}
public void resumeGame() {
isPaused = false;
}
public void pauseGame() {
isPaused = true;
}
public void togglePaused() {
isPaused = !isPaused;
}
public boolean getIsPaused() {
return isPaused;
}
public void resumeMasterGame() {
isMasterPaused = false;
}
public void pauseMasterGame() {
isMasterPaused = true;
}
public void toggleMasterPaused() {
isMasterPaused = !isMasterPaused;
}
public boolean getIsMasterPaused() {
return isMasterPaused;
}
public void stopGame() {
isRunning = false;
gameController.quit();
}
@Override
@SuppressWarnings({"SleepWhileInLoop", "CallToThreadYield"})
public void run() {
long b, a, beforeTime, afterTime, timeDiff, sleepTime;
long overSleepTime = 0L;
int noDelays = 0;
long excess = 0L;
beforeTime = System.nanoTime();
isRunning = true;
while (isRunning) {
//b = System.nanoTime();
gameUpdate();
//a = System.nanoTime();
//System.out.println("Update: " + ((a - b) / 1000000));
//b = System.nanoTime();
//if (((a - b) / 1000000) > 100) {
// System.exit(0);
//}
gameRender();
paintScreen();
// a = System.nanoTime();
//System.out.println("Draw: " + ((a - b) / 1000000));
//System.out.println("----------");
afterTime = System.nanoTime();
timeDiff = afterTime - beforeTime;
sleepTime = (period - timeDiff) - overSleepTime;
if (sleepTime > 0) {
try {
Thread.sleep(sleepTime / 1000000L); // nano -> ms
} catch (InterruptedException ex) {
}
overSleepTime = (System.nanoTime() - afterTime) - sleepTime;
} else { // sleepTime <= 0; the frame took longer than the period
excess -= sleepTime;
overSleepTime = 0L;
if (++noDelays >= NO_DELAYS_PER_YIELD) {
Thread.yield(); // give another thread a chance to run
noDelays = 0;
}
}
beforeTime = System.nanoTime();
int skips = 0;
while ((excess > period) && (skips < MAX_FRAME_SKIPS)) {
excess -= period;
gameUpdate();
skips++;
}
}
System.exit(0);
}
private void gameUpdate() {
gameController.update();
}
private void gameRender() {
if (dbImage == null) {
dbImage = createImage(pWidth, pHeight);
if (dbImage == null) {
EIError.debugMsg("dbImage is null");
return;
} else {
dbg = dbImage.getGraphics();
}
}
dbg.setColor(Color.black);
dbg.fillRect(0, 0, pWidth, pHeight);
gameController.render(dbg);
}
private void paintScreen() {
Graphics g;
try {
g = this.getGraphics();
if ((g != null) && (dbImage != null)) {
g.drawImage(dbImage, 0, 0, null);
}
// Sync the display on some systems.
// (on Linux, this fixes event queue problems)
Toolkit.getDefaultToolkit().sync();
g.dispose();
} catch (Exception e) {
EIError.debugMsg("Graphics context error: " + e);
}
}
}