NOVINKA - Online rekvalifikační kurz Java programátor. Oblíbená a studenty ověřená rekvalifikace - nyní i online.
IT rekvalifikace s podporou uplatnění. Seniorní programátoři vydělávají až 160 000 Kč/měsíc a rekvalifikace je prvním krokem. Zjisti, jak na to!

Diskuze: Deaktivování objektů

V předchozím kvízu, Online test znalostí GameMakeru, jsme si ověřili nabyté zkušenosti z kurzu.

Aktivity
Avatar
Goblin
Neregistrovaný
Avatar
Goblin:16.2.2013 15:09

Zdar, potřebuji pomoci s tímto:

Když hráč zmáčkne např. enter, objeví se inventář (dejme tomu, že se vykreslí uprostřed hry a jeho délky stran jsou menší než samotný room - jako např. inventář v Minecraftu). To vše bez problému zvládnu, ale kámen úrazu je to, že potřebuji, aby hráč při otevřeném inventáři nemohl manipulovat s ostatními objekty ve hře.

Napadlo, mě využít příkazu

instance_deactivate_all()

to sice splní svoji funkci, ale v tu chvíli veškeré instance kolem inventáře přestanou vykreslovat své obrázky a ve hře zůstane pouze pozadí roomu...

Lze tedy nějakým způsobem deaktivovat instance, aniž by ztratily vykreslování svých sprite images?

 
Odpovědět
16.2.2013 15:09
Avatar
TomBen
Tvůrce
Avatar
TomBen:16.2.2013 15:54

Deaktivace je dobrá pro objekty, které je třeba kompletně vypnout.
Např. když je mnoho objektů úplně mimo zobrazené okno, nemají nijak
reagovat ani nic počítat. K ničemu jinému se deaktivace moc nehodí.

K účelu co píšeš stačí zavést u objektů test typu

if (!invertory.open) **{do_something();} else **{nothing()}****

Žádné složitosti bych v tom nedělal. Pokud máš objektů hodně a
nepamatoval jsi na vypínání předem, můžeš jim dát obecný parent
nebo použít konstrukci with(). Ono bývá všeobecně snazší mít
inventář v jiném roomu a pak se ti spousta problémů vyřeší sama.

Editováno 16.2.2013 15:54
Nahoru Odpovědět
16.2.2013 15:54
Za posledních 200 miliónů let se nic zvláštního nestalo, akorát dinosauři vymřeli a opice se naučily programovat.
Avatar
Goblin
Neregistrovaný
Avatar
Goblin:16.2.2013 16:15

To mě taky napadlo, ale tomu jsem se chtěl právě vyhnout, protože těch objektů a jejich událostí u kterých bych musel zavádět takovou podmínku by bylo moc. Chci to udělat tak, aby to bylo univerzální a nemusel takové podmínky zavádět u každého objektu...

Nešlo by to třeba nějak takhle:

  1. vytvořil by se screen v aktuálním stavu hry, ještě před otevřením inventáře
  2. potom by se vytvořil inventář a ten by v události create deaktivoval všechny ostatní instance a nastavil jako pozadí vytvořený screen
  3. při zavření inventáře, by se screen smazal a vše opět aktivovalo

Díky screenu, by měl hráč pocit, že instance za inventářem jsou stále na svém místě, ale nemohl by s nimi nijak manipulovat, jelikož by byly deaktivované...

 
Nahoru Odpovědět
16.2.2013 16:15
Avatar
Drakeman
Tvůrce
Avatar
Odpovídá na
Drakeman:16.2.2013 16:19

Jo takhle by to taky šlo. :)

Nahoru Odpovědět
16.2.2013 16:19
Když se chce, tak jde všechno,
Avatar
Goblin
Neregistrovaný
Avatar
Goblin:16.2.2013 17:13

A poradíte mi ještě prosím, jestli lze v kódu nějak zkombinovat tyto dva příkazy

screen_save()

background_replace()

tak, aby se zachycený obrázek nemusel ukládat do složky s hrou a znovu do hry nahrával? Chci aby to bylo pro hru co nejmíň náročný, jelikož hráč bude inventář otevírat často..

 
Nahoru Odpovědět
16.2.2013 17:13
Avatar
TomBen
Tvůrce
Avatar
Odpovídá na
TomBen:16.2.2013 17:24

Vykreslíš ho do surface a pak ho můžeš používat
kolikrát chceš. Je to rozumně rychlé a neošoupáváš disk.

Nahoru Odpovědět
16.2.2013 17:24
Za posledních 200 miliónů let se nic zvláštního nestalo, akorát dinosauři vymřeli a opice se naučily programovat.
Avatar
Goblin
Neregistrovaný
Avatar
Goblin:16.2.2013 17:34

S tím bohužel nemám zkušenosti, můžete to prosím napsat konkrétněji? Zkouším to tu nějak v GML spáchat, ale nemůžu na to přijít.. :(

 
Nahoru Odpovědět
16.2.2013 17:34
Avatar
TomBen
Tvůrce
Avatar
Odpovídá na
TomBen:16.2.2013 17:56

No, je to pravda trochu složitější než save na disk..

  1. surface se musí vytvořit o potřebné velikosti v pixelech (w,h)
  2. přesměruješ vykreslování do surface
  3. dáš překreslit obraz ( buď redraw nebo počkáš na event )
  4. vrátíš vykreslování zpět ( reset_target )
  5. vykreslíš samotný surface ( draw_surface )

Jestli jsi to nikdy nepoužil, otevři si prázdný projekt
a nejprve si to zkus. Budeš potřebovat tak dvě až tři hodiny
pokusů než ti to půjde hladce, ale je to silná technika.
Vyplatí se to umět.

Nahoru Odpovědět
16.2.2013 17:56
Za posledních 200 miliónů let se nic zvláštního nestalo, akorát dinosauři vymřeli a opice se naučily programovat.
Avatar
Goblin
Neregistrovaný
Avatar
Goblin:16.2.2013 18:04

Ok, mrknu na nějaký tutotiály a do Game Maker help, snad na to přijdu.. díky, kdyžtak se ještě zeptám

 
Nahoru Odpovědět
16.2.2013 18:04
Avatar
Goblin
Neregistrovaný
Avatar
Goblin:16.2.2013 19:47

Něco jsem si přečetl na netu o surfaces, ale stále nemůžu přijít na bod č. 3:
"3. dáš překreslit obraz ( buď redraw nebo počkáš na event )"

Jak mám uložit do paměti aktuální screen hry? Abych ho poté vykreslil pomocí draw_surface()?

 
Nahoru Odpovědět
16.2.2013 19:47
Avatar
TomBen
Tvůrce
Avatar
Odpovídá na
TomBen:16.2.2013 20:23

Když máš přesměrovaný výstup pomocí surface_set_target,
tak se cokoli, co vykresluješ kteroukoli funkcí draw,
kreslí do surface místo do obrazu.

Tzn. například draw_sprite pak zakreslí daný sprite
do rovnou surface. Ber to jako malířské plátno.

Nahoru Odpovědět
16.2.2013 20:23
Za posledních 200 miliónů let se nic zvláštního nestalo, akorát dinosauři vymřeli a opice se naučily programovat.
Avatar
Goblin
Neregistrovaný
Avatar
Goblin:16.2.2013 21:15

Rozumim, pochopil jsem princip příkazu

surface_set_target

Ale stále nemůžu přijít na způsob, jak si screen ze hry do surface uložit.. Něco jako

screen_save()
 
Nahoru Odpovědět
16.2.2013 21:15
Avatar
TomBen
Tvůrce
Avatar
Odpovídá na
TomBen:16.2.2013 21:28

To už je přece to nejsnazší.
Když máš surface jako target, tak se všechny draw eventy
všech objektů automaticky vykreslují do surface.
Tzn, stačí screen_redraw() a máš v surface uložený
screenshot.

Nahoru Odpovědět
16.2.2013 21:28
Za posledních 200 miliónů let se nic zvláštního nestalo, akorát dinosauři vymřeli a opice se naučily programovat.
Avatar
TomBen
Tvůrce
Avatar
TomBen:16.2.2013 21:31

Jenom pozor na to, že když chceš mít surface čisté,
musíš do něj vykreslit jednobarevný obdélník podkladové
barvy, jinak se volně kreslí jedno přes druhé. Je dobré
to dělat často.

Nahoru Odpovědět
16.2.2013 21:31
Za posledních 200 miliónů let se nic zvláštního nestalo, akorát dinosauři vymřeli a opice se naučily programovat.
Avatar
TomBen
Tvůrce
Avatar
TomBen:16.2.2013 21:35

Ještě se dá asi používat místo surface funkci
sprite_add_from_scre­en určenou na úpravu resources.
Jenže se surface se pak líp zachází, když už jednou
vznikne a umí lepší kousky.

Nahoru Odpovědět
16.2.2013 21:35
Za posledních 200 miliónů let se nic zvláštního nestalo, akorát dinosauři vymřeli a opice se naučily programovat.
Avatar
Goblin
Neregistrovaný
Avatar
Goblin:16.2.2013 21:42

A samotné draw_surface() může být v Create, nebo musí být v Draw?

 
Nahoru Odpovědět
16.2.2013 21:42
Avatar
TomBen
Tvůrce
Avatar
Odpovídá na
TomBen:16.2.2013 21:48

Mělo by být v eventu draw poté co se vrátí vykreslování zpět.
Pokud ho chceš mít jinde, musíš opět zajistit překreslení
screenu kódem, protože v draw eventu se o to stará systém.

Nahoru Odpovědět
16.2.2013 21:48
Za posledních 200 miliónů let se nic zvláštního nestalo, akorát dinosauři vymřeli a opice se naučily programovat.
Avatar
Goblin
Neregistrovaný
Avatar
Goblin:16.2.2013 22:19

Tak už se více méně zadařilo, moc děkuju za ochotu! ;)

Jenom poslední otázečka: jak mám vykreslit ten jednobarevný obdelník jako podkladovou barvu? Zachycené pozadí v surface se mi už totiž vykresluje, ale při příkazu v Draw

draw_surface(surface,view_xview+64,view_yview+64)

se na sebe vykreslují další a další surfaces...

 
Nahoru Odpovědět
16.2.2013 22:19
Avatar
Goblin
Neregistrovaný
Avatar
Goblin:16.2.2013 22:25

Tak už jsem na to přišel

surface_reset_target()

jsem měl předtím v Create a teď se problém vyřešil tím, že jsem tento příkaz dal do Draw..

Je to správně, nebo jsme problém vyřešil náhodou? A pokud to správně je, proč reset target nemůže být v Create abych to správně pochopil?

 
Nahoru Odpovědět
16.2.2013 22:25
Avatar
TomBen
Tvůrce
Avatar
Odpovídá na
TomBen:16.2.2013 22:39

Reset_target může být kdekoli.
Prostě se od té chvíle jakýkoli draw kreslí zas do obrazu jako dřív.

Nahoru Odpovědět
16.2.2013 22:39
Za posledních 200 miliónů let se nic zvláštního nestalo, akorát dinosauři vymřeli a opice se naučily programovat.
Avatar
TomBen
Tvůrce
Avatar
TomBen:16.2.2013 22:43

Možná bys sem pak mohl publikovat výsledek svého snažení.
Rád bych viděl, co jsi natvořil.
Moc se nestává, že se mezi neregistrovanýma objeví někdo,
kdo používá hlavu i víc, než aby mu jen nepršelo do krku.

Nahoru Odpovědět
16.2.2013 22:43
Za posledních 200 miliónů let se nic zvláštního nestalo, akorát dinosauři vymřeli a opice se naučily programovat.
Avatar
Goblin
Neregistrovaný
Avatar
Goblin:16.2.2013 23:02

No, jedná se o point and click adventuru, která má některé pasáže i jako klasická plošinovka.. Vlastně vůbec nešlo o inventář, který jsme tu řešili. Ve hře bude spousta předmětů, na které když se klikne, tak se objeví zvětšenina předmětu a s tou bude muset hráč manipulovat tak, aby vyřešil nějaký rébus (např. otevřel dveře pomocí mechanismu, apod.). Proto jsem potřeboval, aby ostatní objekty v okolí byly v takové situaci deaktivované...

Obrázky, pozadí a animace si sám kreslím pastelkami, sice se nejedná o nic světoborného, ale i přesto bych to zde nerad zveřejňoval, dokud to není hotové.

Každopádně bych velice rád poděkoval tomuto serveru za Vaši pomoc a ochotu ;)

 
Nahoru Odpovědět
16.2.2013 23:02
Děláme co je v našich silách, aby byly zdejší diskuze co nejkvalitnější. Proto do nich také mohou přispívat pouze registrovaní členové. Pro zapojení do diskuze se přihlas. Pokud ještě nemáš účet, zaregistruj se, je to zdarma.

Zobrazeno 22 zpráv z 22.