我正在为学校项目创建一个程序。这是一个基于粉丝的神奇宝贝程序,我在理解如何根据击键更改图像方面遇到了一些麻烦。
以下是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;
}
}
}
提前感谢您的帮助!
答案 0 :(得分:2)
基本上,您需要知道当前的键状态和当前帧(基于每个位置有两个图像的事实)。
使用此信息,您可以确定应显示哪个字符图像。
此示例非常简单,它演示key bindings API过度使用KeyListener
,因为它解决了处理焦点的问题。它还演示了通过单个基础Action
示例的MainCharacter
有一个方法(感兴趣),用于根据当前KeyState
(本例中为enum
)确定应显示哪个图像当前frame
。
getCharacter
方法每10帧切换一次图像,以便在当前位置之间提供动画......
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>