Делаем свою первую MMO на GameMaker 8.0 №2! (+39dll)
|
|
Deswing | Дата: Воскресенье, 26 Декабря 2010, 13:46 | Сообщение # 1 |
заслуженный участник
Сейчас нет на сайте
| Как создать клиент yo! Ха! Вот и продолжение статьи! Перед тем, как начнем писать сервер, допишем кое-что в клиенте(image_anlge) Для этого в обьекте другого игрока (objRemote) в событии draw (рисование) заменим: Code draw_sprite(sprite_index, image_index, x, y); на Code draw_sprite_ext(sprite_index, image_index, x, y,1,1,image_angle,c_white,1); Итак, мы это заменили. Теперь надо сделать так, чтобы игрок крутился. Для этого в обьекте игрока (objPlayer) в событии step (шаг) вставляем код: Code image_angle=point_direction(x,y,mouse_x,mouse_y); Что это значит? Image_angle - это угол поворота обьекта. В нашем случае image_angle будет равняться point_direction по отношению к мышки. Если сказать проще - обьект будет смотреть в сторону мышки! Сейчас займемся передачей переменной image_angle! Но перед тем, как я покажу это, я должен вам рассказать важную вещь - алгоритм передачи! Что такое алгоритм? Алгори́тм, от имени учёного аль-Хорезми (перс. خوارزمی [al-Khwārazmī]) — точный набор инструкций, описывающих порядок действий исполнителя для достижения результата решения задачи за конечное время. В старой трактовке вместо слова «порядок» использовалось слово «последовательность», но по мере развития параллельности в работе компьютеров слово «последовательность» стали заменять более общим словом «порядок». Иными словами алгоритм - это последовательность, порядок каких-либо действий. Зачем я это вам говорю? Просто при передаче и считывании переменных нужно соблюдать порядок! Тоесть если мы написали передачу переменных вот так (у нас это в alarm): Code clearbuffer(); writebyte(playerlocation); writeshort(x); writeshort(y); sendmessage(objControl.socket); alarm[0] = 2; то и сервер обязан читать все это в такой последовательности! Мы не должны забывать, что компьютер - машина, а программиирование - язык общения с ней. Тоесть если мы не дадим четких инструкций - ничего не выйдет! Так... О чем это я? А! Точно! Передача image_angle! Для этого в обьекте objPlayer зайдите в событие alarm 0 (Будильник №0) и в коде, после передачи координаты y, допишите: Code writeshort(image_angle); У меня это будет выглядить так: Quote clearbuffer(); writebyte(playerlocation); writeshort(x); writeshort(y); writeshort(image_angle); sendmessage(objControl.socket); alarm[0] = 2; Думаете это всё? Неееее-а! >D Откройте обьект objControl и в событии Step (шаг). Там найдите строку case playerlocation: . После прочтения координаты y допишите: Quote case playerlocation: player = players[readbyte()]; player.x = readshort(); //Читаем координату х player.y = readshort(); //Читаем координату у player.image_angle = readshort(); //тадамс! Читаем угол поворота других игроков! *_* break; Воть... С клиентом закончили! Пишем сервер! Откройте архив, который скачали на уроке №1 и снова разархивируйте (для удобства создайте папку "Server") После этих действий откройте проект и создайте обьект server. В этом обьекте создайте событие create (создание) и вставьте код: Code dllinit(0, true, true); //Снова подключаем 39dll =) listen = tcplisten(14804, 30, true); //Включаем порт 14804 (вы ведь не забыли? В клиенте мы писали 14804!) if(!listen) //Если не получилось включить порт (возможно занят) { error_message("Unable to create listen socket"); //Показываем ошибку exit; //И выходим =) } //Добавляем в playerlist for(i = 0; i < 256; i += 1) { players[i] = -1; } А вы заметили? Мы ip не писали! "Почему?" - спросите вы? А зачем ip серверу? Мммм? Клиент вводит айпи (адрес) к нашему компьютеру и подключается к порту, а сервер прсото включает этот порт Теперь создайте событие step (шаг): Code player = tcpaccept(listen, 1); //Принимаем нового игрока if(player) //Иесли игрок зашел { playerid = newplayerid(); //Генерируем ему id if(playerid < 0)exit; //Если слишком много игроков, выходим i = instance_create(0, 0, objPlayer); //Создаем обьект игрока i.socketid = player; //Установливаем разъем ID для игрока в сокет, которого только что приняли i.playerid = playerid; players[playerid] = i; setnagle(player, false); //Выключить алгоритм Нагла для сокета //Говорим всем, что зашел нвоый игрок clearbuffer(); writebyte(newplayer); writebyte(playerid); writeshort(0); writeshort(0); writestring("", true); //Отправляем другим игрокам with(objPlayer) { if(id != other.i) { sendmessage(socketid); } } with(objPlayer) { if(id != other.i) { clearbuffer(); writebyte(newplayer); writebyte(playerid); writeshort(x); writeshort(y); writestring(nick, true); sendmessage(other.player); //Отправляем } } } Теперь создадим событие Game End (Игра закончена (вышли)) и пишем код: Code closesocket(listen); //Зыкрываем порт dllfree();//Выключаем 39dll =( Виии! *_* Мы дописали обьект server, теперь последний - objPlayer *-* Для начала создаем обьект, потом в create (создание), как всегда, пишем: Code x = 32; //Координаты нового игрока y = 32; //Координаты нового игрока nick = ""; //Ник alarm[0]= 1; //Включаем будильник (Раньше о них говорил)
timeout = 0; deltatime = current_time; Хмммм... Походу у нас дежавю О,о Про координаты ведь речь была! Да-да, вы правы х) Создайте событие destroy : Code clearbuffer(); //Чистим буффер writebyte(exitgame); //Пишем сообщение, что вышли writebyte(playerid); //Пишем id //Отправляем всем игрокам with(objPlayer) { if(id != other.id) { sendmessage(socketid); //Сама отправка } } closesocket(socketid); //закрываем сокет (не наш) server.players[playerid] = -1; //В случае, если вышли, сносим нас с Playerlist *_* Теперь Alarm 0 : Quote clearbuffer(); writebyte(playerlocation); //message id writebyte(playerid); //наш id writeshort(x); //позиция x writeshort(y); //позиция у writeshort(image_angle) //переменная image_angle, вращение //Отправляем другим with(objPlayer) { if(id != other.id) { sendmessage(socketid); } } alarm[0] = 3; Таааак! Ураааа! Сделали полный обмен с Image_angle! ЯХУ!! Хочу заметить - всегда писали после отправкии координаты у! Последнее событие Step! Code while(1) //Бесконечный цикл { size = receivemessage(socketid); if(size < 0)break; if(size == 0) { instance_destroy(); break; } timeout = 0; mid = readbyte(); //Читаем сообщение id switch(mid) { case playerlocation: //players location x = readshort(); //Читаем х y = readshort(); //Читаем у break; case playernick: //Новый никнейм nick = readstring(); //Читаем никнейм clearbuffer(); //Чистим буффер writebyte(playernick); //Пишем messageid writebyte(playerid); //Пишем мой id writestring(nick, true); //пишем nick //Отправляем игрокам with(objPlayer) { if(id != other.id) { sendmessage(socketid); } } break; case exitgame: //Если игрок вышел instance_destroy(); //Уничтожаем break; } } timeout += current_time - deltatime; deltatime = current_time; if(timeout > 8000)instance_destroy(); //if havnt received a message in 8 seconds then destroy Ставим в левый верхний угол обьект server и радуемся! =) Ура! Поздравляю вас! Вы создали свою первую ммо! Вопросы в тему Следующий туториал - создание авторизации через ini файлы!
Сообщение отредактировал Deswing - Воскресенье, 26 Декабря 2010, 15:34 |
|
| |
neksins | Дата: Воскресенье, 26 Декабря 2010, 13:58 | Сообщение # 2 |
постоянный участник
Сейчас нет на сайте
| Deswing, респект! прекрасные статьи
Мой проект по типу Guitar Hero ИГРА ВЫПУЩЕНА!
|
|
| |
zik13 | Дата: Воскресенье, 26 Декабря 2010, 13:59 | Сообщение # 3 |
Dark wolf
Сейчас нет на сайте
| FATAL ERROR in action number 1 of Create Event for object server: COMPILATION ERROR in code action Error in code at line 8: (-1 = no player)//Добавляем в playerlist ^ at position 13: Symbol ) expected.
|
|
| |
Deswing | Дата: Воскресенье, 26 Декабря 2010, 14:01 | Сообщение # 4 |
заслуженный участник
Сейчас нет на сайте
| neksins, огромное спасибо!) В будущем напишу статьи по созданию офф. сайта (php) и системы авторизации) Ну это в будущем, устал немного Добавлено (26.12.2010, 14:01) ---------------------------------------------
Quote (zik13) (-1 = no player) (пробел)//Добавляем в playerlist
|
|
| |
zik13 | Дата: Воскресенье, 26 Декабря 2010, 14:04 | Сообщение # 5 |
Dark wolf
Сейчас нет на сайте
| Quote (Deswing) (-1 = no player) (пробел)//Добавляем в playerlist не очень понял
|
|
| |
Angevengelist | Дата: Воскресенье, 26 Декабря 2010, 14:05 | Сообщение # 6 |
постоянный участник
Сейчас нет на сайте
| Deswing, может -1 просто в скобки взять (-1), // это комментарии из за них неможет быть ошибки
|
|
| |
Deswing | Дата: Воскресенье, 26 Декабря 2010, 14:07 | Сообщение # 7 |
заслуженный участник
Сейчас нет на сайте
| zik13, пробелма в Server, обьект server? Строка Code for(i = 0; i < 256; i += 1) { players[i] = -1; } как я понял?Добавлено (26.12.2010, 14:07) ---------------------------------------------
Quote (Angevengelist) это комментарии из за них неможет быть ошибки может быть, если компьютер посчитает что код - коментарий (зеленым будет)
|
|
| |
zik13 | Дата: Воскресенье, 26 Декабря 2010, 14:09 | Сообщение # 8 |
Dark wolf
Сейчас нет на сайте
| dllinit(0, true, true); listen = tcplisten(14804, 30, true); if(!listen) { error_message("Unable to create listen socket"); exit; } (-1= no player) for(i = 0; i < 256; i += 1) { players[i] = -1; } тут ошибка и еще player = tcpaccept(listen, 1); if(player) { playerid = newplayerid(); if(playerid < 0)exit; i = instance_create(0, 0, objPlayer); i.socketid = player; i.playerid = playerid; players[playerid] = i; setnagle(player, false); clearbuffer(); writebyte(newplayer); writebyte(playerid); writeshort(0); writeshort(0); writestring("", true); with(objPlayer) { if(id != other.i) { sendmessage(socketid); } } with(objPlayer) { if(id != other.i) { clearbuffer(); writebyte(newplayer); writebyte(playerid); writeshort(x); writeshort(y); writestring(nick, true); sendmessage(other.player); } } } тут
|
|
| |
IroNN | Дата: Воскресенье, 26 Декабря 2010, 14:09 | Сообщение # 9 |
постоянный участник
Сейчас нет на сайте
| Зачем по созданию офф сайта? Это лишнее. Все офф на укозе делают
пол года учил GML. GameMaker отказывается теперь работать на моем компе... Здравствуй Construct!
|
|
| |
Deswing | Дата: Воскресенье, 26 Декабря 2010, 14:10 | Сообщение # 10 |
заслуженный участник
Сейчас нет на сайте
| zik13, пардон, строку (-1= no player) убирай, это мой косяк
|
|
| |
|
Deswing | Дата: Воскресенье, 26 Декабря 2010, 14:14 | Сообщение # 12 |
заслуженный участник
Сейчас нет на сайте
| Quote (Juwell) Я после статей начал интересоватся Гейм Мейкером ХОЧУ ЕЩЕ СТАТЕЙ!!!! будут статьи, позже... Я просто болею и пишу статьи с трудом (только ради Gcup Написал ) Quote (Juwell) ЛОВИ ++++++ пасяб
|
|
| |
|
zik13 | Дата: Воскресенье, 26 Декабря 2010, 14:16 | Сообщение # 14 |
Dark wolf
Сейчас нет на сайте
| а че насчет ошибки
|
|
| |
Deswing | Дата: Воскресенье, 26 Декабря 2010, 14:18 | Сообщение # 15 |
заслуженный участник
Сейчас нет на сайте
| Quote (Juwell) В БЛИЖАЙШЕЕ ВРЕМЯ ММО ПОРАБОТЯТ МИР!!! не совсем... В серверах на GameMaker есть минус... Они не переносят больших нагрузок, просто не могут потянуть много... Максимум - 64 человек (и то, если ускорить скорость комнаты). Самое лучшее - написать на Си, но для меня это - темный лес Добавлено (26.12.2010, 14:18) ---------------------------------------------
Quote (zik13) а че насчет ошибки это косяк с переводом... Строку ту сносишь (то был коментарий, а я забыл убрать (забыл)) Пардон, если что Остальные переменные (например Mana) делайте по примеру image_angle
|
|
| |
zik13 | Дата: Воскресенье, 26 Декабря 2010, 14:19 | Сообщение # 16 |
Dark wolf
Сейчас нет на сайте
| я про это playerid = newplayerid();
|
|
| |
Deswing | Дата: Воскресенье, 26 Декабря 2010, 14:21 | Сообщение # 17 |
заслуженный участник
Сейчас нет на сайте
| Quote (zik13) playerid = newplayerid(); здесь все правильно, просто убери Quote (zik13) (-1= no player) и запусти
|
|
| |
zik13 | Дата: Воскресенье, 26 Декабря 2010, 14:21 | Сообщение # 18 |
Dark wolf
Сейчас нет на сайте
| FATAL ERROR in action number 1 of Step Event for object server: COMPILATION ERROR in code action Error in code at line 4: playerid = newplayerid() ^ at position 16: Unknown function or script: newplayerid
|
|
| |
Deswing | Дата: Воскресенье, 26 Декабря 2010, 14:24 | Сообщение # 19 |
заслуженный участник
Сейчас нет на сайте
| zik13, скриптов значит нет... Проект из архива второй раз разархивируй и делай) Содержимое скрипта: Code if(instance_number(objPlayer) > 256)return -1; //If more than 256 then return error for(i = 0; i < 256; i += 1) //loop through player list { if(players[i] == -1)return i; //if id is free the return it } return -1;
Сообщение отредактировал Deswing - Воскресенье, 26 Декабря 2010, 14:25 |
|
| |
BaHu3aTop | Дата: Воскресенье, 26 Декабря 2010, 14:27 | Сообщение # 20 |
постоянный участник
Сейчас нет на сайте
| ___________________________________________ ERROR in action number 1 of Alarm Event for alarm 0 for object objPlayer: Error in code at line 3: writebyte(playerid); //наш id ^ at position 12: Unknown variable playerid скрипт добавил
|
|
| |