Game Maker - создание игр | HellRoom Games
Январь 14, 2025, 10:23:30 *
Добро пожаловать, Гость. Пожалуйста, войдите или зарегистрируйтесь.

Войти
Новости:
 
   Начало   Game Maker Помощь Правила форума Поиск Календарь Войти Регистрация  
Страниц: [1]   Вниз
  Печать  
Автор Тема: [Example:Easy]ImageData для создания изображений  (Прочитано 4358 раз)
0 Пользователей и 1 Гость смотрят эту тему.
VladTheCat
Немного
GM Pro user
*

Репутация: 145
Offline Offline

Пол: Мужской
Награды:
1000 сообщений!За постоянность! [100 дней на форуме]Настоящий игродел!
API: Love
Деятельность: Целая игростудия, состоящая из одного кота.
Сообщений: 1435



« : Март 18, 2013, 20:42:54 »

Привет Всем. Хочу вам рассказать о такой вещи, как ImageData.

Некоторые видели его в Вики, но не все поняли, что это и зачем. Поясню:

imageData - Декодированное изображение, своего рода сурфейс, только предназначен для попиксельного редактирования отдельного изображения. Одно из применений - Убрать из файлов изображения и генерировать их внутри игры (чем больше, тем сложнее), уменьшая конечный размер игры. Или же можно создавать какие-то рандомные тайлы, чтобы не рисовать каждый отдельно и  сохранять в кучу файлов.

Есть еще несколько применений. Например, у готового изображения можно считывать пиксели и генерировать 2D массив (карта мира). Но сейчас мы остановимся только на создании изображения

Генерировать ImageData можно 3-мя путями: Вручную попиксельно, С помощью массива или автоматически, с помощью какого-либо алгоритма.

Стандартных функций нам нужно только 2 - love.load (не обязательно. Можно прямо вне функций все писать) и love.draw. Начну с описания аргументов love.image.newImageData:

их всего 2 - x, y - Размеры ImageData в пикселях. Счет пикселей начинается с 0. Например. Изображение шириной 8 пикселей. Для проверки всех пикселей в ширину надо считать от 0 до 7 (включительно).

Приступим к кодингу. Так как тут я использовал метод создания массивом, то нам надо сначала подготовить сам массив.
Код:
function love.load()
  tHero = {
  {0, 0, 4, 4, 4, 4, 0, 6},
  {0, 3, 4, 9, 9, 9, 0, 6},
  {0, 3, 9, 1, 9, 1, 0, 6},
  {0, 3, 9, 9, 9, 9, 0, 6},
  {4, 3, 4, 4, 4, 4, 4, 9},
  {9, 5, 6, 6, 7, 6, 0, 3},
  {0, 3, 4, 4, 4, 4, 0, 0},
  {0, 2, 0, 0, 0, 2, 0, 0},
  }
end
PS: не буду сразу показывать, что у нас получится :3

Наше изображение будет черно-белым. Цифры от 1 до 9 - интенсивность белого цвета (1 - темно-серый, 9 - почти белый). 0 - пустой прозрачный пиксель.

Еще 1 важная вещь - при таком создании массива местами меняются x и y. То есть, если мы используем циклы for для отрисовки этого массива, то в координатах рисования пишем нормально: X, Y; а в координатах массива наоборот: Y, X. Например:
Код:
love.graphics.print(array[y][x], x * 10, y * 10)
Если же писать не повернутые аргументы, то изображение повернется на 90 градусов.

Но вернемся к делу. Теперь создаем наш ImageData, с размерами 8*8. Допишем в конце love.load:
Код:
imgD = love.image.newImageData(8, 8)

Сейчас надо "забить" пиксели из массива в декодированное изображение, после этого - создать нормальное изображение с помощью love.graphics.newImage
Код:
for y = 0, 7 do
  for x = 0, 7 do
    local c = tHero[y+1][x+1]
    if c ~= 0 then
      imgD:setPixel(x, y, 255/10*c, 255/10*c, 255/10*c, 255)
    end
  end
end

img = love.graphics.newImage(imgD)

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

Также, чтобы можно было лучше рассмотреть наше получившееся изображение, в Love.draw его можно увеличить, но оно будет размазанным. С помощью функции image:setFilter можно убрать сглаживание у изображения:
Код:
img:setFilter('nearest','nearest')

В love.load мы закончили. Переходим к love.draw. Тут просто рисование нашего увеличенного изображения.
Код:
function love.draw()
  love.graphics.draw(img, 100, 100, 0, 10, 10)
  for y=1, 8 do
    for x=1, 8 do
      love.graphics.print(tHero[y][x], x * 10 + 300, y * 10 + 90)
    end
  end
end
Цикл в конце - рисование значений массива рядом с изображением, чтобы было видно, из чего оно вышло :)

Теперь можно посмотреть на готовое изображение:



Как всегда - Листинг main.lua:
Код:
function love.load()
  tHero = {
  {0, 0, 4, 4, 4, 4, 0, 6},
  {0, 3, 4, 9, 9, 9, 0, 6},
  {0, 3, 9, 1, 9, 1, 0, 6},
  {0, 3, 9, 9, 9, 9, 0, 6},
  {4, 3, 4, 4, 4, 4, 4, 9},
  {9, 5, 6, 6, 7, 6, 0, 3},
  {0, 3, 4, 4, 4, 4, 0, 0},
  {0, 2, 0, 0, 0, 2, 0, 0}
  }
  imgD = love.image.newImageData(8, 8)
  for y = 0, 7 do
    for x = 0, 7 do
      local c = tHero[y+1][x+1]
      if c ~= 0 then
        imgD:setPixel(x, y, 255/10*c, 255/10*c, 255/10*c, 255)
      end
    end
  end

  img = love.graphics.newImage(imgD)
  img:setFilter('nearest','nearest')
  love.graphics.setBackgroundColor(50,0,0)
end

function love.draw()
  love.graphics.draw(img, 100, 100, 0, 10, 10)
  for y=1, 8 do
    for x=1, 8 do
      love.graphics.print(tHero[y][x], x * 10 + 300, y * 10 + 90)
    end
  end
end
Также можно скачать .love пример

Всем спасибо за внимание :)
Записан


Будьте вежливы: Вам помогли? Не забудьте поставить плюс. А то банда злобных апельсинов придет за вами. И даже тех. поддержка вам не поможет. :3

Когда я что-то пишу в "<>", то это значит, что содержимое надо заменить на свое значение.
Страниц: [1]   Вверх
  Печать  
 
Перейти в:  

HellRoom Games © 2006-2012 All Rights Reserved
Powered by SMF 1.1.21 | SMF © 2013, Simple Machines
Страница сгенерирована за 0.097 секунд. Запросов: 27.