import java.awt.*;
import java.awt.event.*;
import java.awt.image.BufferedImage;
import java.util.ArrayList;
import javax.swing.*;
public class Screen extends JPanel implements ActionListener, KeyListener, MouseListener, MouseMotionListener {
// __working variables__
public long lastTime = 0;
// mouse
private boolean captured = false;
private final Point2D mouseRel = new Point2D(0,0);
private Cursor invisibleCursor;
public ObjectCollection mainCollection;
// testing\
//private Line line = new Line(new Point2D(200, 200),new Point2D(1, 1));
//private Triangle Triangle = new Triangle(new Point2D(200, 200), new Point2D(1, 1), new Point2D(400,200));
private Point3D[] points = new Point3D[]{
new Point3D(10,10,-1),
new Point3D(-10, 10, -1),
new Point3D(-10, -10, -1),
new Point3D(10, -10, -1)};
double ang = 0;
// __config variables__
// controls the delay between each tick in ms
private final int DELAY = 25;
// controls the size of the board
public static final int TILE_SIZE = 50;
public static final int ROWS = 12;
public static final int COLUMNS = 18;
// suppress serialization warning
private static final long serialVersionUID = 490905409104883233L;
// keep a reference to the timer object that triggers actionPerformed() in
// case we need access to it in another method
private final Timer timer;
private final Player player;
public Screen(ObjectCollection _mainCollection) {
mainCollection = _mainCollection;
// set the game board size
setPreferredSize(new Dimension(TILE_SIZE * COLUMNS, TILE_SIZE * ROWS));
// set the game board background color
setBackground(new Color(232, 232, 232));
// hide the mouse cursor (https://stackoverflow.com/questions/191592/how-do-i-get-rid-of-the-mouse-cursor-in-full-screen-exclusive-mode)
Toolkit toolkit = Toolkit.getDefaultToolkit();
Point hotSpot = new Point(0,0);
BufferedImage cursorImage = new BufferedImage(1, 1, BufferedImage.TRANSLUCENT);
invisibleCursor = toolkit.createCustomCursor(cursorImage, hotSpot, "InvisibleCursor");
// initialize the game state
player = new Player();
// this timer will call the actionPerformed() method every DELAY ms
timer = new Timer(DELAY, this);
timer.start();
}
@Override
public void actionPerformed(ActionEvent e) {
// this method is called by the timer every DELAY ms.
// runs the tick of the player before the board is redrawn
player.tick(get_mouse_rel());
// calling repaint() will trigger paintComponent() to run again,
// which will refresh/redraw the graphics.
repaint();
}
@Override
public void paintComponent(Graphics g) {
super.paintComponent(g);
// when calling g.drawImage() we can use "this" for the ImageObserver
// because Component implements the ImageObserver interface, and JPanel
// extends from Component. So "this" Board instance, as a Component, can
// react to imageUpdate() events triggered by g.drawImage()
// draw graphics.
drawScreen(g);
// player.draw(g, this);
// this smooths out animations on some systems
Toolkit.getDefaultToolkit().sync();
}
private void drawScreen(Graphics g) {
BufferedImage img = new BufferedImage(getWidth(), getHeight(), BufferedImage.TYPE_INT_RGB );
BufferedImage debugimg = new BufferedImage(getWidth(), getHeight(), BufferedImage.TYPE_INT_ARGB);
debugimg.createGraphics();
g.setColor(Color.white);
// line.point2.x = 100*Math.sin(ang) + 200;
// line.point2.y = 100*Math.cos(ang) + 200;
// Triangle.point2.x = 100*Math.sin(ang+3) + 200;
// Triangle.point2.y = 100*Math.cos(ang+3) + 200;
// line.draw(img);
/* ArrayList<Point3D> newPoints = new ArrayList<Point3D>();
for (Point3D point: points) {
Point3D _new = new Point3D(0,0,0);
player.camMatrix.multiplyPoint3to(point, _new);
if(_new.z > .1) {
newPoints.add(_new);
} else{
newPoints.add(null);
}
}
Triangle t1 = null;
Triangle t2 = null;
try {
t1 = new Triangle(
newPoints.get(0).project(player.Fpdis, getWidth(), getHeight()),
newPoints.get(1).project(player.Fpdis, getWidth(), getHeight()),
newPoints.get(2).project(player.Fpdis, getWidth(), getHeight()));
} catch(NullPointerException ignored){}
try{
t2 = new Triangle(
newPoints.get(0).project(player.Fpdis, getWidth(), getHeight()),
newPoints.get(2).project(player.Fpdis, getWidth(), getHeight()),
newPoints.get(3).project(player.Fpdis, getWidth(), getHeight()));
} catch(NullPointerException ignored){}
try{t1.draw(img);}catch (NullPointerException ignored){}
try{t2.draw(img);}catch (NullPointerException ignored){}
ang += 0.02;*/
mainCollection.invalidate(true);
mainCollection.draw(img, debugimg, player.camMatrix, player.Fpdis, getWidth(), getHeight(), player.getPos());
g.drawImage(img, 0, 0, this);
g.drawImage(debugimg, 0, 0, this);
// DEBUG DRAWING
g.drawString(Math.round(1000/(float)(System.currentTimeMillis() - lastTime)) + " fps" , 10, 10);
lastTime = System.currentTimeMillis();
}
@Override
public void keyTyped(KeyEvent e) {}
@Override
public void keyPressed(KeyEvent e) {
int key = e.getKeyCode();
if (key == KeyEvent.VK_ESCAPE){
captured = false;
setCursor(new Cursor(Cursor.DEFAULT_CURSOR));
}
// pass key-press to the player, so they can handle it as well
player.keyPressed(key);
}
@Override
public void keyReleased(KeyEvent e) {
int key = e.getKeyCode();
// pass key-release to the player, so they can handle it as well
player.keyReleased(key);
}
// gets the relative position of the mouse since the last time this function was called
public Point2D get_mouse_rel(){
Point2D rel;
// this doesn't work if the mouse isn't captured. If I need it to, I can
// probably make it, but I don't know what the functionality looks like.
if (captured) {
rel = new Point2D(MouseInfo.getPointerInfo().getLocation().x - getLocationOnScreen().x - getSize().width / 2 + mouseRel.x,
MouseInfo.getPointerInfo().getLocation().y - getLocationOnScreen().y - getSize().height / 2 + mouseRel.y);
mouseRel.set(0, 0);
// set the position of the mouse back to (0,0)
try {
Robot robot = new Robot();
robot.mouseMove(getLocationOnScreen().x + getSize().width / 2,
getLocationOnScreen().y + getSize().height / 2);
} catch (AWTException ex) {
ex.printStackTrace();
}
}
else{
rel = new Point2D(0,0);
}
return rel;
}
@Override
public void mouseClicked(MouseEvent mouseEvent) {
if (mouseEvent.getButton() == MouseEvent.BUTTON1){
captured = true;
get_mouse_rel();
setCursor(invisibleCursor);
}
}
@Override
public void mousePressed(MouseEvent mouseEvent) {}
@Override
public void mouseReleased(MouseEvent mouseEvent) {}
@Override
public void mouseEntered(MouseEvent mouseEvent) {}
@Override
public void mouseExited(MouseEvent mouseEvent) {
if (captured) {
// add current mouse relative location to mouseRel so mouse movements are not lost
mouseRel.x += mouseEvent.getX() - getSize().width / 2d;
mouseRel.y += mouseEvent.getY() - getSize().height / 2d;
// System.out.println(mouseEvent.getX() + " " + mouseEvent.getY());
// set the position of the mouse back to (0,0)
try {
Robot robot = new Robot();
robot.mouseMove(getLocationOnScreen().x + getSize().width / 2,
getLocationOnScreen().y + getSize().height / 2);
} catch (AWTException ex) {
ex.printStackTrace();
}
}
}
@Override
public void mouseDragged(MouseEvent mouseEvent) {}
@Override
public void mouseMoved(MouseEvent mouseEvent) {
}
}