分类: Java
2006-09-18 07:41:43
import java.awt.*;
import java.awt.image.*;
import java.awt.event.*;
import javax.swing.*;
public class GameFramework extends JFrame implements Runnable,
KeyListener,
MouseListener,
MouseMotionListener,
FocusListener,
EventProcessable
{
public GameFramework(GraphicsDevice graphicsDevice)
{
super(graphicsDevice.getDefaultConfiguration());
this.graphicsDevice = graphicsDevice;
getContentPane().setLayout(null);
setIgnoreRepaint(true);
setResizable(false);
addWindowListener(new WindowAdapter()
{
public void windowClosing(WindowEvent e)
{
exitProgram();
}
});
addKeyListener(this);
getContentPane().addMouseListener(this);
getContentPane().addMouseMotionListener(this);
addFocusListener(this);
eventProcessor = new EventProcessor(this);
Globals.framework = this;
// set up the sound manager...
Globals.soundManager = new SoundManager();
// set up mouse and keyboard
Globals.keyboard = new Keyboard();
Globals.mouse = new Mouse();
}
public void setMode(int mode)
{
if(mode==FULLSCREEN_MODE)
if(!graphicsDevice.isFullScreenSupported())
{
mode = WINDOWED_MODE;
System.out.println("Sorry, fullscreen mode not
supported, continuing in windowed mode");
}
this.mode = mode;
try
{
if(mode==FULLSCREEN_MODE)
{
setUndecorated(true);
graphicsDevice.setFullScreenWindow(this);
if(graphicsDevice.isDisplayChangeSupported())
{
DisplayMode dm = new DisplayMode(Globals
.DISPLAY_WIDTH, Globals.DISPLAY_HEIGHT, 16,
DisplayMode.REFRESH_RATE_UNKNOWN);
if(isDisplayModeAvailable(dm))
graphicsDevice.setDisplayMode(dm);
else
{
System.out.println("Display mode not
available: "+
dm.getWidth()+":"+
dm.getHeight()+":"+
dm.getBitDepth());
System.exit(0);
}
}
else
{
System.out.println("Display change not
supported");
System.exit(0);
}
}
else // WINDOWED_MODE
{
setTitle("Windowed Mode");
setVisible(true);
Insets insets = getInsets();
DISPLAY_X = insets.left;
DISPLAY_Y = insets.top;
resizeToInternalSize(Globals.DISPLAY_WIDTH,
Globals.DISPLAY_HEIGHT);
}
createBufferStrategy(3);
strategy = getBufferStrategy();
}
catch(Exception e)
{
graphicsDevice.setFullScreenWindow(null);
e.printStackTrace();
}
if(!strategy.getCapabilities().isPageFlipping())
System.out.println("Page flipping is not available in
this mode");
waitForReadyStrategy();
}
public void resizeToInternalSize(int internalWidth, int
internalHeight)
{
Insets insets = getInsets();
final int newWidth = internalWidth + insets.left +
insets.right;
final int newHeight = internalHeight + insets.top +
insets.bottom;
Runnable resize = new Runnable()
{
public void run()
{
setSize(newWidth, newHeight);
}
};
if(!SwingUtilities.isEventDispatchThread())
{
try
{
SwingUtilities.invokeAndWait(resize);
}
catch(Exception e) {}
}
else
resize.run();
validate();
}
public boolean isDisplayModeAvailable(DisplayMode dm)
{
DisplayMode[] availableModes = graphicsDevice
.getDisplayModes();
for(int i=0; i{
if(dm.getWidth()==availableModes[i].getWidth() &&
dm.getHeight()==availableModes[i].getHeight() &&
dm.getBitDepth()==availableModes[i].getBitDepth())
return true;
}
return false;
}
public void waitForReadyStrategy()
{
int iterations = 0;
while(true)
{
try
{
Thread.sleep(20);
}
catch(InterruptedException e) {}
try
{
strategy.getDrawGraphics();
break;
}
catch(IllegalStateException e)
{
System.out.println("BufferStrategy not ready yet");
}
iterations++;
if(iterations == 100)
{
// (Unlikely event) No use after 2 seconds (100*20ms
// = 2secs) give up trying
System.out.println("Exiting Program, unable to use
BufferStrategy");
System.exit(0);
}
}
}
public void start()
{
loop = new Thread(this);
loop.start();
}
public void run()
{
long startTime, waitTime, elapsedTime;
// 1000/25 Frames Per Second = 40 millisecond delay
int delayTime = 1000/25;
Thread thisThread = Thread.currentThread();
while(loop==thisThread)
{
startTime = System.currentTimeMillis();
eventProcessor.processEventList();
Globals.currentScreen.process();
Graphics g = strategy.getDrawGraphics();
if(!strategy.contentsLost())
{
g.translate(DISPLAY_X, DISPLAY_Y);
Globals.currentScreen.render(g);
g.dispose();
strategy.show();
}
// handle frame rate
elapsedTime = System.currentTimeMillis() - startTime;
waitTime = Math.max(delayTime - elapsedTime, 5);
try
{
Thread.sleep(waitTime);
}
catch(InterruptedException e) {}
}
System.out.println("Program Exited");
dispose();
System.exit(0);
}
public void exitProgram()
{
loop = null;
}
public void initGame()
{
// create your screens...
Globals.sampleScreen = new SampleScreen();
// load any sounds into the sound manager...
// set the current (starting) screen...
Globals.currentScreen = Globals.previousScreen =
Globals.sampleScreen;
Globals.currentScreen.load();
}
public boolean handleGlobalEvent(AWTEvent e)
{
// handle global events...
switch(e.getID())
{
case KeyEvent.KEY_PRESSED:
KeyEvent keyEvent = (KeyEvent) e;
Globals.keyboard.keyState[keyEvent.getKeyCode()]
= true;
switch(keyEvent.getKeyCode())
{
case KeyEvent.VK_ESCAPE:
exitProgram();
return true;
}
break;
case KeyEvent.KEY_RELEASED:
Globals.keyboard.keyState[((KeyEvent)e).getKeyCode()]
= false;
break;
case MouseEvent.MOUSE_MOVED:
case MouseEvent.MOUSE_DRAGGED:
{
MouseEvent mouseEvent = (MouseEvent) e;
Globals.mouse.x = mouseEvent.getX();
Globals.mouse.y = mouseEvent.getY();
break;
}
case MouseEvent.MOUSE_PRESSED:
switch(((MouseEvent)e).getButton())
{
case MouseEvent.BUTTON1:
Globals.mouse.button[Mouse.LEFT_BUTTON]
= true;
break;
case MouseEvent.BUTTON2:
Globals.mouse.button[Mouse.MIDDLE_BUTTON]
= true;
break;
case MouseEvent.BUTTON3:
Globals.mouse.button[Mouse.RIGHT_BUTTON]
= true;
break;
}
break;
case MouseEvent.MOUSE_RELEASED:
switch(((MouseEvent)e).getButton())
{
case MouseEvent.BUTTON1:
Globals.mouse.button[Mouse.LEFT_BUTTON]
= false;
break;
case MouseEvent.BUTTON2:
Globals.mouse.button[Mouse.MIDDLE_BUTTON]
= false;
break;
case MouseEvent.BUTTON3:
Globals.mouse.button[Mouse.RIGHT_BUTTON]
= false;
break;
}
break;
case FocusEvent.FOCUS_LOST:
// reset key states...
Globals.keyboard.resetAllStates();
// reset mouse button states...
Globals.mouse.resetAllStates();
break;
case FocusEvent.FOCUS_GAINED:
break;
}
return false;
}
public void handleEvent(AWTEvent e)
{
if(!handleGlobalEvent(e))
Globals.currentScreen.handleEvent(e);
}
public void setCurrentScreen(TemplateScreen screen)
{
// unload the current screen...
Globals.currentScreen.unload();
// set this screen to the previous screen...
Globals.previousScreen = Globals.currentScreen;
// assign the new screen...
Globals.currentScreen = screen;
// load it...
Globals.currentScreen.load();
}
// key listener methods
public void keyPressed(KeyEvent e)
{ eventProcessor.addEvent(e); }
public void keyReleased(KeyEvent e)
{ eventProcessor.addEvent(e); }
public void keyTyped(KeyEvent e) {} // not used
// mouse listener methods
public void mousePressed(MouseEvent e)
{ eventProcessor.addEvent(e); }
public void mouseReleased(MouseEvent e)
{ eventProcessor.addEvent(e); }
public void mouseClicked(MouseEvent e) {} // not used
public void mouseEntered(MouseEvent e) {} // not used
public void mouseExited(MouseEvent e) {} // not used
// mouse motion listener methods
public void mouseMoved(MouseEvent e)
{ eventProcessor.addEvent(e); }
public void mouseDragged(MouseEvent e)
{ eventProcessor.addEvent(e); }
// focus listener methods
public void focusGained(FocusEvent e)
{ eventProcessor.addEvent(e); }
public void focusLost(FocusEvent e)
{ eventProcessor.addEvent(e); }
public static void main(String args[])
{
GraphicsEnvironment ge = GraphicsEnvironment
.getLocalGraphicsEnvironment();
GameFramework mainAppFrame = new GameFramework
(ge.getDefaultScreenDevice());
Object[] options = {"FullScreen Mode", "Windowed Mode"};
int choice = JOptionPane.showOptionDialog(null,
"Select Display Mode:",
"Display Mode",
JOptionPane.DEFAULT_OPTION,
JOptionPane.QUESTION_MESSAGE,
null,
options,
options[0]);
if(choice!=JOptionPane.CLOSED_OPTION)
{
// choice will be either 0 or 1 corresponding to our mode
// flags, FULLSCREEN_MODE = 0, WINDOWED_MODE = 1
// initialize and start the game...
mainAppFrame.initGame();
mainAppFrame.setMode(choice);
mainAppFrame.start();
}
else
System.exit(0);
}
private Thread loop;
private GraphicsDevice graphicsDevice;
// not final - application may need to adjust these coordinates
// to adapt to windowed border
private int DISPLAY_X = 0;
private int DISPLAY_Y = 0;
private BufferStrategy strategy;
private static final int FULLSCREEN_MODE = 0;
private static final int WINDOWED_MODE = 1;
private int mode;
private EventProcessor eventProcessor;
}