# 000114. Делаем спидометр!

Делаем спидометр!|Всем привет! Сегодня речь пойдёт об спидометрах! Мы научимся создавать без каких-либо усилий неплохие измерители скорости автомобилей.|wmysterio|wmysterio||||Хочу сказать, что методов очень много и в этом уроке я расскажу о самом популярном и моём любимом способе - привязка скорости автомобиля к углу текстуры. Первым шагом будет поиск нужных текстур. Рыская в интернете, я нашел подходящие картинки для спидометра. Эти картинки я закинул в новый TXD-архив "SPEED", который вы можете скачать [отсюда](https://github.com/wmysterio/scm-scripting-lessons/blob/main/data_base/sa/SPEED.txd). и поместил в папку **models/txd**.\
Запускаем наш Санни Билдер, и создаём новый документ. Проверим, сначала, если игрок не найден, то завершим наш поток:

```
{$CLEO}
0000:
thread 'SPEED'

if
Player.Defined($PLAYER_CHAR)
jf @SPEED_END

// // //

:SPEED_END
wait 0
0A93: end_custom_thread
```

Если условие сработало, то создаём новый бесконечный цикл. В нём напишем проверку: "Актёр $PLAYER\_ACTOR в транспорте?". Если этот так, то загружаем наш архив текстур и сами картинки, которые она содержит:

```
while true
 if
 Actor.Driving($PLAYER_ACTOR)
 then
 0390: load_txd_dictionary 'SPEED'
 038F: load_texture "CIRCLE" as 1
 038F: load_texture "STRELK" as 2 
 
 // // // // //
 
 0391: release_txd_dictionary 
 end
wait 0
end
```

и тут-же выгружаем её из памяти. На месте комментариев, нам понадобится ещё один цикл **while**. Проверка будет такая-же, как и в условие IF, в которого вложен цикл:

```
 while Actor.Driving($PLAYER_ACTOR)
 03F0: enable_text_draw 1

 wait 0
 end
```

Следующий пункт - рисование текстур. Обе картинки в нас имеют размер 256х256, что, согласитесь, многовато. Поэтому рисовать текстуры мы будем размером 128х128. Первую текстуру мы будем рисовать опкодом "038D", так как мы не собираемся её привязывать к скорости. А вот вторую ( стрелку ) рисуем опкодом "074B", так как он может вращать картинки на экране. В нас получится следующее:

```
 while Actor.Driving($PLAYER_ACTOR)
 03F0: enable_text_draw 1
 03E3: set_texture_to_be_drawn_antialiased 1
 038D: draw_texture 1 position 540.0 280.0 size 128.0 128.0 RGBA 255 255 255 200
 03E3: set_texture_to_be_drawn_antialiased 1 
 074B: draw_texture 2 position 540.0 280.0 scale 128.0 128.0 angle 2@ color_RGBA 255 255 255 128
 wait 0
 end
```

Всё, что нам осталось - определить переменную "2@". Что-бы сделать скорость реалистичнее, и спидометр показывал более-менее правильные данные, мы должны перевести скорость ( юниты ) машины в километры. Я подсчитал, что для данного спидометра нужно умножить скорость машины на 4.0. Так, как выбранная машина едет со скоростью 40 юнитов ( в игре по ровной трассе ), а в "handling.cfg" указано 160.0 км ( или миль ), юниты должны быть умножены на ( 160 / 40 ) = 4. Следовательно, мы получим:

```
03C0: 1@ = actor $PLAYER_ACTOR car
02E3: 2@ = car 1@ speed
2@ *= 4.0
```

Таким образом, мы получили скорость машины. Нам осталось отобразить её на спидометре. Если так запустить скрипт, то стрелка будет в начале смотреть в низ, где никаких цифр не указано. Следовательно нам нужно сместить угол поворота стрелки на какой-то градус. Я вычислил, что для данного спидометра смещение должно быть на 54.0 градуса:

![](https://github.com/wmysterio/scm-scripting-lessons/blob/main/_pu/1/31167069.png)

В нас получится следующий код:

```
{$CLEO}
0000:

thread 'SPEED'
if
Player.Defined($PLAYER_CHAR)
jf @SPEED_END

while true
 if
 Actor.Driving($PLAYER_ACTOR)
 then
 0390: load_txd_dictionary 'SPEED'
 038F: load_texture "CIRCLE" as 1
 038F: load_texture "STRELK" as 2 
 while Actor.Driving($PLAYER_ACTOR)
 03F0: enable_text_draw 1
 03E3: set_texture_to_be_drawn_antialiased 1
 038D: draw_texture 1 position 540.0 280.0 size 128.0 128.0 RGBA 255 255 255 200
 03E3: set_texture_to_be_drawn_antialiased 1
 03C0: 1@ = actor $PLAYER_ACTOR car
 02E3: 2@ = car 1@ speed
 2@ *= 4.0 // Переводим скорость с юнитов в километры
 2@ += 54.0 // Поворачиваем текстуру стрелки на 54 градуса 
 074B: draw_texture 2 position 540.0 280.0 scale 128.0 128.0 angle 2@ color_RGBA 255 255 255 128
 wait 0
 end 
 0391: release_txd_dictionary 
 end
wait 0
end

:SPEED_END
wait 0
0A93: end_custom_thread
```

Результат:

![](https://github.com/wmysterio/scm-scripting-lessons/raw/resources/_pu/1/32064124.png)

Спидометр работает как часики, что и нужно было сделать :) На этом урок окончен. Удачи!

P.S. Вычислял нужный угол смещения стрелки я следующим кодом:

```
 03C0: 1@ = actor $PLAYER_ACTOR car
 02E3: 2@ = car 1@ speed
 2@ *= 4.0
 0087: 0@ = 2@ // (float)
 
 while true
 if
 0AB0: key_pressed 49 // 1
 then
 if
 0AB0: key_pressed 16 // SHIFT
 then
 0@ += 0.2
 end 
 0@ += 0.2
 end 

 038D: draw_texture 1 position 540.0 280.0 size 128.0 128.0 RGBA 255 255 255 200
 074B: draw_texture 2 position 540.0 280.0 scale 128.0 128.0 angle 0@ color_RGBA 255 255 255 128
 0AD0: show_formatted_text_lowpriority "%f" time 1 0@
 wait 0
 end
```

Когда мы сели в транспорт, нажимаем 1 и стрелка будет постепенно менять свой угол. Я определил, что число 54, которые показывает опкод "0AD0" и есть идеальным смещением для даного случая.|2018|1|0|32064124`png`600`337`400`224``\|31167069`png`350`289

```
`\||delaem_spidometr|1504503695
```


---

# Agent Instructions: Querying This Documentation

If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter:

```
GET https://lessons.sannybuilder.com/00100/00600/000114.-delaem-spidometr.md?ask=<question>
```

The question should be specific, self-contained, and written in natural language.
The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
