2016-05-27 7 views
0

私はゲームを作ってるんだ、と私は、次の主要なクラスビューからキーが押されたことをコントローラに通知しますか?

メインコントローラクラスがあります。私は、コードをこのように整理しました

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) { 
} 
} 

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(); 
} 
} 

メインビュークラスをなぜなら、私は本当にMVCに固執しようとしているからです(しかも、managerクラスにkeyListenerを置くことは、今、バットの痛みです)。 MasterRendererがキーを登録したときにManagerに通知する簡単な方法はありますか?

+0

私の記事を見て、[レトロスネークゲーム](http://java-articles.info/articles/?p=768)、Aの例を見てMVCパターンを使用するSwingアプリケーションであり、キーボード入力にもKey Bindingsを使用します。 –

+0

....................こんにちは? –

答えて

0

ビュー内にはコントロール参照がなく、リスナーを登録するメソッドもありません。これがなければ、ビューとコントロールとの通信方法はわかりません。私はあなたが2つの解決策を持っている参照してください。

  1. がビューにコントロールの参照を渡し、それが状態変化のことを通知したいときにコントロールのビュー呼び出し方法を持っている、またはメカニズムを設定
  2. SwingPropertyChangeSupportメカニズムなど、状態を変更するためのリスナーへの制御を許可します。あなたがこのルートに行くなら、あなたはサポートの適切な方法を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); 
     } 

    } 

} 
関連する問題