Автор работы: Пользователь скрыл имя, 24 Февраля 2013 в 05:40, курсовая работа
В качестве курсовой работы по объектно-ориентированному программированию было предложено написать простую игру. Основные требования к программе:
1. Наличие не менее десяти различных классов
2. Наличие различных типов связей между классами – наследование, агрегация и т.д.
3. Взаимодействие между классами в реальном времени.
1. Постановка задачи 4
2. Список классов 5
2.1 Класс Object 5
2.2 Класс ObjectList 5
2.3 Класс Game 5
2.4 Класс Player 5
2.5 Класс Enemy 5
2.6 Класс Boss 5
2.7 Класс Bullet 5
2.8 Класс Sp_Bull 5
2.9 Класс Explosion 5
2.10 Класс Life 5
2.11 Класс Defense 6
3. Диаграмма классов 7
4. Описание классов. 8
4.1 Класс Object 8
4.1.1 Атрибуты класса 8
4.1.2 Методы класса 8
4.2 Класс ObjectList. 9
4.2.1 Атрибуты класса 9
4.2.2 Методы класса 9
4.3 Класс Game 9
4.3.1 Атрибуты класса 10
4.3.2 Методы класса 10
4.4 Класс Player 10
4.4.1 Атрибуты класса 10
4.4.2 Методы класса 11
4.5 Класс Enemy 11
4.5.1 Атрибуты класса 11
4.5.2 Методы класса 11
4.6 Класс Boss 11
4.6.1 Атрибуты класса 11
4.6.2 Методы класса 12
4.7 Класс Bullet 12
4.7.1 Атрибуты класса 12
4.7.2 Методы класса 12
4.8 Класс Sp_Bull 12
4.8.1 Атрибуты класса 12
4.8.2 Методы класса 12
4.9 Класс Explosion 13
4.9.1 Атрибуты класса 13
4.9.2 Методы класса 13
4.10 Класс Life 13
4.10.1 Атрибуты класса 13
4.10.2 Методы класса 13
4.11 Класс Defense 13
4.11.1 Атрибуты класса 13
4.11.2 Методы класса 14
5. Программная реализация классов 15
5.1 Реализация абстрактного класса Object. 15
5.2 Реализация класса ObjectList 15
5.3 Реализация класса Game 17
5.4 Реализация класса Player 18
5.5 Реализация класса Enemy 20
5.6 Реализация класса Boss 22
6. Основной модуль
7. Заключение
class Defence : public Object
{
ObjectList* pList;
public:
Defence(Game* game, ObjectList* list, int x, int y);
int GetType() { return OBJECTTYPE_DEFENCE; }
void Process(Object* pObject);
bool Move();
virtual ~Defence();
};
#include "stdafx.h"
#include "Object.h"
void Object::Init(int x, int y, int width, int height)
{
//устанавливаем размеры прямоугольника, в который вписывается объект
box.x=x;
box.y=y;
box.w=width;
box.h=height;
}
void Object::Blit()
{
if (bAnim==true)
apply_surface( box.x, box.y+480-pGame->camera.y, nsSurface, pGame->screen, &clip[Frame] );
else
apply_surface( box.x, box.y+480-pGame->camera.y, nsSurface, pGame->screen );
}
bool Object::Collision(Object* pObject)
{
//метод проверяет,
не пересекаются ли
//вписаны объект,
чей метод мы вызвали, и
int left, leftB;
int right, rightB;
int top, topB;
int bottom, bottomB;
left = box.x;
right = box.x + box.w;
top = box.y;
bottom = box.y + box.h;
leftB = pObject->box.x;
rightB = pObject->box.x + pObject->box.w;
topB = pObject->box.y;
bottomB = pObject->box.y +pObject->box.h;
if( bottom <= topB )
return false;
if( top >= bottomB )
return false;
if( right <= leftB )
return false;
if( left >= rightB )
return false;
return true;
}
#include "stdafx.h"
#include "ObjectList.h"
ObjectList::ObjectList(Game* game)
{
pGame = game;
}
void ObjectList::AddObject(Object* pObject)
{
Objects.push_front(pObject);
}
void ObjectList::BlitObjects()
{
Object* pObject;
if(!Objects.empty())
{
for(OBJECTLIST_ITERATOR iterator=Objects.begin(); iterator != Objects.end(); iterator++)
{
pObject=*iterator;
pObject->Blit();
}
}
}
void ObjectList::ProcessObjects()
{
// Передвигаем объекты и проверяе, не взаимодействуют ли они.
if(!Objects.empty())
{
OBJECTLIST_ITERATOR iterator = Objects.begin();
Object* pObject;
while(iterator != Objects.end())
{
pObject=*iterator;
if(!pObject->Move())
{
delete pObject;
iterator = Objects.erase(iterator);
}
else
iterator++;
}
iterator = Objects.begin();
while(iterator != Objects.end())
{
pObject=*iterator;
OBJECTLIST_ITERATOR iterator2 = Objects.begin();
Object* pObject2;
while(iterator2 != Objects.end())
{
pObject2=*iterator2;
if(pObject != NULL && pObject2 != NULL && pObject != pObject2)
pObject->Process(pObject2);
iterator2++;
}
iterator++;
}
}
apply_surface(0,0,pGame->
}
ObjectList::~ObjectList()
{
Object* pObject;
if(!Objects.empty())
{
for(OBJECTLIST_ITERATOR iterator=Objects.begin(); iterator != Objects.end(); iterator++)
{
pObject=*iterator;
delete(pObject);
}
}
Objects.clear();
}
#include "stdafx.h"
#include "Game.h"
Game::Game()
{
//установка размеров экрана
int SCREEN_WIDTH = 640;
int SCREEN_HEIGHT = 480;
int SCREEN_BPP = 32;
//установка размера камеры
camera.h=SCREEN_HEIGHT;
camera.w=SCREEN_WIDTH ;
camera.x=0;
camera.y=480;
//подключение всех возможностей SDL
SDL_Init( SDL_INIT_EVERYTHING );
screen = SDL_SetVideoMode( SCREEN_WIDTH, SCREEN_HEIGHT, SCREEN_BPP, SDL_SWSURFACE );
SDL_WM_SetCaption( "Space shooter", NULL );
//загрузка изображений в поверхности
nsPlayer = load_image("bmp\\player.bmp");
nsEnemy = load_image("bmp\\enemy.bmp");
nsBullet = load_image("bmp\\bullet.bmp");
nsExplosion = load_image("bmp\\explo.bmp");
nsLive = load_image("bmp\\live.bmp");
nsSb = load_image("bmp\\sbl.bmp");
nsGameOver = load_image("bmp\\gameover.bmp"
nsDefence = load_image("bmp\\Defence.bmp")
nsBoss = load_image("bmp\\Boss.bmp");
backgr = load_image("bmp\\backgr.png");
nsSpBull = load_image("bmp\\Sp_Bull.bmp")
nsLifeBonus = load_image("bmp\\LB.bmp");
NumLives = 5;
}
void Game::FlipScreen()
{
//функция SDL для обновления экрана
SDL_Flip( screen );
}
void Game::MoveCam(int y)
{
//метод передвигает камеру при передвижении объекта
camera.y+=y;
if( camera.y < 0 )
{
camera.y = 0;
}
if( camera.y > 960 - camera.h )
{
camera.y = 960 - camera.h;
}
}
void Game::ClearScreen()
{
//функция очистки экрана
SDL_FreeSurface( screen );
}
void Game::DrawStatus()
{
//вывод сообщения о проигрыше
if(NumLives <= 0)
apply_surface(113,100, nsGameOver, screen);
else
for(int index=0; index < NumLives; index++)
{
//прорисовка количества жизней
apply_surface(624,index*16,
}
}
Game::~Game()
{
delete (nsPlayer);
delete (nsEnemy);
delete (nsBullet);
delete (nsExplosion);
delete (nsLive);
delete (nsGameOver);
delete (screen);
delete (backgr);
}
#include "stdafx.h"
#include "player.h"
Player::Player(Game* game, ObjectList* list)
{
//устанавливаем
координаты прямоугольников
// таблицы спрайтов
for(int i=0; i<3; i++)
{
clip[ i ].x = i*32;
clip[ i ].y = 0;
clip[ i ].w = 32;
clip[ i ].h = 32;
}
bDie=false;
bAnim=true;
Counter=0;
Frame=0;
Ammo=4;
pGame = game;
pList = list;
Init(304, 400, 32, 32);
xVel=yVel=0;
nsSurface = pGame->nsPlayer;
}
void Player::Process(Object* pObject)
{
Explosion* pExplosion;
if(bDie) return;
if(!pObject)
return;
//если объект, с которым столкнулся игрок - враг
//то враг погибает, а у игрока отнимается жизнь
if(Collision(pObject))
if(pObject->GetType()==
{
pGame->NumLives--;
for(int index=0; index<8; index++)
{
pExplosion = new Explosion(pGame, pList, box.x + index*4, box.y + rand()%16);
pList->AddObject(pExplosion);
}
pObject->Kill();
}
return;
}
void Player::Show_Am()
{
//выводит число улучшенных пуль
for(int index=0; index < Ammo; index++)
{
apply_surface(640-32*index,
}
}
void Player::handle_input()
{
if (bDie) return;
if(Counter < 3) Counter++;
else
{
Counter = 0;
if(Frame < 2) Frame++;
else
Frame = 0;
}
//реакция на нажатие "стрелок" - движение
if( pGame->event.type == SDL_KEYDOWN)
{
switch(pGame->event.key.
{
case SDLK_LEFT:xVel-=2; break;
case SDLK_RIGHT:xVel+=2; break;
case SDLK_UP:yVel-=2;break;
case SDLK_DOWN:yVel+=2;break;
}
//если это пробел - стрельба
if( pGame->event.key.keysym.sym==
{
Bullet* pBullet = new Bullet(pGame, pList, box.x + 12, box.y - 8, -3);
pBullet->set_sr(true);
pList->AddObject(pBullet);
}
//если это правый Alt - стрельба улучшенными пулями
if( pGame->event.key.keysym.sym==
{
if(Ammo!=0)
{
Sp_Bull* pSB = new Sp_Bull(pGame, pList, box.x + 12, box.y - 8, -3, 2);
pList->AddObject(pSB);
Ammo--;
}
}
}
if( pGame->event.type == SDL_KEYUP)
{
switch( pGame->event.key.keysym.sym )
{
case SDLK_LEFT:xVel+=2; break;
case SDLK_RIGHT:xVel-=2; break;
case SDLK_UP:yVel+=2;break;
case SDLK_DOWN:yVel-=2;break;
}
}
}
bool Player::Move()
{
//двигает объект в пределах игрового поля
if(bDie) return false;
box.x+= xVel;
if( (box.x < 0 ) || ( box.x+32 > 640 ))
box.x-= xVel;
box.y += yVel;
if( ( box.y < -480 ) || ( box.y+32 > 480 ))
box.y -= yVel;
pGame->MoveCam(yVel);
return true;
}
Player::~Player()
{
}
#include "stdafx.h"
#include "Enemy.h"
Enemy::Enemy(Game* game, ObjectList* list, int x, int y)
{
pGame = game;
pList = list;
for(int i=0; i<3; i++)
{
clip[ i ].x = i*32;
clip[ i ].y = 0;
clip[ i ].w = 32;
clip[ i ].h = 32;
}
Init(x, y, 32, 32);
bDie=false;
bAnim=true;
Counter=0;
Frame=0;
MoveCounter = rand()%20;
FireCounter = rand()%20;
xVel = 2 - rand()%4;
yVel = 2 - rand()%4;
nsSurface = pGame->nsEnemy;
}
void Enemy::Process(Object* pObject)
{
if(bDie) return;
}
bool Enemy::Move()
{
if(bDie) return false;
FireCounter++;
if(Counter < 3) Counter++;
else
{
Counter = 0;
if(Frame < 2) Frame++;
else
Frame = 0;
}
if(MoveCounter < 20)
{
box.x += xVel;
box.y += yVel;
if(box.x > 608)
{
box.x = 608;
MoveCounter = 20;
}
if(box.y <0)
{
box.y = 0;
MoveCounter = 20;
}
else
if(box.y > 200)
{
box.y = 200;
MoveCounter = 20;
}
MoveCounter++;
}
else
{
MoveCounter = 0;
if(FireCounter >= 100)
{
Bullet* pBullet = new Bullet(pGame, pList, box.x+12, box.y+32, 3);
pBullet->set_sr(false);
pList->AddObject(pBullet);
FireCounter = 0;
}
else
{
xVel = 2 - rand()%4;
yVel = 2 - rand()%4;
}
}
return true;
}
Enemy::~Enemy()
{
}
#include "stdafx.h"
#include "Enemy.h"
Boss::Boss(Game* game, ObjectList* list, int x, int y, int l, int d):Enemy(game, list, x,y)
{
clip[ 3 ].x = 96;
clip[ 3 ].y = 0;
clip[ 3 ].w = 32;
clip[ 3 ].h = 32;
damg=d;
lives=l;
nsSurface = pGame->nsBoss;
}
void Boss::Process(Object* pObject)
{
if(bDie) return;
if(!pObject)
return;
if(Collision(pObject))
{
switch(pObject->GetType())
{
//если объект столкнулся с пулей - отнимается жизнь
case OBJECTTYPE_BULLET:
lives-=1;
break;
// если
объект столкнулся с
case OBJECTTYPE_SBULL:
{
Sp_Bull *sb =dynamic_cast<Sp_Bull*>(
lives-=sb->Get_Dm();
}
break;
default:
break;
}
if (lives<0)
bDie=true;
return;
}
return;
}
bool Boss::Move()
{
if(bDie) return false;
FireCounter++;
if(Counter < 3) Counter++;
else
{
Counter = 0;
if(Frame < 2) Frame++;
else
Frame = 0;
}
if(MoveCounter < 20)
{
box.x += xVel;
box.y += yVel;
if(box.x > 608)
{
box.x = 608;
MoveCounter = 20;
}
if(box.y < -480)
{
box.y = -480;
MoveCounter = 20;
}
else
if(box.y > -32)
{
box.y = -32;
MoveCounter = 20;
}
MoveCounter++;
}
else
{
MoveCounter = 0;
if(FireCounter >= 100)
{
Sp_Bull* pSB = new Sp_Bull(pGame, pList, box.x+12, box.y+32, 3, 2);
pList->AddObject(pSB);
FireCounter = 0;
}
else
{
xVel = 2 - rand()%4;
yVel = 2 - rand()%4;
}
}
return true;
}
Boss::~Boss()
{
}
#include "stdafx.h"
#include "Bullet.h"
Bullet::Bullet(Game* game, ObjectList* list, int x, int y, int v)
{
for(int i=0; i<3; i++)
{
clip[ i ].x = i*8;
clip[ i ].y = 0;
clip[ i ].w = 8;
clip[ i ].h = 8;
}
bDie=false;
bAnim=true;
Counter=0;
Frame=0;
pGame = game;
pList = list;
yVel = v;
Init(x, y, 8, 8);
nsSurface = pGame->nsBullet;
}
void Bullet::Process(Object* pObject)
{
if(bDie) return;
if(!pObject)
return;
if(Collision(pObject) && pObject->GetType() != OBJECTTYPE_EXPLOSION)
{
switch(pObject->GetType())
{
//при столконовении с врагом, враг погибает только если пуля была выпущена игроком
case OBJECTTYPE_ENEMY:
if(pl==true)
{
pObject->Kill();
Explosion* pExplosion = new Explosion(pGame, pList, box.x, box.y);
pList->AddObject(pExplosion);
}
Kill();
break;
//при столкновении с пулей любого типа обе пули уничтожаются
case OBJECTTYPE_BULLET:
{
Explosion* pExplosion = new Explosion(pGame, pList, box.x, box.y);
pList->AddObject(pExplosion);
pObject->Kill();
}
break;
case OBJECTTYPE_SBULL:
{
Explosion* pExplosion = new Explosion(pGame, pList, box.x, box.y);
pList->AddObject(pExplosion);
pObject->Kill();
}
break;
//при столкновении с припятствием пуля его постепенно разрушает
case OBJECTTYPE_DEFENCE:
{
Explosion* pExplosion = new Explosion(pGame, pList, box.x, box.y);
pList->AddObject(pExplosion);
if(pObject->Frame < 5)
pObject->Frame++;
else
{
for(int index=0; index<8; index++)
{
pExplosion = new Explosion(pGame, pList, box.x + index*4, box.y + rand()%16);
pList->AddObject(pExplosion);
}
pObject->Kill();
}
}
break;
//при столкновнии у игрока отнимается жизнь
case OBJECTTYPE_PLAYER:
{
Explosion* pExplosion = new Explosion(pGame, pList, box.x, box.y);
pList->AddObject(pExplosion);
pGame->NumLives--;
if(pGame->NumLives <= 0)
{
pObject->Kill();
for(int index=0; index < 8; index++)
{
pExplosion = new Explosion(pGame, pList, box.x+rand()%32, box.y+rand()%32);
pList->AddObject(pExplosion);
}
}
}
break;
default:
break;
}
Kill();
return;
}
return;
}
bool Bullet::Move()
{
if(bDie) return false;
if(Counter < 3) Counter++;
else
{
Counter = 0;
if(Frame < 2) Frame++;
else
Frame = 0;
}
box.y += yVel;
if(box.y < -480 || box.y > 472)
return false;
return true;
}
Bullet::~Bullet()
{
}
#include "stdafx.h"
#include "Sp_Bull.h"
Sp_Bull::Sp_Bull(Game* game, ObjectList* list, int x, int y, int v, int d):Bullet(game, list, x, y, v)
{
for(int i=0; i<3; i++)
{
clip[ i ].x = i*16;
clip[ i ].y = 0;
clip[ i ].w = 19;
clip[ i ].h = 8;
}
Damage=d;
Init(x, y, 16, 8);
nsSurface = pGame->nsSpBull;
}
void Sp_Bull::Process(Object* pObject)
{
if(bDie) return;
if(!pObject)
return;
if(Collision(pObject) && pObject->GetType() != OBJECTTYPE_EXPLOSION)
{
Explosion* pExplosion = new Explosion(pGame, pList, box.x, box.y);
pList->AddObject(pExplosion);
switch(pObject->GetType())
{
case OBJECTTYPE_ENEMY:
{
if(pl==true)
pObject->Kill();
Kill();
}
break;
case OBJECTTYPE_BULLET:
pObject->Kill();
break;
case OBJECTTYPE_SBULL:
pObject->Kill();
break;
case OBJECTTYPE_DEFENCE:
{
for(int index=0; index<8; index++)
{
pExplosion = new Explosion(pGame, pList, box.x + index*4, box.y + rand()%16);
pList->AddObject(pExplosion);
}
pObject->Kill();
}
break;
case OBJECTTYPE_PLAYER:
pGame->NumLives=pGame->
if(pGame->NumLives <= 0)
{
pObject->Kill();
for(int index=0; index < 8; index++)
{
pExplosion = new Explosion(pGame, pList, box.x+rand()%32, box.y+rand()%32);
pList->AddObject(pExplosion);
}
}
break;
default:
break;
}
Kill();
return;
}
return;
}
bool Sp_Bull::Move()
{
if(bDie) return false;
if(Counter < 3) Counter++;
else
{
Counter = 0;
if(Frame < 2) Frame++;
else
Frame = 0;
}
box.y += yVel;
if(box.y < -480 || box.y > 472)
return false;
return true;
}
Sp_Bull::~Sp_Bull()
{
}
#include "stdafx.h"
#include "Explosion.h"
Explosion::Explosion(Game* game, ObjectList* list, int x, int y)
{
bDie=false;
bAnim=true;
for(int i=0; i<8; i++)
{
clip[ i ].x = i*32;
clip[ i ].y = 0;
clip[ i ].w = 32;
clip[ i ].h = 32;
}
Counter=0;
Frame=0;
pGame = game;
pList = list;
Init(x-16, y-16, 32, 32);
nsSurface = pGame->nsExplosion;
}
void Explosion::Process(Object* pObject)
{
if(bDie) return;
}
bool Explosion::Move()
{
if(bDie) return false;
if(Counter < 3) Counter++;
else
{
Counter = 0;
if(Frame < 8)
Frame++;
else
return false;
}
return true;
}
Explosion::~Explosion()
{}
#include "stdafx.h"
#include "Life.h"
Life::Life(Game* game, ObjectList* list, int x, int y, int b)
{
pGame = game;
pList = list;
Init(x, y, 24, 24);
bDie=false;
bAnim=false;
Frame=0;
Counter=0;
bonus=b;
nsSurface=pGame->nsLifeBonus;
}
void Life::Process(Object* pObject)
{
if(bDie) return;
if(!pObject)
return;
if(Collision(pObject) && (pObject->GetType() == OBJECTTYPE_PLAYER))
{
//если столкнвение прозошло с игроком, то число его жизней увеличивается
pGame->NumLives+=bonus;
Kill();
}
return;
}
bool Life::Move()
{
if(bDie) return false;
return true;
}
Life::~Life()
{
}
#include "stdafx.h"
#include "Defence.h"
Defence::Defence(Game* game, ObjectList* list, int x, int y)
{
pGame = game;
pList = list;
Init(x, y, 32, 32);
bDie=false;
bAnim=false;
Frame=0;
Counter=0;
nsSurface=pGame->nsDefence;
}
void Defence::Process(Object* pObject)
{
if(bDie) return;
if(!pObject)
Информация о работе Объектно ориентированное программирование. Простая игра