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

MineOs GUI Container

Вопрос

Опять вопрос косит под ECS. Есть программа, условно пока-что передвижение в пространстве на кастомной карте. Но вот проблема, что-бы игрок оставался в поле зрения мы передвигаем карту, так вот, что-бы не перерисовывать карту каждый раз когда мы дёргаемся, мы передвигаем контейнер с картой. Но вот не задача судари, контейнер оставляет за собой след, который упирается в любую пикчу.

 

Скрытый текст

local gui = require('gui')
local event = require('event')
local fs= require('filesystem')
local elements = {} -- Будещее...
local camera = {x=1,y=1} --Вроде не нужно, но этоже еще в разработке)
local player = {x=50,y=25,facing='Right'} -- информация об игроке
local image = require('image')
local images = {} -- Вперёд в будущее (по тексту)
local key = require('keyboard')

images['Brick'] = image.load('/Brick.pic') -- будущее настало
images['Man Left'] = image.load('/Man.pic')
images['Man Right'] = image.flipHorizontally(image.load('Man.pic'))
images['Man Up'] = image.load('/Mann.pic')
images['Man Down'] = image.flipVertically(image.load('Mann.pic')) -- Заранее подгружаем пикчи что-бы не грузить диск по любомму требованию

wk  = gui.workspace(1,1,160,50)
local bg = wk:addChild(gui.panel(1,1,160,50,0xFFFFFF)) -- Задний фон
local text = wk:addChild(gui.text(20,20,0x989898,'0 0'))
local data = fs.readTable('/Test.map') -- {[1]={[1]='Brick'},X=1,Y=1} --Карта
local map = wk:addChild(gui.container(1,1,160,50)) -- Наш пациент, контейнер
local playerpic = wk:addChild(gui.image(50,25,images['Man Right']))
local a=  0 
for x=1,160 do -- потом карта будет сама определять свой размер, исходя из файлы карты
  for y=1,50 do
    a = a + 1
    pcall(function()
    -- Второе будущее
    elements[a] = map:addChild(gui.image(x,y,images[data[x][y]])) -- Спавн элементов карты, координаты и что за элемент там хранится, в будущем будет колайды (можно ли уперется в объект (пол и тумбочка)), а также делаем так,что-бы мы могли в будущем управлять компонентами карты запихивая в "элементы"(карты)
    end)
  end
end
while true do
  e1,e2,e3,e4,e5,e6=event.pull(0.01)
  text.text = tostring(e3)..' '..tostring(e4)
  playerpic:remove() -- Дабы не рисовать супер линий игроком
  if key.isKeyDown(30) then -- A
    if player.x > 20 then
    player.facing = 'Left'
    player.x = player.x - 2
    else
    map.localX = map.localX-2 end
  end
  if key.isKeyDown(32) then -- D
    if player.x < 140 then
    player.facing = 'Right'
    player.x = player.x + 2
    else
    map.localX = map.localX+2 end
  end
  if key.isKeyDown(17) then -- W
    if player.y > 10 then
    player.y = player.y - 1
    player.facing = 'Up'
    else
    map.localY = map.localY-1
    end
  end
  if key.isKeyDown(31) then -- S
    if player.y < 40 then
    player.y = player.y + 1
    player.facing = 'Down'
    else
      map.localY = map.localY+1
    end
  end
  local playerpic = wk:addChild(gui.image(player.x,player.y,images['Man '..player.facing])) -- показываем игрока, снова
  wk:draw()
end
wk:draw()
wk:start()

 

 

И результат:
image.thumb.png.76f48124a22eb7eee4b41afad8ea1fc5.png

На вторую пикчу не хватило бюджета, но на игрока оно тоже стопорит закраску, игнорируя текст.

Изменено пользователем Oleshe

Поделиться сообщением


Ссылка на сообщение
Поделиться на других сайтах

Рекомендуемые сообщения

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

 

1) Обработка событий встроена, workspace.start() сам по себе запускает бесконечный цикл пуллинга событий, и делать это вручную через while true нет смысла:

wk.eventHandler = function(e1, e2, e3, e4, e5, e6)
  ...
end

wk:start(0.01)

2) Непонятно, зачем конкретно в твоём случае используется таймаут поллинга в 0.01 сек. Эта фича используется в довольно редких ситуациях, когда нужно делать что-то с заданным интервалом. Например, опрашивать внешние компоненты типа реакторов или перемещать визуальные элементы в играх раз в N сек. Если тебе требуется лишь анализ нажатия клавиш, то:

bg.eventHandler = function(e1, e2, e3, e4, e5, e6)
  if e1 == "key_down" then
    -- A
    if e3 == 30 then
      ...
        
      wk:draw()
    -- D
    else if e3 == 32 then
      ...
      
      wk:draw()
    end
  end
end

wk:start(0.01)

3) Изменять экранные координаты объекта бесполезно, т.к. они рассчитываются автоматически и используются только во время вызова метода draw(). Чтобы изменить позицию элемента в родительском контейнере, используй localX/localY:

-- Нельзя
player.x = player.x - 2

-- Можно
player.localX = player.localX - 2

4) Нет смысла удалять и пересоздавать объекты картинок при каждом ивенте. Если тебе нужно попросту заменить картинку в существующем виджете, то:

local playerpic = wk:addChild(gui.image(50,25,images['Man Right']))

bg.eventHandler = function(e1, e2, e3, e4, e5, e6)
  if e1 == "key_down" then
    -- A
    if e3 == 30 then
      player.facing = 'Left'
      playerpic.image = images['Man ' .. player.facing]
      
      wk:draw()
    end
  end
end

5) Можно вообще создать собственный виджет "player", определив ему метод отрисовки и не собирать его из GUI.image. Он и работать будет быстрее, и все поля будут храниться в одном месте, и любой кастом можно будет оформить за пару строк кода:

local player = wk:addChild(gui.object(50, 25, 8, 4))
player.facing = 'Left'

player.draw = function(player)
  screen.drawImage(player.x, player.y, images['Man ' .. player.facing]
end

 

Поделиться сообщением


Ссылка на сообщение
Поделиться на других сайтах
3 часа назад, ECS сказал:

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

 

1) Обработка событий встроена, workspace.start() сам по себе запускает бесконечный цикл пуллинга событий, и делать это вручную через while true нет смысла.

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

3 часа назад, ECS сказал:

2) Непонятно, зачем конкретно в твоём случае используется таймаут поллинга в 0.01 сек. Эта фича используется в довольно редких ситуациях, когда нужно делать что-то с заданным интервалом. Например, опрашивать внешние компоненты типа реакторов или перемещать визуальные элементы в играх раз в N сек. Если тебе требуется лишь анализ нажатия клавиш, то /.../

Что-бы цикл не стопорил все на 2 минуты по кастомному конфигу. Иногда мне нужно обработать огромный цикл, это занимает больше секунды и оно вылетает. Цикл как правило гарантировано с выходом, ему просто нужно время. Использование спячки очень медлит работу. Тут у нас нету выхода из цикла, как минимум не за 2 минуты, поэтому тут и спим.

4 часа назад, ECS сказал:

3) Изменять экранные координаты объекта бесполезно, т.к. они рассчитываются автоматически и используются только во время вызова метода draw(). Чтобы изменить позицию элемента в родительском контейнере, используй localX/localY /../

В чем отличие? Как и описывалось в коде список "игрок" описывает его, он не является контейнером, либо я не правильно понял ответ (или вопрос). Или имелось в виду что если используем контейнер. Из-за этого и пошла ошибка отрисовки, при перемещений контейнера на фоне пластины оно и закрашивало.

3 часа назад, ECS сказал:

4) Нет смысла удалять и пересоздавать объекты картинок при каждом ивенте. Если тебе нужно попросту заменить картинку в существующем виджете, то /.../

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

4 часа назад, ECS сказал:

5) Можно вообще создать собственный виджет "player", определив ему метод отрисовки и не собирать его GUI.image. Он и работать будет быстрее, и все поля будут храниться в одном месте, и любой кастом можно будет оформить за пару строк кода /../

Вот это топ подгон).

Попробую переделать под это все и посмотрим изменится ли что-нибудь.


Хотелось-бы что-бы каждый граф. элемент имел динамические координаты, кнопка, картинка, текст, ползунок и т.д., не только контейнеры.

Поделиться сообщением


Ссылка на сообщение
Поделиться на других сайтах
22 часа назад, Oleshe сказал:

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

Дык его попросту нельзя использовать. Либа сама делает всю работу, обрабатывая ивенты по-своему и творя внутреннюю магию. Если используешь - получаешь "unexpected behaviour" со всеми вытекающими. Поэтому либо повторяй в точности всю "магию", либо присоединяй eventHandler как положено и не парься

 

22 часа назад, Oleshe сказал:

Что-бы цикл не стопорил все на 2 минуты по кастомному конфигу. Иногда мне нужно обработать огромный цикл, это занимает больше секунды и оно вылетает.

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

 

22 часа назад, Oleshe сказал:

В чем отличие? Как и описывалось в коде список "игрок" описывает его, он не является контейнером, либо я не правильно понял ответ (или вопрос). Или имелось в виду что если используем контейнер. Из-за этого и пошла ошибка отрисовки, при перемещений контейнера на фоне пластины оно и закрашивало.

localX/localY отвечают за положение элемента внутри родительского контейнера, а x/y - за позицию на экране во время отрисовки. При этом x/y рассчитываются автоматически и используются только во время операций отрисовки. Вообще все подробности имеются в доке, которую было бы неплохо чекнуть

 

22 часа назад, Oleshe сказал:

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

localX/localY

 

22 часа назад, Oleshe сказал:

Хотелось-бы что-бы каждый граф. элемент имел динамические координаты, кнопка, картинка, текст, ползунок и т.д., не только контейнеры

Дык имеют же. Читай доку!!11

Поделиться сообщением


Ссылка на сообщение
Поделиться на других сайтах

Присоединяйтесь к обсуждению

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

Гость
Ответить на вопрос...

×   Вы вставили отформатированное содержимое.   Удалить форматирование

  Разрешено использовать не более 75 эмодзи.

×   Ваша ссылка была автоматически встроена.   Отобразить как ссылку

×   Ваш предыдущий контент был восстановлен.   Очистить редактор

×   Вы не можете вставлять изображения напрямую. Загружайте или вставляйте изображения по ссылке.


×
×
  • Создать...