Fastbar
Powrót do strony głównej
Trzymaj pliki na gmclan.org!
Game Maker w pytaniach i odpowiedziach!
Polska dokumentacja
Tabela wyników ligi 24
Pobierz GM
Kategorie bazy artykułów
Artykuły -> Game Maker -> Kursy dla początkujących
Treść artykułu
If, then, else, switch zamiast else - jak traktuje je GM
autor: gnysek (22.11.07)
Często na GMC poruszane są problemy dotyczące złego napisania jakiegoś skryptu, ze względu na nieprawidłowe umieszczenie if i else w całym skrypcie. Dzisiaj chciałbym zwrócić uwagę na to, jak można zapisywać i czym skutkuje zapisywanie warunków w Game Makerze. Będzie mowa o tym jak gdzie i kiedy używać if, then i else, oraz kiedy warto konstrukcję if ... else if ... else zastąpić konstrukcją switch.

Załóżmy, że dla wszystkich przykładów w create definiujemy zmienne:

gml:
test=true;
test2=false;
predkosc=5;


1. if <cośtam>

Sprawdzanie cy jakaś wartość jest większa czy mniejsza, dokonujemy poprzez używanie znaków >, >=, =, <, <=, <>

Na przykład:

gml:
if predkosc>5
if predkosc>=5
if predkosc<5
if predkosc<=5
if predkosc<>5
if predkosc=5
if predkosc==5 //oznacza to samo co wyżej


Jest to dość oczywiste. Skupmy się jednak na ostatnich dwóch przykładach. Pomijam już to, że dla GM oba zapisy są prawidłowe, pomimo, że znakiem = nadajemy również wartość, a powinno być to jakoś rozróżniane. Ale dla wygody jest tak. O ile porównujemy liczby, to jeszcze wszystko jest jasne, ale jak się okazuje, porównując wartości boolean, czyli true i false, można zastosować jeszcze kilka innych sztuczek. Warto zwrócić uwagę, że każdy warunek jaki postawimy po if, tak na prawdę zwraca właśnie true, lub false i wykonuje się, gdy zwrócona wartość będzie równa true. Zatem poniższe warunki tak naprawdę oznaczają to samo

gml:
if test=true //zwracana jest wartosc true, bo skoro zdefiniowaliśmy, że test=true, to nasz warunek tak naprawdę to if true=true...
if test //też zwracana jest wartość true, bo test=true, co zostało zdefiniowane wcześniej


Jak widać, jeżeli coś przybiera wartość true, nie trzeba pisać znaku równości co natomiast, gdybym napisał if test2 ?? Warunek oczywiście nie będzie prawdziwy, a co za tym idzie dalszy kod nie wykona się, ponieważ zdefiniowana przez nas zmienna test2=false, a warunek if test2 to inaczej if test2=true. W takim razie czy da się jakoś skrócić też warunkiem dla zmiennych równych false? Oczywiście. Wystarczy użyć znaku ! który w programowaniu oznacza negację. Neguje zatem następujące po nim wyrażenie, np.:

gml:
if predkosc!=5 //to taki sam zapis jak if predkosc<>5


No tak, a jak ma się to do wartości false? A tak:

gml:
if test2=false
if test2 //test 2 false, zatem otrzymujemy funkcję if false=true - nie jest ona prawdziwa
if !test2 //test 2 jest negowany, zatem z false zrobi się true i wyjdzie nam funkcja if true=true, lub jak kto woli if false=false, w każdym bądź razie sama prawda


Skoro wiemy już jak to działa, to można pobawić się dalej:

gml:
if !test!=true //if false<>true
if !test!=!true //if false<>false


Warto też wiedzieć, że w podobny sposób można zmieniać wartość z true na false, na przykład gdy na zmianę po naciśnięciu spacji obiekt znika i pojawia się.:

gml:
if keyboard_check(vk_space) visible=!visible;


Dzięki temu, gdy visible było true, zmieni się na false (bo ! neguje czyli zamienia na przeciwne true i false), a jak visible=false to zmienia się na true. Ot, taka ciekawostka. Kolejna ciekawostka to taka, ze true to inaczej 1, a false to inaczej 0 (czyli bity jak ktoś nie wie). Zatem zamiast if test=true można napisać też:

gml:
if test=1


I to też prawda. Warto jeszcze zaznaczyć, że postawienie; oznacza zakończenie danej linijki kodu, zatem napiasnie if test=true; to tak naprawdę nie napisanie niczego,bo wszystko co napiszemy za znakiem ; traktowane jest, jak coś nowego.

2. if <cośtam> then

Dobra, skoro mamy warunek, trzeba by coś wykonać. Konstrukcja if <cośtam> then po naszemu znaczy po prostu Jeżeli coś tam to wtedy. Ale czy tak naprawdę potrzeba pisać zawsze then ? Okazuje się, że i tutaj GM okazuje się dość tolerancyjny i można sobie odpuścić then. Zatem kod można zapisać np.:

gml:
if predkosc>5 then predkosc=5;
if predkosc>5 predkosc=5; //j.w.


No dobra, zapis nie wygląda pięknie, bo brak słowa then zanieczyszcza lekko kod. Ale gdy potrzebujemy zapisać trochę więcej kodu, wygląda to już inaczej:

gml:
if predkosc>5 then
{
predkosc=5;
test=false;
}

//i to samo, ale bez then

if predkosc>5
{
predkosc=5;
test=false;
}


No i tym razem brak then tylko upiększa kod. Warto więc czasem zastanowić sie, czy warto użyć then.

3. if <cośtam> then <cośtam> else <cośtam>

Kontrukcja else dość często sprawia początkującym programistom problem. Po prostu zapominają jej użyć, co prowadzi często do błędów. Ale jak jej w ogóle używać? Instrukcja else wykonywana jest, gdy to co wpisaliśmy w if nie jest prawdą, np.:

gml:
if predkosc>5 then predkosc=5 else predkosc+=1;


albo bardziej rozbudowanie:

gml:
if predkosc>5 then
{
predkosc=5;
test=true;
}
else predkosc+=1;


Jak widać, gdy zmienna prędkość jest większa niż 5, ustawiana jest na 5, w przeciwnym wypadku dodajemy do niej 1 (tak na marginesie, powyższy kod ogranicza narastanie zmiennej predkość do 5, i tak na prawdę to lepiej zapisać go jako if predkosc<5 then predkosc+=1 else predkosc=5; a skoro już podaję przykłady pisania warunków, to również predkosc<=4 then predkosc+=1 else predkosc=5; jest prawidłowym skryptem, ale nieco mniej czytelnym na pierwszy rzut oka.). Dobra, ale przejdźmy to tego najdzczęściej popełnianego błędu - w tym celu posłużę się przykładem. Załóżmy, że dwukrotne wciśnięcie spacji powoduje, że nasz obiekt niszczy się, a po pierwszym wciśnięciu jego prędkość spada o połowę. Wniosek prosty, trzeba zrobić coś, aby za pierwszym razem nie zginął. Ustalamy zatem, że na początku zmienna test2=false;. Gdy wciskamy spację, a test2=false, to test2 ustawiamy na true, a speed=speed/2; gdy natomiast naciskamy spację i test2=true, obiekt zostaje zniszczony. Tylko jak to zapisać? No cóż, większość początkujących w zdarzeniu Keyboard Press <space> wpisze taki kod (pomijam tutaj uproszczenia o których mowa była wcześniej, dla lepszego zobrazowania):

gml:
if test2=false
{
test2=true;
speed=speed/2;
}
if test2=true
{
instance_destroy();
}


Na pierwszy rzut oka, kod jest dobry, bo oba warunki zostały wpisane jako osobne warianty. Ale po mimo to, obiekt znika za pierwszym wciśnięciem. Dlaczego? A bo w 3 linijce tego kodu, zmieniamy test2 na true, kod analizuje się dalej, zmienia prędkośc, wpada na klamerkę kończoncą ten blok kodu i co ? Wpada na warunek if test2=true - który zgodnie z tym co chwilę temu ustawiliśmy jest prawdziwy i też się wykonuje. Każde nowe if - o ile nie zostało poprzedzone słowem else i innym if, traktowane jest jako osobny, nowy kod. Wystarczy dodać else i pozbędziemy się tego błędu:

gml:
if test2=false
{
test2=true;
speed=speed/2;
}
else if test2=true
{
instance_destroy();
}


Teraz drugi kod nie wykona się bo po pierwszym if pomija wszystkie else w tym bloku, aż napotka kolejne słowo if nie poprzedzone else - czyli nowy kod bloku. Dobra, ale czy musieliśmy pisać drugie else? Nie. Skoro w przypadku, gdy test2=false, pierwsze if jest pomijane, wystarczy samo else, aby wykonać kod - tak naprawdę nie interesuje nas ile teraz wynosi test2, czy true, czy 5 czy może 'tekst' - ważne, ze nie false, bo właśnie tak stanowi pierwszy warunek. Zatem prawidłowy zapis to także:

gml:
if test2=false
{
test2=true;
speed=speed/2;
}
else
{
instance_destroy();
}


Dlaczego zatem poprzednio napisałem po else if ? Teraz zakładamy, że na początku zmienna predkosc=1, a za każdym razem, gdy naciskamy spację, zwiększa się o 1. Gdy wyniesie 2, speed zwiększymy razy 2, a gdy wyniesie 3, zniszczymy obiekt. Ten kod zapiszemy tak:

gml:
if predkosc=1
{
predkosc=2; //mozna tez predkosc+=1;
}
else if predkosc=2
{
predkosc=3;
speed=speed*2;
}
else
{
instance_destroy();
}


No i wszystko jasne. Jeżeli predkosc nie równa się 1, to sprawdzamy drugi warunek, ale skoro nie równa się 2, to wykonany zostanie następny, a jako że nie ma tam już żadnego innego warunku, tylko samo else, no to dla każdej innej wartości zostanie wykonany ten właśnie kod. No właśnie - to należy podkreślić - dla każdej innej, nie spełniającej dwóch pierwszych warunków. Zatem nie tylko dla predkosc=3, ale też predkosc=-1, predkosc=10, predkosc='test'; (chociaż doszukiwanie się w zmiennej tekstowej zmiennej liczbowej, może wywalić nam errora, ale to inna bajka :P), zatem aby ominąć ten błąd poprawiamy kolejny raz nasz kod:

gml:
if predkosc=1
{
predkosc=2; //mozna tez predkosc+=1;
}
else if predkosc=2
{
predkosc=3;
speed=speed*2;
}
else if predkosc=3
{
instance_destroy();
}


No. To mamy za sobą kawał dłuugiej lekcji, z której na pewno dało się sporo wynieść. Nie rozpisuje się już na temat and or i łączenia warunków, czy zagnieżdzania w jedym warunku kolejnych. Zwrócę jednak uwagę na jeszcze jeden zapis - a mianowocie, kiedy if i else warto zastąpić switchem.

4. Switch zamiast if .. else if .. else if .. else

Bierzemy znany nam już kod, który niszczy obiekt, zawsze poza przypadkiem gdy predkosc=1 lub =2.

gml:
if predkosc=1
{
predkosc=2; //mozna tez predkosc+=1;
}
else if predkosc=2
{
predkosc=3;
speed=speed*2;
}
else instance_destroy();


switch to taka jakby szafa z szufladami, które otwieramy w określonych przypadkach i jedną szufladą, otwieraną, dla pozostałych przypadków, na które nie było już w tej szafie miejsca. Powyższa konstrukcja wygląda jako switch tak:

gml:
switch predkosc
{
case 2: predkosc=3; speed=speed*2; break;
case 1: predkosc=2; break;
default: instance_destroy(); break;
}


Trochę mniej miejsca, nie? Od razu mówię, po co tam funkcja break. Otóż break powoduje, przerwanie przetwarzania dalej danego bloku, zatem jeżeli prędkość=2 i wykonany zostaje case 2, to reszta kodu będzie pominięta - czyli inaczej zrobi się else if. Z kolei default to czyste else. Fakt braku break i wykonania nastepnych linijek kodu można wykorzystać - skoro zawsze dodajemy do prędkości 1:

gml:
switch predkosc
{
case 2: speed=speed*2;
case 1: predkosc+=1; break;
default: instance_destroy(); break;
}


i teraz dla case 2 zostaną wykonane również instrukcje poniżej - pomimo, że to case 1. Po prostu, gdy otworzymy daną szufladę, automatycznie dostajemy dostęp do wszystkich następnych na tak długo, aż napotkamy break.

Warto zapamiętać to o czym była dzisiaj mowa, warto eksperymentować i mieszać ze sobą poznane techniki - naprawdę można w ten sposób zdziałać wiele, bo ja nie wyczerpałem jeszcze tematu.

Miłej zabawy!
głosów: 13 | ocena: 7.69 oceń zasób | dodał: gnysek
Komentarze
stron: 21

2


av

gnysek (11:12, 24.11.2007)

ale inni nie wiedzą :/

av

Matthew (11:14, 24.11.2007)

Pisząc "switch zamiast else" Gnyskowi chodziło o "switch zamiast if... else if"

av

gnysek (11:18, 24.11.2007)

ja nie wiem, zrobić coś, to jeszcze skrytykują, może lepiej nie dodawać nic ?

av

I am Lord (11:32, 24.11.2007)

@Matthew wyżej napisałem to samo. A sam artykuł wydaje się nieco nie potrzebny.

av

Tymon (12:47, 24.11.2007)

Wszystko co dodajesz wiąże się z krytyką.

No i napisanie "switch zamiast else" jest usprawiedliwione i poprawne jak mniemam.

Spoczko gnysek! Ten kto się nie zna powie, że jest dobrze, a ten co się zna, że tak ma być.
Jest cool!

av

Woock (14:05, 25.11.2007)

Gnysek, źle do tego podchodzisz. Krytyka też jest formą zainteresowania, a podobno nie istnieje takie coś, jak zła sława...

av

Będe brał Cie (17:28, 3.07.2009)

Mi sie zajebiś... Podoba a moderatorzy są do du..

av

Będe brał Cie (17:29, 3.07.2009)

Oprucz gnyśka

stron: 21

2



Dodaj komentarz:
Treść:
Menu
Panel użytkownika
Jesteś niezalogowany!

Nie masz konta? Zarejestruj się
Użytkownicy on-line
99 użytkownik(ów) aktywny(ch) przez ostatnie 15 minut:
gości: 94, userów: 5, ukrytych: 0
exp, I am vader, Danielus, monikowa26, Uzjel

0 użytkownik(ów) na gmczacie i 0 bot(ów)
Shoutbox
Nikas (15:16, 21.01.17):
ayyy ;///
exp (13:54, 21.01.17):
to nie byłem ja
Wojo (13:23, 21.01.17):
tylko przy referenie
Wojo (13:22, 21.01.17):
tatu - robot
Nikas (13:01, 21.01.17):
A ja nie wiem już, pamiętam tylko, że pytałeś się przy jakim traczku ją przelecieć. xDDD
exp (11:37, 21.01.17):
o jakiej lasce ja ci pisałem kiedyś?
Nikas (0:15, 21.01.17):
spk a u ciebie exp? stuknąłeś w końcu tą laskę co mi o niej pisałeś kiedyś? xD
Chell (0:02, 21.01.17):
przywolalem po nieobecnosci od wrzesnia, nie ma za co
exp (23:47, 20.01.17):
jak tam żyjecie
Nikas (23:39, 20.01.17):
XDDDD
MaxGaming (22:52, 20.01.17):
YXE bo jak mówiłeś trzeba być miłym dla niepełnosprawnych
Nikas (22:41, 20.01.17):
Jezu w ogóle olać kwestię bana czy ostrzeżenia. xD Przeciez jak ja teraz dostaję warna to nie wiem co o tym mysleć. xD
ΨΧΞ (22:34, 20.01.17):
to dlaczego nie mam?
MaxGaming (22:15, 20.01.17):
No ale jak już YXE sam wszedł w ten temat to gdyby Nikas obraził jego matkę(w dodatku sugerując że jest lekkich obyczajów) miałby bana na pewno...
Wojo (22:13, 20.01.17):
powinieneś dostać na odmułę ale układy, układziki
MaxGaming (22:11, 20.01.17):
Masz na myśli że ja teraz zasugerowałem że złamałeś regulamin? Nie, nie zasugerowałem
ΨΧΞ (22:09, 20.01.17):
iksde xD zastanawiam sie, skoro rzekomo złamałem regulamin, dlaczego nie mam jeszcze bana?
MaxGaming (21:08, 20.01.17):
Pod tytułem "Czy jeżeli 27 latek obraża matki innych userów ci zareagują inaczej niż na gimba?" XDD
ΨΧΞ (17:50, 20.01.17):
durnyś xD
Ranmus (17:43, 20.01.17):
O wy durni, ale się daliście wciągnąć. Przecież to kolejny test socjologiczny. Nie widzicie tego?
ANtY (7:27, 20.01.17):
>długa dyskusja przed snem, że po prześwietleniu historii postów patryka jego DZIEWCZYNA (ONA MA DZIEWCZYNE, NIE ZAPOMNIJCIE!!! była zawiedziona poziomem jego wypowiedzi, po czym nastąpiły długie przeprosiny i obietnica poprawy hmm
Wojzax (2:47, 20.01.17):
YXE co to za pedalski slang i gdzie jest obiecana gra w niszczenie wieżowców?
ΨΧΞ (22:48, 19.01.17):
nudzi mi się, odpisz coś
ΨΧΞ (22:25, 19.01.17):
pamiętasz, co pisałem o mojej obietnicy grzecznego i miłego odzywania się do niepełnosprawnych? nom, to pardon, ale albo załapiesz, albo ta dyskusja nie ma sensu :*
MaxGaming (21:41, 19.01.17):
Patrząc na ilość buziaczków i czułych zwrotów to chyba Twoja dziewczyna jest bardziej męska od Ciebie?
Adriann (20:28, 19.01.17):
Nie mit, nie chodzi tam o samą ilość a nie radzenie sobie organizmu z czymśtam..;d
Ignatus (20:11, 19.01.17):
Nie wiem czy z tym testosteronem i łysieniem to nie jakiś mit.W końcu najwyższy poziom testy jest w okresie dojrzewania-kiedy każdy ma burze loków, a po 30 zaczyna gwałtownie spadać,kiedy właśnie u większości zaczyna się łysienie...
ΨΧΞ (19:56, 19.01.17):
xD oj pysiu głuptaśny, a w mikołaja też wierzysz? nie przejmuj się, każdy ma prawo nie wiedzieć - pozwól, iż przedstawię Cię łysinie androgenowej. dokształcon? nie dziękuj :*
MaxGaming (19:00, 19.01.17):
No zazwyczaj stres o tym mówię, tylko że YXE twierdzi że nie ma uczuć i się niczym nie przejmuje absolutnie xd
Adriann (18:55, 19.01.17):
Eee nie ma co się przejmować, sam mam bardzo mało włosów i wiem że niebawem będę miał kolano na głowie ale to nie oznaka stresu a zbyt dużej ilości testosteronu, możesz nie mieć włosów a dalej być takim seksualnym tyranozaurem jak ja
MaxGaming (18:48, 19.01.17):
A czy łysienie w tym wieku to nie jest głównie oznaka stresu? Czy stres nie oznacza że jednak masz emocję i dosyć bardzo się przejmujesz? xd Zrozum że udając kogoś kim nie jesteś zawsze wcześniej czy później narazisz się na śmieszność. Masz ogromną wiedzę i ogółem swoimi dobrymi stronami powinieneś się legitymować a nie udawać coś w wieku 27 lat...
Wojo (17:10, 19.01.17):
nawet moja składnia
Wojo (17:10, 19.01.17):
nie wiesz wcale, że jego nic nie rusza ?
Wojo (17:10, 19.01.17):
ah ty pysiaczku głupaśny
ΨΧΞ (16:59, 19.01.17):
nie, no jasne iż nie mam. to mój najczulszy punkt, przezeń płaczę po nocach
Ranmus (16:41, 19.01.17):
Patryk spokojnie. Nie musisz tak szczegóło tłumaczyć, że masz dystans do siebie w kwestii łysienia... masz?
ANtY (16:09, 19.01.17):
zawsze kisne xD
ANtY (16:08, 19.01.17):
>ludzie często pytają mnie [..]
ΨΧΞ (15:29, 19.01.17):
przeto to logiczne: chociażby dlatego, że noszę kapelusz i mówię dlaczego, gdy ktoś mnie pyta, nawet tu się to przewijało myślałeś, że noszę go bo chcę być fajny i mędrkuję? xD kaman, łysina jest nieestetyczna D: musiałbym się ogolić cały, a do 30-stki nie zrobie tego.
Ranmus (14:39, 19.01.17):
Patryk, przecież o tym wiem i nie neguję. Zresztą skąd miałbym wiedzieć, że łysiejesz skoro cały czas nosisz czapkę?
Wojo (14:20, 19.01.17):
brrr xD
ΨΧΞ (13:40, 19.01.17):
znikas, dzięki - ląduje w kolekcji memów :*
ΨΧΞ (13:39, 19.01.17):
Pysiaczku głuptaśny, przeto ja mówiłem, "[...] bo łysieję" - nie było tam nigdzie "nie". ale to cudowne, że się starasz pamiętać :*
Ranmus (13:31, 19.01.17):
Zmień "bo mam klasę i chłód" na "bo mam klasę i wcalę nie łysieję Xd". Będzie legitniej.
Nikas (13:23, 19.01.17):
also psichix fajne meme znalazłem podobne tylko z innym kolesiem hehe gmclan.org/uplo...wiek_top_bk.png
Nikas (13:18, 19.01.17):
>mów komuś o tym, żeby nauczył się dobrych pocisków >sam dowal jakiś gimbopocisk po matce xDDDD boże jak to możliwe mając tyle lat
Ignatus (11:11, 19.01.17):
Dzieki
Ranmus (11:10, 19.01.17):
Korodzik, co tam u rodzinki słychać?
Korodzik (10:55, 19.01.17):
Ignatus, kliknij "Opcje" i wybierz widok standardowy
Ankieta
» Czy jesteś szczery odpowiadając w ankietach w Internecie?
Tak
Nie

GMCLAN to serwis o programie Game Maker i nie tylko.
Copyright © 2002-2017. GMCLAN.ORG
Wszelkie prawa zastrzeżone. Kopiowanie materiałów bez zgody redakcji zabronione!

[ Czas generowania strony: 0.08433 sekund ] [ Liczba zapytań MySQL: 16 ]

thecrims Otserv List Otserv LyricsTown Harry Potter Serwery Gier
dev nodev