我正在制作游戏,我有以下主要课程
主控制器类:
public class Manager implements Runnable {
private boolean running;
private Thread thread;
private MasterRenderer window;
private PlayerCharacter player;
private Map map;
public Manager() {
window = new MasterRenderer();
player = new PlayerCharacter(0, 0, Entity.FACING_DOWN, "Pepe", 0, 1, 2);
map = new Map();
}
public void initialize() {
window.setPlayerRenderer(new PlayerRenderer(player));
window.setMapRenderer(new MapRenderer(map));
window.setTerrainRenderer(new TerrainRenderer(new Terrain(0, 0, Entity.FACING_DOWN, "arbol", false)));
running = true;
thread = new Thread(this);
thread.start();
}
public void run() {
long timer = System.currentTimeMillis();
long lastTime = System.nanoTime();
final double ns = 1000000000.0 / 60.0;
double delta = 0;
int frames = 0;
int ticks = 0;
while (running) {
long now = System.nanoTime();
delta += (now - lastTime) / ns;
lastTime = now;
while (delta >= 1) {
tick(delta);
ticks++;
delta--;
frames++;
render();
}
if (System.currentTimeMillis() - timer > 1000) {
timer += 1000;
System.out.println("Frames: " + frames + "\tTicks: " + ticks);
frames = ticks = 0;
}
}
}
public void tick(double delta) {
}
public void render() {
window.render();
}
public static void main(String[] args) {
Manager manager = new Manager();
manager.initialize();
}
}
主视图类:
public class MasterRenderer extends Canvas implements KeyListener {
private static final long serialVersionUID = 1L;
public static final int WIDTH = 640;
public static final int HEIGHT = WIDTH * 3 / 4;
public static final String TITLE = "The legend of Finn";
private JFrame frame;
private BufferStrategy bs;
private Graphics g;
private PlayerRenderer playerR;
private MapRenderer mapR;
private TerrainRenderer terrainR;
public MasterRenderer() {
setPreferredSize(new Dimension(WIDTH, HEIGHT));
frame = new JFrame();
addKeyListener(this);
frame.setTitle(TITLE);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.add(this);
frame.setResizable(false);
frame.pack();
frame.setLocationRelativeTo(null);
frame.setVisible(true);
requestFocus();
}
public void render() {
bs = getBufferStrategy();
if (bs == null) {
createBufferStrategy(3);
return;
}
g = bs.getDrawGraphics();
g.setColor(Color.BLACK);
g.fillRect(0, 0, getWidth(), getHeight());
playerR.render(g);
mapR.render(g);
terrainR.render(g);
bs.show();
g.dispose();
}
public void setMapRenderer(MapRenderer mapR) {
this.mapR = mapR;
}
public void setPlayerRenderer(PlayerRenderer playerR) {
this.playerR = playerR;
}
public void setTerrainRenderer(TerrainRenderer terrainR) {
this.terrainR = terrainR;
}
@Override
public void keyTyped(KeyEvent e) {
}
@Override
public void keyPressed(KeyEvent e) {
int i=e.getKeyCode();
System.out.println("Key pressed!!");
}
@Override
public void keyReleased(KeyEvent e) {
}
}
我以这种方式组织代码,因为我试图真正坚持MVC(此外,将keyListener放在管理器类中现在是一个痛苦的屁股)。有什么简单的方法可以在MasterRenderer注册按键时通知Manager吗?
答案 0 :(得分:0)
您的View中没有Control引用,也没有注册侦听器的方法,如果没有这个,我看不到视图将如何与控件通信。我看到你有两种可能的解决方案:
fireXxx(...)
方法。幸运的是,许多Swing和AWT组件已经具有上面的数字2的机制,我建议你这样做:让你的控件用你的Canvas对象注册一个PropertyChangeListener(如果它是一个JPanel更好!),然后在你的KeyListener firePropertyChange(...)
方法通知控制状态更改。
例如:
import java.awt.Dimension;
import java.awt.event.KeyAdapter;
import java.awt.event.KeyEvent;
import java.beans.PropertyChangeEvent;
import java.beans.PropertyChangeListener;
import javax.swing.*;
public class MyControl implements Runnable, PropertyChangeListener {
public MyControl() {
// TODO finish
}
@Override
public void propertyChange(PropertyChangeEvent pcEvt) {
// this is only one of potentially many properties that the control can listen to
if (MyView.KEY_PRESSED.equals(pcEvt.getPropertyName())) {
// respond to the key pressed code
System.out.println("KeyCode is: " + pcEvt.getNewValue());
}
}
@Override
public void run() {
// TODO Finish!
}
private static void createAndShowGui() {
// create both view and control
MyControl control = new MyControl();
MyView view = new MyView();
// now wire the control to listen to the view
view.addPropertyChangeListener(MyView.KEY_PRESSED, control);
JFrame frame = new JFrame("MyControl");
frame.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);
frame.getContentPane().add(view);
frame.pack();
frame.setLocationByPlatform(true);
frame.setVisible(true);
}
public static void main(String[] args) {
SwingUtilities.invokeLater(() -> createAndShowGui());
}
}
class MyView extends JPanel {
// constant for PropertyChangeListener use:
public static final String KEY_PRESSED = "key pressed";
private static final int PREF_W = 400;
private static final int PREF_H = PREF_W;
public MyView() {
setFocusable(true);
requestFocusInWindow();
addKeyListener(new MyKeyListener());
}
@Override
public Dimension getPreferredSize() {
if (isPreferredSizeSet()) {
return super.getPreferredSize();
}
return new Dimension(PREF_W, PREF_H);
}
private class MyKeyListener extends KeyAdapter {
@Override
public void keyPressed(KeyEvent e) {
// get the keycode pressed
int newValue = e.getKeyCode();
// ** notify any listeners that this key has been pressed **
firePropertyChange(KEY_PRESSED, null, newValue);
}
}
}