1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185
|
====== Модуль sprites ======
^ Подключение | require "sprites" |
^ Тип | игровой/расширение кода |
^ Зависимости | theme |
===== Описание =====
Начиная с версии 1.4.0 INSTEAD поддерживает расширенные возможности для работы с изображениями, позволяющие в том числе делать 2d игры.
Модуль sprites предоставляет api, содержащие следующие функции:
^ Функция ^ Описание ^
| sprite.load(file_name) | загрузка спрайта из файла изображения. При этом функция вернет дескриптор загруженного спрайта (далее spr); |
| sprite.free(spr) | освобождение спрайта; |
| sprite.screen() | возвращает спрайт - игровой экран. Используется только в режиме прямого доступа; |
| sprite.font_scaled_size(size) | возвращает размер шрифта с учетом масштабирования шрифтов; |
| sprite.font(font_path, size) | загружает шрифт, возвращает дескриптор загруженного шрифта (далее font); |
| sprite.free_font(font) | выгружает шрифт; |
| sprite.font_height(font) | возвращает высоту шрифта в пикселях; |
| sprite.alpha(spr, alpha) | создает новый спрайт с заданной прозрачностью alpha (255 - не прозрачно); |
| sprite.dup(spr) | создает копию спрайта;|
| sprite.scale(spr, xs, ys) | масштабирование спрайта, для отражений используйте масштаб -1.0. (медленно! не для реального времени); |
| sprite.rotate(spr, angle) | поворот спрайта на заданный угол в градусах (медленно! не для реального времени); |
| sprite.text(font, text, col, [style]) | создание текстового спрайта, col - здесь и далее - цвет в текстовом формате (в формате '#rrggbb' или 'текстовое название цвета'); |
| sprite.size(spr) | возвращает ширину и высоту спрайта в пикселях; |
| sprite.text_size(font, text) | вычисляет размер, который будет занимать текстовый спрайт, без создания спрайта; |
| sprite.draw(src_spr, fx, fy, fw, fh, dst_spr, x, y, [alpha]) | рисование области src спрайта в область dst спрайта; (задание alpha сильно замедляет выполнение функции) |
| sprite.draw(src_spr, dst_spr, x, y, [alpha]) | рисование спрайта, укороченный вариант;(задание alpha сильно замедляет выполнение функции) |
| sprite.copy(src_spr, fx, fy, fw, fh, dst_spr, x, y, [alpha]) | копирование содержимого спрайта (рисование - замещение) |
| sprite.copy(src_spr, dst_spr, x, y, [alpha]) | копирование содержимого спрайта (рисование - замещение), укороченный вариант |
| sprite.fill(spr, x, y, [w, h, [col]]) | заполнение спрайта цветом; |
| sprite.pixel(spr, x, y, col, [alpha]) | заполнение пикселя спрайта; |
| sprite.pixel(spr, x, y) | взятие пикселя спрайта (возвращает цвет в текстовой форме); |
===== Примеры использования =====
Внимание!!! Состояние спрайтов не попадает в файл сохранения игры, поэтому задача восстановления игровой ситуации на основе сохраняемых переменных лежит на авторе игры. Общие рекомендации:
В функции init можно загружать и создавать те спрайты, которые будут необходимы во время цикла всей игры, например:
<code lua>
function init()
bg = sprite.load 'background.png'
font = sprite.font ('sans.ttf', 32);
end
</code>
В функции start, вы можете восстанавливать игровую ситуацию на основе сохраненных переменных, так как start выполняется после загрузки игры или после первого запуска игры, например:
<code lua>
function start()
if here() == main then
main.pic = sprite.text(font, 'BIG ADVENTURE', 'black');
end
end
</code>
Если вы создаете временные спрайты, освобождайте их, когда они больше не нужны, например:
<code lua>
function show_score()
local t = sprite.text(font,'Score:'..tostring(score), 'white');
sprite.draw(t, sprite.screen(), 0, 0);
sprite.free(t);
end
</code>
Спрайты могут быть встроены в игру как и любая другая графика -- с помощью img/imgl/imgr или присвоены переменной pic сцены, но в последнем случае, любое изменение содержимое спрайта pic (например, в обработчике таймера) будет отражено в реальном времени в игре. Эту особенность можно использовать для анимационных квестов или заставок.
Например:
<code lua>
instead_version '1.3.5'
require 'sprites'
require 'timer'
main = room {
nam = 'demo';
pic = sprite.load 'box:320x200,black';
}
function init()
timer:set(30);
end
game.timer = function()
sprite.pixel(main.pic, rnd(320), rnd(200), 'white');
end
</code>
Начиная с 1.4.0 если обработчик не возвращает ничего, то игровая сцена не изменяется, за исключением модификаций pic сцены, если это спрайт.
Также, игра может задействовать режим прямого доступа, когда игра может рисовать непосредственно в экранную область INSTEAD. Переключение в режим осуществляется с помощью параметра темы:
<code lua>
scr.gfx.mode = direct
</code>
Вы можете задать этот параметр в theme.ini игры или менять его динамически, с помощью модуля theme.
В режиме прямого доступа, все отрисовки в специальный спрайт sprite.screen() отображаются в реальном времени.
Таким образом, если вы пишите 2d игру на INSTEAD типовой алгоритм ее работы выглядит следующим образом.
1. init() - загрузка спрайтов
2. start() - задание начальных значений или восстановление;
3. game.timer() - отрисовка кадра игры (модуль timer);
4. game.click() - получение событий мыши (модуль click);
5. game.kbd() - получение событий клавиатуры (модуль kbd);
INSTEAD всегда скрывает факт масштабирования от игры, поэтому, обычно игра работает независимо от выбранного разрешения. Все размеры и координаты выглядят так, как будто масштабирования нет. В отдельных случаях, в результате погрешностей округления это может стать проблемой (например подгонка tiles пиксель в пиксель). В этом случае автор может запретить масштабирование:
<code lua>
scr.gfx.scalable = 0
</code>
Начиная с версии 1.4.0 в INSTEAD существует возможность отслеживать интервалы времени в миллисекундах. Для этого используйте функцию get_ticks().
Опрос или установка координат курсора мыши: mouse_pos([x, y]).
Пример работы со спрайтами:
<code lua>
instead_version "1.4.0"
require "timer"
require "sprites"
spr = sprite
function init()
fnt = spr.font(theme.get 'win.fnt.name', 32);
ball = spr.text(fnt, "INSTEAD 1.4.0", 'white', 1);
ballw,ballh = spr.size(ball);
bg = spr.load 'box:640x480,black';
line = spr.load 'box:320x8,lightblue';
end
function start()
timer:set(10)
G = 9.81
by = -ballh
bv = 0
bx = 320
t1 = get_ticks()
end
function phys()
local t = timer:get() / 1000;
bv = bv + G * t;
by = by + bv * t;
if by > 400 then
bv = - bv
end
end
game.timer = function(s)
local i
for i = 1, 10 do
phys()
end
if get_ticks() - t1 >= 20 then
spr.copy(bg, spr.screen(), 0, 0);
spr.draw(ball, spr.screen(), (640 - ballw) / 2, by - ballh/2);
spr.draw(line, spr.screen(), 320/2, 400 + ballh / 2);
t1 = get_ticks()
end
end
</code>
Файл theme.ini
<code lua>
scr.w = 640
scr.h = 480
scr.gfx.mode = direct
</code>
Еще один вариант, пропускающий кадры при необходимости:
<code lua>
game.timer = function(s)
local i
for i = 1, 10 do
phys()
end
if get_ticks() - t1 >= 15 then
t1 = get_ticks()
return
end
t1 = get_ticks()
spr.copy(bg, spr.screen(), 0, 0);
spr.draw(ball, spr.screen(), (640 - ballw) / 2, by - ballh/2);
spr.draw(line, spr.screen(), 320/2, 400 + ballh / 2);
end
</code>
|