Сначала немного теории:
Я буду говорить о схеме построения многопользовательской игры, где клиентскую часть будет представлять устройство, например компьютер, планшет или смартфон. На этом устройстве и будет установлена сама игра. Понятное дело она должна быть установлена у каждого игрока.
И вторая часть сервер на котором будет храниться и передаваться информация о игре, от игрока к игроку. Например, в шутере это могут быть координаты положения человечка игрока в игровом пространстве, его здоровье и наносимый им урон какому то другому игроку, ну и другие показатели.
Суть простая, через определенное время (постоянно автоматически) отправляем запрос серверу с клиентской части (с нашей игры установленной на устройстве). Т.е. первый игрок отправляет информацию на сервер, там она сохраняется. В свою очередь он берет с сервера информацию о других игроках. Например, о нанесенном ему уроне, и положении игроков в пространстве. То же самое делают и другие игроки.
В чем специфика многопользовательских игр на стороне клиента. Данные не отправляются с основного потока, а идут в фоновом режиме. Это связано с тем, что запрос к интернету, может затянуться. Следовательно, что бы ваша игра не зависла, запрос на сервер выполняют в фоновом потоке.
Ну и сервер должен быть готов к обращению и перезаписи информации сразу нескольких игроков. В принципе серверное программирование всегда изначально осуществляется с этим учетом. Различные блокировки на запись и чтение. Базы данных уже подготовленные к многопользовательской записи и чтению.
А сам принцип отправки клиентом информации очень простой.
По сути вы просто обращаетесь к интернет сайту, по обычному адресу, и соответственно получаете назад страницу сайта и обрабатываете результат.
Т.е. ничем не отличается от простого серфинга по интернету. Только по интернет адресам ходите не вы, а клиентская часть игры. Тоже самое с получением информации. Пришедшую информацию не вы читаете на экране в браузере, а ее читает и обрабатывает клиентская часть игры.
Принцип один на многопользовательские игры, чаты, социальные сети.
Например, как нам определить, что человек на каком либо сайте, чате, социальной сети, или многопользовательской игре находится онлайн или нет. Все просто автоматические запросы к серверу с клиентской части и запись на сервере информации последнего посещения. Другой пользователь при обращаясь к серверу запустит проверку времени отсутствия интересуемого его игрока (последнего его сохраненного времени на сервере). В результате получит ответ находится пользователь онлайн или уже закрыл сайт, игру и т.д.
Запросы на сервер делаются разными методами, например GET и POST.
GET –это отправка в самом адресе интернет запроса (обычно применяется при небольших по размеру запросов на сервер)
POST – если данных отправляется много.
Вы наверное много раз встречались со случаем когда при переходе назад на страницу в браузере, сайт просит повторить отправку данных. Это как раз и есть метод POST.
В браузерных онлайн играх все в принципе тоже самое, только запрос к серверу через определенное время отправляет программа написанная на Javascript. А сама технология называется АЯКС. Есть и другие способы, но АЯКС самый распространенный и хорошо поддерживается всеми популярными браузерами.
Ну хватит болтовни приведу простейший пример обращения клиентской части (это будет программа на Андройд на языке программирования Java), к серверной написанной на языке PHP.
Внизу код для операционной системы Андройд, язык программирования Java.
Как видите, я обращаюсь из фонового потока к сайту:
https:// poshta.000webhostapp.com/onlain/aaaregistr/zaproskigre.php
И передаю данные (на сервер):
pl = par_oool (правая часть это у меня глобальная переменная)
lo = log_iii
zd = zdorov__ и т.д.
Как вы поняли это выжимка части кода из реальной многопользовательской игры. В данном случае шутера.
Я получаю результат (ответ от сервера) и записываю все в строку rezult_1 (тут в коде это глобальная переменная)
Сам код ниже:
class CatTask extends AsyncTask<Integer, Integer, String[]> {
@Override
protected void onPreExecute() {
super.onPreExecute();
}
// Ниже наш фоновый поток
@Override
protected String[] doInBackground(Integer... params) {
String[] ito_ = {"", ""};
if(zapl_zapusk == 1){// Это просто условие запуска кода ниже
StringBuilder sb = new StringBuilder();
try {
int zdorov__ = (int)otpravlaemoe_zdorov_igroka;
URL pageURL = new URL("https:// poshta.000webhostapp.com/onlain/aaaregistr/zaproskigre.php?pl=" + par_oool + "&lo=" + log_iiin+"&zd="+zdorov__+"&br="+0+"&koef="+(koef_zdorov_igroka + kooefic_zdorov_slogn_igroka)+"&yr="+obshiy_ur_nanes_nepriiatilu+"&got="+gotov_li_k_igre+"&etot="+tochno_etot+"&mess="+""); // params[0]
String inputLine;
URLConnection uc = pageURL.openConnection();
BufferedReader buff = new BufferedReader(new InputStreamReader(uc.getInputStream()));
while ((inputLine = buff.readLine()) != null) {
sb.append(inputLine);
}
buff.close();
}
catch (Exception e) {
}
rezult_1 = sb.toString();// Здесь результат ответ от сервера
// По сути мы получаем обычную HTML страницу и считываем в строку
}
return ito_;
}
@Override
protected void onPostExecute(String[] result) {
super.onPostExecute(result);
//Toast.makeText(Trancleit.this, result[0], Toast.LENGTH_SHORT).show();
}
@Override
protected void onProgressUpdate(Integer... values) {
super.onProgressUpdate(values);
}
}
Теперь серверная часть на PHP ниже:
<?php
header("Content-Type: text/html;charset=UTF-8"); // кодировка
// этот логин приходит со стороны клиента (из игры)
$login_polz = substr(htmlspecialchars($_GET['lo']),0,100);
// Здесь также происходит проверка и обрезка данных
// Сам запрос $_GET['lo']
// Я логин сохраняю в переменную $login_polz
?>
Как вы поняли мы считали наш “lo = log_iii” из адресной строки методом GET
log_iii – это просто имя переменной (как видно в первом коде для Андройда это просто глобальная переменная в которой содержится передаваемая на сервер строка)
Так же получаем и остальные данные обрабатываем их и возвращаем результат.
Вернуть результат можно так:
<?php
echo $fd;
// В данном случае я вывожу на отправляемой клиенту интернет странице данные хранящиеся в переменной $fd
// Эти данные мы и получим в результате в первом коде в строковой переменной rezult_1
?>
Как же вы спросите делать запрос с помощью метода POST.
Смотрим код ниже, также выжимка кода Андройд язык Java:
StringBuilder sb = new StringBuilder();
String inputLine="";
try {
String urlStr = "https://translate.yandex.net/api/v1.5/tr.json/translate?key=trnsl.1.1.20180828T130619Z.d332899fc8f0a0c676dd406170b895493363fdc81a88\n";
URL urlObj = new URL(urlStr);
HttpsURLConnection connection = (HttpsURLConnection) urlObj.openConnection();
connection.setRequestMethod("POST");
connection.setDoOutput(true);
DataOutputStream dataOutputStream = new DataOutputStream(connection.getOutputStream());
dataOutputStream.writeBytes("text=" + URLEncoder.encode(params[0], "UTF-8") + "&lang=" + "en-ru");
//URLConnection uc = urlObj.openConnection();
BufferedReader buff = new BufferedReader(new InputStreamReader(connection.getInputStream()));
while ((inputLine = buff.readLine()) != null) {
sb.append(inputLine);
}
buff.close();
} catch (Exception e) {
}
Как видно в коде, я прошу Яндекс перевести текст с английского на русский (код рабочий но ключ Яндекса здесь неверный ). Вы можете его получить сами он бесплатный.
Спасибо за внимание.
Надеюсь не сильно мудрено написал. Удачи вам в ваших начинаниях.
И не забудьте подписаться на канал. Будет много интересного по программированию игр под операционную систему Android на языке программирования Java.