这是我第一次用Java编写游戏。我正在创建一个RPG游戏。我已成功使用KeyListener函数使用箭头键移动我的角色。但是,当我点击窗口时,我一直试图将我的角色移向我的鼠标。我已经想通了可以使用mouseClicked函数完成它但我似乎无法在我的代码中实现它。我一直试图理解正确的解决方法,但互联网上的所有不同代码都让我越来越困惑。我正在使用mouseAdapter上的小代码上传我的播放器类。任何实施它的帮助将不胜感激。
import java.awt.Graphics;
import java.awt.event.KeyListener;
import java.awt.event.KeyAdapter;
import java.awt.event.KeyEvent;
import java.awt.event.MouseListener;
import java.awt.event.MouseMotionAdapter;
import java.awt.event.MouseAdapter;
public class Player implements KeyListener {
private int x,y;
private SpriteSheet ss;
private boolean up = false, down = false, left= false, right = false;
public boolean mouseActive = false; // mouse
public Point mouse; // mouse
private final int SPEED = 3;
public Player( int x, int y, SpriteSheet ss) {
this.x = x;
this.y = y;
this.ss = ss;
}
public void tick() {
if(up) {
y-=SPEED;
}
if (down) {
y+=SPEED;
}
if (left){
x-=SPEED;
}
if (right) {
x+=SPEED;
}
}
public void render( Graphics g) {
g.drawImage(ss.crop(0,0,16,16), x, y, 16* Game.SCALE, 16* Game.SCALE, null);
}
public void keyPressed(KeyEvent e) {
if (e.getKeyCode() == KeyEvent.VK_UP) {
up = true;
}
if (e.getKeyCode() == KeyEvent.VK_DOWN) {
down = true;
}
if (e.getKeyCode() == KeyEvent.VK_LEFT) {
left = true;
}
if (e.getKeyCode() == KeyEvent.VK_RIGHT) {
right = true;
}
if (e.getKeyCode() == KeyEvent.VK_M) { // mouse
mouseActive = true;
}
}
public void keyReleased(KeyEvent e) {
if (e.getKeyCode() == KeyEvent.VK_UP) {
up = false;
}
if (e.getKeyCode() == KeyEvent.VK_DOWN) {
down = false;
}
if (e.getKeyCode() == KeyEvent.VK_LEFT) {
left = false;
}
if (e.getKeyCode() == KeyEvent.VK_RIGHT) {
right = false;
}
if (e.getKeyCode() == KeyEvent.VK_M) {
mouseActive = false;
}
}
// this is where I have been trying to add mouseClicked function to my code
addMouseListener( new MouseAdapter() {
public void mouseClicked(MouseEvent e) {
mouse = new Point(e.getX(), e.getY() - 25);
if(e.getButton() == MouseEvent.BUTTON1 && !mouseActive) {
x = mouse.x;
y = mouse.y;
}
}
});
}
编译错误: 找到5个错误:
文件:/Users/welcome/Documents/Player.java [line:11] 错误:/Users/welcome/Documents/Player.java:11:播放器不是抽象的,并且不会覆盖java.awt.event.KeyListener中的抽象方法keyTyped(java.awt.event.KeyEvent)
文件:/Users/welcome/Documents/Player.java [line:18] 错误:/Users/welcome/Documents/Player.java:18:找不到符号 符号:类Point location:class Player
文件:/Users/welcome/Documents/Player.java [line:112] 错误:/Users/welcome/Documents/Player.java:112:找不到符号 符号:类MouseEvent location:class Player
文件:/Users/welcome/Documents/Player.java [line:113] 错误:/Users/welcome/Documents/Player.java:113:找不到符号 符号:类Point location:class Player
文件:/Users/welcome/Documents/Player.java [line:115] 错误:/Users/welcome/Documents/Player.java:115:找不到符号 符号:变量MouseEvent location:class Player
答案 0 :(得分:0)
这是概念的证明。这个想法是角色总是试图移动到一个给定的点(在这种情况下是target
)。
键盘控制元件设计用于在按下目标时将目标移动到距当前玩家位置规定的距离。
鼠标控制元素简单地将目标移动到鼠标单击位置。
主引擎只是试图将角色驱动到那一点。
在此示例中,键盘操作会覆盖鼠标操作
import java.awt.BorderLayout;
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.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.util.ArrayList;
import java.util.HashSet;
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 MoveMe {
public static void main(String[] args) {
new MoveMe();
}
public MoveMe() {
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 Surface());
frame.pack();
frame.setLocationRelativeTo(null);
frame.setVisible(true);
}
});
}
public enum KeyControl {
UP, DOWN, LEFT, RIGHT
}
public class Surface extends JPanel {
private Character character;
private Point target;
private int xDelta = 2;
private int yDelta = 2;
private Set<KeyControl> keyControls;
public Surface() {
keyControls = new HashSet<>(4);
character = new Character(new Rectangle(95, 95, 10, 10));
Timer timer = new Timer(40, new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
processKeyCommands();
if (target != null) {
Rectangle bounds = character.getBounds();
Point cp = new Point(bounds.getLocation());
cp.x += bounds.width / 2;
cp.y += bounds.height / 2;
if (!cp.equals(target)) {
if (cp.x != target.x) {
if (target.x < cp.x) {
cp.x -= xDelta;
if (cp.x < target.x) {
cp.x = target.x;
}
} else {
cp.x += xDelta;
if (cp.x > target.x) {
cp.x = target.x;
}
}
}
if (target.y != cp.y) {
if (target.y < cp.y) {
cp.y -= yDelta;
if (cp.y < target.y) {
cp.y = target.y;
}
} else {
cp.y += yDelta;
if (cp.y > target.y) {
cp.y = target.y;
}
}
}
bounds.x = cp.x - bounds.width / 2;
bounds.y = cp.y - bounds.height / 2;
if (bounds.x < 0) {
bounds.x = 0;
} else if (bounds.x + bounds.width > getWidth()) {
bounds.x = getWidth() - bounds.width;
}
if (bounds.y < 0) {
bounds.y = 0;
} else if (bounds.y + bounds.height > getHeight()) {
bounds.y = getHeight() - bounds.height;
}
} else {
target = null;
}
}
repaint();
}
});
timer.start();
addMouseListener(new MouseAdapter() {
@Override
public void mouseClicked(MouseEvent e) {
target = e.getPoint();
}
});
InputMap im = getInputMap(WHEN_IN_FOCUSED_WINDOW);
im.put(KeyStroke.getKeyStroke(KeyEvent.VK_UP, 0, false), "pressUp");
im.put(KeyStroke.getKeyStroke(KeyEvent.VK_DOWN, 0, false), "pressDown");
im.put(KeyStroke.getKeyStroke(KeyEvent.VK_LEFT, 0, false), "pressLeft");
im.put(KeyStroke.getKeyStroke(KeyEvent.VK_RIGHT, 0, false), "pressRight");
im.put(KeyStroke.getKeyStroke(KeyEvent.VK_UP, 0, true), "releaseUp");
im.put(KeyStroke.getKeyStroke(KeyEvent.VK_DOWN, 0, true), "releaseDown");
im.put(KeyStroke.getKeyStroke(KeyEvent.VK_LEFT, 0, true), "releaseLeft");
im.put(KeyStroke.getKeyStroke(KeyEvent.VK_RIGHT, 0, true), "releaseRight");
ActionMap am = getActionMap();
am.put("pressUp", new KeyStateAction(keyControls, KeyControl.UP, true));
am.put("pressDown", new KeyStateAction(keyControls, KeyControl.DOWN, true));
am.put("pressLeft", new KeyStateAction(keyControls, KeyControl.LEFT, true));
am.put("pressRight", new KeyStateAction(keyControls, KeyControl.RIGHT, true));
am.put("releaseUp", new KeyStateAction(keyControls, KeyControl.UP, false));
am.put("releaseDown", new KeyStateAction(keyControls, KeyControl.DOWN, false));
am.put("releaseLeft", new KeyStateAction(keyControls, KeyControl.LEFT, false));
am.put("releaseRight", new KeyStateAction(keyControls, KeyControl.RIGHT, false));
}
protected Point createTargetBasedOnCharacter() {
target = new Point();
Rectangle bounds = character.getBounds();
target.x = bounds.x + bounds.width / 2;
target.y = bounds.y + bounds.height / 2;
return target;
}
protected void processKeyCommands() {
if (keyControls.contains(KeyControl.UP)) {
Point target = createTargetBasedOnCharacter();
target.y -= xDelta;
} else if (keyControls.contains(KeyControl.DOWN)) {
Point target = createTargetBasedOnCharacter();
target.y += xDelta;
}
if (keyControls.contains(KeyControl.LEFT)) {
Point target = createTargetBasedOnCharacter();
target.x -= xDelta;
} else if (keyControls.contains(KeyControl.RIGHT)) {
Point target = createTargetBasedOnCharacter();
target.x += xDelta;
}
}
@Override
public Dimension getPreferredSize() {
return new Dimension(200, 200);
}
@Override
protected void paintComponent(Graphics g) {
super.paintComponent(g);
Graphics2D g2d = (Graphics2D) g.create();
if (target != null) {
g2d.setColor(Color.RED);
g2d.fillOval(target.x - 5, target.y - 5, 10, 10);
}
character.render(g2d);
g2d.dispose();
}
}
public class Character {
private Rectangle bounds;
public Character(Rectangle bounds) {
this.bounds = bounds;
}
public Rectangle getBounds() {
return bounds;
}
public void render(Graphics2D g) {
g.setColor(Color.BLUE);
g.fill(getBounds());
}
}
public class KeyStateAction extends AbstractAction {
private final Set<KeyControl> keyControls;
private final KeyControl keyControl;
private final boolean pressed;
private KeyStateAction(Set<KeyControl> keyControls, KeyControl keyControl, boolean pressed) {
this.keyControls = keyControls;
this.keyControl = keyControl;
this.pressed = pressed;
}
@Override
public void actionPerformed(ActionEvent e) {
if (pressed) {
keyControls.add(keyControl);
} else {
keyControls.remove(keyControl);
}
}
}
}
此示例使用key bindings API,可以更好地控制触发关键事件所需的焦点水平。
我还将实体(Character
)与控件分离。这就是,键盘和鼠标控制并由Surface
管理,因为恕我直言,玩家实体应该不知道。这集中了控件,意味着可以通过任何输入来移动角色......