danilaxxl danilaxxl

CollectableItemData.cs

[CreateMenuItem(fileName = "newItem", menuName = "Data/Items/Collectable", order = 51]

GoloGames GoloGames

vadya_ivan, рад, что вам игра показалась интересной : )

P.S. Кстати уже доступна бесплатная демо-версия в Steam

vadya_ivan vadya_ivan

Визуал, задумка, музыка , механики, все в цель

GoloGames GoloGames

Ato_Ome, спасибо за позитивные эмоции, будем стараться : )

Ato_Ome Ato_Ome

Потрясающий результат, все так четенько, плавненько)
То ли саунд, то ли плавность напомнили мне игрушку World of Goo, удачи вам в разработке и сил побольше дойти до релиза!)

Cute Fox Cute Fox

Graphics are a little cool, good HD content. But this game doesn't cause nary interest me.
However the game is well done.

GMSD3D GMSD3D

Почему действие после всех условий выполняется?
[step another object]

Zemlaynin Zemlaynin

Jusper, Везде, но наугад строить смысла нет. Нужно разведать сперва территорию на наличие ресурсов.

Jusper Jusper

Zemlaynin, а карьеры можно будет везде запихать?
Или под них "особые" зоны будут?

Zemlaynin Zemlaynin

Это так скажем тестовое строительство, а так да у города будет зона влияния которую нужно будет расширять.

Jusper Jusper

А ссылка есть?

Jusper Jusper

Я не оч понял из скриншота, как вообще работает стройка. У игрока будет как бы поле строительства?

split97 split97

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

split97 split97

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

ViktorJaguar ViktorJaguar

Почему я нигде не могу найти нормальный туториал, где покажут как экипировать предмет (например, меч) в определенную (выделенную под оружие) ячейку???

Логотип проекта Прочие движки

Текстовый редактор [LOVE]

Текстовый редактор [LOVE] — Прочие движки — DevTribe: инди-игры, разработка, сообщество

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

В общем к делу господа.

Подготовка
=

Для начала я предлагаю тебе не садиться писать код, а воссоздать небольшую иерархию проекта. Для начала создай в любом месте папку проекта,
внутри которой подготовь такие папки как:

  • lua
  • Text
  • ui

А внутри ui ещё одну папку fonts В которую скинь шрифт (любой), но если что, то вот, держи Pixel Font

Также в папку ui Кинем текстуру кнопки, которую лучше взять здесь

Идём далее. Создадим в корневой папке проекта наши любимые файлы main.lua и conf.lua, а в папке lua создадим файл ui.lua

Кстати, может кому это будет интересно ( Огромное спасибо человеку Андреич за этот фрагмент кода )

Создадим в корневой папке текстовый файл (с любым названием) !!Предварительно в настройках папок нужно снять галочку с "скрывать расширения для зарезервированных типов" или как-то так

И пишем туда вот этот кусочек отборного кода для 64-х разрядной системы:

@ECHO OFF
start "" "%PROGRAMFILES%\LOVE\love" .

Для 32-х (86-х) разрядной системы:

@ECHO OFF
start "" "%PROGRAMFILES(x86)%\LOVE\love"  .

Далее меняем расширения с .txt на .bat

Профит

Также предлагаю создать в папке Text текстовый файл с любым названием. Из этого файла, в этой части статьи, мы будем подгружать имена персонажей с их репликами.

Теперь к коду перейдём.

Код
=

Итак, давай начнём пока что с конфига ( conf.lua) и далее уже приступим писать разные крутые штуки. Можешь написать всё сам, а можешь взять конфигурацию с сайта или от сюда:

 function love.conf(t)
    t.identity = nil                    -- The name of the save directory (string)
    t.version = "0.10.1"                -- The LÖVE version this game was made for (string)
    t.console = false                   -- Attach a console (boolean, Windows only)
    t.accelerometerjoystick = true      -- Enable the accelerometer on iOS and Android by exposing it as a Joystick (boolean)
    t.externalstorage = false           -- True to save files (and read from the save directory) in external storage on Android (boolean) 
    t.gammacorrect = false              -- Enable gamma-correct rendering, when supported by the system (boolean)
 
    t.window.title = "Quest"         -- The window title (string)
    t.window.icon = nil                 -- Filepath to an image to use as the window's icon (string)
    t.window.width = 1280                -- The window width (number)
    t.window.height = 920               -- The window height (number)
    t.window.borderless = false         -- Remove all border visuals from the window (boolean)
    t.window.resizable = true          -- Let the window be user-resizable (boolean)
    t.window.minwidth = 1               -- Minimum window width if the window is resizable (number)
    t.window.minheight = 1              -- Minimum window height if the window is resizable (number)
    t.window.fullscreen = false         -- Enable fullscreen (boolean)
    t.window.fullscreentype = "desktop" -- Choose between "desktop" fullscreen or "exclusive" fullscreen mode (string)
    t.window.vsync = false               -- Enable vertical sync (boolean)
    t.window.msaa = 0                   -- The number of samples to use with multi-sampled antialiasing (number)
    t.window.display = 1                -- Index of the monitor to show the window in (number)
    t.window.highdpi = false            -- Enable high-dpi mode for the window on a Retina display (boolean)
    t.window.x = nil                    -- The x-coordinate of the window's position in the specified display (number)
    t.window.y = nil                    -- The y-coordinate of the window's position in the specified display (number)
 
    t.modules.audio = true              -- Enable the audio module (boolean)
    t.modules.event = true              -- Enable the event module (boolean)
    t.modules.graphics = true           -- Enable the graphics module (boolean)
    t.modules.image = true              -- Enable the image module (boolean)
    t.modules.joystick = true           -- Enable the joystick module (boolean)
    t.modules.keyboard = true           -- Enable the keyboard module (boolean)
    t.modules.math = true               -- Enable the math module (boolean)
    t.modules.mouse = true              -- Enable the mouse module (boolean)
    t.modules.physics = true            -- Enable the physics module (boolean)
    t.modules.sound = true              -- Enable the sound module (boolean)
    t.modules.system = true             -- Enable the system module (boolean)
    t.modules.timer = true              -- Enable the timer module (boolean), Disabling it will result 0 delta time in love.update
    t.modules.touch = false              -- Enable the touch module (boolean)
    t.modules.video = true              -- Enable the video module (boolean)
    t.modules.window = true             -- Enable the window module (boolean)
    t.modules.thread = true             -- Enable the thread module (boolean)
end

Правки я внёс лишь в название файла, в отключение вертикальной синхронизации и всё на этом.

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

Воть:

font = {};
button = {};


function Button(name, img, nameFont, pathFont, sizeFont, x, y, scaleX, scaleY, r, g, b)


font[nameFont] = love.graphics.newFont(pathFont, sizeFont);    
font[nameFont]:setFilter("nearest","nearest");

buttonImg:setFilter("nearest","nearest");
    

local text = love.graphics.newText(font[nameFont], name);


    
love.graphics.setColor(r, g, b);
button[name] = love.graphics.draw(img, x, y,0,scaleX,scaleY,0,0);

love.graphics.setColor(0,0,0);
love.graphics.draw(text, x + img:getWidth() - text:getWidth() / 4 + scaleX * 12 - string.len(name) * 2, y + img:getHeight(), 0, 1, 1, 0, 0);

    
    
end

function Text(title, nameFont, pathFont, sizeFont, x, y, r, g, b, a)
   
font[nameFont] = love.graphics.newFont(pathFont, sizeFont);    
font[nameFont]:setFilter("nearest","nearest");
    
local text = love.graphics.newText(font[nameFont], title);

love.graphics.setColor(r, g, b, a);
love.graphics.draw(text, x, y, 0, 1, 1, -1, 0,0,0);
    
end

Этот код из файла ui.lua. Немного подробнее о нём. Здесь мы можем наблюдать пока две функции (на момент написания статьи). Это Button и Text.
Думаю итак понятно что, за что отвечает. В Button мы подгружаем стандартную текстурку кнопки, а также создаём текст по центру кнопки. Всё это указывается в параметрах кнопки, то есть при вызове функции, поэтому сейчас мы переходим в main.lua и пишем основу там.

Для начала объявим начальные переменные:

dofile("lua/ui.lua");
dofile("lua/logic.lua");

resolutionX = 0;
resolutionY = 0;

widthWindow = 0;
heightWindow = 0;

fontPath = "ui/fonts/3572.ttf";

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

Далее первые три функции:

function love.load()

resolutionX, resolutionY = love.window.getMode();

 findFile("Text/words.txt");
 readFile();
    
end

function love.resize(width, height)
   
    resolutionX = width;
    resolutionY = height;
end

function love.update(frame)
    
    widthWindow = resolutionX / 2;
    heightWindow = resolutionY / 3;
end

В love.load() мы передаём начальные размеры игрового окна в переменные. В love.resize() мы передаём новые размеры окна, если они были изменены, тем самым все элементы, которые будут на экране, смогут подстраиваться. В love.update() мы задаём размеры диалогового окна. Именно там, потому что размеры окна пользователь может изменить.

Далее остальное:

unction love.draw()
    
    
    --BACKGROUND
    love.graphics.setBackgroundColor(0,0,0);
    
  -- WINDOW DIALOG
------------------------------------------    
     love.graphics.setColor(55,100,115); -- COLOR WINDOW BACKGROUND
     love.graphics.rectangle("fill", (resolutionX / 2) - widthWindow / 2 , resolutionY  - heightWindow / 2, widthWindow, heightWindow / 2);
    
     love.graphics.setColor(255,255,255);
     love.graphics.rectangle("line", (resolutionX / 2) - widthWindow / 2 , resolutionY  - heightWindow / 2, widthWindow, heightWindow / 2);
    
-------------------------------------------
    
    
  --MAIN TEXT
    
  Text(name[id] .. ": " .. string.sub(phrases[id], count),"Main",fontPath,20,resolutionX / 2, resolutionY / 2, 255,255,255,255);
    

    
    
end

function love.keyreleased(button)
   
    if button == "escape" then love.event.quit(); end
    
    if button == "space" and id < table.getn(phrases) then id = id + 1;  readFile(); end
end

В love.draw() Задаю фон, рисую диалоговое окно, далее вывожу текст, подгружаемый из файла,
который в свою очередь подгружается из файла logic.lua
В love.keyreleased() я реализовал выход по нажатию на Escape и смену текста по нажатию на Space.
И последний файл logic.lua

phrases = {};

id = 1;

file = nil;

path = "";

iterator = 0;

name = {};


function findFile(pathFile)
    
    path = pathFile
   
    file = love.filesystem.newFile(path);
    
    
     
end

function readFile()
    
    iterator = love.filesystem.lines(path);
    
    count = 0;
    
    for text  in iterator do
    
    table.insert(phrases, text);
    
    count = string.find(phrases[id]," ");    
        
    name[id] = string.sub(phrases[id],1, count - 1);
    
        
    end    
    
end

В нём я храню реплики героев, файл, путь к файлу и имена героев. Далее в функции findFile я нахожу файл. Саму функцию вызываю в love.load (смотрим выше)

В функции readFile я пихаю по таблицам текст и имена героев. НО.

Как же сделал вот так:

Текстовый редактор [LOVE] — Прочие движки — DevTribe: инди-игры, разработка, сообщество

С помощью таких функций как string.find, string.sub. В самом же текстовом файле, у меня содержится следующая информация:

Текстовый редактор [LOVE] — Прочие движки — DevTribe: инди-игры, разработка, сообщество

Хочу заметить что имена "Pit" и "Mary" хранятся в отдельной таблице. В функции readFile я нахожу индекс самого первого пробела и до него - 1 беру имя, где - 1 - это вычитания единицы от индекса, чтобы не было пробела между именем и двоеточия ":". Основной же текст грузится после этого индекса. Тем самым мы и получаем

  • "Pit: Hello!"
  • "Mary: Hi!"

Нет, серьёзно, вот же:

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

Первый акт закончен, господа, расходимся на перерыв в месяц, снова.

Смотрите также:


Комментарии



Трудно разобраться, в каком виде всё-таки хранятся диалоги?

Anton Riot, В обычном текстовом файле. Но стоит понимать, что это простая система, поэтому всё так банально

DasBro:

Anton Riot, В обычном текстовом файле. Но стоит понимать, что это простая система, поэтому всё так банально

Понятно что в текстовом, я имею ввиду в какой структуре? Как хранится дерево (или это граф?) диалога? Или там конечный автомат состояний?

Anton Riot, Граф

На яве в 40 строк делается

Справка