Форум программистов
 

Восстановите пароль или Зарегистрируйтесь на форуме, о проблемах и с заказом рекламы пишите сюда - alarforum@yandex.ru, проверяйте папку спам!

Вернуться   Форум программистов > разработка игр, графический дизайн и моделирование > Gamedev - cоздание игр: Unity, OpenGL, DirectX
Регистрация

Восстановить пароль
Повторная активизация e-mail

Купить рекламу на форуме - 42 тыс руб за месяц

Ответ
 
Опции темы Поиск в этой теме
Старый 09.09.2009, 17:25   #1
Гром
Старожил
 
Аватар для Гром
 
Регистрация: 21.03.2009
Сообщений: 2,193
По умолчанию Компоненты для игр в Билдере; + пара вопросов по проектированию.

Доброго времени суток!

Изучая C++, я решил для отработки навыков написать небольшую и весьма простую игру, жанр - РПГ. Работаю в среде Borland C++ Builder 6, с которой познакомился в универе и серьезных книг по ней не читал, разбирался понемногу сам. Потому хочу спросить у вас, верно ли я определился с приоритетами?
Более точно - какие компоненты лучше всего использовать при создании игры такого жанра в Билдере? Предполагается, что игровой процесс будет проходить в окошке, в основном с использованием мыши. При этом картинка, в которую будет тыкать игрок может содержать не только само игровое поле, но и всякие кнопки/окошки/полоски игрового интерфейса.
Я предполагаю использовать в качестве самой главной (и, возможно, единственной) взаимодействующей с пользователем компоненты PaintBox, а все игровые кнопочки/окошки написать самостоятельно. При нажатии по PaintBox'у программа определяет, по какому элементу игрового интерфейса мы кликнули и уже этот элемент реагирует на щелчок.
Насколько PaintBox подходит для таких целей и вообще насколько целесообразен подобный подход для взаимодействия игры с пользователем?

Кстати, по поводу распознавание нажатого элемента интерфейса - мне в голову пришла пока только одна идея осуществления этого действия, особенно в случае кнопочек-и-др. неправильной формы. У нас имеется еще один невидимый PaintBox, совпадающий по размеру с главным, и он раскрашен так, что контуры расположенных на нем цветных пятен соответствуют контурам кнопочек-и-примкнувшим-к-ним на главном PaintBox'е. Соответственно, каждый цвет маркирует конкретный элемент интерфейса. Таким образом, получение информации о нажатом элементе сводится к определению цвета пикселя по его координатам.
Если же различные кнопочки-сотоварищи меняют свою форму, размер, расположение, оказываются скрытыми, перекрываются главным меню и т.п. - маркировочный PaintBox просто перерисовывается.
Что можно сказать про такой способ - насколько он применим, эффективен, затратен? Есть ли что-то лучше по каким-либо критериям?

Ну и еще такие вопросы уже ближе к внутренней структуры игры. Предполагается, что карта, по которой будет ходить и приключаться персонаж, будет представлена двумерным массивом клеток, каждая из которых содержит информацию о том что на ней находится - во-первых, пустая ли она, либо на ней элемент ландшафта, либо же некий объект, с которым можно взаимодействовать (встав на клетку с ним); во-вторых - ID объекта (0 если пусто). А сами объекты хранятся рядышком в ассоциативном массиве, проиндексированном по этому самому ID.
Все объекты наследуются от общего класса - класс объекта карты, MapObject. Сначала я думал непосредственно от него унаследовать два класса - StaticObject для элементов ландшафта (на клетку с ним нельзя встать, с ним нельзя взаимодействовать) и ActiveObject для доступных для взаимодействия объектов (встал на клетку с ним - начал взаимодействовать). И уже от ActiveObject я хотел наследовать монстров, артефакты, NPC...
Затем решил вовсе выкинуть StaticObject, и предполагать, что MapObject и есть класс для элемента ландшафта, а ActiveObject является его расширением. С одной стороны, StaticObject и впрямь ничего нового в себе не должен нести по сравнению с базовым классом, с другой - не вполне логично считать, что активный объект является частным случаем статичного...
Есть мысль оставить единственный класс MapObject, и прямо от него наследовать монстров, артефакты и пр. Но скорее лучше оставить ActiveObject с чисто виртуальной функцией Interaction() (взаимодействие)... Или же засунуть Interaction() в MapObject и тогда вызывать ее будет совсем просто, а для статичных объектов она не будет делать ничего, да к тому же клетка поля помнит, что на нее нельзя встать.
Ох, долго, нудно и путано получилось как-то...) Прошу прощения за столь "много букв"!)

Стало быть, что вы, уважаемые форумчане думаете по этим вопросам?) Я буду рад мыслям по любому из означенных пунктов!)
Простые и красивые программы - коды программ + учебник C++
Создание игры - взгляд изнутри - сайт проекта
Тема на форуме, посвященная ему же
Гром вне форума Ответить с цитированием
Старый 09.09.2009, 20:20   #2
Beermonza
Инженер ИС
Старожил
 
Аватар для Beermonza
 
Регистрация: 13.12.2006
Сообщений: 2,671
По умолчанию

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

Для объектов используйте один класс GameObject, если он статичен, то флажок на то у него есть, пусть будет False, если динамичен, то флажок True. Зато можно любой объект "оживить" если потребуется. Например, было дерево статичное, пришел дровосек рубить, стало быть теперь дерево - динамический объект игры.
Проходимость лучше хранить отдельно от карты и объектов, все может измениться, например, секретные проходы, левитация персонажей и пр.
Руководитель проекта MMO 2D RPG: Настоящее имя Денис Стрижак (10.05.1981-6.02.2019) Мир духу его
Beermonza вне форума Ответить с цитированием
Старый 09.09.2009, 20:46   #3
Вадим Буренков
Участник клуба
 
Аватар для Вадим Буренков
 
Регистрация: 06.03.2009
Сообщений: 1,346
По умолчанию

А мне кажется что лучше все делать в одном окне растягиваюшемся на весь экран. А с клакссами я особо не заморачиваюся: делаю класс GameObject с параметрами встречающемися у любого объекта. А потом все объекты делаются на его основе. Делать можно как угодно, главное чтоб не слишком сложно и работало .
Вадим Буренков вне форума Ответить с цитированием
Старый 11.09.2009, 18:33   #4
Гром
Старожил
 
Аватар для Гром
 
Регистрация: 21.03.2009
Сообщений: 2,193
По умолчанию

Beermonza, не знал про такой способ, попробую!) Благодарю, что просветили!)
Beermonza, Вадим Буренков, спасибо за совет, буду наследовать всех от одного класса!)
Простые и красивые программы - коды программ + учебник C++
Создание игры - взгляд изнутри - сайт проекта
Тема на форуме, посвященная ему же
Гром вне форума Ответить с цитированием
Старый 11.09.2009, 18:45   #5
Вадим Буренков
Участник клуба
 
Аватар для Вадим Буренков
 
Регистрация: 06.03.2009
Сообщений: 1,346
По умолчанию

Например когда делал космонойд был такой основной класс:
Код:
TGraphicObject = class
//графика
//BmpImage:TBitMap;
//BmpImagePath:string;
//графика
Image:TEffects;

//скорость и координаты
Xpos,Ypos:single;
Xspeed, Yspeed:single;

//логические переменные
Enable:boolean;
//звук
Sound:TSound;

end;
Его потомками были все объекты на экране: оружие, патроны, бонусы, противники, игрок и.т.д.
Вадим Буренков вне форума Ответить с цитированием
Старый 28.01.2010, 15:53   #6
Гром
Старожил
 
Аватар для Гром
 
Регистрация: 21.03.2009
Сообщений: 2,193
По умолчанию

Цитата:
Сообщение от Beermonza Посмотреть сообщение
Для меню в игре лучше использовать вторую форму, без бордеров, установить ей цвет розовый (ну или который в текстурах кнопочек не встречается), установить цвет альфы формы этот цвет, и прозрачность на ноль. Пусть форма двигается синхронно с главной. В результате, вторую форму мы не видим, клик работает только на видимые объекты, кнопки, рисунки, все даже неправильной формы, а все прозрачные места формы не распознаются, считается что клик идет по первой форме, ...это проверено. Ничего придумывать не нужно.
Делаю сейчас меню по вашему совету как раз через вторую форму. Создаю ее, устанавливаю параметры:
Код:
Height, Width
FormStyle - fsStayOnTop
BorderStyle - bsNone
Color
TransparentColor - true
TransparentColorValue
устанавливаю события OnMouseMove, OnClick.
По таймеру синхронизирую координаты обеих форм, на главной рисую фон, на второстепенной - картинки неправильной формы. Все вроде бы хорошо, вот только события OnMouseMove и OnClick, относящиеся к второстепенной форме, срабатывают даже когда курсор находится над ее прозрачной частью. Пробовал устанавливать AlplaBlend на true и AlplaBlendValue на 0, но тогда верхняя форма становилась полностью прозрачной вместе со своими картинками и события на ней не срабатывали.

Есть, конечно, вариант проверять цвет формы в той точке, где находится курсор и вместо "курсор над второй формой"/"курсор над главной формой" использовать "курсор над картинкой"/"курсор над цветом прозрачности", вот только это будет уже стрельба из пушек по воробьям, т.к. тогда можно не использовать вторую форму, а взять вместо нее просто еще один Bitmap...
Простые и красивые программы - коды программ + учебник C++
Создание игры - взгляд изнутри - сайт проекта
Тема на форуме, посвященная ему же
Гром вне форума Ответить с цитированием
Старый 28.01.2010, 21:02   #7
Beermonza
Инженер ИС
Старожил
 
Аватар для Beermonza
 
Регистрация: 13.12.2006
Сообщений: 2,671
По умолчанию

Чтобы окно было полупрозрачным:
AlphaBlend = True
AlplaBlendValue = степень прозрачности (255 - не прозрачная, 0 - полностью прозрачная)

Чтобы скрыть форму, кроме ее объектов:
BorderStyle = bsNone
FormStyle = fsStayOnTop
TransparentColor = True
TransparentColorValue = цвет (тот же что и у формы в Color)

Все работает. Примените OnKeyDown, OnKeyPress, OnKeyUp и все, что с мышью.
Руководитель проекта MMO 2D RPG: Настоящее имя Денис Стрижак (10.05.1981-6.02.2019) Мир духу его
Beermonza вне форума Ответить с цитированием
Старый 29.01.2010, 22:04   #8
Гром
Старожил
 
Аватар для Гром
 
Регистрация: 21.03.2009
Сообщений: 2,193
По умолчанию

Хмм... Вот тестовый проектик:
Код:
//---------------------------------------------------------------------------

#include <vcl.h>
#pragma hdrstop

#include "Unit1.h"
//---------------------------------------------------------------------------
#pragma package(smart_init)
#pragma resource "*.dfm"
TForm1 *Form1;
TForm* SecondForm;
//---------------------------------------------------------------------------
__fastcall TForm1::TForm1(TComponent* Owner)
        : TForm(Owner)
{
}
//---------------------------------------------------------------------------
void __fastcall TForm1::FormCreate(TObject *Sender)
{
SecondForm = new TForm(Form1);
SecondForm -> BorderStyle = bsNone;
SecondForm -> FormStyle = fsStayOnTop;
SecondForm -> Color = TColor(0x008000FF);
SecondForm -> TransparentColor = true;
SecondForm -> TransparentColorValue = TColor(0x008000FF);
SecondForm -> Top = Form1 -> Top;
SecondForm -> Left = Form1 -> Left;
SecondForm -> Show();
}
//---------------------------------------------------------------------------
void __fastcall TForm1::FormDestroy(TObject *Sender)
{
delete SecondForm;
}
//---------------------------------------------------------------------------
void __fastcall TForm1::Button1Click(TObject *Sender)
{
SecondForm -> Canvas -> Pen -> Color = clRed;
SecondForm -> Canvas -> Brush -> Color = clGreen;
SecondForm -> Canvas -> FillRect(TRect(20, 20, 120, 120));
}
//---------------------------------------------------------------------------

void __fastcall TForm1::FormClick(TObject *Sender)
{
Edit1 -> Text = "!";
}
По нажатию на кнопке рисуется (на всякий случай) прямоугольник на второй, прозрачной форме. В общем-то что до нажатия на кнопку, что после клик в области, где находится невидимая форма (в т.ч. по прозрачным ее частям) не приводит к срабатыванию OnClick главной формы. При этом после клика главная форма становится по внешнему виду "неактивной" (или уж как это называется), т.е. в данный момент я щелкнул таки по второй, прозрачной форме, и она становится "впереди планеты всей" пока где-нибудь еще не щелкну.

Может это такое разное видение мира у Билдера и Дельфи?...
Простые и красивые программы - коды программ + учебник C++
Создание игры - взгляд изнутри - сайт проекта
Тема на форуме, посвященная ему же
Гром вне форума Ответить с цитированием
Старый 30.01.2010, 09:35   #9
Swarog
Форумчанин
 
Аватар для Swarog
 
Регистрация: 26.01.2010
Сообщений: 215
По умолчанию

Цитата:
Код:
SecondForm -> TransparentColor = true;
SecondForm -> TransparentColorValue = TColor(0x008000FF);
Ну на сколько я понял в делфи бы это сработало так же, ты устанавливаешь цвет который будет прозрачным, точнее даже не так... цвет на месте которого формы не будет. Следовательно в этом месте форма пропустит щелчок мыши под себя. Поправьте меня если я не прав.

А зачем это извращение с двумя формами?
Могу лишь пнуть в нужном направлении (ну или как получится)

Последний раз редактировалось Swarog; 30.01.2010 в 09:45.
Swarog вне форума Ответить с цитированием
Старый 30.01.2010, 15:56   #10
Гром
Старожил
 
Аватар для Гром
 
Регистрация: 21.03.2009
Сообщений: 2,193
По умолчанию

Swarog, по идее - да. Но мой билдер отказывается игнорировать щелчок по прозрачной части формы, все равно считает, что событие относится именно к ней.
А насчет зачем вторая форма - точно не знаю. Вопрос к Beermonza. Если бы заработало как ожидалось, какой-то прок, вполне возможно, и был бы. Впрочем, я, не зная, из каких соображений Beermonza советовал вторую форму, потихоньку склоняюсь к просто еще одному Bitmap'у. И проще, и наверняка меньше расходов, чем с формой (впрочем, думаю, они не слишком существенны), да и главная форма в любом случае остается тогда активной...
Простые и красивые программы - коды программ + учебник C++
Создание игры - взгляд изнутри - сайт проекта
Тема на форуме, посвященная ему же
Гром вне форума Ответить с цитированием
Ответ


Купить рекламу на форуме - 42 тыс руб за месяц

Опции темы Поиск в этой теме
Поиск в этой теме:

Расширенный поиск


Похожие темы
Тема Автор Раздел Ответов Последнее сообщение
Пара вопросов Life9 Общие вопросы Delphi 38 14.07.2009 21:05
пара вопросов DeDoK Общие вопросы Delphi 1 10.11.2008 17:58
Пара вопросов [Smarik] Gamedev - cоздание игр: Unity, OpenGL, DirectX 7 18.04.2008 14:28
Пара вопросов xak2 Общие вопросы Delphi 6 08.05.2007 20:58
пара вопросов Trooper Общие вопросы Delphi 3 05.11.2006 17:56