burlachenko:
Молодец player очень доступно, (хотелось-бы что-бы все уроки так были расписаны).
Насчет подгрузки текстовых файлов тоже хочется посмотреть пример (в хозяйстве всё пригодится).
И еще вопрос: можно-ли загружать variables из папок, или они "намертво" должны сидеть в .cap файле?
Еще раз огромное спасибо Друг!
player:
Да всегда пжлста. Адд: Пример с загрузкой текстовиков.
TestText.rar
Rvl:
player может тебе урок "Как создать онлайн игру" сделать?
burlachenko:
Отличный пример, еще раз спасибо player, получается почти так-же как рисунками.
Скорее всего с музыкой и видео нужно работать таким-же способом (или нет?).
Rvl, для этого скорее всего нужно создать новую тему на форуме.
Rvl:
burlachenko я знаю
player:
Хотя, ., видео в костракте достаточно глючное и наверное лучше использовать какую нить стороннею библиотеку.
Насчет онлайн игр попробую описать как есть: опять же я еще пока в этом всем плохо разбираюсь, да и в силу нубства пишу достаточно кривой код, всетки не программист же.
Но попробую часть того, что мне более менее немного понятно, описать, авось кому то пригодиться.
В сети достаточно много библиотек на питоне, которые можно использовать для создания онлайна на Scirra. Самые годные, ., это PodSixNet и Mastermind.
Вообще основным условием для библиотеки является поддержка TCP или UDP протоколов, где TCP гарантирует доставку пакета юзеру + доставку в той последовательности в которой пакеты были отправлены. а UDP хоть и работает быстрее чем TCP но грубо говоря доставку не контролирует (т.е. например в UDP у каждого пакета должен быть ID который привязывает его к определенному клиенту ). Вообще в сети много статей на эту тему, на вики также есть инфа ( какие онлайн игры какие пакеты используют ), так что проще погуглить.
Что касаеться самих библиотек PodSixNet ., удобнее чем mastermind, в нем больше функций по умолчанию (защита от спама, работа с каждым подключенным клиентом в отдельности и со всеми вместе и пр. ) но он работает только через tcp + если верить гайду у него иногда возникают проблемы с Nat настройками. Попробую на нем что-то написать в ближайшем будущем, но ничего не обещаю.
Masstermind же хорош тем что держит сразу udp и tcp и работает достаточно быстро, по сравнению с PodSix. Но функционал спартанский – пакет принял/пакет отправил – ничего лишнего.
Гайд я писать не буду попробую просто немного расширенно ответить на вопрос про онлайн т.е. попробуем написать что нить простое на Mastermind, бегающие шарики, например. Потребуется python 2.6, Mastermind Net Lib и собственно сама Scirra.
Наверное будет проще если действия будут описаны пошагово:
Шаг 1:
Создаем новый проект в Scirra (DirectX игру) назовем его Client. В нем создаем три обькта два спрайта в виде кружков и TiledBackground – который будет выполнять роль почвы, проще говоря создаем платформер. Sprite1 – будет выполнять роль вашего персонажа (тоесть применим к нему все те свойства которые необходимы для создания персонажа в платформере), Sprite2 же, будет копироваться и размножаться и выполнять роль других игроков.
Шаг 2:
К слову немного о том как это работает (я еще нуб во всем этом поэтому прошу строго не судить): Клиент, написанный на Scirra отправляет при помощи Mastermind через TCP пакет серверу, состоящий из ID клиента в последовательности и координат игрока XY. На сервере же есть последовательность всех игроков, сервер этот пакет принимает и записывает координаты в серверную последовательность согласно ID. Последовательность выглядит примерно так :
[100, 200] [200, 300] [500, 600] и так далее, где
Свой ID клиент получает во время первого коннекта к серверу, id = (онлайн пользователей на данный момент + 1) также во время первого коннекта выполняется добавление одного элемента в конец последовательности на сервере, в этот элемент буду записываться координаты юзвера и происходит создание нужного количества спрайтов в клиенте = равного количеству пользователей подключенных к серверу (игроков).
Далее, получив пакет с координатами от пользователя и записав в последовательность на сервере, сервер сформирует обратный пакет – который будет из последовательности и состоять. Т.е. из координатов всех пользователей. Получив этот пакет клиент отрисует координаты всех спрайтов через массив. Конечно, данный способ мега нубский и любой из создателей серьезных онлайн игр/игр да и просто программист на питоне и нет, над ним посмеется, но это первый способ который пришел мне в голову при работе с mastermind (К тому же похожий способ используется по умолчанию в Mastermind примерах). Безусловно, еще нужно проверять данные, делать защиту, чтобы сервер не уронили и так далее, но это я пока описывать не буду (к тому же я толком и не умею).
Перейдем к делу, начнем создавать сервер, создадим просто текстовый файл для блокнота и назовем его Server. Заменим .txt, в конце на .py – тем самым создадим исполняемое приложение на питоне. Закинем папку Net с исходниками библиотеки Mastermind в папку к серверу и клиенту. В Server.py запишем следующий код:#!/usr/bin/python
# -*- coding: utf-8 -*-
print "--- Scirra Test ---"
import os,sys, re
sys.path.append(os.path.split(sys.path[0])[0])
from Net import *
class ServerHandler(TCPServer):
def __init__(self):
TCPServer.__init__(self)
self.senddata = ["0","0"]
def add_player(self, data1):
ffff = int(self.senddata[0])
ffff +=1
self.senddata[0] = ffff
self.senddata.append("0")
def add_position(self, data1):
Nomer = int(data1[1])
PlayerX = int(data1[2])
PlayerY = int(data1[3])
self.senddata[Nomer] = [PlayerX, PlayerY]
def handle_data(self, data1):
if data1[0] == "add_player":
self.add_player(data1)
elif data1[0] == "add_position":
self.add_position(data1)
self.send_data(self.senddata)
print self.senddata
def main():
serverlogin = ServerHandler()
serverlogin.connect("localhost",5121)
serverlogin.serve_forever()
serverlogin.quit()
if __name__ == '__main__': main()
Не буду полностью расписывать его работу, опишу немного поверхностно.
Первое что выполняется в приложении это импортируются нужные модули и Mastermind из папки Net. За это отвечает следующий код:import os,sys, re
sys.path.append(os.path.split(sys.path[0])[0])
from Net import *
Далее следует основной класс – код сервера: class ServerHandler(TCPSer.
self.senddata = ["0","0"] - это и есть наша основная последовательность, состоящая из онлайна и координат всех пользователей.
def handle_data - это основная функция, пакет ( далее Data1), приходя на сервер, попадает сюда. Он по сути тоже состоит из последовательности (Как она формируется в Scirra описано ниже в шаге 3): [Команда для сервера, ID клиента, КоординатыХ, КоординатыY], если клиент конектиться первый раз пакет выглядит так: [Команда для сервера – в нашем случае add_player, 0]
Происходит проверка если клиент конектиться первый раз - add_player (if data1[0] == "add_player") то data1 передается в функцию add_player и там обрабатывается: if data1[0] == "add_player":
self.add_player(data1)
Если же пришел пакет с координатами игрока (elif data1[0] == "add_position") то data1 передается в функцию add_position (self.add_position(data1. и там содержимое data1 – координаты - записывается в последовательность. elif data1[0] == "add_position":
self.add_position(data1)
команда - self.send_data(self.senddata) отправляет пакет пользователю, где self.senddata – конечный, сформированный пакет (последовательность).
print self.senddata - печатаем в cmd отправленные данные, контроль качества =D def add_player(self, data1):
ffff = int(self.senddata[0])
ffff +=1
self.senddata[0] = ffff
self.senddata.append("0")
ffff = int(self.senddata[0]) - необходимо для синтаксиса.
ffff +=1 - прибавляем пользователя онлайн
self.senddata[0] = ffff - записываем в последовательность на самую первую позицию
self.senddata.append("0") - добавляем в конец последовательнсоти элемент равный нулю, в дальнейшем будет заменен на координаты вновь пришедшего игрока. def add_position(self, data1):
Nomer = int(data1[1])
PlayerX = int(data1[2])
PlayerY = int(data1[3])
self.senddata[Nomer] = [PlayerX, PlayerY]
Получаем номер, координаты игрока по Х и Y - и записываем в последовательность.
В конце цикл… serverlogin.connect("localhost",5121) – сервер забенден на адрес localhost на 5121 порт, при желании можно поменять на свой IP.
Шаг 3:
Снова возвращаемся в Scirra:from Net import *
MainClient = TCPClient()
MainClient.connect("localhost",5121)
MainClient.send_data(["add_player", 0])
getData = MainClient.wait_for_data()
MoiNomer = getData[0]
PlayerOnlineFirst = 1
mojno = 0
NomerR.SetText("Ваш номер : " + str(MoiNomer.
from Net import * - Импортируем Mastermind
MainClient = TCPClient() – Оснавная переменная клиента + сообщаем mastermind что будем использовать tcp.
MainClient.connect("localhost",5121) – конектимся к адресу на который забенден сервер.
MainClient.send_data(["add_player", 0]) - отправляем первый пакет, добавляем игрока в последовательность.
getData = MainClient.wait_for_data() - ждем пакета с сервера.
MoiNomer = getData[0] – получаем свой ID в последовательности.
PlayerOnlineFirst = 1 – переменная для контроля количества спрайтов.
mojno = 0 - переменная для разрешения отрисовки координат, на тот случай если Scirra еще не успела создать спрайт а отрисовка координат уже пошла – иначе будет ошибка.
NomerR.SetText("Ваш номер : " + str(MoiNomer. – записываем в текстовый эелемент свой порядковый номер.SENDDATA = ["add_position", MoiNomer, Sprite1.X, Sprite1.Y]
MainClient.send_data(SENDDATA)
DataFromTheServer = MainClient.wait_for_data()
ProverkaOnline = DataFromTheServer[0]
if mojno == 1:
for drawz in range(1,PlayerOnlineFirst+1):
Sprite2[drawz-1].SetPosition(DataFromTheServer[drawz][0], DataFromTheServer[drawz][1])
SENDDATA = ["add_position", MoiNomer, Sprite1.X, Sprite1.Y] - формируем пакет из своего номера и координат.
MainClient.send_data(SENDDATA) - отправляем его.
DataFromTheServer = MainClient.wait_for_data()– ждем ответный пакет с сервера.
ProverkaOnline = DataFromTheServer[0] – получаем количесво игроков на сервере. Если количесво игроков на сервере больше > PlayerOnlineFirst – созданных спрайтов то создаем еще спрайтов:if ProverkaOnline > PlayerOnlineFirst:
mojno = 0
System.CreateByName("Sprite2", 1, 100,100)
PlayerOnlineFirst +=1
else:
mojno = 1
Отрисовываем координаты спрайтов: for drawz in range(1,PlayerOnlineFirst+1):
Sprite2[drawz-1].SetPosition(DataFromTheServer[drawz][0], DataFromTheServer[drawz][1])
Ну вот как то так, вообще должно получиться что то типа этого: Видео
Все что я пока успел написать на Mastermind здесь (Возможно пригодиться)
TestOnline.rar