Java控制台游戏开发|方法

时间:2014-06-09 16:57:35

标签: java

好的,请允许我详述我的困境。

我用Java制作控制台游戏。它不会超级简单,但我也不希望它真的先进。我只是尝试使用我学到的基础知识来测试自己的技能。我已经开了几次,但经常遇到同样的问题"。

虽然这不是一个问题,但我能做得更好。解释它的最好方法是只显示一些示例代码。

这是我的主课。我们称之为" Main.java"。

package com.mattkx4.cgamedev.main;

public class Main {
    public static void main(String[] args) {

    }
}

好的,现在让我们在Main.java中创建一个新方法。我们将此方法称为“#34;开始"”。我们的主要班级现在看起来像这样:

package com.mattkx4.cgamedev.main;

import java.util.Scanner;

public class Main {
    public static void main(String[] args) {

    }

    public static void start() {
        System.out.println("This is the start.");
        Scanner s = new Scanner(System.in);
        System.out.println("Enter \"NEXT\" to continue.");
        String in = s.nextLine();

        if(in.equalsIgnoreCase("NEXT")) {
        }else{
            System.out.println("Please input \"NEXT\".");
            start();
        }
    }
}

现在我们再添加两个方法。我们打电话给他们"中"和"结束"。我们完成的课程现在看起来像这样:

package com.mattkx4.cgamedev.main;

import java.util.Scanner;

public class Main {
    public static void main(String[] args) {
        start();
    }

    public static void start() {
        System.out.println("This is the start.");
        Scanner s = new Scanner(System.in);
        System.out.println("Enter \"NEXT\" to continue.");
        String in = s.nextLine();

        if(in.equalsIgnoreCase("NEXT")) {
            middle();
            s.close();
            System.exit(0);
        }else{
            System.out.println("Please input \"NEXT\".");
            start();
        }
    }

    public static void middle() {
        System.out.println("This is the middle.");
        System.out.println("Let's move on to the end.");
        end();
    }

    public static void end() {
        System.out.println("This is the end.\nFinishing up, and heading back to the start() method to close program.");
    }
}

我在这里写的是一个非常低效的程序。编写代码的效率低下。必须有另一种方法来完成这个程序,而不是调用其他方法中的方法来移动程序。

我的问题摘要:上面的代码是编写控制台游戏的最有效方法吗?

提前致谢!如果您有任何问题,我将很乐意回答。 马修

5 个答案:

答案 0 :(得分:5)

您的问题有很多种答案。我只列举一些基本的东西。

  1. 您的设计是线性的,完全僵硬。不易伸缩。像这样的大多数应用程序,而不是链接任何方法等,以某种方式存储状态。这通常使用enum来实现。了解state-based programming works的方式非常重要。所以你可能有类似的东西:

    public enum GameState {
        LOAD, START, STOP, BEGIN, MIDDLE, END, GAME_OVER // ... and so on
    }
    
  2. 您正在使用一堆static方法。这肯定不是你想要做的。它完全放弃任何面向对象。如果你正在建立一个游戏世界,理想情况下,你将为你的世界中的每个不同对象创建一个类,并且它们将按照extends彼此或{{1}排列在逻辑层次结构中。 - 不同的接口。

  3. 您需要学习并发性。如果游戏具有任何复杂性,那么您的用户输入几乎必然与游戏渲染异步。至少非常,你可能至少需要Swing来创建一个GUI。

  4. 因此,只需使用这三个非常基本的笔记,您就需要了解object-orientationpolymorphismconcurrency以及您可以使用的所有各种数据结构。坦率地说,您的示例具有Java 101项目的复杂性。 (我不是说那是卑鄙的。)如果你打算制作一款真正的游戏,你需要更多的基础知识才能取得真正的进展。

    你的想法很好,你的编程目标很大很好。但是把这个大梦想打破成可管理的大块。它会越走越快,也会让你灰心丧气。

    祝你好运!


    作为旁注,如果您开始编写一些简单的游戏(甚至像基于控制台的Hangman或Tic-Tac-Toe这样简单的游戏),请转到Code Review Beta。我们非常乐意为您提供详细的代码审查,并帮助您成为一名资深程序员!这是一个很好的社区,有很多非常有建设性的批评。我在那里帮助过那些人(使用Java)并在学习Python时获得了很多帮助。

答案 1 :(得分:3)

好吧,我不太了解这与性能或优化有什么关系。但通常你会使用类和方法来构建你的程序。

话虽如此,你的start方法存在很大的错误。您应该设置不必要的递归并改为使用循环,并删除exit调用:

public static void start() {
    System.out.println("This is the start.");
    Scanner s = new Scanner(System.in);
    System.out.println("Enter \"NEXT\" to continue.");
    String in = s.nextLine();

    if(in.equalsIgnoreCase("NEXT")) {
        middle();
        s.close();
        System.exit(0);
    }else{
        System.out.println("Please input \"NEXT\".");
        start();  // <-- recursion!
    }
}

最好这样做:

public static void start() {
    System.out.println("This is the start.");
    Scanner s = new Scanner(System.in);

    System.out.println("Enter \"NEXT\" to continue.");

    while ( !s.nextLine().equals("NEXT")) {
        System.out.println("Please input \"NEXT\".");
    }

    middle();

    // you probably also want to put "end();" here - it is not called in the original code
    s.close();
}

答案 2 :(得分:3)

我猜你正在尝试构建的是应用程序的主要框架。我建议搜索“Game Loop”。那里有很多很好的文章。

对于一般解决方案,算法在大规模上或多或少是这样的:

while (notExit()) {
   event = getNextEvent(); // this can be the user keyboard input or mouse
   renderGame(); // display the graphics on the screen
   doGameLogic(event); // do the game logic according to the events occurred
}

稍后,您必须考虑在屏幕上绘制的每秒的次数(FPS)以及计算更改的次数(每秒的物理帧数)。

与GUI编程的任何类比都只是纯粹的巧合。我开玩笑,这不是巧合,是GUI和游戏编程共享一个线程来实现事件调度线程的角色。

有关详细信息,我建议您阅读本教程:http://sol.gfxile.net/gp/index.html

希望它有所帮助!

答案 3 :(得分:2)

真的取决于应用程序/游戏的类型,如何构建它。

在这种情况下,您可能会发现使用某种控制方法很有用,这种控制方法以正确的顺序运行函数并且具有&#34; flow&#34;逻辑。

在一个更复杂的游戏中,这种方法会处理用户输入,将用户输入引导到不同的房间/等级/等。你甚至可能有更小的控制方法来处理子部分。

例如, 您可以使用调用registerPlayer()的playGame方法,该方法将处理获取播放器的名称和任何其他信息。当该方法返回时,playGame将调用levelOne()方法,依此类推。

尝试将其分解为游戏的逻辑单元!

答案 4 :(得分:2)

从我的头顶解决方案,

创建课程

class Location{
public Location( String locationId, String desctiption, List<String> exit){
//populate fields
}

private final String locationId;
private final String desctiption;
private final List<String> exits;
//getters ommited
}

然后你可以有3个位置;

start = new Location("START","This is the start.",Arrays.asList("middle"));
middle= new Location("middle","This is the middle.\nLet's move on to the end.",Arrays.asList("end"));
end= new Location("end","This is the end.",null);

现在是您的启动器类

公共课游戏{     Map locations = new HashMap();

public Game() {
    locations.put("START", new Location("START", "This is the start.",
            Arrays.asList("middle")));
    locations.put("middle",
            new Location("middle",
                    "This is the middle.\nLet's move on to the end.",
                    Arrays.asList("end")));
    locations.put("end", new Location("end", "This is the end.", null));
}

public static void main(String[] args) {
    Game game = new Game();
    game.start();

}

private void start() {
    visitLocation(locations.get("START"));

}

public void visitLocation(Location location) {
    System.out.println(location.getDescription());

    if (location.getExits().isEmpty()) {
        return;
    }

    Scanner s = new Scanner(System.in);
    String in = "";
    do {
        System.out.println("Choose exit from location : ");
        for (String exit : location.getExits())
            System.out.print(exit + " ");
        in = s.nextLine();
    } while (!location.getExits().contains(in));
    s.close();

    visitLocation(locations.get(in));
}

}

这仍然不是最好的,但我认为它会给你一些想法,