Implementace hry „Had“ (angl. Snake) pomocí GUI
Transkript
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
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...
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
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
11:40, B880 Hydraulika HYA - kruh 53 (K = 53), ZS 2014/2015
poslední aktualizace: 11.12.2014
A
N
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...
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...
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...