Java JavaFX - Canvas darstellung der Grafik funktioniert nicht wie gewollt

SparkMonkay

Commander
Registriert
Feb. 2013
Beiträge
2.337
Moinsen,

ich bin mit meinen Klausuren durch und hatte vor etwas kleines zu programmieren, da kam ich auf die Idee ein kleines Spiel zu programmieren.
Aktuell sitze ich an der Grafik wie der Titel es schon sagt. Wir haben folgendes Szenario: Ich bin auf einer Karte mit der Breite X und der Höhe Y un mein Mänchen darf sich von (0,0) bis (X,Y) frei durch das Teil bewegen. Jedoch wenn ich zu nah an die Ränder gege bekomme ich ArrayOutOfBounds Exceptions ab. Somit kam ich auf die Idee für die Ecken und Kanten eigene Zeichen-Methoden zu schreiben, damit ich das umgehe.

Aktuell habe ich die für die obere linke Ecke aber die obere Kante will mir nicht gelingen, geschweige denn eine anderen Ecken. Ich weiß nicht warum, ich sitze an einer Ecke bzw. Kante schon über einer Stunde, vielleicht sieht jemand den Fehler.

Hier der Teil meines Programms:
Code:
 public void drawFields(GraphicsContext gc)
      {
            //grenzen für die Schleifen es werden 40 Elemente in der horizontalen und 26 in der vertikalen gezeichnet
            int limitX=player.x+20;
            int limitY=player.y+13;
            
            //Die Variablen für die Position der Elemente auf den Bildschirmen
            int grapX=0;
            int grapY=0;

            //draw center of map
            if( (player.x - 20) >= 0 && (player.x + 20) <= x && (player.y - 13) >= 0 && (player.y + 13) <= y)
            {
                  for (int countX = player.x - 20; countX < limitX; countX++)
                  {
                        for (int countY = player.y - 13; countY < limitY; countY++)
                        {
                              gc.drawImage(map[countX][countY][0].image, grapX, grapY);
                              grapY += 32;
                        }
                        grapY = 0;
                        grapX += 32;
                  }
                  //der Spieler
                  gc.drawImage(player.image, (1280 / 2), (800 / 2), 32, 64);
            }

            //TOP LEFT CORNER
            else if( player.x < 19 && player.y < 14)
            {
                  for( int countX=0; countX< 40; countX++)
                  {
                        for( int countY=0; countY<26; countY++)
                        {
                              gc.drawImage(map[countX][countY][0].image, grapX, grapY);
                              grapY += 32;
                        }
                        grapY =0;
                        grapX += 32;
                  }

                  gc.drawImage(player.image, player.x*32, player.y*32, 32, 64);
            }

            //TOP RIGHT CORNER
            else if( player.x > x-20 && player.y < 14)
            {
                  for( int countX=limitX-20; countX< 40; countX++)
                  {
                        for( int countY=0; countY<26; countY++)
                        {
                              gc.drawImage(map[countX][countY][0].image, grapX, grapY);
                              grapY += 32;
                        }
                        grapY =0;
                        grapX += 32;
                  }

                  gc.drawImage(player.image, player.x*32, player.y*32, 32, 64);
            }
            //top
            else if( player.y > 14)
            {
                  for( int countX=player.x - 20; countX< limitX; countX++)
                  {
                        for( int countY=0; countY< 26; countY++)
                        {
                              gc.drawImage(map[countX][countY][0].image, grapX, grapY);
                              grapY += 32;
                        }
                        grapY =0;
                        grapX += 32;
                  }

                  gc.drawImage(player.image, 1280/2, player.y*32, 32, 64);
            }

      }

Ich weiß nicht, warum aber es werden nur die ersten beiden if-Abfragen bearbeitet, bzw. obwohl ich die bed. für die dritte if-Abfrage erfülle geht er nicht da rein...

Außerdem wenn es Verbesserungsvorschläge gibt, dann immer her damit :)
Ich bin mir etwas unsicher ob es so sein sollte, dass ich 9 if abfragen hier haben soll.

Danke für eure Hilfe!
 
Machs doch einfacherer...

if([player]+[move] > canvas.height){
}
if([player.location]+[move] < 0){
}

hoffe du verstehst was ich damit meine...
 
EDITED
@Lacritz
Also, ich habe ein Array aus dem ich das alles lade. Zeile 18 "map[...][...][0]....", das ist der Boden. jetzt mache ich es so, dass wenn ich halt die Grenzen im Bildschirm habe, soll in der Methode die Fläche anders gezeichnet werden.

Da mein Canvas 1280*800p groß ist lade ich aus dem Array nur das was ich brauche. Also ich lade in der breite 40 Elemente, denn 40*32=1280 und 26*32=832, ja die musste ich nehmen, damit ich beim Teilend durch 2 nicht plötzlich 11 habe, daher eins aufaddiert.

Wenn ich dich richtig verstehe verstehst du mich so dass ich alles gleichzeigt haben will, nein nicht so. Ich wollte es so wie in GoldenSun, Pokemon, Final Fantasy I, II ... machen. Vogelperspektive und du siehst nur einen Teil der Karte. Ich glaube man kann sich am meisten vorstellen was ich will wenn ich sage ich will eine Kameraführung wie in Pokemon (ältere Teile).
 
Zuletzt bearbeitet:
Zentriert also auf deinen Character? Dann bau dir eine Arraylist, und eine standart KartenGröße aus 500x500 oder sowas
 
Okay,

Ich habe es folgendermaßen gelöst bekommen.
Ich habe meine Map, mit X*Y in insgesamt 9 Zonen unterteilt
Code:
+-----+---------------------------+-----+
|     |           TOP             |     |
|     |                           |     |
+-----+---------------------------+-----+
|     |                           |     |
|     |                           |     |
|     |                           |     |
|  L  |                           | R   |
|     |                           |     |
|     |       CENTER              |     |
|     |                           |     |
|     |                           |     |
|     |                           |     |
|     |                           |     |
+-----+---------------------------+-----+
|     |       BOTTOM              |     |
|     |                           |     |
+-----+---------------------------+-----+
Der Code um das gescheit zu behandeln sieht so aus, der wurde auch in eine extra Klasse ausgelagert;
Code:
public void draw(GraphicsContext gc)
      {

            if( (map.player.x - 20) >= 0 && (map.player.x + 20) <= map.x && (map.player.y - 13) >= 0 && (map.player.y + 13) <= map.y)
                  drawCenter(gc);
            else if( map.player.x < 20 && map.player.y < 14)
                  drawTopLeftCorner(gc);
            else if( map.player.x > map.x-20 && map.player.y < 14)
                  drawTopRightCorner(gc);
            else if( map.player.x < 20 && map.player.y > map.y-14)
                  drawBottomLeftCorner(gc);
            else if( map.player.x > map.x-20 && map.player.y > map.y-14)
                  drawBottomRightCorner(gc);

            else if( map.player.y < 14)
                  drawTop(gc);
            else if( map.player.x <20)
                  drawLeft(gc);
            else if( map.player.y > map.x-14)
                  drawBottom(gc);
            else if( map.player.x > map.x-20)
                  drawRight(gc);

      }

      private void drawCenter(GraphicsContext gc)
      {
            int limitX=map.player.x+20;
            int limitY=map.player.y+13;

            int grapX=0;
            int grapY=0;

            for (int countX = map.player.x - 20; countX < limitX; countX++)
            {
                  for (int countY = map.player.y - 13; countY < limitY; countY++)
                  {
                        gc.drawImage(map.map[countX][countY][0].image, grapX, grapY);
                        grapY += 32;
                  }
                  grapY = 0;
                  grapX += 32;
            }
            gc.drawImage(map.player.image, (1280 / 2), (800 / 2), 32, 64);
      }

      private void drawTopLeftCorner(GraphicsContext gc)
      {
            int grapX=0;
            int grapY=0;

            for( int countX=0; countX< 40; countX++)
            {
                  for( int countY=0; countY<26; countY++)
                  {
                        gc.drawImage(map.map[countX][countY][0].image, grapX, grapY);
                        grapY += 32;
                  }
                  grapY =0;
                  grapX += 32;
            }

            gc.drawImage(map.player.image, map.player.x * 32, map.player.y * 32, 32, 64);
      }

      private  void drawBottomLeftCorner(GraphicsContext gc)
      {
            int grapX=0;
            int grapY=0;

            for( int countX=0; countX< 40; countX++)
            {
                  for( int countY=map.x-26; countY<map.x; countY++)
                  {
                        gc.drawImage(map.map[countX][countY][0].image, grapX, grapY);
                        grapY += 32;
                  }
                  grapY =0;
                  grapX += 32;
            }
           
            int playerY = (map.y-map.player.y)*(-32);
            gc.drawImage(map.player.image, map.player.x *32, playerY+816, 32, 64);
      }

      private void drawTopRightCorner(GraphicsContext gc)
      {
            int grapX=0;
            int grapY=0;

            for( int countX=map.x-40; countX<map.x; countX++)
            {
                  for( int countY=0; countY<26; countY++)
                  {
                        gc.drawImage(map.map[countX][countY][0].image, grapX, grapY);
                        grapY += 32;
                  }
                  grapY =0;
                  grapX += 32;
            }
         
            int playerX = (map.player.x - map.x) * (32);
            gc.drawImage(map.player.image, playerX+1280 ,map.player.y*32 ,32 , 64);
      }

      private void drawBottomRightCorner(GraphicsContext gc)
      {
            int grapX=0;
            int grapY=0;

            for( int countX=map.x-40; countX<map.x; countX++)
            {
                  for( int countY=map.x-26; countY<map.x; countY++)
                  {
                        gc.drawImage(map.map[countX][countY][0].image, grapX, grapY);
                        grapY += 32;
                  }
                  grapY =0;
                  grapX += 32;
            }
            int playerX = (map.player.x - map.x) * (32);
            int playerY = (map.player.y-map.y)*32;
            gc.drawImage(map.player.image, playerX+1280 ,playerY+832 ,32 , 64);
      }
Soweit kommt mein Char auch "fließend" von einen Bereich in den anderen ohne irgendwelche Sprünge zu machen, die durch die fehlenden 16 Pixel zustande kamen.

Ich müsste nur noch die if-Abfragen oben etwas besser optimieren und die Zahlen die so oft vorkommen gegen Variablen tauschen.

@Lacritz
Eine ArrayList währe zwar auch eine Idee aber ich habe hier ein Array welches ich als ein 2-Dimensionales behandel mit quasi 2 Ebenen, da kam es mir etwas unpraktisch vor, vor allem dass ich immer weiß wie groß das Teil sein soll. Oder war dein Vorschlag zu der ArrayList wirklich nur auf den Teil bezogen der im Endeffekt auf den Bildschirm kommt?
 
Nein der Vorschlag war auf alle deine Karten bezogen, das deine normale Karte begrenzt ist hatte ich mir gedacht. Ich habe nach wie vor das Gefühl das es hier recht kompliziert ist, obwohl es hätte einfacherer werden können. Da ich aber ehrlich gesagt nach wie vor nicht zu 100% verstehe kann ich da leider nicht helfen..

Was ich meine ist, Mann kam das Feld vorher einfach in Große Abschnitte unterteilen und den Charakter dort entlang führen, die dran Methode würde sich dann die x und y Koordinaten über dieses Feld errechnen.

Falls du Hilfe brauchst , oder einfach etwas darüber sprechen willst kannst du dich gerne melden!
 
Zurück
Oben