
- •Затверджую
- •Індивідуальне завдання на курсову роботу з дисципліни «Об’єктно орієнтоване програмування» студенту _Романець Івану Володимировичу_____________________________
- •Розробка і обгрунтування технічного завдання
- •Проектування програмного забезпечення
- •Розробка програмного забезпечення
- •Додатки
Додатки
ДОДАТОК А
Технічне завдання
Міністерство освіти та науки України
Вінницький національний технічний університет
Інститут інформаційних технологій та комп’ютерної інженерії
ЗАТВЕРДЖУЮ
Зав. каф. КН, д.т.н., проф.
___________С.І.Перевозніков «__» _____________ 20__ р.
ТЕХНІЧНЕ ЗАВДАННЯ
На розробку об'єктно-орієнтованої системи для генерації лабіринту
1 Найменування й область застосування.
Робоча назва розроблюваного програмного комплексу (ПК) – «об'єктно-орієнтована система для генерації лабіринту». Після закінчення розробки він буде застосовуватися як гра.
2 Підстави для розробки .
Завдання на курсове проектування, протокол засідання кафедри ІС №2 від 15. 09.2008 р.
3 Мета та призначення розробки
Функціонально розроблюваний ПК служить для того, щоб можна було перепочити за веселою логічною грою.
Експлуатаційне призначення ПК – генерація лабіринту.
4 Вимоги до програмного забезпечення.
4.1 Вимоги до функціональних характеристик:
- відображення інтерфейсу користувача;
- відповідно до встановлених користувачем параметрів встановлення розміру та важкості карти.
4.2 Вимоги до програмного середовища.
- ПК розробляється на мові С++. Дане середовище розробки обране в результаті аналізу функціональних можливостей різних середовищ розробки. С++ має такі переваги:
висока ефективність і швидкодія коду;
наочність та зручність інтерфейсу середовища;
орієнтація на платформу MS Windows;
простота розробки зручного інтерфейсу майбутнього користувача.
- ПК повинний працювати під керуванням ОС Windows, що пояснюється поширеністю даної ОС.
4.3 Вимоги до інформаційного забезпечення .
- інтерфейс ПЗ повинний:
відображати всю гру;
надавати можливість вибору карти.
5 Вимоги до технічного забезпечення
Повністю збігаються з вимогами, що необхідні для встановлення ОС Windows.
6 Додаткові вимоги
Для роботи з ПК до простого користувача не пред’являється особливих вимог.
ДОДАТОК Б
Алгоритм програми
ДОДАТОК В
UML
ДОДАТОК Г
Лістинг програми
#ifdef WIN32
#pragma comment (lib, "SDL.lib")
#pragma comment (lib, "SDLmain.lib")
#pragma comment (lib, "SDL_image.lib")
#pragma comment (lib, "SDL_ttf.lib")
#pragma comment (lib, "SDL_mixer.lib")
#endif
#include "SDL.h"
#include "SDL_image.h"
#include "SDL_mixer.h"
#include "SDL_ttf.h"
#include <stdio.h>
#include <stdlib.h>
#define SOUND_ON
int SCREEN_X = 800;
int SCREEN_Y = 600;
int step = 32, startx = 0, starty = 0, done, winner, mode = 1, delay = 50, count_steps, FPS, iter;
bool monsters = 0;
int grid_x = SCREEN_X / step;
int grid_y = SCREEN_Y / step;
const char *mus[]={
"music/ARYX.S3M",
"music/fldsgold.mod",
"music/solitude.xm",
"music/ds_infmx.xm",
"music/Wait4Spring.xm",
"music/djbourg_02_dark.xm"
};
#include "images.h"
#include "engine.h"
void* my_callback_param;
Uint32 my_callbackfunc ( Uint32 interval, void *param )
{
printf ( "FPS: %d\n", FPS );
FPS = 0;
return interval;
}
int main ( int argc, char *argv[] )
{
if ( SDL_Init ( SDL_INIT_TIMER | SDL_INIT_VIDEO ) < 0 )
exit ( 1 );
atexit ( SDL_Quit );
TTF_Init();
atexit ( TTF_Quit );
screen = SDL_SetVideoMode ( SCREEN_X, SCREEN_Y, 32, SDL_HWSURFACE | SDL_RESIZABLE | SDL_DOUBLEBUF);
SDL_WM_SetCaption ( "Labirint..))", "Labirint..))" );
#ifdef SOUND_ON
if ( Mix_OpenAudio(44000, AUDIO_S16SYS, 2, 1024) < 0 ) {
fprintf(stderr,
"Warning: Couldn't set audio\n- Reason: %s\n",
SDL_GetError());
}
#endif
pers = SDL_DisplayFormat ( IMG_Load ( "Gfx/pers2.png" ) );
back = SDL_DisplayFormat ( IMG_Load ( "Gfx/clear.png" ) );
lose = SDL_DisplayFormat ( IMG_Load ( "Gfx/lose.png" ) );
win = SDL_DisplayFormat ( IMG_Load ( "Gfx/win.png" ) );
path = SDL_DisplayFormatAlpha ( IMG_Load ( "Gfx/path.png" ) );
squares[0] = SDL_DisplayFormat ( IMG_Load ( "Gfx/clear.png" ) );
squares[1] = SDL_DisplayFormat ( IMG_Load ( "Gfx/wall1.png" ) );
squares[2] = SDL_DisplayFormat ( IMG_Load ( "Gfx/wall2.png" ) );
squares[3] = SDL_DisplayFormat ( IMG_Load ( "Gfx/wall3.png" ) );
squares[4] = SDL_DisplayFormat ( IMG_Load ( "Gfx/monster2.png" ) );
squares[5] = SDL_DisplayFormat ( IMG_Load ( "Gfx/trap.png" ) );
squares[6] = SDL_DisplayFormat ( IMG_Load ( "Gfx/exit.png" ) );
if ( screen == NULL )
exit ( 1 );
int close_game = 0;
SDL_TimerID my_timer_id = SDL_AddTimer ( 1000, my_callbackfunc, my_callback_param );
while ( close_game == 0 )
{
startx = starty = winner = done = count_steps = 0;
SDL_ShowCursor ( SDL_DISABLE );
field labirint;
switch ( mode )
{
case 1:
labirint.init ( 23, 17, 6 );
break;
case 2:
labirint.init ( 30, 30, 6 );
break;
case 3:
labirint.init ( 50, 50, 15 );
break;
case 4:
labirint.init ( 50, 50, 10 );
break;
case 5:
labirint.init ( 100, 100, 20 );
break;
case 6:
labirint.init ( 100, 100, 10 );
break;
case 7:
labirint.init ( 200, 200, 20 );
break;
case 8:
labirint.init ( 500, 500, 33 );
break;
case 9:
labirint.init ( 1000, 1000, 40 );
break;
}
player gamer ( &labirint );
if(!monsters)
gamer.health=1;
gamer.draw();
SDL_Flip ( screen );
bool resize=0;
while ( done == 0 )
{
#ifdef SOUND_ON
if ( ! Mix_PlayingMusic() ) {
Mix_Music *music = Mix_LoadMUS(mus[rand()%6]);
Mix_PlayMusic(music, 0);
}
#endif
SDL_Event event;
while ( SDL_PollEvent ( &event ) )
{
if ( event.type == SDL_QUIT )
{
close_game = 1;
done = 1;
}
if ( event.type == SDL_VIDEORESIZE )
{
SCREEN_X = event.resize.w;
SCREEN_Y = event.resize.h;
grid_x = SCREEN_X / step;
grid_y = SCREEN_Y / step;
resize = 1;
}
else if ( resize )
{
screen = SDL_SetVideoMode ( SCREEN_X, SCREEN_Y, 32, SDL_SWSURFACE | SDL_RESIZABLE);
gamer.draw();
SDL_Flip(screen);
resize = 0;
}
if ( event.type == SDL_KEYDOWN )
{
if ( winner )
{
done = 1;
continue;
}
SDL_ShowCursor ( 0 );
if ( event.key.keysym.sym == SDLK_ESCAPE )
{
close_game = 1;
done = 1;
}
else
switch ( event.key.keysym.sym )
{
case SDLK_HOME:
gamer.exit();
if(winner)
continue;
break;
case SDLK_F1:
done = 1;
mode = 1;
break;
case SDLK_F2:
done = 1;
mode = 2;
break;
case SDLK_F3:
done = 1;
mode = 3;
break;
case SDLK_F4:
done = 1;
mode = 4;
break;
case SDLK_F5:
done = 1;
mode = 5;
break;
case SDLK_F6:
done = 1;
mode = 6;
break;
case SDLK_F7:
done = 1;
mode = 7;
break;
case SDLK_F8:
done = 1;
mode = 8;
break;
case SDLK_F9:
done = 1;
mode = 9;
break;
case SDLK_F10:
done = 1;
if ( monsters )
monsters = 0;
else
monsters = 1;
break;
}
while ( event.type != SDL_KEYUP && !winner )
{
if ( event.key.keysym.sym == SDLK_UP )
gamer.check ( 0, -1 );
if ( event.key.keysym.sym == SDLK_DOWN )
gamer.check ( 0, 1 );
if ( event.key.keysym.sym == SDLK_LEFT )
gamer.check ( -1, 0 );
if ( event.key.keysym.sym == SDLK_RIGHT )
gamer.check ( 1, 0 );
gamer.draw();
SDL_Flip ( screen );
SDL_Delay ( 100 );
SDL_PollEvent ( &event );
if ( event.type == SDL_MOUSEMOTION )
break;
}
FPS++;
}
else
{
if ( event.type == SDL_MOUSEBUTTONUP && winner )
{
done = 1;
continue;
}
if ( event.type == SDL_MOUSEBUTTONUP && event.button.button == SDL_BUTTON_LEFT && !winner )
gamer.go ( event.button.x / step - startx, event.button.y / step - starty );
}
}
if ( event.type == SDL_MOUSEMOTION && !winner )
{
SDL_ShowCursor ( 1 );
bool t=0;
if ( event.motion.x > ( SCREEN_X - 20 ) && SCREEN_X <= ( labirint.size_x + startx )*step )
{
t = 1;
startx--;
}
if ( event.motion.x < 20 && startx < 0 )
{
t = 1;
startx++;
}
if ( event.motion.y < 20 && starty < 0 )
{
t = 1;
starty++;
}
if ( event.motion.y > ( SCREEN_Y - 20 ) && SCREEN_Y <= ( labirint.size_y + starty )*step +24 )
{
t = 1;
starty--;
}
if(t)
{
gamer.draw();
SDL_Flip ( screen );
}
FPS++;
}
SDL_Delay ( 30 );
}
}
return 0;
}
ДОДАТОК Д
Інструкція користувача
Для того щоб виграти, потрібно пройти в протилежний кут лабіринту, не втративши при цьому все здоров'я. Спочатку у гравця 100 життів. Якщо гравець зустрінеться з перешкодою, він втрачає деяку кількість життів.
Можливі наступні перешкоди:
1. Монстр. Він завжди видно на екрані, забирає 25 життів. 2. Пастка. Її не можна побачити, зате легко знайти, забирає 10 життів. 3. Стіна міцна. Гравець може пройти через неї і втратить 10 життів. 4. Стіна слабка (напівпрозора). Те ж саме, забирає 5 життів. Відмінність монстрів і пасток від стін полягає в тому, що при зустрічі з монстром персонаж при нестачі здоров'я гине, а через стіну він не зможе пройти.
Управління:
Персонаж управляється стрілками і мишею. При управлінні мишею (напівавтоматичне управління), вам просто потрібно клікнути на будь-який порожній клітці, а ваш персонаж сам знайде найкоротший шлях до неї. Щоб пройти крізь стіну, клацніть по ній, коли персонаж знаходиться поруч зі стіною. Будьте уважні - він може наступити на пастку або на монстра! Стрілками персонаж управляється повністю вручну.
У грі також є механізм повністю автоматичного управління, персонаж сам вибере оптимальний найкоротший шлях до виходу, а якщо це неможливо - попередить вас про це. Даний режим активується клавішею Home. Під час того, як комп'ютер робить ходи, коліщатком миші можна збільшити або зменшити швидкість його переміщення.
Для того, щоб просто подивитися на лабіринт без переміщення персонажа, потрібно підвести курсор миші до краю екрана.
Esc - вихід з гри
F10 - включити / відключити монстрів у грі
Стрілки - переміщення персонажа
Home - знайти вихід автоматично
Ви можете вибирати різні рівні складності клавішами F1-F9.
Клавіша |
Розмір лабіринту |
Кількість монстрів (тільки режим F10) |
F1 |
18х17 |
мало |
F2 |
30х30 |
багато |
F3 |
50х50 |
мало |
F4 |
50х50 |
багато |
F5 |
100х100 |
мало |
F6 |
100х100 |
багато |
F7 |
200х200 |
мало |
F8 |
500х500 |
мало |
F9 |
1000х1000 |
мало |
Ще не знайдено людину, яка б виграла на рівні 7 з клавішею «F10» і вище.