JavaRush /Java 博客 /Random-ZH /java 中的多人控制台游戏
timurnav
第 21 级

java 中的多人控制台游戏

已在 Random-ZH 群组中发布
大家好,我早就写完了游戏,但还没抽出时间来写文章,算是这篇文章的顺理成章的延续吧 如果你还没有尝试过做其他的事情比JavaRush任务,那么熟悉游戏将正是您想要开始的地方,您将需要开始准备真实项目的测试任务,我强烈建议大家参加。总的来说,是时候停止在真空中成为一名球形程序员并开始学习 java 核心之外的东西了。为了简单地观看比赛,您必须安装 MySQL,如果您还没有使用它,请不要犹豫 - 安装它,这是您将在工作和个人项目中使用的数据库之一!我不会描述如何安装和使用数据库;互联网上有大量的教程和视频;我建议您自己解决这个问题,这也是程序员最重要的技能之一 - 计算自己解决:) 在生活中,您将需要能够在本机中使用 sql 编写查询,并通过 JDBC、hibernate、spring、spring data,也许这个列表可以继续,但我的知识就到此为止。现在别再读这篇文章了,弄清楚MySQL,其实一点也不难,你需要安装服务器本身,唯一的设置就是登录名和密码。然后了解工作时使用哪些命令。 使用服务器的命令: createshowuse和其他命令help- 将给出完整的命令列表。 使用特定表的查询: selectinsertdelete其他。不要太深入,仅仅阅读命令有可能只记住一小部分。随着时间的推移,你会学到一切。你可以在MySQL终端中玩,创建数据库,创建表,填充它们,发出显示数据的请求,添加查询条件。最有可能的是,这不会超过 2-3 小时;如果更长,也不必担心,随着经验的积累,你会更快地掌握新材料。如果你的基础没有问题,那么你可以开始开发游戏,基于我已经写过的关于井字棋的游戏。很长一段时间我不知道如何实现多人游戏,我找到了使用数据库的解决方案。游戏过程假设玩家轮流进行,游戏中的所有变化都记录在数据库中。已经基于此,我们知道我们有一个玩家,并且有一个包含玩家链接的比赛场地,在比赛场地中,应该将一个玩家等待第二个玩家采取行动的逻辑联系起来之后他们的角色发生变化,第一个玩家采取行动,第二个玩家等待。由于所有更改都必须在数据库中复制,因此每次移动后我们都需要保存该字段。所以我们得出第一个结论,数据库中必须有一个比赛场地,并且由于我们正在谈论多人游戏,因此我们需要在那里添加玩家。让我们在 MySQL 中创建表,我是通过 mysql 终端窗口本地完成的。比赛场地包含与球员的链接,因此首先创建一个包含球员的表是合乎逻辑的。 我们的球员有:
  • id– 序列号,我们将其设为主键;
  • name– 通用名称、字符串;
  • wins– 胜利次数;
  • loses– 病变数量;
  • games– 玩过的游戏总数。
游戏桌:
  • id– 序列号,我们将其设为主键;
  • x– 玩游戏的玩家 ID х– 辅助键;
  • o– 玩游戏的玩家 ID o– 辅助键;
  • field– 字段本身,其格式将在下面描述;
  • status– 这是多人游戏正常工作所必需的,状态表征了游戏的状态:
    已创建、正在玩、游戏结束

  • current– 也适用于多人游戏,特别是在游戏过程中,该字段控制现在轮到谁,
    并在结束后宣布获胜者或平局

我们已经整理好了表格,现在我们需要创建具有相应字段的 Java 类 -GameUser
public class Game {
    private Integer id;
    private Integer x;
    private Integer y;
    private Integer field;
    private String status;
    private String current;
}
public class User {
    private Integer id;
    private String name;
    private Integer wins;
    private Integer loses;
    private Integer games;
    private Boolean busy;
}
让我们添加一个不带参数的空构造函数 - 用于使用数据库和另一个用于创建对象的构造函数。让我们为所有字段添加 setter 和 getter。现在让我们来处理休眠:)它并没有变得越来越容易。它比 MySQL 稍微复杂一些,我将快速浏览一下一般结构。再说一遍,并不是所有事情都那么复杂,通过任何教程都可以在几个小时内学习基础知识,并且最好在编写项目时深入学习。从 JAVA 处理数据库涉及到使用 JDBC,请在wiki上阅读相关内容。但是如果你在写代码时使用它,它会带来很多麻烦,编写DAO类(也是wiki)会有些复杂,hibernate会稍微改善这种情况,有了它你的重复性就会少很多(模板) 代码。为了让 hibernate 工作,您需要将一个库连接到项目,这非常简单:Ctrl+Alt+Shift+S(文件-项目结构),转到“库”选项卡,单击“+”并添加一个预下载的库(作为一个选项,从这里)。为了链接类,UserGame需要使用注释 - 它们非常易于使用,使用它们,代码如下所示:
@Entity
@Table(name="games")
public class Game {
    private Integer id;
    private Integer x;

    @Id
    @GeneratedValue
    @Column(name = "id")
    public Integer getId() {
        return id;
    }

    @Column(name = "x")
    public Integer getX() {
        return x;
    }
}
这里很简单
  • @Entity– 表示类是一个“实体”,简单来说,它与数据库中的表绑定在一起。
  • @Table(name="games")– 表示哪个表,games– 数据库中表的名称
  • @Id, @GeneratedValue, @Column(name = "id")– 通过这三个注解我们表示这个字段是一个标识字段,它是自动生成的,数据库中的列称为id。
  • @Column(name = "x")– 数据库中列的名称。
接下来,您需要构建级别 - DAO 级别和服务级别。如果我们将一切简化为真空条件,然后处理数据会经过服务级别,这是抽象级别之一,它允许您使应用程序工作更加独立,以便游戏逻辑的开发人员无需深入细节设置对数据库的访问,或者例如,如果我们突然决定使用 spring 而不是简单的 hibernate,那么更改将不会超出服务层,否则一半的应用程序将不得不重写!这是设计模式之一。让我们开始编写DAO级别。
public class UserDAO {

    public void addUser(User user) throws SQLException {
        Session session = null;
        try{
            session = HibernateUtil.getSessionFactory().openSession();
            session.beginTransaction();
            session.save(user);
            session.getTransaction().commit();
        } catch (Exception e){
            e.printStackTrace();
        } finally {
            if (session != null && session.isOpen()) {
                session.close();
            }
        }
    }
}
这就是向数据库添加新用户的操作的样子。请注意,只有实体类的对象传递给该方法;这里不需要其他信息。我们从 HibernateUtil 类接收到与数据库的现成通信会话,这一事实确保了这一点。让我们考虑一下。
public class HibernateUtil {
    private static SessionFactory sessionFactory = null;

    static {
        try {

            sessionFactory = new Configuration().configure().buildSessionFactory();
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    public static SessionFactory getSessionFactory() {
        return sessionFactory;
    }
}
正如您所看到的,这里的一切也非常简单SessionFactory- 这是来自 hibernate 库的接口,我们将其连接到我们的项目。为了正确操作,剩下的就是填写 hibernate.cfg.xml 配置文件
<!DOCTYPE hibernate-configuration PUBLIC
        "-//Hibernate/Hibernate Configuration DTD 3.0//EN"
        "http://hibernate.sourceforge.net/hibernate-configuration-3.0.dtd">
<hibernate-configuration>
    <session-factory>
        <property name="connection.driver_class">com.mysql.jdbc.Driver</property>
        <property name="connection.url">jdbc:mysql://localhost:3306/tictactoe</property>
        <property name="connection.username">root</property>
        <property name="connection.password">root</property>
        <property name="connection.pool_size">100</property>
        <property name="dialect">org.hibernate.dialect.MySQL5InnoDBDialect</property>
        <property name="show_sql">false</property>
        <property name="hbm2ddl.auto">update</property>
        <property name="hibernate.connection.autocommit">false</property>
        <property name="current_session_context_class">thread</property>
        <property name="hibernate.enable_lazy_load_no_trans">true</property>
        <mapping class="entity.User" />
        <mapping class="entity.Game" />
    </session-factory>
</hibernate-configuration>
如果您浏览一下标签,就会清楚我们在这里设置什么以及如何设置。hibernate的另一个特性是,如果我们突然决定将数据库从MySQL更改为其他数据库,我们只需要更改标签内的驱动程序property name="connection.driver_class" DAO层已准备好,让我们创建一个服务层。为了避免在服务层创建DAO对象,我们使用工厂模式。
public class Factory {
    private static UserDAO userDAO = null;
    private static Factory instance = null;
    private Factory() {
    }

    public static synchronized Factory getInstance() {
        if (instance == null) {
            instance = new Factory();
        }
        return instance;
    }

    public UserDAO getUserDAO() {
        if (userDAO == null) {
            userDAO = new UserDAO();
        }
        return userDAO;
    }
}
这是服务级别方法之一
public class UserService {
    static void setUserBusy(User user){
        user.setBusy(true); //делаем его занятым
        //и обновляем его в БД
        Factory.getInstance().getUserDAO().updateUser(user);
    }

}
使用数据库的代码已完成,我们根据更改重写游戏逻辑。首先,让我们将主要的启动方法分离到一个单独的类中Main,它只是一个控制类 - 一个游戏菜单,您可以在其中启动游戏或查看统计数据。让我们创建一个类GameLogic来描述游戏的所有逻辑并检查比赛场地。他会将赛场上的所有变化以及赛后球员统计数据的保存委托给服务层。有一个有趣的功能,我们以数组的形式包含比赛场地,它们可以保存在数据库中,但在这个阶段我决定重新发明轮子,在我的数据库中,该场地被包含为一个 int,即 9 -digit数字,使用类方法进行两次解析GameLogic,我不建议这样做,我会在游戏的下一个版本中改进:)祝大家学习JAVA好运!您可以在此处下载该项目。
评论
TO VIEW ALL COMMENTS OR TO MAKE A COMMENT,
GO TO FULL VERSION