Skocz do zawartości

Temat zbiorczy na drobnostki


Chell

Rekomendowane odpowiedzi

Witam, vspeed to jest prędkość pionowa, co nie? Mam tutaj kod, jest bardzo prosty, jestem na tyle głupi, aby nie zrozumieć, dlaczego jeżeli używam if i not, to vspeed reaguje tylko wtedy, gdy przemieszcza się w dół, dlaczego?!

Tutaj przykład:

if not vspeed = 0
sprite_index = s_Player_Jump;

Za odpowiedzi serdeczne dzięki :moo:

Odnośnik do komentarza
Udostępnij na innych stronach

Kontekst: Znak ! znaczy to samo co not

 

zamiast robić if !vspeed=0 zrób if vspeed!=0

 

Możliwe że kompilator interpretuje !vspeed jako "Odwóć vspeed", gdzie wartość 0 i mniej to negative a powyżej 0 to positive. Program zamienia wartość dodatnią (>0)(czyli TRUE) na 0 (czyli FALSE), podczas gdy wartość jest ujemna (<0) jest już FALSE więc zostaje zmieniona na TRUE czyli 1.

A że 1 nie równa się 0 kod się nie wykonuje.

Tutaj jeszcze tabelka dla zwizualizowania sytuacji

Liczba Wartość Odwrócona wartość Odwrócona wartość w formie liczbowej  
<0 FALSE TRUE 1 Nie równe 0, nie wykonuje kodu.
0 FALSE TRUE 1 Nie równe 0, nie wykonuje kodu.
>0 TRUE FALSE 0 Równe 0, wykonuje kod
Odnośnik do komentarza
Udostępnij na innych stronach

Musiałbyś to zapisać w ten sposób:
 

if not (vspeed = 0) sprite_index = s_Player_Jump;

albo

if  !(vspeed = 0) sprite_index = s_Player_Jump;


nie wiem czy to dobrze wytłumaczę, ale w Twoim przykładzie not odnosi się tylko do vspeed i GM traktuje vspeed jako true/false a nie jako zmienną int.

not vspeed daje false i to póżniej przyrównuje do 0 (czyli wg GM drugie false) co razem daje true. To samo powinno być jakbyś zapisał

if  vspeed  sprite_index = s_Player_Jump;

 

Odnośnik do komentarza
Udostępnij na innych stronach

  • Administratorzy

if not vspeed = 0

to dokładnie to samo co

if (not vspeed) = 0

 

zatem w tej sytuacji, negujesz vspeed (zatem zwraca true gdy vspeed jest 0 i false w pozostałych przypadkach).

 

Tobie chodzi o:

 

if not (vspeed = 0).

Odnośnik do komentarza
Udostępnij na innych stronach

  • 1 miesiąc temu...

nie ma. poza tym, nie wiem, czy w ogole oplacalnym jest utrzymywanie wsparcia dla wymarlej architektury prockow.

Odnośnik do komentarza
Udostępnij na innych stronach

  • 3 miesiące temu...

Szybki temat, nie wiem jak się za to zabrać:

To jest zmienna, która odpowiada za to, że na tej długości pikseli wróg widzi i strzela do mnie:

max_range = 600 - czyli w promieniu 600 pxl widzi i naparza.

Chciałbym to zamienić, aby to 600 stało się zakresem viewa gracza, czyli krótko mówiąc, aby strzelał, tylko gdy go widzę na ekranie.

Pozdro :D

Odnośnik do komentarza
Udostępnij na innych stronach

Lolik, musisz zrobić coś w stylu collision_rectangle, tylko na view'a. Dam Ci prosty kod, zmień go na własne potrzeby (uwzględnij spirte_width wroga itp)

 

vx = view_xview;
vy = view_yview;

vh = view_hview;
vw = view_wview;


if(  (x >= vx and x <= vx+vw) and (y >= vy and y <= vy+vh)  )
{
    //kod na strzelanie w gracza
}
else
{
    //kod na cokolwiek, kiedy gracza nie widzi
}

 

Odnośnik do komentarza
Udostępnij na innych stronach

Nope, w Create sprawdzi kod tylko raz przy tworzeniu instancji. Gra musi sprawdzać to co klatkę tak, żeby nie przeoczyła momentu kiedy wróg pojawia się w polu widzenia gracza, tak więc wklejasz to w Step. Jedynie co możesz dać w Create to zmienne, ale równie dobrze zamiast zmiennych własnych, możesz napisać od razu view_xview zamiast vx.

Odnośnik do komentarza
Udostępnij na innych stronach

Tu jest ów fragment kodu:

 

if on_turret
            {
                if df < inaccuracy+turret_nearest.inaccuracy*2
                && collision_line(x,y,x+lengthdir_x(turret_nearest.max_range,dir),y+lengthdir_y(turret_nearest.max_range,dir),enemy_nearest,prec_wall_collision,1)
                && !collision_line(x,y,x+lengthdir_x(turret_nearest.max_range,dir),y+lengthdir_y(turret_nearest.max_range,dir),ally,prec_wall_collision,1)
                {
                    event_user(1) // shoot
                    shooting = 1
                }
            }
            else
            {
                if df < inaccuracy*2
                && collision_line(x,y,x+lengthdir_x(max_range,dir),y+lengthdir_y(max_range,dir),enemy_nearest,prec_wall_collision,1)
                && !collision_line(x,y,x+lengthdir_x(max_range,dir),y+lengthdir_y(max_range,dir),ally,prec_wall_collision,1)
                {
                    event_user(1) // shoot
                    shooting = 1
                }
            }

Podmianka max_range, na te dane vx vw itp sprawiło, że oponent nie strzela wcale.

Odnośnik do komentarza
Udostępnij na innych stronach

Tak jak napisałem wyżej, musisz zrobić coś na podobieństwo colission_rectangle, czyli wywal całkiem swoje collision_line, nie używaj tego. Nie wiem co znaczą twoje zmienne, ale jak na mój rozum, drugiego ifa też trzeba się pozbyć, zostaje tylko ten pierwszy (cokolwiek robi). Coś takiego, powinno być.

 

if(  (x >= vx and x <= vx+vw) and (y >= vy and y <= vy+vh)  )
{
    //kod na strzelanie w gracza
	event_user(1) // shoot (co to jest?)
    shooting = true // do uzyskiwania wyniku prawda/fałsz nie używaj int'a tylko bool'a - zajmuje mniej komórek pamięci w Ramie (optymalizacja)
}
else
{
    //kod na cokolwiek, kiedy gracza nie widzi
    shooting = false
}

Pokombinuj na różne sposoby. Ogólnie, mój kod:

(x >= vx and x <= vx+vw) and (y >= vy and y <= vy+vh)

Zwraca Ci wartość z czy przeciwnik wchodzi w view gracza. Dając "else" po tym if'ie, negujesz tą wartość, czyli wychodzi "false"
Przypatrz się dobrze, spróbuj zrozumieć :thumbsup:

Odnośnik do komentarza
Udostępnij na innych stronach

  • 3 tygodnie później...

 

Mam obiekt(ręce), który ma być przekręcony (image_angle) w zależności położenia myszki. Lecz gdy myszka będzie po drugiej stronie obiektu (lewej) (x<x) ma wykonać image_xscale -1. Lecz gdy to zrobię, obiekt obraca się o 180 stopni, i jest w kierunku przeciwnym od kursora myszki

EDIT: jest w przeciwnym kierunku od kursora myszki aż do momentu powrotu na pierwszą stronę(prawą).

EDIT2 Tak to wygląda:

20181007_110003.gif

Chcę, by ręce podlegały xscale, lecz by nie obracały się tyłem od kursora, żeby w czasie xscale nie było rotacji

EDIT:3 Sorry, pomyliłem xscale z yscale xd. jest już wszystko ok. Dzięki za odp

Odnośnik do komentarza
Udostępnij na innych stronach

  • 3 miesiące temu...

Hejo,zgłaszam się do was z takim problemem.

Kliknięcie na zdjęcie powinno wywołać zmienną fc_alert() i to działa,ale gdy już zmienna alert_showed dostanie wartość true to switch wcale nic nie robi z tym.

Początkowo gdy zmienna ma wartość false to hide_alert() się aktywuje,według switch'a. Dziękuję za odpowiedzi :)

<div id="alert">
            
        </div>
            <img src="wykrzyknik.jpg" id="alert_s" onclick="fc_alert()" width="100" height="100">
        
        <script>
            
            var alert_showed=false;
            function fc_alert()
            {
               // document.getElementById("alert").innerHTML=alert_showed;
                alert_showed=true;
            }
            function show_alert()
            {
                document.getElementById("alert").style.backgroundColor="blue";
                document.getElementById("alert").style.width="500px";
                document.getElementById("alert").style.height="500px";
            }
            function hide_alert()
            {
                document.getElementById("alert").style.backgroundColor="red";
                document.getElementById("alert").style.width="50px";
                document.getElementById("alert").style.height="50px";
            }
            
            switch(alert_showed)
                {
                    case true:
                    show_alert();
                    break;
                    case false:
                    hide_alert();
                    break;
                }
            
        </script>

 

Odnośnik do komentarza
Udostępnij na innych stronach

  • Administratorzy

@PatrykPlayingPOLSKA Bo ten switch nie jest w żadnej funkcji? On się wykonuje tylko w momencie wczytania strony, a nie non-stop. To nie game maker, że masz ciągle step event :) Jeśli chcesz go ponownie wywołać, wsadź go w którąś z funkcji.

https://jsfiddle.net/gnysek/z4w9ncpy/4/ - tu masz działające rozwiązanie

Odnośnik do komentarza
Udostępnij na innych stronach

10 godzin temu, gnysek napisał:

@PatrykPlayingPOLSKA Bo ten switch nie jest w żadnej funkcji? On się wykonuje tylko w momencie wczytania strony, a nie non-stop. To nie game maker, że masz ciągle step event :) Jeśli chcesz go ponownie wywołać, wsadź go w którąś z funkcji.

https://jsfiddle.net/gnysek/z4w9ncpy/4/ - tu masz działające rozwiązanie

 

Dziękuję bardzo,racja to bardzo myli w porównaniu do gamemaker'a.

Jeszcze raz dziękuję :)

Odnośnik do komentarza
Udostępnij na innych stronach

  • 3 tygodnie później...

Hej, krótkie pytanie, czy jest różnica w wydajności kodu pomiędzy użyciem eventu Collision a użyciem funkcji instance_place w evencie Step?

 

Na chłopski rozum użycie eventu Collision powinno być wydajniejsze, zważywszy, że step jest sprawdzany co klatkę , ale z drugiej strony, czy nie jest przypadkiem tak, że jeśli stworzymy event Collision w danym obiekcie, i wrzucimy tam cokolwiek, choćby jedną linijkę kodu, to GM i tak musi co klatkę sprawdzać, czy pomiędzy dwoma obiektami doszło do kolizji, czy też nie? Podejrzewam, że po komplikacji kodu i tak wszelaki kod, który napisaliśmy jest jakby w Stepie, a poszczególne eventy to po prostu zbiór różnych if-ów. Tak to sobie wyobrażam, ale mogę się mylić. Ponadto, te kolizje w evencie Collision są chyba sprawdzane dokładniej aniżeli instance_place czy też position_meeting, więc koniec końców może wydajniej jest użyć ev Step i funkcji instance_place? Ciekaw jestem waszych spostrzeżeń.

 

Pozdro

nowy_user

Odnośnik do komentarza
Udostępnij na innych stronach

  • Administratorzy

Wszystko zależy od ustawień masek kolizji spritów, ale generalnie... step i collision są wykonywane tyle samo razy (tzn. liczba klatek / sekunda). W stepie można jakoś ograniczyć event kolizji czasem, więc może być wydajniejsze. Co do dokładności - no to zalezy własnie od ustawień spritów (jednego z nich, bo jak jeden jest pixel-perfect a drugi nie, to i tak pixel-perfext sprawdzanie będzie).

Odnośnik do komentarza
Udostępnij na innych stronach

Tak znowu ja, tak dalej mam pierdołę :P
GMS 2!

 

W Create mam tablicę dwuwymiarową broni,

weapon[1,1] = 20 //Posiadana ilość amunicji

W stepie wpisałem kod

ammo = weapon[weaponh,1]

gdzie weaponh jest aktualnie wybraną bronią i tutaj zaczynają się cuda... (w GMS zawsze działało to normalnie)

w Evencie Global Mosue Left Down po wpisaniu na próbę ammo -= 1; nie ma reakcji... totalne 0 (mam debugowanie na draw'ach więc widzę czy ubywa czy nie)

Po stworzeniu w stepie kodu:

if mouse_check_button(mb_left){
    if weaponh > 0{
        if ammo > 0 {
            ammo -= 1;    
        }
    }
}

Amunicji ubywa po naciśnięciu i trzymaniu LPM tylko o 1, po puszczeniu wraca do poziomu 20, siedzę myślę i dalej nie wiem co zrobiłem źle, a jak zrobiłem to pewnie jakąś pierdołę, której nie widzę :/

CREATE:

//    SECONDARY //

weapon[1,0] = true; // Have Weapon
weapon[1,1] = 20; // Ammo
weapon[1,2] = 20; // Max Ammo
weapon[1,3] = 2; // Mag
weapon[1,4] = 3; // Max Mag
weapon[1,5] = 1; // Reload Time
weapon[1,6] = 1; // Shot Time
weapon[1,7] = 5; // DMG
weapon[1,8] = 15; // MAX DMG
weapon[1,9] = 3; // Armor Penetration
weapon[1,10] = "Test1"; // Name



STEP:

ammo = weapon[weaponh,1];
maxammo = weapon[weaponh,2];
mag = weapon[weaponh,3];
maxmag = weapon[weaponh,4];
reloadtime = weapon[weaponh,5];
shottime = weapon[weaponh,6];
dmg = weapon[weaponh,7];
maxdmg = weapon[weaponh,8];
armorp = weapon[weaponh,9];
weapname = weapon[weaponh,10];

 

Odnośnik do komentarza
Udostępnij na innych stronach

  • Administratorzy

No tak, w każdy stepie ustawiasz ammo na weapon[waponh, 1], czyli 20. Chyba chciałeś tak:

 

if mouse_check_button(mb_left){
    if weaponh > 0{
        if ammo > 0 {
            weapon[weaponh, 1] -= 1;    
        }
    }
}

Pamiętaj, w GM nie ma referencji, jak kopiujesz to wartość zmiennej, ale to są dwie różne zmienne.

Odnośnik do komentarza
Udostępnij na innych stronach

Hej, mam szybkie pytanie, czy deaktywowane obiekty potrzebują czasu na rozruch , gdy próbujemy je aktywować ponownie? Mam taką sytuację, mam 5 obiektów o_square na planszy, z czego 2 są aktywne, a pozostałe są deaktywowane. Gdy używam takiego kodu w Evencie  global_left pressed_mouse_buttron

 

instance_activate_object(o_square);
number_temp=instance_number(o_square);

 

to zmienna number_temp przy pierwszym kliknięciu pokazuje wartość 2 czyli ilość aktywnych squarów jest niezaktualizowana. Dopiero po drugim kliknięciu pokazuje 5. Jest to bardzo dziwne, używam GMS 1.4999, i zastanawiam się, czy zaktywowane obiekty potrzebują czasu na rozruch, aby były rzeczywiście wliczane?

 

EDIT : Chyba znalazłem odpowiedź na GMCommunity, wklejam ją dla tych, którzy będą zmagać się z podobnym problemem w przyszłości:

 

Cytuj

Also take account that the reactivate will occur in the next step. So you can only interact with them in the next step not the step you tell the objects to reactivate.

Note that this is only true if the object is deactivated when the step start. If it was activated on the start of the tick and you deactivate and then activate in the same step you will be able to interact with the objects instantly.

 

Odnośnik do komentarza
Udostępnij na innych stronach

  • 4 tygodnie później...

Mam taką zagwozdkę, może mnie ktoś oświecić?

W evencie kolizji z obiektem
Dlaczego ten kod nie działa:

if(scr_arrow_can_hit == 1)
{
    //Zrob cos
}
other.array_objectID[array_length_1d(other.array_objectID)+1] = id;

SKRYPT:

///scr_arrow_can_hit
var i;
var al = array_length_1d(other.array_objectID);
for(i=0; i<al; i++)
{
    if(other.array_objectID[i] == id) return 0;
}

return 1;

Wynik: Nie wyrzuca żadnego błędu, tylko nie wykonuje if'a, tak jakby wynik zawsze był !=1 

 


Ale ten napisany bez skryptu tylko ciągiem w jednym kodzie już tak:

var al = array_length_1d(other.array_objectID);
for(i=0; i<al; i++)
{
    if(other.array_objectID[i] == id) exit;
    other.array_objectID[array_length_1d(other.array_objectID)+1] = id;
}

//Zrob cos


Te returny jakoś inaczej działają w gml'u?

Odnośnik do komentarza
Udostępnij na innych stronach

Cześć, nie wykonujesz skryptu, tylko porównujesz jego ID. Skrypty wywołujesz jak każdą inną funkcję, czyli w pierwszym if-ie daj:

if(scr_arrow_can_hit() == 1) (...)

 

Dodatkowo dodam od siebie, że zamiast używać other w skryptach, to powinieneś przesyłać dane poprzez parametry. Poprawia czytelność kodu oraz pozwala używać tego skryptu w różnych miejscach a nie tylko w Collision Event:

///scr_arrow_can_hit(array, against_id)
var arr = argument0;
var inst = argument1;

var i, al = array_length_1d(arr);
for(i=0; i<al; i++)
{
    if(arr[i] == inst) return 0;
}

return 1;

 

Potem używasz tego skryptu w ten sposób:

if(scr_arrow_can_hit(other.array_objectID, id) == 1) (...)

 

Odnośnik do komentarza
Udostępnij na innych stronach

Jeśli chcesz dodać odpowiedź, zaloguj się lub zarejestruj nowe konto

Jedynie zarejestrowani użytkownicy mogą komentować zawartość tej strony.

Zarejestruj nowe konto

Załóż nowe konto. To bardzo proste!

Zarejestruj się

Zaloguj się

Posiadasz już konto? Zaloguj się poniżej.

Zaloguj się
  • Ostatnio przeglądający   0 użytkowników

    • Brak zarejestrowanych użytkowników przeglądających tę stronę.
×
×
  • Dodaj nową pozycję...