Форум программистов, компьютерный форум, киберфорум
C++ Builder
Войти
Регистрация
Восстановить пароль
Блоги Сообщество Поиск Заказать работу  
 
 
Рейтинг 4.79/33: Рейтинг темы: голосов - 33, средняя оценка - 4.79
 Аватар для freemanc
14 / 14 / 6
Регистрация: 27.11.2012
Сообщений: 140

Программа "Путеводитель по учебному заведению"

21.01.2013, 16:55. Показов 6924. Ответов 56
Метки нет (Все метки)

Студворк — интернет-сервис помощи студентам
Создана с целью продолжения затронутой темы про графику (Начало тут: Анимированное изображение в RAD Studio 2010 )
0
Programming
Эксперт
39485 / 9562 / 3019
Регистрация: 12.04.2006
Сообщений: 41,671
Блог
21.01.2013, 16:55
Ответы с готовыми решениями:

Дайте комментарии к учебному коду
нужно прокомментировать все, что после WM_COMMAND ... RECT a,b; POINT a1,b1; ... LRESULT CALLBACK WndProc(HWND hWnd,...

Консультация по учебному курсу для Linux-a
Здравствуйте Форумчане! Решил посоветоваться с вами для создания программы будущего курса "Безопасности Linux". В данный момент...

Путеводитель по разделу
Литература по бд Access и VBA: Cправка Microsoft, самоучитель Taurion, И.Харитонова, В.Михеева "Ms Access" Матвеев Microsoft...

56
 Аватар для QVO
652 / 462 / 80
Регистрация: 26.10.2010
Сообщений: 1,263
Записей в блоге: 4
21.01.2013, 16:57
Краткое руководство по работе с классом TCanvas для начинающих

Не по теме:

так подняли бы ту тему.

1
 Аватар для freemanc
14 / 14 / 6
Регистрация: 27.11.2012
Сообщений: 140
21.01.2013, 17:52  [ТС]
Вы не так поняли, это продолжение существующей темы, мне модератор запретил дальше в старой обсуждать интересующие меня проблемы, т.к. это не вписывается в тему "Анимированное изображение в RAD Studio 2010". А за ссылку спасибо, но уже читал)

Добавлено через 14 минут
Deimon, за время вашего отсутствия я столкнулся с рядом новых проблем и вопросов, которые хотел бы обсудить.

1) Дело дошло до отображения на форме этажа. Мне очень хотелось бы реализовать "хождение" по этажу, отрисовывая только его часть (ну как это делается в мобильных играх: человечек подходит ближе к краю экрана, и карта сдвигается, становится видно куда идти дальше). Вот только как это делать - ума не приложу...

2) Когда этаж будет готов (когда я дорисую изображение), нужно будет предотвращать хождение сквозь стены. Тут 2 варианта: либо определение цвета пикселя, либо регионы о которых Вы говорили. Плюсом в опред. цвета пикс. является простота процесса, а минусом то, что получить цвет можно только левым верхним углом человечка (изображения). На счет регионов - пытался искать какую то инфу, но все время натыкаюсь на формы в виде кругов и многоугольников....

Помогите мне пожалуйста в решении этих вопросов, т.к. они стопорят весь процесс разработки




Просьба ко всем, кто так или иначе сталкивался с подобного рода задачами и вообще с разработкой игр, игровых приложений, кидать по возможности полезную информацию, ссылки, темы, т.к. это будет в помощь всем начинающим
0
 Аватар для QVO
652 / 462 / 80
Регистрация: 26.10.2010
Сообщений: 1,263
Записей в блоге: 4
21.01.2013, 18:10
1. Реализовать класс камеры.
2. Я делал двоичный массив, и проверял так:
X, Y - позиция персонажа
MoveMap[50][50] - двоичный массив заполненный 0 и 1.
0 - нельзя идти, 1 - можно.
abs - вернет целую часть от деления. 327 / 32 = 10
Как найти ячейку в которой сейчас персонаж? Нужно текущую координату разделить на размер спрайта.
+-14 - это центрирования координаты относительно центра изображения игрока
C++
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
void __fastcall TPlayer::Move(int **MoveMap)
{
  if(Move_Up == true)
  {
    if(MoveMap[abs((X+14)/32)][abs((Y+14)/32)-1] != 0)
    {
      if(MoveMap[abs((X-14)/32)][abs((Y+14)/32)-1] != 0)
      {
        Y  -= Speed;
      }
    }
  }
  if(Move_Down  == true)
  {
    if(MoveMap[abs((X-15)/32)][abs((Y-15)/32)+1] != 0)
    {
      if(MoveMap[abs((X+15)/32)][abs((Y-15)/32)+1] != 0)
      {
        Y  += Speed;
      }
    }
  }
  if(Move_Left  == true)
  {
    if(MoveMap[abs((X+14)/32)-1][abs((Y-14)/32)] != 0)
    {
      if(MoveMap[abs((X+14)/32)-1][abs((Y+14)/32)] != 0)
      {
        X  -= Speed;
      }
    }
  }
  if(Move_Right == true)
  {
    if(MoveMap[abs((X-15)/32)+1][abs((Y-15)/32)] != 0)
    {
      if(MoveMap[abs((X-15)/32)+1][abs((Y+15)/32)] != 0)
      {
        X  += Speed;
      }
    }
  }
}
Возьмите листок бумаги, карандаш и все поймете.
1
 Аватар для cpp_developer
20124 / 5691 / 417
Регистрация: 09.04.2010
Сообщений: 22,546
Записей в блоге: 1
22.01.2013, 00:08
Список полезных/интересных тем и решение необычных задач
Раздел: Создание игр, программирование графики
1
Эксперт С++
 Аватар для Avazart
8488 / 6155 / 615
Регистрация: 10.12.2010
Сообщений: 28,683
Записей в блоге: 30
22.01.2013, 05:43
Так задача вроде на тему OpenGL и DirectX, а не С++Builder
( как я понял 3D графика...)
0
 Аватар для freemanc
14 / 14 / 6
Регистрация: 27.11.2012
Сообщений: 140
22.01.2013, 20:29  [ТС]
Avazart, пока что все имеет вид 2D. Как только сдам диплом, буду знакомится и с 3D, т.к. темы очень интересные. Но если у Вас есть что то и про 3D, можете выложить, я с удовольствием ознакомлюсь)

QVO, подскажите пожалуйста:
1) как вы создали событие
C++
1
void __fastcall TPlayer::Move(int **MoveMap)
2) можно чуть подробней про класс камеры?
0
 Аватар для Deimon
35 / 35 / 6
Регистрация: 29.08.2009
Сообщений: 183
05.02.2013, 09:33
HRGN регионы

Мы все с Вами привыкли, что Windows прямоугольный. Вроде к этому ведет всё. Формы, окна все они прямоугольные. Единственный способ бороться с этим - это применять регионы. Использование регионов позволит Вам создавать окна любой формы. Регион в Windows - это замкнутая фигура, обычно для региона применяют английское слово RGN. В MFC есть соотвествующий класс CRgn. Как всегда этот класс соответствует чему-то в Windows. В Windows же есть понятие HRGN, то есть указатель на регион. У каждого приложения есть регион. Вы его можете представить как область, за пределами которой окна не существует. То еть оно может быть, но пока есть регион он обрезает все, что выходит за его область. Любой класс порожденный от CWnd имеет регион.
Я так понял, что регион в памяти компьютера выглядит как указатель на массив прямоугольников (таких как TRect). Отсюда и первая необходимость всегда освобождать память при помощи DeleteObject(). Второе, что нужно понимать, это то что прямоугольная область в памяти компьютера разместится как один TRect (и не важно каких он будет размеров). Тогда как тот же прямоугольник, повернутый на 45 градусов потребует для хранения гораздо больше TRect'ов.

Пример: прямоугольная область 4 на 4 пикселя займет 1 TRect, а та же область повернутая на 45 градусов займет как минимум 7 TRect'ов.


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

1. Объявление региона
C++
1
HRGN имя_региона;
2. Создание региона
C++
1
2
3
4
5
6
7
8
имя_региона = CreateRectRgn(x1,y1,x2,y2); //прямоугольный регион
 
TPoints ArrayOfPoints[]={TPoint(x1,y1),TPoint(x2,y2),TPoint(x3,y3),TPoint(x4,y4),TPoint(x5,y5)};
имя_региона = CreatePolygonRgn(ArrayOfPoints, sizeof(ArrayOfPoints)/sizeof(TPoint), метод_создания);
/*Методы создания:
ALTERNATE = 1, регионом будет каждый четный или нечетное пересечение многоугольника (сложно объяснить, вообщем это Вам не нужно)
WINDING = 2, удобнее использовать этот метод. Все что входит в контур точек будет регионом
*/
3. Удаление региона
Это обязательно по завершению каждого использования. Как и с оператором new.
C++
1
DeleteObject(имя_региона);
4. Работа с регионами
Вам понадобится проверка на пересечение с регионами, поэтому вот набор полезных методов:

Проверка на вхождение точки в регион.
C++
1
2
3
4
5
BOOL PtInRegion(
  _In_  HRGN hrgn,
  _In_  int X,
  _In_  int Y
);
Проверка на вхождение прямоугольной области (TRect) в регион.
C++
1
2
3
4
BOOL RectInRegion(
  _In_  HRGN hrgn,
  _In_  const RECT *lprc
);
К сожалению нормаьной функции, которая говорила бы есть пересечение регионов или нет - я не знаю, но пользуюсь таким методом с fnCombineMode со значением RGN_AND.
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
int CombineRgn(
  _In_  HRGN hrgnDest,
  _In_  HRGN hrgnSrc1,
  _In_  HRGN hrgnSrc2,
  _In_  int fnCombineMode
);
/*
fnCombineMode:
RGN_AND - создает пересечение двух областей
RGN_COPY - создает копию региона hrgnSrc1, hrgnSrc2 игнорируется, можно написать NULL
RGN_DIFF - объединяет части hrgnSrc1, которые не являются частью hrgnSrc2
RGN_OR - объединяет два региона
RGN_XOR - объединяет два региона, кроме области их пересечения
*/
Этот метод возвращает следующие значения:
NULLREGION - полученный регион пустой (тоесть пересечений нет)
SIMPLEREGION - регион состоит из одного прямоугольника (тоесть пересечение есть)
COMPLEXREGION - регион состоит из нескольких прямоугольников (опять же, пересечение)
ERROR - ошибка при создании региона. (Если что-то не получается и регионы у Вас не работают, советую поставить проверку на получение такой ошибки, возможно что-то не правильно объявили или потеряли указатель.

Для использования этого метода, помимо двух регионов, которые надо проверить, придеться создать третий регион, который Вы будете передавать в качестве параметра hrgnDest. Он обязательно должен быть инициализирован. Например HRGN tempRgn = CreateRectRgn(0,0,0,0); Этого вполне достаточно. А по окончанию работы с ним, не забудьте удалить.
Вложения
Тип файла: rar example.rar (5.98 Мб, 24 просмотров)
1
 Аватар для Deimon
35 / 35 / 6
Регистрация: 29.08.2009
Сообщений: 183
05.02.2013, 10:12

Не по теме:

В последнем сообщении, я прикрепил примитивный пример того, что Вам нужно (example.rar) (камера, карта, столкновения)


Цитата Сообщение от freemanc Посмотреть сообщение
1) как вы создали событие
по всей видимости, это метод Move, созданный в классе TPlayer.

Цитата Сообщение от freemanc Посмотреть сообщение
1) Дело дошло до отображения на форме этажа. Мне очень хотелось бы реализовать "хождение" по этажу, отрисовывая только его часть (ну как это делается в мобильных играх: человечек подходит ближе к краю экрана, и карта сдвигается, становится видно куда идти дальше). Вот только как это делать - ума не приложу...
Ну тут на самом деле проще, чем кажется. Вам ведь нужно чтобы персонаж был в кадре камеры. Следовательно, камера должна знать где персонаж находится - то есть получать координаты игрока. Дальше можно добавить условие, что если персонаж находится в какой-нибудь ограниченной области в центре экрана, то камеру не трогать, а как только персонаж выйдет за границы области, то отцентровать камеру на персонаже и следовательно задать границы новой области, в которой персонаж может перемещаться не тревожа камеру.

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

Цитата Сообщение от freemanc Посмотреть сообщение
На счет регионов - пытался искать какую то инфу, но все время натыкаюсь на формы в виде кругов и многоугольников....
Действительно, регионы предназначены для предания формы окну. Но это не значит, что этим возможности применения регионов ограничиваются =)
Круги и многоугольники вам врятли понадобятся (разве что прямоугольник(CreateRectRgn(x1,y1,x2,y2) , чтобы создать пустой регион или область стены). Но вот создание региона по точкам, - вполне годный инструмент для описания сложных фигурных форм в 2D (CreatePolygonRgn(...) с методом создания региона WINDING).
1
 Аватар для freemanc
14 / 14 / 6
Регистрация: 27.11.2012
Сообщений: 140
24.02.2013, 19:11  [ТС]
Здравствуйте Deimon. Огромное спасибо регионы, многое теперь стало понятным. И отдельное спасибо за sample, особенно за камеру!) Простите что долго не заходил, вообще не было времени...(

Касательно регионов:
Не поймите меня неправильно, но - больше узнав о них, у меня возникло больше сомнений об их использовании. Я с огромным удовольствием и не задумываясь использовал бы их, если бы это был не диплом.
Вот один из 6 этажей который необходимо нарисовать в разрешении, раза в 4-5 больше чем в примере:

Я конечно же не отбрасываю категорично использование регионов в проекте, думаю будут места где они понадобятся.

И если я буду рисовать каждую стену как регион, то 6-й этаж я закончу к новому году, не раньше=) (если, конечно же, я не ошибаюсь). И мне кажется единственным способом, (опять же, могу ошибаться), решения данной задачи через регионы в поставленные сроки - это создание некоего редактора карты, в котором можно будет эти регионы рисовать и сохранять координаты их позиций и само размещение, по другому я себе этого не представляю. Но, конечно же, это очень сложный и трудоемкий процесс, тем более пока что и не для моего ума (если это вообще реально)...

По этому я и использую примитивный способ предотвращения коллизий через определение цвета.
Так выглядит этаж, на котором я тренировался ловить столкновения:

В каждой из комнат будет находится знак "?", нарисованный либо как регион, либо как и сам человечек. Когда координаты человечка столкнуться с координатами значка, будет выскакивать окно с описанием данной комнаты.

Ознакомившись с содержанием вашего файла sample, я немного переделал свой проект. У меня была очень похожая на вашу реализация перемещения, но она не совсем корректно работала, т.к. была описана в событии FormKeyDown.
По этому я кое что сделал как у вас.

Но появились новые проблемы:
1) человечек ходит нормально, пока не сталкивается со стеной. После столкновения он не может двигаться
2) Нужен ваш совет - где лучше всего описывать смену анимации движения персонажа? (нажали "Влево" - анимация сменяется на движение влево, и т.д.)
3) Пытаюсь изучить ваш класс камеры, но многое до сих пор не ясно. Не могли бы вы написать небольшие комментарии к содержимому класса, пожалуйста.
Помогите мне пожалуйста в решении вопросов.
Проект:
Animation.rar
0
 Аватар для freemanc
14 / 14 / 6
Регистрация: 27.11.2012
Сообщений: 140
01.03.2013, 01:03  [ТС]
с 1-й проблемой разобрался, сделав буфер анимации, с помощью которого определял, можно идти или нет, теперь все нормально работает. Над 3-й работаю, а вот 2-ю проблему никак не могу решить. Все дело в том, что анимация просто не успевает проиграться до конца, и её начинает загружать заново функция в таймере, и если увеличить интервал, смена будет происходить некрасиво и с запаздыванием.
Вот переделанный проект, с обработкой коллизий ( способ конечно "дубовый", но все же рабочий)
Коллизия.rar
0
 Аватар для Deimon
35 / 35 / 6
Регистрация: 29.08.2009
Сообщений: 183
11.03.2013, 13:36
freemanc, доброго времени суток. Взглянув на Ваш план здания, создалось впечатление, что регионами тут можно воспользоваться от силы раз или два, а все остальное описать при помощи TRect. При чем, как мне кажется, легче описать TRect'ами не препятствия а зоны по которым можно перемещаться. Но для этого надо инвертировать логику =)

Цитата Сообщение от freemanc Посмотреть сообщение
использую примитивный способ предотвращения коллизий через определение цвета
Не скорю, что задумывался о подобной (хотел в сплайновой графике попадание так определять, создать маску изображения и не раставлять никаких границ), но из-за нахождения альтернативных решений как то не дошло. Поэтому в логике мало чем помочь смогу.

Цитата Сообщение от freemanc Посмотреть сообщение
В каждой из комнат будет находится знак "?", нарисованный либо как регион
думаю TRect будет вполне достаточно, или же TPoint'ом (поставить точку, и проверять не входит ли эта точка в человечка, но TRect'ом будет проще описать "зону" вопросительного знака, чем раставлять вокруг него точки).

Цитата Сообщение от freemanc Посмотреть сообщение
1) человечек ходит нормально, пока не сталкивается со стеной. После столкновения он не может двигаться
Предположительно проблема в том, что сначала Вы проверяете на столкновения, а потом уже перемещаетесь. Или такое бывает, когда перемещение завязано на скорости от пройденного времени, при этом где-то появляется разность пути, который надо пройти.

Цитата Сообщение от freemanc Посмотреть сообщение
2) Нужен ваш совет - где лучше всего описывать смену анимации движения персонажа? (нажали "Влево" - анимация сменяется на движение влево, и т.д.)
Если Вы брали вариант описанный у меня со структурой, то там где определенной кнопке присваивается булево значение, там же менять и анимацию. (событие Нажатия кнопки). А в конце события отжатия кнопки написать блок кода, где проверялось бы значение всех кнопок движения. И если они все отжаты, то загрузить анимацию "стоять на месте"

Цитата Сообщение от freemanc Посмотреть сообщение
3) Пытаюсь изучить ваш класс камеры, но многое до сих пор не ясно. Не могли бы вы написать небольшие комментарии к содержимому класса, пожалуйста.
C++
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
#include <vcl.h> //для использования Graphics::TBitmap
 
class CCamera
{
  private:
    TPoint pos;  
    TRect rect;
  public:
    ~CCamera(void) {};
    CCamera(void) {};
    TRect ShowRect(void) { return rect; }
    TPoint ShowXY(void) { return pos; }
    int ShowX(void) { return (int) pos.x; }
    int ShowY(void) { return (int) pos.y; }
    void ChangePos(TPoint _pos)  //меняет позицию и положение TRect
                           // получая отрицательные или положительные значения.
      {
        pos.x+=_pos.x;
        pos.y+=_pos.y;
        OffsetRect(rect,_pos.x,_pos.y);
      }
    void SetPos(TPoint _pos, int W, int H)
//устанавливает начальную позицию, и ширину и высотой TRect'а 
//необходимо вызывать каждый раз, когда меняется размер экрана
      {
        pos=_pos;
        rect.Left = 0;
        rect.Top = 0;
        rect.Right = W;
        rect.Bottom = H;
        OffsetRect(rect,_pos.x,_pos.y);
      }
    void Follow(TPoint _tag)
//функция получает положение отслеживаемой цели в виде точки.
//и "наводится" на нее путем высчитывания расстояния до цели, деления 
//полученного значения на 2, и прибавления к текущей позиции камеры.
//Таким образом получается что-то вроде плавного и в тоже время не медлительного
//отслеживания.
    {
            //высчитывает расстояние
      int tempX = rect.Left+(rect.Right-rect.Left)/2 - _tag.x;
      int tempY = rect.Top+(rect.Bottom - rect.Top)/2 - _tag.y;
      //делит на два и "разворачивает вектор направления" умножением на -1
      TPoint _pos;
      _pos.x = tempX/2*(-1);
      _pos.y = tempY/2*(-1);
      //отправляет полученные значения.
      ChangePos(_pos);
    }
};
Ваш код у меня не компилится и не запускается =( даже мои проекты не все открываются после отпуска.
Но код посмотрел:
Это я бы вообще убрал. Этот таймер Вам не нужен. Загружайте в событиях нажатия и отжатия клавиш.
C++
1
2
3
4
5
6
7
8
9
 if(animation.MoveLeft==true)
        animation.LoadAnimation("move_left.bmp",0,6);
   else
        animation.LoadAnimation("stay_left.bmp",0,1);
 
   if(animation.MoveRight==true)
        animation.LoadAnimation("move_right.bmp",0,6);
   else
        animation.LoadAnimation("stay_right.bmp",0,1);
красивее было написать в шеснадцатирисчном коде =)
C++
1
2
3
4
5
 if(leftX==13078918)
   {
 
        keys.CanMove=false;
   }
//почему только три точки, а не 4 ?
C++
1
2
3
    TColor leftX = GetPixel(hdc, x, y);    //Цвет левой верхней точки анимации
    TColor downY = GetPixel(hdc, x, y+animation.FrameHeight);  //Цвет нижней точки анимации
    TColor rightX = GetPixel(hdc, x+animation.FrameWidth, y);  //Цвет правой верхней точки анимации
Хорошо бы взглянуть на маску этажа. Мне показалось что у вас в перемещении считается каждый пятый пиксель, следовательно стена в ширине должна быть не меньше.

И кажется нашел ошибку из-за которой у вас не работали столкновения:
вместо
C++
1
2
x = animation.GetX()+Form1->Left+7;
    y = animation.GetY()+Form1->Top+31;
попробуйте так
C++
1
2
x = animation.GetX()+Form1->Left+7+pos.x;
    y = animation.GetY()+Form1->Top+31+pos.y;
1
 Аватар для freemanc
14 / 14 / 6
Регистрация: 27.11.2012
Сообщений: 140
12.03.2013, 02:01  [ТС]
Здравствуйте Deimon, рад снова Вас видеть) Я сильно благодарен Вам за example, файлы внутри открыли мне на многое глаза, и, что самое главное, дали понять некоторые принципы и механику, это очень помогло)
За время Вашего отсутствия мне удалось продвинуться дальше в ходе реализации проекта, чему я несказанно рад))
Подробнее об изменениях:
1) Удалось упростить алгоритм с определением цвета. Раньше использовалась функция CreateDCA(...) которая делала скрин экрана, записывала его в переменную, ф-ей GetPixel(...) определяла цвет, при этом координаты точки нужно было постоянно корректировать по отношению к окну (ну вобщем, бред)
И тут вдруг нашлось и вспомнилось свойство канвы - Pixels[][], которое помогло увеличить производительность и упростить весь алгоритм
2)
...думаю TRect будет вполне достаточно, или же TPoint'ом
Наконец то я допер механизм работы с TRect-ами, и с большим удовольствием запихнул себе в классы. Механизм, оказывается, очень простой и очень классный (отдельная благодарность содержимому файлов Object.h и Target.h за это)
3)
человечек ходит нормально, пока не сталкивается со стеной. После столкновения он не может двигаться
Решил с помощью "буфера анимации", сдвигая сначала его, и проверяя, нет ли столкновений с объектами и стенами, это то о чем Вы и говорили.
4)
Хорошо бы взглянуть на маску этажа. Мне показалось что у вас в перемещении считается каждый пятый пиксель, следовательно стена в ширине должна быть не меньше.
Не совсем понял про маску, но этаж положил в архив Проект.rar, в папку Debug

5) Со временем я более-менее разобрался с Вашим классом камеры, интересовали больше всего вот эти строчки и "развертывание вектора направления" (что это? ):
C++
1
2
int tempX = rect.Left+(rect.Right-rect.Left)/2 - _tag.x;
      int tempY = rect.Top+(rect.Bottom - rect.Top)/2 - _tag.y;
6)
Ваш код у меня не компилится и не запускается =(
Странно( Даже не знаю в чем прикол, а что пишет?

Вот сам проект, какой он есть на сегодняшний день:
Проект.rar
0
 Аватар для Deimon
35 / 35 / 6
Регистрация: 29.08.2009
Сообщений: 183
14.03.2013, 14:22
Цитата Сообщение от freemanc Посмотреть сообщение
Удалось упростить алгоритм с определением цвета.
Я все же смог запустить ваш проект, правда не с первого раза, у Вас там зачем-то прикреплена библиотека для работы с Gif. Мне не нравится как ловятся стокновения при помощи значения цвета. Вы обратили внимание, что боком можно ходить сквозь стены, а если "разбежаться", то и в лоб можно пройти препятствие)
Чтоб этого не было надо проверять пиксели по всему контуру человечка.
Не понравилось, что вопросы выглядят как препятствия и в комнату невозможно пройти. Да и то что они не пропадают после "использования" - тоже не хорошо.
C++
1
2
3
4
5
        Animation = new Graphics::TBitmap();
        Position.x = x;
        Position.y = y;
        //Rect = TRect(0, 0, 53, 53);
        OffsetRect(Rect, x, y); //без строчки выше - бесполезна и эта строка
C++
1
2
X = rect.Left+(rect.Right-rect.Left)/2;
//Х - центральная точка экрана (камеры) в координатах карты по Х.
Вообщем смысл найти центр экрана и вычесть из нее точку игрока. Получится разница в расстоянии между ними. Чтобы не делать резкого перехода (грубо говоря не приравнивать центральную точку экрана к точке игрока), мы делем ее на два, и добавляем к координатам камеры. Если делить не на два, а на три, то будет еще более плавное "наведение на цель". умножение на -1 нужно просто потому, что я вычитаю из центра точку игрока, если бы я из игрока вычитал точку центра, то лишнее умножение было бы не нужным.
1
 Аватар для freemanc
14 / 14 / 6
Регистрация: 27.11.2012
Сообщений: 140
16.03.2013, 21:27  [ТС]
Цитата Сообщение от Deimon Посмотреть сообщение
у Вас там зачем-то прикреплена библиотека для работы с Gif
Прошу прощения, я совсем забыл что она там болталась...
Цитата Сообщение от Deimon Посмотреть сообщение
Мне не нравится как ловятся стокновения при помощи значения цвета. Вы обратили внимание, что боком можно ходить сквозь стены, а если "разбежаться", то и в лоб можно пройти препятствие)
Чтоб этого не было надо проверять пиксели по всему контуру человечка.
Просто я переживал что если циклически буду проверять каждую сторону прога будет глючить, но каковым было мое удивление, когда это оказалось не так)) Теперь с передвижением человечка все в порядке, цвет определяется каждой точкой периметра.
Не понравилось, что вопросы выглядят как препятствия и в комнату невозможно пройти. Да и то что они не пропадают после "использования" - тоже не хорошо.
Это тоже исправил, теперь после столкновения с "?" его изображение меняется на такое же, только желтого цвета, ходить по нему и по комнате можно.
У меня опять проблемы(
1) С одним этажом вроде бы разобрался, и начал делать переход на 2й. Принцип был таким : создать 2 объекта "лестница" того же типа, что и знаки "?", и при столкновении их TRect'ов с TRect'ом человечка, использовать метод объекта Map - LoadMap(<путь>). Так и сделал, но в итоге получилось так, что столкновения со стенами отслеживаются только на первом этаже, на 2м ничего не происходит
2) В Вашем проекте очень удобно хранились объекты - в векторе. Я решил последовать примеру, и делал тоже самое, но с вектором ничего не получается. Пришлось даже тему отдельную создавать, потому что классы одинаковые, а работает только один. В примере, который я кидал, уже использовался deque. Суть проблемы в следующем: я хотел создать двумерный массив с объектами, что бы было удобней работать, 1 этаж - соответствующий массив объектов, и т.д.
C++
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
Ask temp;
temp.LoadAnimation("Ask.bmp", 0, 1);
 
Rooms.push_back(Ask(temp));
Rooms[0].SetPosition(152, 64);
 
Rooms.push_back(Ask(temp));
Rooms[1].SetPosition(543, 64);
 
Rooms.push_back(Ask(temp));
Rooms[2].SetPosition(935, 64);
 
Rooms.push_back(Ask(temp));
Rooms[3].SetPosition(151, 424);
 
Rooms.push_back(Ask(temp));
Rooms[4].SetPosition(543, 424);
 
Rooms.push_back(Ask(temp));
Rooms[5].SetPosition(927, 424);
 
Objects.push_back(Rooms);
  for(int i=0; i<Rooms.size(); i++)
    Objects[0][i].SetPosition(Rooms[i].Position.x, Rooms[i].Position.y);
Rooms.clear();
 
//Заполнение второго этажа
Rooms.push_back(Ask(temp));
Rooms[0].SetPosition(154, 64);
 
Rooms.push_back(Ask(temp));
Rooms[1].SetPosition(590, 64);
 
Rooms.push_back(Ask(temp));
Rooms[2].SetPosition(970, 64);
Objects.push_back(Rooms);
for(int i=0; i<Rooms.size(); i++)
    Objects[1][i].SetPosition(Rooms[i].Position.x, Rooms[i].Position.y);
Rooms.clear();
Если использовать код до 24 строки, все "?" будут рисоваться, но когда человечек столкнется с ними, изображение, символизирующее посещенный "?" будет рисоваться в точке (0,0), а не в той же, где стоял "?".
Название: trouble1.jpg
Просмотров: 169

Размер: 45.2 Кб ,
в 24-й строчке я пытаюсь присвоить координаты "?" элементам массива Objects, координаты "?" сохраняются, но вместо 6-ти значков "?" рисуются только 2.

Очень нужна Ваша помощь, т.к. с этими проблемами я бьюсь об стену головой уже целый день, перепробовал кучу вариантов, так ничего и не помогло
Помогите мне, пожалуйста, разобраться в чем тут проблема, потому что я уже не знаю что и делать.
Проект:
Проект.rar
0
 Аватар для Deimon
35 / 35 / 6
Регистрация: 29.08.2009
Сообщений: 183
18.03.2013, 10:50
Цитата Сообщение от freemanc Посмотреть сообщение
толкновения со стенами отслеживаются только на первом этаже, на 2м ничего не происходит
потому что стены второго этажа нарисованы другим цветом.

Цитата Сообщение от freemanc Посмотреть сообщение
уже использовался deque
выбор типа массива из STL библиотек обычно обусловленно конкретной задачей. Вы уверены что list не подходит вам лучше?
С проблемой знаков я не разобрался, не понимаю что конкретно должно должно происходить.
1
 Аватар для freemanc
14 / 14 / 6
Регистрация: 27.11.2012
Сообщений: 140
25.03.2013, 23:16  [ТС]
Цитата Сообщение от Deimon Посмотреть сообщение
выбор типа массива из STL библиотек обычно обусловленно конкретной задачей. Вы уверены что list не подходит вам лучше?
С проблемой знаков я не разобрался, не понимаю что конкретно должно должно происходить.
Об этом напишу чуть позже.
Вы говорили, что лучше работать с значением цвета в шестнадцатеричной форме. В фотошопе код цвета, которым рисуются стены первого этажа, имеет код #8691c7, а второго - #8691c8 (как Вы и говорили).
Подскажите пожалуйста, как мне код #8691c8 например представить в "съедобном" для проги шестнадцатеричном виде?
0
 Аватар для Deimon
35 / 35 / 6
Регистрация: 29.08.2009
Сообщений: 183
26.03.2013, 12:38
Цитата Сообщение от freemanc Посмотреть сообщение
как мне код #8691c8 например представить в "съедобном" для проги шестнадцатеричном виде?
вместо # написать 0x ("ноль икс"), а дальше ваше число. Рагистр вроде как не учитывается, тоесть:
C++
1
2
 //0xff = 0XFF = 0xfF = 255.
if (0xff == 0XFF && 0xFf == 255 && 0XfF == 0xFF) ShowMessage("справедливо");
Цитата Сообщение от freemanc Посмотреть сообщение
лучше работать с значением цвета в шестнадцатеричной форме.
лучше не для компьютера, а для Вашего восприятия кода. Я например когда вижу миллионы, то думаю о миллионах. А когда вижу шестнадцатиричное число из шести значений, то в первую очередь думаю о значении цвета, а потом уже о возможных параметрах настраиваемого устройства =)

Цитата Сообщение от freemanc Посмотреть сообщение
стены первого этажа, имеет код #8691c7, а второго - #8691c8
видите какой у меня глаз-алмаз могу различать более 16 млн. цветов))) Девушки с "светло-бледно-розовым" даже в сравнение со мной не идут)))
1
 Аватар для freemanc
14 / 14 / 6
Регистрация: 27.11.2012
Сообщений: 140
26.03.2013, 20:55  [ТС]
Цитата Сообщение от Deimon Посмотреть сообщение
видите какой у меня глаз-алмаз могу различать более 16 млн. цветов))) Девушки с "светло-бледно-розовым" даже в сравнение со мной не идут)))
Что есть то есть)))) Жаль у меня скилла такого нет, сидел вот голову ломал 2 дня=)

Цитата Сообщение от Deimon Посмотреть сообщение
вместо # написать 0x ("ноль икс"), а дальше ваше число.
Так изначально и писал: #8691c7 как 0x8691c7 ( и 0х8691С7) - не работает, хоть убей)
Сегодня нашел выход из ситуации: преобразователь RGB(число, число , число);
Тоесть, в окне фотошопа в палитре нужно брать соответствующие значения :

и записать в функцию: RGB(134, 145, 200);
C++
1
2
if(cPoint == RGB(134, 145, 200))
            ...
0
 Аватар для cpp_developer
20124 / 5691 / 417
Регистрация: 09.04.2010
Сообщений: 22,546
Записей в блоге: 1
26.03.2013, 20:59
Цитата Сообщение от freemanc Посмотреть сообщение
в окне фотошопа в палитре нужно брать соответствующие значения
в билдере есть точно такой же компонент
1
Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
inter-admin
Эксперт
29715 / 6470 / 2152
Регистрация: 06.03.2009
Сообщений: 28,500
Блог
26.03.2013, 20:59
Помогаю со студенческими работами здесь

Путеводитель по городу
Всем привет! Прошу помочь мне с курсовой работой &quot;Путеводитель по городу&quot;. Мне необходима любая помощь. Заранее благодарен.

Путеводитель по кафедрам факультета
Приложение должно выполнять функции путеводителя по кафедрам одного из факультетов университета : 1. схематически отображать расположение...

Путеводитель по книжкам про C++ Builder
Несколько лет назад попытался повысить свой уровень путем осваивания C++ Builder. Накупил кучу книжек. Начал с Архангельского. Всем...

Приложение «Путеводитель по любому городу»
Помогите сделать расчетно-графическую работу.

NTI - ССЫЛКА-ПУТЕВОДИТЕЛЬ СПРАВОЧНИК ДЛЯ ПУТЕШЕСТВУЮЩИХ ПО НОРВЕГИИ
Здравствуйте, мы просто хотим некоторую обратную связь для нашей новой странице информации о поездках и в Норвегии. Конечно, изображения,...


Искать еще темы с ответами

Или воспользуйтесь поиском по форуму:
20
Ответ Создать тему
Новые блоги и статьи
SDL3 для Web (WebAssembly): Вывод текста со шрифтом TTF с помощью SDL3_ttf
8Observer8 01.02.2026
Содержание блога В этой пошаговой инструкции создадим с нуля веб-приложение, которое выводит текст в окне браузера. Запустим на Android на локальном сервере. Загрузим Release на бесплатный. . .
SDL3 для Web (WebAssembly): Сборка C/C++ проекта из консоли
8Observer8 30.01.2026
Содержание блога Если вы откроете примеры для начинающих на официальном репозитории SDL3 в папке: examples, то вы увидите, что все примеры используют следующие четыре обязательные функции, а. . .
SDL3 для Web (WebAssembly): Установка Emscripten SDK (emsdk) и CMake для сборки C и C++ приложений в Wasm
8Observer8 30.01.2026
Содержание блога Для того чтобы скачать Emscripten SDK (emsdk) необходимо сначало скачать и уставить Git: Install for Windows. Следуйте стандартной процедуре установки Git через установщик. . . .
SDL3 для Android: Подключение Box2D v3, физика и отрисовка коллайдеров
8Observer8 29.01.2026
Содержание блога Box2D - это библиотека для 2D физики для анимаций и игр. С её помощью можно определять были ли коллизии между конкретными объектами. Версия v3 была полностью переписана на Си, в. . .
Инструменты COM: Сохранение данный из VARIANT в файл и загрузка из файла в VARIANT
bedvit 28.01.2026
Сохранение базовых типов COM и массивов (одномерных или двухмерных) любой вложенности (деревья) в файл, с возможностью выбора алгоритмов сжатия и шифрования. Часть библиотеки BedvitCOM Использованы. . .
SDL3 для Android: Загрузка PNG с альфа-каналом с помощью SDL_LoadPNG (без SDL3_image)
8Observer8 28.01.2026
Содержание блога SDL3 имеет собственные средства для загрузки и отображения PNG-файлов с альфа-каналом и базовой работы с ними. В этой инструкции используется функция SDL_LoadPNG(), которая. . .
SDL3 для Android: Загрузка PNG с альфа-каналом с помощью SDL3_image
8Observer8 27.01.2026
Содержание блога SDL3_image - это библиотека для загрузки и работы с изображениями. Эта пошаговая инструкция покажет, как загрузить и вывести на экран смартфона картинку с альфа-каналом, то есть с. . .
Влияние грибов на сукцессию
anaschu 26.01.2026
Бифуркационные изменения массы гриба происходят тогда, когда мы уменьшаем массу компоста в 10 раз, а скорость прироста биомассы уменьшаем в три раза. Скорость прироста биомассы может уменьшаться за. . .
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2026, CyberForum.ru