Skocz do zawartości

Konrad-GM

Użytkownicy
  • Postów

    2 728
  • Dołączył

  • Ostatnia wizyta

  • Wygrane w rankingu

    44

Odpowiedzi społeczności

  1. Konrad-GM odpowiedź w Zbiory liczb został oznaczony jako odpowiedź   
    Takiej konstrukcji "jakisSet == 7" nawet nie ma python, jakbym zobaczył kogoś z pracy overloadującego tak operatory, udusiłbym gołymi rękoma. Tworzysz "set" czyli zbiór, w GML możesz wykorzystać do tego ds_map albo właśnie tablice i funkcja array_contains powinna być wystarczająca, ale ds_mapy mogą być szybsze przy dużym zbiorze liczb - przez praktycznie liniową złożoność hashowania i podejrzenia, czy klucz istnieje.
  2. Konrad-GM odpowiedź w Animacja bohatera podczas wykonywania ruchów w wodzie jest zbyt szybka został oznaczony jako odpowiedź   
    Bo ją sam przyśpieszasz, wywal tą linię i z głowy.
  3. Konrad-GM odpowiedź w Boki budynków migotają został oznaczony jako odpowiedź   
    Na moje oko wygląda to na z-fighting, precyzji z-buffera w GM nie można zmienić, ale zakładam, że i tak jest ustawiony na 24bity. Niestety pozostaje zmniejszenie maksymalnej odległości rysowania na mniejszą, albo zrobić niewielką przestrzeń między nakładającymi się teksturami, bądź w ogóle nie rysować nakładających się ścian.
  4. Konrad-GM odpowiedź w Przewidywanie pozycji na ścieżce został oznaczony jako odpowiedź   
    GameMaker ma kilka funkcji związanych ze ścieżkami, możesz wykorzystać je aby "przewidzieć" pozycję po X czasie, np.:
    // Ścieżki działają na wartościach od 0 (początek) do 1 (koniec) // Dlatego na początek policzymy ile ścieżki (od 0 do 1) ludek przejdzie po 1 klatce var path_spd = 1 / path_get_length(path_index); // Mnożąc prędkość 1 klatki na ścieżce przez 20 możemy "przewidzieć" pozycję po 20 klatkach var predict = path_spd * speed * 20; // Instancje mają zmienną wbudowaną path_position // Zwraca ona aktualną pozycję instancji na ścieżce (od 0 do 1!) var from_pos = path_position; var to_pos = from_pos + predict; // Liczymy przewidywaną pozycję x/y na ścieżce var to_x = path_get_x(path_index, to_pos); var to_y = path_get_y(path_index, to_pos);
    Funkcje te można znaleźć w doksie:
    https://docs.yoyogames.com/source/dadiospice/002_reference/paths/index.html
    https://docs.yoyogames.com/source/dadiospice/002_reference/paths/path information/index.html

    Nie testowałem tego więc mogą być jakieś niedociągnięcia, ale powinieneś załapać koncept
  5. Konrad-GM odpowiedź w Punkty za zabicie grupy przeciwników został oznaczony jako odpowiedź   
    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
  6. Konrad-GM odpowiedź w texture_set_interpolation został oznaczony jako odpowiedź   
    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. Konrad-GM odpowiedź w FPS zwalnia! został oznaczony jako odpowiedź   
    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. Konrad-GM odpowiedź w Strzał 3d został oznaczony jako odpowiedź   
    Z tego co widzę, nie aktualizujesz zmiennych globalnych, powinno to wyglądać tak:
     
    obj_cam i nasz Create Event:
    // włączamy tryb 3D d3d_start(); // wysokość naszej kamery nad podłogą z = 10 // deklarujemy naszą zmienną do obracania się bohatera góra/dół pitch = 0; // dodatkowo użyjemy wbudowanej zmiennej tj. // 'direction' do obracania się lewo/prawo // deklarujemy nasze zmienne globalne, // będziemy je aktualizować w Step Event global.camcos = 1; // tymczasowo nadajemy wartość 1, ponieważ cos(0rad) = 1 global.camsin = 0; // natomiast sin(0rad) = 0 global.campitch = 0;  
    Create Event głównie służy nam tutaj do deklaracji naszych zmiennych, potem będziemy na nich operować w Step Event:
    // obracamy naszego bohatera // operujemy tutaj na stopniach (degrees) direction -= (display_mouse_get_x() - display_get_width()/2)/10; pitch -= (display_mouse_get_y() - display_get_height()/2)/10; pitch = max(min(pitch,89.9),-89.9); // 180 stopni góra/dół, -0.1 żeby uniknąć błedu z przeskokiem display_mouse_set(display_get_width()/2,display_get_height()/2); // aktualizujemy nasze zmienne globalne // tutaj operujemy już na radianach (radians) // dlatego użyjemy funkcji degtorad var dirrad = degtorad(direction); var pitchrad = degtorad(pitch); // poniższe równanie to nic innego jak zredukowane mnożenie macierzy obrotu // więcej możesz się dowiedzieć np. na http://planning.cs.uiuc.edu/node102.html // jak pomnożysz macierze [Pitch] * [Yaw] przez wektor |xyz|, otrzymasz poniższe równanie: global.camcos = cos(dirrad) * cos(pitchrad); global.camsin = -sin(dirrad) * cos(pitchrad); global.campitch = sin(pitchrad);  
    W Draw Event bohatera ustawiamy projekcję naszej kamery:
    // ustawiamy projekcję rysowania d3d_set_projection( // pozycja 'oka' kamery x, y, z, // punkt, na który 'patrzy' nasza kamera // użyjemy tutaj naszych zmiennych globalnych i dodamy do aktualnej pozycji x + global.camcos, y + global.camsin, z + global.campitch, // wektor 'góry' naszej kamery // pozycja Z jest naszą górą 0, 0, 1 );  
    Teraz nasz pocisk musi dowiedzieć się, w którym kierunku 'patrzy' nasz bohater i następnie będziemy na tej podstawie obliczać.
    obj_pocisk i w Create Event deklarujemy następujące zmienne:
    // wysokość pocisku od podłogi z = 10 // tekstura pocisku tex = sprite_get_texture(spr_pocisk, 0); // budujemy wektor lotu pocisku // ze zmiennych tymczasowych: var dir_x = global.camcos; var dir_y = global.camsin; var dir_z = global.campitch; // normalizujemy wektor dir_xyz var dir_len = sqrt(dir_x*dir_x + dir_y*dir_y + dir_z*dir_z); dir_x /= dir_len; dir_y /= dir_len; dir_z /= dir_len; // predkosc pocisku jako zmienna tymczasowa // posłuży nam do obliczenia wektora motion_xyz var spd = 5; // tworzymy zmienną lokalną jako wektor motion_xyz // poruszania sie naszego pocisku: motion_x = dir_x * spd; // 'wydłużamy' wektor o wartość zmiennej spd motion_y = dir_y * spd; motion_z = dir_z * spd;  
    Step Event w pocisku jest trywialny i chyba nie wymaga tłumaczenia:
    x += motion_x; y += motion_y; z += motion_z;  
    Teraz czas na rysowanie naszego pocisku w Draw Event:
    // obliczamy obrót w stronę kamery: var dirtocam = point_direction(obj_cam.x, obj_cam.y, x, y); var dirtocamrad = degtorad(dirtocam); var xx = -cos(dirtocamrad + pi/2) * 5; var yy = sin(dirtocamrad + pi/2) * 5; // rysujemy 'ścianę' odwróconą w stronę naszej kamery, tzw. billboard: d3d_draw_wall( // x1, y1, z1 x - xx, y - yy, z + 5, // x2, y2, z2 x + xx, y + yy, z - 5, // tekstura i jej powtarzanie tex, 1, 1 );  
×
×
  • Dodaj nową pozycję...