package client;
import client.gui.*;
import common.*;
import java.awt.*;
import java.awt.event.*;
import java.awt.geom.*;
//import java.util.logging.Level;
import java.util.logging.Logger;
import java.util.Vector;
import javax.swing.*;
/**
* This class manages displaying the current play area
* @author dvanhumb
*/
public class ClientViewArea extends JComponent implements MouseMotionListener, MouseListener, KeyListener, Constants, MapChangeListener {
public static Logger logger = Logger.getLogger(CLIENT_LOGGER_NAME);
private static final long serialVersionUID = 23498751L;
public static final int MAP_WIDTH = 16;
public static final int MAP_HEIGHT = 16;
public static final boolean DRAW_CENTER_DOT = false;
public int framesPerSecond;
// Drawing-related variables
protected boolean antialiasing;
protected float scale;
protected boolean drawMap;
protected Point lastOffset;
// Colour-defining variables
// Gui-related stuff:
protected Vector<Widget> widgetList;
// Game-related stuff:
protected LocalPlayer localPlayer;
protected PlayerHealthMeter healthMeter;
protected TrackingObject viewTracker;
protected Map map;
protected int mapWidth, mapHeight;
protected GameEngine gameEngine;
// Temporary testing stuff:
public ClientViewArea(GameEngine engine)
{
gameEngine = engine;
framesPerSecond = 0;
Dimension d = new Dimension(GAME_WINDOW_WIDTH, GAME_WINDOW_HEIGHT);
setMinimumSize(d);
setPreferredSize(d);
setMaximumSize(d);
setBackground(Color.black);
setForeground(STONE_COLOR);
addMouseListener(this);
addMouseMotionListener(this);
addKeyListener(this);
widgetList = new Vector<Widget>();
scale = 50;
antialiasing = false;
drawMap = true;
MapRadar radar = new MapRadar(5, -5, gameEngine, map);
addWidget(radar);
if (gameEngine != null)
{
gameEngine.addMapListener(this);
gameEngine.addMapListener(radar);
}
else
System.err.println("client.ClientViewArea.<init>: GameEngine not specified!");
mapWidth = MAP_WIDTH;
mapHeight = MAP_HEIGHT;
lastOffset = new Point();
healthMeter = new PlayerHealthMeter(-55, -5, 100, 15, Color.green, null);
addWidget(healthMeter);
setFocusable(true);
}
public Point getLastOffset()
{
return lastOffset;
}
public void setLocalPlayer(LocalPlayer p)
{
localPlayer = p;
healthMeter.setPlayer(p);
// if (viewTracker == null)
// {
// viewTracker = new TrackingObject(localPlayer);
// gameEngine.addActor(viewTracker);
// }
repaint();
}
public LocalPlayer getLocalPlayer()
{
return localPlayer;
}
public void setMap(Map m)
{
map = m;
if (this.isVisible())
repaint();
if (map != null)
{
mapWidth = map.getWidth();
mapHeight = map.getHeight();
}
else
{
mapWidth = MAP_WIDTH;
mapHeight = MAP_HEIGHT;
}
}
public Map getMap()
{
return map;
}
public void setDrawMap(boolean show)
{
drawMap = show;
repaint();
}
public boolean getDrawMap()
{
return drawMap;
}
public void addWidget(Widget w)
{
widgetList.add(w);
}
public void removeWidget(Widget w)
{
widgetList.remove(w);
}
public void showFPS()
{
addWidget(new FrameRateCounter(5, 5, 100, 15, Color.lightGray));
}
public void paint(Graphics g)
{
Graphics2D g2 = (Graphics2D) g;
if (antialiasing)
g2.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
else
g2.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_OFF);
Rectangle clip = g2.getClipBounds(); // The clipping bounds, so we don't draw stuff over again
int offset_x=0, offset_y=0;
offset_x = getWidth() / 2;
offset_y = getHeight() / 2;
// Save temporary copies of parameters changed
Color oldColor = g2.getColor();
AffineTransform oldTransform = g2.getTransform();
// Draw the background
g2.setColor(getBackground());
g2.fill(clip);
if (viewTracker != null)
{
offset_x -= Math.round(viewTracker.getPosition().getX()*scale);
offset_y -= Math.round(viewTracker.getPosition().getY()*scale);
}
lastOffset.x = offset_x;
lastOffset.y = offset_y;
g2.translate(offset_x, offset_y);
// Draw all actors:
// for (Actor a : gameEngine.actorList)
// a.draw(g2, scale);
synchronized(gameEngine.bulletList) {
for (Actor a : gameEngine.bulletList)
a.draw(g2, scale);
}
synchronized(gameEngine.playerList) {
for (Actor a : gameEngine.playerList)
a.draw(g2, scale);
}
// Draw the walls
if (map != null && drawMap)
{
int left, right, top, bottom;
left = Math.round((clip.x - offset_x) / scale - 0.5f);
right = Math.round((clip.x + clip.width - offset_x) / scale);
top = Math.round((clip.y - offset_y) / scale - 0.5f);
bottom = Math.round((clip.y + clip.height - offset_y) / scale);
left = Math.max(0, Math.min(map.getWidth()-1, left));
right = Math.max(0, Math.min(map.getWidth()-1, right));
top = Math.max(0, Math.min(map.getHeight()-1, top));
bottom = Math.max(0, Math.min(map.getHeight()-1, bottom));
g2.setColor(getForeground());
for (int x=left; x <= right; x++)
for (int y=top; y <= bottom; y++)
{
if (map.isWall(x, y))
g2.fillRect(Math.round(x*scale), Math.round(y*scale), Math.round(scale), Math.round(scale));
}
} // end draw map
// Draw everybody's labels
synchronized(gameEngine.playerList) {
for (Player p : gameEngine.playerList)
p.drawLabel(g2, scale);
}
// Restore the view so the widgets are in the right spot
g2.setTransform(oldTransform);
// Mark the center of the window
if (DRAW_CENTER_DOT)
{
g2.setColor(Color.red);
g2.fillRect(getWidth()/2 - 1, getHeight()/2 - 1, 3, 3);
}
final int width = getWidth(), height = getHeight();
// Draw the widgets
for (Widget w : widgetList)
w.draw(g2, width, height);
// Restore all parameters changed
g2.setColor(oldColor);
}
// Called when the mouse is moved with at least one button down
public void mouseDragged(MouseEvent e)
{
int width = getWidth(), height = getHeight(), x = e.getX(), y = e.getY();
for (Widget w : widgetList)
{
if (!(w instanceof InteractiveWidget)) continue;
InteractiveWidget iw = (InteractiveWidget) w;
if (iw.containsFixed(x, y, width, height))
{
if (iw.getState() == InteractiveWidget.STATE_UNHOVERED)
{
iw.setState(InteractiveWidget.STATE_HOVERED);
repaint(iw.getFixedBounds(width, height));
}
}
else
{
if (iw.getState() == InteractiveWidget.STATE_HOVERED)
{
iw.setState(InteractiveWidget.STATE_UNHOVERED);
repaint(iw.getFixedBounds(width, height));
}
}
} // end for (w in widgetList)
} // end mouseDragged()
public void mouseMoved(MouseEvent e)
{
int width = getWidth(), height = getHeight(), x = e.getX(), y = e.getY();
for (Widget w : widgetList)
{
if (!(w instanceof InteractiveWidget)) continue;
InteractiveWidget iw = (InteractiveWidget) w;
if (iw.containsFixed(x, y, width, height))
{
if (iw.getState() != InteractiveWidget.STATE_HOVERED)
{
iw.setState(InteractiveWidget.STATE_HOVERED);
repaint(iw.getFixedBounds(width, height));
}
}
else
{
if (iw.getState() != InteractiveWidget.STATE_READY)
{
iw.setState(InteractiveWidget.STATE_READY);
repaint(iw.getFixedBounds(width, height));
}
}
} // end for (Widget)
} // end mouseMouse()
public void mouseClicked(MouseEvent e)
{
}
public void mouseEntered(MouseEvent e)
{
}
public void mouseExited(MouseEvent e)
{
}
public void mousePressed(MouseEvent e)
{
}
// Called when the mouse button is released
public void mouseReleased(MouseEvent e)
{
if (e.getButton() != MouseEvent.BUTTON1) return;
for (Widget w : widgetList)
{
if (!(w instanceof InteractiveWidget)) continue;
InteractiveWidget iw = (InteractiveWidget) w;
if (iw.getState() == InteractiveWidget.STATE_HOVERED) iw.trigger(e.getButton());
iw.setState(InteractiveWidget.STATE_READY);
}
}
public void keyPressed(KeyEvent e)
{
if (e.getKeyCode() == KeyEvent.VK_ESCAPE)
{
if (gameEngine != null)
gameEngine.gameOver();
else
System.exit(0);
}
else if (e.getKeyCode() == KeyEvent.VK_INSERT)
{
antialiasing = !antialiasing;
repaint();
}
}
public void keyReleased(KeyEvent e)
{
}
public void keyTyped(KeyEvent e)
{
}
public void mapChanged(Map newMap)
{
setMap(newMap);
}
public float getScale()
{
return scale;
}
} // end ClientViewArea clas