2016-01-25 3 views
0

J'ai construit un programme court qui dessine un vaisseau spatial sur un JPanel et qui écoute les touches qui indiquent au programme de tirer une balle. Le problème est que ce n'est même pas en train de peindre le vaisseau spatial ou les balles à l'écran. Je soupçonne également que les KeyBindings ne fonctionnent peut-être pas car c'était un problème antérieur (que je n'ai peut-être pas résolu), mais le principal problème reste le fait que mon écran n'est pas peint. Voici mon code:Le programme ne peint pas l'écran correctement

public enum Direction { 
    LEFT, RIGHT, SPACE 
} 

import javax.swing.JFrame; 

public class Main { 
    public static void main(String[] args) { 
     JFrame frame; 

     Ship s1; 
     Shoot shoot; 

     // Set the frame up 
     frame = new JFrame(); 
     frame.setSize(400, 300); 
     frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); 
     frame.setResizable(false); 
     frame.setVisible(true); 

     // Get some more necessary objects 
     s1 = new Ship(); 
     shoot = new Shoot(s1); 
     frame.getContentPane().add(shoot); 
     s1.setShoot(shoot); 

     // Threads 
     Thread ship = new Thread(s1); 
     ship.start(); 
    } 
} 

import java.awt.Graphics; 
import java.awt.event.KeyEvent; 

import javax.swing.Action; 
import javax.swing.ActionMap; 
import javax.swing.InputMap; 
import javax.swing.JPanel; 
import javax.swing.KeyStroke; 

public class Shoot extends JPanel { 

    Ship s1; 

    public Shoot(Ship s1) { 
     this.s1 = s1; 

     addKeyBinding(KeyEvent.VK_LEFT, "left.pressed", new MoveAction(true, s1, Direction.LEFT), true); 
     addKeyBinding(KeyEvent.VK_LEFT, "left.released", new MoveAction(false, s1, Direction.LEFT), false); 

     addKeyBinding(KeyEvent.VK_RIGHT, "right.pressed", new MoveAction(true, s1, Direction.RIGHT), true); 
     addKeyBinding(KeyEvent.VK_RIGHT, "right.released", new MoveAction(false, s1, Direction.RIGHT), false); 

     addKeyBinding(KeyEvent.VK_SPACE, "space.pressed", new MoveAction(true, s1, Direction.SPACE), true); 
     addKeyBinding(KeyEvent.VK_SPACE, "space.released", new MoveAction(false, s1, Direction.SPACE), false); 

     setDoubleBuffered(true); 
    } 

    @Override 
    public void paintComponent(Graphics g) { 
     // Draw the ship 
     super.paintComponent(g); 
     s1.draw(g); 
     g.fill3DRect(40, 50, 10, 10, false); 
    } 

    protected void addKeyBinding(int keyCode, String name, Action action, boolean keyPressed) { 
     if (keyPressed) { 
      addKeyBinding(KeyStroke.getKeyStroke(keyCode, 0, false), name, action); 
     } else { 
      addKeyBinding(KeyStroke.getKeyStroke(keyCode, 0, true), name, action); 
     } 
    } 

    protected void addKeyBinding(KeyStroke keyStroke, String name, Action action) { 
     InputMap inputMap = getInputMap(WHEN_IN_FOCUSED_WINDOW); 
     ActionMap actionMap = getActionMap(); 
     inputMap.put(keyStroke, name); 
     actionMap.put(name, action); 
    } 

} 

import java.awt.Color; 
import java.awt.Graphics; 
import java.awt.Rectangle; 

public class Ship implements Runnable { 
    int x, y, xDirection, bx, by; 
    boolean readyToFire, shooting = false; 
    Rectangle bullet; 
    Shoot shoot; 

    public Ship() { 
     x = 175; 
     y = 275; 
     bullet = new Rectangle(0, 0, 3, 5); 
    } 

    public void draw(Graphics g) { 
     // System.out.println("draw() called"); 
     g.setColor(Color.BLUE); 
     g.fillRect(x, y, 40, 10); 
     g.fillRect(x + 18, y - 7, 4, 7); 
     if (shooting) { 
      g.setColor(Color.RED); 
      g.fillRect(bullet.x, bullet.y, bullet.width, bullet.height); 
     } 
     shoot.repaint(); 
    } 

    public void move() { 
     x += xDirection; 
     if (x <= 0) 
      x = 0; 
     if (x >= 360) 
      x = 360; 
     shoot.repaint(); 
    } 

    public void shoot() { 
     if (shooting) { 
      bullet.y--; 
      shoot.repaint(); 
     } 
    } 

    public void setXDirection(int xdir) { 
     xDirection = xdir; 
    } 

    public void setShoot(Shoot shoot) { 
     this.shoot = shoot; 
    } 

    @Override 
    public void run() { 
     try { 
      while (true) { 
       shoot(); 
       move(); 
       Thread.sleep(5); 
      } 
     } catch (Exception e) { 
      System.err.println(e.getMessage()); 
     } 

    } 
} 

import java.awt.Rectangle; 
import java.awt.event.ActionEvent; 
import java.util.HashSet; 

import javax.swing.AbstractAction; 

public class MoveAction extends AbstractAction { 

    boolean pressed; 
    Ship s1; 
    Direction dir; 
    private Set<Direction> movement; 

    public MoveAction(boolean pressed, Ship s1, Direction dir) { 
     System.out.println("moveaction class"); 
     movement = new HashSet<Direction>(); 
     this.pressed = pressed; 
     this.s1 = s1; 
     this.dir = dir; 
    } 

    @Override 
    public void actionPerformed(ActionEvent e) { 
     try { 
      if (movement.contains(Direction.LEFT)) { 
       if (pressed) { 
        s1.setXDirection(-1); 
       } else { 
        s1.setXDirection(0); 
       } 
      } else if (movement.contains(Direction.RIGHT)) { 
       if (pressed) { 
        s1.setXDirection(1); 
       } else { 
        s1.setXDirection(0); 
       } 
      } else if (movement.contains(Direction.SPACE)) { 
       if (pressed) { 
        if (s1.bullet == null) 
         s1.readyToFire = true; 
        if (s1.readyToFire) { 
         s1.bullet.x = s1.x + 18; 
         s1.bullet.y = s1.y - 7; 
         s1.shooting = true; 
        } 
       } else { 
        s1.readyToFire = false; 
        if (s1.bullet.y <= -7) { 
         s1.bullet = null; 
         s1.shooting = false; 
         s1.bullet = null; 
         s1.bullet = new Rectangle(0, 0, 0, 0); 
         s1.readyToFire = true; 
        } 
       } 
      } 
     } catch (NullPointerException ex) { 
      System.out.println("NullPointerException"); 
     } 
    } 
+0

appel 'setVisible' last – MadProgrammer

+0

En ce qui concerne le problème des raccourcis clavier, vous utilisez le 'movement'' Set' (qui est suspect), mais vous n'y ajoutez rien, vous devriez vérifier la valeur 'dir'. D'une manière générale, vous le codez, bon, partout – MadProgrammer

Répondre

5

Donc, il y a un certain nombre de questions ...

Vous devez appeler setVisible sur le JFrame dernier, cela fera en sorte que les composants sont mis en page

Votre problème de raccourcis clavier semble lié au fait que vous utilisez le mouvement Set, mais vous n'y ajoutez rien. Au lieu de cela, vous devriez vérifier la valeur dir.

Et probablement un tas d'autres choses. Votre code est étroitement couplé et il n'y a pas de gestion centralisée de l'état. Je commencerais par avoir une meilleure compréhension du paradigme Model-View-Controller et séparer le code dans les domaines de responsabilité appropriés. Les "données" pour le jeu doivent se séparer du "rendu" du jeu, qui doit être séparé des décisions sur la façon dont le jeu doit être mis à jour.

Ce que je vais présenter est une simplification excessive destinée à susciter des idées, plutôt que été une solution concrète, car il y a un certain nombre de façons dont vous pouvez réaliser la mise en œuvre physique ...

Alors, ce que nous le besoin est, un concept de quelque chose dans le jeu, AKA une "entité", les entités prennent de nombreuses formes, mais je vais me concentrer sur des entités rendables/affichables. Vous avez besoin d'une sorte de modèle qui est responsable de la modélisation de l'état actuel du jeu et qui est responsable de la mise en œuvre des règles. Vous avez besoin d'un type de vue, qui est responsable du rendu du modèle et de la réponse aux entrées de l'utilisateur. Vous avez besoin d'un contrôleur qui contrôle la façon dont le modèle et la vue sont pontés.

Il est toujours judicieux de commencer par une série de interfaces qui définissent les attentes contractuelles et les moyens attendus par lesquels les éléments sont censés communiquer les uns avec les autres. Encore une fois, j'ai pris une approche simple et directe, mais il est certainement pas la seule ...

public static enum Direction { 
    LEFT, 
    RIGHT, 
    SPACE 
} 

public interface Entity { 
    public void paint(Graphics2D g2d); 
    public Point getLocation(); 
    public void setLocation(Point p); 
    public Dimension getSize(); 
} 

public interface GameModel { 
    public Entity[] getEntities(); 
    public void update(Rectangle bounds, Set<Direction> keys); 
} 

public interface GameController { 
    public Entity[] getEntities(); 
    public void setDirection(Direction direction, boolean pressed); 
    public void start(); 
} 

public interface GameView { 
    public void setController(GameController controller); 
    public GameController getController(); 
    public Rectangle getViewBounds(); 
    public void repaint(); 
} 

Jetons un coup d'oeil à la mise en œuvre des entités. Cet exemple a deux entités, une Player et Bullet ...

public abstract class AbstractEntity implements Entity { 

    private final Point location = new Point(0, 0); 

    @Override 
    public Point getLocation() { 
     return new Point(location); 
    } 

    @Override 
    public void setLocation(Point p) { 
     location.setLocation(p); 
    } 

} 

public class Player extends AbstractEntity { 

    public Player(Rectangle bounds) { 
     int x = bounds.x + ((bounds.width - getSize().width)/2); 
     int y = bounds.y + (bounds.height - getSize().height); 
     setLocation(new Point(x, y)); 
    } 

    @Override 
    public Dimension getSize() { 
     return new Dimension(40, 17); 
    } 

    @Override 
    public void paint(Graphics2D g2d) { 
     Point p = getLocation(); 
     Dimension size = getSize(); 
     g2d.setColor(Color.BLUE); 
     g2d.fillRect(p.x, p.y + 7, size.width, 10); 
     g2d.fillRect(p.x + 18, p.y, 4, 7); 
    } 

} 

public class Bullet extends AbstractEntity { 

    @Override 
    public void paint(Graphics2D g2d) { 
     Rectangle bullet = new Rectangle(getLocation(), getSize()); 
     g2d.setColor(Color.RED); 
     g2d.fill(bullet); 
    } 

    @Override 
    public Dimension getSize() { 
     return new Dimension(4, 8); 
    } 

} 

rien de spectaculaire, mais ils définissent chacun leurs paramètres et peut rendre leurs états quand on lui demande.

Ensuite, nous avons le modèle, le contrôleur et la vue. Cet exemple utilise le contrôleur en tant que boucle de jeu principale, responsable de la mise à jour de l'état du jeu (modèle) et de la planification des repeints. Ceci est fait avec l'utilisation d'un Swing Timer car cela empêche les conditions de course possibles entre la boucle de mise à jour et la boucle de peinture. Une mise en œuvre plus complexe devrait prendre en charge le processus de peinture grâce à l'utilisation d'un BufferStrategy et BufferStrategy and BufferCapabilities.

Le modèle prend simplement les limites de vue actuelles et l'état actuel des clés et met à jour l'état des entités.

La vue surveille l'entrée de l'utilisateur, notifie le contrôleur et restitue l'état actuel du jeu.

Vous remarquerez que la vue et le modèle ne communiquent jamais directement entre eux, c'est le domaine du contrôleur.

public class DefaultGameModel implements GameModel { 

    private final List<Entity> entities; 
    private Player player; 

    private Long lastShot; 

    public DefaultGameModel() { 
     entities = new ArrayList<>(25); 
    } 

    @Override 
    public Entity[] getEntities() { 
     return entities.toArray(new Entity[0]); 
    } 

    @Override 
    public void update(Rectangle bounds, Set<Direction> keys) { 
     if (player == null) { 
      player = new Player(bounds); 
      entities.add(player); 
     } 

     Point p = player.getLocation(); 
     int xDelta = 0; 
     if (keys.contains(Direction.LEFT)) { 
      xDelta = -4; 
     } else if (keys.contains(Direction.RIGHT)) { 
      xDelta = 4; 
     } 
     p.x += xDelta; 
     if (p.x <= bounds.x) { 
      p.x = bounds.x; 
     } else if (p.x + player.getSize().width >= bounds.x + bounds.width) { 
      p.x = bounds.width - player.getSize().width; 
     } 
     player.setLocation(p); 

     Iterator<Entity> it = entities.iterator(); 
     while (it.hasNext()) { 
      Entity entity = it.next(); 
      if (entity instanceof Bullet) { 
       Point location = entity.getLocation(); 
       Dimension size = entity.getSize(); 
       location.y -= size.height; 
       if (location.y + size.height < bounds.y) { 
        it.remove(); 
       } else { 
        entity.setLocation(location); 
       } 
      } 
     } 

     if (keys.contains(Direction.SPACE)) { 
      if (lastShot == null || System.currentTimeMillis() - lastShot > 100) { 
       lastShot = System.currentTimeMillis(); 
       Bullet bullet = new Bullet(); 
       int x = p.x + ((player.getSize().width - bullet.getSize().width)/2); 
       int y = p.y - bullet.getSize().height; 
       bullet.setLocation(new Point(x, y)); 

       entities.add(bullet); 
      } 
     } 
    } 

} 

public class DefaultGameController implements GameController { 

    private GameModel model; 
    private GameView view; 

    private Timer timer; 

    private Set<Direction> keys = new HashSet<>(25); 

    public DefaultGameController(GameModel gameModel, GameView gameView) { 
     gameView.setController(this); 

     view = gameView; 
     model = gameModel; 
    } 

    @Override 
    public Entity[] getEntities() { 
     return model.getEntities(); 
    } 

    @Override 
    public void setDirection(Direction direction, boolean pressed) { 
     if (pressed) { 
      keys.add(direction); 
     } else { 
      keys.remove(direction); 
     } 
    } 

    @Override 
    public void start() { 
     if (timer != null && timer.isRunning()) { 
      timer.stop(); 
     } 
     timer = new Timer(40, new ActionListener() { 
      @Override 
      public void actionPerformed(ActionEvent e) { 
       model.update(view.getViewBounds(), Collections.unmodifiableSet(keys)); 
       view.repaint(); 
      } 
     }); 
     timer.start(); 
    } 

} 

public class DefaultGameView extends JPanel implements GameView { 

    private GameController controller; 

    public DefaultGameView() { 
     addKeyBinding("left.pressed", KeyEvent.VK_LEFT, true, new DirectionAction(Direction.LEFT, true)); 
     addKeyBinding("left.released", KeyEvent.VK_LEFT, false, new DirectionAction(Direction.LEFT, false)); 
     addKeyBinding("right.pressed", KeyEvent.VK_RIGHT, true, new DirectionAction(Direction.RIGHT, true)); 
     addKeyBinding("right.released", KeyEvent.VK_RIGHT, false, new DirectionAction(Direction.RIGHT, false)); 
     addKeyBinding("space.pressed", KeyEvent.VK_SPACE, true, new DirectionAction(Direction.SPACE, true)); 
     addKeyBinding("space.released", KeyEvent.VK_SPACE, false, new DirectionAction(Direction.SPACE, false)); 
    } 

    protected void addKeyBinding(String name, int keyEvent, boolean pressed, DirectionAction action) { 
     addKeyBinding(name, KeyStroke.getKeyStroke(keyEvent, 0, !pressed), action); 
    } 

    protected void addKeyBinding(String name, KeyStroke keyStroke, DirectionAction action) { 
     InputMap inputMap = getInputMap(WHEN_IN_FOCUSED_WINDOW); 
     ActionMap actionMap = getActionMap(); 

     inputMap.put(keyStroke, name); 
     actionMap.put(name, action); 
    } 

    @Override 
    public void setController(GameController controller) { 
     this.controller = controller; 
    } 

    @Override 
    public GameController getController() { 
     return controller; 
    } 

    @Override 
    public Rectangle getViewBounds() { 
     return new Rectangle(new Point(0, 0), getSize()); 
    } 

    @Override 
    public Dimension getPreferredSize() { 
     return new Dimension(400, 400); 
    } 

    @Override 
    protected void paintComponent(Graphics g) { 
     super.paintComponent(g); 
     GameController controller = getController(); 
     for (Entity entity : controller.getEntities()) { 
      // I don't trust you 
      Graphics2D g2d = (Graphics2D) g.create(); 
      entity.paint(g2d); 
      g2d.dispose(); 
     } 
    } 

    public class DirectionAction extends AbstractAction { 

     private Direction direction; 
     private boolean pressed; 

     public DirectionAction(Direction direction, boolean pressed) { 
      this.direction = direction; 
      this.pressed = pressed; 
     } 

     @Override 
     public void actionPerformed(ActionEvent e) { 
      getController().setDirection(direction, pressed); 
     } 

    } 

} 

D'accord, mais c'est très bien, mais comment l'utilisez-vous? Quelque chose comme ça par exemple ...

Play

import java.awt.Color; 
import java.awt.Dimension; 
import java.awt.EventQueue; 
import java.awt.Graphics; 
import java.awt.Graphics2D; 
import java.awt.Point; 
import java.awt.Rectangle; 
import java.awt.event.ActionEvent; 
import java.awt.event.ActionListener; 
import java.awt.event.KeyEvent; 
import java.util.ArrayList; 
import java.util.Collections; 
import java.util.HashSet; 
import java.util.Iterator; 
import java.util.List; 
import java.util.Set; 
import javax.swing.AbstractAction; 
import javax.swing.ActionMap; 
import javax.swing.InputMap; 
import javax.swing.JFrame; 
import javax.swing.JPanel; 
import javax.swing.KeyStroke; 
import javax.swing.Timer; 
import javax.swing.UIManager; 
import javax.swing.UnsupportedLookAndFeelException; 

public class Main { 

    public static void main(String[] args) { 
     new Main(); 
    } 

    public Main() { 
     EventQueue.invokeLater(new Runnable() { 
      @Override 
      public void run() { 
       try { 
        UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName()); 
       } catch (ClassNotFoundException | InstantiationException | IllegalAccessException | UnsupportedLookAndFeelException ex) { 
        ex.printStackTrace(); 
       } 

       GameModel model = new DefaultGameModel(); 
       DefaultGameView view = new DefaultGameView(); 
       GameController controller = new DefaultGameController(model, view); 

       JFrame frame = new JFrame("Testing"); 
       frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); 
       frame.add(view); 
       frame.pack(); 
       frame.setLocationRelativeTo(null); 
       frame.setVisible(true); 

       controller.start(); 
      } 
     }); 
    } 

    public static enum Direction { 
     LEFT, 
     RIGHT, 
     SPACE 
    } 

    public interface Entity { 
     public void paint(Graphics2D g2d); 
     public Point getLocation(); 
     public void setLocation(Point p); 
     public Dimension getSize(); 
    } 

    public interface GameModel { 
     public Entity[] getEntities(); 
     public void update(Rectangle bounds, Set<Direction> keys); 
    } 

    public interface GameController { 
     public Entity[] getEntities(); 
     public void setDirection(Direction direction, boolean pressed); 
     public void start(); 
    } 

    public interface GameView { 
     public void setController(GameController controller); 
     public GameController getController(); 
     public Rectangle getViewBounds(); 
     public void repaint(); 
    } 

    public class DefaultGameModel implements GameModel { 

     private final List<Entity> entities; 
     private Player player; 

     private Long lastShot; 

     public DefaultGameModel() { 
      entities = new ArrayList<>(25); 
     } 

     @Override 
     public Entity[] getEntities() { 
      return entities.toArray(new Entity[0]); 
     } 

     @Override 
     public void update(Rectangle bounds, Set<Direction> keys) { 
      if (player == null) { 
       player = new Player(bounds); 
       entities.add(player); 
      } 

      Point p = player.getLocation(); 
      int xDelta = 0; 
      if (keys.contains(Direction.LEFT)) { 
       xDelta = -4; 
      } else if (keys.contains(Direction.RIGHT)) { 
       xDelta = 4; 
      } 
      p.x += xDelta; 
      if (p.x <= bounds.x) { 
       p.x = bounds.x; 
      } else if (p.x + player.getSize().width >= bounds.x + bounds.width) { 
       p.x = bounds.width - player.getSize().width; 
      } 
      player.setLocation(p); 

      Iterator<Entity> it = entities.iterator(); 
      while (it.hasNext()) { 
       Entity entity = it.next(); 
       if (entity instanceof Bullet) { 
        Point location = entity.getLocation(); 
        Dimension size = entity.getSize(); 
        location.y -= size.height; 
        if (location.y + size.height < bounds.y) { 
         it.remove(); 
        } else { 
         entity.setLocation(location); 
        } 
       } 
      } 

      if (keys.contains(Direction.SPACE)) { 
       if (lastShot == null || System.currentTimeMillis() - lastShot > 100) { 
        lastShot = System.currentTimeMillis(); 
        Bullet bullet = new Bullet(); 
        int x = p.x + ((player.getSize().width - bullet.getSize().width)/2); 
        int y = p.y - bullet.getSize().height; 
        bullet.setLocation(new Point(x, y)); 

        entities.add(bullet); 
       } 
      } 
     } 

    } 

    public class DefaultGameController implements GameController { 

     private GameModel model; 
     private GameView view; 

     private Timer timer; 

     private Set<Direction> keys = new HashSet<>(25); 

     public DefaultGameController(GameModel gameModel, GameView gameView) { 
      gameView.setController(this); 

      view = gameView; 
      model = gameModel; 
     } 

     @Override 
     public Entity[] getEntities() { 
      return model.getEntities(); 
     } 

     @Override 
     public void setDirection(Direction direction, boolean pressed) { 
      if (pressed) { 
       keys.add(direction); 
      } else { 
       keys.remove(direction); 
      } 
     } 

     @Override 
     public void start() { 
      if (timer != null && timer.isRunning()) { 
       timer.stop(); 
      } 
      timer = new Timer(40, new ActionListener() { 
       @Override 
       public void actionPerformed(ActionEvent e) { 
        model.update(view.getViewBounds(), Collections.unmodifiableSet(keys)); 
        view.repaint(); 
       } 
      }); 
      timer.start(); 
     } 

    } 

    public abstract class AbstractEntity implements Entity { 

     private final Point location = new Point(0, 0); 

     @Override 
     public Point getLocation() { 
      return new Point(location); 
     } 

     @Override 
     public void setLocation(Point p) { 
      location.setLocation(p); 
     } 

    } 

    public class Player extends AbstractEntity { 

     public Player(Rectangle bounds) { 
      int x = bounds.x + ((bounds.width - getSize().width)/2); 
      int y = bounds.y + (bounds.height - getSize().height); 
      setLocation(new Point(x, y)); 
     } 

     @Override 
     public Dimension getSize() { 
      return new Dimension(40, 17); 
     } 

     @Override 
     public void paint(Graphics2D g2d) { 
      Point p = getLocation(); 
      Dimension size = getSize(); 
      g2d.setColor(Color.BLUE); 
      g2d.fillRect(p.x, p.y + 7, size.width, 10); 
      g2d.fillRect(p.x + 18, p.y, 4, 7); 
     } 

    } 

    public class Bullet extends AbstractEntity { 

     @Override 
     public void paint(Graphics2D g2d) { 
      Rectangle bullet = new Rectangle(getLocation(), getSize()); 
      g2d.setColor(Color.RED); 
      g2d.fill(bullet); 
     } 

     @Override 
     public Dimension getSize() { 
      return new Dimension(4, 8); 
     } 

    } 

    public class DefaultGameView extends JPanel implements GameView { 

     private GameController controller; 

     public DefaultGameView() { 
      addKeyBinding("left.pressed", KeyEvent.VK_LEFT, true, new DirectionAction(Direction.LEFT, true)); 
      addKeyBinding("left.released", KeyEvent.VK_LEFT, false, new DirectionAction(Direction.LEFT, false)); 
      addKeyBinding("right.pressed", KeyEvent.VK_RIGHT, true, new DirectionAction(Direction.RIGHT, true)); 
      addKeyBinding("right.released", KeyEvent.VK_RIGHT, false, new DirectionAction(Direction.RIGHT, false)); 
      addKeyBinding("space.pressed", KeyEvent.VK_SPACE, true, new DirectionAction(Direction.SPACE, true)); 
      addKeyBinding("space.released", KeyEvent.VK_SPACE, false, new DirectionAction(Direction.SPACE, false)); 
     } 

     protected void addKeyBinding(String name, int keyEvent, boolean pressed, DirectionAction action) { 
      addKeyBinding(name, KeyStroke.getKeyStroke(keyEvent, 0, !pressed), action); 
     } 

     protected void addKeyBinding(String name, KeyStroke keyStroke, DirectionAction action) { 
      InputMap inputMap = getInputMap(WHEN_IN_FOCUSED_WINDOW); 
      ActionMap actionMap = getActionMap(); 

      inputMap.put(keyStroke, name); 
      actionMap.put(name, action); 
     } 

     @Override 
     public void setController(GameController controller) { 
      this.controller = controller; 
     } 

     @Override 
     public GameController getController() { 
      return controller; 
     } 

     @Override 
     public Rectangle getViewBounds() { 
      return new Rectangle(new Point(0, 0), getSize()); 
     } 

     @Override 
     public Dimension getPreferredSize() { 
      return new Dimension(400, 400); 
     } 

     @Override 
     protected void paintComponent(Graphics g) { 
      super.paintComponent(g); 
      GameController controller = getController(); 
      for (Entity entity : controller.getEntities()) { 
       // I don't trust you 
       Graphics2D g2d = (Graphics2D) g.create(); 
       entity.paint(g2d); 
       g2d.dispose(); 
      } 
     } 

     public class DirectionAction extends AbstractAction { 

      private Direction direction; 
      private boolean pressed; 

      public DirectionAction(Direction direction, boolean pressed) { 
       this.direction = direction; 
       this.pressed = pressed; 
      } 

      @Override 
      public void actionPerformed(ActionEvent e) { 
       getController().setDirection(direction, pressed); 
      } 

     } 

    } 

} 

Encore une fois, vous allez devoir aller et faire quelques recherches, mais l'idée générale

+0

D'accord, merci pour les suggestions, je vais essayer de digérer votre code d'abord si! – Eames

+0

Aussi, savez-vous pourquoi mon autre code ne fonctionne pas même après avoir changé le placement de la méthode setVisible() (toujours rien afficher)? Je suis juste curieux. – Eames

+0

Cela a fonctionné (surtout) pour moi, mais je n'ai pas vraiment creusé, car il y avait tellement de "getchas" possibles qu'il était plus simple de changer d'approche – MadProgrammer

0

Votre dessin dépend de la prise de vue booléenne; il y a un endroit où le tournage est réglé sur vrai; Si les opérations clés ne fonctionnent pas, le déroulement du programme risque de ne jamais être atteint et cela risque de ne jamais se produire. Donc je vous suggère de minimiser votre projet à un écran qui dessine le graphique sans dépendant des touches.

Si vous pouvez voir les graphiques vous pouvez ajouter progressivement les touches