Forum.iFiction.Ru

iFiction.Ru · ifHub · FAQ · IFWiki · QSP · URQ · INSTEAD · AXMA

форум об interactive fiction, текстовых приключенческих играх и всём таком...

Вы не зашли.

0    0    #1
25.12.2012 21:06

noname
Участник (+36, -9)
Зарегистрирован: 04.04.2008
Сообщений: 729

noname

Instead: вводный курс

эта тема предназначена для тех, кто уже установил свежую версию инстеад, уже играл в какие-то инстедовские игры, и по каким-то причинам заинтересовался созданием своей игры на этой платформе.

и убедитесь, что в вашем текстовом редакторе выставлена кодировка UTF-8.

сегодня я начал осваиваться с Instead, и.. освоился! и теперь я хочу поделиться опытом.

для начала рассмотрим простейший шаблон. этот шаблон нужно поместить в текстовый файл с расширением lua, а текстовый файл- в папку этого шаблона, аналогично тому, как другие инстедовские игры лежат каждая в своей папке:

Код:

--$Name: Мой эксперимент$
--$Version: 0.0$
instead_version "1.8.1";
---------------------------------------------------------------------------------------------------
main = room {
    nam = 'Название игры';
    dsc = [[ Описание игры.]];
}
---------------------------------------------------------------------------------------------------

как вы уже, наверное, догадались, знак -- означает комментарий. первые две строчки кода- тег названия и тег версии игры. их читает ланчер инстеда и соответственно им представляет игру в списке. конкретно это поделие будет отображено в списке под названием 'Мой эксперимент', а номер версии будет указан как '0.0'

третья строчка- версия инстеда, на которую расчитана эта игра. теоретически, если язык платформы претерпит какие-то изменения, то эта информация поможет обеспечить совместимость. т е ваша игра всё равно запустится.

дальше я сделал длинный коментарий, чтобы отделить 'шапку' игры от основной части. таким же комментарием я буду отделять различные игровые сцены(они же локации, они же- комнаты) друг от друга.

основная часть пока что состоит из описания всего одной только сцены. называется она main, и именно со сцены main начинается исполнение программ на инстеде. в описании сцены использованы следующие ключевые слова:

room - игровая сцена. в нашем случае описана игровая сцена main.

nam - название игровой сцены, которое будет выведено в верху. т е после запуска этой 'игры' вверху будет выведено 'Название игры'. в настоящей игре в этом месте можно было бы написать, например, 'Вступление' или название игры.

dsc - описание игровой сцены. то, что будет выведено под названием. описание тоже можно было написать в кавычках '', но для длинных описаний лучше использовать квадратные скобки [[]]. чтобы не морочить мозг, я просто буду всегда использовать скобки.

можно было бы вставить ещё и картинку. например, так:
pic = 'gfx/thecat.png';
тогда название выведется над картикой, а описание- под картинкой. в данном случае интерпретатор будет искать картинку thecat.png в подпапке gfx папки нашей игры.

ещё один тонкий момент: в конце строк я понавставлял точек с запятой ; на самом деле они не везде там нужны, но проще понаставить их везде, чем разбираться, где они нужны, а где нет. можно вместо точек с запятой использовать обычные запятые, но новичкам я это настоятельно НЕ рекомендую.

Отредактировано noname (25.12.2012 21:44)

Неактивен

0    0    #2
25.12.2012 21:27

noname
Участник (+36, -9)
Зарегистрирован: 04.04.2008
Сообщений: 729

noname

Re: Instead: вводный курс

следующий пример демонстрирует не совсем стандартную для инстеда вещь, а именно- обычную ссылку в тексте. вставим под описанием игры ссылку 'начать игру', по нажатию на которую игрок попадёт уже в саму игру:

Код:

--$Name: Мой эксперимент$
--$Version: 0.0$
instead_version "1.8.1";

require "xact"            -- подключаем модуль xact
---------------------------------------------------------------------------------------------------
main = room {
    nam = 'Название игры';
    dsc = [[ Описание игры.^^ {xwalk(room1)| Начать игру.}]];
}
---------------------------------------------------------------------------------------------------
room1 = room {
    nam = 'Первая комната';
    dsc = [[ Первая комната.]];
}
---------------------------------------------------------------------------------------------------

чтобы делать такие ссылки максимально просто и кратко, я подключил модуль xact, который как раз для этого(и другого подобного) и предназначен.

саму ссылку {xwalk(room1)| Начать игру.} можно было вставить в любом месте текста. значки ^^ перед ссылкой означают переводы строк. в нашем примере мы выводим описание игры, после- два перевода строк, после- выводим ссылку начать игру, по нажатию которой игрок попадёт в сцену room1. думаю, тут всё достаточно просто и ясно. и, да- xwalk- это служебное слово, с помощью которого делаются такие штуки.

сцена room1- обычная простейшая сцена. создана подобно тому, как создавалась сцена main в предыдущем примере.

Неактивен

0    0    #3
25.12.2012 21:42

noname
Участник (+36, -9)
Зарегистрирован: 04.04.2008
Сообщений: 729

noname

Re: Instead: вводный курс

добавим в пример ещё одну комнату, чтобы из первой комнаты можно было переходить во вторую и обратно:

Код:

--$Name: Мой эксперимент$
--$Version: 0.0$
instead_version "1.8.1";

require "xact"            -- подключаем модуль xact
---------------------------------------------------------------------------------------------------
main = room {
    nam = 'Название игры';
    dsc = [[ Описание игры.^^ {xwalk(room1)| Начать игру.}]];
}
---------------------------------------------------------------------------------------------------
room1 = room {
    nam = 'Первая комната';
    dsc = [[ Первая комната.]];
     way = {
        'room2';
    };
}
---------------------------------------------------------------------------------------------------
room2 = room {
    nam = 'Вторая комната';
    dsc = [[Вторая комната.]];
     way = {
        'room1';
    };
}
---------------------------------------------------------------------------------------------------

на этот раз переходы между комнатами я описал стандартным для инстеда способом. если надо сделать много выходов, то они перечисляются через запятую. вот так:
way ={
  'room1',
  'room2',
  'room3',
  'roomN'
};

если есть картинка, то название сцены будет над картинкой, выходы будут сразу под картинкой, а ниже будет описание сцены.

Неактивен

0    0    #4
25.12.2012 22:11

noname
Участник (+36, -9)
Зарегистрирован: 04.04.2008
Сообщений: 729

noname

Re: Instead: вводный курс

добавим в первую комнату объектов:

Код:

--$Name: Мой эксперимент$
--$Version: 0.0$
instead_version "1.8.1";

require "xact"            -- подключаем модуль xact

-- если для объекта не прописана реакция, то реагировать будем так:
game.act = "Ничего не произошло.";     -- если нажали на объект на сцене
game.inv = "И откуда это у меня?";     -- если применили объект из инвентаря сам на себя
game.use = "Так не пойдёт.";        -- если применили объект на другой объект
---------------------------------------------------------------------------------------------------
main = room {
    nam = 'Название игры';
    dsc = [[ Описание игры.^^ {xwalk(room1)| Начать игру.}]];
}
---------------------------------------------------------------------------------------------------
room1 = room {
    nam = 'Первая комната';
    dsc = [[ Первая комната.]];
    obj = {
        'table','box';
    };
     way = {
        'room2';
    };
}

table = obj {
    nam = 'стол';
    dsc = 'В комнате стоит {стол}.';
    act = 'Гм... Просто стол...';
}

box = obj {
    nam = 'шкатулка';
    dsc = 'На столе стоит {шкатулка}.';
    tak = 'Интересная штуковина.';
}
---------------------------------------------------------------------------------------------------
room2 = room {
    nam = 'Вторая комната';
    dsc = [[Вторая комната.]];
     way = {
        'room1';
    };
}
---------------------------------------------------------------------------------------------------

в конце 'шапки' игры, до описания сцены main, я прописал реакцию на не предусмотренные действия пользователя. это нужно, чтобы наша игра никогда не оставляла действия игрока без ответа.

в основном тексте программы я описал объекты table и box. это - стол и шкатулка, соответственно. описываются они почти так же как и комнаты, только ключевое слово не room, а obj. ну, ещё для стола прописано действие act, которое будет выполняться при нажатии на стол. а для шкатулки действие act не прописано, зато прописано действие tak. а это означает, что нажав на шкатулку, игрок заберёт её в свой инвентарь. после этого игрок может попробовать применить шкатулку из инвентаря на саму себя или на стол, но эти действия пока не прописаны, и в ответ будут выданы сообщения, которые я поместил в конце 'шапки' игры, до описания сцены main.

НО мало описать объекты, надо ещё указать, где они находятся. поэтому в описании комнаты room1 я добавил список объектов. он задаётся почти так же как список выходов, только вместо way используется ключевое слово obj:
    obj = {
        'table','box';
    };

После описания первой комнаты будет выведено по-очереди описание каждого из объектов в комнате. Обратите внимание, что и в описании стола и в описании шкатулки часть текста взята в фигурные скобки {} именно эта часть текста и будет той ссылкой, с которой сможет взаимодействовать игрок.

Неактивен

0    0    #5
25.12.2012 22:24

noname
Участник (+36, -9)
Зарегистрирован: 04.04.2008
Сообщений: 729

noname

Re: Instead: вводный курс

Вы могли заметить, что когда игрок, находясь в комнате, выполняет какие-то действия(трогает предметы), то описание комнаты не выводится каждый раз. каждый раз будет выводиться только описание объектов в комнате. обычно этого должно быть вполне достаточно, так как обстановка в комнате как раз и составляется из описаний объектов. но можно сделать и такое описание, которое не будет пропадать.

я добавил во вторую комнату бесполезную пока дверь, и улицу, на которую можно выйти из второй комнаты и зайти обратно. в нашем простом примере на улице нет никаких объектов, и поэтому я описал улицу как xroom и добавил xdsc- это именно то описание, которое не будет пропадать:

Код:

--$Name: Мой эксперимент$
--$Version: 0.0$
instead_version "1.8.1";

require "xact"            -- подключаем модуль xact

-- если для объекта не прописана реакция, то реагировать будем так:
game.act = "Ничего не произошло.";     -- если нажали на объект на сцене
game.inv = "И откуда это у меня?";     -- если применили объект из инвентаря сам на себя
game.use = "Так не пойдёт.";        -- если применили объект на другой объект
---------------------------------------------------------------------------------------------------
main = room {
    nam = 'Название игры';
    dsc = [[ Описание игры.^^ {xwalk(room1)| Начать игру.}]];
}
---------------------------------------------------------------------------------------------------
room1 = room {
    nam = 'Первая комната';
    dsc = [[ Первая комната.]];
    obj = {
        'table','box';
    };
     way = {
        'room2';
    };
}

table = obj {
    nam = 'стол';
    dsc = 'В комнате стоит {стол}.';
    act = 'Гм... Просто стол...';
}

box = obj {
    nam = 'шкатулка';
    dsc = 'На столе стоит {шкатулка}.';
    tak = 'Интересная штуковина.';
}
---------------------------------------------------------------------------------------------------
room2 = room {
    nam = 'Вторая комната';
    dsc = [[Вторая комната.]];
    obj = {
        'door';
    };
     way = {
        'room1', 'street';
    };
}

door = obj {
    nam = 'дверь';
    dsc = 'В этой комнате есть {дверь} на улицу.';
}
---------------------------------------------------------------------------------------------------
street = xroom {
    nam = 'На улице.';
    dsc = [[ Вы на улице.]];
    xdsc = [[Та часть описания, которая не пропадает.]];
     way = {
        'room2';
    };
}
---------------------------------------------------------------------------------------------------

Отредактировано noname (25.12.2012 22:30)

Неактивен

0    0    #6
26.12.2012 14:20

noname
Участник (+36, -9)
Зарегистрирован: 04.04.2008
Сообщений: 729

noname

Re: Instead: вводный курс

а теперь переходим  к самому интересному- к действиям с объектами. я добавил в игру ключ и прописал различные реакции на действия над объектами:

Код:

--$Name: Мой эксперимент$
--$Version: 0.0$
instead_version "1.8.1";

require "xact"            -- подключаем модуль xact

-- если для объекта не прописана реакция, то реагировать будем так:
game.act = "Ничего не произошло.";     -- если нажали на объект на сцене
game.inv = "И откуда это у меня?";     -- если применили объект из инвентаря сам на себя
game.use = "Так не пойдёт.";        -- если применили объект на другой объект
---------------------------------------------------------------------------------------------------
main = room {
    nam = 'Название игры';
    dsc = [[ Описание игры.^^ {xwalk(room1)| Начать игру.}]];
}
---------------------------------------------------------------------------------------------------
room1 = room {
    nam = 'Первая комната';
    dsc = [[ Первая комната.]];
    obj = {
        'table','box';
    };
     way = {
        'room2';
    };
}

table = obj {
    nam = 'стол';
    dsc = 'В комнате стоит {стол}.';
    act = 'Гм... Просто стол...';
}

box = obj {
    _empty = false;
    nam = 'шкатулка';
    dsc = 'На столе стоит {шкатулка}.';
    tak = 'Интересная штуковина.';
    inv = function(s)
        if s._empty then 
            p'В шкатулке больше ничего нет.';
        else
            p'Вы достали из шкатулки ключ.';
            take 'key';
            s._empty = true;
        end;
    end;
    use = function(s,w)
        if w == table then
            remove(box,me()); -- убираем шкатулку из игрока
            put(box,room1); -- помещаем шкатулку в room1
            p'Вы положили шкатулку обратно на стол';
        end;
    end;
}

key = obj {
    nam = 'ключ';
    tak = 'Вы достали из шкатулки ключ.';
    inv = 'Похож на ключ от двери.';
    use = function(s,w)
        if w == door and door._locked then
            door._locked = false;
            p'Вы отперли дверь ключом';
        elseif w == door then
            door._locked = true;
            p'Вы заперли дверь ключом';
        end;
    end;
}

---------------------------------------------------------------------------------------------------
room2 = room {
    nam = 'Вторая комната';
    dsc = [[Вторая комната.]];
    obj = {
        'door';
    };
     way = {
        'room1', 'street';
    };
}

door = obj {
    _locked = true;
    nam = 'дверь';
    dsc = 'В этой комнате есть {дверь} на улицу.';
    act = function(s)
        if s._locked then
            p'Дверь заперта';
        else
            p'Дверь не заперта';
        end;
    end;
}
---------------------------------------------------------------------------------------------------
street = xroom {
    nam = 'На улице.';
    dsc = [[ Вы на улице.]];
    xdsc = [[Та часть описания, которая не пропадает.]];
     way = {
        'room2';
    };
}
---------------------------------------------------------------------------------------------------

что тут нового?

в описании шкатулки:

-- описано свойство _empty = false; по-сути, это обычная переменная(в данном случае- булевская). начинается с подчёркивания- значит будет сохраняться при сохранении игры. обращаться в дальнейшем к ней можно как к box._empty - потому что она была описана в шкатулке.

-- после inv описывается реакция на применение предмета инвентаря сам на себя. НО на этот раз вместо inv='текст'; я написал inv=function(s) потому что хочу не просто выводить текст, а выполнять какие-то проверки и действия. единственный параметр функции- s, это сам объект(в шкатулке это box).

-- команда take 'объект' помещает объект в инвентарь. в данном случае мы помещаем в инвентарь ключ.

-- после use описывается реакция на применение этого объекта на другой объект. здесь я тоже использую функцию: use=function(s,w) первый параметр- наш объект, который используем, второй параметр- то, на что игрок наш объект применил. в данном случае я проверяю только, не применил ли игрок шкатулку на стол. и если да, то удаляю шкатулку из инвентаря игрока(текущий игрок это me) и кладу его на сцену room1.

ну и дальше всё должно быть уже понятно. правда, от двери в нашем примере мало толку, но этому я посвящу следующий пример.

upd: мне подсказали, что вместо

Код:

            remove(box,me()); -- убираем шкатулку из игрока
            put(box,room1); -- помещаем шкатулку в room1

можно использовать всего одну команду drop(s);

разберём её подробнее: команда drop 'роняет' предмет из инвентаря в текущую сцену. если нужно уронить в другу сцену, то пишем drop(s,куда). если нужно уронить другой предмет, то пишем drop(предмет, куда).

я код выше исправлять пока не стал- пусть будет. это даже хорошо, что в этом уроке мы рассмотрели столько разных функций. в следующем примере этот момент будет исправлен.

Отредактировано noname (26.12.2012 14:38)

Неактивен

0    0    #7
26.12.2012 15:51

noname
Участник (+36, -9)
Зарегистрирован: 04.04.2008
Сообщений: 729

noname

Re: Instead: вводный курс

В этом примере я не только допилил дверь, чтобы она препятствовала выходу на улицу(когда заперта), но и добавил третью комнату, с окном. Во-первых, комната с окном демонстрирует другой способ организации запирающихся переходов, а во-вторых, можно вылезти в окно и проверить с улицы, заперта ли дверь:

Код:

--$Name: Мой эксперимент$
--$Version: 0.0$
instead_version "1.8.1";

require "xact"            -- подключаем модуль xact

-- если для объекта не прописана реакция, то реагировать будем так:
game.act = "Ничего не произошло.";     -- если нажали на объект на сцене
game.inv = "И откуда это у меня?";     -- если применили объект из инвентаря сам на себя
game.use = "Так не пойдёт.";        -- если применили объект на другой объект
---------------------------------------------------------------------------------------------------
main = room {
    nam = 'Название игры';
    dsc = [[ Описание игры.^^ {xwalk(room1)| Начать игру.}]];
}
---------------------------------------------------------------------------------------------------
room1 = room {
    nam = 'Первая комната';
    dsc = [[ Первая комната.]];
    obj = {
        'table','box';
    };
     way = {
        'room2','room3';
    };
}

table = obj {
    nam = 'стол';
    dsc = 'В комнате стоит {стол}.';
    act = 'Гм... Просто стол...';
}

box = obj {
    _empty = false;
    nam = 'шкатулка';
    dsc = 'На столе стоит {шкатулка}.';
    tak = 'Интересная штуковина.';
    inv = function(s)
        if s._empty then 
            p'В шкатулке больше ничего нет.';
        else
            p'Вы достали из шкатулки ключ.';
            take 'key';
            s._empty = true;
        end;
    end;
    use = function(s,w)
        if w == table then
            drop(s); -- выкладываем в текущую комнату
            p'Вы положили шкатулку обратно на стол.';
        end;
    end;
}

key = obj {
    nam = 'ключ';
    tak = 'Вы достали из шкатулки ключ.';
    inv = 'Похож на ключ от двери.';
    use = function(s,w)
        if w == door and door._locked then
            door._locked = false;
            p'Вы отперли дверь ключом.';
        elseif w == door then
            door._locked = true;
            p'Вы заперли дверь ключом.';
        elseif w == box then
            box._empty = false;
            remove(s,me());
            p'Вы спрятали ключ обратно в коробку.';    
        end;
    end;
}
---------------------------------------------------------------------------------------------------
room2 = room {
    nam = 'Вторая комната';
    dsc = [[Вторая комната.]];
    obj = {
        'door';
    };
     way = {
        'room1', 'street';
    };
    exit = function(s,w)
        if w== street and door._locked then
            p'Запертая дверь на даёт Вам выйти.';
            return false;
        end;
    end;
}

door = obj {
    _locked = true;
    nam = 'дверь';
    dsc = 'В этой комнате есть {дверь} на улицу.';
    act = function(s)
        if s._locked then
            p'Дверь заперта.';
        else
            p'Дверь не заперта.';
        end;
    end;
}
---------------------------------------------------------------------------------------------------
room3 = room {
    nam = 'Третья комната';
    dsc = [[Третья комната.]];
    obj = {
        'window';
    };
     way = {
        'room1', 'to_street';
    };
}

window = obj {
    _closed = true;
    nam = 'окно';
    dsc = 'В этой комнате есть большое {окно}.';
    act = function(s)
        if s._closed then
            s._closed = false;
            to_street:enable();
            p'Вы открыли окно.';
        else
            s._closed = true;
            to_street:disable();
            p'Вы закрыли окно.';
        end;
    end;
}

to_street = vroom('вылезти в окно', 'street'):disable();
---------------------------------------------------------------------------------------------------
street = xroom {
    nam = 'На улице';
    dsc = [[ Вы на улице.]];
    xdsc = [[Та часть описания, которая не пропадает.]];
     way = {
        'room2';
    };
    enter = function(s,w)
        if w== room3 then
            p'Вы спрыгнули вниз, на улицу.';
        end;
    end;
    exit = function(s,w)
        if w== room2 and door._locked then
            p'Запертая дверь не даёт Вам войти.';
            return false;
        end;
    end;
}
---------------------------------------------------------------------------------------------------

что тут нового:

в сценах room2 и street появились функции exit. они выполняются каждый раз, когда игрок покидает сцену. второй параметр указывает, куда игрок уходит. НО если возвращать false, то игрок не покинет комнату(по умолчанию возвращается true). именно через exit в этом примере и блокируется возможность войти/выйти через дверь.

в сцене street так же добавлена функция enter, которая аналогична exit, но выполняется, когда мы входим в эту сцену.

ну, c окном, надеюсь, вы разберётесь самостоятельно.

Отредактировано noname (26.12.2012 16:02)

Неактивен

0    0    #8
24.02.2016 17:37

n27i
Участник (+6, -1)
Откуда: Ахтырка
Зарегистрирован: 24.02.2016
Сообщений: 6

Re: Instead: вводный курс

Здраствуйте noname,
Блогарю вас, за такой экскурс к освоению создания, своих проэктов под программу Instead.

Отредактировано n27i (13.01.2018 00:49)

Неактивен

Powered by PunBB
© copyright 2001–2019 iFiction.Ru