播放器是一个面板,它将被移除,其位置发生变化,然后重新添加到另一个面板(包含此方法的面板),该面板被绘制到主框架。还有许多其他小面板包含一个草精灵被绘制到主面板作为地形瓷砖。我认为问题在于,当我调用revalidate()
时,它也会重新验证所有这些小面板。我该如何解决这个问题?
编辑:我应该提一下,我正在使用RelativeLayout
将玩家定位在主要面板上。
private class MainKeyAdapter extends KeyAdapter {
@Override
public void keyPressed(KeyEvent evt) {
// TODO add your handling code here:
if(AttentionedPlayer != null)
{
if (evt.getKeyCode() == KeyEvent.VK_UP) {
AttentionedPlayer.Ypos -= 16;
}
if (evt.getKeyCode() == KeyEvent.VK_DOWN) {
AttentionedPlayer.Ypos += 16;
}
if (evt.getKeyCode() == KeyEvent.VK_LEFT) {
AttentionedPlayer.Xpos -= 16;
}
if (evt.getKeyCode() == KeyEvent.VK_RIGHT) {
AttentionedPlayer.Xpos += 16;
}
remove(AttentionedPlayer);
AttentionedPlayer.movePlayer();
System.out.println("!!!!"+AttentionedPlayer.constraints.toString());
add(AttentionedPlayer, AttentionedPlayer.constraints, AttentionedPlayer.Zpos);
AttentionedPlayer.revalidate();
}
}
}
答案 0 :(得分:4)
AttentionedPlayer.movePlayer();
似乎是一个密集型操作,您可以在EDT(GUI线程)中执行它。而是从新线程或SwingWorker中执行它。
阅读this answer以了解有关SwingWorker的更多信息。
答案 1 :(得分:3)
@Eng.Fouad对他有一个好点+1,虽然我个人从来没有因为这个原因而需要这个,但是你的移动方法可能非常密集。
仅使用 JPanel
游戏逻辑显示示例(从我的评论中扩展),如果正确实施 ,则不需要{{1玩家移动(通过revalidate()
)哪个IMO也会导致大量延迟,尤其是在有很多组件的情况下。正如您将看到我的setLocation(..)
扩展GamePanel
并使用JPanel
/ Null
布局(但在游戏中我们希望更多地控制布局)。
还使用Absolute
来向您展示其用途。
KeyBinding
抱歉,我无法阻止自己
如果您对这里感兴趣的是一个带有游戏循环的高级版本可以暂停,可以设置帧率等,2个键(如 W 和 D 可以同时按下,从而导致import java.awt.Color;
import java.awt.Dimension;
import java.awt.Graphics;
import java.awt.event.ActionEvent;
import javax.swing.AbstractAction;
import javax.swing.JComponent;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.KeyStroke;
import javax.swing.SwingUtilities;
import javax.swing.border.LineBorder;
public class GameLogic {
public GameLogic() {
initComponents();
}
private void initComponents() {
JFrame frame = new JFrame();
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
Entity entity = new Entity("Player", 100, 100, 50, 50);//starting location 100,100 and width/height 50x50
GamePanel gp = new GamePanel(300, 300);
gp.addEntity(entity);
setGamePanelKeyBindings(gp, entity);
frame.add(gp);
frame.pack();
frame.setVisible(true);
}
private void setGamePanelKeyBindings(GamePanel gp, final Entity entity) {
gp.getInputMap(JComponent.WHEN_IN_FOCUSED_WINDOW).put(KeyStroke.getKeyStroke("D"), "D pressed");
gp.getActionMap().put("D pressed", new AbstractAction() {
@Override
public void actionPerformed(ActionEvent ae) {
entity.move(Entity.RIGHT);
}
});
gp.getInputMap(JComponent.WHEN_IN_FOCUSED_WINDOW).put(KeyStroke.getKeyStroke("A"), "A pressed");
gp.getActionMap().put("A pressed", new AbstractAction() {
@Override
public void actionPerformed(ActionEvent ae) {
entity.move(Entity.LEFT);
}
});
gp.getInputMap(JComponent.WHEN_IN_FOCUSED_WINDOW).put(KeyStroke.getKeyStroke("W"), "W pressed");
gp.getActionMap().put("W pressed", new AbstractAction() {
@Override
public void actionPerformed(ActionEvent ae) {
entity.move(Entity.UP);
}
});
gp.getInputMap(JComponent.WHEN_IN_FOCUSED_WINDOW).put(KeyStroke.getKeyStroke("S"), "S pressed");
gp.getActionMap().put("S pressed", new AbstractAction() {
@Override
public void actionPerformed(ActionEvent ae) {
entity.move(Entity.DOWN);
}
});
}
public static void main(String[] args) {
SwingUtilities.invokeLater(new Runnable() {
@Override
public void run() {
new GameLogic();
}
});
}
}
class Entity extends JPanel {
private int width = 50, height = 50;
private int speed = 5;
public static final int UP = 1, DOWN = 2, LEFT = 3, RIGHT = 4;
public Entity(String text, int x, int y, int width, int height) {
this.width = width;
this.height = height;
add(new JLabel(text));
setBorder(new LineBorder(Color.BLACK));
setBounds(x, y, width, height);
}
public void move(int direction) {
switch (direction) {
case UP:
setLocation(getX(), getY() - speed);
break;
case DOWN:
setLocation(getX(), getY() + speed);
break;
case LEFT:
setLocation(getX() - speed, getY());
break;
case RIGHT:
setLocation(getX() + speed, getY());
break;
}
}
@Override
public void setBounds(int x, int y, int w, int h) {
super.setBounds(x, y, width, height);
}
@Override
protected void paintComponent(Graphics grphcs) {
super.paintComponent(grphcs);
grphcs.setColor(Color.CYAN);
grphcs.fillRect(0, 0, getWidth(), getHeight());
}
}
class GamePanel extends JPanel {
private int width, height;
GamePanel(int w, int h) {
setLayout(null);
width = w;
height = h;
}
@Override
public Dimension getPreferredSize() {
return new Dimension(width, height);
}
public void addEntity(Entity e) {
add(e);
}
@Override
protected void paintComponent(Graphics grphcs) {
super.paintComponent(grphcs);
grphcs.setColor(Color.GREEN);
grphcs.fillRect(0, 0, getWidth(), getHeight());
}
}
对角移动):
JPanel