Вы не вошли. Пожалуйста, войдите или зарегистрируйтесь.

Перейти к содержимому раздела

Blind games - Звуковые игры незрячим

Форум сайта "blind.games". Добро пожаловать.

Архивный режим

Форум переводится в архивный режим. Это значит, что все учетные записи, темы и сообщения остаются на момент 19.07.2018, а добавлять новые уже нельзя. То есть, закрыта регистрация, добавлен запрет на создание новых тем и ответы в существующих.
По всем вопросам, как и ранее, вы можете писать на support (собачка) blind (точка) games.

(Страница 3 из 4)

Blind games - Звуковые игры незрячим → Создание игр, программирование → BGT. Делимся опытом: кодинг, решения задач в программировании.

Страницы Назад 1 2 3 4 Далее

Чтобы отправить ответ, вы должны войти или зарегистрироваться

Topic RSS feed

Сообщений с 21 по 30 из 40

21

Re: BGT. Делимся опытом: кодинг, решения задач в программировании.

Всем привет, решил, что коллекцию игр я больше развивать не стану, поэтому с честной совестью выкладываю её исходники сюда, может кому пригодится. увы, но звуки выложить не могу по просьбе best reader'a, дабы избежать пранкеров и тому подобного.
https://yadi.sk/d/RT5lGv1MzAtj8

22

Re: BGT. Делимся опытом: кодинг, решения задач в программировании.

хм, ну на четвёрочку пойдёт, хотя виртуальный редактор можно было по проще сделать, зачем проверять на кучу строк одну клавишу, когда можно всё сделать через get_characters

23

Re: BGT. Делимся опытом: кодинг, решения задач в программировании.

Чёрный сталкер, ну я делал, как умел) а про get_characters спасибо, не знал.

24 (Wed-02-17 20:24:10 отредактировано Igorek)

Re: BGT. Делимся опытом: кодинг, решения задач в программировании.

Линейная алгебра!

в програмировании игр можно и, я считаю, нужно использовать линейную алгебру, это упрощает выполнение кода, и его понимание.
да, тригонометрия работает, но тригонометрические функции медленее, этого незаметно, но если мы будем вызывать 2000 тригонометрических функций, то, я думаю, будет видно снижение производительности.
линейная алгебра, это работа с векторами, матрицами и другим, правда я расскажу здесь только о векторах.
за основу брал
https://habrahabr.ru/post/131931/
я буду показывать вычисления, необходимые в 2d игре основанные на векторах, использовать их буду для положений объектов и направлений.
в bgt есть класс vector, который содержит в себе необходимые методы, но я их тут опишу.
примечание. проверил скорость выполнения тригонометрических функций, они на одну десятую быстрее чем считывание из сохранённых значений. чем это объяснить? наверно в bgt тригонометрические ффункции не вычисляют, а тоже берут значения из кэша.
примечание 2. получается нет смысла искать скорость выполнения кода переходя на линейную алгебру, но во-первых, я мог ошибаться в тестировании, а во-вторых, работа с векторами более понятна и предоставляет много возможностей.

сложение, чтобы сложить, складываем компоненты вектора. (3, 3) плюс (4, 4) равно (7, 7).
в bgt просто vector1 = vector2 + vector3;
я сложение использую в совершении движения объектом, да и много где ещё необходимо складывать векторы.

вычитание. чтобы вычесть один вектор из другого нужно вычесть компоненты вектора из соответствующих компонентов другого вектора. (3, 3) минус (4, 4) равно (-1, -1)
в bgt vector1 = vector2 - vector3;
вычитание я использую в получении вектора направления от одного объекта к другому.

Умножение на скаляр, это умножение на число, каждый компонент умножаем на определённое число. (3, 3) умножить на 5 равно (15, 15);
в bgt можно кратко vector1 *= 5;
я ещё не использовал, но можно например для сопротивления, ну например в воде делать шаги меньше, например мы идём на север, вектор движения (0, 1), умножаем на число сопротивления 0.8, получаем (0, 0.8), а вообще этот приём хорошо использовать в гонках, или для самолётов, космических кораблей, где меняется скорость и есть различного рода ускорения и сопротивления.

длина вектора. можно использовать для вычисления растояния, вычисляется по теореме Пифагора, допустим мы в точке (10, 10), а монстр - (14, 13), вычитаем из положения монстра наше положение, получаем (4, 3), берём длину этого вектора, получаем 5. корень квадратный из суммы квадратов сторон, 4 в квадрате плюс 3 в квадрате равно 25, корень из 25 равно 5.
в bgt  (vector1 - vector2).length();
использую для получения громкости звука разных объектов, которые надо слышать, конечно это пригодиться и при вычислениях силы урона по отношению к монстрам и прочего.

Нормализация вектора. своими словами, сокращение вектора до длины равной единицы, необходимо много где и очень важное действие. чтобы вычислить нормализованный вектор надо компоненты вектора разделить на его длину. например, мы в точке (10, 10), к нам идёт монстр, он находится на точке (14, 13), он должен сделать шаг по направлению к нам, шаг его равен конечно же единице, вычисляем направление и нормализуем вектор (10, 10) минус (14, 13) равно (-4, -3) берём длину этого вектора и делим компоненты вектора направления, получаем (-4 делить 5, -3 делить 5) равно (-0.8, -0.6), теперь к местоположению монстра прибавляем получившийся вектор, и вот первый шаг сделан.
в bgt vector new_mob_position = mob_position + (mob_position - position) / (mob_position - position).length(); // где mob position - положение монстра, а position - наше положение
пока не использую, до монстров ещё не дошёл, но сложностей здесь нет. препятствия надо будет проверять, но это уже другая тема

сколярное произведение векторов. умножаем компоненты и складываем их, казалось бы, для чего? позволяет нам вычислять углы направления, ниже покажу функцию, где я это вычисляю, правда тут используется функция аркосинус, как видно без тригонометрии не обойтись, но всего одна функция при вычислениях направления, например для выстрела попал или не попал, в остальном тригонометрия не нужна.
в bgt не знаю как вычислить сколярное произведение, поэтому беру вручную перемножаю иксы векторов и складываю с произведением игриков. если кто вкурсе, отпишитесь, буду благодарен.
как писал, вычисление углов у меня готово. осталось применять на практике.

Векторное произведение. это не сложное действие, позволяет поворачивать вектора направления на 90 кратные градусы, описывать это не буду, можете почитать в статье на хабре.
я написал функцию поворота на любой градус, зачем нам ещё функция, которая будет по 90 поворачивать?

Базисный вектор. вот эта тема очень интересная и сложноватая, дело в том, что у нас обе оси имеют направления, ось икс это (1, 0), а игрик - (0, 1), это и есть базисные вектора, нужно нам это для того, чтобы поворачивать карту, вернее вычислять другие позиции объектов в зависимости от нашего направления, ну например если я смотрю направнои нахожусь на точке (1,1), то объект который находится в точке(4, 4) должен оказаться в точке (4, -4), это объяснять подробно не буду, но в ниже описаных кодах, я это покажу.
советую изучить базисные вектора, мы этим крутим мир, а главное после того как разберётесь, оно оказывается совсем не сложным.

а теперь код.
я создал полностью с нуля свой sound_pool, и модуль math.bgt, в последнем находятся функции вычисления, у самтупи это был rotation.bgt. в sound_pool я покажу 2 способа вычисления новой точки объекта в зависимости от нашего поворота, а в math  я покажу всё.
начнём с math.bgt

#include "direction_vectors.bgt"; // подключается модуль в котором объявлен константный массив из нормализованых векторов направления, я их вычислил их 360, и беру из кэша, чтобы не вычислять каждый раз

const double PI = 3.1415926535897932384626433832795; // число PI
const int decimal_places = 2; // величина округления, использую в расчёте расстояния, если клетка это метр на метр, то расстояние с точностью до сантиметра, этого достаточно

// ниже константы для поворотов, я их хотел убрать, но оставил пока, честно говоря они не нужны
const int north=0;
const int northeast=45;
const int east=90;
const int southeast=135;
const int south=180;
const int southwest=225;
const int west=270;
const int northwest=315;

// функция возвращает новое положение, нужно для движения
vector move(vector this_vector, int dir) { // принимаем позицию, и направление в градусах, возвращаем новый вектор
if (dir < 0 or dir > 359) { dir = normaly_dir(dir); } // если градусы за пределами 0..359, то вычисляем градус, например если dir будет 500 то нормализуется до 140 градусов.
return this_vector + direction_vectors[dir];// прибавляем к позиции, вектор из массива с индексом dir. никаких синусов
}

// функция поворота направо на определённый градус
int turn_right(int dir, int turn_step) { // принимаем направление в градусах и количество градусов на который надо повернуть, возвращаем новое направление в градусах
dir += turn_step;
if (dir < 0 or dir > 359) { dir = normaly_dir(dir); } // нормализуем направление и тут, вдруг вышли за пределы 0..359
return dir;
}

// аналогичная функция с поворотом налево
int turn_left(int dir, int turn_step) {
dir -= turn_step;
if (dir < 0 or dir > 359) { dir = normaly_dir(dir); }
return dir;
}

// вычисляем дистанцию между двумя точками
double get_distance(vector v1, vector v2) { // принимаем 2 вектора местоположений, возвращаем число с плавающей запятой округлённое до двух чисел после запятой
return round((v1 - v2).length(), decimal_places); // вычли вектор из вектора, взяли длину получившегося вектора и округлили
}

// функция вычисляет направление из одной точки на другую
int get_angle(vector v1, int dir, vector v2) { // принимает позицию и направление объекта и позицию куда надо вычислить направление, возвращает число в градусах
vector vec_dir = normaly_vector(v2 - v1); // вычислили вектор направления и нормализовали его
if (dir < 0 or dir > 359) { dir = normaly_dir(dir); } // если градусы за пределами 0..359, то нормализовали направление в градусах
int a = round(arc_cosine(round(direction_vectors[dir].x * vec_dir.x + direction_vectors[dir].y * vec_dir.y, 4)) / PI * 180, 0); // вычислили по формуле угол, и округлили до 4 знаков после запятой, однако угол в 180 градусов а не в 360
if (direction_vectors[dir].y * vec_dir.x - direction_vectors[dir].x * vec_dir.y < 0) a = 360 - a; // если угол отрицательный, то вычисляем его отнимая от 360, тем самым получаем чёткий угол направления на точку
if (a < 0 or a > 359)
return normaly_dir(a);
else
return a;
}

// функция нормализации градусов
int normaly_dir(int dir) {
dir %= 360;
if (dir < 0) dir += 360;
return dir;
}

// функция нормализации вектора
vector normaly_vector(vector v) {
return v / v.length();
}

пока что всё в этом модуле.
в sound_pool я вычисляю позицию объекта относительно нас двумя способами
1. тригонометрический
double a=normaly_dir(dir)*PI/180; // вычислили угол в радианах
double x = (sound_vector.x - listener_vector.x) * cosine(a) - (sound_vector.y - listener_vector.y) * sine(a);
double y = (sound_vector.y - listener_vector.y) * cosine(a) + (sound_vector.x - listener_vector.x) * sine(a);
где sound_vector - вектор положения объекта, listener_vector - вектор слушателя, dir - число в градусах на сколько повёрнут слушатель
работает как оказалось достаточно быстро, 250000 итераций на слабом железе меньше секунды
2. векторный
int dir2 = normaly_dir(90 - dir); // взяли базисный вектор оси x, вернее повёрнутый базисный вектор оси x относительно слушателя
double x = (sound_vector.x - listener_vector.x) * direction_vectors[dir2].x + (sound_vector.y - listener_vector.y) * direction_vectors[dir2].y * (-1);
double y = (sound_vector.x - listener_vector.x) * direction_vectors[dir2].y + (sound_vector.y - listener_vector.y) * direction_vectors[dir2].x;
также вычислили x и y точки относительно нас., но работает немножко дольше чем тригонометрия, что удивительно.

впринципе всё, в целом могу сказать что не смотря на то, что тригонометрия работает в bgt быстро, я за векторы, они в bgt есть, с ними работать легко, дело за вами по какому пути будете идти, но большинство игр как я понимаю используют линейную алгебру.

Хорошо(+) Плохо(-)

25 (Sat-06-17 13:51:41 отредактировано Danstiv)

Re: BGT. Делимся опытом: кодинг, решения задач в программировании.

привет всем, я вот недавно начал писать модуль для создания меню, потому что extended_menu меня не устраивал, так как нельзя, или я не разобрался как, делать динамические меню, например если в настройках включена возможность перевода, то ниже добавить пункт выбора языка, а если переводчик выключен, то пункт выбора языка пропадает, у меня это реализовано с помощью присваиванию пунктам меню уникальных имён, которые в последствии можно получить, и уже от них отталкиваться, ниже напишу код модуля, постараюсь всё прокоментировать.

class menu_items {
//создали класс элемента меню
string name;
string option;
//создали две переменные, отвечающие за название пункта меню и за его, так называемое имя
menu_items(string opt, string n) {
option=opt;
name=n;
}
menu_items() {
}
//создали два конструктора, первый для создания, второй без параметров, чтобы компилятор не ругался.
}
class dynamic_menu {
//создали класс меню
sound_pool sm;
//создали объект sound_pool, для воспроизведения звуков меню
menu_items []menu_item;
//создали массив элементов меню
sound music_sound;
//звук музыки в главном меню, можно конечно через sound_pool, но так проще изменять громкость
bool enable_home_and_end;
//флаг, можно ли использовать клавиши начало и конец для навигации между первым и последним пунктом меню, сразу хочу сказать, что все свойства не выставляются через функции, как это было в extended_menu, я не вижу в этом смысла, создавать функцию, единственной задачей которой является установка значения переменной, переданной через параметр, поэтому все свойства будем задавать на прямую
bool enable_pages_keys_moveing;
//этим флагом мы задаём возможность переключать по несколько пунктов меню при помощи клавиш страница вверх и вниз
string pages_moveing_sound;
//звук перемещения страницами вверх и вниз
int pages_moveing_value=1;
//количество единиц, на которое нас будут перемещать страницы
string home_and_end_sound;
//звук, который будет играться при использование клавиш начало и конец
string music;
//название звука, в котором у нас музыка, она будет играть при запуске меню
bool enable_up_and_down;
bool enable_left_and_right;
//две переменных, которые отвечают за возможность использования клавиш перемещения стрелками вверх вниз, или влево вправо соответственно, при установки двух флажков в положение true меню будет по четырём направлениям
bool allow_escape;
//можно ли использовать эскейп для выхода
bool wrap;
//будет ли меню циклическим
string click_sound;
//звук перемещения по меню
string enter_sound;
//звук активации пункта меню
string edge_sound;
//звук края меню, если оно не циклическое
string escape_sound; 
//звук, который играется при нажатии эскейпа
string open_sound;
//звук, играющийся при старте меню
string wrap_sound;
//звук прокрутки меню, то-есть переход с последнего пункта меню на первый и наоборот
timer move_timer;
timer wait_timer;
//таймеры, необходимые для красивого перемещения
int move_time=80;
//количество миллисекунд, через которое происходит прокрутка меню
int wait_time=400;
//количество миллисекунд, через которое, после зажатия стрелки, начинается быстрое перемещение
string volume_parameter="volume";
//название параметра, в котором будет сохранена громкость музыки, она записывается в риестр
string volume_section;
//название раздела, в котором будет храниться параметр с громкостью, его можно назвать также, как называется ваша игра.
string volume_company;
//название компании, тоже для создания отдела в риестре, можно присвоить название вашей компании.
timer volume_timer;
//таймер изменения громкости
int volume_time=50;
//скорость увеличения/уменьшения громкости музыки
settings volume;
//объект работы с риестром
dynamic_menu() {
}
//конструктор без параметров
void add_item(string o, string n="") {
menu_items i(o, n);
menu_item.insert_last(i);
}
//функция добавления пункта меню, первый параметр имя пункта меню, который мы будем видеть, второй не обязательный, задаёт уникальное наименование пункта меню.
string get_name(int number) {
if(number<1 or number>menu_item.length())
return "";
return menu_item[number-1].name;
}
//главная фишка модуля, функция получения уникального имени по номеру пункта меню, получаемого при помощи функции run
void reset(bool all=false) {
menu_item.resize(0);
if(all) {
music_sound.close();
music="";
enable_up_and_down=false;
enable_left_and_right=false;
allow_escape=false;
wrap=false;
click_sound="";
enter_sound="";
edge_sound="";
escape_sound="";
open_sound="";
wrap_sound="";
wait_time=400;
wait_timer.restart();
move_timer.restart();
move_time=80;
volume_section="";
volume_parameter="volume";
volume_company="";
volume_timer.restart();
volume_time=50;
}
}
//функция сброса, с не обязательным параметром полного сброса, при неполном сбрасываются только элементы меню, при полном объект меню возвращается в исходное состояние
int run(string intro, int position=0) {
int counter=position-1;
if(counter>menu_item.length())
counter=-1;
if(open_sound!="")
sm.play_stationary(open_sound, false);
if(music!="") {
music_sound.stream(music);
bool result=volume.setup(volume_company, volume_section, true);
if(!result)
alert("Error", "Could not access the registry.");
music_sound.volume=volume.read_number(volume_parameter);
}
music_sound.play_looped();
speak(intro, true);
while(true) {
wait(5);
main_loop();
if(net)
net_loop();
if(menu_item.length()==0) {
music_sound.close();
return -1;
}
if(enable_pages_keys_moveing and (key_down(KEY_LSHIFT) or key_down(KEY_RSHIFT))) {
if(key_pressed(KEY_PRIOR)) {
counter-=pages_moveing_value;
if(counter<0)
counter=0;
if(pages_moveing_sound!="")
sm.play_stationary(pages_moveing_sound, false);
else if(click_sound!="")
sm.play_stationary(click_sound, false);
speak(menu_item[counter].option, true);
}
if(key_pressed(KEY_NEXT)) {
counter+=pages_moveing_value;
if(counter>menu_item.length()-1)
counter=menu_item.length()-1;
if(pages_moveing_sound!="")
sm.play_stationary(pages_moveing_sound, false);
else if(click_sound!="")
sm.play_stationary(click_sound, false);
speak(menu_item[counter].option, true);
}
}
if(enable_home_and_end) {
if(key_pressed(KEY_HOME)) {
counter=0;
if(home_and_end_sound!="")
sm.play_stationary(home_and_end_sound, true);
else if(click_sound!="")
sm.play_stationary(click_sound, false);
speak(menu_item[counter].option, true);
}
if(key_pressed(KEY_END)) {
counter=menu_item.length()-1;
if(home_and_end_sound!="")
sm.play_stationary(home_and_end_sound, true);
else if(click_sound!="")
sm.play_stationary(click_sound, false);
speak(menu_item[counter].option, true);
}
}
if(allow_escape and key_pressed(KEY_ESCAPE)) {
if(escape_sound!="")
sm.play_stationary(escape_sound, false);
music_sound.close();
return 0;
}
if(music_sound.active and key_up(KEY_LSHIFT) and key_up(KEY_RSHIFT)) {
if(key_down(KEY_NEXT) and volume_timer.elapsed>volume_time) {
volume_timer.restart();
music_sound.volume=music_sound.volume-2;
volume.write_number(volume_parameter, music_sound.volume);
}
if(key_down(KEY_PRIOR) and volume_timer.elapsed>volume_time) {
volume_timer.restart();
music_sound.volume=music_sound.volume+2;
volume.write_number(volume_parameter, music_sound.volume);
}
}
if((enable_up_and_down and (key_pressed(KEY_UP) or (key_down(KEY_UP) and move_timer.elapsed>move_time and wait_timer.elapsed>wait_time))) or (enable_left_and_right and (key_pressed(KEY_LEFT) or (key_down(KEY_LEFT) and move_timer.elapsed>move_time and wait_timer.elapsed>wait_time)))) {
move_timer.restart();
if(!wrap) {
if(counter<0) {
counter=menu_item.length()-1;
if(click_sound!="")
sm.play_stationary(click_sound, false);
}
else if(counter>0) {
counter--;
if(click_sound!="")
sm.play_stationary(click_sound, false);
}
else {
if(edge_sound!="")
sm.play_stationary(edge_sound, false);
}
}
else {
counter--;
if(counter<0) {
counter=menu_item.length()-1;
if(wrap_sound!="")
sm.play_stationary(wrap_sound, false);
}
else {
if(click_sound!="")
sm.play_stationary(click_sound, false);
}
}
speak(menu_item[counter].option, true);
}
if((enable_up_and_down and (key_pressed(KEY_DOWN) or (key_down(KEY_DOWN) and move_timer.elapsed>move_time and wait_timer.elapsed>wait_time))) or (enable_left_and_right and (key_pressed(KEY_RIGHT) or (key_down(KEY_RIGHT) and move_timer.elapsed>move_time and wait_timer.elapsed>wait_time)))) {
move_timer.restart();
if(!wrap) {
if(counter<menu_item.length()-1) {
counter++;
if(click_sound!="")
sm.play_stationary(click_sound, false);
}
else {
if(edge_sound!="")
sm.play_stationary(edge_sound, false);
}
}
else {
counter++;
if(counter>=menu_item.length()) {
counter=0;
if(wrap_sound!="")
sm.play_stationary(wrap_sound, false);
}
else {
if(click_sound!="")
sm.play_stationary(click_sound, false);
}
}
speak(menu_item[counter].option, true);
}
//if((enable_up_and_down and key_up(KEY_UP) and key_up(KEY_DOWN)) or (enable_left_and_right and key_up(KEY_LEFT) and key_up(KEY_RIGHT)))
if(key_up(KEY_UP) and key_up(KEY_DOWN) and key_up(KEY_LEFT) and key_up(KEY_RIGHT))
wait_timer.restart();
if(key_pressed(KEY_RETURN) and counter>-1) {
music_sound.close();
return counter+1;
}
}
return -1;
}
//функция меню, принимает 2 параметра, первый отвечает за то, что будет говориться при старте, второй за позицию курсора, саму функцию не коментировал, кому нужно разберётся.
}
//закрыли класс
вот модуль, с помощью которого осуществляется вывод сообщений, он правдо не доработан, библиотеку nvda приходится загружать при запуске игры вручную
int reader;
//номер ридера
void check_and_setup_screen_reader() {
if(screen_reader_is_running(JAWS)) {
install_keyhook();
reader=1;
}
if(screen_reader_is_running(NVDA)) {
reader=4;
}
}
//функция проверки скринридера
void speak(string text, bool stop) {
if(stop==true)
screen_reader_stop_speech(reader);
screen_reader_speak(reader, text);
}
//функция вывода речи, первый параметр текст, второй параметр отвечает за пренудительность сообщения
void dlg(string text) {
speak(text, false);
while(true) {
wait(5);
if(key_pressed(KEY_LEFT) or key_pressed(KEY_RIGHT) or key_pressed(KEY_DOWN) or key_pressed(KEY_UP))
speak(text, true);
if(key_pressed(KEY_ESCAPE) or key_pressed(KEY_RETURN))
break;
}
}
//функция вывода сообщения, которое вам может быть знакомо по stw или up, она принемает в качестве параметра текст, и этот текст мы можем повторять стрелками, чтобы закрыть его нужно нажать энтер или эскейп
void screen_reader_stop() {
screen_reader_stop_speech(reader);
}
//хоть смысла функции и нет, но я её всё-таки написал, она нужна для остановки речи

вот как-то так, зарание извиняюсь за опечатки, или неточность в коментариях, я надеюсь этот модуль будет вам полезен.

26

Re: BGT. Делимся опытом: кодинг, решения задач в программировании.

приветы!
почитав статьи, комментарии и посты на форумах, стал подозревать, что люди либо не используют ооп в bgt либо используют, но плохо понимают как это всё работает, извините, если кого обидел, я просто хочу рассказать об этом, чтобы все могли полноценно кодить, верю что это ещё актуально.
сразу хочу сказать, что нужно понять теоретические моменты, так чтобы не путаться, и я начну с этого, но кратко.
ооп позволяет описывать, создавать и использовать объекты в программе, это значит, что описав один раз птицу, мы сможем создать множество птиц по образцу или шаблону, если бы не было ооп, то каждую птицу мы бы описывали отдельно, что черевато тоннами кода, и плохой читабельностью.
итак, шаблон - это описательная часть объектов, в нем мы описываем свойства, которые должны быть, в нашем случае у птиц, правильно шаблоны называются классами, очень надо четко понимать, что класс, это шаблон, а объект - это сущность созданная на основе класса.
в статье на сайте blind-games.ru я прочёл, что люди это класс, а человек это объект, это в корне не так, поэтому наверно вам сложно понять эту тему в програмировании, попробую объяснить.
мы всё же будем операться на птиц, вот есть птица, любая птица, если она есть в реальности, ну то есть вот она сидит на ветке, но мы не знаем что это за птица, то это объект, это сущность которая имеет признаки птицы, ну например, крылья, клюв, давайте даже скажем, что её создал кто-то на основе класса птицы, то есть по описательному шаблону.
вот она сидит, может чирикает там на своём, она существует, надеюсь понятно что это объект сидит на ветке, а не класс.
как бы смешно я не описывал, хочу чтоб было находчиво и просто, чтобы было понятно, отнеситесь к этому моменту серъезно.
идём далее.
ворона. как выглядит ворона, ну пусть есть клюв как у любой птицы, и она чёрная. ворона каркает, вот минимум что мы знаем о ней, однако я не говорю что ворона сидит вот именно эта ворона, просто говорю о классе птиц ворона, то есть это описательная часть, конкретной вороны нет.
если мы напишем класс ворона, напишем там её свойства, ну например цвет размер, то потом можем рассадить их на любых ветках, создав 100500 объектов ворона, научим их каркать и перемещаться.
а как научить объекты ворона перемещаться? мы должны в классе ворона описать метод переместиться, а у объектов вызывать этот метод.
надеюсь понятно, что все признаки объекта и действия описываются в классе, а при создании вороны мы уже можем ей присвоить признаки и вызывая методы заставлять её что-то делать.
если в классе есть признак возраст, то при создании объекта этот возраст можем определить, ну взять и создать ворону молодую и старую.
поэтому когда говорят люди это класс, а человек - это  объект, это не верно, это 2 класса, а вот именно этот человек - это уже объект.
вообще не представляю себе класс люди, расса людей как класс это более реально.
если эти моменты усвоены, то идём дальше, переходим к практике, и уверяю вас это не сложно. когда я програмировал только переменными и массивами меня всё устраивало, когда я начал програмировать используя ооп, я понял что меня раньше не всё устраивало, и я на самом деле очень сильно мучался.
п.с. конечно будут и теоретические вставки, и я постараюсь написать много, не пугайтесь, просто перечитывайте, это нужно понять, а главное практика.

Статья большая, читайте тут
https://yadi.sk/i/ooAS6zoX3N2RUb

Хорошо(+) Плохо(-)

27

Re: BGT. Делимся опытом: кодинг, решения задач в программировании.

Привет всем.

Igorek пишет:

приветы!
почитав статьи, комментарии и посты на форумах, стал подозревать, что люди либо не используют ооп в bgt либо используют, но плохо понимают как это всё работает, извините, если кого обидел, я просто хочу рассказать об этом, чтобы все могли полноценно кодить, верю что это ещё актуально.

Ну хорошая же статья. Правда. Вот только не понятно, кто запрещает добавить на blind-games. Я неоднократно уже говорил о том, что если материал будет лучше того, что присылает Костя Рыжиков, я опубликую удалив его статью.
Да и вообще, если есть материал лучше, чем на сайте, то он будет опубликован.

28

Re: BGT. Делимся опытом: кодинг, решения задач в программировании.

Привет всем, статья не плохая, сам с классами работаю достаточно давно, и по ним вопросов нет, а вот на счёт дескрипторов, спасибо, теперь ясны некоторые вещи, и вторую часть хотелось бы увидеть, потому что сам так до конца и не понял, как работает наследование, перезапись и т.д.

29

Re: BGT. Делимся опытом: кодинг, решения задач в программировании.

Антон, я не против, публикуй, если статьи устраивают.

вот по наследованию написал, в статье пытаюсь объяснить наследование, полиморфизм, переопределение методов, немного практики набросал.
https://yadi.sk/d/JM7xRGd23N4Bi7
п.с. я называю дескрипторы ссылками, блин привык, не буду уж переделывать, по сути это ссылки, в других языках вроде даже они так называются, может путаю

Хорошо(+) Плохо(-)

30 (Sat-09-17 18:59:24 отредактировано fenix)

Re: BGT. Делимся опытом: кодинг, решения задач в программировании.

Ну в BGT дескрипторы это которые с собачкой, а ссылки, это я сам до конца не понял что, вобщем их можно использовать только в функциях, там перед именем параметра используется амперсант, хотя я их никогда не использовал

Сообщений с 21 по 30 из 40

Страницы Назад 1 2 3 4 Далее

Чтобы отправить ответ, вы должны войти или зарегистрироваться

Blind games - Звуковые игры незрячим → Создание игр, программирование → BGT. Делимся опытом: кодинг, решения задач в программировании.



Currently installed 4 official extensions. Copyright © 2003–2009 PunBB.

Сгенерировано за 0.077 секунды (91% PHP — 9% БД) 10 запросов к базе данных