我写了一个随机的地下城生成器,它给我这样的坐标(S =开始):
现在我想在JPane上打印我的坐标(或任何常见的坐标),但我不知道从哪里开始; - (
我看到我可以在JPane上绘制像矩形或三角形的东西,所以我 试图用我的控制台输出功能覆盖图形对象的paintComponent方法(除了我绘制而不是print()之外,它完全相同)
@Override
public void paintComponent (Graphics g) {
boolean tmpKoordinateExistiert = false;
boolean tmpSpielerKoordiante = false;
for(int y =0;y <=20; y++) {
for(int x = 0; x <=20; x++) {
if(this.sindKoordinatenEinTreffer(x,y,this.spielerKoordinaten.x,this.spielerKoordinaten.y)) {
tmpSpielerKoordiante = true;
}else {
for(Point p: this.koordinatenListe) {
if(this.sindKoordinatenEinTreffer(x,y,p.x,p.y)) {
tmpKoordinateExistiert = true;
}
}
}
if(tmpSpielerKoordiante) {
g.drawOval(x+10, y+10, 1, 1);
tmpSpielerKoordiante = false;
}else if(!tmpKoordinateExistiert) {
this.repaint();
}else {
g.drawRect(x+10, y+10, 1, 1);
tmpKoordinateExistiert = false;
}
}
System.out.println("");
}
}
我该怎么做才能改变它? (对不起,如果这是一个愚蠢的问题,但我坐在这里几个小时,我会盲目找到正确的解决方案)
如果我增加矩形/椭圆的大小,我得到: 整个地牢生成器类:
package de.projekt.dungeon;
import java.awt.Point;
import java.util.ArrayList;
import java.util.Random;
import de.projekt.gui.MiniMap;
import de.projekt.map.DungeonMap;
public class DungeonGenerator {
/**
* startposition des Dungeons
* Kann im Norden, Sueden, osten, Westen liegen (Random)
*/
private Point start;
private Point aktuelleKoordinaten;
/**
* Liste aller Dungeonfelder (bzw. die Koordinaten von denen)
*/
ArrayList<Point> koordinatenListe ;
public ArrayList<Point> getKoordinatenListe() {
return koordinatenListe;
}
public Point getStart() {
return start;
}
/**
* 0 = Norden, 1 = Westen, 2 = Sueden, 3 = Osten
*/
private int himmelsrichtung;
private Random rHimmelsrichtung;
private Random neueKoordinaten;
private int xFaktor = 0;
private int yFaktor = 0;
private Random tmpz = new Random();
/**
* Standardkonstruktor, es werden alles Objekte instanziert, die
* fuer den DungeonGenerator noetig sind.
*
* himmelsrichtung ergibt sich aus einer Zahl zwischen 0-4.
* Dadurch wird Random entschieden, an welcher Stelle der Dungeon startet.
* (N,S,O,W)
* Es wird fuer jeden Startpunkt ein Faktor gesetzt, mit dem im Generator die
* x/y Koordinate multipliziert wird. Dadurch wird sichergestellt, das man nicht im
* Osten startet, und der Dungeon dann in eben diese Richtung generiert wird.
*
* Der Startpunkt wird als erste Koordinate der KoordinatenListe hinzugefuegt.
* Anschliessend beginnt das generieren.
*
* Spaeter koennte man die Mapgroeße ueber das ueberladen des Konstruktors Variabel machen,
* Falls das dann Sinn ergibt.
*
* Jeder Dungeon (Stockwerk?) hat genau eine Map!
*/
public DungeonGenerator(int anzahlMaximalKoordinaten){
this.koordinatenListe = new ArrayList<Point>();
this.rHimmelsrichtung = new Random();
this.neueKoordinaten = new Random();
this.start = new Point();
this.himmelsrichtung = this.rHimmelsrichtung.nextInt(3);
switch(this.himmelsrichtung){
// Norden
case(0): this.start.x = 10;
this.start.y = 0;
this.yFaktor = 1;
break;
// Westen
case(1): this.start.x = 0;
this.start.y = 10;
this.xFaktor = 1;
break;
// Sueden
case(2): this.start.x = 10;
this.start.y = 20;
this.yFaktor = -1;
break;
// Osten
case(3): this.start.x = 20;
this.start.y = 10;
this.xFaktor = -1;
break;
}
koordinatenListe.add(this.start);
this.aktuelleKoordinaten = new Point(this.start);
this.startGenerate(anzahlMaximalKoordinaten);
}
/**
* Generiere den Dungeon und uebergebe den Dungeon(Koordinaten) an die Map.
* (Auch SpielerAnfangskoordinaten)
*/
private void startGenerate(int anzahlMaximalKoordinaten) {
this.generateDungeon(this.start.x, this.start.y, 0, anzahlMaximalKoordinaten);
}
/**
* Gebe das zu dem Dungeon gehoerige Mapobjekt zurueck.
* @return Rueckgabe der Map
*/
public DungeonMap getMap() {
return null;
//return map;
}
/**
* Hier werden die Koordinaten generiert.
*
* Derzeit werden y Koordinaten bevorzugt. (da X nur incr/decr wird, wenn Y == 0 --> Nur eine 50% Chance)
*
* Die Methode wird abgebrochen, sollte eine Wand erreicht werden.
* Die Methode ruft sich ansonsten sooft auf, bis die aktuelle Koordinatenmenge der Maximalen Koordinatenanzahl entspricht
*
* @param x aktuelle x Koordinate
* @param y aktuelle y Koordinate
* @param aktuelleKoordinatenMenge Wieviele Koordinaten umfasst der Dungeon derzeit
* @param anzahlMaximalKoordinaten Wieviele "Spielfelder(Koordinaten)" hat der Dungeon maximal
*/
private void generateDungeon(int x, int y,int aktuelleKoordinatenMenge, int anzahlMaximalKoordinaten) {
int tempX = 0;
int tempY = 0;
while(tempX == 0 && tempY== 0) {
tempX = this.neueKoordinaten.nextInt(2);
tempY = this.neueKoordinaten.nextInt(2);
}
// gehen wir evtl links oder rechts usw., mal sehen
int tmp = this.tmpz.nextInt(3)-1;
// Erlaube es, auf der X / Y Achse zurueckzugehen, fuer verzweigungen
if(this.yFaktor == -1){
this.xFaktor = tmp;
}
if(this.yFaktor == 1){
this.xFaktor = tmp;
}
if(this.xFaktor == -1){
this.yFaktor = tmp;
}
if(this.xFaktor == 1){
this.yFaktor = tmp;
}
// Wenn ich zuerst Nach Y abfrage, wird Y bevorzugt, wenn ich zuerst nach X abfrage halt X
// wenn ich einfach ein Random 0/1 vorklatsche, und nach 0 / 1 Abfrage, dann ist das Ergebniss
// nicht von zuerst X / Y abhaengig.
int randomRichtung = this.neueKoordinaten.nextInt(2);
if(randomRichtung == 0) {
if(tempY==1) {
y = y + (1 * this.yFaktor);
}else if(tempX == 1) {
x = x + (1 * this.xFaktor);
}
}else {
if(tempX==1) {
x = x + (1 * this.xFaktor);
}else if(tempY == 1) {
y = y + (1 * this.yFaktor);
}
}
// Anomalie, bin betrunken, forsche spaeter
if(x == -1)
x=0;
// lul?
if(y == -1)
y=0;
this.aktuelleKoordinaten = new Point(x,y);
//System.out.println("aktuelleKoordinaten: " +this.aktuelleKoordinaten);
this.koordinatenListe.add(this.aktuelleKoordinaten);
if((this.aktuelleKoordinaten.x == 20 && this.start.x !=20)
|| this.aktuelleKoordinaten.y == 20 && this.start.y !=20
|| this.aktuelleKoordinaten.x == 0 && this.start.x !=0
|| this.aktuelleKoordinaten.y == 0 && this.start.y !=0) {
return;
}
aktuelleKoordinatenMenge++;
if(aktuelleKoordinatenMenge <= anzahlMaximalKoordinaten) {
this.generateDungeon(x, y,aktuelleKoordinatenMenge, anzahlMaximalKoordinaten);
} else
return;
}
}
My Gui Class:
package de.projekt.gui;
import java.awt.BorderLayout;
import java.awt.Dimension;
import javax.swing.JFrame;
public class Gui extends JFrame{
MiniMap miau = new MiniMap();
private static final int N = 256;
public Gui() {
this.setSize(400,400);
this.setDefaultCloseOperation(EXIT_ON_CLOSE);
this.setLayout(new BorderLayout());
this.add(this.miau);
}
@Override
public Dimension getPreferredSize() {
return new Dimension(2 * N, 2 * N);
}
}
我的输出类:
package de.projekt.gui;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.Point;
import java.util.ArrayList;
import javax.swing.JPanel;
import de.projekt.dungeon.DungeonGenerator;
import de.projekt.map.DungeonMap;
public class MiniMap extends JPanel{
private ArrayList<Point> koordinatenListe ;
private Point spielerKoordinaten;
private DungeonGenerator map;
MiniMap(){
this.map = new DungeonGenerator(400);
this.spielerKoordinaten = this.map.getStart();
this.koordinatenListe = this.map.getKoordinatenListe();
}
@Override
public void paintComponent (Graphics g) {
super.paintComponent(g);
boolean tmpKoordinateExistiert = false;
boolean tmpSpielerKoordiante = false;
for(int y =0;y <=20; y++)
{
for(int x = 0; x <=20; x++) {
if(this.sindKoordinatenEinTreffer(x,y,this.spielerKoordinaten.x,this.spielerKoordinaten.y)) {
tmpSpielerKoordiante = true;
}else {
for(Point p: this.koordinatenListe) {
if(this.sindKoordinatenEinTreffer(x,y,p.x,p.y)) {
tmpKoordinateExistiert = true;
}
}
}
if(tmpSpielerKoordiante) {
g.drawOval(x, y, 10, 10);
tmpSpielerKoordiante = false;
}else if(!tmpKoordinateExistiert) {
this.repaint();
}else {
g.drawRect(x+10, y+10, 10, 10);
tmpKoordinateExistiert = false;
}
}
System.out.println("test");
}
System.out.println("enhde");
}
public void setStartPunkt(Point startPunkt) {
this.spielerKoordinaten = startPunkt;
}
public ArrayList<Point> getKoordinatenListe() {
return koordinatenListe;
}
public void setKoordinatenListe(ArrayList<Point> koordinatenListe) {
this.koordinatenListe = koordinatenListe;
}
/**
* Da ein Koordinatenvergleich mindestens 2 mal gebraucht wird, in einer Methode
* @param x aktueller x Wert der Schleife
* @param y aktueller y Wert der Schleife
* @param koordx koordinaten vom Punkt
* @param koordy koordinaten vom Punkt
* @return
*/
private boolean sindKoordinatenEinTreffer(int x, int y, int koordx, int koordy) {
if(x == koordx && y == koordy) {
return true;
}else {
return false;
}
}
/**
* Erstmal nur eine Testausgabe usw. in der Konsole, halt bis wir GUI's haben
*/
public void printTest() {
}
}
答案 0 :(得分:3)
最小的渲染单位是一个像素,为了论证,它是一个1x1大小的小方块。
当渲染某些东西时,你需要让你的形状足够大,以便能够满足你的需求,是的,你可以使用一个像素,但是如果你像我一样并花了很多时间盯着屏幕,那么你'可能会失明,所以你可能想要一些更大的东西。
执行此操作时,您还需要偏移形状的位置,以便它不会覆盖其他被绘制的内容。
因此,例如,如果你有一个正方形是10x10,它是以10x20绘制的,那么下一个元素将需要在20x20处绘制在下一列中,或者10x30需要在下一行绘制,作为示例。
现在,我刚刚将迷宫/模型整合在一起,因为它基本上与问题无关,并展示了绘制列和信息行的概念。
import java.awt.Color;
import java.awt.Dimension;
import java.awt.EventQueue;
import java.awt.Graphics;
import java.awt.Graphics2D;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.UIManager;
import javax.swing.UnsupportedLookAndFeelException;
public class Test {
public static void main(String[] args) {
new Test();
}
public Test() {
EventQueue.invokeLater(new Runnable() {
@Override
public void run() {
try {
UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
} catch (ClassNotFoundException | InstantiationException | IllegalAccessException | UnsupportedLookAndFeelException ex) {
ex.printStackTrace();
}
JFrame frame = new JFrame("Testing");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.add(new TestPane());
frame.pack();
frame.setLocationRelativeTo(null);
frame.setVisible(true);
}
});
}
public static class TestPane extends JPanel {
private String[] maze = {
"..........#S##........",
"..........##.#........",
"...........#.#........",
".............#........",
".....##......#........",
"....#####.###.........",
"#####.###.#####.......",
"....###.########......",
"......####.####.......",
"......####..###.......",
"......#####..###......",
"......#####...##......",
"......######..........",
".......######.........",
".......######.........",
".......#######........",
"........#######.......",
"........###...........",
"........###...........",
"......................",
};
protected static final int CELL_SIZE = 10;
public TestPane() {
setBackground(Color.DARK_GRAY);
}
@Override
public Dimension getPreferredSize() {
return new Dimension(22 * CELL_SIZE, 21 * CELL_SIZE);
}
protected void paintComponent(Graphics g) {
super.paintComponent(g);
Graphics2D g2d = (Graphics2D) g.create();
int y = 0;
for (String line : maze) {
int x = 0;
for (char element : line.toCharArray()) {
switch (element) {
case '.':
paintSpace(g2d, x, y);
break;
case '#':
paintHash(g2d, x, y);
break;
case 'S':
paintStart(g2d, x, y);
break;
}
x += CELL_SIZE;
}
y += CELL_SIZE;
}
g2d.dispose();
}
protected void paintSpace(Graphics2D g2d, int x, int y) {
g2d.setColor(Color.DARK_GRAY);
g2d.fillRect(x, y, CELL_SIZE, CELL_SIZE);
}
protected void paintHash(Graphics2D g2d, int x, int y) {
g2d.setColor(Color.LIGHT_GRAY);
g2d.fillRect(x, y, CELL_SIZE, CELL_SIZE);
}
protected void paintStart(Graphics2D g2d, int x, int y) {
g2d.setColor(Color.LIGHT_GRAY);
g2d.fillRect(x, y, CELL_SIZE, CELL_SIZE);
g2d.setColor(Color.RED);
g2d.fillOval(x, y, CELL_SIZE, CELL_SIZE);
}
}
}
现在,如果你需要一些不以线性方式维护的东西,或者需要随机更新它的某些部分。您需要将模型坐标转换为物理坐标。
基于上面的例子,如果我想要在第5行第15列绘制一个元素,我只需要通过CELL_SIZE
多个这两个点来给我物理坐标
答案 1 :(得分:0)
MadProgrammer的解决方案(但我的代码):
@Override
public void paintComponent (Graphics g) {
super.paintComponent(g);
Graphics2D g2d = (Graphics2D) g.create();
boolean tmpKoordinateExistiert = false;
boolean tmpSpielerKoordiante = false;
int shapesizeY = 0;
for(int y =0;y <=20; y++) {
int shapesizeX = 0;
for(int x = 0; x <=20; x++) {
if(this.sindKoordinatenEinTreffer(x,y,this.spielerKoordinaten.x,this.spielerKoordinaten.y)) {
tmpSpielerKoordiante = true;
}else {
for(Point p: this.koordinatenListe) {
if(this.sindKoordinatenEinTreffer(x,y,p.x,p.y)) {
tmpKoordinateExistiert = true;
}
}
}
if(tmpSpielerKoordiante) {
paintStart(g2d, shapesizeX, shapesizeY);
tmpSpielerKoordiante = false;
}else if(!tmpKoordinateExistiert) {
paintSpace(g2d, shapesizeX, shapesizeY);
}else {
paintHash(g2d, shapesizeX, shapesizeY);
tmpKoordinateExistiert = false;
}
shapesizeX += CELL_SIZE;
}
shapesizeY += CELL_SIZE;
}
}
protected void paintSpace(Graphics2D g2d, int x, int y) {
g2d.setColor(Color.DARK_GRAY);
g2d.fillRect(x, y, CELL_SIZE, CELL_SIZE);
}
protected void paintHash(Graphics2D g2d, int x, int y) {
g2d.setColor(Color.LIGHT_GRAY);
g2d.fillRect(x, y, CELL_SIZE, CELL_SIZE);
}
protected void paintStart(Graphics2D g2d, int x, int y) {
g2d.setColor(Color.LIGHT_GRAY);
g2d.fillRect(x, y, CELL_SIZE, CELL_SIZE);
g2d.setColor(Color.RED);
g2d.fillOval(x, y, CELL_SIZE, CELL_SIZE);
}
非常感谢,先生!