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

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

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

Ответ
 
Опции темы
Старый 31.03.2009, 03:21   #1
HolyDel
 
Регистрация: 26.09.2006
Сообщений: 6,035
Написано 1,474 полезных сообщений
(для 2,707 пользователей)
Sigel Tutorial 1. Свой Crimsoland.

писать буду в несколько заходов.
приветствуется критика и вопросы.






Описание статьи и «игры»:

Разработка игры на Sigel. На примере небольшой 2д стрелялки. Аля свой crimsoland на С++ и Sigel. Будут рассматриваться сам язык С++ (вкратце, предполагаю что читатель уже слышал о таком и писал что то стоящее на каком нибудь другом), движок Sigel (архитектура, основы, нюансы), немного glsl (шейдеры). Сама игра будет предельно проста, но все же в меру технологична (освещение на шейдерах, запеченная в текстуру кровища, MRT и отложенное освещение).
Будем в ней бегать и стрелять. Вид сверху. 2д. Освещаться будет зона вокруг игрока, и будет свет от пуль, возможно еще какие нибудь «светлячки». Но в целом мир будет темным. Поэтому освещение будет отложенным (т.е сначала формируем screen-space текстуры с диффуз-картой и нормал-картой и потом уже освещаем). Также будут «моря крови», естественно с записью в текстуру.
Игрок будет спрайтом, свет тоже будет спрайтом, и враги будут спрайтом, и пули
Также будут звуки и музыка. Меню не будет (не думаю что с этим могут возникнуть сложности).
Также будет синхронизация по времени (delta time).
Далеко не все в туториале сделано оптимально. Часто можно былобы сделать попроще или побыстрее, но так как цель этого туториала показать движек. То и решаются задачи по разному.

Немного терминологии движка:

Entity (ентити) — некий абстрактный объект. Обладает ориентацией и позицией в пространстве. Можно к нему прикреплять текстуры, шейдеры и прочую муть.
Surface (сюрфейс) — некая сетка геометрии. Рендерится за один батч (дип), с настройками объекта.

Ну, с описанием покончено, перейдем собственно к уроку. Предполагаю что MSVS 2005, Sigel и драйвера уже установлены и настроены. Создаем новый проект:
Нажмите на изображение для увеличения
Название: pic1.png
Просмотров: 925
Размер:	59.3 Кб
ID:	5718

выбираем тип проекта — SigelApp, и вводим имя проекта (я его назвал в честь игрушки _Ish, написанной еще на блице).
Нажмите на изображение для увеличения
Название: pic2.png
Просмотров: 927
Размер:	23.9 Кб
ID:	5719

Далее, выбираем какие компоненты будут использоваться. Я решил что будут использоваться Devil и bass. Первый — для загрузки разных форматов текстур. (в первую очередь — ради png, его ядро движка не держит на данный момент). Второй — для звука и музыки.
Физика, скрипты и сеть не нужны для данной игры. Да и не сделаны они еще на должном уровне.
Нажмите на изображение для увеличения
Название: pic3.png
Просмотров: 913
Размер:	13.7 Кб
ID:	5720

После нажатия на Finish, мастер сам создаст и скопирует нужные файлы, и простым щелчком на исходнике — мы переходим к его редактированию:
Нажмите на изображение для увеличения
Название: pic4.png
Просмотров: 914
Размер:	47.7 Кб
ID:	5721

В итоге у нас получается исходник:
#define SIGEL_USE_ONLY

#define SIGEL_DEVIL
#define SIGEL_SOUND
//#define SIGEL_SCRIPT
//#define SIGEL_PHYSX
//#define SIGEL_NETWORK

#include <sigel/ISigel.h>

sGAME
{
	debug::startlog();
	InitDemo();
	AppTitle("_ISh2");

	VWait(0);
	CameraHelper ch;

	TFont *fnt = new TFont("tahoma.txt");

	while(!KeyDown(VK_ESCAPE))
	{
		//3d
		ch.Update();
		Render();
		//2d

		fnt->Text(GetFPS(),10,10);
		Flip();
	}

	DeInit();
	debug::endlog();
};
Во-первых меняем InitDemo() на Init() - это инициализирует полноэкранный режим, размером с рабочий стол. Что нам и нужно. Так как у большинства сейчас стоят жк мониторы, а на них картинка размером неравная матрице — выглядит смазаной.

Убираем отсюда все что связано с CameraHelper (ch). CameraHelper – это специальный объект, которым можно управлять с мыши и клавиатуры, он бывает полезен для отладки сцен, а камеру создавать и писать управление ею — лениво. Создаем свою камеру. Тут важно заметить, что объекты в сижеле могут быть двух типов — сами объекты и так называемые «инструменты». Если первые могут иметь позицию, шейдер, цвет, текстуру и т.д., то вторые всего этого не имеют, но у них есть ссылка на так называемые entity-hoster. Как правило это пивот. Но это не обязательно. Например для зеркал это обычно сюрфейс.
Camera *eye = new Camera();
Entity *cam = new Entity(EC_PIVOT);
eye->BindEntity(cam);
cam->Rotate(-90.0f,0,0);  //поворачиваем камеру вниз. Игра то с видом сверху.
Таким образом управлять настройками камеры (например цветом отчистки, Fov-ом или дистанцией прорисовки) нужно через собственно камеру (в нашем случае eye), а позицией и прочими параметрами — через cam. Грубо говоря мы возим и поворачиваем пивот, и каждый проход рендера камера ставится на его позицию.

Объявим entity игрока. Этот объект явно будет много где еще использоваться, поэтому он должен быть глобальным. т.е. Объявлен до точки вход sGAME по умолчанию. Проще всего объявить так: Entity *player = 0;
Заметьте, сам объект мы будем создавать уже после инициализации!

Сам игрок будет квадом. Впрочем много чего будет квадами, пожалуй даже все.

Пишем до sGAME:
Surface *bb = 0;
Entity *player = 0;
и после инициализации:
bb = new Surface();
bb->MakeQuad(1.0f);
player = new Entity(bb);
также нужен пол.
Для этого надо создать квад, загрузить текстуру, создать entity и затекстурить его. Вообще надо четко разделять геометрию и ее представление. Все это — сюрфейсы, террайны, биллбоарды и партикловые системы — это геометрия, которая рендерится каким то особым способом. Вот например куб — это сюрфейс из 12 трисов и 24 вершин. У нас может быть 1000 таких кубов. Это будет тысяча entity, но только один сюрфейс, который, тем ни менее, будет рендерится 1000 раз за кадр. Но в разных позициях, с разными материалами и шейдерами. Создаем сюрфейс, грузим текстуру и создаем ентити.
Surface *sfloor = new Surface();
sfloor->MakeQuad(256.0f,32.0f); //квад размером 256 на 256. и uv координатами от 0 до 32.

Entity *efloor = new Entity(sfloor);

Texture *fdiffus = new Texture("media/Fieldstone.png",TF_MIPMAP | TF_ANISOTROPIC);
efloor->BindTex(fdiffus);
Ставим игрока на середину карты:
player -> Position(128.0f,0.5f,128.0f); //ставим игрока на середину. (чуть выше земли).
В игровом цикле обновляем положение камеры. Она будет смотреть прямо на игрока сверху.
cam->Position(player); \\ставит камеру в позицию игрока
cam->PositionY(32.0f); \\ставит Y позицию камеры в 32.
В итоге у нас получается такой код:
#define SIGEL_USE_ONLY
  #define SIGEL_DEVIL
  #define SIGEL_SOUND

#include <sigel/ISigel.h>

Surface *bb = 0;
Entity *player = 0;

sGAME
{
	debug::startlog();
	Init();
	AppTitle("_ISh2");

	Camera *eye = new Camera();
	Entity *cam = new Entity(EC_PIVOT);
	eye->BindEntity(cam);
	cam->Rotate(-90.0f,0,0);  //поворачиваем камеру вниз. Игра то с видом сверху.

	bb = new Surface();
	bb->MakeQuad(1.0f);

	player = new Entity(bb);
	
	Surface *sfloor = new Surface();
	sfloor->MakeQuad(256.0f,32.0f);

	Entity *efloor = new Entity(sfloor);

	Texture *fdiffus = new Texture("media/Fieldstone.png",TF_MIPMAP | TF_ANISOTROPIC);
	efloor->BindTex(fdiffus);

	VWait(0);

	TFont *fnt = new TFont("tahoma.txt");

	player -> Position(128.0f,0.5f,128.0f); //ставим игрока на середину. (чуть выше земли).

	while(!KeyDown(VK_ESCAPE))
	{
		//3d

		cam->Position(player);
		cam->PositionY(32.0f);

		Render();
		//2d


		fnt->Text(GetFPS(),10,10);
		Flip();
	}

	DeInit();
	debug::endlog();
};
и вот такой скрин:
Нажмите на изображение для увеличения
Название: pic5.jpg
Просмотров: 938
Размер:	125.3 Кб
ID:	5723

Следующим шагом загрузим текстуры игрока и курсора, также заставим игрока двигаться и поворачиваться в сторону курсора.
Для перемещения придется ввести dt. Это переменная тоже должна быть глобальной, значит надо ее объявить где? Правильно, в начале (не в функции точки входа по крайней мере). Узнать текущее время кадра можно функцией GetFrameTime().
float dt = 0;

в цикле:
ft = GetFrameTime();
также нужно загрузить текстуры. Делается это так:
Texture *playerdiffus[19];

for(int i=0;i<19;++i)
{
	char buff[80];
	sprintf_s(buff,80,"media/solider/%d.png",i+1);
	playerdiffus[i] = new Texture(buff);
}
цифра в квадратных скобках после имени переменной при ее объявлении означанет количество элементов в массиве. Например int a[4], a – это массив из 4 интов.
Так в нашем случае Texture *playerdiffus[19]; - это массив из 19 указателей на текстуры. Заметьте — что индексация происходит в ранге 0..18. т.е. На 1 меньше.
Циклы for имеют следующий синтаксис — у них есть три выражения, они разделены точкой с запятой. Первое — инициализация, второе — условие ПОВТОРЕНИЯ, последнее — что делать с переменной.
sprintf_s – эта команда пишет в массив char-ов некую строку. Сама строка задается третьим параметром, вторым идет макс число элементов в массиве. В этой строке "media/solider/%d.png", %d заменяется на следующий параметр (целочисленный), так например %s для строки, а %f для float.

Также нам нужны будут переменные для текущего кадра и флаг движется игрок или нет — чтобы его анимировать.
Конечно, игрока нужно затекстурить:
int move = 0;
float frame = 0;
player->BindTex(playerdiffus[(int)frame]);
Далее, в главном цикле нужно сделать управление игроком. Оно будет заключаться в движении на WASD и повороте на указатель мышки.
move = 0;
Vector2D mdir(0,0);

if(KeyDown('W'))
{
	move = 1;
	mdir.y -= 1;
}

if(KeyDown('S'))
{
	move = 1;
	mdir.y += 1;
}

if(KeyDown('A'))
{
	move = 1;
	mdir.x -= 1;
}

if(KeyDown('D'))
{
	move = 1;
	mdir.x += 1;
}


if(move)
{
	mdir.normalize();
	mdir *= (dt*0.01f);

	player->Translate(mdir.x,0,mdir.y);

	frame += dt * 0.03f;
	if(frame>18.0f)
		frame -= 18.0f;
	player->BindTex(playerdiffus[(int)frame]);
}
тут стоит описать подробнее. В данном участке — мы определяем вектор направления. Далее, если нажата одна из клавиш WASD, то мы говорим что игрок двигается. И добавляем в вектор направление клавиши. В результате у нас получится вектор показывающий направление. Далее, мы его нормализируем (приводим вектор к единичному) и домножим на скорость помноженную на dt.
Потом просто перемещаем наш объект. Translate перемещает объект не обращая внимание на его направление, в отличие от Move.
С анимцией тоже не сложно. Просто прибавляем к кадру некую цифру помноженную на dt (я ее вывел методом проб и ошибок )) )
Если кадр выходит за максимальный, то мы просто отнимаем от него это число. Это нужно, чтобы анимация выглядела более плавной.
Ну и прикрепляем текстуру с нужным индексом.
float a = atan2f((float)((ScreenWidth()/2)-MouseX()),(float)((ScreenHeight()/2)-MouseY()));
player->RotateY(a*57.1f);
первая строчка считает угол. Между центром экрана и координатой курсора. Она выглядит страшной только потому, что пришлось приводить int к float чтобы компилятор не кидал warning-и. Это делается так, если кто не знает — (float)42. Например.
Заметьте в Sigel-е углы задаются в градусах, а с++ считает в радианах. Поэтому надо домножить на (180 / pi) — примерно 57.1f. Кстати, f на конце числа означает что это число float, а если оно не указано, то компилятор считает что ето double. Так как все расчеты внутри движка ведутся в float-то и в игре удобно оперировать ими.


Грузим курсор в картинку.
Image *cur = new Image(“media/cur.jpg”);
эту же картинку нужно отрисовать с аддиативным блендингом перед самым flip-ом.
Blend(BM_ADD);
cur->Draw(MouseX()-16,MouseY()-16);
Blend(BM_ALPHA);
обратите внимание картинка рисуется в оконных координатах. Указывается позиция ее верхнего левого угла, поэтому и нужно было вычесть 16 из каждой координаты (размер картинки — 32 на 32)
ну и наконец — последний стришок — прячем стандартный курсор. HidePointer(), незабываем его показать при выходе из программы — ShowPointer():
вот такой исходник:
#define SIGEL_USE_ONLY
  #define SIGEL_DEVIL
  #define SIGEL_SOUND

#include <sigel/ISigel.h>

Surface *bb = 0;
Entity *player = 0;
float dt = 0;

sGAME
{
	debug::startlog();
	Init();
	AppTitle("_ISh2");

	Image *cur = new Image("media/cur.jpg");

	Camera *eye = new Camera();
	Entity *cam = new Entity(EC_PIVOT);
	eye->BindEntity(cam);
	cam->Rotate(-90.0f,0,0);  //поворачиваем камеру вниз. Игра то с видом сверху.

	bb = new Surface();
	bb->MakeQuad(2.0f);

	player = new Entity(bb);
	player->Blend(BM_ALPHA);

	Texture *playerdiffus[19];

	for(int i=0;i<19;++i)
	{
		char buff[80];
		sprintf_s(buff,80,"media/solider/%d.png",i+1);
		playerdiffus[i] = new Texture(buff);
	}

	Surface *sfloor = new Surface();
	sfloor->MakeQuad(64.0f,16.0f);

	Entity *efloor = new Entity(sfloor);

	Texture *fdiffus = new Texture("media/Fieldstone.png",TF_MIPMAP | TF_ANISOTROPIC);
	efloor->BindTex(fdiffus);

	VWait(0);

	TFont *fnt = new TFont("tahoma.txt");

	player -> Position(32.0f,0.5f,32.0f); //ставим игрока на середину. (чуть выше земли).

	int move = 0;
	float frame = 0;
	player->BindTex(playerdiffus[(int)frame]);

	HidePointer();
	while(!KeyDown(VK_ESCAPE))
	{
		dt = GetFrameTime();
		//3d
		move = 0;
		Vector2D mdir(0,0);

		if(KeyDown('W'))
		{
			move = 1;
			mdir.y -= 1;
		}

		if(KeyDown('S'))
		{
			move = 1;
			mdir.y += 1;
		}

		if(KeyDown('A'))
		{
			move = 1;
			mdir.x -= 1;
		}

		if(KeyDown('D'))
		{
			move = 1;
			mdir.x += 1;
		}


		if(move)
		{
			if(mdir.length()>0.1f)
				mdir.normalize();

			mdir *= (dt*0.01f);

			player->Translate(mdir.x,0,mdir.y);

			frame += dt * 0.03f;
			if(frame>18.0f)
				frame -= 18.0f;

			player->BindTex(playerdiffus[(int)frame]);
		}

		float a = atan2f((float)((ScreenWidth()/2)-MouseX()),(float)((ScreenHeight()/2)-MouseY()));
		player->RotateY(a*57.1f);

		cam->Position(player);
		cam->PositionY(24.0f);

		Render();
		//2d


		fnt->Text(GetFPS(),10,10);

		Blend(BM_ADD);
		cur->Draw(MouseX()-16,MouseY()-16);
		Blend(BM_ALPHA);
		Flip();
	}
	ShowPointer();
	DeInit();
	debug::endlog();
};
вот такой скриншот:
Нажмите на изображение для увеличения
Название: pic6.jpg
Просмотров: 949
Размер:	115.6 Кб
ID:	5724

скачать исходник и "игру" можно тут:
http://rghost.ru/177603

Последний раз редактировалось HolyDel, 31.03.2009 в 03:30.
(Offline)
 
Ответить с цитированием
Эти 7 пользователя(ей) сказали Спасибо HolyDel за это полезное сообщение:
-=SCiP=- (31.03.2009), ABTOMAT (31.03.2009), falcon (31.03.2009), h1dd3n (31.03.2009), H@NON (31.03.2009), impersonalis (31.03.2009), moka (31.03.2009)
Старый 31.03.2009, 07:23   #2
HolyDel
 
Регистрация: 26.09.2006
Сообщений: 6,035
Написано 1,474 полезных сообщений
(для 2,707 пользователей)
Ответ: Sigel Tutorial 1. Свой Crimsoland.

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

Пишем:
Billboard *bspark;
Texture *bsparktex;
Texture *btex;

class Bullet
{
	Entity *ent;
	float l;
public:
	Bullet();
	~Bullet();

	void Update();

};

class Flash
{
	Entity *ent;
	float l;
public:
	Flash(Entity *asent);
	~Flash();

	void Update();
};
все пули и все вспышки надо хранить в списках. Списки std::list. Естественно храниться в списках будут не сами объекты а указатели на них.

typedef std::list<Bullet*> TBList;
TBList blist;

typedef std::list<Flash*> TFList;
TFList flist;
чтобы каждый раз не писать длинную муть вроде std::list<Bullet*> можно переопределить тип — командой typedef. У нее первое выражение это старое имя типа, а второе — новое.
Конструктор Bullet:
Bullet::Bullet()
{
	ent = new Entity(bb);
	ent->Blend(BM_ADD);
	ent->Position(player);
	ent->Rotate(player);
	ent->Move(2);
	ent->BindTex(btex);
	ent->Scale(0.5f);
	l = 1000.0f;

	Flash *f = new Flash(ent);

	blist.push_back(this);
}
как видите, создаем квад, ставим его в позицию игрока, сдвигаем на 2 еденицы вперед (Если у Move только один параметр — это значит смещение по Z в object-space), прикрепляем текстуру, настраиваем блендинг на аддиативный и размеры поменьще. Задаем время жизни в миллисекундах.
Кроме того, на месте пули создаем вспышку. И собственно добавляем созданный экземпляр в список. this – это указатель на текущий (создаваемый объект).

Деструктор пули:
Bullet::~Bullet()
{
	delete ent;
	blist.remove(this);
}
ну, тут ничего сложного — просто удаляем ентити и выкидываем из списка удаляемый экземпляр.

Функция обновления пули (она должна иметь именно такой формат):
void Bullet::Update()
{
	ent->Move(0.08f * dt);

	l -= dt;
	if(l<0)
		delete this;
}
двигаем вперед пулю (с учетом dt). Сокращаем время жизни. Не забывайте, что dt это вреся кадра в миллисекундах (пусть и дробное). Если пуля изжила свою секунду — она уничтожается.
Конструктор Flash:
Flash::Flash(Entity *asent)
{
	ent = new Entity(bspark);
	ent->Blend(BM_ADD);
	ent->Position(asent);
	ent->BindTex(bsparktex);
	ent->Animate(0.0f,8.0f,7.0f / 500.0f);
	flist.push_back(this);

	l = 500;
}
тут все тоже самое. Стоит только остановиться на методе — Animate. Он собственно задает границу анимации (начальный и конечный кадр). Третий параметр — скорость анимации.

Деструктор Flash аналогичен деструктору Bullet.

Метод обновления даже проще:
void Flash::Update()
{
	l-=dt;

	if(l<0)
		delete this;
}
далее, загрузка / создание ресурсов:

bspark = new Billboard(1.0f);
bspark->AnimLenght(8);
bspark->SetSmoothAnim(1);

bsparktex = new Texture("media/bflash.jpg");
btex = new Texture("media/bullet.jpg");
создаем биллбоард (он был выбран вместо квада так как его можно анимировать). Задаем ему длинну анимации в кадрах. Так как в текстуре 8 кадров то и тут пишем 8. SetSmoothAnim(1) – включает линейную интерполяцию между кадрами.

Ну и грузим две текстуры. Ничего сложного

до главного цикла объявили переменную float – fire.

if(MouseDown(1))
{
	if(fire<1)
	{
		Bullet *b = new Bullet();
		fire = 100;
	}
}

fire = max_(0,fire-dt);

misc::update_this<TBList>(blist);
misc::update_this<TFList>(flist);

AnimUpdate(dt);
первый фрагмент (там где MouseDown(1)) – это стрельба.
Если ствол остыл (fire<1) то можно стрелять.
Поэтому создаем новую пулю, не волнуйтесь, она не засрет память, даже если мы и теряем ее указатель, так как в списке она осталась, и будет корректо почищена.
Ствол остывает - fire = max_(0,fire-dt);

следующие две строчки очень интересны. Они запускают обновление элементов в списке. Он отличается от std::for_each тем, что в нем элементы во время обновления могут удалить сами себя. А в for_each теряется итератор.

AnimUpdate – обновляет все анимированные объекты. Параметр — это twin.


Исходник:
#define SIGEL_USE_ONLY
  #define SIGEL_DEVIL
  #define SIGEL_SOUND

#include <sigel/ISigel.h>

Surface *bb = 0;
Entity *player = 0;
float dt = 0;
Billboard *bspark;
Texture *bsparktex;
Texture *btex;

class Bullet
{
	Entity *ent;
	float l;
public:
	Bullet();
	~Bullet();

	void Update();

};

class Flash
{
	Entity *ent;
	float l;
public:
	Flash(Entity *asent);
	~Flash();

	void Update();
};

typedef std::list<Bullet*> TBList;
TBList blist;

typedef std::list<Flash*> TFList;
TFList flist;

Bullet::Bullet()
{
	ent = new Entity(bb);
	ent->Blend(BM_ADD);
	ent->Position(player);
	ent->Rotate(player);
	ent->MoveY(0,2);
	ent->BindTex(btex);
	ent->Scale(0.5f);
	l = 1000.0f;

	Flash *f = new Flash(ent);

	blist.push_back(this);
}

Bullet::~Bullet()
{
	delete ent;
	blist.remove(this);
}

void Bullet::Update()
{
	ent->Move(0.08f * dt);

	l -= dt;
	if(l<0)
		delete this;
}


Flash::Flash(Entity *asent)
{
	ent = new Entity(bspark);
	ent->Blend(BM_ADD);
	ent->Position(asent);
	ent->BindTex(bsparktex);
	ent->Animate(0.0f,8.0f,7.0f / 500.0f);
	flist.push_back(this);

	l = 500;
}

Flash::~Flash()
{
	delete ent;
	flist.remove(this);
}

void Flash::Update()
{
	l-=dt;

	if(l<0)
		delete this;
}

sGAME
{
	debug::startlog();
	Init();
	AppTitle("_ISh2");

	Image *cur = new Image("media/cur.jpg");

	Camera *eye = new Camera();
	Entity *cam = new Entity(EC_PIVOT);
	eye->BindEntity(cam);
	cam->Rotate(-90.0f,0,0);  //поворачиваем камеру вниз. Игра то с видом сверху.

	bb = new Surface();
	bb->MakeQuad(2.0f);

	player = new Entity(bb);
	player->Blend(BM_ALPHA);

	Texture *playerdiffus[19];

	for(int i=0;i<19;++i)
	{
		char buff[80];
		sprintf_s(buff,80,"media/solider/%d.png",i+1);
		playerdiffus[i] = new Texture(buff);
	}

	Surface *sfloor = new Surface();
	sfloor->MakeQuad(64.0f,16.0f);

	Entity *efloor = new Entity(sfloor);

	Texture *fdiffus = new Texture("media/Fieldstone.png",TF_MIPMAP | TF_ANISOTROPIC);
	efloor->BindTex(fdiffus);

	bspark = new Billboard(1.0f);
	bspark->AnimLenght(8);
	bspark->SetSmoothAnim(1);

	bsparktex = new Texture("media/bflash.jpg");
	btex = new Texture("media/bullet.jpg");

	VWait(0);

	TFont *fnt = new TFont("tahoma.txt");

	player -> Position(32.0f,0.5f,32.0f); //ставим игрока на середину. (чуть выше земли).

	int move = 0;
	float frame = 0;
	player->BindTex(playerdiffus[(int)frame]);

	HidePointer();
	float fire = 0;
	while(!KeyDown(VK_ESCAPE))
	{
		dt = GetFrameTime();
		//3d
		move = 0;
		Vector2D mdir(0,0);

		if(KeyDown('W'))
		{
			move = 1;
			mdir.y -= 1;
		}

		if(KeyDown('S'))
		{
			move = 1;
			mdir.y += 1;
		}

		if(KeyDown('A'))
		{
			move = 1;
			mdir.x -= 1;
		}

		if(KeyDown('D'))
		{
			move = 1;
			mdir.x += 1;
		}


		if(move)
		{
			if(mdir.length()>0.1f)
				mdir.normalize();

			mdir *= (dt*0.01f);

			player->Translate(mdir.x,0,mdir.y);

			frame += dt * 0.03f;
			if(frame>18.0f)
				frame -= 18.0f;

			player->BindTex(playerdiffus[(int)frame]);
		}

		float a = atan2f((float)((ScreenWidth()/2)-MouseX()),(float)((ScreenHeight()/2)-MouseY()));
		player->RotateY(a*57.1f);


		cam->Position(player);
		cam->PositionY(24.0f);

		if(MouseDown(1))
		{
			if(fire<1)
			{
				Bullet *b = new Bullet();

				fire = 100;
			}

		}

		fire = max_(0,fire-dt);

		misc::update_this<TBList>(blist);
		misc::update_this<TFList>(flist);

		AnimUpdate(dt);
		Render();
		//2d


		fnt->Text(GetFPS(),10,10);

		Blend(BM_ADD);
		cur->Draw(MouseX()-16,MouseY()-16);
		Blend(BM_ALPHA);
		Flip();
	}
	ShowPointer();
	DeInit();
	debug::endlog();
};
часть скриншота:
Нажмите на изображение для увеличения
Название: pic7.png
Просмотров: 931
Размер:	626.5 Кб
ID:	5725
(Offline)
 
Ответить с цитированием
Эти 5 пользователя(ей) сказали Спасибо HolyDel за это полезное сообщение:
-=SCiP=- (31.03.2009), falcon (31.03.2009), h1dd3n (31.03.2009), H@NON (31.03.2009), impersonalis (31.03.2009)
Старый 31.03.2009, 07:31   #3
HolyDel
 
Регистрация: 26.09.2006
Сообщений: 6,035
Написано 1,474 полезных сообщений
(для 2,707 пользователей)
Ответ: Sigel Tutorial 1. Свой Crimsoland.

последняя версия исходника, описание как делалось / делать выложу вечером.

#define SIGEL_USE_ONLY
  #define SIGEL_DEVIL
  #define SIGEL_SOUND

#include <sigel/ISigel.h>

Surface *bb = 0;
Entity *player = 0;
float dt = 0;
Billboard *bspark;
Texture *bsparktex;
Texture *btex;
Texture *enemytex;
Texture *nnmap;
Camera *eye = 0;

class Bullet
{
	Entity *ent;
	float l;
public:
	Bullet(float precission);
	~Bullet();

	void Update();
	float Dist(float x,float y);
	void Kill();
};

class Flash
{
	Entity *ent;
	float l;
public:
	Flash(Entity *asent);
	~Flash();

	void Update();
};

class Enemy
{
	Entity *ent;
	float visibility;
	float energy;
	float ebartime;
	Vector2D target;
public:
	Enemy();
	~Enemy();

	void Update();
	void Draw();
};

typedef std::list<Bullet*> TBList;
TBList blist;

typedef std::list<Flash*> TFList;
TFList flist;

typedef std::list<Enemy*> TEnList;
TEnList enlist;

Bullet::Bullet(float precission = 0)
{
	ent = new Entity(bb);
	ent->Blend(BM_ADD);
	ent->Position(player);
	ent->Rotate(player);
	ent->MoveY(0,2);
	ent->Turn(0,rnd(-precission,precission),0);
	ent->BindTex(btex);
	ent->Scale(0.5f);
	l = 1000.0f;

	Flash *f = new Flash(ent);

	blist.push_back(this);
}

Bullet::~Bullet()
{
	delete ent;
	blist.remove(this);
}

void Bullet::Update()
{
	ent->Move(0.08f * dt);

	l -= dt;
	if(l<0)
		delete this;
}

float Bullet::Dist(float x,float z)
{
	return ent->Dist(x,z);
}

void Bullet::Kill()
{
	l = -1;
}

Flash::Flash(Entity *asent)
{
	ent = new Entity(bspark);
	ent->Blend(BM_ADD);
	ent->Position(asent);
	ent->BindTex(bsparktex);
	ent->Animate(0.0f,8.0f,7.0f / 500.0f);
	flist.push_back(this);

	l = 500;
}

Flash::~Flash()
{
	delete ent;
	flist.remove(this);
}

void Flash::Update()
{
	l-=dt;

	if(l<0)
		delete this;
}


Enemy::Enemy()
{
	ent = new Entity(bb);
	ent->Blend(BM_ALPHA);
	ent->Position(rnd(4.0f,60.0f),0.6f,rnd(4.0f,60.0f));
	ent->BindTex(enemytex);

	target.x = rnd(8.0f,56.0f);
	target.y = rnd(8.0f,56.0f);

	energy = 100.0f;
	visibility = 0.5f;
	ebartime = 0;

	enlist.push_back(this);
}

Enemy::~Enemy()
{
	delete ent;
	enlist.remove(this);
}

void Enemy::Update()
{
	float x = ent->X();
	float z = ent->Z();

	TBList::const_iterator ci = blist.begin();
	TBList::const_iterator ce = blist.end();

	for(;ci!=ce;++ci)
	{
		float d = (*ci)->Dist(x,z);

		if(d<2)
		{
			(*ci)->Kill();
			energy-=10.0f;

			if(d<1.5f)
				energy -= 4.0f;

			if(d<1.0f)
				energy -= 8.0f;

			if(d<0.5f)
				energy -= 16.0f;
		}
	}

	if(energy<0)
		delete this;
}

void Enemy::Draw()
{
	Vector3D res;
	eye->Project(ent,res);
	if(res.z>0)
	{
		int x = res.x-50;
		int y = res.y-50;

		Color(100,100,100,200);
		Rect(x-3,y-3,106,18);
		Color(200,200,200,200);
		Rect(x-2,y-2,104,16);

		Color(150,150,150,200);
		Rect(x-1,y-1,102,14);

		Color(0,255,0,200);
		Rect(x,y,energy,12);
	}
}

sGAME
{
	debug::startlog();
	Init();
	AppTitle("_ISh2");

	Image *cur = new Image("media/cur.jpg");

	eye = new Camera();
	Entity *cam = new Entity(EC_PIVOT);
	eye->BindEntity(cam);
	cam->Rotate(-90.0f,0,0);  //поворачиваем камеру вниз. Игра то с видом сверху.

	bb = new Surface();
	bb->MakeQuad(2.0f);

	player = new Entity(bb);
	player->Blend(BM_ALPHA);

	Texture *playerdiffus[19];

	for(int i=0;i<19;++i)
	{
		char buff[80];
		sprintf_s(buff,80,"media/solider/%d.png",i+1);
		playerdiffus[i] = new Texture(buff);
	}

	Surface *sfloor = new Surface();
	sfloor->MakeQuad(64.0f,16.0f);

	Entity *efloor = new Entity(sfloor);

	Texture *fdiffus = new Texture("media/Fieldstone.png",TF_MIPMAP | TF_ANISOTROPIC);
	efloor->BindTex(fdiffus);

	bspark = new Billboard(1.0f);
	bspark->AnimLenght(8);
	bspark->SetSmoothAnim(1);

	bsparktex = new Texture("media/bflash.jpg");
	btex = new Texture("media/bullet.jpg");

	enemytex = new Texture("media/enemy.png");
	nnmap = new Texture("media/nnmap.jpg");

	VWait(0);

	TFont *fnt = new TFont("tahoma.txt");

	player -> Position(32.0f,0.5f,32.0f); //ставим игрока на середину. (чуть выше земли).

	int move = 0;
	float frame = 0;
	player->BindTex(playerdiffus[(int)frame]);

	HidePointer();
	float fire = 0;
	float enemyborn = 0;

	while(!KeyDown(VK_ESCAPE))
	{
		dt = GetFrameTime();
		//3d
		move = 0;
		Vector2D mdir(0,0);

		if(KeyDown('W'))
		{
			move = 1;
			mdir.y -= 1;
		}

		if(KeyDown('S'))
		{
			move = 1;
			mdir.y += 1;
		}

		if(KeyDown('A'))
		{
			move = 1;
			mdir.x -= 1;
		}

		if(KeyDown('D'))
		{
			move = 1;
			mdir.x += 1;
		}


		if(move)
		{
			if(mdir.length()>0.1f)
				mdir.normalize();

			mdir *= (dt*0.01f);

			player->Translate(mdir.x,0,mdir.y);

			frame += dt * 0.03f;
			if(frame>18.0f)
				frame -= 18.0f;

			player->BindTex(playerdiffus[(int)frame]);
		}

		float a = atan2f((float)((ScreenWidth()/2)-MouseX()),(float)((ScreenHeight()/2)-MouseY()));
		player->RotateY(a*57.1f);


		cam->Position(player);
		cam->PositionY(24.0f);

		//стрельбa
		if(MouseDown(1))
		{
			if(fire<1)
			{
				Bullet *b = new Bullet(2.0f);

				fire = 100;
			}

		}


		if(MouseDown(2))
		{
			if(fire<1)
			{
				for(int i=0;i<10;++i)
				{
					Bullet *b = new Bullet(22.5f);
				}

				fire = 1111;
			}

		}

		fire = max_(0,fire-dt);

		//создание врагов
		enemyborn+=dt;

		if(enemyborn>3000)
		{
			Enemy *e = new Enemy();
			enemyborn = 0;
		}

		misc::update_this<TBList>(blist);
		misc::update_this<TFList>(flist);
		misc::update_this<TEnList>(enlist);

		AnimUpdate(dt);
		Render();
		//2d
		Blend(BM_ALPHA);
		std::for_each(enlist.begin(),enlist.end(),std::mem_fun<void,Enemy>(&Enemy::Draw));

		Color(255,255,255,255);
		fnt->Text(GetFPS(),10,10);

		Blend(BM_ADD);
		cur->Draw(MouseX()-16,MouseY()-16);
		Blend(BM_ALPHA);
		Flip();
	}
	ShowPointer();
	DeInit();
	debug::endlog();
};
геймплей дальше сильно усложняться не будет, лишь враги начнут двигаться и пожирать игрока. кстати, врагов видно не будет. они будут невидимками. просто на их месте будет искажаться пространство.
Дальше будет в основном только украшение (враги-невидимки, свет от пуль, кровища, бамп/спекуляр на земле и т.д.)
"игра" и исходники:
ttp://rghost.ru/177734

скрин:
Нажмите на изображение для увеличения
Название: _ISh2 2009-03-31 06-29-09-99.jpg
Просмотров: 926
Размер:	333.5 Кб
ID:	5726
(Offline)
 
Ответить с цитированием
Эти 8 пользователя(ей) сказали Спасибо HolyDel за это полезное сообщение:
-=SCiP=- (31.03.2009), ABTOMAT (31.03.2009), Aceton (31.03.2009), dimanche13 (01.04.2009), falcon (31.03.2009), h1dd3n (31.03.2009), H@NON (31.03.2009), impersonalis (31.03.2009)
Старый 31.03.2009, 21:23   #4
Данил
Модератор
 
Аватар для Данил
 
Регистрация: 11.07.2007
Сообщений: 2,910
Написано 686 полезных сообщений
(для 1,694 пользователей)
Ответ: Sigel Tutorial 1. Свой Crimsoland.

Хм, мб у меня с видеодравом что-то не так, мб комп тупой, мб из-за висты, но при запуске проекта - такой эффект красивый, как буд-то flip'а нету, а картинку фона провели слева направо и остаолся тако эффект, и что-то там видно на ней, но все равно. а при принтскрине монитор вообще погас, и затем видодрайв восстановился, но игра уже была в отключке.
(Offline)
 
Ответить с цитированием
Сообщение было полезно следующим пользователям:
HolyDel (31.03.2009)
Старый 31.03.2009, 21:26   #5
HolyDel
 
Регистрация: 26.09.2006
Сообщений: 6,035
Написано 1,474 полезных сообщений
(для 2,707 пользователей)
Ответ: Sigel Tutorial 1. Свой Crimsoland.

Данил
кинь плиз sigel.log.
(Offline)
 
Ответить с цитированием
Старый 31.03.2009, 21:40   #6
Данил
Модератор
 
Аватар для Данил
 
Регистрация: 11.07.2007
Сообщений: 2,910
Написано 686 полезных сообщений
(для 1,694 пользователей)
Ответ: Sigel Tutorial 1. Свой Crimsoland.

запустил еще раз - этого бага не заметил.
мб из-за какого-то приложения, запущенного...

Последний раз редактировалось Данил, 30.11.2009 в 20:55.
(Offline)
 
Ответить с цитированием
Сообщение было полезно следующим пользователям:
HolyDel (31.03.2009)
Старый 01.04.2009, 11:34   #7
dimanche13
Мастер
 
Регистрация: 19.03.2007
Сообщений: 1,039
Написано 153 полезных сообщений
(для 252 пользователей)
Ответ: Sigel Tutorial 1. Свой Crimsoland.


вот это здорово! ведь движок без примеров, все равно что пистолет без патронов.
Респект.
__________________
(Offline)
 
Ответить с цитированием
Старый 01.04.2009, 11:42   #8
SBJoker
Злобный Админ
 
Аватар для SBJoker
 
Регистрация: 04.09.2005
Сообщений: 5,926
Написано 3,415 полезных сообщений
(для 9,330 пользователей)
Ответ: Sigel Tutorial 1. Свой Crimsoland.

Почему бы несделать картинкам Image'ам возможность указания "якоря" в ручную. Как в блитзмаксе, и относительно этой точки и транформировать картинку.. двигать крутить масштабировать...
__________________
(Offline)
 
Ответить с цитированием
Сообщение было полезно следующим пользователям:
HolyDel (01.04.2009)
Старый 01.04.2009, 13:43   #9
FDsagizi
Бывалый
 
Аватар для FDsagizi
 
Регистрация: 04.01.2008
Адрес: Казахстан \ Талдыкорган
Сообщений: 659
Написано 170 полезных сообщений
(для 509 пользователей)
Ответ: Sigel Tutorial 1. Свой Crimsoland.

HolyDel
Поздравляю, растешь!
__________________
Жизнь как говориться игра- делать игры моя профессия(с)

Программирование, это религия! Её нужно исповедовать.
(Offline)
 
Ответить с цитированием
Старый 01.04.2009, 15:00   #10
Aceton
ПроЭктировщик
 
Аватар для Aceton
 
Регистрация: 22.03.2009
Сообщений: 140
Написано 15 полезных сообщений
(для 24 пользователей)
Ответ: Sigel Tutorial 1. Свой Crimsoland.

у меня тоже не запускается =\\ черный экран и все
__________________
Все о создании и разработке игр и не только
(Offline)
 
Ответить с цитированием
Старый 01.04.2009, 15:15   #11
HolyDel
 
Регистрация: 26.09.2006
Сообщений: 6,035
Написано 1,474 полезных сообщений
(для 2,707 пользователей)
Ответ: Sigel Tutorial 1. Свой Crimsoland.

Aceton, дай мне sigel.log пожалуйста.
(Offline)
 
Ответить с цитированием
Старый 01.04.2009, 19:24   #12
Aceton
ПроЭктировщик
 
Аватар для Aceton
 
Регистрация: 22.03.2009
Сообщений: 140
Написано 15 полезных сообщений
(для 24 пользователей)
Ответ: Sigel Tutorial 1. Свой Crimsoland.

лови sigel.txt
__________________
Все о создании и разработке игр и не только
(Offline)
 
Ответить с цитированием
Сообщение было полезно следующим пользователям:
HolyDel (01.04.2009)
Старый 01.04.2009, 19:30   #13
HolyDel
 
Регистрация: 26.09.2006
Сообщений: 6,035
Написано 1,474 полезных сообщений
(для 2,707 пользователей)
Ответ: Sigel Tutorial 1. Свой Crimsoland.

Aceton
не должно же быть черного экрана. должно же все вылететь нафиг.
это глюк в драйверах судя по всему. в новой версии его исправили.
(Offline)
 
Ответить с цитированием
Старый 01.04.2009, 19:32   #14
Aceton
ПроЭктировщик
 
Аватар для Aceton
 
Регистрация: 22.03.2009
Сообщений: 140
Написано 15 полезных сообщений
(для 24 пользователей)
Ответ: Sigel Tutorial 1. Свой Crimsoland.

оно еще открывает вижал студио и просит выбрать тип дебугера
__________________
Все о создании и разработке игр и не только
(Offline)
 
Ответить с цитированием
Старый 01.04.2009, 19:48   #15
HolyDel
 
Регистрация: 26.09.2006
Сообщений: 6,035
Написано 1,474 полезных сообщений
(для 2,707 пользователей)
Ответ: Sigel Tutorial 1. Свой Crimsoland.

Нажмите на изображение для увеличения
Название: screen_6.JPG
Просмотров: 940
Размер:	344.3 Кб
ID:	5749

Aceton, проверь эту версию плиз:
http://rghost.ru/180172

кстати, тут уже можно набрать очки и проиграть))
управление WASD + мыш(3 кнопки)

вот ее исходник:
#define SIGEL_USE_ONLY //указываем что движек будет юзаться не весь
  #define SIGEL_DEVIL //подрубмаем модуль DEVIL. для загрузкаи разных форматов изображений
  #define SIGEL_SOUND //подрубаем модель для работы со звуком

#include <sigel/ISigel.h> //подрубаем сам двиг.

Surface *bb = 0; //сюрфейс квада. много где будет использоваться
Entity *player = 0; //игрок
float dt = 0; //DeltaTime. время кадра в миллисекундах
Billboard *bspark = 0; // спрайт для вспышек от выстрелов
Texture *bsparktex = 0; //текстуры вспышек выстрелов (8 в 1)
Texture *btex = 0; //текстура пули
Texture *enemytex = 0; //текустура врага
Texture *nnmap = 0; //текстура смещений нормалей (для преломления пространства под врагом)
Texture *bloodtex[6];
Camera *eye = 0; //камера
float playeren=0; //энергия игрока
int score = 0;
int scoremul = 0;
float smtime = 0;
Texture *bloodlake = 0;

class Bullet //класс пули
{
	Entity *ent; //интити пули
	float l; //время жизни
public:
	Bullet(int tp); //tp - тип пули
	~Bullet(); //деструктор

	void Update(); //функция обновления
	float Dist(float x,float y); //функция возвращает расстояние до пули
	void Kill(); //убивает пулю
};

class Flash //класс вспышки от выстрела
{
	Entity *ent; //интити вспышки
	float l; //время жизни
public:
	Flash(Entity *asent); //параметр - на место какого интити ставим вспышку
	~Flash();

	void Update(); //функция обновления
};

class Enemy //класс врага
{
	Entity *ent; //интити врага
	float visibility; //видимость - от 0 до 1
	float energy; //энергия - от 0 до 100
	float ebartime; //время жизни полоски жизни - от 0 до 1000
	Vector2D target; //куда прет враг если игрока нет рядом

	bool findplayer;
public:
	Enemy(); //конструктор
	~Enemy(); //деструктор

	void Update(); //функция обновления
	void Draw(); //функция 2д отрисовки
};

class BloodSpark
{
	Entity *ent;
	float sz;
	float dx,dy,dz;
	float turnspeed;
public:
	BloodSpark(Entity *asent,Vector2D &dir);
	~BloodSpark();

	void Update();
};

typedef std::list<Bullet*> TBList; //тип списка с пулями
TBList blist; //список с пулями

typedef std::list<Flash*> TFList; //тип списка с вспышками
TFList flist; //список со вспышками

typedef std::list<Enemy*> TEnList; //тип списка с врагами
TEnList enlist; //список с врагами

typedef std::list<BloodSpark*> TBSList;
TBSList bslist;

Bullet::Bullet(int tp = 0)
{
	ent = new Entity(bb);
	ent->Blend(BM_ADD);
	ent->Position(player);
	ent->Rotate(player);
	ent->MoveY(0,2);
	
	float precission = 0;
	switch(tp)
	{
	case 0:
		precission = 0;
		break;
	case 1:
		precission = 3.0f;
		break;
	case 2:
		precission = 22.5f;
		break;
	case 3:
		precission = 60.0f;
		break;
	default:
		precission = 0;
		break;
	};


	ent->Turn(0,rnd(-precission,precission),0);
	ent->BindTex(btex);
	ent->Scale(0.5f);
	l = 1000.0f;

	Flash *f = new Flash(ent);

	blist.push_back(this);
}

Bullet::~Bullet()
{
	delete ent;
	blist.remove(this);
}

void Bullet::Update()
{
	ent->Move(0.07f * dt);

	l -= dt;
	if(l<0)
		delete this;
}

float Bullet::Dist(float x,float z)
{
	return ent->Dist(x,z);
}

void Bullet::Kill()
{
	float dx,dz;
	ent->GetDirY(dx,dz);

	BloodSpark *bs = new BloodSpark(ent,Vector2D(dx,dz));
	l = -1;
}

Flash::Flash(Entity *asent)
{
	ent = new Entity(bspark);
	ent->Blend(BM_ADD);
	ent->Position(asent);
	ent->BindTex(bsparktex);
	ent->Animate(0.0f,8.0f,7.0f / 500.0f);
	flist.push_back(this);

	l = 500;
}

Flash::~Flash()
{
	delete ent;
	flist.remove(this);
}

void Flash::Update()
{
	l-=dt;

	if(l<0)
		delete this;
}


Enemy::Enemy()
{
	ent = new Entity(bb);
	ent->Blend(BM_DECAL);
	Vector2D pos(rnd(-1.0f,1.0f),rnd(-1.0f,1.0f));
	pos.normalize();

	pos*= 50.0f;

	ent->Position(pos.x,0.6f,pos.y);
	ent->BindTex(enemytex);

	target.x = rnd(-32.0f,32.0f);
	target.y = rnd(-32.0f,32.0f);

	energy = 100.0f;
	visibility = 0.5f;
	ebartime = 0;
	findplayer = 0;
	enlist.push_back(this);
}

Enemy::~Enemy()
{
	delete ent;
	enlist.remove(this);
}

void Enemy::Update()
{
	float x = ent->X();
	float z = ent->Z();

	//поход к новой точке и преследование игрока
	float d = ent->Dist(player);

	Vector2D dir;

	if(d<2) //пожираем игрока
	{
		playeren -= dt*0.02f; // за 0.02 * 1000 = 20. по 20 ед в секунду тратится здоровье игрока.
	}

	if(d<10) //если расстояние мало - находим игрока
		findplayer = 1;

	if(d>20) //если велико - теряем
		findplayer = 0;

	if(findplayer) //если игрок далеко, и мы его не видим
	{
		dir.x = player->X() - ent->X();
		dir.y = player->Z() - ent->Z();
	}
	else
	{
		if(Dist2D(x,z,target.x,target.y)<2) //если цель близка, то ставим ее на новое мест
		{
			target.x = rnd(-32.0f,32.0f);
			target.y = rnd(-32.0f,32.0f);
		}

		dir.x = target.x - ent->X();
		dir.y = target.y - ent->Z();
	}

	if(dir.length()>1)
	{
		dir.normalize();
		dir *= (dt * 0.007f);

		ent->Translate(dir.x,0,dir.y);
	}

	//столкновение с пулями
	TBList::const_iterator ci = blist.begin();
	TBList::const_iterator ce = blist.end();

	for(;ci!=ce;++ci)
	{
		float d = (*ci)->Dist(x,z);

		if(d<2)
		{
			if(energy>-1.0f)
			{
				(*ci)->Kill();

				energy-=10.0f;

				if(d<1.5f)
					energy -= 20.0f;

				if(d<1.0f)
					energy -= 30.0f;

				if(d<0.5f)
					energy -= 40.0f;

				ebartime = 1000.0f;

			}
		}
	}

	//столкновение с игроком
	if(energy<0)
	{
		if(smtime>0)
		{
			scoremul ++;
		}
		else
		{
			scoremul =1;
		}

		score += scoremul;

		smtime = 500;
		delete this;
	}
}

void Enemy::Draw()
{
	Vector3D res;
	eye->Project(ent,res);
	if(res.z>0)
	{
		int x = (int)res.x-50;
		int y = (int)res.y-50;

		unsigned char a = (unsigned char)(ebartime / 4.0f);
		ebartime = max_(0,ebartime-dt);

		Color(100,100,100,a);
		Rect(x-3,y-3,106,18);
		Color(200,200,200,a);
		Rect(x-2,y-2,104,16);

		Color(150,150,150,a);
		Rect(x-1,y-1,102,14);

		Color(0,255,0,a);
		Rect(x,y,(int)energy,12);
	}
}

BloodSpark::BloodSpark(Entity *asent,Vector2D &dir)
{
	ent = new Entity(bb);
	ent->Blend(BM_ALPHA);
	ent->Position(asent);
	
	ent->BindTex(bloodtex[rand(5,5)]);
	ent->Scale(rnd(0.3f,0.4f));
	ent->Rotate(0,rnd(0,360.0f),0);

	dx = dir.x * 0.01f;
	dz = dir.y * 0.01f;

	dy = 0.02f;

	turnspeed = rnd(120.0f,600.0f) * 0.001f;
	turnspeed *= ((rand(0,1)*2)-1);

	bslist.push_back(this);

}
BloodSpark::~BloodSpark()
{
	delete ent;
	bslist.remove(this);
}

void BloodSpark::Update()
{
	ent->Translate(dx*dt,dy*dt,dz*dt);
	ent->Turn(0,turnspeed*dt,0);
	dy -= dt*0.00005f;

	if(ent->Y()<0.1f)
		delete this;
}

sGAME
{
	debug::startlog();
	Init();
	AppTitle("_ISh2");

	Image *cur = new Image("media/cur.jpg");

	eye = new Camera();
	Entity *cam = new Entity(EC_PIVOT);
	eye->BindEntity(cam);
	cam->Rotate(-90.0f,0,0);  //поворачиваем камеру вниз. Игра то с видом сверху.

	bb = new Surface();
	bb->MakeQuad(2.0f);

	player = new Entity(bb);
	player->Blend(BM_ALPHA);

	Texture *playerdiffus[19];

	for(int i=0;i<19;++i)
	{
		char buff[80];
		sprintf_s(buff,80,"media/solider/%d.png",i+1);
		playerdiffus[i] = new Texture(buff);
	}

	Surface *sfloor = new Surface();
	sfloor->MakeQuad(34.0f,8.0f);
	Surface *avzone = new Surface();
	avzone->MakeQuad(32.0f,32.0f);

	Entity *efloor = new Entity(sfloor);
	Entity *eavzone = new Entity(avzone);
	eavzone->Blend(BM_ADD);
	eavzone->Color(64,64,0);
	eavzone->SetY(0.1f);
	eavzone->Hide();

	Texture *fdiffus = new Texture("media/Fieldstone.png",TF_MIPMAP | TF_ANISOTROPIC);
	efloor->BindTex(fdiffus);

	bspark = new Billboard(1.0f);
	bspark->AnimLenght(8);
	bspark->SetSmoothAnim(1);

	bsparktex = new Texture("media/bflash.jpg");
	btex = new Texture("media/bullet.jpg");

	enemytex = new Texture("media/enemy.png");
	nnmap = new Texture("media/nnmap.jpg");

	for(int i=0;i<6;++i)
	{
		char buff[80];
		sprintf_s(buff,80,"media/Blood%d.tga",i);
		bloodtex[i] = new Texture(buff);
	}
	
	VWait(0);

	TFont *fnt = new TFont("media/font.txt");

	player -> Position(0.0f,0.5f,0.0f); //ставим игрока на середину. (чуть выше земли).

	int move = 0;
	float frame = 0;
	player->BindTex(playerdiffus[(int)frame]);

	HidePointer();
	float fire = 0;
	float enemyborn = 0;

	playeren = 100;
	float borntime = 3000;
	score = 0;

	while((!KeyDown(VK_ESCAPE)) && playeren>0 )
	{
		dt = GetFrameTime();
		smtime = max_(0,smtime-dt);

		//3d
		move = 0;
		Vector2D mdir(0,0);

		if(KeyDown('W'))
		{
			move = 1;
			mdir.y -= 1;
		}

		if(KeyDown('S'))
		{
			move = 1;
			mdir.y += 1;
		}

		if(KeyDown('A'))
		{
			move = 1;
			mdir.x -= 1;
		}

		if(KeyDown('D'))
		{
			move = 1;
			mdir.x += 1;
		}


		if(move)
		{
			if(mdir.length()>0.1f)
				mdir.normalize();

			mdir *= (dt*0.01f);

			player->Translate(mdir.x,0,mdir.y);

			frame += dt * 0.03f;
			if(frame>18.0f)
				frame -= 18.0f;

			player->BindTex(playerdiffus[(int)frame]);
		}

		float a = atan2f((float)((ScreenWidth()/2)-MouseX()),(float)((ScreenHeight()/2)-MouseY()));
		player->RotateY(a*57.1f);

		//eavzone->Hide();

		if(player->X()<-32.0f)
			player->SetX(-32.0f);
		if(player->X()>32.0f)
			player->SetX(32.0f);
		if(player->Z()<-32.0f)
			player->SetZ(-32.0f);
		if(player->Z()>32.0f)
			player->SetZ(32.0f);

		cam->Position(player);
		cam->PositionY(24.0f);

		//стрельбa
		if(MouseDown(1))
		{
			if(fire<1)
			{
				Bullet *b = new Bullet(1);

				fire = 100;
			}

		}


		if(MouseDown(2))
		{
			if(fire<1)
			{
				for(int i=0;i<11;++i)
				{
					Bullet *b = new Bullet(2);
				}

				fire = 800;
			}

		}

		if(MouseDown(3))
		{
			if(fire<1)
			{
				for(int i=0;i<400;++i)
				{
					Bullet *b = new Bullet(3);
				}

				fire = 4000;
			}

		}

		fire = max_(0,fire-dt);

		//создание врагов
		enemyborn+=dt;

		if(enemyborn>borntime)
		{
			Enemy *e = new Enemy();
			enemyborn = 0;
			if(borntime>750)
				borntime *= 0.99f;

		}

		misc::update_this<TBList>(blist);
		misc::update_this<TFList>(flist);
		misc::update_this<TEnList>(enlist);
		misc::update_this<TBSList>(bslist);

		AnimUpdate(dt);
		Render();
		//2d
		Blend(BM_ALPHA);
		std::for_each(enlist.begin(),enlist.end(),std::mem_fun<void,Enemy>(&Enemy::Draw));

		Color(255,255,255,255);
		fnt->Text(GetFPS(),10,10);
		char buff[80];

		sprintf_s(buff,80,"Здоровье: %d",(int)playeren);
		fnt->Text(buff,10,40);
		
		sprintf_s(buff,80,"Очков: %d",(int)score);
		fnt->Text(buff,10,70);

		sprintf_s(buff,80,"Врагов: %d",(int)enlist.size());
		fnt->Text(buff,10,100);

		Blend(BM_ADD);
		cur->Draw(MouseX()-16,MouseY()-16);
		Blend(BM_ALPHA);
		Flip();
	}
	ShowPointer();
	DeInit();

	{
		char buff[80];
		sprintf_s(buff,80,"Вы набрали %d очков! Тянет на мировой рекорд...",score);
		Msg(buff);
	}

	debug::endlog();
};

Последний раз редактировалось HolyDel, 01.04.2009 в 20:03.
(Offline)
 
Ответить с цитированием
Ответ


Опции темы

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

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

Похожие темы
Тема Автор Раздел Ответов Последнее сообщение
Sigel HolyDel Проекты C++ 678 26.06.2010 09:38
Blitzmax arcade emulator tutorial dimanche13 2D-программирование 1 24.01.2009 10:54
Sigel vs WarTech HolyDel Болтовня 31 09.04.2008 19:13
Sigel::EntityShaders HolyDel Болтовня 8 01.04.2008 17:52
Pixel Art (Tutorial) moka Создание текстур 10 20.09.2007 16:06


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


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