Skocz do zawartości
  • 0
LolikZabijaka

Blokowanie się na pikselach

Pytanie

Kolejny problem, niby pierdoła, ale wkurza. Chodzi o to, że są porobione pewne przeszkody(ściany itp), są ustawione pod różnym kątem, gracz posiada okrągłą maskę. Problem polega na tym, że kiedy jestem blisko obiektu, to zahaczam o każdy ostający piksel i postać się blokuje. Czy da się zrobić, aby postać nie przełaziła przez ścianę, ale przy okazji, żeby gładko mogła się wzdłuż niej poruszać, bez blokowania sie o piksele? Dodam że jak wiadomo postać miewa zmienne image_angle. Kod przy kolizji ze ścianą:

 

GML
x = xprevious y = yprevious

 

Udostępnij tego posta


Odnośnik do posta
Udostępnij na innych stronach

21 odpowiedzi na to pytanie

Rekomendowane odpowiedzi

  • 0

Jak najbardziej! Chcesz tutaj skorzystać z trygonometrii aby poruszać postacią pod kątem ściany. Niestety rozwiązanie to jest troche bardziej skomplikowane, więc nie mogę podać Ci gotowego kodu. Postaram się coś zmontować i dać w edicie, ale nie zapewniam że to zrobię.

Udostępnij tego posta


Odnośnik do posta
Udostępnij na innych stronach
  • 0

Nawet nie musialem sie wysilic, bo w GMie jest obecnie artykul o tym jak zrobic dokladnie to czego Ci trzeba. Nazywa sie Buttery Smooth Movement. W linku ponizej jest jego zastosowanie w przykladowym projekcie:

 

https://led.feen.us/rclpal3n.zip

Udostępnij tego posta


Odnośnik do posta
Udostępnij na innych stronach
  • 0

No dobra. Nie wiem czy bedzie dzialac na gm 8 ale zobaczymy:

 

skrypt o nazwie move:

GML
/// @arg speed

/// @arg direction

var spd = argument0;

var dir = argument1;

 

var xtarg = x+lengthdir_x(spd,dir);

var ytarg = y+lengthdir_y(spd,dir);

 

if place_free(xtarg,ytarg) {

x = xtarg;

y = ytarg;

}

else {

var sweep_interval = 10;

 

for ( var angle = sweep_interval; angle <= 80; angle += sweep_interval) {

for ( var multiplier = -1; multiplier <= 1; multiplier += 2) {

var angle_to_check = dir+angle*multiplier;

xtarg = x+lengthdir_x(spd, angle_to_check);

ytarg = y+lengthdir_y(spd, angle_to_check);

if place_free(xtarg,ytarg) {

x = xtarg;

y = ytarg;

exit;

}

}

}

}

 

 

Skrypt na poruszanie sie:

GML
//Zaciagniete z przykladu "Buttery Smooth Movement" bo jestem leniwy

movement_inputs[0] = ord("D");

movement_inputs[1] = ord("W");

movement_inputs[2] = ord("A");

movement_inputs[3] = ord("S");

var move_xinput = 0;

var move_yinput = 0;

 

for ( var i = 0; i < array_length_1d(movement_inputs); i++){

var this_key = movement_inputs;

if keyboard_check(this_key) {

var this_angle = i*90;

move_xinput += lengthdir_x(1, this_angle);

move_yinput += lengthdir_y(1, this_angle);

}

}

var moving = ( point_distance(0,0,move_xinput,move_yinput) > 0 );

if moving {

var move_dir = point_direction(0,0,move_xinput,move_yinput);

move(2,move_dir);

}

 

 

Podmień 2 na prędkość chodzenia w ostatniej lini.

Udostępnij tego posta


Odnośnik do posta
Udostępnij na innych stronach
  • 0

Oh come on, nie jesteś pierwszym lepszym użytkownikiem, powinieneś wiedzieć, że jeżeli wywala błąd powinieneś go wkleić na forum. Bez treści błędu nic nie wiemy.

Udostępnij tego posta


Odnośnik do posta
Udostępnij na innych stronach
  • 0

GML
/// @arg speed

/// @arg direction

var spd = argument0;

var dir = argument1;

 

var xtarg = x+lengthdir_x(spd,dir);

var ytarg = y+lengthdir_y(spd,dir);

 

if place_free(xtarg,ytarg) {

x = xtarg;

y = ytarg;

}

else {

var sweep_interval = 10;

 

for ( var angle = sweep_interval; angle <= 80; angle += sweep_interval) {

for ( var multiplier = -1; multiplier <= 1; multiplier += 2) {

var angle_to_check = dir+angle*multiplier;

xtarg = x+lengthdir_x(spd, angle_to_check);

ytarg = y+lengthdir_y(spd, angle_to_check);

if place_free(xtarg,ytarg) {

x = xtarg;

y = ytarg;

exit;

}

}

}

}

 

Wywala błąd przy znaku równości przy tej części kodu:

 

GML
var spd = argument0;

var dir = argument1;

Udostępnij tego posta


Odnośnik do posta
Udostępnij na innych stronach
  • 0

A zamień

GML
var spd = argument0;

var dir = argument1;

na

GML
spd = argument0;

dir = argument1;

 

Chyba GM 8 nie ma var'ów. Bedziesz musial wszedzie var'y pousuwac.

Udostępnij tego posta


Odnośnik do posta
Udostępnij na innych stronach
  • 0

I am vader chyba były ale takie:

GML
var spd, dir;

spd = argument0;

dir = argument1;

Udostępnij tego posta


Odnośnik do posta
Udostępnij na innych stronach
  • 0

Tym razem wywala buga w skrypcie chodzenia "Unknown function array_length_1d"

 

A otwieranie pliku w GMS, to już w ogóle dramat, bo ciągle bugi wywala.

Udostępnij tego posta


Odnośnik do posta
Udostępnij na innych stronach
  • 0

Zamień

GML
for ( var i = 0; i < array_length_1d(movement_inputs); i++){

na

GML
for ( var i = 0; i < 4; i++){

 

Przeniósłbyś się na tego GMSa, co?

Udostępnij tego posta


Odnośnik do posta
Udostępnij na innych stronach
  • 0
Nie ! :D Znalazłem za to coś ciekawego, oto to:

https://forum.gmclan.org/index.php?showtopic=30200

Dokładnie to czego szukałem, ale mały kłopot, kiedy postać jest blisko ściany to strasznie zwalnia, gdzie jest fragment kodu odpowiedzialny za to ?

 

GML
if(collision_circle(x + lengthdir_x(1, direction) + hspeed, y + lengthdir_y(1, direction) - vspeed, 16, obj_block, 1, 1)) { // There's a horizontal collision

hspeed = 0; // Cancel horizontal movement

}

if(collision_circle(x + lengthdir_x(1, direction) - hspeed, y + lengthdir_y(1, direction) + vspeed, 16, obj_block, 1, 1)) { // There's a vertical collision

vspeed = 0; // Cancel vertical movement

}

Udostępnij tego posta


Odnośnik do posta
Udostępnij na innych stronach
  • 0

wbiłem wszędzie 1 i nadal zwalnia, co ciekawe, kiedy chodzę na boki, postać przełazi przez ścianę, oto kod chodzenia:

 

GML
// poruszanie

if ( point_distance( x , y , mouse_x , mouse_y ) > 5 and trzyma=true and bieganie = false and celowanie=0 or 1 )

{

s = 5 // prędkość poruszania na boki

if( keyboard_check( ord('A')) or keyboard_check( vk_left ))

 

{

x += lengthdir_x( s, direction + 90 );

y += lengthdir_y( s, direction + 90 );

}

else

 

if( keyboard_check( ord( 'D' )) or keyboard_check( vk_right ))

{

x += lengthdir_x( s, direction - 90 );

y += lengthdir_y( s, direction - 90 );

}

 

if ( keyboard_check( ord( 'W' )) or keyboard_check( vk_up ))

speed = 6

else

if ( keyboard_check( ord( 'S' )) or keyboard_check( vk_down ))

speed = -4

else

speed = 0

 

if(collision_circle(x + lengthdir_x(1, direction) + hspeed, y + lengthdir_y(1, direction) - vspeed, 16, sciana_parent, 1, 1)) { // There's a horizontal collision

hspeed = 0; // Cancel horizontal movement

}

if(collision_circle(x + lengthdir_x(1, direction) - hspeed, y + lengthdir_y(1, direction) + vspeed, 16, sciana_parent, 1, 1)) { // There's a vertical collision

vspeed = 0; // Cancel vertical movement

}

}

Udostępnij tego posta


Odnośnik do posta
Udostępnij na innych stronach

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

Tylko 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ę tutaj.

Zaloguj się tutaj

  • Przeglądający   0 użytkowników

    Brak zarejestrowanych użytkowników, przeglądających tę stronę.

×