Du bist nicht angemeldet.

Stilllegung des Forums
Das Forum wurde am 05.06.2023 nach über 20 Jahren stillgelegt (weitere Informationen und ein kleiner Rückblick).
Registrierungen, Anmeldungen und Postings sind nicht mehr möglich. Öffentliche Inhalte sind weiterhin zugänglich.
Das Team von spieleprogrammierer.de bedankt sich bei der Community für die vielen schönen Jahre.
Wenn du eine deutschsprachige Spieleentwickler-Community suchst, schau doch mal im Discord und auf ZFX vorbei!

Werbeanzeige

Loha

Frischling

  • »Loha« ist der Autor dieses Themas
  • Private Nachricht senden

1

25.07.2015, 11:06

SFML View

Hallo,

Ich beschäftige mich seit 2Wochen mit SFML und habe jetzt eine Frage zur Kamerasteuerung.
Mein Problem war wie ich es anstelle dass die Kameraansicht nicht über den Rand meiner Tilemap geht wobei die Kamera meinen Sprite verfolgen soll.
Nach einigen Überlegungen hab ich eine Kollisionsabfrage erstellt mit der es auch funktioniert, die aber recht umfangreich geworden ist.
Nun ist meine Frage ob man das alles nicht auch einfacher und eleganter lösen kann.

Danke im Voraus :thumbup:
Mfg Loha


Tilemap Größe: 1000 * 800,
Fenster und View Größe: 800 * 600,
Tile Größe: 50 * 50,

C-/C++-Quelltext

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
                if (Sprite.getPosition().x < view.getSize().x / 2 && Sprite.getPosition().y > MapHeight * 50 - (view.getSize().y / 2))
                {
                    view.setCenter(view.getSize().x / 2, MapHeight * 50 - (view.getSize().y / 2));
                }
                else if (Sprite.getPosition().x > MapWidth * 50 - (view.getSize().x / 2) && Sprite.getPosition().y > MapHeight * 50 - (view.getSize().y / 2))
                {
                    view.setCenter(MapWidth * 50 - (view.getSize().x / 2), MapHeight * 50 - (view.getSize().y / 2));
                }
                else if (Sprite.getPosition().x < view.getSize().x / 2 && Sprite.getPosition().y < view.getSize().y / 2)
                {
                    view.setCenter(view.getSize().x / 2, view.getSize().y / 2);
                }
                else if (Sprite.getPosition().x > MapWidth * 50 - (view.getSize().x / 2) && Sprite.getPosition().y < view.getSize().y / 2)
                {
                    view.setCenter(MapWidth * 50 - (view.getSize().x / 2), view.getSize().y / 2);
                }
                else if (Sprite.getPosition().x < view.getSize().x / 2 && Sprite.getPosition().y > view.getSize().y / 2)
                {
                    view.setCenter(view.getSize().x / 2, Sprite.getPosition().y);
                }
                else if (Sprite.getPosition().x > view.getSize().x / 2 && Sprite.getPosition().y > MapHeight * 50 - (view.getSize().y / 2))
                {
                    view.setCenter(Sprite.getPosition().x, MapHeight * 50 - (view.getSize().y / 2));
                }
                else if (Sprite.getPosition().x > MapWidth * 50 - (view.getSize().x / 2) && Sprite.getPosition().y > view.getSize().y / 2)
                {
                    view.setCenter(MapWidth * 50 - (view.getSize().x / 2), Sprite.getPosition().y);
                }
                else if (Sprite.getPosition().x > view.getSize().x / 2 && Sprite.getPosition().y < view.getSize().y / 2)
                {
                    view.setCenter(Sprite.getPosition().x, view.getSize().y / 2);
                }
                else
                {
                    view.setCenter(Sprite.getPosition()); 
                }

BlueCobold

Community-Fossil

Beiträge: 10 738

Beruf: Teamleiter Mobile Applikationen & Senior Software Engineer

  • Private Nachricht senden

2

25.07.2015, 11:13

Ohne jeden jeden einzelnen Fall analysiert zu haben, der da ausgeschrieben steht, das geht sicher auch anders, ja. Dazu müsste man allerdings erstmal wissen nach welchen Kriterien Du die Bewegung des Views einschränken möchtest. (und nein, ich lese mir nicht alle Fälle durch, um es heraus zu finden ;) )
Teamleiter von Rickety Racquet (ehemals das "Foren-Projekt") und von Marble Theory

Willkommen auf SPPRO, auch dir wird man zu Unity oder zur Unreal-Engine raten, ganz bestimmt.[/Sarkasmus]

Loha

Frischling

  • »Loha« ist der Autor dieses Themas
  • Private Nachricht senden

3

25.07.2015, 11:38

Also die Kriterien sind das die Kamera dem Sprite folgt und nicht die Ränder der Tilemap überschreitet, wenn ich deine Frage richtig verstanden habe.
Das du mir nochmal bestätigst dass es auch anders geht hilft mir leider auch nicht weiter :D
Trotzdem danke für die Antwort

BlueCobold

Community-Fossil

Beiträge: 10 738

Beruf: Teamleiter Mobile Applikationen & Senior Software Engineer

  • Private Nachricht senden

4

25.07.2015, 11:41

Nun, dann würde ich sowas machen wie:
ViewCenter = Max(LeftUpper + ViewSize/2, Min(RightLower - ViewSize/2, SpriteCenter))
Teamleiter von Rickety Racquet (ehemals das "Foren-Projekt") und von Marble Theory

Willkommen auf SPPRO, auch dir wird man zu Unity oder zur Unreal-Engine raten, ganz bestimmt.[/Sarkasmus]

Loha

Frischling

  • »Loha« ist der Autor dieses Themas
  • Private Nachricht senden

5

25.07.2015, 11:47

Ich werds ausprobieren, danke

Loha

Frischling

  • »Loha« ist der Autor dieses Themas
  • Private Nachricht senden

6

25.07.2015, 12:14

Habs mir angeguckt aber werde echt nicht schlau daraus bzw weiß nicht wie genau ich es umsetzen soll ?(
kannst du es genauer erklären oder hat noch jemand einen Tipp?

BlueCobold

Community-Fossil

Beiträge: 10 738

Beruf: Teamleiter Mobile Applikationen & Senior Software Engineer

  • Private Nachricht senden

7

25.07.2015, 12:24

Das ist einfache Mathematik.
Anders ausgedrückt: Der View soll zentriert im Sprite liegen. Allerdings muss die linke obere Ecke des Views immer größere (oder gleiche) Koordinaten haben als die linkere obere Ecke der Map. Andererseits darf die rechte untere Ecke des Views nur Koordinaten kleiner oder gleich der rechten unteren Ecke der Map haben. Genau das steht in meinem Code.
Teamleiter von Rickety Racquet (ehemals das "Foren-Projekt") und von Marble Theory

Willkommen auf SPPRO, auch dir wird man zu Unity oder zur Unreal-Engine raten, ganz bestimmt.[/Sarkasmus]

Loha

Frischling

  • »Loha« ist der Autor dieses Themas
  • Private Nachricht senden

8

25.07.2015, 12:50

Ich habe den Sinn deines Codes schon verstanden bloß wie gesagt weiß ich nicht wie ich den umsetze (ich bin echt ein Neuling noch :D )
Was ist Max und Min? meinst du fmax? oder sind das Variablen die ich vorher festlegen muss?
oder ViewSize / 2, muss ich ViewSize auch vorher festlegen? weil view.getSize() / 2 geht ja nicht ich muss x oder y angeben.

TrommlBomml

Community-Fossil

Beiträge: 2 117

Wohnort: Berlin

Beruf: Software-Entwickler

  • Private Nachricht senden

9

25.07.2015, 13:02

Vielleicht kann man den Algorithmus so etwas leichter formulieren: deine Position der Kamera soll idealerweise der Position deines Sprites entsprechen, dem du folgst. Da du weißt, wie groß deine Tilemap und dein Viewport ist, musst du die Position der Kamera einfach den Differenzbereich begrenzen. Dazu mal folgende Rechnung bezogen auf deine Werte da oben:

1) Tilemap geht z.b. von 0,0 bis 999, 799 -> Größe 1000x800 px.
2) dein Viewport hat eine Größe von 800x600px. Wir beziehen uns bei dem View auf das Zentrum als 0,0.

Somit ergibt ergibt sich als maximale X-Verschiebung deines View-Center 1000px - 800px = 200px. Da du nach Links und Rechts gleich viel verschieben kannst, also um -100px und 100px bezogen auf Zentrum der Tilemap. Daraus ergibt sich folgene Minimun/Maximum als Center für deinen View bezogen auf die Tilemap: 500px - 100px = 400, 500px + 100px = 600: Also den View darf in X-Richtung maximal den Wert 600 und muss mindestens den Wert 400 haben. Nennen wir diese Werte minCameraX und maxCameraX;

Wenn du diesen Wert jetzt zusammen mit der Spriteposition relativ zur Tilemap beschreibst, kannst du einfach mit std::min und std::max arbeiten

C-/C++-Quelltext

1
float cameraCenterX = std::min(maxCameraX, std::max(minCameraX, sprite.getX());


Dadurch setzt du CameraCenterX auf die X-Position deines Sprite. Falls die genannten Grenzen über- oder unterschritten werden, so werden die Grenzwerte verwendet. Selbiges machst du für Y. Damit kannst du dann ja dein ViewCenter setzen.

Hoffe, das war irgendwie verständlich.

Dieser Beitrag wurde bereits 1 mal editiert, zuletzt von »TrommlBomml« (25.07.2015, 18:48)


Loha

Frischling

  • »Loha« ist der Autor dieses Themas
  • Private Nachricht senden

10

25.07.2015, 13:13

Ich danke dir, jetzt hab ichs verstanden :thumbsup:
std::min und std::max kannte ich noch nicht

Werbeanzeige

Ähnliche Themen