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: 2, userów: 0, ukrytych: 0
Użytkownicy na czacie discord
MaxGaming (3:18, 23.04.18):
Niekoniecznie dla reklamodawcy, ale w dużym uproszczeniu średnia wyjdzie taka sama(nie biorąc pod uwagę targetu właściciela serwisu/aplikacji, ale to już problem reklamodawcy i właściciela nośnika tych reklam).
MaxGaming (3:16, 23.04.18):
Ale dlaczego miałoby się równać? Myślę że to lepsze rozwiązanie niż stałe zużycie niezależnie od tego jaki ktoś ma komputer. Procentowe zużycie wydaje mi się dużo bardziej sprawiedliwe niż stałe dla każdego urządzenia
Wojo (10:29, 20.04.18):
Jeśli chodzi o reklamy to odpowiadają mi takie co są na gmclanie teraz niż zamienianie połowy gmclanu na reklamę podpasek czy czegoś podobnego
Wojo (10:27, 20.04.18):
Tylko, że 10% zużycia słabego komputera nie równa się 10% zużyciu dobrego komputera
Wojo (10:27, 20.04.18):
Tylko, że 10% zużycia kom
MaxGaming (1:00, 20.04.18):
Wiesz wirusy też są mimo tego że nie powinny, ale jakoś radzimy sobie z tym
MaxGaming (1:00, 20.04.18):
Mi mniej przeszkadza kopanie bitcoinów w tle niż npnatarczywe reklamy. Wolałbym natomiast aby takie strony mogły się do tego przyznać i nie były linczowane
MaxGaming (0:59, 20.04.18):
przeciwko oszustą byłby fakt braku ograniczeń. Strona musiałaby tylko informować, a czy wkorzysta 90% to jej sprawa. BYleby użytkownik wiedział sam na co się pisze
MaxGaming (0:58, 20.04.18):
Ale o to chodzi z procentami. Dzięki temu nawet jak mamy wolny komputer odczujemy tak samo. Co do innego prawa. Na każdej stronie jakoś jest informacja np. o plikach cookies. Dałoby to sięogarnąć, tym bardziej gdyby powstałą organizacja sprawdzająca takie informacje i byłaby np na jej stronie lista nieuczuciwych stron które należy unikać. Możnaby wprowadzić także w przeglądarkach żeby takie strony nie otwierały się, albo wymagały wyraźnego potwierdzenia użytkownika. Myślę że głównym argumentem
Wojo (23:08, 19.04.18):
tak samo bodajże w szwecji partia piratów chciała założyć własne małe państwo gdzie piractwo byłoby legalne dzięki czemu niektóre strony mogłyby obejść prawo w taki lub inny sposób
Wojo (23:06, 19.04.18):
a żeby mieć jakiś faktyczny zysk z takich koparek bitcoinów to musiałbyś je ustawić na jakiejś popularnej stronie bo np na takim gmclanie zbyt wiele nie wydobędziesz
Wojo (23:05, 19.04.18):
Ale to brzmi abstrakcyjnie Stronę zawsze można założyć w innym państwie gdzie takie prawo nie obowiązuje, 10% mocy obliczeniowej komputera przecież się różni w zależności od tego jak mocny mamy komputer
MaxGaming (21:08, 19.04.18):
Według mnie jeśliby ustanowić prawnie że strona która twierdzi że pobierze np. 10% mocy obliczeniowej naszego komputera na prawdę musi tyle pobierać pod groźbą kary to np kopanie bitcoin w tle jest fajną alternatywą dla reklam
Wojo (10:33, 19.04.18):
Jak dla mnie to sprytne rozwiązanie ktoś wymyślił
I am vader (0:53, 19.04.18):
Nie pamietam jak ten program sie nazywal ale za jaja bym powiesil skurczybyka ktory to zrobil.
I am vader (0:52, 19.04.18):
Odmowilem, nic wielkiego, ale potem przed pobraniem programu kazano mi kopac conajmniej jakastam chwile, tu juz sie podniosly czerwone flagi. Wiec sprawdzilem ten program pod katem wirusow i okazalo sie ze wygenerowane exeki instaluja koparki na kompach uzytkownikow.
I am vader (0:52, 19.04.18):
Znalazlem taki program ktory zamienia pliki bat w exe poniewaz powody, ale na stronie zostalem zapytany czy uzycze komputera na mineowanie kryptowalut podczas przegladania strony zeby wspomoc tworce.
I am Lord (23:59, 18.04.18):
może flash coś dodaje?
Wojo (23:06, 18.04.18):
Nawet pobrałem sobie ADW cleanera i nic nie wykrył
Wojo (22:38, 18.04.18):
No ale co mi po tym, że ktoś ma ip z Gdańska i jest zainteresowany zabawkami dla psów co jest bezużytecznymi danymi nawet dla hakera
Wojo (22:36, 18.04.18):
W sumie jak tak siedzę i się zastanawiam to może wydobyć pliki cookies, przechwycić naciśnięte klawisze
Wojo (22:33, 18.04.18):
Ale co ma śledzić? Lokalizację na podstawie ip? Bo nie rozumiem za bardzo
PsichiX (21:38, 18.04.18):
mowie o skrypcie js-agent.newrelic.com, ktory rozpoznawany jest jako narzedzie sledzace.
PsichiX (21:36, 18.04.18):
prowo?
Wojo (19:40, 18.04.18):
To tak zwane "prowo", które było nieudolną próbą "prowo" yxa
I am Lord (16:59, 18.04.18):
Aż tak ci się zacina to?
Wojo (16:11, 18.04.18):
Pół biedy ze śledzeniem ale denerwuje mnie kopanie BitCoinów przez ten link Nie ma to jak napychać portfel komuś kogo nie znam
I am Lord (0:04, 18.04.18):
Nic o tym nie wiem, a co to za skrypt?
PsichiX (23:56, 17.04.18):
a ten skrypt śledzący to Ty wrzucałeś, czy twórcy scratcha są na tyle ułomni, że coś takiego od siebie dodają? ;>
I am Lord (22:56, 17.04.18):
gnysek (9:35, 12.04.18):
No ja raz miałem nieważną z winy sekretariatu i też chyba musiałem 10zł zapłacić.
Wojo (12:34, 11.04.18):
A wszyscy co chcieli rzucić gimnazjum to po prostu strzelali kible do oporu i ich przenosili do ohp
Wojo (12:08, 11.04.18):
Nie mam jak się zapytać gdyż nie posiadam żadnych znajomych
Gibki Kaktus (10:15, 11.04.18):
To powiedz, że ich popierdoliło xD
MaxGaming (19:39, 10.04.18):
Ustawowa opłata za duplikat to właśnie 9zl. Przeczytajcie jeszcze raz o czym ja mówię :/
Gibki Kaktus (17:11, 10.04.18):
Ja jak zgubiłem to płaciłem 9 czy tam 10 zł xD
MaxGaming (23:07, 9.04.18):
Opłata 9zł to co innego, Nie bardzo, bo kolega z innej szkoły miał podobne doświadczenia...
Chell (22:59, 9.04.18):
albo uisc oplate, jeszcze nie slyszalem o darmowych duplikatach dokumentow
Ignatus (22:20, 9.04.18):
Chyba po prostu Cię nie lubią i robią sobie jaja.Przysłuchaj się przy drzwiach od sekretariatu czy nie kwiczą ze śmiechu zaraz po Twoim wyjsciu
MaxGaming (21:29, 9.04.18):
Szukam na necie i nigdzie nie widzę że jest taki przepis. I wątpie że jeśli jest to muszą to być drogie i nie czytane przez nikogo anonse. Wie ktoś coś?
MaxGaming (21:28, 9.04.18):
Ma ktoś pojęcie na jakiej podstawie szkoła może ode mnie żądać płatnego(i to słono jak za taką usługę) ogłoszenia w anonsach jeśli zgubiłem legitymacje? Twierdzą że nie mogą mi wyrobić nowej bez potwierdzenia zamieszczenia ogłoszenia w anonsach i uiszczenia opłaty...
Wojo (21:11, 9.04.18):
Nie ogarnalem ze jest tylko 48h ,myslalem ze z tydzien ;p
Ignatus (21:04, 7.04.18):
Nie ogarnalem ze jest tylko 24h ,myslalem ze z tydzien ;p
I am vader (19:00, 7.04.18):
Troche pozno zaalarmowales
Ignatus (18:25, 7.04.18):
Nieważne już ,zabrakło kilku głosów,przepadło
Ignatus (16:36, 7.04.18):
Moja żona robi charytatywnie lalki dla chorych i niepełnosprawnych dzieci.Mogę prosić o "wykop" ? www.wykop.pl/li...epelnosprawnych
PsichiX (0:04, 6.04.18):
uuu, antyleniwizm!
I am Lord (23:43, 5.04.18):
Ale kierowniczka widziała że sam ładuję to mu da popalić
I am Lord (23:42, 5.04.18):
zacząłem ładować przed 22 i gość miał mi pomóc a dał nogę
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-2018 {=|=} fable_inside();

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