Skocz do zawartości

Konrad-GM

Użytkownicy
  • Zawartość

    2572
  • Rejestracja

  • Ostatnia wizyta

  • Wygrane w rankingu

    7

Zawartość dodana przez Konrad-GM

  1. Punkty za zabicie grupy przeciwników

    Cześć, najłatwiej byłoby po prostu dla każdej jednostki z oddziału "zapamiętać" z jakiego spawna pochodzą. Po prostu zrobić jakiś prosty licznik i sprawdzać, czy został on wyzerowany: W obiekcie powiedzmy obj_spawn dodajesz zmienną w Create Event: units_alive = 0; Potem przy tworzeniu jednostki obj_unit nadać mu dodatkowo ID instancji obj_spawn jako "pochodzenie", np. w obiekcie obj_spawn w User Event 0 dać coś takiego: // tworzymy instancje jednostki var unit = instance_create(x, y, obj_unit); unit.spawn_id = id; // dodajemy jednostke do licznika units_alive += 1; A na koniec w obiekcie obj_unit w Destroy Event wystarczy dekrementować licznik powiązanej instancji obj_spawn: spawn_id.units_alive -= 1; Potem sprawdzenie ile jednostek pozostało żywych jest chyba oczywiste
  2. Zatrzymanie gry

    Możesz jeszcze użyć dezaktywacji obiektów, ale trzeba pamiętać, aby obiekt popup-a był aktywny, bo inaczej nie będzie można wrócić do gry W Create Event obiektu obj_popup daj taki kod: instance_deactivate_all(); instance_activate_object(obj_popup); Ale pamiętaj też o aktywacji obiektów po zniknięciu komunikatu, np. w Event Destroy obiektu obj_popup daj: instance_activate_all(); Edit: GameMaker nie udostępnia funkcji do przetworzenia zdarzeń systemowych -> pętla w grze po prostu Ci nie zadziała, bo nie będziesz w stanie obsłużyć żadnego kliknięcia, nawet krzyżyka na belce okna. Jeżeli pisałeś kiedykolwiek aplikacje na Windowsa, to jest tam taka funkcja jak GetMessage/PeekMessage, GameMaker nie udostępnia swojego odpowiednika Pętla musiałaby wyglądać tak: 1. obsłuż zdarzenia systemowe 2. jezeli nacisniete esc lub myszka na ok skocz do 6<- tutaj można sprawdzić, czy esc/myszka została naciśnięta bo zdarzenia systemowe zostały zinterpretowane 3. wyswietl napis 4. swap buffers - wyświetl na ekran wygenerowany obraz 5. skocz do 1 6. <kontynuuj program> Ale w GameMakerze jest to niemożliwe. Przynajmniej nie znalazłem funkcji do obsługi systemowych zdarzeń.
  3. Zatrzymanie gry

    Cześć, musisz przyblokować wykonywanie się kodu innym obiektom, pętla while Ci nie zadziała ze względu na to, jak działa pętla główna Game Makera. Jak używasz pętli while, to GameMaker nie przetwarza systemowych zdarzeń jak np. kliknięcie myszką czy klawisza. Żeby przyblokować wykonywanie kodu w obiektach, możesz stworzyć np. zmienną globalną jak: global.is_paused = false; A potem w każdym z obiektów w Step Event, przed blokiem całego kodu dodaj po prostu taką linijkę: if (global.is_paused) exit; Jak chcesz zapałzować grę, to po prostu ustawiasz zmiennej global.is_paused na true, analogicznie odblokowujesz grę po ustawieniu global.is_paused na false.
  4. texture_set_interpolation

    Bezszwowe tekstury to normalna praktyka by się pozbyć tego efektu, ale czasami to nie wystarcza, zwłaszcza jak się podzieli teksturę na mniejsze elementy, bo po prostu limit rozmiaru tekstury nie pozwala na to. Efekt co prawda nie jest idealny, ale można i z tym powalczyć, np. przekopiowując krańce tekstury z tekstury sąsiadującej. Coś na zasadzie dodawania 1px obramowania do sprite'ów w atlasie tekstur, żeby też ominąć te brzydkie łączenia z sąsiednim spritem. (w 3D tekstura musi być rozmiaru potęgi dwójki, dlatego np. 2050px odpada i trzeba obraz skalować)
  5. texture_set_interpolation

    Ważne, że działało i dawało zadowalające efekty, tyle, że to takie mini-piekło dla perfekcjonisty Jednak ten problem z interpolacją dotyczy każdego silnika czy biblioteki graficznej, brak shaderów czy chociaż podstawowych ustawień tekstur to już rzeźnia po prostu. Ale warto wiedzieć jak sobie radzić z takimi problemami gdy ogranicza narzędzie
  6. texture_set_interpolation

    Cześć, problem z interpolacją tekstur jest jak najbardziej "normalną" odpowiedzią od karty graficznej, generalnie ten problem występuje od zawsze, odkąd istnieje interpolacja sampli. Jednym z rozwiązań jest wyłączenie powtarzalności tekstur np. w OpenGL jest to ustawienie w teksturze flagi GL_TEXTURE_WRAP_S/T na GL_CLAMP_TO_EDGE, jednak GameMaker nie udostępnia takowych funkcji Przykładowe ustawienia wrap-owania tekstur w OpenGL (opcje te występują również w DirectX); W Twoim przypadku GameMaker prawdopodobnie ustawia teksturom odpowiednik GL_REPEAT w DirectX, dlatego pojawiają Ci się te "artefakty" na krańcach tekstury. Dodatkowo każda tekstura musiałaby być "stworzona" jako oddzielna tekstura w VRAM, atlas tekstur nie zadziała, jak to się dzieje w przypadku GMS1.4+ (tzw. grupy obrazków w ustawieniach GMa, ale da się to akurat ominąć). Więc w skrócie problem polega na tym, że interpolacja sampli w fragment shaderze miesza sąsiadujące kolory, tworząc tzw. texel, jak się pewnie domyślasz, artefakty które pojawiają Ci się na krańcach modelu podłogi to po prostu zmieszane kolory z drugiego krańca tekstury, dlatego też warto czasami używać tekstur seamless Po więcej teorii dot. tekstur i metod samplowania odsyłam do https://cglearn.eu/pub/computer-graphics/textures-and-sampling Jako, że nie możemy wyłączyć powtarzalności tekstur, można za to wykluczyć krańce tekstury z samplowania, efekt nie jest idealny, ale nie ma tak oczojebnych artefaktów. Przykład poniżej: Jednak aby wykluczyć krańce tekstury w GMie, trzeba stworzyć własny model podłogi, bo draw_floor nie udostępnia funkcji do modyfikacji UV per vertex, ani GameMaker 8.0 nie wspiera shaderów. Kod obj_floor w Create Event u mnie wygląda tak: // tworzymy model podlogi tylko raz i przypisujemy model do zmiennej globalnej if (!variable_global_exists("model_floor")) { // obliczamy polowe texela tekstury do wykluczenia go z sampla // teraz kazdy kafelek Twojej podlogi musi miec taka sama wielkosc var u, v; u = (1.0 / background_get_width(texTile)) * 0.5; v = (1.0 / background_get_height(texTile)) * 0.5; // szerokosc i dlugosc podlogi var w, h; w = 64; h = 64; // tworzymy model podlogi (tylko raz) global.model_floor = d3d_model_create() d3d_model_primitive_begin(global.model_floor, pr_trianglefan); d3d_model_vertex_texture(global.model_floor, 0, 0, 0, 0.0 + u, 0.0 + v); d3d_model_vertex_texture(global.model_floor, w, 0, 0, 1.0 - u, 0.0 + v); d3d_model_vertex_texture(global.model_floor, w, h, 0, 1.0 - u, 1.0 - v); d3d_model_vertex_texture(global.model_floor, 0, h, 0, 0.0 + u, 1.0 - v); d3d_model_primitive_end(global.model_floor); } // tekstura podlogi texid = background_get_texture(texTile); Natomiast obj_floor i Draw Event: d3d_model_draw(global.model_floor, x, y, 0, texid); Można też poprawić wygląd łączeń, ale tutaj jest trochę więcej roboty - musiałbyś zeskalować tekstury powiedzmy z 2048 do 2046 na środek i te wolne piksele na krańcach przekopiować z sąsiadujących ze sobą tekstur (tekstura nadal musi mieć 2048px).
  7. FPS zwalnia!

    Pomysł @gnysek może się sprawdzić, ale zamiast with i place_meeting spróbuj użyć collision_circle w step event obj_pocisk: var potwor = collision_circle(x, y, 8, obj_potwor, true, true); if (potwor != noone) { if (z < 24) { with (potwor) { instance_destroy(); } } } Wartość parametru rad = 8 możesz modyfikować wedle uznania, żeby dostosować promień kolizji.
  8. FPS zwalnia!

    W poprzednim temacie napisałem co można by zrobić, ale powtórzę: BTW. Nazwa tematu nie jest dostatecznie opisowa.
  9. collision circle

    Cześć, funkcja collision_circle (jak każda funkcja zaczynająca się od collision_*) zwraca ID instancji, także other Ci tutaj nie zadziała. Musisz zapisać ID do zmiennej tj. var potwor = collision_circle(x, y, 100, obj_potwor, false, true); while (potwor != noone) { with (potwor) { instance_destroy(); } potwor = collision_circle(x, y, 100, obj_potwor, false, true); } Dałem funkcję w pętli, ponieważ funkcje collision_* zwracają Ci tylko ID jednej instancji. Dla GMS1.4+ zamiast with(potwor) można zapisać instance_destroy(potwor)
  10. Czy GM domyślnie rysuje poza viewem?

    Dokładnie, bez sensownego mierzenia wydajności, jakakolwiek próba optymalizacji nie ma sensu, bo może to być zwykłą stratą czasu. Edit: Na szybko sprawdziłem, czy zmiana visible połowy sprite na false ma jakiś wpływ na FPS - i nie ma żadnego, FPS tak samo niski jaki był
  11. Czy GM domyślnie rysuje poza viewem?

    IMO przedwczesna optymalizacja też jest zła, optymalizuj rysowanie sprite, kiedy faktycznie będzie miało to wpływ na wydajność Przejrzyj może artykuł dot. optymalizacji na Yoyo, jest tam kilka wzmianek o optymalizacji rysowania spritów.
  12. Czy GM domyślnie rysuje poza viewem?

    To też nie do końca prawda, odrzucane są trójkąty podczas renderingu, po vertex shaderze (Vertex Post-Processing). Także żeby zminimalizować draw call'e, które też mają wpływ na wydajność, stosuje się własny clipping. Podejrzewam, że o to chodziło autorowi
  13. Strzał 3d

    Widzę, że wkraczasz w bardziej złożone kwestie z programowaniem fizyki w grach Podejrzewam, że problem jest z dużą ilość wrogów na mapie - albo użyj dezaktywacji obiektów poza pewnym rejonem dookoła gracza funkcjami z rodziny instance_(de)activate_*, albo porzuć stosowanie flagi solid i oprogramuj swoją obsługę kolizji w Collision Event-ach. Nie mam pojęcia, jak GameMaker obsługuje kolizje i czy stosuje coś na wzór spatial partitioning - quadtree, spatial hash itp., może ktoś bardziej obeznany w tych kwestiach z GMem by podpowiedział. Ale mógłbyś też posilić się własną implementacją sprawdzania kolizji używając quadtree czy prostszym w implementacji spatial hashing (quadtree vs spatial hashing). PS. Możesz skrócić swój kod with(obj_potwor) do with(obj_potwory) ustawiając wrogom tego samego rodzica parent obj_potwory.
  14. Jak zabezpieczacie swoje gry w GMS?

    Też raczej bym się tym nie przejmował, jak zrobisz interesującą grę, to więcej osób po prostu ją pobierze (co jest chyba ważniejsze). Zamiast tracić czas na implementację *byle* zabezpieczeń (które i tak można złamać) to poświęć ten czas na jakiś fajny feature w grze Ale żeby nie odchodzić od tematu kompletnie bez rozwiązania żadnego, to można zastosować jakieś proste triki jak np. oszukiwać gracza "hakera" o wartościach zmiennych, np. złoto w grze byłoby przesunięte o 3 bity, co dawałoby kompletnie inne wartości w Cheat Engine (potem trzeba tego pilnować przy odczycie/zapisie ilości złota!), albo użyć coś na wzór XOR-owania zmiennych przed i po zapisie w pamięci RAM. Albo jak gnysek wspomniał, użyj hashowania zmiennych kluczowych, ale też w pamięci gry, a jak ktoś Cheat Enginem spróbuje je zmienić, to hash się nie będzie zgadzał przed np. odczytem ilości złota albo dodatków. Wtedy będziesz mógł obsłużyć próbę "zhakowania" gry i odczytać te zmienne np. z zaszyfrowanego save-a.
  15. Cześć, GameMaker Studio 1.4 tworzy backupy w katalogu %USERPROFILE%\Documents\GameMaker\Backups (ustawienia standardowe), generalnie polecam używać jakiś VCS jak np. Git.
  16. adresowanie zmiennych

    W większości przypadków self praktycznie Ci się nie przyda, osobiście sam nie stosowałem tego rodzaju odwołania i nie potrafię powiedzieć, do czego byłoby to użyteczne, ponieważ i tak blok kodu jest wykonywany w kontekście self.
  17. adresowanie zmiennych

    Mam wrażenie, że nie przeczytałeś tego co napisał @I am Lord Średnik ';' służy tylko do oddzielania wyrażeń, także jeżeli napiszesz dwa wyrażenia w jednej linii oddzielając je średnikiem, to nie ma to żadnego znaczenia, poza formatowaniem kodu. Także w Twoim przypadku zmienna 'z' będzie zmieniona w instancji obiektu obj_pocisk.
  18. adresowanie zmiennych

    Jeżeli w obiekcie obj_pocisk, stworzysz event Collision Event z obiektem obj_wrog, to ten kod: z = 10; Będzie dotyczyć instancji obiektu, w którym ten event (kod eventu) jest wykonywany. W tym wypadku będzie to instancja obiektu obj_pocisk. Aby odwołać się do instancji obiektu obj_wrog, używasz referencji other, tj. other.z = 10; Dodatkowo, w GM jak edytujesz skrypt, to w belce edycji jest taka opcja jak Applies To. Jeżeli zaznaczysz np. opcję Other, to cały kod będzie objęty tak jakby blokiem with: with(other) { <kod_skryptu> } Nie polecam tej opcji, utrudnia tylko czytanie kodu, także warto mieć to na uwadze, żeby z tej opcji nie korzystać.
  19. Nad czym aktualnie pracujesz?

    @LionX Dagger robił grę o kucach, zapewne chodzi o NHFEA, to też muszę przyznać, że styl mógł się skojarzyć
  20. adresowanie zmiennych

    Cześć, mi to wygląda na to, że Twój obiekt obj_krew nie ma zmiennej 'z'. Zmienne przeważnie tworzy się w Create Event, bo jest to event, który jest wykonywany wraz z funkcją instance_create i potem te zmienne są dostępne w referencjach na instancję zaraz po jej stworzeniu (np. "other.zmienna = 10", czy "var inst=instance_create(x,y,obj_krew); inst.zmienna = 10"). Artykułów dot. zmiennych na GMClan jest kilka, np. https://gmclan.org/index.php?czytajart=30 , przejrzyj listę artykułów na stronie https://gmclan.org/index.php?artykuly=17 mogą Ci się przydać w zrozumieniu zmiennych, argumentów, funkcji, operacji na nich itd. EDIT: v
  21. Strzał 3d

    Wyrażenie other jest tak jakby referencją na instancję, także każdy parametr instancji jest dostępny poprzez other.parametr_instancji, polecam przejrzeć dokumentację: https://docs.yoyogames.com/source/dadiospice/002_reference/001_gml language overview/keywords.html
  22. Strzał 3d

    Jeżeli używasz tego kodu na obj_pocisk co Ci przesłałem, to ten pocisk nie używa zmiennej direction, dlatego direction zawsze będzie równe 0. Spróbuj odczytać kierunek pocisku od jego zmiennych motion_xyz. Jest to wektor lotu pocisku i można za jego pomocą policzyć wektor normalny w którym kierunku leci pocisk na płaszczyźnie 2D tj.: // normalizujemy wektor 2D motion_xy var motionlen = sqrt(other.motion_x*other.motion_x + other.motion_y*other.motion_y); var xdir = other.motion_x / motionlen; var ydir = other.motion_y / motionlen; // teraz przesuwamy wroga x += xdir * 5; y += ydir * 5;
  23. Strzał 3d

    Funkcja place_meeting bierze pod uwagę maski obu instancji, maskę obj_pocisk i obj_wrog. Jeszcze istnieje taka funkcja jak position_meeting do sprawdzania kolizji tylko punktowo
  24. Nad czym aktualnie pracujesz?

    Nie jest to tak trudne, po prostu wymaga trochę innego myślenia niż GM-owe surface'y, podsyłam też niewielki przykład: render-target.zip Nie jestem pewien, czy z forum działa pobieranie plików, ale wgrałem też na inny hosting: https://www23.zippyshare.com/v/xXpprq1O/file.html - LPM "niszczy" surface
  25. Nad czym aktualnie pracujesz?

    @I am Lord Jasne, w czołgach używam właśnie metody "surface" żeby połączyć elementy otoczenia w teksturę, ale w Godocie działa to odrobinę inaczej. Viewporty w Godot to nic innego jak OpenGL'owe Framebuffery, ale aktualizują się dopiero po wyświetleniu kolejnej klatki, nie da się rysować bezpośrednio na Viewportach ze względu na VisualServer, który odpowiedzialny jest za interpretowanie komend rysowania np. VisualServer.canvas_item_add_line jest podpięte bezpośrednio pod CanvasItem.draw_line (Node2D, Sprite etc.), dotyczy to wszystkich funkcji rysowania. Dlatego Godot też udostępnia taką funkcję jak VisualServer.request_frame_drawn_callback, dzięki niej można nasłuchiwać, kiedy Viewporty zostały zaktualizowane. Żeby nie aktualizować Viewporta co klatkę, polecam ustawić parametr Viewport.render_target_update_mode na UPDATE_ONCE (ten parametr potem jest ustawiany na UPDATE_DISABLED przez VisualServer, także każda kolejna aktualizacja wymaga przełączenie tego parametru). Zalecałbym też przełączenie tej flagi Viewport.render_target_v_flip na True, bo standardowo obraz będzie odwrócony. Nie zapomnij też o parametrze Viewport.size. Dodatkowo wspomnę, że Viewport.get_texture zwraca referencję na teksturę i wystarczy pobrać teksturę jednorazowo np. w funkcji _ready i narysować ją raz w metodzie _draw bez wywoływania metody update. Ale nie można wtedy usunąć Viewporta, bo usunie nam też teksturę. Jakbyś chciał "ukryć" Node'y z drzewa sceny nie musząc dodawać Viewport node'ów, możesz użyć bezpośrednio metod z VisualServer tj. VisualServer.viewport_create, VisualServer.viewport_set_active, VisualServer.viewport_get_texture, VisualServer.viewport_attach_canvas, VisualServer.canvas_create, VisualServer.canvas_item_set_parent, VisualServer.free_rid itd. np. do obsługi roboczych Viewportów. Jeszcze wspomnę o OpenGL ES na mobilkach - Texture.get_data nie działa ze względu na limity samego OpenGL ES, które uniemożliwiają przepływu danych z GPU do RAM, także nie da się pobrać pikseli z Viewporta czy jakiejkolwiek tekstury do zmiennej, natomiast na desktopach działa bez problemu.
×