File: sprites.txt

package info (click to toggle)
instead 1.6.0-1
  • links: PTS
  • area: main
  • in suites: wheezy
  • size: 6,220 kB
  • sloc: ansic: 26,619; makefile: 247; sh: 207; cpp: 93
file content (185 lines) | stat: -rw-r--r-- 10,376 bytes parent folder | download
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>