【问题标题】:OOP Coordinates in grid Java wont work. How to program? [duplicate]网格 Java 中的 OOP 坐标不起作用。如何编程? [复制]
【发布时间】:2021-04-21 00:55:19
【问题描述】:

我没有让这个工作。这是面向对象的。向上、向下、向左或向右移动时,我应该在网格中获取 (x,y) 坐标。我需要 toString 始终为我采取的每一步更新。我更喜欢在键盘上使用箭头键,但我不知道如何。如果有人知道这对程序会很好。我必须能够 - 例如 - 按向上、然后向下、然后向上而不停止。

    package stateandbehavior;
    import java.util.*;
    public class Location {

        int x;
        int y;
    
        public void up() {
        boolean run = true;
        while (run) {   
        Scanner tast = new Scanner(System.in);
        String tas = tast.nextLine();
        if (tas == "W" || tas == "w") {
            y-=1;
        }else {
            run = false;
        }
        }
    }
    
    public void down() {
        boolean run = true;
        while (run) {
        Scanner tast = new Scanner(System.in);
        String tas = tast.nextLine();
        if(tas == "S" || tas == "s") {
            y+=1;
        } else {
            run = false;
        }
        }
        
    }
    
    public void right() {
        boolean run = true;
        while (run) {
        Scanner tast = new Scanner(System.in);
        String tas = tast.nextLine();
        if (tas == "D" || tas == "d") {
            x+=1;
        }else {
            run = false;
        }
        }
    }
    
    public void left() {
        boolean run = true;
        while(run)
        Scanner tast = new Scanner(System.in);
        String tas = tast.nextLine();
        if(tas == "A" || tas == "a") {
            x-=1;
        }else {
            run = false;
        }
    }
    
    public int getX() {
        return x;
    }
    
    public int getY() {
        return y;   
    }
    
    public String toString() {
        return "(" + x + ","+ y + ")";
    }
    
    public static void main(String[] args) {
        Location Loc = new Location();
        Loc.up();
        Loc.down();
        Loc.right();
        Loc.left();
        Loc.getX();
        Loc.getY();
        System.out.println(Loc);    
    }
}

【问题讨论】:

  • 你的代码太糟糕了。 a) 这是错误的。错误的概念。生病发布解决方案。 b)格式(尤其是意图)非常糟糕。使用 Eclipse 或 IntelliJ,使用它们带来的格式化功能。 c) 代码有句法/结构错误。大括号放置错误。 d) 命名约定是小写的对象名称,即它应该是Location loc = new Location()

标签: java


【解决方案1】:

第二个解决方案。使用 Java Swing 构建 GUI。

问题在于当前的 Java 控制台支持,无法获取按下的键的 KeyCode。 您可以为侦听器使用库:我喜欢为此使用 JNativeHook。 您还可以欺骗您的操作系统来处理您的键码,这非常骇人听闻。 所以最后,游戏和诸如此类的东西并不总是使用真正的 GUI 窗口,并且随之而来的是简单的输入处理:

(与我在另一个答案中提供的 Location2 类一起使用)

package stackoverflow.notmoving;

import java.awt.BorderLayout;
import java.awt.event.ActionEvent;
import java.awt.event.KeyAdapter;
import java.awt.event.KeyEvent;

import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JLabel;

public class LocationWindow extends JFrame {
    private static final long serialVersionUID = -6515573336353025277L;



    private final JLabel    cLabPosition    = new JLabel("Position: ");
    private final JButton   cBtnControl     = new JButton("Focus this for controls...");

    private final Location2 myLocation = new Location2();

    public LocationWindow() {
        setDefaultCloseOperation(EXIT_ON_CLOSE);
        setLayout(new BorderLayout());
        setTitle("Simple GUI");

        add(cLabPosition, BorderLayout.NORTH);

        cBtnControl.addActionListener(e -> buttonPressed(e));
        cBtnControl.addKeyListener(new KeyAdapter() {
            @Override public void keyPressed(final KeyEvent pE) {
                LocationWindow.this.keyPressed(pE);
            }
        });
        add(cBtnControl, BorderLayout.CENTER);

        pack();
    }



    protected void keyPressed(final KeyEvent pE) {
        System.out.println("LocationWindow.keyPressed(" + pE + ")");
        switch (pE.getKeyCode()) {
            case (KeyEvent.VK_UP): {
                myLocation.up();
                break;
            }
            case (KeyEvent.VK_LEFT): {
                myLocation.left();
                break;
            }
            case (KeyEvent.VK_DOWN): {
                myLocation.down();
                break;
            }
            case (KeyEvent.VK_RIGHT): {
                myLocation.right();
                break;
            }
            case (KeyEvent.VK_ESCAPE): {
                dispose();
                break;
            }
            default:
                /* ignore */
        }
        cLabPosition.setText("Position: " + myLocation);
    }

    private void buttonPressed(@SuppressWarnings("unused") final ActionEvent pE) {
        cLabPosition.setText("You have taken control!");
        cBtnControl.setText("Controlling...");
    }

    public static void main(final String[] args) {
        final LocationWindow l = new LocationWindow();
        l.setVisible(true);
    }

}

你会发现两者之间有很多相似之处。

【讨论】:

  • 谢谢。为了使这个功能起作用,我总是需要在按下 WASD 时按回车键。我怎样才能让它自己注意到它并增加或减少它的数量
  • 3 种可能性:1) 表单中没有任何可聚焦的控件,因此所有事件都“通过”到 JFrame 本身。而不是cBtnControl.addKeyListener(...);,你可以写this.addKeyListener(...);('this'是LocationWindow/JFrame。2)你可以用https://stackoverflow.com/questions/58713715/how-to-get-a-key-event-in-a-java-swing-jframe-instance-which-has-many-jtextfield中的KeyListener注册键事件,3)你可以使用一个全局监听器来监听操作系统上的所有关键事件,例如 JNativeHook。从 (1) 到 (3) hackyness 呈指数增长。
  • 我认为您的评论针对的是另一个示例。正如我在这个例子中所说的,使用 Java System.in/console 不会让你得到事件,除非你按下回车键。所以控制台是不够的,你需要像 JNativeHooks 这样的 hacks 或库。
【解决方案2】:

这是我的第一个解决方案,使用带有行输入的 WASD 键(需要按 Enter):

package stackoverflow.notmoving;

import java.util.Scanner;

public class Location2 {

    private int x;
    private int y;

    public void up() {
        y -= 1;
    }
    public void down() {
        y += 1;
    }
    public void right() {
        x += 1;
    }
    public void left() {
        x -= 1;
    }

    public int getX() {
        return x;
    }
    public int getY() {
        return y;
    }

    @Override public String toString() {
        return "(" + x + "," + y + ")";
    }



    public static void main(final String[] args) {
        final Location2 loc = new Location2();

        final Scanner scanner = new Scanner(System.in);

        firstLoop: while (true) {
            System.out.print("Please enter new direction: ");
            final String inputRaw = scanner.nextLine();
            final String input = inputRaw == null ? "" : inputRaw.toLowerCase();
            switch (input) {
                case "w": {
                    loc.up();
                    break;
                }
                case "a": {
                    loc.left();
                    break;
                }
                case "s": {
                    loc.down();
                    break;
                }
                case "d": {
                    loc.right();
                    break;
                }
                case "e": {
                    System.out.println("Exiting input loop");
                    break firstLoop;
                }
                default:
                    /* ignore all other keys/strings */
            }
            System.out.println("New location: " + loc);
        }

        System.out.println("App ended with location: " + loc);
    }

}

真正的箭头键解决方案在第二个答案中出现

【讨论】:

    猜你喜欢
    • 2020-08-02
    • 1970-01-01
    • 2018-07-19
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多