/*
DEVELOPING GAME IN JAVA
Caracteristiques
Editeur : NEW RIDERS
Auteur : BRACKEEN
Parution : 09 2003
Pages : 972
Isbn : 1-59273-005-1
Reliure : Paperback
Disponibilite : Disponible a la librairie
*/
import java.awt.DisplayMode;
import java.awt.EventQueue;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.GraphicsConfiguration;
import java.awt.GraphicsDevice;
import java.awt.GraphicsEnvironment;
import java.awt.Image;
import java.awt.Toolkit;
import java.awt.Window;
import java.awt.image.BufferStrategy;
import java.awt.image.BufferedImage;
import java.lang.reflect.InvocationTargetException;
import java.util.ArrayList;
import javax.swing.ImageIcon;
import javax.swing.JFrame;
public class SpriteTest1 {
public static void main(String args[]) {
SpriteTest1 test = new SpriteTest1();
test.run();
}
private static final DisplayMode POSSIBLE_MODES[] = {
new DisplayMode(800, 600, 32, 0), new DisplayMode(800, 600, 24, 0),
new DisplayMode(800, 600, 16, 0), new DisplayMode(640, 480, 32, 0),
new DisplayMode(640, 480, 24, 0), new DisplayMode(640, 480, 16, 0) };
private static final long DEMO_TIME = 10000;
private ScreenManager screen;
private Image bgImage;
private Sprite sprite;
public void loadImages() {
// load images
bgImage = loadImage("images/background.jpg");
Image player1 = loadImage("images/player1.png");
Image player2 = loadImage("images/player2.png");
Image player3 = loadImage("images/player3.png");
// create sprite
Animation anim = new Animation();
anim.addFrame(player1, 250);
anim.addFrame(player2, 150);
anim.addFrame(player1, 150);
anim.addFrame(player2, 150);
anim.addFrame(player3, 200);
anim.addFrame(player2, 150);
sprite = new Sprite(anim);
// start the sprite off moving down and to the right
sprite.setVelocityX(0.2f);
sprite.setVelocityY(0.2f);
}
private Image loadImage(String fileName) {
return new ImageIcon(fileName).getImage();
}
public void run() {
screen = new ScreenManager();
try {
DisplayMode displayMode = screen
.findFirstCompatibleMode(POSSIBLE_MODES);
screen.setFullScreen(displayMode);
loadImages();
animationLoop();
} finally {
screen.restoreScreen();
}
}
public void animationLoop() {
long startTime = System.currentTimeMillis();
long currTime = startTime;
while (currTime - startTime < DEMO_TIME) {
long elapsedTime = System.currentTimeMillis() - currTime;
currTime += elapsedTime;
// update the sprites
update(elapsedTime);
// draw and update the screen
Graphics2D g = screen.getGraphics();
draw(g);
g.dispose();
screen.update();
// take a nap
try {
Thread.sleep(20);
} catch (InterruptedException ex) {
}
}
}
public void update(long elapsedTime) {
// check sprite bounds
if (sprite.getX() < 0) {
sprite.setVelocityX(Math.abs(sprite.getVelocityX()));
} else if (sprite.getX() + sprite.getWidth() >= screen.getWidth()) {
sprite.setVelocityX(-Math.abs(sprite.getVelocityX()));
}
if (sprite.getY() < 0) {
sprite.setVelocityY(Math.abs(sprite.getVelocityY()));
} else if (sprite.getY() + sprite.getHeight() >= screen.getHeight()) {
sprite.setVelocityY(-Math.abs(sprite.getVelocityY()));
}
// update sprite
sprite.update(elapsedTime);
}
public void draw(Graphics g) {
// draw background
g.drawImage(bgImage, 0, 0, null);
// draw sprite
g.drawImage(sprite.getImage(), Math.round(sprite.getX()), Math
.round(sprite.getY()), null);
}
}
/**
* The SimpleScreenManager class manages initializing and displaying full screen
* graphics modes.
*/
class SimpleScreenManager {
private GraphicsDevice device;
/**
* Creates a new SimpleScreenManager object.
*/
public SimpleScreenManager() {
GraphicsEnvironment environment = GraphicsEnvironment
.getLocalGraphicsEnvironment();
device = environment.getDefaultScreenDevice();
}
/**
* Enters full screen mode and changes the display mode.
*/
public void setFullScreen(DisplayMode displayMode, JFrame window) {
window.setUndecorated(true);
window.setResizable(false);
device.setFullScreenWindow(window);
if (displayMode != null && device.isDisplayChangeSupported()) {
try {
device.setDisplayMode(displayMode);
} catch (IllegalArgumentException ex) {
// ignore - illegal mode for this device
}
}
}
/**
* Returns the window currently used in full screen mode.
*/
public Window getFullScreenWindow() {
return device.getFullScreenWindow();
}
/**
* Restores the screen's display mode.
*/
public void restoreScreen() {
Window window = device.getFullScreenWindow();
if (window != null) {
window.dispose();
}
device.setFullScreenWindow(null);
}
}
class Sprite {
private Animation anim;
// position (pixels)
private float x;
private float y;
// velocity (pixels per millisecond)
private float dx;
private float dy;
/**
* Creates a new Sprite object with the specified Animation.
*/
public Sprite(Animation anim) {
this.anim = anim;
}
/**
* Updates this Sprite's Animation and its position based on the velocity.
*/
public void update(long elapsedTime) {
x += dx * elapsedTime;
y += dy * elapsedTime;
anim.update(elapsedTime);
}
/**
* Gets this Sprite's current x position.
*/
public float getX() {
return x;
}
/**
* Gets this Sprite's current y position.
*/
public float getY() {
return y;
}
/**
* Sets this Sprite's current x position.
*/
public void setX(float x) {
this.x = x;
}
/**
* Sets this Sprite's current y position.
*/
public void setY(float y) {
this.y = y;
}
/**
* Gets this Sprite's width, based on the size of the current image.
*/
public int getWidth() {
return anim.getImage().getWidth(null);
}
/**
* Gets this Sprite's height, based on the size of the current image.
*/
public int getHeight() {
return anim.getImage().getHeight(null);
}
/**
* Gets the horizontal velocity of this Sprite in pixels per millisecond.
*/
public float getVelocityX() {
return dx;
}
/**
* Gets the vertical velocity of this Sprite in pixels per millisecond.
*/
public float getVelocityY() {
return dy;
}
/**
* Sets the horizontal velocity of this Sprite in pixels per millisecond.
*/
public void setVelocityX(float dx) {
this.dx = dx;
}
/**
* Sets the vertical velocity of this Sprite in pixels per millisecond.
*/
public void setVelocityY(float dy) {
this.dy = dy;
}
/**
* Gets this Sprite's current image.
*/
public Image getImage() {
return anim.getImage();
}
}
/**
* The ScreenManager class manages initializing and displaying full screen
* graphics modes.
*/
class ScreenManager {
private GraphicsDevice device;
/**
* Creates a new ScreenManager object.
*/
public ScreenManager() {
GraphicsEnvironment environment = GraphicsEnvironment
.getLocalGraphicsEnvironment();
device = environment.getDefaultScreenDevice();
}
/**
* Returns a list of compatible display modes for the default device on the
* system.
*/
public DisplayMode[] getCompatibleDisplayModes() {
return device.getDisplayModes();
}
/**
* Returns the first compatible mode in a list of modes. Returns null if no
* modes are compatible.
*/
public DisplayMode findFirstCompatibleMode(DisplayMode modes[]) {
DisplayMode goodModes[] = device.getDisplayModes();
for (int i = 0; i < modes.length; i++) {
for (int j = 0; j < goodModes.length; j++) {
if (displayModesMatch(modes[i], goodModes[j])) {
return modes[i];
}
}
}
return null;
}
/**
* Returns the current display mode.
*/
public DisplayMode getCurrentDisplayMode() {
return device.getDisplayMode();
}
/**
* Determines if two display modes "match". Two display modes match if they
* have the same resolution, bit depth, and refresh rate. The bit depth is
* ignored if one of the modes has a bit depth of
* DisplayMode.BIT_DEPTH_MULTI. Likewise, the refresh rate is ignored if one
* of the modes has a refresh rate of DisplayMode.REFRESH_RATE_UNKNOWN.
*/
public boolean displayModesMatch(DisplayMode mode1, DisplayMode mode2)
{
if (mode1.getWidth() != mode2.getWidth()
|| mode1.getHeight() != mode2.getHeight()) {
return false;
}
if (mode1.getBitDepth() != DisplayMode.BIT_DEPTH_MULTI
&& mode2.getBitDepth() != DisplayMode.BIT_DEPTH_MULTI
&& mode1.getBitDepth() != mode2.getBitDepth()) {
return false;
}
if (mode1.getRefreshRate() != DisplayMode.REFRESH_RATE_UNKNOWN
&& mode2.getRefreshRate() != DisplayMode.REFRESH_RATE_UNKNOWN
&& mode1.getRefreshRate() != mode2.getRefreshRate()) {
return false;
}
return true;
}
/**
* Enters full screen mode and changes the display mode. If the specified
* display mode is null or not compatible with this device, or if the
* display mode cannot be changed on this system, the current display mode
* is used.
* <p>
* The display uses a BufferStrategy with 2 buffers.
*/
public void setFullScreen(DisplayMode displayMode) {
final JFrame frame = new JFrame();
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setUndecorated(true);
frame.setIgnoreRepaint(true);
frame.setResizable(false);
device.setFullScreenWindow(frame);
if (displayMode != null && device.isDisplayChangeSupported()) {
try {
device.setDisplayMode(displayMode);
} catch (IllegalArgumentException ex) {
}
// fix for mac os x
frame.setSize(displayMode.getWidth(), displayMode.getHeight());
}
// avoid potential deadlock in 1.4.1_02
try {
EventQueue.invokeAndWait(new Runnable() {
public void run() {
frame.createBufferStrategy(2);
}
});
} catch (InterruptedException ex) {
// ignore
} catch (InvocationTargetException ex) {
// ignore
}
}
/**
* Gets the graphics context for the display. The ScreenManager uses double
* buffering, so applications must call update() to show any graphics drawn.
* <p>
* The application must dispose of the graphics object.
*/
public Graphics2D getGraphics() {
Window window = device.getFullScreenWindow();
if (window != null) {
BufferStrategy strategy = window.getBufferStrategy();
return (Graphics2D) strategy.getDrawGraphics();
} else {
return null;
}
}
/**
* Updates the display.
*/
public void update() {
Window window = device.getFullScreenWindow();
if (window != null) {
BufferStrategy strategy = window.getBufferStrategy();
if (!strategy.contentsLost()) {
strategy.show();
}
}
// Sync the display on some systems.
// (on Linux, this fixes event queue problems)
Toolkit.getDefaultToolkit().sync();
}
/**
* Returns the window currently used in full screen mode. Returns null if
* the device is not in full screen mode.
*/
public JFrame getFullScreenWindow() {
return (JFrame) device.getFullScreenWindow();
}
/**
* Returns the width of the window currently used in full screen mode.
* Returns 0 if the device is not in full screen mode.
*/
public int getWidth() {
Window window = device.getFullScreenWindow();
if (window != null) {
return window.getWidth();
} else {
return 0;
}
}
/**
* Returns the height of the window currently used in full screen mode.
* Returns 0 if the device is not in full screen mode.
*/
public int getHeight() {
Window window = device.getFullScreenWindow();
if (window != null) {
return window.getHeight();
} else {
return 0;
}
}
/**
* Restores the screen's display mode.
*/
public void restoreScreen() {
Window window = device.getFullScreenWindow();
if (window != null) {
window.dispose();
}
device.setFullScreenWindow(null);
}
/**
* Creates an image compatible with the current display.
*/
public BufferedImage createCompatibleImage(int w, int h, int transparancy) {
Window window = device.getFullScreenWindow();
if (window != null) {
GraphicsConfiguration gc = window.getGraphicsConfiguration();
return gc.createCompatibleImage(w, h, transparancy);
}
return null;
}
}
/**
* The Animation class manages a series of images (frames) and the amount of
* time to display each frame.
*/
class Animation {
private ArrayList frames;
private int currFrameIndex;
private long animTime;
private long totalDuration;
/**
* Creates a new, empty Animation.
*/
public Animation() {
frames = new ArrayList();
totalDuration = 0;
start();
}
/**
* Adds an image to the animation with the specified duration (time to
* display the image).
*/
public synchronized void addFrame(Image image, long duration) {
totalDuration += duration;
frames.add(new AnimFrame(image, totalDuration));
}
/**
* Starts this animation over from the beginning.
*/
public synchronized void start() {
animTime = 0;
currFrameIndex = 0;
}
/**
* Updates this animation's current image (frame), if neccesary.
*/
public synchronized void update(long elapsedTime) {
if (frames.size() > 1) {
animTime += elapsedTime;
if (animTime >= totalDuration) {
animTime = animTime % totalDuration;
currFrameIndex = 0;
}
while (animTime > getFrame(currFrameIndex).endTime) {
currFrameIndex++;
}
}
}
/**
* Gets this Animation's current image. Returns null if this animation has
* no images.
*/
public synchronized Image getImage() {
if (frames.size() == 0) {
return null;
} else {
return getFrame(currFrameIndex).image;
}
}
private AnimFrame getFrame(int i) {
return (AnimFrame) frames.get(i);
}
private class AnimFrame {
Image image;
long endTime;
public AnimFrame(Image image, long endTime) {
this.image = image;
this.endTime = endTime;
}
}
}
|