Jak mogę przesunąć duszka w kierunku, w którym jest skierowane?


11

Używam Java / Slick 2D. Próbuję użyć myszy, aby obrócić duszka i klawiszy strzałek, aby przenieść duszka. Mogę zmusić duszka do obracania się bez problemu, ale nie mogę zmusić go do ruchu w kierunku, w którym powinien. Kiedy nacisnę „naprzód”, duszek niekoniecznie przesuwa się w kierunku myszy. W rzeczywistości przesunie się naprawdę tylko w lewą stronę ekranu. Jestem pewien, że musi to być jakiś standardowy kod, ponieważ wiele gier używa tego stylu ruchu. Czy ktoś może mi pomóc z tym, co powinno być wyzwalaniem? Dzięki

EDYCJA: Oto kod rotacyjny (który robi coś jeszcze dziwnego: /programming/12610320/why-is-my-image-rotating-off-center )

int mX = Mouse.getX();
        int mY = HEIGHT - Mouse.getY();
        int pX = sprite.x;
        int pY = sprite.y;
        int tempY, tempX;
        double mAng, pAng = sprite.angle;
        double angRotate=0;

        if(mX!=pX){
            mAng = Math.toDegrees(Math.atan2(mY - pY, mX - pX));
            if(mAng==0 && mX<=pX)
                mAng=180;
        }
        else{
            if(mY>pY)
                mAng=90;
            else
                mAng=270;
        }

        sprite.angle = mAng;
        sprite.image.setRotation((float) mAng); 

I kod ruchu. Mogę tylko przesunąć się w lewą stronę ekranu ...

double ang = sprite.angle;
            Input input = gc.getInput();

            if(input.isKeyDown(sprite.up)){
                sprite.x += Math.cos(ang)*sprite.moveSpeed;
                sprite.y += Math.sin(ang)*sprite.moveSpeed;
            }if (input.isKeyDown(sprite.down)){
                sprite.x += -1*Math.cos(ang*Math.PI/180)*sprite.moveSpeed;
                sprite.y += -1*Math.sin(ang*Math.PI/180)*sprite.moveSpeed;
            }if (input.isKeyDown(sprite.left)){
                sprite.x -= Math.cos(ang*Math.PI/180)*sprite.moveSpeed;
                sprite.y += Math.sin(ang*Math.PI/180)*sprite.moveSpeed;
            }if (input.isKeyDown(sprite.right)){
                sprite.x += Math.cos(ang*Math.PI/180)*sprite.moveSpeed;
                sprite.y -= Math.sin(ang*Math.PI/180)*sprite.moveSpeed;
            }

Jaki jest sens dodanego kodu? Czy to nowy problem? Jeśli to nowy problem, otwórz nowe pytanie. Zaktualizuj to pytanie tylko o informacje związane z przemieszczaniem duszka w kierunku, w którym jest skierowane.
MichaelHouse

Nie, to kod, który użyłem, spowodował problem. Zobacz komentarze poniżej. Ktoś o to poprosił.
rphello101

Nie widzę, gdzie obliczysz sprite.movespeed?
AturSams,

movespeed jest stałą, w tym przypadku ustawioną na .3
rphello101,

Odpowiedzi:


14

Będziesz chciał uzyskać wektor na podstawie bieżącej prędkości i kursu. Następnie użyj tego wektora, aby zwiększyć swoją pozycję.

//first get the direction the entity is pointed
direction.x = (float) Math.cos(Math.toRadians(rotation));
direction.y = (float) Math.sin(Math.toRadians(rotation));
if (direction.length() > 0) {
    direction = direction.normalise();
}
//Then scale it by the current speed to get the velocity
velocity.x = direction.x * speed;
velocity.y = direction.y * speed;

Teraz znasz swoją prędkość na podstawie obrotu. Za pomocą tych informacji możesz zaktualizować swoją pozycję.

//Update the position based on our current speed
//This is basic s = vt physics
position.x += velocity.x * timeElapsed;
position.y += velocity.y * timeElapsed;

W przypadku (niechlujnej) klasy, która zawiera to wszystko, możesz zobaczyć wpis Ludum Dare 21, który tutaj utworzyłem
MichaelHouse

Dziękuję Ci. Po kilku modyfikacjach zadziałało. Mam jednak inne pytanie, jeśli zdołasz to przeczytać: skłonienie duszka do cofnięcia się jest po prostu - = tym, co masz tutaj. Jak sprawić, by poruszał się w lewo lub w prawo?
rphello101

@ rphello101 Dobre pytanie, powinieneś zadać nowe pytanie. Więcej osób skorzysta i możesz uzyskać lepszą odpowiedź niż ta, którą mam.
MichaelHouse

3

Dostajesz pozycję myszy

mouseX = ... 
mouseY = ...

Otrzymasz pozycję duszka

spriteX = ...
spriteY = ...

Znajdziesz kąt

angle = Math.atan2(mouseY - spriteY, mouseX - spriteX);

Twój ruch będzie:

moveX = Math.cos(angle) * speed * time;
moveY = Math.sin(angle) * speed * time;

Wskazówka: utwórz tabelę (tablicę) dla cos i sin z wstępnie obliczonymi wartościami. więc możesz po prostu zrobić kąt cosTable [(int)] * prędkość * czas i kąt sinTable [(int)] * prędkość * czas To nie jest tak dokładne. Ale twoje wartości są znacznie szybsze.
Sidar

Spowoduje to przesunięcie duszka w stronę myszy, ale nie jest to to samo, co kierunek duszka. Duszek może nadal obracać się w stronę myszy, jeśli jego prędkość obrotu jest ograniczona lub z innego powodu. Zasadniczo odpowiadasz na złe pytanie.
MichaelHouse

@ Byte56 powiedział: „Kiedy uderzę„ do przodu ”, duszek niekoniecznie porusza się w kierunku myszy.„ Myślę, że o to zapytał. Możesz mieć rację.
AturSams,

To na pewno trochę dwuznaczne. Właśnie w tym przypadku domyślnie wprowadziłem tytuł pytania. Nie zrozum mnie źle, twoja odpowiedź jest dobra. Chyba dowiemy się, czego chciał OP, kiedy / jeśli wrócą.
MichaelHouse

2
@ Sidar To byłaby przedwczesna optymalizacja. Budowanie tabel sin / cos bez identyfikowania operacji sin / cos jako wąskiego gardła to strata czasu.
bummzack,
Korzystając z naszej strony potwierdzasz, że przeczytałeś(-aś) i rozumiesz nasze zasady używania plików cookie i zasady ochrony prywatności.
Licensed under cc by-sa 3.0 with attribution required.