Skocz do zawartości

[java] obracanie dziala w kierunku celownika (myszy)


wlochaty7

Polecane posty

Cześć, pisze grę platformowąi chce zrobić tak by można celować myszką. Innymi słowy, pocisk ma lecieć wskazane przez mysz. na rysunku to wygląda tak:

 

Obrazek

 

Rysunek duzo uproszczony, ale grunt to skumac o co mi chodzi :P Chce by dzialo obracalo się w kierunku wskazanym przez mysz czyli celownika. Wiec musze obliczyc kat no nie, obliczylem tak ze

 

                       int x_c=(int)celownik.getX(); //wspolrzedne celownika (myszki)
                       int y_c=(int)celownik.getY();
                       int x_b=(int)dzialo.getX(); //wspolrzedne dziala
                       int y_b=(int)dzialo.getY();


                       int x_n=x_c-x_b; //przyprostokatna x
                       int y_n=y_c-y_b; //przyprostokatna y

                       double dot = Math.sqrt((x_n*x_n)+(y_n*y_n)); /przeciwprostokatna d

                       double a_c = x_n/dot; //obliczam cosinusa kata alfa
                       double a_s = y_n/dot;

                       double kat = Math.acos(a_c)*180/3.14; //tu powinienem uzyskac kat alfa w stopniach

                       if(a_s<0) kat=-kat;

 

No i gdy zrobiłem te obliczenia dzialo za grzyba nie chce mi wskazywac na celownik i teraz nie wiem gdzie mam bład. Zwykle jak zrobie maly ruch to ono sie obraca wokół własnej osi jak oszalałe.. a nie powinno..

Link do komentarza
Udostępnij na innych stronach

Miałem kiedyś podobny problem ...

 

W tym przypadku musisz na pewno korzystać z cosinusa i sinusa.

 

Ja to załatwiłem tak ,że najpierw obliczam długość przeciwprostokatnej (Twierdzenie Pitagorasa) .Znając X i Y tych obiektów ,można to łatwo obliczyć (dodatkowo utworzony został trójkąt prostokątny ,więc da się)

 

Teraz ustawiasz tak rysowanie linii (łączącej celownik z dizalem) ,żeby początek znalazł się na środku dziala ,a koniec szukał zmieniając kąt rysowania ...

 

 

Blebleble ...

 

 

Dam ci kod (w delphi) na obliczenie położenia X ,Y celownika (po przekształceniu będziesz mieć kąt w radianach) :

A - Alpha ,czyli kąt szukany działa

 

celownik.x=dzialo.x+długosclinii*Cos(DegToRad(A))

celownik.y=dzialo.y+długosclinii*Sin(DegToRad(A))

 

Po przekształceniu :

 

długośćlinii*Cos(DegToRad(A))=Celownik.x-Działo.x

Cos(DegRoRad(A))=(Celownik.x-Dzialo.x)/długośćlinii

 

A=RadToDeg(Sec((Celownik.x-Dzialo.x)/długośćlinii))

 

Więc ,jeśli chcesz obliczyć Kąt ,to musisz znać X Celownika ,Działa i długość linii łączącej działo z celownikiem

 

X znasz ,a długość obliczasc za pomocą Twirdzenia Pitagorasa (a^2+b^2=c^2 , c=pierwiastek(a^2+b^2) c- długość naszej linii łączącej działo z celownikiem )

 

 

 

Chyba wszystko jasne ??

Aktualnie piszę 32 bitowy system operacyjny.

ASE2.0 100% ,DME (Dynamic Motion Engine) v2.0 10% ,32 bit PumaOS - 40%

Stick's Adventure 3 - 0%

Komp nr.1 AMD Duron 1,3 Ghz ,256 MB Ram DDR PC133 (na eBoostr mam jeszcze 1 GB) ,Nvidia GeForce FX 5500 256MB DDR

Komp nr.2 (laptop) AMD Athlon XP 2,0 Ghz , 192 MB Ram DDR PC2700 (na eBoostr mam jeszcze 3 GB) , Via S3 Unichrome IGP

Przykład programu w ASE2.0:

<?arg #CreateProcs; $i:?;

#For('$i,10,1,@Lab');@Lab;

#Sleep(100);

#Message("Ten komputer ulegnie autodestrukcji za $i sekund");

#Retf;

#Message('Dead'); arg?>

Link do komentarza
Udostępnij na innych stronach

cos takiego, znalazlem u siebie, znalezione chyba nawet na unit1.

 


function WartoscKataZPunktu(Punkt : TPoint;Srodek : TPoint) : integer;
var klatka : byte;
   dlA, dlX, kat : currency;

begin
Result :=-1;

If (Punkt.X = Srodek.X )and(Punkt.Y = Srodek.Y) then  exit;

If (Punkt.X < Srodek.X)and(Punkt.Y <= Srodek.Y) then  Klatka := 2;
If (Punkt.X <= Srodek.X)and(Punkt.Y > Srodek.Y) then  Klatka := 3;
If (Punkt.X >= Srodek.X)and(Punkt.Y < Srodek.Y) then  Klatka := 1;
If (Punkt.X >= Srodek.X)and(Punkt.Y > Srodek.Y) then  Klatka := 4;

DlA := SQRT( SQR(ABS(Punkt.X-Srodek.X)));

DlX := SQRT( SQR(ABS(Punkt.X-Srodek.X))+ SQR(ABS(Punkt.Y-Srodek.Y)) );

Kat := RadToDeg(ArcCos(DlA / DlX));

If Klatka = 1 then
kat:= 270-kat;
If Klatka = 2 then
Kat := kat + 90;

If Klatka = 3 then
Kat :=90 - kat;

If Klatka = 4 then
Kat := 270+ Kat;


Result := round(Kat);

end;


Link do komentarza
Udostępnij na innych stronach

Sekans ,odwrotność cosinusa jeśli się nie myle

Aktualnie piszę 32 bitowy system operacyjny.

ASE2.0 100% ,DME (Dynamic Motion Engine) v2.0 10% ,32 bit PumaOS - 40%

Stick's Adventure 3 - 0%

Komp nr.1 AMD Duron 1,3 Ghz ,256 MB Ram DDR PC133 (na eBoostr mam jeszcze 1 GB) ,Nvidia GeForce FX 5500 256MB DDR

Komp nr.2 (laptop) AMD Athlon XP 2,0 Ghz , 192 MB Ram DDR PC2700 (na eBoostr mam jeszcze 3 GB) , Via S3 Unichrome IGP

Przykład programu w ASE2.0:

<?arg #CreateProcs; $i:?;

#For('$i,10,1,@Lab');@Lab;

#Sleep(100);

#Message("Ten komputer ulegnie autodestrukcji za $i sekund");

#Retf;

#Message('Dead'); arg?>

Link do komentarza
Udostępnij na innych stronach

  • 2 months later...

Zarchiwizowany

Ten temat jest archiwizowany i nie można dodawać nowych odpowiedzi.

×
×
  • Utwórz nowe...