Current time: 13.04.2024, 13:43 Hello There, Guest! (LoginRegister)
Language: english | russian  

Post Reply 
Threaded Mode | Linear Mode
С++, общая тема
Author Message
etoprostoya Offline

Posts: 1809
Post: #346

Наобум.
template <typename T>
class T
{
    Sub<int> s1;
    Sub<T> s2;
};

Просто редко приходится работать с шаблонами.
19.06.2012 13:50
Find all posts by this user Quote this message in a reply
Efrit Offline
Administrators

Posts: 6183
Post: #347

etoprostoya, спасибо, но такой способ не подойдёт. Нужно просто переименовать тип, не параметризовывая его.

Считай, что помимо Temp есть ещё Temp2, Temp3 и так далее - и в каждом из них есть член, имеющий тип Sub<>. И вот как мне не указывать постоянно конкретное имя внутри угловых скобок - а дать понять компилятору, что нужно использовать "текущий" класс?


Welcome to the soldier side,
Where there is no one here but me.
People all grow up to die,
There is no one here but me...
19.06.2012 13:59
Find all posts by this user Quote this message in a reply
Efrit Offline
Administrators

Posts: 6183
Post: #348

Оказывается - то, что я хочу сделать, всё же есть в стандарте C++11, но ещё не реализовано в GCC:

Quote:If a function-definition or member-declarator declares a member function of a class X, the expression this is a prvalue of type “pointer to cv-qualifier-seq X” between the optional cv-qualifier-seq and the end of the function-definition or member-declarator. It shall not appear before the optional cv-qualifier-seq and it shall not appear within the declaration of a static member function (although its type and value category is defined within a static member function as it is within a non-static member function). [Note: the type and value category is defined even for the case of a static member function because declaration matching does not occur until the complete declarator is known, and this may be used in the trailing-return-type of the declarator. —end note]

Otherwise, if a member-declarator declares a non-static data member (9.2 [class.mem]) of a class X, the expression this is a prvalue of type “pointer to X” within the optional brace-or-equal-initializer. It shall not appear elsewhere in the member-declarator.

Буду ждать...


Welcome to the soldier side,
Where there is no one here but me.
People all grow up to die,
There is no one here but me...
20.06.2012 18:28
Find all posts by this user Quote this message in a reply
packa Offline

Posts: 1210
Post: #349

Снова нубс-проблемка)

Случайно обнаружил что у моей главной формы почему-то стоит Visible=false в свойствах, и при этом она отлично отображается...

Создал вторую форму, и как мне все же сделать чтобы при запуске показывалась сразу вторая форма, а первая только после нажатия, допустим "старт" ?


подпись была удалена администрацией
просьба не использовать картинки с сайта heroeslibrary.net, так как на них ругается Chrome
26.06.2012 21:21
Find all posts by this user Quote this message in a reply
FallenAngel Offline

Posts: 834
Post: #350

packa, не знаю, как это в си, но вроде везде такое должно быть. Поищи где-нибудь в строке меню должны быть настройки проекта.
(This post was last modified: 27.06.2012 11:25 by FallenAngel.)
27.06.2012 11:24
Find all posts by this user Quote this message in a reply
Efrit Offline
Administrators

Posts: 6183
Post: #351

Что ж, Пакка, как и просил - держи рецензию на свой код Ab
Прокомментирую его так, будто это настоящий продакшн-код:

PHP Code:
//---------------------------------------------------------------------------

#include <vcl.h>
#include <math.h>
#pragma hdrstop

#include "Unit1.h"
#include <vector>
//---------------------------------------------------------------------------
#pragma package(smart_init)
#pragma resource "*.dfm"
using namespace std;
TForm1 *Form1;
int mainXmainYraznica_ammo_enemy_YammoNn;
bool build;
const 
int enemyN=5;

class 
Tower
{
public:
    
int xx;
    
int yy;
    
int health;
    
int damage;
    
int target;
    
int reload;

    
Tower int xint yint hint dint tint r);

    
void Draw_Tower();
    
void Zahvat_Target();
    
void Draw_Lazer();
    
void Reload_Tower();
};

class 
Enemy
{
public:
    
int xx;
    
int yy;
    
int health;

    
Enemyint xint yint h );

    
void Draw_Enemy();
    
void Move_Enemy();
};


class 
Ammo
{
public:
    
int xx;
    
int yy;
    
int number;
    
int target;

    
Ammo (int xint yint nint t);

    
void Move_Ammoint j);
    
void Spawn_Ammoint j);
    
void Draw_Ammo();
};


vector <Enemyenemy_group;
vector <Towertower_group;
vector <Ammoammo_group;
vector <intinterval;

Graphics::TBitmap *enemy2 ;
Graphics::TBitmap *ammo ;
Graphics::TBitmap *tower ;
Graphics::TBitmap *boom ;
Graphics::TBitmap *main ;
//---------------------------------------------------------------------------
__fastcall TForm1::TForm1(TComponentOwner)
        : 
TForm(Owner)
{
}
//---------------------------------------------------------------------------
Enemy::Enemyint xint yint h )
{
 
xx=x;
 
yy=y;
 
health=h;
}

//----------------------------

void Enemy::Draw_Enemy()
{
for (
int i=0i<enemyNi++)
{
    if (
enemy_group[i].xx!=mainX)
    {
        if (
enemy_group[i].health>0)
        {
            
Form1->Canvas->Draw(enemy_group[i].xxenemy_group[i].yyenemy2);
        }
        else
        {
            
Form1->Canvas->Draw(enemy_group[i].xxenemy_group[i].yyboom);
        }
    }
}
}
//---------------------

void Enemy::Move_Enemy()
{
        if ( 
xx != mainX )
        {
            if (
xx>0)
            {
                
xx+=1;
            }
        }
}
//===========================

Tower::Towerint xint yint hint dint tint r)
{
    
xx=x;
    
yy=y;
    
health=h;
    
damage=d;
    
target=t;
    
reload=r;
}
//---------------

void Tower::Zahvat_Target()
{
int rasstoyanie[5]; //Массив расстояний от башни до врага
        
for (int j=0enemyNj++)
        {
        if (
enemy_group[j].health>0)
        {
        
int raznicaXtarget xx enemy_group[j].xx//Разница по Х
        
int raznicaYtarget yy enemy_group[j].yy//Разница по Y
                
if (raznicaYtarget<0){         //Если башня выше цели
                
raznicaYtarget=enemy_group[j].yy yy;
                }
        
rasstoyanie[j]=sqrt(pow(raznicaXtarget,2)+pow(raznicaYtarget,2)); //Расстояние от врага до башни, по Пифагору
        
}
        
int min rasstoyanie[0];
        
int b=0;
        for (
int j=0j<enemyNj++){
                if (
rasstoyanie[j]<min){
                        
min=rasstoyanie[j]; //Находим ближайшего врага
                        
b=j;
                }

                if (
rasstoyanie[j]<350)
                { 
//Если враг в области поражения башни (пока числом)
                
target=b//Запоминаем номер врага
                
}
        }
        }


}
//-------------

void Tower::Draw_Tower()
{
Form1->Canvas->Draw(xxyytower);
}

//-------------

void Tower::Draw_Lazer()
{
    
Form1->Canvas->Pen->Color=(TColor)RGB(200,0,0);
    
Form1->Canvas->MoveTo(xx,yy);
    
Form1->Canvas->LineTo(enemy_group[target].xx,enemy_group[target].yy);
}
//--------------

void Tower::Reload_Tower()
{
    
reload+=1;
}

//=====================================================================

Ammo::Ammo (int xint yint nint t)
{
    
xx=x;
    
yy=y;
    
number=n;
    
target=t;
}

//-----------------------

void Ammo::Move_Ammoint j )
{
for(
int j=0j<ammoNj++)                       // Для каждого патрона из массива... Делать столько раз, сколько патронов в потоке.
    
{
        if ( 
enemy_group [target].xx == xx && enemy_group[target].yy == yy )
        {
            
enemy_group[target].health-=50;
        }
        else
        {
            
xx-=1;   // Движение по оси Х

            //Разница между высотой врага и патрона=высота патрона - высота"выделенного" врага
            
raznica_ammo_enemy_Y=0;
            if (
enemy_group[target].yy yy//Если высота врага < высота патрона
            
{
                
raznica_ammo_enemy_Y enemy_group[target].yy yy;
                if (
raznica_ammo_enemy_Y 5)
                {
                    
yy += raznica_ammo_enemy_Y;
                }
                else
                {
                    
yy += 5//Опускаемся на 5
                
}
            }
            else
            {
                
raznica_ammo_enemy_Y yy enemy_group[target].yy;
                if (
raznica_ammo_enemy_Y<5)
                {
                    
yy -= raznica_ammo_enemy_Y;
                }
                else
                {
                    
yy -= 5//Поднимаемся на 5
                
}
            }
        }
    }
}

//--------------------------
void Ammo::Spawn_Ammo int j )
{
    if ( 
tower_group[j].target >= && tower_group[j].target )           //Если у башни есть цель
    
{
        if (
enemy_group[tower_group[j].target].health>0)
        {
                
Ammo newAmmo (tower_group[j].xxtower_group[j].yyammoNtower_group[j].target);
                
ammo_group.push_backnewAmmo );
                
ammoN++;
                
tower_group[j].reload=0;   //Обнуляем для нового отсчета
        
}
    }
}
//-----------------

void Ammo::Draw_Ammo()
{
    
Form1->Canvas->Drawxxyyammo);
}
//===========================

void __fastcall TForm1::Button1Click(TObject *Sender)
{
for (
int i=0enemyNi++)
{
    
Enemy newEnemyrandom(100),random(300), 100 );
    
enemy_group.push_backnewEnemy );
}
Timer1->Enabled true;
}
//---------------------------------------------------------------------------

void __fastcall TForm1::Timer1Timer(TObject *Sender)
{
for (
int i=0i<enemyNi++)
{
enemy_group[i].Move_Enemy();
}
//
if (tower_group.empty()!=true)
{
    for (
int i=0i<tower_group.size(); i++)
    {
    
tower_group[i].Zahvat_Target(); //Башни ищут ближайшую цель
    
}
    for(
int j=0j<nj++)
    {
        if (
tower_group[j].reload==10)
        {
            
ammo_group[j].Spawn_Ammo);
        }
        else
        {
            
tower_group[j].Reload_Tower();
        }
    }
    for (
int k=0k<ammoNk++)
    {
    
ammo_group[k].Move_Ammo);  //Двигаем все патроны
    
}
}
Invalidate();
}
//---------------------------------------------------------------------------

void __fastcall TForm1::FormPaint(TObject *Sender)
{
for (
int i=0i<enemyNi++)
{
enemy_group[i].Draw_Enemy();
}

if (
tower_group.empty()!=true)
{
    for (
int i=0i<tower_group.size(); i++)
    {
        
tower_group[i].Draw_Tower();
        if ( 
tower_group[i].target >= )           //Если у башни есть цель то рисуем "лазер"
        
{
            if (
enemy_group[tower_group[i].target].health>0)
            {
              
tower_group[i].Draw_Lazer();
            }
        }
    }
    for(
int j=0ammoNj++)
    {
        
ammo_group[j].Draw_Ammo();
    }
}
Form1->Canvas->Draw(610235main);
}
//---------------------------------------------------------------------------

void __fastcall TForm1::FormCreate(TObject *Sender)
{
DoubleBuffered=true;
for (
int i=0enemyNi++)
{
    
Enemy newEnemyrandom(100),random(300), 100 );
    
enemy_group.push_backnewEnemy );
}
n=0;
mainX=610;
mainY=235;
ammoN=0;
tower = new Graphics::TBitmap;
tower->LoadFromFile("tower.bmp");
main = new Graphics::TBitmap;
main->LoadFromFile("main.bmp");
enemy2 = new Graphics::TBitmap;
enemy2->LoadFromFile("enemy2.bmp");
ammo = new Graphics::TBitmap;
ammo->LoadFromFile("ammo.bmp");
boom = new Graphics::TBitmap;
boom->LoadFromFile("boom.bmp");
}
//---------------------------------------------------------------------------


void __fastcall TForm1::FormMouseDown(TObject *SenderTMouseButton Button,
      
TShiftState Shiftint Xint Y)
{
if (
build==true)
{
    
Tower newTower X,Y10050, -110);
    
tower_group.push_backnewTower );
    
n++;
}
Invalidate();
Form1->Edit1->Text=tower_group.size();
}
//---------------------------------------------------------------------------


void __fastcall TForm1::Button2Click(TObject *Sender)
{
 if (
build==true){
build=false;
}
else {
build=true;}
}
//--------------------------------------------------------------------------- 

Оформление:
 
1) Бросается в глаза разный стиль именования переменных: mainX, mainY, raznica_ammo_enemy_Y. Нотация везде должна быть единой, даже если эта нотация - венгерская.
2) Конструктор класса Tower вынесен за его пределы - это ладно (хотя и не ясно, зачем), но почему он записан где-то в середине файла, а не сразу вслед за классом? А ещё лучше - выносить классы в отдельные файлы.
3) Да и что значат его переменные, почему они все однобуквенны? В строке Tower ( int x, int y, int h, int d, int t, int r) разобраться сможет только автор этого кода, и никто другой. А писать код надо так, будто сопровождать его будет склонный к насилию психопат - который знает, где ты живёшь. (с)
4) За названия вроде "raznica_ammo_enemy_Y" или "Zahvat_Target()" нужно вырвать и застрелить руки. Если уж не знаешь полностью английского (что вполне простительно) - то пиши всё транслитом, но смешивать языки - это моветон.
5) Все символы, относящие к названию типа, нужно писать слитно. В строке vector <Enemy> у тебя Enemy является частью типа, поэтому пробел ставить не надо. Это же касается и звёздочек в объявлениях указателей.
6) А вот в строках типа enemy_group[i].xx!=mainX, наоборот, нужно обязательно отделять пробелом знаки операций. Иначе визуально ничего не понятно. Арифметические операции - это полноценные функции, и они заслуживают "отделения".
7) Скобки {} кое-где поплыли, а кое-где и отступы вместе с ними. Местами вообще получилась нечитабельная каша, как в функции Zahvat_Target().


Кодинг:
 
1) Строка #include <vector> должна стоять выше, чем #pragma hdrstop. Потому как в твоём случае <vector> будет инклудиться всегда, хотя достаточно всего одного раза.
2) Используется множество глобальных переменных - которые, как известно, не есть гут. В большинстве случаев их можно заменить локальными, если только это не синглтоны. Да и хотя бы прокомментировать их не мешало бы.
3) Из-за конструкций вроде Form1->Canvas->Draw(610, 235, main) есть риск быть похороненным в закрытом гробу бирюзового цвета. Почему именно бирюзового? Потому что 610. А если уж эта строка нужна чисто "для дебага", то нужен комментарий об этом (а ещё лучше - условная компиляция).
4) В конструкторах лучше использовать списки инициализации, а не поочерёдное присваивание. Во-первых, так безопаснее. Во-вторых, только так можно проинициализировать не-статические константы класса.
5) Кстати, а где константы-то? В коде хватает переменных, которые не изменяются после инициализации. А ведь "константность" защищает от ошибок на этапе исполнения.
6) Раздражают конструкции вида if (tower_group.empty()!=true) или reload+=1. В первом случае сравнение с true можно не писать, а во втором нужен обычный инкремент.
7) Приведение типов в стиле C, как в строке (TColor)RGB(200,0,0), не всегда безопасно - лучше использовать "плюсовые" static_cast и dynamic_cast.
8) Зачем в функцию Move_Ammo( int j ) передаётся параметр j, когда он же вводится в первой строчке самой функции? Либо неиспользуемая переменная, либо просто ошибка.
9) Ввело в ступор содержимое функции Button2Click(). Надеюсь, что это просто "заглушка" такая?


Рекомендации:
 
1) Использовать везде единый стиль записи. Это касается именования переменных, расстановки скобок и комментариев. Имена должны быть осмысленными.
2) Упаковывать данные внутрь классов, используя идиому RAII. Если картинка относится к элементу конкретного класса, не надо таскать её как глобальную переменную - нужно выделить память под неё в конструкторе, и освободить в деструкторе.
3) Почему не стоит обходить вектор через int-переменную, скромно умолчу. Но на всякий случай посоветую почитать про итераторы. Через них всё идёт намного быстрее.
4) Вместо "голых" указателей лучше использовать shared_ptr<> и создавать всё в стеке, избегая кучи вообще. Хотя тебе ещё далековато до такой техники.
5) Вместо множества функций типа Draw_Tower() и Draw_Lazer() лучше иметь одну перегруженную функцию Draw(), которая могла бы принимать объекты разных типов. Это удобно для вызова функций (IDE сама показывает перегрузки), да и наследоваться от таких классов куда проще.
6) В любом классе желательно наличие конструктора по умолчанию (без параметров), дабы его объекты можно было использовать внутри массивов и STL-контейнеров. У тебя же далеко не везде так.

P.S. Только не стоит расстраиваться от прочитанного - я в твоём возрасте кодил намного хуже Rolleyes


Welcome to the soldier side,
Where there is no one here but me.
People all grow up to die,
There is no one here but me...
04.07.2012 19:44
Find all posts by this user Quote this message in a reply
etoprostoya Offline

Posts: 1809
Post: #352

(04.07.2012 19:44)Efrit Wrote:  9) Ввело в ступор содержимое функции Button2Click(). Надеюсь, что это просто "заглушка" такая?

Функция меняет параметр build с true на false и наоборот. Что непонятного?
А в остальном почти во всём присоединяюсь.
04.07.2012 19:56
Find all posts by this user Quote this message in a reply
packa Offline

Posts: 1210
Post: #353

Image: 6db876e06533.jpg

Оформление (Click to View)
Кодинг (Click to View)
рекомендации (Click to View)


подпись была удалена администрацией
просьба не использовать картинки с сайта heroeslibrary.net, так как на них ругается Chrome
(This post was last modified: 05.07.2012 08:08 by packa.)
04.07.2012 21:47
Find all posts by this user Quote this message in a reply
Deo Offline

Posts: 494
Post: #354

Я эти ваши C++ не знаю, но ведь метод Draw_Enemy проходит по всем врагам и рисует их, но помимо этого он вызывается для каждого врага, не?

05.07.2012 06:29
Find all posts by this user Quote this message in a reply
packa Offline

Posts: 1210
Post: #355

Quote:Я эти ваши C++ не знаю, но ведь метод Draw_Enemy проходит по всем врагам и рисует их, но помимо этого он вызывается для каждого врага, не?
Угу, это фейл.

Но к счастью это ни на что не влияет, кроме как зря рисует, зато четче будет)))


подпись была удалена администрацией
просьба не использовать картинки с сайта heroeslibrary.net, так как на них ругается Chrome
05.07.2012 08:12
Find all posts by this user Quote this message in a reply
Efrit Offline
Administrators

Posts: 6183
Post: #356

packa Wrote:Единой и старался делать) в 3 переменной просто необходимо такое название, иначе не ясно разница между чем и чем.
Не, я про другое. Я про символы подчёркивания в именах. Их надо либо использовать везде, либо вообще не использовать.

packa Wrote:У меня все конструкторы вынесены ниже, рядом с методами. Почему в середине? Просто у меня еще 2 класса, группировал контруктор+метод+метод+...
Нет, функции-члены класса должны распаолагаться либо внутри него, либо сразу вслед за ним. Я не хочу рыскать по всему cpp-шнику в поисках нужной мне функции - особенно, если самих классов много.

packa Wrote:Исключительно для конструктора. Если заглянуть в сам конструктор там все предельно ясно
Ничего не ясно. В строке Tower ( int x, int y, int h, int d, int t, int r) - что такое x? Что такое h? Что такое d, t, r? Если я захочу создать экземпляр твоего класса - то я не смогу этого сделать, поскольку я понятия не имею, что же значат его параметры. Правильно писать Tower (int x_pos, int y_pos, int health, int damage, int target, int reload). Поскольку иначе мне придётся копаться во внунренностях твоего класса, а мне некогда.

packa Wrote:Не понял что не так) КоординатаХ, КоординатаУ, картинка - вроде так все пишется.
Почему именно 610 и 235, а не 510 и 234? С какого перепугу функция меняет конкретные пиксели экрана? А что, если я захочу уменьшить размеры окна? Или у меня экран 480*320? А если это число 610 используется в нескольких функциях, а я захотел его поменять, что тогда? Мне придётся править каждую функцию, что ли?
Запомни: вообще нельзя использовать какие-то конкретные числа внутри кода. В худшем случае - такие константы надо дефайнить, и внутри функций использовать именно константы, а не явно указанные числа. Единственные числа, которые можно указывать явно - это 0, 1 и -1 (ну и двойка также иногда разрешается). Разве что, ещё можно использовать 8 как число бит в байте, 10 и 16 для функций перевода в системы счисления, ну и 100 для подсчёта процентов. Не более!

packa Wrote:Ammo::Ammo (int x, int y, int n, int t) : xx(x), yy(y), number(n), target(t); // ?
Да, именно так.

packa Wrote:Одна есть и хватит)) А если серьезно - специально оставлял переменные - чтобы при надобности просто их менять, не правя при этом код.
Константы сильно экономят время, отлавливая ошибки ещё на этапе компиляции. Когда-нибудь ты это оценишь.

packa Wrote:Со вторым полностью согласен, а вот с первым нет. Потому что код явно теряет свою очевидность, что тупо мешает читаемости. Я бы сказал что здесь овчинка выделки не стоит)
Какое из двух высказываний для тебя звучит более понятно?
   1) Если группа башен пуста, то...
   2) Если верно, что группа башен пуста, то...
На мой взгляд - однозначно первое... Вот и с кодом то же самое. Особенно если условий много, и они вложены друг в друга.

packa Wrote:Нажали на кнопку - Вошли в режим строительства - каждый клик строит башню.
Нажали повторно, вышли из режима, можем кликать до посинения, ничего не произойдет
Део верно заметил, что можно просто написать build = !build и не мучаться.

packa Wrote:Мозгу нуба намного сподручнее пользоваться интами, чем абстрактными итераторами)
Кстати уже заюзал в одном месте, но все равно тяжко обрабатывать мозгу, как это работает, хоть и понятно достаточно.
Итератор - это просто "обёртка" над указателем. Если ты не до конца понимаешь адресную арифметику указателей - то, конечно, итераторами пользоваться ещё не стоит.

packa Wrote:Почему? 3 класса = 3 конструктора.
Дык это не конструкторы по умолчанию - у них параметры есть! Я же говорил именно про конструкторы по умолчанию...

P.S. Да, ещё забыл сказать: public-переменные в классе - это почти всегда плохо. Нужно везде использовать get- и set-функции для каждой переменной, к которой планируется "сторонний" доступ. Даже если они будут простейшими.


Welcome to the soldier side,
Where there is no one here but me.
People all grow up to die,
There is no one here but me...
05.07.2012 08:33
Find all posts by this user Quote this message in a reply
NIKr0m@nceR Offline

Posts: 203
Post: #357

Давайте я тут что ли спрошу. Дело в том что я заядлый дндшник и жутко устал тратить кучу сил и времени на генерацию персонажа, заполнение чарников, которые постоянно забываются и т.д. и т.п. Посему мне хочется это дело автоматизировать, но основная проблема заключается в том, что я слабо представляю какое этому всему придать внутреннее устройство. ну то есть я конечно могу зафигачить один такой большой map и обращаться к параметрам по строке-названию. после чего написать 9к строк кода с кучами свичей, а после того как захочу подкорректировать что-нибудь, благополучно стать погребённым в этом коде. У кого-нибудь есть идеи как мне помочь/что полистать/о чём размыслить
/кто виноват/что делать
?


всё на благо народа
08.07.2012 13:54
Find all posts by this user Quote this message in a reply
Efrit Offline
Administrators

Posts: 6183
Post: #358

Чубайс / трясти надо

Сложно ответить, поскольку я не знаю, что именно из себя представляют ДнД-шные чарники.
Можешь кинуть ссылки на описание, а ещё лучше - скрины/фотки заполненных листов?

И что там может поменяться, разве правила не фиксированы?


Welcome to the soldier side,
Where there is no one here but me.
People all grow up to die,
There is no one here but me...
08.07.2012 14:28
Find all posts by this user Quote this message in a reply
Efrit Offline
Administrators

Posts: 6183
Post: #359

Посмотрел чарлисты и чуток глянул правила. Да уж, объёмистая штука!

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

Плюс, хватает "божественных объектов" типа класса или расы: если у персонажа изменить расу/класс, то у него вообще всё поменяется нафиг. Более того - насколько я понимаю, класс зависит от расы. И персонажи могут приобретать какие-то новые фичи в зависимости от комбинации раса+класс... Короче гря, полный набор антипаттернов Ab

Но уж твой вариант с "огромным map-ом" точно не прокатит - запутаешься с всевозможными хитросплетениями "божественных" параметров персонажа типа расы/класса/пола. Я бы советовал прежде всего выделить те классы, которые вообще никак не меняются: например, "слоты персонажа" вроде бы фиксированы (или же, у каких-то рас есть третья рука?). И в первую очередь - реализовать их.

Из-за того, что всё сильно связано - очень советую юзать property, иначе замучаешься. То есть либо юзай С#, либо (если хочется именно на плюсах) VC++ или Qt (второе лучше, так как кроссплатформ). Кроме этого, не советую юзать где-либо внутри классов поле "родитель" - это только ещё больше запутает код, поскольку вдобавок ко всему придётся помнить, чем является такое-то заклинание: врождённой фичей персонажа, или же свойством оружия...

Какие-то конкретные методы проектирования мне в голову не лезут. Хотя, той же "абстрактной фабрикой" здесь можно попробовать воспользоваться - поскольку изменение расы/класса/пола не ведут к добавлению каких-то абсолютно новых классов, а лишь к модификации свойств старых. Но сами фабрики получатся огромные - хз, стоит ли здесь овчинка выделки. Но это в любом случае куда лучше, чем сотни map-овских ключей, ещё и без пропертей 118

P.S. Кстати, я для своей ФРПГ (Аредита) чарлисты полностью автоматизировал, а заодно с ними и проведение битв тоже, но мне было куда легче - у меня есть "модульность" на уровне системы. Например, у моих персонажей нет классов вообще, а пол почти ни на что не влияет - то есть хоть какую-то иерархию классов (программных) построить можно... А вот как быть с ДнД, я толком не знаю - слишком её система уж громоздка.


Welcome to the soldier side,
Where there is no one here but me.
People all grow up to die,
There is no one here but me...
08.07.2012 16:49
Find all posts by this user Quote this message in a reply
NIKr0m@nceR Offline

Posts: 203
Post: #360

Бывает и 3 руки. у меня с паттернами вообще говоря практически шапочное знакомство, я никогда реально их не использовал пока что. Мне тоже в голову пришла фабрика но я только боюсь как бы с ней не запутаться. про третью руку - и такое бывает, а вот 6 базовых параметров практически на 100% незыблемы. ладно, спасибо за помощь, пойду строить фабрику


всё на благо народа
08.07.2012 17:11
Find all posts by this user Quote this message in a reply
« Next Oldest | Next Newest »
Post Reply 


Forum Jump:

Powered by MyBB Copyright © 2002-2024 MyBB Group