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
2 użytkownik(ów) aktywny(ch) przez ostatnie 15 minut:
gości: 1, userów: 1, ukrytych: 0
Uzjel
Użytkownicy na czacie discord
ANtY (11:09, 23.07.18):
grubo sie robi
I am Lord (9:53, 23.07.18):
Też nie znam jej, max chyba jesteś jedyny na tym forum który zna
Wojo (9:40, 23.07.18):
Albo to że na forum udzielam się tylko ja i jakiś debil. Mało mnie to pociesza
Wojo (9:37, 23.07.18):
To nie ja niepotrzebnie kręcę gownoburze a jak zwykle jestem temu winny. Wiesz co ? Wbite w to mam. Zaczynacie się zachowywać jak administracja elektrody. A później wielkie zdziwienie że nowi użytkownicy to dwóch małolatów...
Wojo (9:35, 23.07.18):
Co masz na myśli?
gnysek (9:25, 23.07.18):
@Wojo się prosisz o jakąś blokadę tak btw.
gnysek (9:25, 23.07.18):
weźcie se takie rzeczy załatwiajcie na messengerze czy gdzieś
Wojo (19:48, 21.07.18):
stolen from america, brought to africa...
Wojo (19:31, 21.07.18):
od teraz kto poruszy jej temat na gmclanie to ma małego
exp (19:11, 21.07.18):
no np. wy teraz robicie, bo ja nie wiedziałem, kto to jest, a teraz wiem
Wojo (19:06, 21.07.18):
to jest po prostu groupie jakich wiele, a ludzie robią niepotrzebny szum w okół niej
I am vader (18:02, 21.07.18):
Na ten planecie nie ma miejsca dla takich idiotów jak Ty.
I am vader (18:02, 21.07.18):
Zrób ludziom przysługę i won z tego forum bo tylko problemy innym robisz. Jesteś najgorszym typem ignoranta, na zasadzie "jeśli ja coś wiem każdy musi wiedzieć bo inaczej jest głupkiem. Jak mnie coś interesuje to musi obchodzić wszyskich a jak kogoś nie obchodzi to jest bucem".
I am vader (18:01, 21.07.18):
A za te życzenia śmierci to bym Ci prz......lił, bezmózgi, tryglodycki bucu śmieciowaty.
I am vader (18:00, 21.07.18):
MAx, może obudź mózg, bo to że na liście rzeczy które mam gdzieś napisałem "polska muzyka" nie znaczy że ona musi być muzykiem. Przeczytaj co napisałem jeszcze raz i nie pierdziel bo zatruwasz powietrze głupotą.
MaxGaming (16:47, 21.07.18):
Vader masz wszystko w dupie to idź sobie skocz z jakiegoś mostu
MaxGaming (16:46, 21.07.18):
Ale ona nie jest muzykiem XD właściwie jest nikim ale ma fejm ale nie chcę mi się tego tłumaczyć xd jesteś trochę bucowaty, bo wystarczyło wpisać w neta i byś po chwili zrozumiał xd tak btw drażnią mnie ludzie którzy mają wszystko w dupie. W sensie niech sobie robią co chcą ale jak w moim towarzystwie się tak zachowują to marzę żeby uznali żeby zniknęli i nie psuli atmosfery
Wojo (13:42, 21.07.18):
czyli potwierdzenie moich słów
I am vader (13:07, 21.07.18):
A to robi z tego sprawę Polskiego internetu, który, jakbyś nie zauważył, też mam w dupie.
I am vader (13:05, 21.07.18):
Bo ja wiem, Martyna Linkiewicz brzmi, ale tylko tak ciut ciut, ale może to tylko moje wrażenie, mimo to jednak to powiem: Martyna Linkiewicz brzmi jak POLSKIE IMIE.
Wojo (9:24, 21.07.18):
Mam w dupie polską scenę a warszawską na czele
MaxGaming (1:21, 21.07.18):
Tylko powiem że wgl tu nie chodziło o muzykę a tym bardziej o polską xd
MaxGaming (1:21, 21.07.18):
Hahaha po prostu nie ważne XD
I am vader (1:14, 21.07.18):
Mam w dupie polską scenę, polski internet i polską muzykę, nie wiem kim jest martyna Linkiewicz i nie chcę wiedziec i mi z tym dobrze.
MaxGaming (1:01, 21.07.18):
Poczytaj dlaczego zdobyła fejm. Niestety nie mogę tego napisać na portalu gdzie są dzieci...
MaxGaming (1:01, 21.07.18):
Że w 2018 roku trzeba jeszcze takie zaetty tłumaczyć xd
MaxGaming (1:00, 21.07.18):
Ale nie chodzi o hip hop tylko o Martynę Linkiewicz xd nie musisz słuchać rapu żeby znać tą historię xd
I am vader (0:43, 21.07.18):
Nie wiem co hip hop(??) ma do tego
MaxGaming (0:28, 21.07.18):
A dla niektórych od koncertu Rae Sremmurd
MaxGaming (0:26, 21.07.18):
Niestety ale bycie celebrytom zaczyna się od 5 lajków...
I am vader (23:44, 20.07.18):
4 lajki podglądu który wrzuciłem, czy to już sława?
Wojo (10:13, 20.07.18):
Prawda:p
MaxGaming (4:49, 20.07.18):
Bo te egzaminy są śmieszne jak to całe technikum XD
I am vader (1:08, 20.07.18):
Papierki są do rozpałki
Sutikku (0:07, 20.07.18):
głupie rozwiązanie, czemu nie pozwolić każdemu kto chce przystąpić? Strach przed tym, że egzamin wcale nie potwierdza kwalifikacji do zawodu? To może pora coś zmienić
Wojo (23:36, 19.07.18):
2 lata w zawodzie bądź w szkole poliecalnej z tego co mi wiadomo
Sutikku (23:34, 19.07.18):
trochę śmieszne gdybym miał zdane egzaminy zawodowe, a chodziłbym do szkoły na lekcje które mają mnie do nich przygotować
Sutikku (23:32, 19.07.18):
takie pytanie mam, czy hipotetycznie można podejść do egzaminów zawodowych nie kończąc szkoły? W sensie, jak jestem w 2 technikum czy mógłbym sam się przygotować i podejść do egzaminu w jakiejś instytucji w tracie kiedy ostatnie klasy technikum będą je pisać
Wojo (21:45, 19.07.18):
eigentlich, masz rację
I am vader (19:17, 19.07.18):
Jest różnica między podmienieniem całego zdania, a podmianą w trącenia jak "I mean" lub "Actually".
Wojo (16:45, 19.07.18):
Oh Wojo stop being so mean...
Wojo (16:44, 19.07.18):
Ja znaju kak pa polski gawarit, lecz podobają mi się takie wtrącenia z obcych języków
I am vader (12:48, 19.07.18):
I mean, wiedzialem ze ds_mapy tak robią, ale zapomniałem o tym gdy pisałem ten kawałek kodu.
gnysek (10:07, 19.07.18):
tak, ds_mapy od jsonów usuwają sie same. Można też zrobić tak z własnymi chyba, ze się dowiązane usuwają, za pomocą ds_list_mark_as_list / ds_list_mark_as_map
I am vader (22:31, 18.07.18):
Głupi, prostacki błąd, ale głęboko w kodzie, więc nie zwróciłem na to uwagi wcześniej
I am vader (22:23, 18.07.18):
Jakby kogos interesowalo skad moj problem z ds_listami, to dlatego ze uzywalem tych ds_list do robienia JSON, ale jak juz nie potrzebowalem tymczasowej ds_mapy(ktora byla tylko po to aby zbudowac JSON) to usuwalem te ds_mape a to usuwalo z kolei wszystkie powiazane ds_listy, a tych nie chcialem usuwac.
MaxGaming (20:39, 17.07.18):
Zamknięty system operacyjny...
Wojo (19:21, 17.07.18):
sklep play jest czynny tylko do godziny 17 i w niedziele handlowe...
MaxGaming (17:48, 17.07.18):
Sklep play mógłby też istnieć na darmowym/płatnym androidzie który byłby zamknięty
MaxGaming (17:48, 17.07.18):
Nie mogą pobierać opłat od producentów w obecnej formie licencyjnej.
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.
[ Polityka prywatności ]
Copyright © 2002-2018. GMCLAN.ORG
Wszelkie prawa zastrzeżone. Kopiowanie materiałów bez zgody redakcji zabronione!
© 2002-2017 Ranmus (ranmus.pl), © 2017-2018 {=|=} fable_inside();

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