Перейти к содержимому

Zer0Galaxy

Гуру
  • Публикации

    1 220
  • Зарегистрирован

  • Посещение

  • Победитель дней

    189

Сообщения, опубликованные пользователем Zer0Galaxy


  1. Ещë можно написать GUI-шную прогу, для просмотра подключенных компонентов и их методов.

     

     

    local forms=require("forms")
    local gpu=require("component").gpu
    local component = require("component")
    
    local WinW, WinH = 80,25
    gpu.setResolution(WinW,WinH)
    
    mainForm=forms.addForm()
    
    function lstCompsonChange(self,line,item)
      lstMembers:clear()
      local proxy = component.proxy(item)
      if proxy then
        for name, member in pairs(proxy) do
          lstMembers:insert(name,member)
        end  
      end
      lblAddr.caption=item
      lblAddr:redraw()
      lstMembersonChange(lstMembers,lstMembers.lines[1],lstMembers.items[1])
    end
    
    function lstMembersonChange(self,line,item)
      if type(item)=="number" then
        lblDescript.caption='number: '..item
      elseif type(item)=="string" then
        lblDescript.caption='string: "'..item..'"'
      else
        lblDescript.caption=tostring(item)
      end
      lblDescript:redraw()
    end
    
    lstComps=mainForm:addList(1,1,lstCompsonChange)
    lstComps.W=WinW / 2
    lstComps.H=15
    lstComps:addLabel(3,1,"Components")
    
    lstMembers=mainForm:addList(41,1,lstMembersonChange)
    lstMembers.W=lstComps.W
    lstMembers.H=lstComps.H
    lstMembers:addLabel(3,1,"Members")
    
    lblAddr=mainForm:addLabel(1,lstComps.H+1)
    
    lblDescript=mainForm:addLabel(1,lblAddr.top+1)
    lblDescript.autoSize=false
    lblDescript.W=WinW
    lblDescript.H=WinH-lblDescript.top-1
    
    btnExit=mainForm:addButton(WinW-10,WinH,"Exit",forms.stop)
    
    lstComps:clear()
    for address, name in component.list() do lstComps:insert(name,address) end
    lstCompsonChange(lstComps,lstComps.lines[1],lstComps.items[1])
    
    forms.run(mainForm)
    require("term").clear() 

    Для запуска требуется библиотека forms

     

     


  2. function hook()

         coroutine.yield()

    end

     

    debug.sethook(hook, 100)

     

    Каждые 100 инструкции будет вызываться coroutine.yield. в OC таким образом реализована защита от while true do и большой нагрузки цп.

    Попытался выполнить такой код:

    function hook(ev,linenum)
      linenum=linenum or ""
      io.write(ev.." "..linenum.." ")
    end
     
    debug.sethook(hook,"l",100)
    
    for i=1,100 do
      io.write(i.." ")
    end
    

    Думал, хук будет хукать на каждые сто строк, т.е. пару раз за сто итераций цикла for. А не тут то было, на каждую строку хукает. Что не так делаю?


  3.  

     

    Конечно можно написать сервер и на самом love2d, но скорость будет хромать. love2d не предназначен для высоконагруженных серверов, это фреймворк для 2д игр.

     

    Там Box2D юзается для физики. Либа написана на C++, но можно воткнуть куда угодно практически (потому что врапперов к ней море). Так что если знаком с каким-нибудь языком более подходящим для бекэнда, стоит его рассмотреть как вариант
    Может ли кто подробно расписать реализацию  луа-скриптов из под С++ или какого то другого языка? Я одно время пытался этим заняться, но потом забросил.

  4.  

     

    Нужно в первую очередь определиться с целью обмена. А некоторых случаях нужно использовать UDP, в некоторых TCP.
    Обмен будет осуществляться как то так: Клиент отправляет команду с параметрами, сервер ее исполняет и возвращает результат.

    Например: 

    Клиент:  "залогиниться <username> <password>"
    Сервер: "Ok"
    Клиент: "получи_новый_скрипт <skript_name> while true do end"
    Сервер: "Ok"
    Клиент: "выполни_скрипт <skript_name>"
    Сервер: "Error: Too long without yielding"

    Ориентируюсь на TCP, т.к. более надежен. Об одновременном использовании обоих протоколов в пределах одной программы не думал.

     

     

     

    Насчет луа-скриптов от игроков: исполнять их в любом случае надо на сервере. Пока неизвестно на чем будет написан сервер нельзя точно сказать как прервать блокирование такого потока, ограничение по ресурсам и прочие хитрости. Конечно можно написать сервер и на самом love2d, но скорость будет хромать. love2d не предназначен для высоконагруженных серверов, это фреймворк для 2д игр.
    Предполагаю, что сервер будет на love исключительно из-за того, что там уже реализована физика взаимодействия твердых тел. А что скорость будет хромать, так вряд ли эту игрушку будут юзать более пяти игроков одновременно. Должно потянуть.

     

     

    И вот вопросик - как будет работать всякая чушь типа файловой системы, ограниченного размера озу у каждого компа, etc? Надо уж понять, как будет работать главная фича(тм) игрульки.
    Файловая система пока за пределами моих мечтаний. Это все таки не OpenComputers, а что-то на много проще. А вот ограничение ОЗУ это действительно проблема. Как ее решать, надеюсь придумаем со временем.

     

     

    debug.sethook, ей можно регулировать такие вещи.
    Пример приведи, пожалуйста. 

  5. Сетевой обмен.

    Love2d предоставляет несколько способов обмена по сети. Это и библиотека enet и библиотека LUBE. Тем не менее, я решил остановиться на стандартном TCP-сокете.

    Начнем с сервера. Предположим мы хотим создать сервер, который будет принимать строку символов, как то ее преобразовывать (например, инвертировать символы) и возвращать обратно клиенту. Сделать это можно так:

     

    -- подключаем либу
    local socket = require("socket")
    -- создаем TCP-сокет сервера и открываем на нем порт
    local server = socket.try(socket.bind("*", 12345))
    -- чтобы сокет не блокировал поток, устанавливаем нулевой таймаут
    server:settimeout(0)
    -- тут будем хранить сокеты клиентов
    clients={}
    -- для тех, кто не в курсе, функция love.update вызывается love-средой автоматически с минимальным периодом
    function love.update(dt)
      -- проверяем, не хочет ли кто законектиться
      local client = server:accept()
      if client then  -- если хочет
      -- устанавливаем минимальное время ожидания, что бы сокет не блокировал поток
        client:settimeout(0)
      -- посылаем клиенту приветствие
    	client:send("Hello\n")
      -- и сохраняем сокет клиента
        clients[#clients+1]=client
      end
      local i,n=1,#clients
        -- проверяем, что говорят клиенты
      while i<=n do
        local line, err = clients[i]:receive()
        if not err then -- если клиент что-то сказал,
    	  if line=="quit" then
    clients[i]:close() – если клиент сказал «quit», разрываем соединение с клиентом
    	  else
    		clients[i]:send(line:reverse() .. "\n") -- или отвечаем клиенту
    	  end
    	elseif err=="closed" then -- если клиент закрылся,
    		table.remove(clients,i) -- удаляем его из списка активных клиентов
    		i=i-1
    		n=n-1
    	end
    	i=i+1
      end
    end

     

     

     

    И клиент:

     

     

    local utf8 = require("utf8")
    local socket = require("socket")
    local text, ansver = "","" -- вводимый текст и ответ от сервера
    
    function love.load()
        -- enable key repeat so backspace can be held down to trigger love.keypressed multiple times.
        love.keyboard.setKeyRepeat(true)
    	-- создаем клиент-сокет
    	client = assert(socket.connect("localhost", 12345))
    	client:settimeout(0)
    end
     
    function love.textinput(t)
        text = text .. t – добавляем символ к строке ввода
    end
     
    function love.keypressed(key)
        if key == "backspace" then -- если нажата клавиша backspace
            -- get the byte offset to the last UTF-8 character in the string.
            local byteoffset = utf8.offset(text, -1)
     
            if byteoffset then
    			-- удаляем последний введенный символ
                text = string.sub(text, 1, byteoffset - 1)
            end
        end
    	if key == "return" then -- если нажата клавиша Enter,
    		client:send(text.."\n") -- отправляем введеный текст на сервер
    		text="" -- и сбрасываем строку ввода
    	end
    end
    
    function love.update(dt)
    	local line, err = client:receive() -- проверяем что ответил сервер
    	if line then ansver = line end 
    	if err=="closed" then ansver="closed" end
    end
    
    function love.draw()
        love.graphics.print(text, 0, 0) -- строка ввода
        love.graphics.print(ansver, 0, 12) -- ответ сервера
    end
    

     

     

     

    Следует заметить, что обмен реализуется исключительно путем передачи строк. Причем если верить документации, функция может принимать первым параметром одно из трех значение:

    - “*a” – читает из сокета, пока соединение не будет закрыто. Не совсем понял как это. А если я не собираюсь закрывать сокет в ближайшее время?

    - “*l” – читает из сокета строку, которая должна завершаться символом «перевод строки». Сам символ «перевод строки» не передается. В результате возникает проблема, если мы попытаемся передать текст из нескольких строк (а при передаче скрипта так и будет). На приемной стороне текст будет разбит на строки и придется его снова собирать по каким то правилам. Есть конечно вариант на передающей стороне заменить символ перевода на какой ни будь другой, а на приемной стороне выполнить обратную замену.

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

    Короче, ни один из трех способов не устраивает меня в полной мере. Кто использовал сокеты, что думаете?


  6. Две недели назад я начал изучать платформу для создания двумерных игр Love2d. Не скажу, что знаю ее уже досконально, но некоторое представление имеется. В первую очередь меня интересовала возможность создания многопользовательских игр, в которых игроку предстояло бы создавать программы. Под управлением этих программ должны работать некие игровые объекты. Не имеет значения, будут ли это космические корабли, бороздящие просторы вселенной, или роботы, роющие алмазики в шахтах, суть игры остается неизменной – определить, чья программа эффективнее.

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

    Для начала сформулирую основные задачи:

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

    2)      Возможность исполнения на сервере lua-скрипров, написанных игроками. Может и не стоило бы выделять это в отдельную задачу (все мы слышали про функцию load) если бы не одно «но». Скрипт, что бы там ни было написано, не должен блокировать работу сервера. Как, к примеру, парировать работу такого скрипта?

    while true do end

    Он напрочь завесит сервер, если не принять мер.

    3)      Параллельное выполнение скриптов. Один скрипт может выполняться несколько часов или даже дней. Это не означает, что остальные скрипты должны ждать своей очереди. Тут нам на помощь придут потоки (threads). Поток – довольно дорогое удовольствие и при большом количестве потоков на сервере могут возникнуть проблемы, но другого способа обеспечить распараллеливание я не знаю. Об особенностях реализации потоков и способах обмена между потоком и основной программой я бы хотел поговорить.

     

    А можно мне модерку на эту тему, что б тут флудосрач не разводили?


  7. бред єто все-равно что спросить сколько килограмм в 5км/ч (даже в физике вес и скорость разные понятия)

    Вес и скорость может и разные, но вот килобайт и мегабит все же единицы измерения одной величины - объема информации.

    • Нравится 1

  8. Пожалуйста приведите примеры битовых операция в Lua. А конкретно:

    Перевод какого либа числа в двоичное.

    Перевод двоичного числа в обычное.

     

    И самое главное, использую только библиотеку bit32.

    Может я и ошибаюсь, но битовые операции и библиотека bit32 в частности, имеют мало общего с переводом из одной системы счисления в другую. Удивляюсь почему Кверти до сих пор не вспомнил про свой универсальный конвертер из 13-ричной системы в 42-хричную.
    • Нравится 2

  9.  

     

    есть ли какие-то встроенные функции для сравнения чисел n и ключа таблицы, и замены v на значения ключа таблицы?

    Не совсем понял, что на что надо менять, но допустим есть переменная n и таблица t  с ключами k и соответствующими им значениями v. Необходимо найти в таблице ключ k, равный n, и присвоить n значение v, соответствующее ключу k.

    t={a=1,b=2,c=3}
    n="b"
    if t[n] then n=t[n] end
    

    • 1. Как вывести PNG\BMP файл ASCII символами в love2d и OC. (Пример программы с комментариями)

    Ссылка. Какие тут нужны комментарии, не понимаю. Изображение разбирается по пикселям, каждый пиксель заменяется символом.

    • 2. Чем отличаются таблицы от переменных?(Мне говорили, что без таблиц я не смогу сдлеать нормальной проги, но я особых отличий таблицы от переменной не нашёл)

    Таблица отличается от переменной тем, что переменная это имеющая имя область памяти, которая может хранить какие либо данные. Таблица это один из нескольких типов данных, доступных в Луа. Например, t={1,2,3}. Здесь t - переменная, а {1,2,3} - таблица. Кроме таблиц в Луа присутствуют булевые, числовые, строковые данные, функции, потоки и что-то кажется еще. От всех остальных типов таблицы отличаются тем, что могут хранить одновременно несколько значений.

    • 3. Как можно реализовать многозадачность? (Есть-ли какая-нибудь либа? Как самому такую либу сделать, какие для этого знания понадобятся?) Многопоточность есть многозадачность?

    Многозадачность и многопоточность это немного разные вещи. Многопоточность это способность одного приложения выполнять свой код в несколько потоков, например, имеются две функции, которые выполняются одновременно и независимо друг от друга. (На самом деле не одновременно, а по кусочкам. Сначала кусочек первой функции, потом кусочек второй, потом снова первой и т.д.). Многозадачность это особенность операционной системы, которая позволяет запускать одновременно несколько приложений. Что бы реализовать многозадачность тебе нужно написать свою операционку.

    • 4. Где можно найти аналоговый передатчик данных? (Какие знания потребуются для его создания?)

    Что за передатчик? :umnik2:

    • 5. Нужно засунуть pngшные обои под кнопки этой либы. (Как это можно реализовать?)

    Нужно переопределить функцию paint для формы.

    Тебе нужно:

    forms=require("forms")         -- подключить библиотеку
    Form1=forms.addForm()          -- создать форму
    Btn1=Form1:addButton(10,20,"Кнопка") -- создать кнопку на форме
    function Form1.paint()          -- переопределить процедуру paint
      -- тут выводим картинку
    end
    forms.run(Form1)               --запускаем gui 
    
    • Нравится 4

  10. Под условия попадает не совсем (PNG, внешняя либа).

    Но интересный вариант :)

    function love.load()
      im=love.image.newImageData('Image.bmp')
    end
    
    function love.draw()
      for y=1,im:getHeight() do
        for x=1,im:getWidth() do
    		r,g,b=im:getPixel(x-1,y-1)
    		r=(r+g+b)/3
    		love.graphics.print(r>205 and " " or r>154 and "." or r>102 and "/" or r>51 and "=" or "#",x*10,y*10)
    	end
      end
    end
    

    319 байт

    После минимизации

    l=love i=l.image.newImageData('Image.bmp')function l.draw()for y=1,i:getHeight()do for x=1,i:getWidth()do r,g,b=i:getPixel(x-1,y-1)r=r+g+b l.graphics.print(r>615 and" "or r>462 and"."or r>306 and"/"or r>153 and"="or"#",x*9,y*9)end end end 

    238 байт

    Результат почти тот же.post-7-0-37663600-1473074208_thumb.png

    • Нравится 1

  11. Love2D

    Изображение необходимо разместить в папке проекта под именем Image.png

    function love.load()
      im=love.image.newImageData('Image.png')
    end
    
    function love.draw()
      for y=1,im:getHeight() do
        for x=1,im:getWidth() do
    		r,g,b,a=im:getPixel(x-1,y-1)
    		r=(r+g+b)/3
    		love.graphics.print(((a==0 or r>205) and " " or r>154 and "." or r>102 and "/" or r>51 and "=" or "#"),x*10,y*10)
    	end
      end
    end
    

    333 байта

    Исходное изображение post-7-0-25096900-1473071940.png

    Результат post-7-0-71678600-1473071968_thumb.png

    • Нравится 2

  12.  

     

    Вот, помогаю вам. Не держу вас за нубов. // Вы могли знать про это. Вот эту хрень нужно использовать для того, чтобы элемент перемещался независимо от частоты обновления кадров. Например, так: ... если (нажата клавиша "вперед") то переместить(скорость * дельта между кадрами, 0, 0) конец ...
    Перемещения нужно реализовывать в процедуре  love.update(dt), в которую дельта передается в качестве параметра.
    • Нравится 1

  13. Предположим, имеется некая функция, возвращающая несколько значений. Например:

    function foo()
      return 2,3,4
    end
    

    Вызов этой функции можно вставить в качестве параметра в другую функцию. Например:

    print(foo()) --> 2    3    4
    

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

    К этому списку можно добавить еще элементы, но только в начало.

    print(1,foo()) --> 1    2    3    4
    

    Если же мы попытаемся добавить элемент в конец списка ...

    print(1,foo(),5) --> 1    2    5
    

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

    Почему так происходит и как сделать так, что бы передавались все элементы?

    print(1,foo(),5) --> 1    2    3    4    5
    
    • Нравится 1
×
×
  • Создать...