Всім привіт, давно вже дописав гру, все ніяк не доходабо руки до написання статті, вона є логічним продовженням цієї писуліни Якщо ви поки що не пробували робити щось крім завдань JavaRush, то знайомство з грою буде саме тим, з чого потрібно буде почати підготовку до тестових завдань реального проекту, в якому я рекомендую взяти участь кожному. Та й взагалі час вже перестати бути сферичним програмістом у вакуумі і почати вивчати щось за межами java-core. Для того, щоб просто подивитися гру, у вас має бути встановлений MySQL, якщо ви поки що таким не користувалися, не соромтеся – ставте, це одна з тих баз даних, які ви будете використовувати у своїй роботі та особистих проектах! Я не наводитиму опис установки та роботи з базою, в інтернеті навалом туторіалів та відео, рекомендую розібратися з цим питанням самостійно, це теж один з найважливіших скілів програміста – розбиратися самостійно.hibernate , spring, spring data, можливо, список можна продовжити, але мої знання на цьому закінчуються. А тепер відкладіть читання цієї статті та розберіться з MySQL, це насправді зовсім не складно, вам потрібно поставити сам сервер, з налаштувань там лише логін та пароль. потім почитайте про те які команди застосовуються при роботі. Команди для роботи із сервером: дуже багато болю в задньому проході деяку складність у написанні класів DAO ( теж вікі), hibernate трохи покращить ситуацію, з ним у вас буде набагато менше повторюваного (шаблонного) коду. Для того, щоб працювати hibernate, до проекту необхідно підключити бібліотеку, робиться це дуже просто: Ctrl+Alt+Shift+S(File-Project Structure), заходимо у вкладку Libraries, натискаємо "+" і додаємо попередньо завантажену бібліотеку (як варіант , звідси ). Для того, щоб зв'язати класи
create
, show
, use
, та інші, команда help
– дасть повний перелік команд. Запити до роботи з конкретною таблицею: select
, insert
,delete
та інші. особливо сильно не заглиблюйтесь, є ймовірність, що від простого читання команд запам'ятається лише мала частина. ви все вивчите з часом. Можете пограти в терміналі MySQL, створіть базу даних, створіть таблички, заповніть їх, зробіть запит на виведення даних, додайте критерії запитів. Швидше за все, у вас на цій піде не більше 2-3 годин, якщо довше - не засмучуйтеся, з досвідом ви освоюватимете новий матеріал швидше. Якщо з базами у вас проблем немає, то можна приступати до розробки гри, за основу взято гру, про яку я вже писав хрестики-нуліки. Я дуже довго не міг розібратися з тим, як реалізувати мультиплеєр, вихід я знайшов у використанні БД. Процес гри передбачає, що гравці ходять по черзі, всі зміни в грі фіксуються в базі даних. вже виходячи з цього ми розуміємо, що у нас є гравець і є ігрове поле, яке містить посилання на гравців, саме в ігровому полі має бути зав'язана логіка, в якій один гравець перебуває в очікуванні ходу другого гравця і після чого їх ролі змінюються і вже перший гравець робить хід, а другий чекає. Оскільки всі зміни повинні дублюватися в БД, то після кожного ходу нам потрібно зберігати поле. Отже ми дійшли першого висновку, в Базі даних має бути ігрове поле і якщо ми говоримо про мультиплеєрі, то потрібно туди додати і гравців. Створимо таблиці в MySQL, я зробив це нативно, через вікно терміналу mysql. Гравці у нас мають:
id
- Порядковий номер, ми його робимо первинним ключем;name
- Звичайне ім'я, рядок;wins
– кількість перемог;loses
– кількість поразок;games
- Загальна кількість проведених ігор.
id
- Порядковий номер, ми його робимо первинним ключем;x
– id гравця граючогох
– вторинний ключ;o
– id гравця граючогоo
– вторинний ключ;field
- саме поле, про його формат буде написано нижче;status
- Це потрібно для коректної роботи мультиплеєра, статус характеризує стан гри:
створена, граємо, гра закінченаcurrent
- теж для мультиплеєра, саме під час гри це поле управляє тим чий зараз хід,
а після її закінчення воно оголошує переможця або нічию
Game
та User
.
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;
}
Додамо порожній конструктор без параметрів – для роботи з БД та ще один конструктор, яким ми створюватимемо об'єкти. додамо сеттери та гетери для всіх полів. Тепер розберемося з hibernate :) час від часу не легше. Тут трохи складніше, ніж з MySQL, я швидко пройдуся за загальною структурою. Знову ж таки не все так складно, основи можна засвоїти через будь-який туторіал за пару-трійку годин, а поглиблено вже краще вивчати в процесі написання своїх проектиків. Робота з БД з JAVA має на увазі використання JDBC, почитайте про нього у вікі . Але якщо користуватися ним у написанні коду, то це принесе User
і Game
вам потрібно використовувати інструкції – вони дуже прості у використанні, з ними код виглядає так:
@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")
- Ім'я стовпця в БД.
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-тизначне число, парсинг якого проводиться двома методами класуGameLogic
, Так робити не рекомендую, в наступних релізах гри я виправлятимуся :) Всім удачі у вивченні JAVA! Завантажити проект можна тут .
ПЕРЕЙДІТЬ В ПОВНУ ВЕРСІЮ