2011-08-10 7 views
5

jestem programowania gier dachówka 2D opartych na Javie jak Bomberman (moja pierwsza gra).Jak koordynować położenie graficzne i logiczne w grze opartej na kafli 2D przy użyciu tablicy?

Używam tablicy 2D do przedstawienia mapy, na której śledzę ściany, miejsca do chodzenia itp. Do tej pory byłem w stanie sprawić, że gracz poruszał się płynnie zmieniając duszki w zależności od klawisza kierunkowego, który naciska (ale nie wchodził w interakcje z tło/mapę, może chodzić losowo i wyjść z ekranu).

Mój problem pojawia się, gdy chcę śledzić pozycję gracza w tablicy. Logicznie postać zawsze należy do tylko jednego pola, ale graficznie może znajdować się pomiędzy dwoma kaflami. Jak mogę rozwiązać ten problem?

ja już próbowałem:

currentTileArrayX = x/tileWidth;

currentTileArrayY = Y/tileHeight;

Gdzie x i y są lewymi górnymi współrzędnymi ikonki. Ale wszystko stało się bardzo niebezpieczne, ponieważ spriterze gracza nie mają tego samego rozmiaru co kafelki.

Miałem inną opcję, która rozwiązałaby poprzedni problem: Kiedy gracz naciśnie klawisz kierunkowy, przesuń go do następnego pola, tak jak animację. To nie pozwoliłoby graczowi zatrzymać się w środku dwóch płytek ... Ale co, jeśli przerywa to innym klawiszem? Jak mogę zatrzymać działanie użytkownika podczas wykonywania animacji? Myślę, że to najłatwiejsze rozwiązanie, ale nie wiem, jak go wdrożyć.

Próbowałem już znaleźć rozwiązanie w innych kwestiach, ale nie miałem szczęścia. Mam nadzieję że możesz mi pomóc.

Wielkie dzięki.

Odpowiedz

2

Aaaaaaaaaaaaaaah! Napotkanie problemu "dyskretnej przestrzeni" :) Twoja mapa logiki jest dyskretna, ale ruchy użytkownika są w przestrzeni ciągłej.Nie mogę, aby użytkownik był w obu kafelkach "w tym samym czasie" - wizualnie tak, ale nigdy "wewnętrznie". Teraz otrzymujesz pozycję gracza i to może być "gdziekolwiek" w obrębie płytki lub "na granicy" 2 płytek, że tak powiem ...

Masz dwa rozwiązania tego problemu, IMO:

  1. używać prostych zaokrąglanie: Jeśli pozycja gracz jest < dachówka granica po prostu trzymać go na poprzedniej płytki. Jeśli Większy w następnym. Teraz problem granicy - można użyć metody heurystyczne, ponieważ nie należy ufać dokładności pływających porównań punktowych (czyli, w porównaniu do 0 nie jest dobrą rzeczą do zrobienia). Możesz więc wypróbować coś takiego: if(currentPosition - boundary <= 0.000000001), a następnie założyć, że to kolejny kafel, pozostały na tym samym.
  2. Dobrze @Jay mnie uprzedził. Więc druga jest rzeczywiście mają prędkość ruch zdefiniowany i przesunąć znak, że wiele kroków na „click”/„” naciśnij przycisk - ale mówisz, że mają problem kluczowy wciśnięty „pomiędzy”. Zgaduję, jeśli kod jest zaprojektowany jak to to nie powinno być problemu:
 
    update() 
     { 
      calculate(); //update all datastructures/calculations 
      draw(); //update the visual representation based on calculations 
     } 

update() jest a.k.a, gameLoop. Myślę, że to powinno rozwiązać problem ...

+0

Nupul zmieniłem kod za pomocą numeru jedno rozwiązanie. Dzięki temu rozwiązał wiele błędów, mógłbym powiedzieć, że prawie teraz działa. Ale mam jeszcze jeden problem: http://imageshack.us/f/687/bomberbug.png/ Mam nadzieję, że wyjaśniłem to poprawnie w obrazie. – Rama

+0

Na obrazie bieżące położenie pozostaje czerwoną płytką. Ponieważ czerwony kafelek jest prawy, jest wolny, mogę iść w prawo, ale graficznie nie mogę. – Rama

+0

@Rama: Nie jest jasne, co masz na myśli ... Jeśli MOŻESZ iść w prawo, to "dlaczego nie?" Po drugie, jeśli "graficznie" nie da się tego zrobić, to dane również strukturalnie nie powinny być dozwolone. Twój model wewnętrzny musi być dokładną reprezentacją Twojego widoku. Jeśli nie mogę pójść w prawo w modelu, nie powinienem mieć do tego prawa w widoku, a nie odwrotnie, ponieważ widok jest dziesiętnie zorientowany, by tak rzec, v.v.v.v. Czy mógłbyś wyjaśnić problem nieco bardziej, jeśli nie zrozumiałem go poprawnie? – PhD

1

Spróbowałbym zachować część logiczną (do której należy gracz) i część wizualizacji (animacja między płytkami) jako oddzielne, jak to możliwe. Moje podejście byłoby mieć logiczną lokalizację (dachówka odtwarzacz jest ustawiony na) i prędkość poruszania się (co w zasadzie oznacza ilość czasu gracz nie może przejść do następnej płytki po przeprowadzce do płytki). Następnie animacja z jednej płytki na drugą oznaczałoby, że ikonka jest zawsze w kierunku współrzędnych ekranu z płytek - czas trwa to może z łatwością być określona przez szybkość ruchu (jeden pełny ruch płytki powinny podjąć tak długo, jak gracz musi spoczywaj na bieżącym kafelku).

Jedynym specjalnym przypadkiem byłoby "odwrócenie się", w którym gracz mógłby wrócić do kafelka, z którego przybył, w dowolnym momencie, biorąc tylko (timeToRecoverOnTile - (timeToRecoverOnTile - timeSinceMovementStarted)).

1

ja kiedyś w zasadzie to samo w AS3, ale transfery koncepcja Java. Postanowiłem stworzyć dwie główne wartości, aby pomóc śledzić ruch, Punkt zawierający wartość x/y gracza (przez kafelek) i kierunek Kierunek ruchu. Oto niektóre pseudo-code:

if(direction.x == 0 && direction.x == 0) { 
    if (up) direction.y = -1; 
    else if (down) direction.y = 1; 
    else if (left) direction.x = -1; 
    else if (right) direction.x = 1; 
} else { 
    player.x += direction.x; 
    player.y += direction.y; 
    distance--; 
    if(distance == 0) { 
     direction.x = direction.y = 0; 
     distance = tileWidth; 
    } 
} 

Oczywiście, trzeba by uszczypnąć, że do swoich potrzeb, ale to podstawy. Również tileWidth można zastąpić literałem całkowitym, który jest po prostu równy szerokości pojedynczego kafelka.

Powiązane problemy