移动玩家时滞后秒杀

时间:2012-12-09 20:42:22

标签: java swing jframe jpanel

播放器是一个面板,它将被移除,其位置发生变化,然后重新添加到另一个面板(包含此方法的面板),该面板被绘制到主框架。还有许多其他小面板包含一个草精灵被绘制到主面板作为地形瓷砖。我认为问题在于,当我调用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();
        }
    }

}

2 个答案:

答案 0 :(得分:4)

AttentionedPlayer.movePlayer();似乎是一个密集型操作,您可以在EDT(GUI线程)中执行它。而是从新线程或SwingWorker中执行它。

阅读this answer以了解有关SwingWorker的更多信息。

答案 1 :(得分:3)

@Eng.Fouad对他有一个好点+1,虽然我个人从来没有因为这个原因而需要这个,但是你的移动方法可能非常密集。

仅使用 JPanel游戏逻辑显示示例(从我的评论中扩展),如果正确实施 ,则不需要{{1玩家移动(通过revalidate())哪个IMO也会导致大量延迟,尤其是在有很多组件的情况下。正如您将看到我的setLocation(..)扩展GamePanel并使用JPanel / Null布局(但在游戏中我们希望更多地控制布局)。

还使用Absolute来向您展示其用途。

enter image description here

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