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.