如何根据击键更改图像

时间:2014-05-25 23:01:05

标签: java swing graphics jpanel actionlistener

我正在为学校项目创建一个程序。这是一个基于粉丝的神奇宝贝程序,我在理解如何根据击键更改图像方面遇到了一些麻烦。

以下是Character Class

的代码
import java.awt.Image;
import java.awt.event.KeyEvent;
import java.io.*;                        //the File class
import java.util.*;                     //the Scanner class
import javax.swing.ImageIcon;
import javax.swing.JPanel;
import java.awt.image.*;


import javax.swing.ImageIcon;

public class MainCharacter {

  private Image up, up1, up2, down, down1, down2, left, left1, left2, right, right1, right2;


  private void loadImages() {


     up = new ImageIcon("Up.png").getImage();
     up1 = new ImageIcon("Up1.png").getImage();
     up2 = new ImageIcon("Up2.png").getImage();
     down = new ImageIcon("Down.png").getImage();
     down1 = new ImageIcon("Down1.png").getImage();
     down2= new ImageIcon("Down2.png").getImage();
     left = new ImageIcon("Left.png").getImage();
     left1 = new ImageIcon("Left1.png").getImage();
     left2 = new ImageIcon("Left2.png").getImage();
     right = new ImageIcon("Right.png").getImage();
     right1 = new ImageIcon("Right1.png").getImage();
     right2 = new ImageIcon("Right2.png").getImage();

  }










/*public Image getImage() 
{
     //dont know what to return here
}
*/


  public void keyPressed(KeyEvent e) {

     int key = e.getKeyCode();

     if (key == KeyEvent.VK_LEFT) {

     //dont know what to do

     }

     if (key == KeyEvent.VK_RIGHT) {
        //dont know what to do

     }


     if (key == KeyEvent.VK_UP) {

        //dont know what to do
     }

     if (key == KeyEvent.VK_DOWN) {
        //dont know what to do
     }
  }

  public void keyReleased(KeyEvent e) {
     int key = e.getKeyCode();

     if (key == KeyEvent.VK_LEFT) {
        //dont know what to do
     }

     if (key == KeyEvent.VK_RIGHT) {
        //dont know what to do
     }

     if (key == KeyEvent.VK_UP) {
        //dont know what to do
     }

     if (key == KeyEvent.VK_DOWN) {
        //dont know what to do
     }
  }
}

以下是与地图一起移动的类:

import java.awt.Color;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.Toolkit;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.KeyAdapter;
import java.awt.event.KeyEvent;

import javax.swing.JPanel;
import javax.swing.Timer;


public class MapMovement extends JPanel implements ActionListener {

private Timer timer;
private Map map;
 private MainCharacter mainCharacter;

public MapMovement() {

    addKeyListener(new TAdapter());
    setFocusable(true);
    setBackground(Color.BLACK);
    setDoubleBuffered(true);

    map = new Map();

    timer = new Timer(5, this);
    timer.start();
}


public void paint(Graphics g) {
    super.paint(g);

    Graphics2D g2d = (Graphics2D)g;
    g2d.drawImage(map.getImage(), map.getX(), map.getY(), 1000, 1500, this);

    Toolkit.getDefaultToolkit().sync();
    g.dispose();
}


public void actionPerformed(ActionEvent e) {


      map.move();
    repaint();  
}


private class TAdapter extends KeyAdapter {

    public void keyReleased(KeyEvent e) {
        map.keyReleased(e);
            //mainCharacter.keyReleased(e);
    }

    public void keyPressed(KeyEvent e) {
        map.keyPressed(e);
            //mainCharacter.keyPressed(e);

    }
}

}

更新:

这是Map类

import java.awt.Image;
import java.awt.event.KeyEvent;

import javax.swing.ImageIcon;

public class Map {

private String map = "Map-1stCity.png";

private int dx;
private int dy;
private int x;
private int y;
private Image image;

public Map() {
    ImageIcon ii = new ImageIcon(this.getClass().getResource(map));
    image = ii.getImage();
    x = -100;
    y = -100;
}


public void move() {
    x += dx;
    y += dy;
}

public int getX() {
    return x;
}

public int getY() {
    return y;
}

public Image getImage() {
    return image;
}

public void keyPressed(KeyEvent e) {

    int key = e.getKeyCode();

    if (key == KeyEvent.VK_LEFT) {
        dx = 1;
    }

    if (key == KeyEvent.VK_RIGHT) {
        dx = -1;
    }

    if (key == KeyEvent.VK_UP) {
        dy = 1;
    }

    if (key == KeyEvent.VK_DOWN) {
        dy = -1;
    }
}

public void keyReleased(KeyEvent e) {
    int key = e.getKeyCode();

    if (key == KeyEvent.VK_LEFT) {
        dx = 0;
    }

    if (key == KeyEvent.VK_RIGHT) {
        dx = 0;
    }

    if (key == KeyEvent.VK_UP) {
        dy = 0;
    }

    if (key == KeyEvent.VK_DOWN) {
        dy = 0;
    }
}
}

提前感谢您的帮助!

1 个答案:

答案 0 :(得分:2)

概述

基本上,您需要知道当前的键状态和当前帧(基于每个位置有两个图像的事实)。

使用此信息,您可以确定应显示哪个字符图像。

实施例

此示例非常简单,它演示key bindings API过度使用KeyListener,因为它解决了处理焦点的问题。它还演示了通过单个基础Action

修改当前状态是多么容易

示例的MainCharacter有一个方法(感兴趣),用于根据当前KeyState(本例中为enum)确定应显示哪个图像当前frame

getCharacter方法每10帧切换一次图像,以便在当前位置之间提供动画......

Walk

import java.awt.BorderLayout;
import java.awt.Dimension;
import java.awt.EventQueue;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.Image;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.KeyEvent;
import java.io.File;
import java.io.IOException;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
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 Character {

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

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

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

    public class GamePane extends JPanel {

        private MainCharacter mc;
        private KeyState keyState;
        private int frame;

        public GamePane() {

            mc = new MainCharacter();

            Timer timer = new Timer(40, new ActionListener() {
                @Override
                public void actionPerformed(ActionEvent e) {
                    frame++;
                    if (frame > 100) {
                        frame = 0;
                    }
                    repaint();
                }
            });
            timer.start();


            InputMap im = getInputMap(WHEN_IN_FOCUSED_WINDOW);
            im.put(KeyStroke.getKeyStroke(KeyEvent.VK_UP, 0), "Up");
            im.put(KeyStroke.getKeyStroke(KeyEvent.VK_DOWN, 0), "Down");
            im.put(KeyStroke.getKeyStroke(KeyEvent.VK_LEFT, 0), "Left");
            im.put(KeyStroke.getKeyStroke(KeyEvent.VK_RIGHT, 0), "Right");

            ActionMap am = getActionMap();
            am.put("Up", new KeyStateAction(KeyState.UP));
            am.put("Down", new KeyStateAction(KeyState.DOWN));
            am.put("Left", new KeyStateAction(KeyState.LEFT));
            am.put("Right", new KeyStateAction(KeyState.RIGHT));
        }

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

        @Override
        protected void paintComponent(Graphics g) {
            super.paintComponent(g);
            Graphics2D g2d = (Graphics2D) g.create();
            Image img = mc.getCharacter(keyState, frame);
            int x = (getWidth() - img.getWidth(this)) / 2;
            int y = (getHeight() - img.getHeight(this)) / 2;
            g2d.drawImage(img, x, y, this);
            g2d.dispose();
        }

        public class KeyStateAction extends AbstractAction {

            private KeyState state;

            public KeyStateAction(KeyState state) {
                this.state = state;
            }

            @Override
            public void actionPerformed(ActionEvent e) {
                keyState = state;
            }

        }

    }

    public enum KeyState {

        UP, DOWN, LEFT, RIGHT;

    }

    public class MainCharacter {

        private Map<KeyState, List<Image>> mapImage;

        public MainCharacter() {
            mapImage = new HashMap<>(25);
            try {
                mapImage.put(KeyState.UP, loadImages("Up"));
                mapImage.put(KeyState.DOWN, loadImages("Down"));
                mapImage.put(KeyState.LEFT, loadImages("Left"));
                mapImage.put(KeyState.RIGHT, loadImages("Right"));
            } catch (IOException exp) {
                exp.printStackTrace();
            }
        }

        protected List<Image> loadImages(String name) throws IOException {

            List<Image> images = new ArrayList<>(25);
            images.add(ImageIO.read(new File(name + "1.png")));
            images.add(ImageIO.read(new File(name + "2.png")));

            return images;

        }

        public Image getCharacter(KeyState keyState, int frame) {

            Image img = null;
            List<Image> images = mapImage.get(keyState);
            if (images == null) {
                images = mapImage.get(KeyState.DOWN);
            }
            int index = (frame / 10) % 2 == 0 ? 0 : 1;
            img = images.get(index);

            return img;

        }

    }

}

正如我在评论中所说的那样,不要在你没有创建的dispose上下文中调用Graphics,因为这不仅会影响你的绘画内容,还会影响你之后绘制的内容。< / p>