| Полезные функции |
|
Ang3L
| Дата: Пятница, 21.11.2008, 17:57 | Сообщение # 1 |
Каждый 5й пост мой
Группа: Админы
Сообщений: 2667
Статус: Offline
|
Здесь предлагаю складировать функций. Что для этого нужно: 1) Подробное описание функций. 2) Входящие данные. 3) Выходные данные. 4) Пример использования, если функция предполагает использование с другими функциями. Спрятать точку: Эти две фунций находят точку куда надо прийти чтобы стать не видимым для врага. enemy - ID или Объект врага. obstacle - ID или Объект препятствия за которое надо спрятаться. offset - насколько далеко от препятствия наша точка прятанья в пикселях. Название скрипта hide_x: Quote //находим ближайшее препятствие var obstacle; obstacle = instance_nearest(x, y, argument1); //находим угол направленный от врага к препятствию var dir; dir = point_direction(argument0.x, argument0.y, obstacle.x, obstacle.y); //находим координату х за препятствием, да так чтобы враг не нашёл. var _x; _x = obstacle.x + lengthdir_x(argument2, dir); return _x; Возращает координату x куда надо прийти, чтобы спрятаться. Название скрипта hide_y: Quote //находим ближайшее препятствие var obstacle; obstacle = instance_nearest(x, y, argument1); //находим угол направленный от врага к препятствию var dir; dir = point_direction(argument0.x, argument0.y, obstacle.x, obstacle.y); //находим место за препятствием, да так чтобы враг не нашёл. var _y; _y = obstacle.y + lengthdir_y(argument2, dir); return _y; Возращает координату y куда надо прийти, чтобы спрятаться. Пример: Quote _x = hide_x(enemy, obstacle, offset); _y = hide_y(enemy, obstacle, offset); Теперь можно идти к точке (_x, _y) любым известным вам способом.
Blogpost
|
| |
| | |
|
Kamikaze
| Дата: Суббота, 22.11.2008, 00:32 | Сообщение # 2 |
Молчун
Группа: Пользователь
Сообщений: 15
Статус: Offline
|
Продукт поворота: Данная функция возвращает знак на который надо домножить число, которое будем добавлять к углу направления объекта чтобы плавно развернуть его в нужную сторону по кратчайшему пути. product_rotation Quote //Входные данные: //argument0 - текущий угол поворота обьекта в градусах //argument1 - угол в который планируется поворот обьекта //argument2 - точность в градусах (чем больше число, тем скорее функция начнет возвращать 0, лучше чтобы совпадало с числом на которое будет умножатся результат данной функции) //Выходные данные: //result - 1,0,-1 - множитель возвращаемый функцией if(argument1 > argument0 + argument2) if(argument1 - argument0 > 180) return -1 else return 1; else if(argument0 - argument2 > argument1) if(argument0 - argument1 > 180) return 1 else return -1; return 0; Пример (плавное изменение направления от 0 до 270 по кратчайшему пути): Quote var disp; disp = product_rotation(0, 270, 4); [color=blue]direction += 4 * disp; Возвращает кратчайшую разность углов между двумя углами (в расчете что углы могут быть тока от 0 до 360). Таким образом разность между 45 и 300 градусами будет 95. angles_difference Quote //argument0 - angle1 //argument1 - angle2 if([color=blue]argument0 > 360) argument0 = argument0 - 360; else if(argument0 < 0) argument0 = 360 + argument0; if(argument1 > 360) argument1 = argument1 - 360; else if (argument1 < 0) argument1 = 360 + argument1; argument0 = round(argument0) if(argument0 == 360) argument0 = 0; argument1 = round(argument1) if(argument1 == 360) argument1 = 0; var tmp; tmp = abs(argument0 - argument1) if(tmp > 180)return 360 - tmp; return tmp; Пример: Quote var ang_dif; ang_dif = angles_difference(45, 300); [color=green]//рисуем например сектор равный ang_dif градусов и получаем радиус видимости игрока :-) или просто фонарик)[/font]
Сообщение отредактировал Kamikaze - Суббота, 22.11.2008, 00:25 |
| |
| | |
|
Ang3L
| Дата: Суббота, 07.02.2009, 16:48 | Сообщение # 3 |
Каждый 5й пост мой
Группа: Админы
Сообщений: 2667
Статус: Offline
|
Поменять местами переменные: Меняет местами переменые a и b: Quote a = a ^ b; b = b ^ a; a = a ^ b; Плюсы: -Выше скорость -Меньше памяти занимает Минусы: -Неудобность чтения
Blogpost
|
| |
| | |
|
NewStrannik
| Дата: Вторник, 10.02.2009, 07:18 | Сообщение # 4 |
Всех уже задолбал
Группа: Проверенные
Сообщений: 808
Статус: Offline
|
#define file_bin_write_integer //file_bin_write_integer(file, number) var _a; _a = argument1; file_bin_write_byte(argument0, _a); file_bin_write_byte(argument0, _a >> 8); file_bin_write_byte(argument0, _a >> 16); file_bin_write_byte(argument0, _a >> 24); #define file_bin_read_integer //file_bin_read_integer(file) return (file_bin_read_byte(argument0) | (file_bin_read_byte(argument0) << 8) | (file_bin_read_byte(argument0) << 16) | (file_bin_read_byte(argument0) << 32))
Сообщение отредактировал NewStrannik - Вторник, 10.02.2009, 12:33 |
| |
| | |
|
CH@$ER
| Дата: Вторник, 10.02.2009, 23:55 | Сообщение # 5 |
Всех уже задолбал
Группа: Высший Советник
Сообщений: 1088
Статус: Offline
|
Сборник скриптов для побайтной записи в файл (строки определенной длины, строки, заканчивающиеся нулевым байтом, однобайтные, двубайтные и четырехбайтные знаковые и беззнаковые числа) Code #define file_bin_write_string var i, len;
len = string_length(argument1); for(i = 1; (i <= len) and (i <= argument2); i += 1) file_bin_write_byte(argument0, ord(string_char_at(argument1, i))); repeat (argument2 - len) file_bin_write_byte(argument0, 0); #define file_bin_write_string_ex file_bin_write_string(argument0, argument1, string_length(argument1) + 1); #define file_bin_write_smallint file_bin_write_byte(argument0, (argument1 + 128) mod 256); #define file_bin_write_word repeat (2) { file_bin_write_byte(argument0, argument1 mod 256); argument1 = argument1 >> 8; } #define file_bin_write_integer argument1 = argument1 + (1 << (8 * 2 - 1));
repeat (2) { file_bin_write_byte(argument0, argument1 mod 256); argument1 = argument1 >> 8; } #define file_bin_write_largeint argument1 = argument1 + (1 << (8 * 4 - 1));
repeat (4) { file_bin_write_byte(argument0, argument1 mod 256); argument1 = argument1 >> 8; } #define file_bin_read_string var result, ch, i;
result = '';
i = 0; repeat (argument1) { ch = file_bin_read_byte(argument0); i += 1; if ch != 0 result += chr(ch) else { repeat (argument1 - i) file_bin_read_byte(argument0); break; } } return result; #define file_bin_read_string_ex var result, ch;
result = '';
do { ch = file_bin_read_byte(argument0); if ch != 0 result += chr(ch) } until ch = 0; return result; #define file_bin_read_smallint return file_bin_read_byte(argument0) - 128; #define file_bin_read_word return file_bin_read_byte(argument0) + file_bin_read_byte(argument0) * 256; #define file_bin_read_integer return (file_bin_read_byte(argument0) + file_bin_read_byte(argument0) * 256) - (1 << 15); #define file_bin_read_largeint var result, mul;
result = 0; mul = 1; repeat (4) { result += file_bin_read_byte(argument0) * mul; mul *= 256; }
return result - (1 << 31); нахождение минимального расстояния до отрезка (в глобальных переменных global.tx, global.ty содержатся координаты ближайшей точки до данной на отрезке): Code /* (argument0, argument1) - first line point (argument2, argument3) - second line point (argument4, argument5) - point */
var wx, wy, px, py, c1, c2;
//calcs distance to line px = argument2 - argument0; //line vector py = argument3 - argument1; wx = argument4 - argument0; wy = argument5 - argument1; c1 = wx * px + wy * py; if c1 <= eps { global.tx = argument0; global.ty = argument1; } else { c2 = px * px + py * py; if c2 <= c1 { global.tx = argument2; global.ty = argument3; } else { d = c1 / c2; global.tx = argument0 + px * d; global.ty = argument1 + py * d; } }
return point_distance(argument4, argument5, global.tx, global.ty); Поворот точки на угол вокруг центра координат с масштабированием (для поворота вокруг точки сначала вычитаем из этой нужной точки координаты оси, поворачиваем и прибавляем назад): Code /* (argument0, argument1) - (x,y) argument2 - angle argument3 - xscale argument4 - yscale */
var sp, cp;
sp = -sin(argument2 * pi / 180); cp = cos(argument2 * pi / 180);
argument0 *= argument3; argument1 *= argument4;
global.px = argument0 * cp - argument1 * sp; global.py = argument1 * cp + argument0 * sp; Проверка пересечения отрезка с окружностью (возвращает количество точек пересечения, в глобальных переменных global.p1x, global.p1y, global.p2x, global.p2y содержит координаты точек пересечения): Code /* (argument0, argument1) - first line point (argument2, argument3) - second line point (argument4, argument5) - circle position argument6 - radius */
var d, a;
d = distance_to_line(argument0, argument1, argument2, argument3, argument4, argument5); if d > argument6 - eps if d < argument6 + eps return 1; else return 0; a = arccos(d / argument6) * 180 / pi; d = point_direction(argument4, argument5, global.tx, global.ty);
global.p1x = argument4 + lengthdir_x(argument6, d + a); global.p1y = argument5 + lengthdir_y(argument6, d + a); global.p2x = argument4 + lengthdir_x(argument6, d - a); global.p2y = argument5 + lengthdir_y(argument6, d - a);
return 2; Вовзращает ближайшее число степени двойки, большее данного числа: Code return 1 << ceil(log2(argument0)); Вовзращает ближайшее число степени двойки, меньшее данного числа: Code return 1 << floor(log2(argument0)); Многие функции использую константу eps. Определите ее равной 0.0001 Добавлено (10.02.2009, 23:55) --------------------------------------------- Определение положения точки относительно отрезка: Code /* (argument0, argument1) - lineA (argument2, argument3) - lineB (argument4, argument5) - point */
var ax, ay, bx, by, sa;
bx = argument2 - argument0; by = argument3 - argument1; ax = argument4 - argument0; ay = argument5 - argument1;
sa = ax * by - bx * ay; if sa > 0 return LEFT; if sa < 0 return RIGHT; if (ax * bx < 0) || (ay * by < 0) return BEHIND; if ax * ax + ay * ay < bx * bx + by * by return BEYOND; if argument0 == argument4 && argument1 == argument5 return ORIGIN; if argument2 == argument4 && argument3 == argument5 return DESTINATION; return BETWEEN; Не забудьте определить константы: LEFT (слева), RIGHT(справа), BEHIND(сзади: по прямой до начальной точки), BEYOND(спереди: по прямой после конечной точки), ORIGIN(в начальной точке), DESTINATION(в конечной точке), BETWEEN(по прямой между начальной и конечной точками).
Создание 3D FPS · Онлайновые таблицы рекордов · Многое другое!
Сообщение отредактировал CH@$ER - Вторник, 10.02.2009, 23:46 |
| |
| | |
|
WertyXBOCT
| Дата: Пятница, 13.02.2009, 21:09 | Сообщение # 6 |
Каждый 5й пост мой
Группа: Страж
Сообщений: 2467
Статус: Offline
|
var и with Для того чтобы обратиться к переменной находящейся вне блока with нужно написать other.имя_переменной. Если переменная объявленна в блоке var, то произойдет ошибка. В таком случае нужно писать просто имя переменной без other. т.е. Code var near; near = instance_nearest(x,y,objEnemy)
if near!=noone { direction = point_direction(x,y,near.x,near.y) if point_distance(x,y,near.x,near.y)<32 with instance_create(x,y,objRocket) { spd = 8; dmg = 20; obj = near; //obj = other.near - вызовет ошибку, нет такой переменной image_angle = other.direction; //image_angle = direction; - логическая ошибка } } Функция out(переменная, переменная, переменная); очень полезная функция при поиске логических ошибок и с переменными. Может использоваться в качестве точки останова Code #define out if !argument1 show_message(string(argument0)); else if !argument2 show_message(string(argument0)+' '+string(argument1)); else if !argument3 show_message(string(argument0)+' '+string(argument1)+' '+string(argument2)); пример использования: out('Координаты: ',x,y);
Blog:www.WeslomPo.ru mailto: i@weslompo.ru
|
| |
| | |
|
WertyXBOCT
| Дата: Вторник, 17.02.2009, 00:12 | Сообщение # 7 |
Каждый 5й пост мой
Группа: Страж
Сообщений: 2467
Статус: Offline
|
Понятия не имею зачем написал... но мне чем то не понравился стандартные функции работы с ini... аааа! вспомнил! Мне нужно было знать какие ключи есть в этом ini... а ведь все равно не добился чего хотел)) хотя час потратил на это)) но ничего там пару строк вбить. Суть функций: Вызываем функцию iniOpen(имяинифайла); Возвращает ID открытого ini (как бы не так! умные люди сразу после беглого взгляда на эту функцию поймут ЧТО возвращает функция).Нет ограничений по местоположению файла. Но используется медленный самопальный метод работы) iniGetReal(iniID,Section,Key); <- может выдать ошибку, будьте внимательны с содержимым iniGetString(iniID,Section,Key); Обе функции возвращают значения, хранящиеся в соответсвующих секциях и ключах. Код вроде работает, думаю, для ознакомления людей с принципами распознования текстовых файлов сгодится) архив весит меньше 2х килобайт, внутри gml файл, добавте его в свой проект для работы
Blog:www.WeslomPo.ru mailto: i@weslompo.ru
|
| |
| | |
|
3bl3gamer
| Дата: Вторник, 24.03.2009, 21:54 | Сообщение # 8 |
Хоть палкой гони
Группа: Проверенные
Сообщений: 650
Статус: Offline
|
Функция находит координаты точки пересечения (perpx,perpy) перпендикуляра, опущенного из точки (x1,y1) на прямую, проходящую через точки (x3,y3) и (x4,y4). Входящие данные: (х1; y1) - точка из которой выходит перпендикуляр на прямую. (x3; y3) и (x4; y4) - точка через которую проходит прямая. Выходные данные: (perpx; perpy) - точка пересечения перпендиуляра с прямой. intsec - если точка (x1,y1) находится между (x3,y3) и (x4,y4), то она равна 1, иначе - 0. Quote (Код) if(x3 == x4) {perpx = x3; perpy = y1;} if(y3 == y4) {perpx = x1; perpy = y3;} if(x3 != x4) and (y3 != y4) { a2 = 1 / (x4-x3); b2 = -1 / (y4-y3); c2 = y3 / (y4-y3) - x3 / (x4 - x3); k1 = b2 / a2; d1= y1 - k1 * x1; k2 =-a2 / b2; d2=-c2 / b2; perpx = (d2 - d1) / (k1 - k2); perpy = k1 * perpx + d1; } if(x3 < x4) { if(perpx > x3) and (perpx < x4) intsec = 1; else intsec = 0; } else { if(perpx < x3) and (perpx > x4) intsec = 1; else intsec = 0; } Функция находит координаты точки пересечения двух прямых. Входные данные: (x1; y1) (x2; y2) - две точки на одной прямой. (x3; y3) (x4; y4) - на другой. Выходные данные: (promx; promy) - точка пересечения 2 прямых. Quote (Код) a1 = 1 / (x2 - x1); b1= -1 / (y2 - y1); c1 = y1 / (y2 - y1) - x1 / (x2 - x1); a2 = 1 / (x4 - x3); b2 =-1 / (y4 - y3); c2 = y3 / (y4 - y3) - x3 / (x4 - x3); promy = (a2 * c1 - a1 * c2) / (a1 * b2 - a2 * b1); promx = (x2 - x1) * (promy - y1) / (y2 - y1) + x1; Функция находит координаты точек пересечения оуружности с прямой. Входные данные: r - радиус окружности. (x0; y0) - координаты центра окружности. (x1; y1) (x2; y2) - координаты двух точек на прямой. Выходные данные: dltz - если окружность прямую не пересекает, эта переменная равна 1, иначе - 0. (circx1; circy1) (circx2; circy2) - координаты двух точек пересечения. Quote a1 = 1 / (x2 - x1); b1 =-1 / (y2 - y1); c1 =y1 / (y2 - y1) - x1 / (x2 - x1); a = b1 * b1 / a1 / a1 + 1; b = (b1 / a1 * (c1 / a1 + x0) - y0); c = (c1 / a1 + x0) * (c1 / a1 + x0) + y0 * y0 - r * r; disc = b * b - a * c; if(disc < 0) {disc = -disc; dltz = 1;} else {dltz = 0;} sqrtd = sqrt(disc); circy1 = (-b + sqrtd) / a; circy2 = (-b - sqrtd) / a; circx1 = -b1 / a1 * circy1 - c1 / a1; circx2 = -b1 / a1 * circy2 - c1 / a1; Неужели было так трудно привести в приличный вид? Ang3L
Сообщение отредактировал 3bl3gamer - Вторник, 24.03.2009, 21:36 |
| |
| | |
|
Ang3L
| Дата: Понедельник, 18.04.2011, 19:13 | Сообщение # 9 |
Каждый 5й пост мой
Группа: Админы
Сообщений: 2667
Статус: Offline
|
cut(min, value, max); Ограничение значения(value) с двух сторон, слева - min, справа - max. Пример, есть жизни, они принимают значения от 0 до 100, чтобы не было числа выходящего за эти границы делаем так: cut(0, health, 100); Code return(max(argument0, min(argument1, argument2))); Quote (Druce) У меня просто была ситуация, где значение ограничивается несколькими факторами, от нескольких переменных. Могут быть разные отрезки в одной плоскости. т.е. по cut() на переменную. P.S.: Вы можете не делать отдельный скрипт, а просто выдернуть из return'а всю строку и вместо argument'ов поставить свои значения. Добавлено (18.04.2011, 19:13) --------------------------------------------- Как и обещал, пачка скриптов для чтения/записи бинарных файлов (переделанный вариант NewStrannik'а под несколько типов). Скачать (в ГМ: Scripts > Import Scripts... и выбираете этот файл) Пользовать точно также как и обычно, только вместо байт (который любезно предоставил нам Марк) может читать/писать и другие варианты: Различия между функциями read|write надеюсь писать не надо? short [2 байта]|int [4 байта] - целые типы short - целое число от -32768 до 32767 (размер 2 байта == 65536 значений) integer - целое число от -2млрд. до 2млрд. (размер 4 байта == 4млрд значений == 2^32) float [2 байта]|double [4 байта] - дробные типы Точность может быть не особо высокая, не для космической программы готовилась, но для игр вполне сойдёт. Все типы с приставкой "u" означают unsigned, т.е. беззнаковое, т.е. положительное от 0 до размера типа (кол-во значений == 2^(размер типа)). Допустим надо записать/прочитать положение (от нуля и до 65535) и скорость объекта (дробное, знаковое, т.е. как положительное так и отрицательное): Quote var file; file = file_bin_open("file.dat", 2); //на чтение и на запись //запись в файл file_bin_write_int(file, object.pos_x); file_bin_write_int(file, object.pos_y); file_bin_write_float(file, object.speed); //Возвращаемся в начало файла file_bin_seek(file, 0); //чтение object.pos_x = file_bin_read_int(file); object.pos_y = file_bin_read_int(file); object.speed = file_bin_read_float(file); file_bin_close();
Blogpost
|
| |
| | |
|
BanShee
| Дата: Понедельник, 18.04.2011, 19:59 | Сообщение # 10 |
Хрен заткнешь
Группа: Проверенные
Сообщений: 381
Статус: Offline
|
Как насчет добавить скрипт выдачи порядковой подстроки, который мне писал? И да, смени название темы, а? "Полезные функцИИ"...
Этот пост автоматически делает любой тред на 20% круче, если не указано обратное.
Сообщение отредактировал BanShee - Понедельник, 18.04.2011, 20:00 |
| |
| | |
|
Ang3L
| Дата: Понедельник, 18.04.2011, 23:24 | Сообщение # 11 |
Каждый 5й пост мой
Группа: Админы
Сообщений: 2667
Статус: Offline
|
Quote (BanShee) И да, смени название темы, а? "Полезные функцИИ"... Поправил! Quote (BanShee) Как насчет добавить скрипт выдачи порядковой подстроки, который мне писал? Функция твоя, ты и добавляй, если есть такое желание.
Blogpost
|
| |
| | |
|
SkipH
| Дата: Четверг, 13.10.2011, 06:48 | Сообщение # 12 |
Болтун
Группа: Проверенные
Сообщений: 220
Статус: Offline
|
рисует окно с много строчным текстом так что оно всегда влезало в вид(нужно размещать в draw). входящие данные argument0 - x координата где должно рисоваться окно argument1 - y координата где должно рисоваться окно argument2 - текст, с "#" как разделитель строк. Quote //sc_draw_inf(x,y,string) var n1,n2,n3,n4,window_height,window_width,x_draw,y_draw,text;
//вычисляем размер окна text=argument2 window_height=string_height(text) window_width =string_width (text)
//вычисляем место рисования окна x_draw=argument0-window_width/2 if x_draw<view_xview[0]+8 {x_draw=view_xview[0]+8} if x_draw+window_width>view_xview[0]+view_wview[0]-8 {x_draw=view_xview[0]+view_wview[0]-8-window_width} y_draw=argument1-window_height/4 if y_draw<view_yview[0]+8 {y_draw=view_yview[0]+8} if y_draw+window_height>view_yview[0]+view_hview[0]-8 {y_draw=view_yview[0]+view_hview[0]-8-window_height}
//рисуем окно со всей информацией draw_set_alpha(0.85) draw_set_color(c_white) draw_rectangle(x_draw-4,y_draw-4,x_draw+window_width+4,y_draw+window_height+4,0) draw_set_ alpha(1) draw_set_color(c_black) draw_rectangle(x_draw-4,y_draw-4,x_draw+window_width+4,y_draw+window_height+4,1) draw_set_halign(fa_cent er) draw_set_valign(fa_top) draw_text(x_draw+window_width/2,y_draw,text) draw_set_valign(fa_middle) Пример использования: Quote text='Имя'+'#'; text+='Количество'+'#'; text+='Описание'+'#'; sc_draw_inf(mouse_x,mouse_y,text); Добавлено (13.10.2011, 06:48) --------------------------------------------- нахождение расстояния от точки до прямой distance_to_line(line_x1,line_y1,point_x,point_y,line_dir) line_x1 - х координата любой точки на прямой line_y1 - у координата любой точки на прямой point_x - х кордината точки point_y - у координато точки line_dir - угол относительно координаты х, можно заменить на point_direction(line_x1,line_y1,line_x2,line_y2) Code return abs(lengthdir_y(point_distance(argument0,argument1,argument2,argument3),point_direction(argument0,argument1,argument2,argument3)-argument4))
Robot v0.7 <200 kb форум One world v0.5~1.6 mb форум
Сообщение отредактировал SkipH - Четверг, 13.10.2011, 06:49 |
| |
| | |
|
WertyXBOCT
| Дата: Четверг, 13.10.2011, 11:48 | Сообщение # 13 |
Каждый 5й пост мой
Группа: Страж
Сообщений: 2467
Статус: Offline
|
Поворот Декартовой системы на угол A Code var vx,vy,X,Y,H,V;
X = mouse_x; Y = mouse_y; A = 45;
vx = cos(degtorad(A)); //Единичный вектор новой системы vy = sin(degtorad(A));
H = X * vx + Y * vy; // Проекция вектора на ось абсцисс V = X * vy - Y * vx; // Проекция вектора на ось ординат
newMouse_x = H * 1 + V * 0; // Умножаем проекцию на вектор старой системы newMouse_y = H * 0 - V * 1; // И получаем что требуется Для оптимизации, если опредлитесь с углом, просчитайте синус и косинус, запишите их константами, а все уравнение в одну-две строки.
Blog:www.WeslomPo.ru mailto: i@weslompo.ru
|
| |
| |
|
|