Implementace hry „Had“ (angl. Snake) pomocí GUI

Transkript

Implementace hry „Had“ (angl. Snake) pomocí GUI
Pátá zápočtová práce z předmětu Programování v Matlabu
Martin Dlask
Implementace hry „Had“ (angl. Snake) pomocí GUI
1.1 Úvod
Ze dvou nabízených témat k naprogramování v Matlabu na poslední úkol jsem si zvolil
vytvoření aplikace pomocí GUI. Jelikož jsem chtěl vytvořit nějaký program, který by
obsahoval jak formulář s menu a dostatečnými vstupy a interakcí pro uživatele, tak
algoritmus, který není příliš elementární, padl výběr na implementaci klasické hry had. I když
se zdá na první pohled implementace hry v interpretačním jazyku, který je spíše určen pro
matematické výpočty a práci s maticemi, bizarně, využívá tento program přesto několik
matematických funkcí a výpočtů s číselnými tabulkami.
1.2 Představení hry, pravidla
Herní prostředí sestává ze čtverce, ve kterém se pohybuje had, který se může pohybovat ve
čtyřech směrech (doprava, doleva, nahoru, dolů), a tudíž se může pohybovat po celém herním
poli. Na tomto čtverci se také nachází potrava. Herní pole má takzvané „propustné zdi“ v situaci, kdy by chtěl had „vyjet“ z tohoto herního pole a překročit okraj, se objeví na
druhém konci herního pole. Podle toho, na který okraj had vjel, se postupně transportuje na
druhý okraj. Hra probíhá v krátkých časových krocích. V každé iteraci se může uživatel
rozhodnout, jestli změní směr pohybu hada, nebo jestli chce hru pozastavit. Had se pohne
posledním určeným směrem a v případě, že sebral potravu (pixel jeho hlavy překryje pixel
potravy) zvětší svoji délku o jedna.
Jak přesně probíhá přesun hada propustnými zdmi, je vidět z následujícího schématu:
[1,1]
[1,R]
[R,1]
px
…
x-ová souřadnice hada (svislá)
py
…
y-ová souřadnice hada (vodorovná)
sh
…
směr hada
[R,R]
sh = 1
…
konstantní souřadnice y, snižující se souřadnice x
↑
sh = 2
…
konstantní souřadnice y, zvyšující se souřadnice x
↓
sh = 3
…
konstantní souřadnice x, snižující se souřadnice y
←
sh = 4
…
konstantní souřadnice x, zvyšující se souřadnice y
→
1
Pátá zápočtová práce z předmětu Programování v Matlabu
Martin Dlask
{
}
sh = 1
nová pozice je [
]
{
}
sh = 2
nová pozice je [
]
{
}
sh = 3
nová pozice je [
]
{
}
sh = 4
nová pozice je [
]
Kudy se had pohybuje, shrnuje následující pravidlo. Směr každé části hada se pohybuje
v časovém okamžiku v takovém směru, jímž se pohybovala jeho hlava, když se nacházela
právě ve stejné pozici.
Hra skončí v okamžiku, kdy had narazí sám do sebe. To může nastat v případě, že uživatel
svou nepozorností dopustil, aby had sám do sebe narazil nebo v případě, že počet pixelů hada
již dosáhl délky R2.
1.3 Krátký historický exkurz
První verze této hry byla představena v roce 1972 pro tehdejší počítače a dále se objevovala
na mnoha platformách až do současné doby. Svojí největší popularity dosáhl Had v roce
1998, kdy byl představen jako mobilní telefonní hra na telefon Nokia 3310. Od roku 2011 je
tajně implementován jako tzv. „Easter Egg“ na serverech Youtube a službě Gmail.
1.4 Funkce a interface programu, možnosti pro uživatele
Na úrovni kódu se dá na začátku nastavit, jaký bude rozměr herního pole (a tím také velikost
jednoho barevného políčka), barva pozadí, barva hada a barva potravy. Po spuštění skriptu se
objeví okno, ve kterém je jak herní pole, ve které se nachází had ve své výchozí pozici, tak i
potrava. Na pravé straně se nachází ovládací panel se směrovými tlačítky pro pohyb doprava,
doleva, nahoru a dolů a také tlačítko pro nastartování nebo pozastavení hry. V horním menu je
možné hru restartovat (načíst novou hru) a případně zobrazit kredity pod položkou About.
Hra se spouští oranžovým tlačítkem Start. V okamžiku stisknutí má had délku 3 a je ve své
výchozí pozici a začne se pohybovat směrem doprava. Směr pohybu lze ještě před
nastartováním hry změnit pomocí jednoho ze čtyř směrových tlačítek. V případě, že had
sebere potravu, se zvětší o jedna a také se přičte bod v tabulce vpravo dole.
Oranžové tlačítko je univerzální – hra lze v jakémkoliv okamžiku přerušit tlačítkem Pauza,
které vzniklo z tlačítka Start. Po jeho stisknutí se přemění na tlačítko Pokračovat pro
pokračování hry z pozice, ve které byla přerušena.
2
Pátá zápočtová práce z předmětu Programování v Matlabu
Martin Dlask
Rychlost pohybu hada se zvyšuje se zvyšujícím se počtem bodů lineárně. Je tedy obtížnější
sebrat každou další potravu oproti předchozí.
Hra skončí v případě, že ji sám uživatel skončí buď zavřením celého okna například kliknutím
na ikonu křížku v pravém horním rohu, nebo restartováním hry kliknutím na Nova hra
v menu, případně tak, že had narazí sám do sebe.
Snímek herního okna při 15-tém levelu. Hra je v tento okamžik pozastavena a tudíž je místo
tlačítka Pauza tlačítko Pokracovat, kterým se dá do rozehrané hry opět vrátit.
1.5 Program
function varargout = had(varargin)
% Begin initialization code - DO NOT EDIT
gui_Singleton = 1;
gui_State = struct('gui_Name',
mfilename, ...
'gui_Singleton', gui_Singleton, ...
'gui_OpeningFcn', @had_OpeningFcn, ...
'gui_OutputFcn', @had_OutputFcn, ...
'gui_LayoutFcn', [] , ...
'gui_Callback',
[]);
if nargin && ischar(varargin{1})
gui_State.gui_Callback = str2func(varargin{1});
end
if nargout
[varargout{1:nargout}] = gui_mainfcn(gui_State, varargin{:});
3
Pátá zápočtová práce z předmětu Programování v Matlabu
Martin Dlask
else
gui_mainfcn(gui_State, varargin{:});
end
% End initialization code - DO NOT EDIT
% --- Executes just before had is made visible.
function had_OpeningFcn(hObject, eventdata, handles, varargin)
% This function has no output args, see OutputFcn.
% hObject
handle to figure
% eventdata reserved - to be defined in a future version of MATLAB
% handles
structure with handles and user data (see GUIDATA)
% varargin
command line arguments to had (see VARARGIN)
% Choose default command line output for had
handles.output = hObject;
% Update handles structure
guidata(hObject, handles);
% UIWAIT makes had wait for user response (see UIRESUME)
% uiwait(handles.figure1);
% --- Outputs from this function are returned to the command line.
function varargout = had_OutputFcn(hObject, eventdata, handles)
% varargout cell array for returning output args (see VARARGOUT);
% hObject
handle to figure
% eventdata reserved - to be defined in a future version of MATLAB
% handles
structure with handles and user data (see GUIDATA)
% Get default command line output from handles structure
varargout{1} = handles.output;
global
global
global
global
global
global
global
global
barvahada;
barvapozadi;
smerhada;
probihahra;
pauza;
rozmer;
delkahada;
potrava;
% globální proměnné potřebné v průběhu hry
rozmer = 50;
probihahra = 0;
pauza = 1;
smerhada = 6;
barvahada = 255;
barvapozadi = 99;
delkahada = 3;
potrava(1,1) = randi([1,rozmer]);
potrava(1,2) = randi([1,rozmer]);
SouradniceHada(1,1)
SouradniceHada(1,2)
SouradniceHada(2,1)
SouradniceHada(2,2)
SouradniceHada(3,1)
=
=
=
=
=
% generování pozice potravy
25;
25;
25;
24;
25;
% defaultní pozice hada
4
Pátá zápočtová práce z předmětu Programování v Matlabu
Martin Dlask
SouradniceHada(3,2) = 23;
CervenaT = zeros(rozmer,rozmer);
for i=1:delkahada
CervenaT(SouradniceHada(i,1),SouradniceHada(i,2)) = barvahada;
end
% barevné plochy pro vykreslení funkcí imshow()
ZelenaT = ones(rozmer,rozmer)*barvapozadi;
ModraT = zeros(rozmer,rozmer);
CervenaT(potrava(1,1),potrava(1,2)) = 255;
ZelenaT(potrava(1,1),potrava(1,2)) = 255;
ModraT(potrava(1,1),potrava(1,2)) = 0;
Obrazek=cat(3,CervenaT,ZelenaT,ModraT);
imshow(uint8(Obrazek));
set(handles.pushbutton5,'String','Start');
set(handles.text2,'String',num2str(delkahada-3));
while 1
if probihahra==1
% pokud probíhá hra, tj. není pozastavena
switch smerhada
case 2
% směr dolů
pomocna = zeros(delkahada,2);
pomocna(2:delkahada,:) = SouradniceHada(1:delkahada-1,:);
pomocna(1,2) = pomocna(2,2);
if pomocna(2,1)+1 > rozmer
pomocna(1,1) = 1;
else
pomocna(1,1) = pomocna(2,1)+1;
end
case 4
% směr doleva
pomocna = zeros(delkahada,2);
pomocna(2:delkahada,:) = SouradniceHada(1:delkahada-1,:);
pomocna(1,1) = pomocna(2,1);
if pomocna(2,2)-1<1
pomocna(1,2) = rozmer;
else
pomocna(1,2) = pomocna(2,2)-1;
end
case 6
% směr doprava
pomocna = zeros(delkahada,2);
pomocna(2:delkahada,:) = SouradniceHada(1:delkahada-1,:);
pomocna(1,1) = pomocna(2,1);
if pomocna(2,2)+1 > rozmer
pomocna(1,2) = 1;
else
pomocna(1,2) = pomocna(2,2)+1;
end
5
Pátá zápočtová práce z předmětu Programování v Matlabu
Martin Dlask
case 8
% směr nahoru
pomocna = zeros(delkahada,2);
pomocna(2:delkahada,:) = SouradniceHada(1:delkahada-1,:);
pomocna(1,2) = pomocna(2,2);
if pomocna(2,1)-1 < 1
pomocna(1,1) = rozmer;
else
pomocna(1,1) = pomocna(2,1)-1;
end
end
% v případě, že had narazil sám do sebe
if (CervenaT(pomocna(1,1),pomocna(1,2))== barvahada) &&
(ModraT(pomocna(1,1),pomocna(1,2))== 0) &&
(ZelenaT(pomocna(1,1),pomocna(1,2))== 0)
errordlg('Konec hry.');
probihahra = 0;
break;
end
SouradniceHada = pomocna;
CervenaT = zeros(rozmer,rozmer);
ZelenaT = ones(rozmer,rozmer)*barvapozadi;
ModraT = zeros(rozmer,rozmer);
CervenaT(potrava(1,1),potrava(1,2)) = 255;
ZelenaT(potrava(1,1),potrava(1,2)) = 255;
ModraT(potrava(1,1),potrava(1,2)) = 0;
for i=1:delkahada
CervenaT(SouradniceHada(i,1),SouradniceHada(i,2)) = barvahada;
ModraT(SouradniceHada(i,1),SouradniceHada(i,2)) = 0;
ZelenaT(SouradniceHada(i,1),SouradniceHada(i,2)) = 0;
end
Obrazek=cat(3,CervenaT,ZelenaT,ModraT);
imshow(uint8(Obrazek));
if (SouradniceHada(1,1)==potrava(1,1)) && % došlo k sežrání potravy
(SouradniceHada(1,2)==potrava(1,2))
delkahada = delkahada+1;
potrava(1,1) = randi([1,rozmer]);
potrava(1,2) = randi([1,rozmer]);
set(handles.text2,'String',num2str(delkahada-3));
end
end
pause(abs(delkahada-3-64)/64*0.1);
end
function pushbutton1_Callback(hObject, eventdata, handles)
global smerhada;
smerhada = 8;
6
Pátá zápočtová práce z předmětu Programování v Matlabu
function pushbutton2_Callback(hObject, eventdata, handles)
global smerhada;
smerhada = 4;
function pushbutton3_Callback(hObject, eventdata, handles)
global smerhada;
smerhada = 6;
function pushbutton4_Callback(hObject, eventdata, handles)
global smerhada;
smerhada = 2;
function pushbutton5_Callback(hObject, eventdata, handles)
global probihahra;
global pauza;
if probihahra == 1
pauza = 1;
probihahra = 0;
set(handles.pushbutton5,'String','Pokracovat');
else
pauza = 0;
probihahra = 1;
set(handles.pushbutton5,'String','Pauza');
end
function KeyPress(Source, EventData)
disp(EventData)
function konec_Callback(hObject, eventdata, handles)
close(had);
function About_Callback(hObject, eventdata, handles)
msgbox('Hra Had, Martin Dlask © 2012','About','help')
7
Martin Dlask
Pátá zápočtová práce z předmětu Programování v Matlabu
1.6 Editor GUI
Na tomto obrázku je vidět, jak vypadá návrh okna programu v módu GUIDE.
1.7 Výstupy na obrazovku
Na začátku (nebo v případě Nové hry) vypadá okno následujícím způsobem:
8
Martin Dlask
Pátá zápočtová práce z předmětu Programování v Matlabu
Po kliknutí na tlačítko Start vypadá následovně:
V případě, že je hra pozastavena, je místo tlačítka Pauza tlačítko Pokračovat:
9
Martin Dlask
Pátá zápočtová práce z předmětu Programování v Matlabu
Martin Dlask
Hra skončí například v případě zobrazeném na dalším obrázku. Potom je možné program
zavřít, nebo vyvolat Novou hru příkazem v menu. Dokud tlačítko uživatel nestiskne, nová hra
se nespustí a může si prohlédnout, proč mu hra skončila.
Možné je také si zobrazit údaje o autorovi  :
10
Pátá zápočtová práce z předmětu Programování v Matlabu
Martin Dlask
1.7 Závěr
Původní klasická hra Snake neměla tolik vylepšení, která skýtají její „novější“ verze. Přidány
byly postupně zejména možnost „průchozích zdí“ a také postupné zrychlování hry při vyšších
levelech a možnost pauzy. Matlab sice není úplně primárně program na vývoj herních
aplikací, nicméně jednodušší grafické výstupy se v něm dají zobrazit poměrně jednoduchým
způsobem a také vytvoření uživatelského prostředí spolu s nastavováním funkcí je docela
intuitivní.
11

Podobné dokumenty

Digitalizace

Digitalizace Co se stane v druhé oblasti, když v jedné oblasti doplním signál nulami na jinou délku? Doplnění nulami v jedné oblasti Ù „Hustší“ (Více hodnot) v druhé oblasti !! Nezvyšuje se však frekvenční rozl...

Více

Metoda Rayleighova podílu

Metoda Rayleighova podílu metoda Raleighova podílu bude rychlejší než mocninná metoda. Příklad: Metodou Raleighova podílu určete dominantní vlastní číslo matice A, kde

Více

Matlab05 (431kB

Matlab05 (431kB objekt, atd. Pokud pracujeme s proměnným počtem argumentů, lze využít funkcí pro práci s argumenty: nargin nargout varargin varargout

Více

návod na úpravu skriptů, naleznete zde

návod na úpravu skriptů, naleznete zde nainstalovaný freewarový SW WinMerge (http://winmerge.org/). Po spuštění DefsComp.exe se vyberou definiční soubory verzí, které se mají porovnávat a stiskem tlačítka Další se provede výpočet porovn...

Více

cvičení 01

cvičení 01 Pro vykreslení grafů lze použít modul matplotlib, což je modul podobný MATLAB funkcím pro vykreslování (intuitivní použití). 1 # Import modulu pro vykreslovani grafu . 2 from matplotlib import pypl...

Více

MATLAB ver. 5

MATLAB ver. 5 nebo y jsou nenulové (True). Vrací hodnotu False (0), kde jak x tak i y jsou nulové (False), nebo jsou oba nenulové (True). Vrací hodnotu True (1), jestliže alespoň jeden prvek vektoru x je nenulov...

Více