Isometrisches Spielfeld die 2te

Neue Frage »

Auf diesen Beitrag antworten »
Tommy1234 Isometrisches Spielfeld die 2te

Hallo,

hab mich mit Transformationen im Grafischen Bereich von Java eingelesen und möchte nun folgendes in Anlehnung an einen früheren Post von mir machen:

Zuerst erzeuge ich ein aus 10x10 Feldern bestehendes Spielfeld als zweidimensionales Rechteckarray.
bestehendes Spielfeld.

In meiner Zeichenmethode transformiere ich zuerst das Koordinatensystem so wie man es in der Schule hatte ( also erster Quadrant ).

Anschließend erzeuge ich eine Rotation und eine Skalierung mittels AffineTransform() und wende die fertige dann auf das Spielfeld an.

Zuletzt nun meine Frage:

Was muss man tun, wenn man erreichen möchte, dass wenn man ein Feld anklickt die richtige Kachel ausgegeben wird?

In meinem letzten Post hat ein sehr fitter Mensch mir eine Formel geliefert, wofür ich auch dankbar bin. Jetzt da ich ein wenig über Transformationen weiß, habe ich mir folgendes gedacht:

Man könnte doch auch einfach die Kachel im ungedrehten Zustand berechnen lassen und diese dann anschließend wieder drehen, sodass , wenn man auf eine Kachel des Isometrischen Spielfeldes klickt eig. die orthogonale Variante berechnet wird aber dennoch das entsprechende isometrische Feld angezeigt wird.

Falls jemand dazu eine Lösung weiß bitte melden, denn bei der Umsetzung harperts noch ziemlich. Zwar kann ich die gängigen Transformationen auf 2-dimensionale Körper anwenden aber die Reihenfolge der einzelnen Transformationen bereitet mir Kopfzerbrechen.


MfG

Tommy
 
Auf diesen Beitrag antworten »
Tommy1234

Noch ein kleiner Nachtrag:

Wahrscheinlich hat das mit der Mausposition zu tun, denn die ist ja auf dem isometrischen Spielfeld eine andere als auf dem untransformierten. Wenn man da eine inverse Form braucht weiss ich allerdings nicht wie man diese auf das gesamte Spielfeld anwendet.
Auf diesen Beitrag antworten »
eulerscheZahl

Nur mal, dass ich das richtig verstehe: du bist an der Funktion zur Umrechnung mittels verketteter Transformationen interessiert?

Blau: Koordinaten in Java, schwarz dein Koordinatensystem. Die Frage zielt vor allem auf [latex]f^{-1}(x',y')[/latex] ab.
falls du [latex]f(x,y) = t_n(\dots (t_2(t_1(x,y))))[/latex] schon hast: die Transformationen der Reihe nach invertieren und die Reihenfolge umkehren: [latex]f^{-1}(x',y') = t_1^{-1}(t_2^{-1}(\dots(t_n^{-1}(x',y'))))[/latex].

Entschuldigung übrigens, dass ich deine Anfragen hier öfter mal ignoriere. Das ist einfach eine Zeitfrage. Wenn jemand eine Dezimalzahl in binär schreiben will, muss ich nicht lange überlegen, bei dir wird es meist aufwendiger.
Auf diesen Beitrag antworten »
Tommy1234

hhhhh, und ich hab ewig nichts gepostet weil ich dachte ich geh den leuten aufn sack hhhhh

Also zurück zum Thema:

Ja ich bin daran interessiert.

Nun muss man also sowohl die Rotation, als auch die Skalierung invertieren und das ganze dann mittels inverser Matrix abbilden hab ich das richtig verstanden?

mFg

Tommy
 
Auf diesen Beitrag antworten »
Tommy1234

Ach ja, wie heißt den die Funktion in Java für die inverse Matrix, denn es gibt da zwei die eine möchte Double Arrays die andere 2 Punkte?
Auf diesen Beitrag antworten »
eulerscheZahl

Was die Java Bibliothek hergibt, weiß ich auch nicht ohne Recherche.
Eben mal reingeschaut: es gibt ein concatenate, mit dem du mehrere verknüpfen kannst.
Mit inverseTransform(Point2D ptSrc, Point2D ptDst) sollte für die Rücktransformation genügen (die Überladung mit Arrays rechnet mehrere Punkte gleichzeitig um, die hast aber nur einen Mauszeiger).

Falls du trotzdem wissen willst, was passiert: die letzte Transformation (also t1 in meiner Formel) wird invertiert. Wenn du das auf den Punkt anwendest, erhältst du einen neuen Punkt. Auf diesen wendest du die inverse von t2 an. Und so weiter.
Auf diesen Beitrag antworten »
Tommy1234

Jetzt muss ich doch nochmal fragen:

Zum einen wird das Feld ja gemalt und zum anderen wird das Feld berechnet.

Hier mal mein Code für die Zeichen Methode:
code:
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:
public void paintField(Graphics g){
		
		Graphics2D g2 = (Graphics2D) g;
                //Das Koordinatensystem auf den ersten Quadranten legen
                AffineTransform at = new AffineTransform();
		at.setToScale(1, -1);
		AffineTransform translate = new AffineTransform();
		translate.setToTranslation(1,480-1);
		at.preConcatenate(translate);
		g2.transform(at);
                //die Rotation
		rotation = new AffineTransform();
		rotation.setToRotation(Math.toRadians(45));
                scale = new Affine Transform();
                scale.setToScale(2,1);
                rotation.preConcatenate(scale);
		
		int mx = Mouse.mousex;
		int my = Mouse.mousey;
		
                //die Rotation auf das Shapeobjekt anwenden und zeichnen
                 
		for(int i = 0; i < 10; i++){
			for(int j = 0; j < 10; j++){
			Shape trans = rotation.createTransformedShape(field[i][j]);
			g2.draw(trans);	
			}
		}


Wenn ich jetzt die inverse Form berechnen will brauche ich also:

Point2D p = Rotation.inverseTransform(new Point(mx,my),null); // ??????
Auf diesen Beitrag antworten »
eulerscheZahl

Könntest du bitte immer gleich so viel Code mit angeben, dass ich das in Eclipse reinkopieren und direkt ausführen kann, ohne noch eine GUI und einen MouseListener ergänzen zu müssen?
Das reduziert meinen Arbeitsaufwand und erhöht deine Aussichten auf eine Antwort.

Muss nicht das komplette Programm sein, falls du das nicht veröffentlichen willst oder es zu umfangreich ist. Aber lauffähig sollte es schon sein.
Auf diesen Beitrag antworten »
Tommy1234

Hier der Code:
code:
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:
37:
38:
39:
40:
41:
42:
43:
44:
45:
46:
47:
48:
49:
50:
51:
52:
53:
54:
55:
56:
57:
58:
59:
60:
61:
62:
63:
64:
65:
66:
67:
68:
69:
70:
71:
72:
73:
74:
75:
76:
77:
78:
79:
80:
81:
82:
83:
84:
85:
86:
87:
88:
89:
90:
91:
92:
93:
94:
95:
96:
97:
98:
99:
100:
101:
102:
103:
104:
105:
106:
107:
108:
109:
110:
111:
112:
113:
114:
115:
116:
117:
118:
119:
120:
121:
122:
123:
124:
125:
126:
127:
128:
129:
130:
131:
132:
133:
134:
135:
136:
137:
138:
139:
140:
141:
142:
143:
144:
145:
146:
147:
148:
149:
150:
151:
152:
153:
154:
155:
156:
157:
158:
159:
160:
161:
162:
163:
164:
165:
166:
167:
168:
169:
170:
171:
172:
173:
174:
175:
176:
177:
178:
179:
180:
181:
182:
183:
184:
185:
186:
187:
188:
189:
190:
191:
192:
193:
194:
195:
196:
197:
198:
199:
200:
201:
202:
203:
204:
205:
206:
207:
208:
209:
package main;

import java.awt.Canvas;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.image.BufferStrategy;

import javax.swing.JFrame;

public class Game extends Canvas implements Runnable{

	private static final long serialVersionUID = 1L;
	
	private JFrame frame;
	private Thread thread;
	private Level level;
	
	public Game(int WIDTH,int HEIGHT) {
		
		level = new Level();
		
		this.addMouseListener(new Mouse());
		this.setFocusable(true);
		
		frame = new JFrame("Game");
		frame.add(this);
		frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
		frame.setSize(WIDTH,HEIGHT);
		frame.setLocationRelativeTo(null);
		frame.setVisible(true);
	}
	
	public void start(){
		thread = new Thread(this);
		thread.start();
	}
	
	public void paint(){
		BufferStrategy bs = this.getBufferStrategy();
        if(bs == null){
            this.createBufferStrategy(3);
            return;
        }
        Graphics g = bs.getDrawGraphics();
        Graphics2D g2 = (Graphics2D) g;
        		
        
        g2.clearRect(0,0,getWidth(),getHeight());
        
        level.paintField(g2);
        //level.update();
        
        g2.dispose();
        bs.show();
	}

	@Override
	public void run() {
		
		int MILLIS = 33;
		float fps;
		try{
			while(true){
				long startTime = System.currentTimeMillis();
				paint();
		        long stopTime = System.currentTimeMillis()-startTime;
		        if(stopTime < MILLIS){
					Thread.sleep(MILLIS-stopTime);
		           	fps = 1000/MILLIS;
		           	frame.setTitle("FPS :  |  " + fps);
		        }
		        else{
		          	fps = (int) (1000/stopTime);
		           	frame.setTitle("FPS :  |  " + fps);
		        }
			}
		} catch (InterruptedException e) {e.printStackTrace();}
		
	}

	public static void main(String[] args) {
		
		Game game = new Game(928,496);
		game.start();
		
	}
}


package main;

import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.Point;
import java.awt.Rectangle;
import java.awt.Shape;
import java.awt.geom.AffineTransform;
import java.awt.geom.NoninvertibleTransformException;
import java.awt.geom.Point2D;

public class Level {

	private Shape[][] field;
	
	private AffineTransform rotation,rotation1;
	private AffineTransform scale,scale1;
	
	public Level() {
		
		field = new Shape[15][15];
		for(int i = 0; i < 10; i++){
			for(int j = 0; j < 10; j++){
				field[i][j] = new Rectangle(i*32,j*32,32,32);
			}
		}
	}

	public void update(){
		
		
		
		AffineTransform at = new AffineTransform();
		at.setToScale(1, -1);
		AffineTransform translate = new AffineTransform();
		translate.setToTranslation(1,480-1);
		at.preConcatenate(translate);
		
		
		
	}
	
	public void paintField(Graphics g){
		
		Graphics2D g2 = (Graphics2D) g;
		
		AffineTransform at = new AffineTransform();
		at.setToScale(1, -1);
		AffineTransform translate = new AffineTransform();
		translate.setToTranslation(1,480-1);
		at.preConcatenate(translate);
		g2.transform(at);

		rotation = new AffineTransform();
		rotation.setToRotation(Math.toRadians(45));
		
		int mx = Mouse.mousex;
		int my = Mouse.mousey;
		
		int tilex = (mx-(mx%32))/32;
		int tiley = (my-(my%32))/32;
		
		rotation1 = new AffineTransform();
		rotation1.setToRotation(Math.toRadians(45));
		rotation1.preConcatenate(at);
		
		try {
			Point2D p = rotation1.inverseTransform(new Point(tilex,tiley),new Point(mx,my));
		} catch (NoninvertibleTransformException e) {e.printStackTrace();}
		
		for(int i = 0; i < 10; i++){
			for(int j = 0; j < 10; j++){
				Shape trans = rotation1.createTransformedShape(field[i][j]);
				g2.draw(trans);	
			}
		}
		
		System.out.println(tilex + "     " + tiley);
		
		
	}

}

package main;

import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;

public class Mouse extends MouseAdapter{

	public static int mousex;
	public static int mousey;
	public static boolean right;
	
	@Override
	public void mouseReleased(MouseEvent e) {
		
		mousex = e.getX();
		mousey = e.getY();
	
		if(e.getButton()==MouseEvent.BUTTON1){
			right = false;
		}
	}
	
	@Override
	public void mouseClicked(MouseEvent e) {
		
		mousex = e.getX();
		mousey = e.getY();
	
		if(e.getButton()==MouseEvent.BUTTON1){
			right = true;
		}
	}

}



Es sind 3 Klassen im package main. MapLooader kannst du erstmal übergehen.
Auf diesen Beitrag antworten »
Tommy1234

In Zeile 145 muss noch die Skalierung rein :

scale = new AffineTransform();
scale.setToScale(2,1);
rotation.preConcatenate(scale);

und bei der Erzeugung der Rechtecke:

also bei new Rectangle( i * 32 + 174,j * 32 -144,32,32);

das wars.
Auf diesen Beitrag antworten »
Tommy1234

und bei trans rotation statt rotation1.
das wars aber jetzt.
Auf diesen Beitrag antworten »
eulerscheZahl

Zitat:
bei new Rectangle( i * 32 + 174,j * 32 -144,32,32);

und wo soll dieses new Rectangle sein?

Aktuell sehe ich die rechte Hälfte eines um 90° gedrehten, nicht gestauchten Gitters (also Höhe und Breite eines Feldes sind gleich).
Auf diesen Beitrag antworten »
Tommy1234

bei field[i][j] = new Rectangle();

Wenn du Skype hast könnten wir skypen wäre um einiges einfacher....
Auf diesen Beitrag antworten »
eulerscheZahl

In Skype heiße ich eulersche_Zahl. Mein Mirko geht nicht richtig, aber wir können ja auch chatten.
Auf diesen Beitrag antworten »
Tommy1234

habe ne kontaktanfrage gesendet mit namen Thomas
Auf diesen Beitrag antworten »
eulerscheZahl

Bei mir kam nichts an, du hast eine private Nachricht gekriegt. Ansonsten kannst du mir auch deinen Nutzernamen geben.
Auf diesen Beitrag antworten »
Tommy1234

...
Auf diesen Beitrag antworten »
eulerscheZahl

Habe dich jetzt in Skype. Wenn du willst, kannst du deinen Namen hier wieder löschen.
Auf diesen Beitrag antworten »
Tommy1234

ruf mal bitte an und send mir ne kontaktanfrage.
Auf diesen Beitrag antworten »
eulerscheZahl

Ich habe dich schon in meiner Kontaktliste. Hatte dir auch schon geschrieben, habe dich aber nochmal angeklingelt.
 
Neue Frage »
Antworten »


Verwandte Themen

Die Beliebtesten »
Die Größten »
Die Neuesten »