Основные этапы развития компьютерных игр.

Содержание.

1. Введение…………………………………………………………………3

2. Теоретическая часть…………………………………………………….5

1.

2.

2.1. Основные этапы развития компьютерных игр…………………. 5

2.2. Виды компьютерных игр…………………………………………. 9

2.3. Выбор средств и среды для разработки…………………………. 13

2.4. Основные логические концепции приложения………………… 15

3. Практическая часть…………………………………………………… 18

3.1. Структура программы и ее реализация………………………… 18

3.2. Интерфейс приложения……………………………………………19

3.3. Руководство пользователя…………………………………………22

4. Заключение……………………………………………………………….

5. Приложения………………………………………………………………

5.1. Полный код программы……………………………………………..

5.2. Дополнительные скриншоты приложения…………………………

6. Список источников……………………………………………………….

1. Введение.

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

В наше время, особенно широкое распространение, получили различные компьютерные игры – уникальный продукт научно-технического развития и развития личности; явление информационного общества, приобретшее в последние десятилетия исключительную популярность. Они привлекают обширнейшую аудиторию, в которую входят представители всех возрастов и слоев населения. По статистике более 90 % современных детей и множество взрослых играют в видеоигры. По сей день спорным вопрос остается влияние компьютерных игр на людей, некоторые считают, что игры являются прекрасным средством для развития различных навыков (внимание, логика, память). Однако существует мнение, что компьютерные игры скорее вредят и отнимают свободное время. Нельзя однозначно сказать хорошо это или плохо. Не смотря на все это, наблюдается стремительное развитие игрового программного обеспечения, постоянное усовершенствование методов реализации игрового процесса, графических представлений, разработка новых методов взаимодействия пользователя с приложением. Существует обширное количество компаний, занимающихся разработкой компьютерных игр. Кроме того, данный процесс сам по себе является способом выражения своих идей и создания своего уникального проекта, сама процесс игры развивает стратегическое, творческое, нестандартное мышление. Данные причины, отражающие с каждым днем растущую актуальность темы разработки компьютерных игр, послужили причиной для выбора темы курсовой работы.

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

1. Отбор литературы, необходимой для ознакомления с темой курсовой работы.

2. Изучение данной литературы, исследование актуальности темы проекта.

3. Ознакомление с предметной областью, историей развития компьютерных игр и их видами.

4. Разработка собственного игрового приложения на основе полученных знаний.

4.1. Разработка основной концепции игры.

4.2. Разработка логики игры.

4.3. Разработка графического и звукового оформления.

4.4. Создание классов и их методов, содержащих сведения и модели поведения объектов.

4.5. Обработка взаимодействия игрока и объектов с окружением.

5. Непосредственная реализация приложения.

6. Тестирование.

Результатом проделанной работы будет являться простейшая компьютерная 2D игра, отражающая исследовательскую работу и знания, примененные на практике. В дальнейшем проект может быть усовершенствован путем улучшения графической или геймплейной составляющей.

2. Теоретическая часть.

Виды компьютерных игр.

Аркады (аркадные игры) имеют несложный игровой процесс, не меняющийся в течение игры. В большинстве аркадных игр для достижения результатов игроку нужно проявлять хорошую реакцию. Обычно в играх аркадах развита система бонусов: начисление очков, временное улучшение характеристик персонажа (оружие, скорость и другие).

Головоломки — вид компьютерных игр, для прохождения которых от игрока требуется решать задачи, требующие логики, воображения и интуиции. Головоломки обычно интегрированы в сюжет, и на их решение в игре делается основной упор.

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

Платформеры - очень популярный вид компьютерных игр. Особенностью платформеров является то, что вы и ваш персонаж передвигаются по уровню, который состоит из платформ, расположенных на разной высоте. Запрыгивая на платформы и собирая различные предметы или монеты, игрок продвигается вперед, пока не достигнет конца уровня. Практически во всех платформерах на уровнях игрок столкнется с врагами, с которыми ему предстоит бороться различными способами. (Рисунок 2.)

Основные этапы развития компьютерных игр. - student2.ru

Рисунок 2. Скриншот игры Mario, являющейся одним из самых популярных платформеров.

Квесты (от англ. quest — поиски приключений), или игры-приключения — обычно игры, в которых герой продвигается по сюжету, выполняет различные задания и взаимодействует с игровым миром посредством использования предметов, общения с другими персонажами и решения головоломок. Название жанру дала серия компьютерных игр от Sierra (Space Quest, King’s Quest, Police Quest) ставшими одними из лучших игр квестов своего времени.

ММОРПГ (от англ. MMORPG — Massively multiplayer online role-playing game), или массовые многопользовательские ролевые онлайн-игры — вид ролевых компьютерных игр, в которых реальные игроки взаимодействуют друг с другом в виртуальном мире. Как и в большинстве обычных ролевых игр в ММОРПГ игрок управляет персонажем, улучшая его характеристики и взаимодействуя с другими игроками. Главные отличия от РПГ состоят в неограниченном числе участников и непрерывности игрового процесса, который протекает круглосуточно, в то время как игроки посещают виртуальный игровой мир по мере возможности.

РПГ (от англ. RPG — Role-Playing Games), или компьютерные ролевые игры — игры, основанные на элементах игрового процесса традиционных настольных ролевых игр. Характерным для РПГ-игр является наличие достаточно большого количества характеристик главного героя, которые определяют его силу и способности. Эти параметры можно совершенствовать, убивая врагов и выполняя различные миссии.

Симуляторы — вид компьютерных игр, имитирующих управление каким-либо процессом, аппаратом или средством передвижения. Для симулятора очень важна реалистичность и полнота моделируемого объекта. Цель хорошего симулятора максимально приблизить условия управления объектом к реальным. Наиболее популярными являются авиасимуляторы, в которых моделируется управление реальным самолетом. Хорошие компьютерные симуляторы могут служить в качестве тренажеров.

Стратегии (стратегические компьютерные игры) — требуют от игрока планирования и выработки определенной тактики и стратегии для достижения необходимой цели, например, победы в военной операции или захвата вражеского государства. Игрок управляет не единственным персонажем, а армиями, городами, государствами или даже цивилизациям. Различают пошаговые стратегические игры, где игроки ходят поочередно, и игры стратегии в реальном времени, в которых все игроки выполняют свои действия одновременно, и течение времени не останавливается. (Рисунок 3.)

Основные этапы развития компьютерных игр. - student2.ru

Рисунок 3. Скриншот из игры Heroes of Might and Magic III: The Restoration of Erathia.

Шутеры (от англ. shoot — стрелять), или «стрелялки» — вид игр, в котором игроку, в большинстве случаев действуя в одиночку, нужно уничтожать противников при помощи различного оружия. В зависимости от конкретной игры игрок может использовать как современные виды оружия, их футуристические аналоги, а также совершенно уникальные виды оружия, выдуманные разработчиками игры. (Рисунок 4.)

Основные этапы развития компьютерных игр. - student2.ru

Рисунок 4. Скриншот из игры Half-Life научно-фантастического шутера от первого лица (1998 год).

Экшены (от англ. action — действие) — один из самых популярных видов компьютерных игр, в которых успех игрока в большой степени зависит от быстроты его реакции и способности оперативно принимать верные решения. Действие в большинстве игр экшенов развивается очень динамично и требует напряжения внимания и быстрой реакции на происходящие события. Оружие или способности героя к рукопашному бою чаще всего используются, как главные инструменты продвижения в игре.

Практическая часть.

Интерфейс приложения.

При запуске приложения пользователь попадает на начальный экран с главным меню, где на заднем фоне воспроизводится звуковое сопровождение игры. (Рисунок 5.)

Основные этапы развития компьютерных игр. - student2.ru

Рисунок 5.Главное меню.

Само меню состоит из трех пунктов: «New game», «About», «Exit». (Меню игры выделено красным цветом на Рисунке 5) В данный момент активным является пункт «New game», для активного состояния характерно изменение цвета и размера надписи, чтобы пользователь мог отчетливо видеть, что именно им сейчас выбрано. При передвижении по пунктам меню издается характерный звук. При нажатии на клавишу [E] можно соответственно начать новую игру, прочитать информацию о приложении (Рисунок 6.) либо выйти из игры.

Фиолетовым цветом (Рисунок 5.) выделена часть, которая демонстрирует пользователю его прогресс, то есть количество собранных им за игру монет (из 17 возможных, при сборе 17 из 17 победа в игре), при начале новой игры прогресс обнуляется. Надпись «Game» показывает пользователю, в каком состоянии сейчас игра, если эта надпись выделена зеленым цветом (Рисунок 7.), то пользователь сейчас в процессе игры. По окончании игры вместо этой надписи появится надпись «Victory!» (Рисунок 6.), в случае выполнения условия прохождения игры, либо «Game over», в случае поражения (смерти). Зеленым цветом (Рисунок 5.) выделено краткое руководство для пользователя, оно наглядно демонстрирует, какие клавиши необходимо нажимать пользователю для навигации по пунктам меню, выбора соответствующего пункта меню или управления персонажем.

Основные этапы развития компьютерных игр. - student2.ru

Рисунок 6.Выбран пункт меню «About», пользователю демонстрируется, что он одержал победу в игре.

При выборе пользователем пункта «New game» он автоматически попадает на карту игры, где находится персонаж, монетки («Coin»), которые необходимо собирать для победы в игре и враги, которые могут быть уничтожены игроком посредством прыжка на них сверху или выстрелить в них, при нажатии клавиши [space]. (Рисунок 7.) Так же слева указывается количество собранных им монет, то, что пользователь находится в игре и количество жизней. (Выделено желтым цветом на Рисунке 7.) Теперь пользователь может непосредственно начать игровой процесс, управляя персонажем для достижения основной цели игры. Игрок взаимодействует с окружением, то есть при прохождении через монетку, она исчезает, при соприкосновении с врагом, персонаж начинает мигать и издавать характерный звук, при этом количество его жизней постепенно уменьшается, однако враги могут быть уничтожены, как было сказано выше. При попадании на шипы здоровье игрока так же начинает уменьшаться, но с большей скоростью. (Рисунок 8.) Если количество жизней игрока опускается до нуля, то игра считается оконченной проигрышем, так же будет считаться проигрыш, если пользователь во время игры нажмет на клавишу [Esc], что вернет его в главное меню. При сборе последней монеты пользователь автоматически возвращается в главное меню, де у него есть возможность начать игру снова либо выйти из игры.

Основные этапы развития компьютерных игр. - student2.ru

Рисунок 7.Карта игры.

Основные этапы развития компьютерных игр. - student2.ru

Рисунок 8.Ситуация попадания персонажа на шипы, при этом воспроизводится соответствующая анимация и звуковое сопровождение, а здоровье игрока начинает стремительно понижаться.

Руководство пользователя.

Здравствуйте! Мы рады приветствовать вас в нашем приложении. Данное руководство предназначается для ознакомления с игрой и игровым процессом. При запуске приложения, вы попадаете в главное меню. (Рисунок 9.) Здесь вы можете выбрать дальнейшие свои действия посредством выбора одного из трех пунктов: «New game» - начать новую игру, «About» - узнать больше о данном приложении, «Exit» - выход из приложения.

Основные этапы развития компьютерных игр. - student2.ru

Рисунок 9.Меню игры.

Кроме того, на экране отображается ваш прогресс в игре в строке «Coin», а именно показывается, сколько монет вы собрали за игру. Основной целью является сбор всех 17 монет на уровне. Ниже будет отображаться одна из двух надписей по окончании игры: «Victory!» в случае вашего выигрыша либо «Game over» в случае смерти. Следует заметить, что если вы выйдите в главное меню во время непосредственно игрового процесса, то ваш результат отобразится, но будет засчитано поражение в игре. Так же справа вы можете увидеть краткое руководство, своеобразную подсказку вам. Там представлен список клавиш, которые вам необходимо нажимать для выполнения различных действий: [E] для выбора необходимого пункта меню, [W][A][S][D] навигация по пунктам меню и передвижение персонажа на уровне, [space] для стрельбы, [Esc] для возвращения в главное меню во время прохождения уровня. При выборе пункта меню «New game» вы попадаете на уровень, где вам необходимо, избегая монстров и шипов, собрать все 17 монет. (Рисунок 10.)

Основные этапы развития компьютерных игр. - student2.ru

Рисунок 10. Карта игры.

Слева на экране отображается количество собранных вами монет («Coin») и ваше здоровье («Health»). От двух этих параметров зависит ваш успех или проигрыш в игре. А именно, при сборе всех монет, как уже говорилось выше, вы одержите победу, а при потере всего здоровья (то есть, когда уровень здоровья опустится со 100 до 0), игра будет проиграна. Здоровье вы можете потерять вследствие контакта с врагами (круглые роботы, передвигающиеся по уровню) либо при попадании на шипы. (Рисунок 11.) В этих случаях вы так же услышите характерный звук, издаваемый персонажем. Заметим, что при попадании на шипы здоровье будет уменьшаться с гораздо большей скоростью. Используя соответствующие клавиши вам необходимо передвигаться по уровню, преодолевая препятствия и уничтожая врагов. Убить врага можно двумя способами: выстрелить в него, нажав соответствующую клавишу (стрелять вы можете стоя на месте, во время бега и карабкаясь по лестнице), либо прыгнуть на него сверху. Заметим, что в обоих случаях урон вам наноситься не будет. Так же на уровне существует секретное место, в которое вам обязательно нужно попасть для прохождения игры. При получении последней монетки или смерти вы автоматически попадете в главное меню, где сможете выбрать ваши дальнейшие действия (начать игру сначала или выйти из игры). Во время прохождения уровня вы сами можете вернуться в главное меню, нажав клавишу [Esc].

Желаем вам приятной игры!

Основные этапы развития компьютерных игр. - student2.ru

Рисунок 11. Попадание персонажа на шипы, что может привести к скорой смерти и проигрышу.

Рекомендуемые системные требования:

· OS: windows 7, 8, 8.1.

· RAM: 54 Мб

· CPU: 1 ГГц

· GPU: Open Gl совместимый.

· Наличие Microsoft VisualC Redist.

· Клавиатура.

Заключение.

В ходе проделанной работы было создано простейшее игровое 2D приложение. Главная цель курсового проекта и задачи, поставленные изначально, были успешно выполнены. Проект можно назвать полноценным игровым приложением, которое имеет дальнейшие перспективы усовершенствования. Основные перспективы:

1. Возможность пользователя отключать звук во время игры.

2. Наличие нескольких уровней.

3. Возможность пользователя вводить свое имя перед началом игры.

4. Возможность пользователя сравнивать свой результат с результатами предыдущих прохождений.

5. Доработка графической составляющей (усовершенствование графики).

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

7. Добавление сюжетной канвы.

8. Нелинейность уровней.

9. Скелетная анимация.

10. Подключение мыши.

Приложения.

Полный код программы.

#include <SFML/Graphics.hpp>

#include <SFML/Audio.hpp>

#include <iostream>

#include <vector>

#include <list>

#include "string.h"

#include <stdio.h>

#include <sstream>//преобразование int в string

#include <string>

#include <windows.h>

#include "level.hpp"

#include "anim.hpp"

using namespace sf;

bool ingame=0,newgame=1,reit=0,esc=0,reite=0;

std::string ress,ress2,winn;

int res=0,reset,buf=100,win=100;

static inline std::string int2Str(int x)

{

std::stringstream type;

type << x;

return type.str();

}

class Entity

{

public:

float x,y,dx,dy,w,h;

AnimationManager anim;

std::vector<Object> obj;

bool life, dir;

float timer, timer_end;

String Name;

int Health;

Entity(AnimationManager &A,int X, int Y)

{

anim = A;

x = X;

y = Y;

dir = 0;

life=true;

timer=0;

timer_end=0;

dx=dy=0;

}

virtual void update(float time) = 0;

void draw(RenderWindow &window)

{

anim.draw(window,x,y+h);

}

FloatRect getRect()

{

return FloatRect(x,y,w,h);

}

void option(String NAME, float SPEED=0, int HEALTH=10, String FIRST_ANIM="")

{

Name = NAME;

if (FIRST_ANIM!="") anim.set(FIRST_ANIM);

w = anim.getW();

h = anim.getH();

dx = SPEED;

Health = HEALTH;

}

};

class Bullet:public Entity

{

public:

Bullet(AnimationManager &a, Level &lev,int x,int y,bool dir):Entity(a,x,y)

{

option("Bullet", 0.3, 10, "move");

if (dir) dx=-0.3;

obj = lev.GetObjects("solid");

}

void update(float time)

{

x+=dx*time;

for (int i=0;i<obj.size();i++)

if (getRect().intersects(obj[i].rect))

{Health=0;}

if (Health<=0) {anim.set("explode");dx=0;

if (anim.isPlaying()==false) life=false;

}

anim.tick(time);

}

};

class PLAYER: public Entity

{

public:

enum {stay,walk,duck,jump,climb,swim} STATE;

bool onLadder, shoot, hit;

std::map<std::string,bool> key;

PLAYER(AnimationManager &a, Level &lev,int x,int y):Entity(a,x,y)

{

option("Player",0,100,"stay");

STATE=stay; hit=0;

obj = lev.GetAllObjects();

}

void KeyCheck()

{

if (key["L"])

{

dir=1;

if (STATE!=duck) dx=-0.1;

if (STATE==stay) STATE=walk;

}

if (key["R"])

{

dir=0;

if (STATE!=duck) dx=0.1;

if (STATE==stay) STATE=walk;

}

if (key["Up"])

{

if (onLadder) STATE=climb;

if (STATE==stay || STATE==walk) { dy=-0.27; STATE=jump; anim.play("jump");}

if (STATE==swim || STATE==climb) dy=-0.05;

}

if (key["Down"])

{

if (STATE==stay || STATE==walk) { STATE=duck; dx=0;}

if (STATE==swim || STATE==climb) dy=0.05;

}

if (key["Space"])

{

shoot=true;

}

/////////////////////если клавиша отпущена///////////////////////////

if (!(key["R"] || key["L"]))

{

dx=0;

if (STATE==walk) STATE=stay;

}

if (!(key["Up"] || key["Down"]))

{

if (STATE==swim || STATE==climb) dy=0;

}

if (!key["Down"])

{

if (STATE==duck) { STATE=stay;}

}

if (!key["Space"])

{

shoot=false;

}

}

void update(float time)

{

KeyCheck();

if (STATE==stay) anim.set("stay");

if (STATE==walk) anim.set("walk");

if (STATE==jump) anim.set("jump");

if (STATE==duck) anim.set("duck");

if (STATE==climb) {anim.set("climb"); anim.pause(); if (dy!=0) anim.play(); if (!onLadder) STATE=stay;}

if (shoot) { anim.set("shoot");

if (STATE==walk) anim.set("shootAndWalk");}

if (hit) { timer+=time;

if (timer>1000) {hit=false; timer=0;}

anim.set("hit");}

if (dir) anim.flip();

x += dx * time;

Collision(0);

if (STATE!=climb) dy+=0.0005*time;

y += dy*time; onLadder=false;

Collision(1);

anim.tick(time);

key["R"]=key["L"]=key["Up"]=key["Down"]=key["Space"]=false;

}

void Collision(int num)

{

for (int i=0;i<obj.size();i++)

if (getRect().intersects(obj[i].rect))

{ if(obj[i].name=="do")

{

}

if(obj[i].name=="trap")

{

hit=1;

Health-=1;

}

if (obj[i].name=="solid")

{

if (dy>0 && num==1) { y = obj[i].rect.top - h; dy=0; STATE=stay;}

if (dy<0 && num==1) { y = obj[i].rect.top + obj[i].rect.height ; dy=0;}

if (dx>0 && num==0) { x = obj[i].rect.left - w; }

if (dx<0 && num==0) { x = obj[i].rect.left + obj[i].rect.width ;}

}

if (obj[i].name=="ladder") { onLadder=true; }

if (obj[i].name=="SlopeLeft")

{ FloatRect r = obj[i].rect;

int y0 = (x+w/2-r.left) * r.height/r.width+ r.top - h;

if (y>y0)

if (x+w/2>r.left)

{y = y0; dy=0; STATE=stay;}

}

if (obj[i].name=="SlopeRight")

{ FloatRect r = obj[i].rect;

int y0 = - (x+w/2-r.left) * r.height/r.width + r.top+r.height - h;

if (y > y0)

if (x+w/2<r.left+r.width)

{y = y0 ; dy=0; STATE=stay;}

}

}

}

};

class ENEMY: public Entity

{

public:

ENEMY(AnimationManager &a, Level &lev,int x,int y):Entity(a,x,y)

{

option("Enemy", 0.01, 15, "move");

}

void update(float time)

{

x += dx * time;

timer+=time;

if (timer>3200) {dx*=-1;timer=0;}

if (Health<=0) {anim.set("dead"); dx=0;

timer_end+=time;

if (timer_end>4000) life=false;

}

anim.tick(time);

}

};

class COIN: public Entity

{

public:

COIN(AnimationManager &a, Level &lev,int x,int y):Entity(a,x,y)

{

option("Coin", 0, 1, "move");

}

void update(float time)

{

x += dx * time;

timer+=time;

if (timer>3200) {dx*=-1;timer=0;}

if (Health<=0) {anim.set("dead"); dx=0;

timer_end+=time;

if (timer_end>4000) life=false;

}

anim.tick(time);

}

};

class MovingPlatform: public Entity

{

public:

MovingPlatform(AnimationManager &a, Level &lev,int x,int y):Entity(a,x,y)

{

option("MovingPlatform", 0.05, 0, "move");

}

void update(float time)

{

x += dx * time;

timer+=time;

if (timer>6000) {dx*=-1;timer=0;}

anim.tick(time);

}

};

int main()

{

Music music,jump,shoot,hit,enter,change;

jump.openFromFile("files/jump.wav");

shoot.openFromFile("files/shoot.wav");

music.openFromFile("files/main.wav");

hit.openFromFile("files/hit.wav");

enter.openFromFile("files/enter.wav");

change.openFromFile("files/change.wav");

Text text,//новая игра

text2,//результаты

text3,//выход

text4,//очки на экран

text5,//гейм овер

text6,//жизнь на экран

text7,//жизнь

text8,//about

text9,//win

text10,// /

text11,//управление

text12;//about выбрано

Font font;

font.loadFromFile("sansation.ttf");

text.setFont(font);

text.setString("New Game");

text.setCharacterSize(24);

text2.setFont(font);

text2.setString("Coin:");

text2.setCharacterSize(24);

text3.setFont(font);

text3.setString("Exit");

text3.setCharacterSize(24);

text4.setFont(font);

text4.setCharacterSize(24);

text5.setFont(font);

text5.setString("Game");

text5.setCharacterSize(24);

text6.setFont(font);

text6.setCharacterSize(24);

text7.setFont(font);

text7.setCharacterSize(24);

text7.setString("Health:");

text8.setFont(font);

text8.setCharacterSize(24);

text8.setString("About");

text9.setFont(font);

text9.setCharacterSize(24);

text10.setFont(font);

text10.setCharacterSize(24);

text10.setString("/");

text11.setFont(font);

text11.setCharacterSize(24);

text11.setString("Press [E] to select\nUse [W][A][S][D] to move\nPress [space] to shoot\nPress [Esc] to return to menu");

text12.setFont(font);

text12.setCharacterSize(24);

text12.setString("Was created by Antonova Evgenia\n Mashukow Nikolay");

///////////// инициализация ///////////////////////////

RenderWindow window(VideoMode(1280, 720), "My Game");

Style::None;

pro1:

View view( FloatRect(0, 0, 1280, 720) );

Level lvl;

lvl.LoadFromFile("level.tmx");

Texture tileSet, moveplatform, megaman, fang,coinn,menu,pict;

Sprite menuspr,pictspr;

menu.loadFromFile("files/menu.png");

menuspr.setTexture(menu);

menuspr.setTextureRect(IntRect(0,0,1280,720));

pict.loadFromFile("files/ingame.png");

pictspr.setTexture(pict);

pictspr.setTextureRect(IntRect(0,0,1280,720));

tileSet.loadFromFile("files/enemy.png");

moveplatform.loadFromFile("files/movingPlatform.png");

megaman.loadFromFile("files//megaman.png");

fang.loadFromFile("files/bullet.png");

coinn.loadFromFile("files/coin.png");

AnimationManager anim;

anim.loadFromXML("files/megaman_anim.xml",megaman);

anim.animList["jump"].loop = 0;

AnimationManager anim2;

anim2.create("move",fang,16,0,16,4,1,0);

anim2.create("explode",fang,6,0,16,16,4,0.01,29,false);

AnimationManager anim3;

anim3.create("move",tileSet,0,0,32,32,2,0.002,32);

anim3.create("dead",tileSet,64,0,32,32,2,0.0005,32);

AnimationManager anim4;

anim4.create("move",moveplatform,0,0,95,22,1,0);

AnimationManager anim5;

anim5.create("move",coinn,0,0,32,32,2,0.002,32);

anim5.create("dead",coinn,64,0,32,32,2,0.0005,32);

std::list<Entity*> entities;

std::list<Entity*>::iterator it;

std::vector<Object> e;

e= lvl.GetObjects("enemy");

for (int i=0;i < e.size();i++)

entities.push_back(new ENEMY(anim3, lvl, e[i].rect.left, e[i].rect.top) );

e = lvl.GetObjects("MovingPlatform");

for (int i=0;i < e.size();i++)

entities.push_back(new MovingPlatform(anim4, lvl, e[i].rect.left, e[i].rect.top) );

e = lvl.GetObjects("Coin");

for (int i=0;i < e.size();i++)

entities.push_back(new COIN(anim5, lvl, e[i].rect.left, e[i].rect.top) );

win=e.size();

Object pl = lvl.GetObject("player");

PLAYER player1(anim, lvl, pl.rect.left, pl.rect.top);

music.play();

Clock clock;

Clock musicc;

/////////////////// основной цикл /////////////////////

while (window.isOpen())

{

ress=int2Str(res);

winn=int2Str(win);

ress2=int2Str(player1.Health);

text4.setString(ress);

text6.setString(ress2);

text9.setString(winn);

float time = clock.getElapsedTime().asMicroseconds();

float musiccc=musicc.getElapsedTime().asSeconds();

clock.restart();

time = time/600;

if (time > 400) time = 400;

if(musiccc>=10)

{

music.play();

musicc.restart();

}

Event event;

while (window.pollEvent(event))

{

if (event.type == Event::Closed)

window.close();

if(ingame==0)

{

if (event.type == Event::KeyPressed)

if (event.key.code==Keyboard::Escape)

window.close();

if(newgame==1)

{

if (event.type == Event::KeyPressed)

if (event.key.code==Keyboard::E)

{ enter.play();

res=0;

ingame=1;

reset=0;

text5.setCharacterSize(24);

}

}

if(esc)

{

if (event.type == Event::KeyPressed)

if (event.key.code==Keyboard::E)

{

window.close();

enter.play();

}

}

}

if (event.type == Event::KeyPressed)

if (event.key.code==Keyboard::Space)

{entities.push_back(new Bullet(anim2,lvl,player1.x+18,player1.y+18,player1.dir) ); shoot.play(); }

}

if(ingame==1)

{

if (Keyboard::isKeyPressed(Keyboard::A)) player1.key["L"]=true;

if (Keyboard::isKeyPressed(Keyboard::D)) player1.key["R"]=true;

if (Keyboard::isKeyPressed(Keyboard::W)){ player1.key["Up"]=true;if(!player1.onLadder) jump.play();}

if (Keyboard::isKeyPressed(Keyboard::S)) player1.key["Down"]=true;

if (Keyboard::isKeyPressed(Keyboard::Escape))

{ enter.play();

ingame=0;

newgame=1;

text5.setString("Game");

text5.setColor(Color::White);

reset=1;

goto pro1;

}

}

if(ingame==0)

{

if(newgame==1)

{

text.setColor(Color::Green);

text8.setColor(Color::White);

text3.setColor(Color::White);

if (Keyboard::isKeyPressed(Keyboard::D))

{ change.play();

newgame=0;

reite=0;

esc=0;

reit=1;

ingame=0;

}

if (Keyboard::isKeyPressed(Keyboard::S))

{ change.play();

reite=0;

esc=1;

reit=0;

ingame=0;

}

}

if(reit==1)

{

text.setColor(Color::White);

text8.setColor(Color::Green);

text3.setColor(Color::White);

if (Keyboard::isKeyPressed(Keyboard::S))

{change.play();

reit=0;

reite=0;

esc=1;

newgame=0;

ingame=0;

}

if (Keyboard::isKeyPressed(Keyboard::A))

{ change.play();

reit=0;

reite=0;

esc=0;

ingame=0;

newgame=1;

}

if (Keyboard::isKeyPressed(Keyboard::E))

{enter.play();

reite=1;

}

}

if(esc)

{

newgame=0;

reit=0;

text8.setColor(Color::White);

text.setColor(Color::White);

text3.setColor(Color::Green);

if (Keyboard::isKeyPressed(Keyboard::W))

{change.play();

reite=0;

reit=0;

newgame=1;

esc=0;

}

}

}

for(it=entities.begin();it!=entities.end();)

{

Entity *b = *it;

b->update(time);

if (b->life==false) { it = entities.erase(it); delete b;}

else it++;

}

player1.update(time);

if(buf!=player1.Health)

{

buf=player1.Health;

hit.play();

}

if(player1.Health<=0)

{

text5.setString("Game over");

text5.setColor(Color::Red);

text5.setCharacterSize(50);

player1.Health=10;

ingame=0;

newgame=1;

reset=1;

buf=100;

goto pro1;

}

if(newgame)

{

text.setCharacterSize(32);

text8.setCharacterSize(24);

text3.setCharacterSize(24);

}

if(reit)

{

text.setCharacterSize(24);

text8.setCharacterSize(32);

text3.setCharacterSize(24);

}

if(esc)

{

text.setCharacterSize(24);

text8.setCharacterSize(24);

text3.setCharacterSize(32);

}

if(player1.Health>0&&ingame==1)

{

text5.setString("Game");

text5.setColor(Color::Green);

}

menuspr.setPosition( window.getView().getCenter().x - window.getView().getSize().x/2, window.getView().getCenter().y - window.getView().getSize().y/2);

pictspr.setPosition( window.getView().getCenter().x - window.getView().getSize().x/2, window.getView().getCenter().y - window.getView().getSize().y/2);

text.setPosition( window.getView().getCenter().x - window.getView().getSize().x/2 + 100-53, window.getView().getCenter().y - window.getView().getSize().y/2 + 100);

text8.setPosition( window.getView().getCenter().x - window.getView().getSize().x/2 + 280-53, window.getView().getCenter().y - window.getView().getSize().y/2 + 100);

text3.setPosition( window.getView().getCenter().x - window.getView().getSize().x/2 + 100-53, window.getView().getCenter().y - window.getView().getSize().y/2 + 140);

text2.setPosition( window.getView().getCenter().x - window.getView().getSize().x/2 + 100-53, window.getView().getCenter().y - window.getView().getSize().y/2 + 180);

text4.setPosition( window.getView().getCenter().x - window.getView().getSize().x/2 + 180-53, window.getView().getCenter().y - window.getView().getSize().y/2 + 180);

text5.setPosition( window.getView().getCenter().x - window.getView().getSize().x/2 + 100-53, window.getView().getCenter().y - window.getView().getSize().y/2 + 220);

text6.setPosition( window.getView().getCenter().x - window.getView().getSize().x/2 + 180-53, window.getView().getCenter().y - window.getView().getSize().y/2 + 260);

text7.setPosition( window.getView().getCenter().x - window.getView().getSize().x/2 + 100-53, window.getView().getCenter().y - window.getView().getSize().y/2 + 260);

text9.setPosition( window.getView().getCenter().x - window.getView().getSize().x/2 + 210-53, window.getView().getCenter().y - window.getView().getSize().y/2 + 180);

text10.setPosition( window.getView().getCenter().x - window.getView().getSize().x/2 + 200-53, window.getView().getCenter().y - window.getView().getSize().y/2 + 180);

text11.setPosition( window.getView().getCenter().x - window.getView().getSize().x/2 + 100-53, window.getView().getCenter().y - window.getView().getSize().y/2 + 380);

text12.setPosition( window.getView().getCenter().x - window.getView().getSize().x/2 + 280-53, window.getView().getCenter().y - window.getView().getSize().y/2 + 140);

for(it=entities.begin();it!=entities.end();it++)

{

if ((*it)->Name=="Enemy")

{

Entity *enemy = *it;

if (enemy->Health<=0) continue;

if (player1.getRect().intersects( enemy->getRect() ))

if (player1.dy>0) { enemy->dx=0; player1.dy=-0.2; enemy->Health=0;}

else if (!player1.hit) { player1.Health-=5; player1.hit=true;

if (player1.dir) player1.x+=10; else player1.x-=10;}

for (std::list<Entity*>::iterator it2=entities.begin(); it2!=entities.end(); it2++)

{

Entity *bullet = *it2;

if (bullet->Name=="Bullet")

if ( bullet->Health>0)

if (bullet->getRect().intersects( enemy->getRect() ) )

{ bullet->Health=0; enemy->Health-=5;}

}

}

if ((*it)->Name=="MovingPlatform")

{

Entity *movPlat = *it;

if (player1.getRect().intersects( movPlat->getRect() ) )

if (player1.dy>0)

if (player1.y+player1.h<movPlat->y+movPlat->h)

{player1.y=movPlat->y - player1.h + 3; player1.x+=movPlat->dx*time; player1.dy=0; player1.STATE=PLAYER::stay;}

}

if ((*it)->Name=="Coin")

{

Entity *coin = *it;

if (player1.getRect().intersects( coin->getRect() ) )

{

if(coin->Health!=0)

res++;

coin->Health=0;

if(win==res)

{

text5.setString("Victory!");

text5.setColor(Color::Blue);

text5.setCharacterSize(50);

ingame=0;

newgame=1;

esc=0;

reit=0;

goto pro1;

}

}

}

/*рисуем*/

view.setCenter( player1.x,player1.y);

window.setView(view);

window.clear(Color(107,140,255));

}

if(ingame==0)

{

window.draw(menuspr);

window.draw(text);

window.draw(text2);

window.draw(text3);

window.draw(text4);

window.draw(text5);

window.draw(text8);

window.draw(text9);

window.draw(text10);

window.draw(text11);

if(reite)

window.draw(text12);

}

if(ingame)

{

window.draw(pictspr);

lvl.Draw(window);

for(it=entities.begin();it!=entities.end();it++)

(*it)->draw(window);

player1.draw(window);

window.draw(text2);

window.draw(text4);

window.draw(text5);

window.draw(text6);

window.draw(text7);

window.draw(text9);

window.draw(text10);

}

window.display();

}

return 0;

}

#ifndef LEVEL_H

#define LEVEL_H

#include <string>

#include <vector>

#include <map>

#include <SFML/Graphics.hpp>

#include <iostream>

#include "TinyXML/tinyxml.h"

struct Object

{

int GetPropertyInt(std::string name);

float GetPropertyFloat(std::string name);

std::string GetPropertyString(std::string name);

std::string name;

std::string type;

sf::Rect<float> rect;

std::map<std::string, std::string> properties;

sf::Sprite sprite;

};

struct Layer

{

int opacity;

std::vector<sf::Sprite> tiles;

};

class Level

{

public:

bool LoadFromFile(std::string filename);

Object GetObject(std::string name);

std::vector<Object> GetObjects(std::string name);

std::vector<Object> GetAllObjects();

void Draw(sf::RenderWindow &window);

sf::Vector2i GetTileSize();

private:

int width, height, tileWidth, tileHeight;

int firstTileID;

sf::Rect<float> drawingBounds;

sf::Texture tilesetImage;

std::vector<Object> objects;

std::vector<Layer> layers;

};

///////////////////////////////////////

int Object::GetPropertyInt(std::string name)

{

return atoi(properties[name].c_str());

}

float Object::GetPropertyFloat(std::string name)

{

return strtod(properties[name].c_str(), NULL);

}

std::string Object::GetPropertyString(std::string name)

{

return properties[name];

}

bool Level::LoadFromFile(std::string filename)

{

TiXmlDocument levelFile(filename.c_str());

// Загружаем XML-карту

if(!levelFile.LoadFile())

{

std::cout << "Loading level \"" << filename << "\" failed." << std::endl;

return false;

}

// Работаем с контейнером map

TiXmlElement *map;

map = levelFile.FirstChildElement("map");

// Пример карты: <map version="1.0" orientation="orthogonal"

// width="10" height="10" tilewidth="34" tileheight="34">

width = atoi(map->Attribute("width"));

height = atoi(map->Attribute("height"));

tileWidth = atoi(map->Attribute("tilewidth"));

tileHeight = atoi(map->Attribute("tileheight"));

// Берем описание тайлсета и идентификатор первого тайла

TiXmlElement *tilesetElement;

tilesetElement = map->FirstChildElement("tileset");

firstTileID = atoi(tilesetElement->Attribute("firstgid"));

// source - путь до картинки в контейнере image

TiXmlElement *image;

image = tilesetElement->FirstChildElement("image");

std::string imagepath = image->Attribute("source");

// Пытаемся загрузить тайлсет

sf::Image img;

if(!img.loadFromFile(imagepath))

{

std::cout << "Failed to load tile sheet." << std::endl;

return false;

}

img.createMaskFromColor(sf::Color(255, 255, 255));

tilesetImage.loadFromImage(img);

tilesetImage.setSmooth(false);

// Получаем количество столбцов и строк тайлсета

int columns = tilesetImage.getSize().x / tileWidth;

int rows = tilesetImage.getSize().y / tileHeight;

// Вектор из прямоугольников изображений (TextureRect)

std::vector<sf::Rect<int>> subRects;

for(int y = 0; y < rows; y++)

for(int x = 0; x < columns; x++)

{

sf::Rect<int> rect;

rect.top = y * tileHeight;

rect.height = tileHeight;

rect.left = x * tileWidth;

rect.width = tileWidth;

subRects.push_back(rect);

}

// Работа со слоями

TiXmlElement *layerElement;

layerElement = map->FirstChildElement("layer");

while(layerElement)

{

Layer layer;

// Если присутствует opacity, то задаем прозрачность слоя, иначе он полностью непрозрачен

if (layerElement->Attribute("opacity") != NULL)

{

float opacity = strtod(layerElement->Attribute("opacity"), NULL);

layer.opacity = 255 * opacity;

}

else

{

layer.opacity = 255;

}

// Контейнер <data>

TiXmlElement *layerDataElement;

layerDataElement = layerElement->FirstChildElement("data");

if(layerDataElement == NULL)

{

std::cout << "Bad map. No layer information found." << std::endl;

}

// Контейнер <tile> - описание тайлов каждого слоя

TiXmlElement *tileElement;

tileElement = layerDataElement->FirstChildElement("tile");

if(tileElement == NULL)

{

std::cout << "Bad map. No tile information found." << std::endl;

return false;

}

int x = 0;

int y = 0;

while(tileElement)

{

int tileGID = atoi(tileElement->Attribute("gid"));

int subRectToUse = tileGID - firstTileID;

// Устанавливаем TextureRect каждого тайла

if (subRectToUse >= 0)

{

sf::Sprite sprite;

sprite.setTexture(tilesetImage);

sprite.setTextureRect(subRects[subRectToUse]);

sprite.setPosition(x * tileWidth, y * tileHeight);

sprite.setColor(sf::Color(255, 255, 255, layer.opacity));

layer.tiles.push_back(sprite);

}

tileElement = tileElement->NextSiblingElement("tile");

x++;

if (x >= width)

{

x = 0;

y++;

if(y >= height)

y = 0;

}

}

layers.push_back(layer);

layerElement = layerElement->NextSiblingElement("layer");

}

// Работа с объектами

TiXmlElement *objectGroupElement;

// Если есть слои объектов

if (map->FirstChildElement("objectgroup") != NULL)

{

objectGroupElement = map->FirstChildElement("objectgroup");

while (objectGroupElement)

{

// Контейнер <object>

TiXmlElement *objectElement;

objectElement = objectGroupElement->FirstChildElement("object");

while(objectElement)

{

// Получаем все данные - тип, имя, позиция, etc

std::string objectType;

if (objectElement->Attribute("type") != NULL)

{

objectType = objectElement->Attribute("type");

}

std::string objectName;

if (objectElement->Attribute("name") != NULL)

{

objectName = objectElement->Attribute("name");

}

int x = atoi(objectElement->Attribute("x"));

int y = atoi(objectElement->Attribute("y"));

int width, height;

sf::Sprite sprite;

sprite.setTexture(tilesetImage);

sprite.setTextureRect(sf::Rect<int>(0,0,0,0));

sprite.setPosition(x, y);

if (objectElement->Attribute("width") != NULL)

{

width = atoi(objectElement->Attribute("width"));

height = atoi(objectElement->Attribute("height"));

}

else

{

width = subRects[atoi(objectElement->Attribute("gid")) - firstTileID].width;

height = subRects[atoi(objectElement->Attribute("gid")) - firstTileID].height;

sprite.setTextureRect(subRects[atoi(objectElement->Attribute("gid")) - firstTileID]);

}

// Экземпляр

Наши рекомендации