簡體   English   中英

Java:移動Image / ImageIcon

[英]Java: Moving an Image/ImageIcon

我正在創建一個類似於Frogger的游戲,如果可以的話,我的sprite(frog)(image)已創建,但不會在我的按鍵上移動,並且我相信該錯誤實際上發生在draw()方法中frog.java類。 這是我自己的項目,我正在嘗試結合多態性和繼承。 有沒有一種方法可以使用我擁有的draw和move方法來移動我的精靈,否則將是正確的方法。 不幸的是,這是在Netbeans中完成的。

import java.awt.*;
import java.awt.event.*;

public class FroggerForm extends Frame implements ActionListener
{
   private Frog frog;
   private javax.swing.Timer moveTimer = new javax.swing.Timer(500, this);
   /**
    Creates new form FroggerForm
    */
   public FroggerForm()
   {
      initComponents();
      this.setSize(400, 400);
      frog = new Frog(froggerPanel);
      moveTimer.start();
   }

   /**
    This method is called from within the constructor to initialize the form.
    WARNING: Do NOT modify this code. The content of this method is always
    regenerated by the Form Editor.
    */
   // <editor-fold defaultstate="collapsed" desc="Generated Code">                          
   private void initComponents()
   {

      froggerPanel = new java.awt.Panel();

      setMinimumSize(new java.awt.Dimension(500, 500));
      addWindowListener(new java.awt.event.WindowAdapter()
      {
         public void windowClosing(java.awt.event.WindowEvent evt)
         {
            exitForm(evt);
         }
      });
      setLayout(null);

      froggerPanel.setBackground(new java.awt.Color(190, 190, 190));
      froggerPanel.setPreferredSize(new java.awt.Dimension(400, 400));
      froggerPanel.addKeyListener(new java.awt.event.KeyAdapter()
      {
         public void keyPressed(java.awt.event.KeyEvent evt)
         {
            keyAdapter(evt);
         }
      });
      add(froggerPanel);
      froggerPanel.setBounds(100, 0, 400, 400);

      pack();
   }// </editor-fold>                        

   /**
    Exit the Application
    */
    private void exitForm(java.awt.event.WindowEvent evt) {                          
       System.exit(0);
    }                         

   private void keyAdapter(java.awt.event.KeyEvent evt)                            
   {                                
      frog.hide();
      if(evt.getSource() == KeyEvent.VK_UP)
         frog.move(0, -10);
      else if(evt.getSource() == KeyEvent.VK_DOWN)
         frog.move(0, 10);
      else if(evt.getSource() == KeyEvent.VK_RIGHT)
         frog.move(10, 0);
      else if(evt.getSource() == KeyEvent.VK_LEFT)
         frog.move(-10 , 0);

   }                           

   /**
    @param args the command line arguments
    */
   public static void main(String args[])
   {
      java.awt.EventQueue.invokeLater(new Runnable()
      {
         public void run()
         {
            new FroggerForm().setVisible(true);
         }
      });
   }
   // Variables declaration - do not modify                     
   private java.awt.Panel froggerPanel;
   // End of variables declaration                   

   @Override
   public void actionPerformed(ActionEvent ae)
   {
      frog.draw();
      frog.move();
   }
}

public abstract class PFigure implements Comparable
{
   protected int x, y;           // Current position of the figure
   protected int width, height;  // Drawn (displayed) this size
   protected int priority;       // Can use to determine "winner"
   protected Panel panel;        // Panel the figure lives on

   public PFigure ( int startX, int startY, int _width, int _height, 
                    int pr, Panel p )
   {
       x = startX;
       y = startY;
       width = _width;
       height = _height;
       priority = pr;
       panel = p;
   }

   // Can use this in "battles", which figures is "greater"
   public int compareTo(Object o)
   {
      if( o instanceof PFigure )
         return priority - ((PFigure)o).priority;
      return Integer.MAX_VALUE;
   }

   // Has "this" figure collided with p?
   public boolean collidedWith ( PFigure p )
   {
      if (  p == null )
         return false;

      return ( x + width ) >= p.x && ( p.x + p.width ) >= x &&
             ( y + height ) >= p.y && ( p.y + p.height ) >= y;
   }

   // Can be used for moving by keyboard or mouse
   public void move ( int deltaX, int deltaY )
   {
      x = x + deltaX;
      y = y + deltaY;
   }

   public void hide()
   {
      Graphics g = panel.getGraphics();
      Color oldColor = g.getColor();
      g.setColor(panel.getBackground() );
      g.fillRect(x, y, width, height);
      g.setColor(oldColor);
   }

   // Can be automatic move, for example, called based on timer
   public void move()
   {
   }


   // Draw the figure.
   // Each derived class will write their own drawing method.
   // The first line should be:
   //    Graphics g = panel.getGraphics();
   abstract public void draw();


}

import java.awt.*;
import java.io.File;
import javax.imageio.ImageIO;

public class Frog extends PFigure
{
   private Image frogImg;
   public Frog(Panel p)
   {
      super(200, 350, 30, 30, 0, p);
      try
       {
          File file = new File("frogger.png");
          frogImg = ImageIO.read(file);
       }
       catch ( Exception e )
       {
          System.out.println("Crashing: " + e);
       }
   }

   @Override
   public void draw()
   {
      if(frogImg != null)
      {
         Graphics g = panel.getGraphics();
         g.drawImage(frogImg, x, y, width, height, null);
      }

   }

   @Override
   public void move(int deltaX, int deltaY)
   {
      if ( x <= 0)
         x = 1;
      else if(x >= panel.getSize().width)
         x = panel.getSize().width - 1;
      else if(y >= panel.getSize().height)
         y = panel.getSize().height - 1;

      x += deltaX;
      y += deltaY;
   }
}

我相信您的第一個錯誤是使用KeyListener

僅當注冊了組件的組件具有焦點且可聚焦時, KeyListener才會響應其擊鍵。

而是使用“ 鍵綁定” ,它們使您可以定義將在其中生成鍵事件的焦點級別。

更新

舉個例子...

巫師

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.awt.image.BufferedImage;
import java.io.IOException;
import java.util.ArrayList;
import java.util.HashSet;
import java.util.List;
import java.util.Set;
import javax.imageio.ImageIO;
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 WizardFireball {

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

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

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

    public class GamePane extends JPanel {

        private GameModel model;

        public GamePane() {
            try {
                model = new DefaultModel();

                ActionMap am = getActionMap();
                InputMap im = getInputMap(WHEN_IN_FOCUSED_WINDOW);

                im.put(KeyStroke.getKeyStroke(KeyEvent.VK_UP, 0, false), "up-pressed");
                im.put(KeyStroke.getKeyStroke(KeyEvent.VK_DOWN, 0, false), "down-pressed");
                im.put(KeyStroke.getKeyStroke(KeyEvent.VK_LEFT, 0, false), "left-pressed");
                im.put(KeyStroke.getKeyStroke(KeyEvent.VK_RIGHT, 0, false), "right-pressed");
                im.put(KeyStroke.getKeyStroke(KeyEvent.VK_UP, 0, true), "up-released");
                im.put(KeyStroke.getKeyStroke(KeyEvent.VK_DOWN, 0, true), "down-released");
                im.put(KeyStroke.getKeyStroke(KeyEvent.VK_LEFT, 0, true), "left-released");
                im.put(KeyStroke.getKeyStroke(KeyEvent.VK_RIGHT, 0, true), "right-released");
                im.put(KeyStroke.getKeyStroke(KeyEvent.VK_SPACE, 0), "fire");

                am.put("up-pressed", new KeyPressedAction(getModel(), Key.UP));
                am.put("down-pressed", new KeyPressedAction(getModel(), Key.DOWN));
                am.put("left-pressed", new KeyPressedAction(getModel(), Key.LEFT));
                am.put("right-pressed", new KeyPressedAction(getModel(), Key.RIGHT));
                am.put("up-released", new KeyReleasedAction(getModel(), Key.UP));
                am.put("down-released", new KeyReleasedAction(getModel(), Key.DOWN));
                am.put("left-released", new KeyReleasedAction(getModel(), Key.LEFT));
                am.put("right-released", new KeyReleasedAction(getModel(), Key.RIGHT));
                am.put("fire", new FireBallAction(getModel()));
            } catch (IOException ex) {
                ex.printStackTrace();
            }

            Timer timer = new Timer(40, new ActionListener() {
                @Override
                public void actionPerformed(ActionEvent e) {
                    for (Asset asset : getModel().getAssets()) {
                        asset.update(GamePane.this);
                    }
                    repaint();
                }
            });
            timer.start();
        }

        public GameModel getModel() {
            return model;
        }

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

        @Override
        protected void paintComponent(Graphics g) {
            super.paintComponent(g);
            Graphics2D g2d = (Graphics2D) g.create();
            for (Asset asset : getModel().getAssets()) {
                asset.paint(this, g2d);
            }
            g2d.dispose();
        }

    }

    public enum Key {

        LEFT,
        RIGHT,
        UP,
        DOWN
    }

    public interface GameModel {

        public void keyPressed(Key key);

        public void keyReleased(Key key);

        public boolean isKeyPressed(Key key);

        public void addFireball();

        public void remove(Asset asset);

        public Wizard getWizard();

        public Iterable<Asset> getAssets();

    }

    public class DefaultModel implements GameModel {

        private Set<Key> keys;
        private Wizard wizard;

        private List<Asset> assets;

        public DefaultModel() throws IOException {
            keys = new HashSet<>(25);
            assets = new ArrayList<>(25);
            wizard = new Wizard();
        }

        @Override
        public void keyPressed(Key key) {
            keys.add(key);
        }

        @Override
        public void keyReleased(Key key) {
            keys.remove(key);
        }

        @Override
        public boolean isKeyPressed(Key key) {
            return keys.contains(key);
        }

        @Override
        public Wizard getWizard() {
            return wizard;
        }

        @Override
        public void addFireball() {
            try {
                assets.add(new Fireball(getWizard()));
            } catch (IOException ex) {
                ex.printStackTrace();
            }
        }

        @Override
        public void remove(Asset asset) {
            assets.remove(asset);
        }

        @Override
        public Iterable<Asset> getAssets() {
            List<Asset> proxy = new ArrayList<>(assets);
            proxy.add(wizard);
            return proxy;
        }

    }

    public abstract class AbstractGameAction extends AbstractAction {

        private GameModel model;

        public AbstractGameAction(GameModel model) {
            this.model = model;
        }

        public GameModel getModel() {
            return model;
        }

    }

    public abstract class AbstractKeyAction extends AbstractGameAction {

        private Key key;

        public AbstractKeyAction(GameModel model, Key key) {
            super(model);
            this.key = key;
        }

        public Key getKey() {
            return key;
        }

    }

    public class KeyPressedAction extends AbstractKeyAction {

        public KeyPressedAction(GameModel model, Key key) {
            super(model, key);
        }

        @Override
        public void actionPerformed(ActionEvent e) {
            getModel().keyPressed(getKey());
        }

    }

    public class KeyReleasedAction extends AbstractKeyAction {

        public KeyReleasedAction(GameModel model, Key key) {
            super(model, key);
        }

        @Override
        public void actionPerformed(ActionEvent e) {
            getModel().keyReleased(getKey());
        }

    }

    public class FireBallAction extends AbstractGameAction {

        public FireBallAction(GameModel model) {
            super(model);
        }

        @Override
        public void actionPerformed(ActionEvent e) {
            getModel().addFireball();
        }

    }

    public interface Asset {

        public void paint(GamePane surface, Graphics2D g2d);

        public void update(GamePane surface);

        public Rectangle getBounds();

    }

    public class Fireball implements Asset {

        private final BufferedImage fireball;
        private final Rectangle bounds;

        public Fireball(Wizard wizard) throws IOException {
            fireball = ImageIO.read(getClass().getResource("/Fireball.png"));
            bounds = new Rectangle();
            bounds.x = wizard.getBounds().x + wizard.getBounds().width;
            bounds.y = wizard.getBounds().y + (wizard.getBounds().height - fireball.getHeight());
            bounds.setSize(fireball.getWidth(), fireball.getHeight());
        }

        @Override
        public Rectangle getBounds() {
            return bounds;
        }

        @Override
        public void paint(GamePane surface, Graphics2D g2d) {

            Rectangle bounds = getBounds();
            g2d.drawImage(fireball, bounds.x, bounds.y, surface);

        }

        @Override
        public void update(GamePane surface) {
            Rectangle bounds = getBounds();
            bounds.x += 8;
            if (bounds.x > surface.getWidth()) {
                surface.getModel().remove(this);
            }
        }

    }

    public class Wizard implements Asset {

        private final BufferedImage wizard;
        private final Rectangle bounds;
        private boolean initialised = false;

        public Wizard() throws IOException {
            wizard = ImageIO.read(getClass().getResource("/Wizard.png"));
            bounds = new Rectangle(wizard.getWidth(), wizard.getHeight());
        }

        @Override
        public Rectangle getBounds() {
            return bounds;
        }

        @Override
        public void paint(GamePane surface, Graphics2D g2d) {

            Rectangle bounds = getBounds();
            Point point = bounds.getLocation();
            if (!initialised) {
                point = new Point(5, (surface.getHeight() - bounds.height) / 2);
                bounds.setLocation(point);
                initialised = true;
            }

            g2d.drawImage(wizard, point.x, point.y, surface);

        }

        @Override
        public void update(GamePane surface) {
            Rectangle bounds = getBounds();
            Point point = bounds.getLocation();
            if (initialised) {
                GameModel model = surface.getModel();
                if (model.isKeyPressed(Key.UP)) {
                    point.y -= 4;
                } else if (model.isKeyPressed(Key.DOWN)) {
                    point.y += 4;
                }

                if (point.y < 0) {
                    point.y = 0;
                } else if (point.y + bounds.height > surface.getHeight()) {
                    point.y = surface.getHeight() - bounds.height;
                }
                bounds.setLocation(point);
            }
        }
    }

}

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM