Rumah > Java > javaTutorial > Bagaimana untuk Membuat Pergerakan Imej di Java Menggunakan Penekanan Kekunci dan Pemasa?

Bagaimana untuk Membuat Pergerakan Imej di Java Menggunakan Penekanan Kekunci dan Pemasa?

Linda Hamilton
Lepaskan: 2024-12-02 10:31:10
asal
740 orang telah melayarinya

How to Make an Image Move in Java Using Keypresses and Timers?

Cara membuat imej bergerak sambil mendengar penekanan kekunci dalam Java

Di Java, anda boleh menggunakan Pemasa Swing dan Pengikatan Kekunci untuk membuat pergerakan imej sambil mendengar penekan kekunci. Berikut ialah contoh:

import java.awt.*;
import java.awt.event.*;
import java.awt.image.BufferedImage;
import javax.swing.*;
import java.util.HashMap;
import java.util.Map;

public class AnimationWithKeyBinding {
   private static final int SPRITE_WIDTH = 20;
   private static final int PANEL_WIDTH = 400;
   private static final int PANEL_HEIGHT = 400;
   private static final int MAX_MSTATE = 25;
   private static final int SPIN_TIMER_PERIOD = 16;
   private static final int SPRITE_STEP = 3;

   private int mState = 0;
   private int mX = (PANEL_WIDTH - SPRITE_WIDTH) / 2;
   private int mY = (PANEL_HEIGHT - SPRITE_WIDTH) / 2;
   private int oldMX = mX;
   private int oldMY = mY;
   private boolean moved = false;
   
   private Map<String, Boolean> keyStates = new HashMap<>();
   
   // an array of sprite images that are drawn sequentially
   private BufferedImage[] spriteImages = new BufferedImage[MAX_MSTATE];

   public AnimationWithKeyBinding() {
      // create and start the main animation timer
      new Timer(SPIN_TIMER_PERIOD, new SpinTimerListener()).start();
      setPreferredSize(new Dimension(PANEL_WIDTH, PANEL_HEIGHT));
      setBackground(Color.white);
      createSprites(); // create the images
      setupKeyBinding();
   }

   private void setupKeyBinding() {
      int condition = JComponent.WHEN_IN_FOCUSED_WINDOW;
      InputMap inMap = getInputMap(condition);
      ActionMap actMap = getActionMap();

      // this uses an enum of Direction that holds ints for the arrow keys
      for (Direction direction : Direction.values()) {
         int key = direction.getKey();
         String name = direction.name();

         // add the key bindings for arrow key and shift-arrow key
         inMap.put(KeyStroke.getKeyStroke(key, 0), name);
         inMap.put(KeyStroke.getKeyStroke(key, InputEvent.SHIFT_DOWN_MASK), name);
         actMap.put(name, new MyKeyAction(this, direction));
      }
   }
   
   // creates a KeyListener that stores key presses and releases in a HashMap
   private class KeyHandler extends KeyAdapter {
      @Override
      public void keyPressed(KeyEvent e) {
         keyStates.put(KeyEvent.getKeyText(e.getKeyCode()), true);
      }
      
      @Override
      public void keyReleased(KeyEvent e) {
         keyStates.put(KeyEvent.getKeyText(e.getKeyCode()), false);
      }
   }
   
   public class MyKeyAction extends AbstractAction {
      private AnimationWithKeyBinding draw;
      private Direction direction;
      
      public MyKeyAction(AnimationWithKeyBinding draw, Direction direction) {
         this.draw = draw;
         this.direction = direction;
      }

      @Override
      public void actionPerformed(ActionEvent e) {
         switch (direction) {
         case UP:
            if (keyStates.get("Up")) {
               draw.incrementY(false);
            }
            break;
         case DOWN:
            if (keyStates.get("Down")) {
               draw.incrementY(true);
            }
            break;
         case LEFT:
            if (keyStates.get("Left")) {
               draw.incrementX(false);
            }
            break;
         case RIGHT:
            if (keyStates.get("Right")) {
               draw.incrementX(true);
            }
            break;

         default:
            break;
         }
      }
   }
   
   enum Direction {
      UP(KeyEvent.VK_UP), DOWN(KeyEvent.VK_DOWN), LEFT(KeyEvent.VK_LEFT), RIGHT(KeyEvent.VK_RIGHT);

      private int key;

      private Direction(int key) {
         this.key = key;
      }

      public int getKey() {
         return key;
      }
   }

   // create a bunch of buffered images and place into an array,
   // to be displayed sequentially
   private void createSprites() {
      for (int i = 0; i < spriteImages.length; i++) {
         spriteImages[i] = new BufferedImage(SPRITE_WIDTH, SPRITE_WIDTH,
                  BufferedImage.TYPE_INT_ARGB);
         Graphics2D g2 = spriteImages[i].createGraphics();
         g2.setColor(Color.red);
         g2.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
         double theta = i * Math.PI / (2 * spriteImages.length);
         double x = SPRITE_WIDTH * Math.abs(Math.cos(theta)) / 2.0;
         double y = SPRITE_WIDTH * Math.abs(Math.sin(theta)) / 2.0;
         int x1 = (int) ((SPRITE_WIDTH / 2.0) - x);
         int y1 = (int) ((SPRITE_WIDTH / 2.0) - y);
         int x2 = (int) ((SPRITE_WIDTH / 2.0) + x);
         int y2 = (int) ((SPRITE_WIDTH / 2.0) + y);
         g2.drawLine(x1, y1, x2, y2);
         g2.drawLine(y1, x2, y2, x1);
         g2.dispose();
      }
   }

   @Override
   protected void paintComponent(Graphics g) {
      super.paintComponent(g);
      g.drawImage(spriteImages[mState], mX, mY, null);
   }

   public void incrementX(boolean right) {
      oldMX = mX;
      if (right) {
         mX = Math.min(getWidth() - SPRITE_WIDTH, mX + SPRITE_STEP);
      } else {
         mX = Math.max(0, mX - SPRITE_STEP);
      }
      moved = true;
   }

   public void incrementY(boolean down) {
      oldMY = mY;
      if (down) {
         mY = Math.min(getHeight() - SPRITE_WIDTH, mY + SPRITE_STEP);
      } else {
         mY = Math.max(0, mY - SPRITE_STEP);
      }
      moved = true;
   }

   public void tick() {
      mState = (mState + 1) % MAX_MSTATE;
   }

   private class SpinTimerListener implements ActionListener {
      @Override
      public void actionPerformed(ActionEvent e) {
         tick();

         int delta = 20;
         int width = SPRITE_WIDTH + 2 * delta;
         int height = width;

         // make sure to erase the old image
         if (moved) {
            int x = oldMX - delta;
            int y = oldMY - delta;
            repaint(x, y, width, height);
         }

         int x = mX - delta;
         int y = mY - delta;

         // draw the new image
         repaint(x, y, width, height);
         moved = false;
      }
   }
   public static void main(String[] args) {
      java.awt.EventQueue.invokeLater(new Runnable() {
         public void run() {
            createAndShowUI();
         }
      });
   }
   public static void createAndShowUI() {
      AnimationWithKeyBinding panel = new AnimationWithKeyBinding(); // the drawing JPanel

      JFrame frame = new JFrame("Animation With Key Binding");
      frame.getContentPane().add(panel);
      frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
      frame.pack();
      frame.setLocationRelativeTo(null);
      frame.setVisible(true);
   }
}
Salin selepas log masuk

Contoh ini menggunakan Pemasa untuk mengalihkan imej pada kelajuan tetap dan Pengikatan Kekunci untuk mendengar tekanan kekunci. Apabila kekunci ditekan, kaedah MyKeyAction dipanggil, yang mengemas kini kedudukan imej. Ini membolehkan imej bergerak sebagai tindak balas kepada tekanan kekunci.

Atas ialah kandungan terperinci Bagaimana untuk Membuat Pergerakan Imej di Java Menggunakan Penekanan Kekunci dan Pemasa?. Untuk maklumat lanjut, sila ikut artikel berkaitan lain di laman web China PHP!

sumber:php.cn
Kenyataan Laman Web ini
Kandungan artikel ini disumbangkan secara sukarela oleh netizen, dan hak cipta adalah milik pengarang asal. Laman web ini tidak memikul tanggungjawab undang-undang yang sepadan. Jika anda menemui sebarang kandungan yang disyaki plagiarisme atau pelanggaran, sila hubungi admin@php.cn
Artikel terbaru oleh pengarang
Tutorial Popular
Lagi>
Muat turun terkini
Lagi>
kesan web
Kod sumber laman web
Bahan laman web
Templat hujung hadapan