问题描述
Mouse.java
package game.input;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.awt.event.MouseWheelEvent;
// holds information about mouse events.
// eg,presses of buttons.
public class Mouse extends MouseAdapter {
// the position of the mouse.
public static int x,y;
// Is the mouse pressed.
public static boolean pressed;
// Is the mouse held.
public static boolean held;
// Is the mouse hovered over the window.
public static boolean focused;
// Is the mouse being dragged.
public static boolean dragging;
// no mouse wheel support.
@Override
public void mouseWheelMoved(MouseWheelEvent event) {}
@Override
public void mouseDragged(MouseEvent event) {
x = event.getX();
y = event.getY();
dragging = true;
}
@Override
public void mouseMoved(MouseEvent event) {
x = event.getX();
y = event.getY();
}
@Override
public void mouseEntered(MouseEvent event) {
focused = true;
}
@Override
public void mouseExited(MouseEvent event) {
focused = false;
}
@Override
public void mousepressed(MouseEvent event) {
held = true;
}
@Override
public void mouseReleased(MouseEvent event) {
held = false;
dragging = false;
pressed = true;
}
}
Keyboard.java
package game.input;
import java.awt.event.KeyAdapter;
import java.awt.event.KeyEvent;
// holds information about key events.
public class Keyboard extends KeyAdapter {
// which keys are being held down.
private static boolean[] heldKeys;
// which keys are being clicked
private static boolean[] clickedKeys;
// size of arrays.
private final int size;
public Keyboard() {
// there are 255 valid key codes.
// plus one for the array size.
size = 256;
clickedKeys = new boolean[size];
heldKeys = new boolean[size];
}
// when the key is pressed.
@Override
public void keypressed(KeyEvent event) {
// catches out of bounds error.
if(event.getKeyCode() > size)
return;
// key is being held.
heldKeys[event.getKeyCode()] = true;
}
@Override
public void keyreleased(KeyEvent event) {
// catches out of bounds error.
if(event.getKeyCode() > size)
return;
// key is let go.
heldKeys[event.getKeyCode()] = false;
// when key is let go,it gets interpreted as it being pressed.
clickedKeys[event.getKeyCode()] = true;
}
// returns whether or not the key is held.
public static boolean keyHeld(Key key) {
if(heldKeys != null)
return heldKeys[key.keyCode];
return false;
}
// returns whether or not the key is clicked.
public static boolean keyClicked(Key key) {
if(clickedKeys != null)
return clickedKeys[key.keyCode];
return false;
}
// resets key input.
public static void resetKeys() {
if(clickedKeys != null)
for(int i = 0; i < clickedKeys.length; i++)
clickedKeys[i] = false;
}
public enum Key {
// movement keys.
LEFT(37),UP(38),RIGHT(39),DOWN(40),// x key.
A(88),// z key.
B(90),// enter key.
START(10);
private int keyCode;
private Key(int keyCode) {
this.keyCode = keyCode;
}
};
}
Game.java
package game;
import java.awt.Graphics2D;
import game.input.Keyboard;
import game.input.Mouse;
import game.room.Room;
import userInterface.containers.BB_Window;
// creates a new game
public final class Game {
// the window that the game resides in.
private static BB_Window window;
// the current room that is drawn to the window.
private static Room room;
private static GameLoop gameLoop;
// game constructor cannot be called.
private Game() {}
// inits the game.
// ie,adds input to the game (key and mouse).
public static void init(BB_Window window) {
if(gameLoop != null)
return;
// creates mouse and keyboard listeners.
Mouse mouse = new Mouse();
Keyboard keyboard = new Keyboard();
// adds input listeners to the window.
window.getJFrame().addKeyListener(keyboard);
window.getCanvas().addMouseListener(mouse);
window.getCanvas().addMouseMotionListener(mouse);
// init game loop
gameLoop = new GameLoop();
// init window
Game.window = window;
gameLoop.start();
}
// updates the current room and resets input.
protected static void update() {
// if room doesn't exist,don't update it.
if(room == null)
return;
// updates current room.
Game.room.update();
// resets mouse input.
Mouse.pressed = false;
// resets key input.
Keyboard.resetKeys();
// if a mouse or key button is clicked,// then it would have to be reset to false here.
}
// renders the current room.
protected static void render() {
// if room doesn't exist,don't render it.
if(room == null)
return;
// creates graphics object from the window canvas.
Graphics2D graphics = (Graphics2D) window.getCanvas().getBufferStrategy().getDrawGraphics();
// creates the screen for next drawing.
graphics.clearRect(0,window.getWidth(),window.getHeight());
// renders the current room.
Game.room.render(graphics);
// shows the buffer.
window.getCanvas().getBufferStrategy().show();
// removes graphics object.
graphics.dispose();
}
// sets the current room to a new one.
public static void setRoom(Room newRoom) {
newRoom.init();
Game.room = newRoom;
}
// returns the current room.
public static Room getRoom() {
return Game.room;
}
// returns width of window.
public static int getwindowWidth() {
return window.getWidth();
}
// returns height of window.
public static int getwindowHeight() {
return window.getHeight();
}
// stops the game loop.
public static void stop() {
gameLoop.stop();
}
}
GameLoop.java
package game;
public class GameLoop implements Runnable {
// the thread that the game runs on.
private Thread thread;
// is the game running.
private boolean running;
// starts the game loop.
// inits the thread and calls its start method.
public void start() {
// you can't start the game if it is started.
if(running)
return;
// starts the game.
running = true;
// creates thread.
thread = new Thread(this);
// starts the game.
// ie,calls thread.run();
thread.start();
}
// stops the game loop.
// interrupts the thread and terminates the currently running JVM.
public void stop() {
// you can't end the game if it is ended.
if(!running)
return;
// ends the game.
running = false;
// interrupts the thread.
// ie,ends the thread.
// this will always end the thread,// because running is set to false.
thread.interrupt();
// ends the program.
System.exit(0);
}
// this is the game loop.
@Override
public void run() {
// holds information about each frames elapsed time.
double start,prevIoUs = System.nanoTime() / 1_000_000_000.0;
// time.
double actualFrameTime,realTime = 0;
// should the game be rendered.
boolean render;
// fps
final int FPS = 60;
final double DESIRED_FRAME_TIME = 1.0 / FPS;
// while the game is running
while(running) {
// calculates the elapsed time of the frame.
// converts from nano seconds to seconds
// by dividing by one billion.
start = System.nanoTime() / 1_000_000_000.0;
actualFrameTime = start - prevIoUs;
prevIoUs = start;
// the game time is updated by the elapsed frame time.
realTime += actualFrameTime;
// resets it to back to false.
render = false;
// if time surpasses desired frame time,game should update.
while(realTime >= DESIRED_FRAME_TIME && realTime != 0) {
realTime -= DESIRED_FRAME_TIME;
Game.update();
// if the game is updated,the game should render.
// if the game is not updated,the game doesn't render.
render = true;
}
if(render)
Game.render();
// sleep if game should not render.
// reduces cpu usage by a lot.
else
try {
// sleep for one millisecond.
Thread.sleep(1);
} catch (InterruptedException e) {
e.printstacktrace();
}
}
}
}
BB_Window.java
package userInterface.containers;
import java.awt.Canvas;
import java.awt.Dimension;
import java.awt.image.BufferStrategy;
import javax.swing.JFrame;
// the JFrame that the game will reside in.
public final class BB_Window {
private JFrame window;
private Canvas canvas;
private Dimension windowDimension;
// constructs the canvas,window,and buffer.
public BB_Window(String title,int width,int height) {
// creates dimension.
windowDimension = new Dimension(width,height);
// creates a canvas with a bunch of defaults.
canvas = new Canvas();
// sets a non-changeable size.
canvas.setPreferredSize(windowDimension);
canvas.setMinimumSize(windowDimension);
canvas.setMaximumSize(windowDimension);
// cannot be focused for event listeners.
canvas.setFocusable(false);
// creates window with a bunch of defaults.
window = new JFrame();
window.getContentPane().add(canvas);
window.setTitle(title);
window.setDefaultCloSEOperation(JFrame.EXIT_ON_CLOSE);
window.setResizable(false);
window.pack();
window.setVisible(true);
// center of screen.
window.setLocationRelativeto(null);
BufferStrategy bufferStrategy = canvas.getBufferStrategy();
if(bufferStrategy == null)
canvas.createBufferStrategy(3);
}
// returns the frame.
public JFrame getJFrame() {
return window;
}
// returns the window width.
public int getWidth() {
return windowDimension.width;
}
// returns the window height.
public int getHeight() {
return windowDimension.height;
}
// returns the canvas.
public Canvas getCanvas() {
return canvas;
}
}
Room.java
package game.room;
import java.awt.Graphics2D;
// future functionality might be added,// which is why this class is abstract and not interface.
// represents a room/location in your Game
// eg,a town,a house,a forest,and a cave are all examples of rooms.
public abstract class Room {
public abstract void init();
public abstract void update();
public abstract void render(Graphics2D graphics);
}
但是,我注意到,每当我测试游戏库时,每隔几秒钟就会发生一次非常明显的停顿,持续了几秒钟。这很烦人。但是,更令人讨厌的是,在我的计算机上,这种块状/缓慢的运动比在其他计算机上更为明显。我的计算机正在发生什么状况?我该如何解决?这是我的游戏库工作方式的示例。
Game.setRoom(new Room() {
private int x,y;
@Override
public void init() {
x = 0;
y = 0;
}
@Override
public void update() {
x++;
y++;
}
@Override
public void render(Graphics2D graphics) {
graphics.fillRect(x,y,100,100);
}});
Game.init(new BB_Window("Test",640,640));
此示例程序绘制一个矩形,该矩形沿屏幕对角线向下移动。 但是,有时,矩形似乎会“跳过”像素,并且移动得比其应有的更多。 我试图记录屏幕以准确显示正在发生的事情,但是由于某些原因,视频中没有出现卡纸现象。
我尝试通过启用硬件加速功能
System.setProperty("sun.java2d.opengl","true");
但是那没做。
我的计算机一点也不坏,为什么游戏在其他计算机上的运行比在我的计算机上更流畅?
该如何解决我的游戏库中的问题?
谢谢。
解决方法
暂无找到可以解决该程序问题的有效方法,小编努力寻找整理中!
如果你已经找到好的解决方法,欢迎将解决方案带上本链接一起发送给小编。
小编邮箱:dio#foxmail.com (将#修改为@)