Извините, ничего не найдено.

Не расстраивайся! Лучше выпей чайку!
Регистрация
Справка
Календарь

Вернуться   forum.boolean.name > Программирование игр для компьютеров > C++

Ответ
 
Опции темы
Старый 27.06.2009, 23:00   #1
Mr_F_
Терабайт исходников
 
Аватар для Mr_F_
 
Регистрация: 13.09.2008
Сообщений: 3,947
Написано 2,189 полезных сообщений
(для 6,051 пользователей)
Хитрая хитрость

итак, задача:

есть несколько классов.

допустим,

class human
{
int x,y,z, height, width;
};


class car
{
int x,y,z,speed;
};


нам нужно задавать внутренние значения для разных объектов разных классов, но имея лишь условный номер значения в объекте класса и
само значение. для примера я сделал что все значения всех классов - int.

т.е. пример условия: 2, 40
где 2 - номер значения (Y для обоих классов), а 40 - само значение, т.е. будь объект хоть car хоть human, в нём Y выставится в 40.

я предположил что надо сделать

массив, имеющийся в объекте каждого класса
который содержит указатели
на все значения (блин ну field'ы короче если говорить по блицевски)
мы сами суём в него указатели на филды при создании объекта в конструкторе класса.

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

я довольно запутался... помню что если класс находится в иерархии другого класса, то мы можем из объектов дочерних классов получать объекты класса родителя, т.е. универсальные, это вроде ещё полиморфизм зовётся. думаю этот массив должен быть как раз в родительском...
__________________
бложик | geom.io | твиттер | faded | демо 1 2 | роботы | лайтмаппер
(Offline)
 
Ответить с цитированием
Старый 27.06.2009, 23:23   #2
jimon
 
Сообщений: n/a
Ответ: Хитрая хитрость

эх

class position
{
public:
int x,y,z;
};

class human:public position
{
public:
int height, width;
};

class car:public position
{
public:
int speed;
};

void setposition(position * obj)
{
obj->x = 1;
}

...
human * lol1 = new human;
setposition(lol1);
delete lol1;
car * lol2 = new car;
setposition(lol2);
delete lol2;
...
если ты хочешь назначать переменную по номеру то это можно, но является жудким говнокодом

ps. я делал бы так
class CVector3d
{
...
};

class CNode
{
protected:
CVector3d Position;
CVector3d Rotation;
CVector3d Scale;
...
public:
...
};

class CCar:public CNode
{
...
};

class CHuman:public CHuman
{
...
};
 
Ответить с цитированием
Сообщение было полезно следующим пользователям:
newman (27.06.2009)
Старый 27.06.2009, 23:34   #3
Genius
Знающий
 
Аватар для Genius
 
Регистрация: 02.11.2007
Сообщений: 255
Написано 27 полезных сообщений
(для 43 пользователей)
Ответ: Хитрая хитрость

Сообщение от jimon Посмотреть сообщение
эх

class position
{
public:
int x,y,z;
};

class human:public position
{
public:
int height, width;
};


class car:public position
{
public:
int speed;
};

void setposition(position * obj)
{
obj->x = 1;
}

...
human * lol1 = new human;
setposition(lol1);
delete lol1;
car * lol2 = new car;
setposition(lol2);
delete lol2;
...
если ты хочешь назначать переменную по номеру то это можно, но является жудким говнокодом
Я бы вообще сделал так:

class Car;
class Human;

class GameObject
{
public:
     float x,y,z,pitch,yaw,roll;
     bool alive;

     bool isAlive() { return alive; }

     Car* getCar(){return 0;}
     Human* getHuman(){return 0;}

    virtual void setPosition(float _x,float _y,float _z){ x=_x;y=_y;z=_z; }
    virtual void setOrientation(float _pitch,float _yaw,float _roll){ pitch=_pitch;yaw=_yaw;roll=_roll;}

    virtual void update(){}
};

class Car : public GameObject
{
public:

     Car* getCar(){return this;}
  
     void setPosition(float x,float y,float z) 
     {
          GameObject::setPosition(x,y,z);
          ....
     }

     void setOrientation(float pitch,float yaw,float roll)
     {
         GameObject::setOrientation(pitch,yaw,roll);
         ...
     }

     void update()
     {
        car physic update...
     }
};

class Human : public GameObject
{
public:

     Human* getHuman(){return this;}
  
     void setPosition(float x,float y,float z) 
     {
          GameObject::setPosition(x,y,z);
          ....
     }

     void setOrientation(float pitch,float yaw,float roll)
     {
         GameObject::setOrientation(pitch,yaw,roll);
         ...
     }

     void update()
     {
         if(health <= 0)alive=false;
     }
};

class CarDriver : public Human
{
....
};

GameObject* car = new Car();
GameObject* human = new Humman();

if(car->getCar() != 0)car->setPosition(40,10,0);
if(human->getHuman() != 0)human->setPosition(40,15,0);
А вообще я не совсем понял вопрос.
(Offline)
 
Ответить с цитированием
Старый 27.06.2009, 23:38   #4
jimon
 
Сообщений: n/a
Ответ: Хитрая хитрость

Genius
Car* getCar(){return 0;}
Human* getHuman(){return 0;}
самый большой говнокод в ООП ! это хуже чем тупо модифицировать класс через смещение в указателях
я за такое тебя бы уволил бы без разбирательств
 
Ответить с цитированием
Старый 27.06.2009, 23:43   #5
Genius
Знающий
 
Аватар для Genius
 
Регистрация: 02.11.2007
Сообщений: 255
Написано 27 полезных сообщений
(для 43 пользователей)
Ответ: Хитрая хитрость

Сообщение от jimon Посмотреть сообщение
Genius

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

З.Ы. Я не говорю что твой код дерьмо,я вырозил своё мнение.
(Offline)
 
Ответить с цитированием
Старый 27.06.2009, 23:52   #6
Mr_F_
Терабайт исходников
 
Аватар для Mr_F_
 
Регистрация: 13.09.2008
Сообщений: 3,947
Написано 2,189 полезных сообщений
(для 6,051 пользователей)
Ответ: Хитрая хитрость

эх
не, xyz у меня тут случайно совпали, в реале могут быть абсолютно разные штуки там)

говнокод тоже не хочется

Гениус чето совсем не по теме вроде.

посоветовали мне тут уже два человека юзать Vector.
запихну его в родительский класс и попробую)
__________________
бложик | geom.io | твиттер | faded | демо 1 2 | роботы | лайтмаппер
(Offline)
 
Ответить с цитированием
Старый 27.06.2009, 23:56   #7
jimon
 
Сообщений: n/a
Ответ: Хитрая хитрость

Genius
о static_cast слышал ?
если уж у тебя так получилось (кривая архитектура или что-то еще) то можно и dynamic_cast использовать

Mr_F_
просто представь что у тебя нету понятия индекс переменной, компилятор переменную которая у тебя написана второй может сделать первой или третей
программируй так чтобы тебе индекс переменной был не нужен
 
Ответить с цитированием
Старый 27.06.2009, 23:58   #8
Genius
Знающий
 
Аватар для Genius
 
Регистрация: 02.11.2007
Сообщений: 255
Написано 27 полезных сообщений
(для 43 пользователей)
Вот ещё немного расширил:
class Car;
class Human;

static std::vector<GameObject*> gameWorld;

void insertGameObject( GameObject* object )
{
     gameWorld.push_back(object);
}

class GameObject
{
public:
     float x,y,z,pitch,yaw,roll;
     bool alive;

     GameObject(){ insertGameObject(this); }
     virtual ~GameObject(){}

     bool isAlive() { return alive; }

     Car* getCar(){return 0;}
     Human* getHuman(){return 0;}

    virtual void setPosition(float _x,float _y,float _z){ x=_x;y=_y;z=_z; }
    virtual void setOrientation(float _pitch,float _yaw,float _roll){ pitch=_pitch;yaw=_yaw;roll=_roll;}

    virtual void update(float ifps){}
};

class Car : public GameObject
{
public:
     int model;
     float max_speed;

     Car()
     {
          max_speed=0;
     }

     virtual ~Car()
     {
         xFreeEntity(model);
     }

     Car* getCar(){return this;}
  
     void setPosition(float x,float y,float z) 
     {
          GameObject::setPosition(x,y,z);
          ....
     }

     void setOrientation(float pitch,float yaw,float roll)
     {
         GameObject::setOrientation(pitch,yaw,roll);
         ...
     }

     void update()
     {
        car physic update...
     }
};

class Human : public GameObject
{
public:

     int health;
     int model;

     Human()
     {
         model = xLoadAnimMesh("human.b3d");
         health=100;
     }

     ~Human()
     {
         xFreeEntity(model);
     }

     Human* getHuman(){return this;}
  
     void setPosition(float x,float y,float z) 
     {
          GameObject::setPosition(x,y,z);
          ....
     }

     void setOrientation(float pitch,float yaw,float roll)
     {
         GameObject::setOrientation(pitch,yaw,roll);
         ...
     }

     void update(float ifps)
     {
         if(health <= 0)alive=false;
     }
};

class CarDriver : public Human
{
....
};

void updateGameWorld(float ifps)
{
        for(unsigned int i = 0; i < gameWorld.size(); i++)
        {
               GameObject* obj = gameWorld[i];
               if(obj->isAlive())
               {
                     obj->update(ifps);
               }
        }
}

....

GameObject* car = new Car();
GameObject* human = new Humman();

if(car->getCar() != 0)car->setPosition(40,10,0);
if(human->getHuman() != 0)human->setPosition(40,15,0);

while(!xKeyDown(1))
{
....
updateGameWorld(deltaTime);
xUpdateWorld(deltaTime);
xRenderWorld();
}
Сообщение от Mr_F_ Посмотреть сообщение
не, xyz у меня тут случайно совпали, в реале могут быть абсолютно разные штуки там)

говнокод тоже не хочется

Гениус чето совсем не по теме вроде.

посоветовали мне тут уже два человека юзать Vector.
запихну его в родительский класс и попробую)
А что мешает юзать Вектор,так даже удобнее,я просто изначально по твоему посту сделал xyz.

А вообще тогда бы было что-то типа

void Car::setPosition(const Vector& pos)
{
position = pos;
бла бла бла,ставим тело в позицию...
А вообще невижу смысла сохранять позицию так как есть же фунекции типа xPositionEntity,pxBodyPosition,xEntityX,pxBodyPosi tionX,etc.
}

Вот те многофункциональный 3D Вектор
Вложения
Тип файла: txt Vector.txt (3.6 Кб, 664 просмотров)

Последний раз редактировалось Genius, 28.06.2009 в 00:09.
(Offline)
 
Ответить с цитированием
Сообщение было полезно следующим пользователям:
Mr_F_ (28.06.2009)
Старый 28.06.2009, 00:05   #9
FDsagizi
Бывалый
 
Аватар для FDsagizi
 
Регистрация: 04.01.2008
Адрес: Казахстан \ Талдыкорган
Сообщений: 659
Написано 170 полезных сообщений
(для 509 пользователей)
Ответ: Хитрая хитрость

В серьёз не воспринемай =), да и пожалуй так не делай )))

struct XYZ{	float x,y,z;};

struct c1{
	char buffer[12]; // sizeof(  xyz )
	// ... 
};

void main(){
	// Тут типа наш вектор
	XYZ mx;
	//Тут классик
	c1 c;
	// А вот так мы передаём данные вектора
	memcpu( &c, (void*)&mx, sizeof( XYZ );
}
__________________
Жизнь как говориться игра- делать игры моя профессия(с)

Программирование, это религия! Её нужно исповедовать.
(Offline)
 
Ответить с цитированием
Старый 28.06.2009, 01:46   #10
Horror
Бывалый
 
Регистрация: 09.09.2006
Сообщений: 656
Написано 54 полезных сообщений
(для 110 пользователей)
Ответ: Хитрая хитрость

Извuниете что я тут со своим мылом. у меня вопрос к Гениус)
нах так писать?
class A
{
 B* GetB()..
 C* GetC()..
};
class B :pub A{...};
class C :pub A{...};
А если еще надо детишек от А то это ты там будеш еще методы Get писать?

я конечно нубокодер)
но мне кажется на худой конец можно просто в родителя добавить переменную тип
а у детей типы разные писать )
(Offline)
 
Ответить с цитированием
Старый 28.06.2009, 02:03   #11
Genius
Знающий
 
Аватар для Genius
 
Регистрация: 02.11.2007
Сообщений: 255
Написано 27 полезных сообщений
(для 43 пользователей)
Ответ: Хитрая хитрость

Сообщение от Horror Посмотреть сообщение
Извuниете что я тут со своим мылом. у меня вопрос к Гениус)
нах так писать?
class A
{
 B* GetB()..
 C* GetC()..
};
class B :pub A{...};
class C :pub A{...};
А если еще надо детишек от А то это ты там будеш еще методы Get писать?

я конечно нубокодер)
но мне кажется на худой конец можно просто в родителя добавить переменную тип
а у детей типы разные писать )
Да буду добавлять,так-как это делается для проверки,откуда ты знаеш что GameObject* car - является классом Car? Эти Get'ы тоже самое что в блице делать проверку EntityClass(ent) == "Mesh"... Только удобнее.

Я не говорю что это униврсальный способ,и для игры где претпологается динамическое добавления новых типов игровых объектов,через скрипт,ini,и т.д он точно не подходит,а вот если все игровые объекты буду описаны кодом то это вполне удобное решение.

Последний раз редактировалось Genius, 28.06.2009 в 02:16.
(Offline)
 
Ответить с цитированием
Старый 28.06.2009, 03:21   #12
Mr_F_
Терабайт исходников
 
Аватар для Mr_F_
 
Регистрация: 13.09.2008
Сообщений: 3,947
Написано 2,189 полезных сообщений
(для 6,051 пользователей)
Ответ: Хитрая хитрость

просто представь что у тебя нету понятия индекс переменной, компилятор переменную которая у тебя написана второй может сделать первой или третей
программируй так чтобы тебе индекс переменной был не нужен
а где интересно было понятие индекс переменной?) конечно его нигде нет, я пишу:
мы сами суём в него указатели на филды при создании объекта в конструкторе класса.
т.е. в нужной последовательности.

ща объясню зачем всё надо)

у меня есть свой формат файла (левел). раньше он состоял из готовых блоков с четко заданой последовательностю и структурой. но потом я стал запариваться, когда нужно было ввести какой то новый параметр в один из видов объектов, или вообще новый вид объекта. старый загрузчик сбивался и грузил черти что, надо было аккуратно менять сначала только сохранение, потом пересохранять все имеющиеся карты, затем менять лоад и тогда только радоваться).
я решил сделать формат файла как бы параметр-driven. аналогичное наблюдается в формате FBX. структура такова:

объект
{
номер значения
значение
}

"номер значения-значение" конечно может быть много, до 255.
их структура выглядит так:

B номер значения
B тип данных
сами данные

(B - байт, тип данных от 1 до 5, соотв от байта до стринга).

а заголовок "объекта" представляет собой:

B тип объекта (номер класса, тут проверяем просто ифом, их немного)
L кол-во впереди идущих параметров со значениями

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

вышеуказанный стиль формата файла имхо может весьма сократить расход нервов и сделать вполне совместимыми файлы разных версий (не хватает инфы? игнорим!)
__________________
бложик | geom.io | твиттер | faded | демо 1 2 | роботы | лайтмаппер
(Offline)
 
Ответить с цитированием
Старый 28.06.2009, 03:55   #13
Genius
Знающий
 
Аватар для Genius
 
Регистрация: 02.11.2007
Сообщений: 255
Написано 27 полезных сообщений
(для 43 пользователей)
Ответ: Хитрая хитрость

Ёпть так надо было сразу с этого начинать...

Я бы так делал:

Мы уже имеем объекты:

представим что у нас в объекте есть массив так называемых Value,Value имеет 2 переменые 1) int,индификатор типа данных которые содержатся в Value и данные void*,

struct Value
{
    enum{
       INT=1,
       FLOAT,
       BOOL,
       STRING
    };
    char type;
    void* data;

    void setInt(int v)
    {
        type = INT;
        data = &v;
    }
    void setFloat(flaot v)
    {
        type = FLOAT;
        data = &v; 
    }
    void setBool(bool v)
    {
        type = BOOL;
        data= &v;
    }
    void setString(char* str)
    {
        type = STRING;
        data=str;
    }

    int toInt()
    {
       return *static_cast<int*>(data);
    }
    float toFloat()
    {
       return *static_cast<float*>(data);
    }
    bool toBool()
    {
       return *static_cast<bool*>(data);
    }
    char* toString()
    {
       return static_cast<char*>(data);
    }

    bool isINT()
    {
       return type == INT;
    }
    bool isFLOAT()
    {
       return type == FLOAT;
    }
    bool isBOOL()
    {
       return type == BOOL;
    }
    bool isSTRING()
    {
       return type == INT;
    }
};

struct Object
{
    char id; // индификатор 0-225
    std::vector<Value> values;
};


пишем в файл кол-во объжектов
for(int i=0;i<count_objects;i++)
{
     Object* obj = objects[i];
     пишем в файл char  - obj->id;
     пишем в файл int - obj->values.size(); - кол-во value'ев
     for(int k=0;k<obj->values.size();k++)
     {
          Value val = obj->values[k];
          пишем char val->type; - тип value
          switch(val->type)
          {
               case Value::INT:
               {
                   пишем int - val->getInt();
               }break;
               case Value::FLOAT:
               {
                   пишем float - val->getFloat();
               }break;
               case Value::BOOL:
               {
                   пишем bool - val->getBool();
               }break;
               case Value::STRING:
               {
                   пишем char* - val->getString();
               }break;
          }
     }

}
Загрузка аналагично записи.
Еесли будет не понятно могу и пример загрузки этого чуда написать..
(Offline)
 
Ответить с цитированием
Сообщение было полезно следующим пользователям:
Mr_F_ (28.06.2009)
Старый 28.06.2009, 04:41   #14
Mr_F_
Терабайт исходников
 
Аватар для Mr_F_
 
Регистрация: 13.09.2008
Сообщений: 3,947
Написано 2,189 полезных сообщений
(для 6,051 пользователей)
Ответ: Хитрая хитрость

спасибо всем!
вроде тут сам успел допереть как то)

сделал так:

родительский класс:
class access
{
public:
	int **ivec;
	bool **bvec;
	float **fvec;
	string **svec;
};
дочерний (начало):

class material:public access{
private:
float alpha, brightness, contrast,...
конструктор дочернего класса (Начало):
(биндим к массиву содержимое объекта класса))
material::material()
{
	
	svec = new (string*[3]);
	fvec = new (float*[16]);
	bvec = new (bool*[25]);

		fvec[0]=&alpha;
		fvec[1]=&brightness;
		fvec[2]=&contrast;
загрузка:
	access *Temp;


	while (!myfile.eof())
	{
		objtype=readbyte(&myfile);
		
		if (objtype==1) {
			material *mat=new material; tempname="materials"; time=int(clock());
			Temp = mat;

		}
		
		params=readlong(&myfile);
		
			for(p=0;p<params;p++)
			{
				paramnum=readbyte(&myfile);
				paramlen=readbyte(&myfile);

					if (paramlen==1) *(Temp->bvec[paramnum-1])=bool(readbyte(&myfile));
					if (paramlen==2) *(Temp->ivec[paramnum-1])=(readshort(&myfile));
					if (paramlen==3) *(Temp->ivec[paramnum-1])=(readlong(&myfile));
					if (paramlen==4) *(Temp->fvec[paramnum-1])=(readfloat(&myfile));
					if (paramlen==5) *(Temp->svec[paramnum-1])=(readstringf(&myfile));

			}

		time=int(clock())-time;
		cout << tempname << " loaded in " << time << "ms." << endl;
	}

}
__________________
бложик | geom.io | твиттер | faded | демо 1 2 | роботы | лайтмаппер
(Offline)
 
Ответить с цитированием
Старый 28.06.2009, 11:38   #15
jimon
 
Сообщений: n/a
Ответ: Хитрая хитрость

Mr_F_
я сделал проще немного, у меня в файле содержится имя переменной и её значение
в программе где нужно я просто получаю значение по имени
таким образом если переменной не было то вернётся default значение
 
Ответить с цитированием
Сообщение было полезно следующим пользователям:
Mr_F_ (28.06.2009)
Ответ


Опции темы

Ваши права в разделе
Вы не можете создавать темы
Вы не можете отвечать на сообщения
Вы не можете прикреплять файлы
Вы не можете редактировать сообщения

BB коды Вкл.
Смайлы Вкл.
[IMG] код Вкл.
HTML код Выкл.


Часовой пояс GMT +4, время: 06:53.


vBulletin® Version 3.6.5.
Copyright ©2000 - 2024, Jelsoft Enterprises Ltd.
Перевод: zCarot
Style crйe par Allan - vBulletin-Ressources.com