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
Akademia GMCLANu
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
1 użytkownik(ów) aktywny(ch) przez ostatnie 15 minut:
gości: 1, userów: 0, ukrytych: 0
Użytkownicy na czacie discord
gnysek (18:29, 19.02.18):
W WPF można robić design apek w XAMLu ? włącznie z animacjami
ANtY (15:51, 19.02.18):
co to za stanowisko C# Designer?
Wojo (12:57, 16.02.18):
Nie
gnysek (9:11, 16.02.18):
Widziałeś kiedyś stackoverflow ?
Wojo (19:36, 15.02.18):
Fajnie jakby się zarabialo a problemy się opisywalo na gmclanie, chociaż ktoś już tak próbował robić.
MaxGaming (18:10, 15.02.18):
oj gnysek, szukasz dziury w cały. Po pierwsze nie wiedziałem właśnie co psuje stronę zupełnie, po drugie nie chiało mi się bawić w takie rzeczy bo dłużej by to zajęło niż potem komuś znaleźć błędy. No a cóż, to każdy mówi jeżeli robisz komercyjnie to i to to musisz wiedzieć to i to. Skoro robię coś komercyjnie i zarabiam to znaczy że umiem wystarczająco dużo żeby to robić i zarabiać
gnysek (16:32, 15.02.18):
Taki hint: w serwisach typu twitter/facebook/discord można wkleić printscreena ze schowka
Wojo (16:23, 15.02.18):
Ja kiedyś dawalem screeny na imageshack to byly czasy...
I am vader (12:10, 15.02.18):
Najlepsze są serwisy do dzielenia się screenami jak puush czy gyazoo, chociaz sam korzystam z feenus ktore jest prywatne niestety wiec tylko ja i pare innych osob ma tam wstep.
Wojo (10:59, 15.02.18):
Służę pomocą tym co nie umieją robić screenów
Wojo (10:58, 15.02.18):
Nawet ja wiem jak to zrobic naciskasz klawisz z napisem prt scr
gnysek (10:53, 15.02.18):
jak robisz komercyjne strony to powinieneś takie rzeczy umieć
gnysek (10:53, 15.02.18):
no ale to całej strony nie trzeba pokazać, żeby naprawić błąd, można zrobić screena i obciąć i pokazać tylko parę bloków albo na jsfiddle.com wrzucić fragmetn co się psuje
MaxGaming (1:15, 15.02.18):
Już mam w sensie że doszedłem sam gdzie jest błąd
MaxGaming (1:14, 15.02.18):
Już mam. Nie chodzi o kradzeż, po prostu robię portal do celów komercyjnych i zależy mi by nikt nie wedział zanim nie skończe co to za portal. Sam html i css jest bez wartości akurat
I am vader (0:14, 15.02.18):
Chwuila zaraz to naprawie.
gnysek (19:10, 14.02.18):
w wersji na androida chyba nikt nie wydał ?
PsichiX (16:14, 14.02.18):
smiejecie sie, ale to bylby achievement, zrobic najlepszego catch the clauna na swiecie
Ignatus (16:01, 14.02.18):
A co jeżeli to najlepszy kacz de klown w historii i zarobi wiecej niz hotline miami?
I am Lord (11:25, 14.02.18):
Ktoś robi kacz de klawna i wysyła na PW bo na pewno ukradnie
I am Lord (11:25, 14.02.18):
uwielbiam to na gmclanie xD
PsichiX (1:50, 14.02.18):
na forum temat zaloz, nie mysl nawet ze ktos by mial krasc cssa, skoro nie dziala a i css to opis materialu, a nie algorytm
MaxGaming (1:36, 14.02.18):
Mógłby mi ktoś pomóc znaleźć błąd w prostym CSSie? Wyślę na PW kod
Wojo (15:36, 13.02.18):
Gierka uspokok się
ANtY (12:19, 13.02.18):
nie mow o mnie za plecami, ok?
Wojo (12:02, 13.02.18):
I się rozwinęły gierki nie można się kłócić...
Wojo (12:02, 13.02.18):
Wiesz o kim mówię
Ignatus (11:20, 13.02.18):
Jak to nie.Zaczynalem od skool daze na c64, przez UFO na amidze 500 az po Fallouta 2 na PC ,zadne pozniejsze gry wiekszego wrazenia juz nie robio
Wojo (10:22, 13.02.18):
Co za babole ludzie wy nie zyliscie w czasach rozwoju gier a pierdzielicie bez sensu. Ja mam dopiero 9 lat i takich głupot nie pierdziele
gnysek (10:14, 13.02.18):
nie nie, babuleńki mówią "za Gierka to było lepiej"
PsichiX (23:03, 12.02.18):
no wlasnie wszyscy mowio na odwrot
Ignatus (22:04, 12.02.18):
A wszyscy mówio że ten Gierek to taki super był
Wojo (8:26, 12.02.18):
Gierka, przecież napisoł
I am Lord (7:24, 12.02.18):
co robisz?
exp (21:17, 11.02.18):
tak dzisiaj stwierdziłem, że gierka, którą robie od jakiegoś czasu to jednak do dupy jest
Chell (20:48, 11.02.18):
musicie mi uwierzyc
Chell (20:47, 11.02.18):
kumpel przedwczoraj puscil i teraz mi podpowiada
Chell (20:47, 11.02.18):
z rok nie slyszalem tenacious d, w podpowiedziach tez nie mialem bo bym se puscil
Chell (20:46, 11.02.18):
tej bez kitu, uwierzylem w to co pisal Vader
Wojo (19:02, 10.02.18):
Bo to nie jest zależne od gmclanu
Gibki Kaktus (0:44, 10.02.18):
Czemu? XD
ANtY (23:57, 9.02.18):
OBY NIGDY
Gibki Kaktus (22:38, 9.02.18):
Ciekawe kiedy jakieś info o wystawie na Pyrkonie dadzą
Nikas (19:32, 7.02.18):
Odbierałem to inaczej. Nieważne. TopHat też po prostu zmarł już dawno i nic z nim nie robiłem.
I am vader (16:38, 7.02.18):
No i elegancko
Wojo (9:57, 7.02.18):
Ja bym dal znizke dla vadera za konstrukcje z krytyki
I am vader (20:58, 6.02.18):
Przepraszam ze konstruktywną krytykę tak źle odbierasz
Nikas (18:20, 6.02.18):
No oczywiście, że nic lepiej się nie dało. Bo jak by się dało, to by się zrobiło.
gnysek (16:32, 6.02.18):
może jeszcze zniżki dla stałych klientów
gnysek (16:32, 6.02.18):
kupony rabatowe
Ankieta
» Jakie kursy najchętniej widziałbyś na stronie ?
GM Studio
GM Studio 2
Godot
Construct

GMCLAN to serwis o programie Game Maker i nie tylko.
Copyright © 2002-2018. GMCLAN.ORG
Wszelkie prawa zastrzeżone. Kopiowanie materiałów bez zgody redakcji zabronione!
© 2002-2017 Ranmus (ranmus.pl), © 2017 {=|=} fable_inside();

[ Czas generowania strony: 0.0505 sekund ] [ Liczba zapytań MySQL: 13 ]