Salut à tous

Voilà mon problème. Je suis en train de faire un jeu et dans celui ci des figurines se déplacent sur une carte.
J'ai donc un fenêtre j'ai un ImageView qui me sert de fond et une liste d'ImageView dans un Group qui sont mes figurines.
Pour chaque figurine j'ai un UserData qui correspond à la position du pion sur la carte.
Je souhaite que le centre de chaque figurine soit sur le point défini par le UserData
Le code ci dessous fonctionne bien tant que l'orientation de ma figurine est 0. Dès que l'angle est différent de 0 j'ai des décalages assez incompréhensibles
L'ajustement de la position de l'ImagteView Figurine se fait dans la méthode corrigeLocation .

Je dois avouer que j'ai beaucoup de mal à comprendre le système de gestion des coordonées

Code : Sélectionner tout - Visualiser dans une fenêtre à part
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
210
211
212
213
214
215
216
 
package application;
 
import java.awt.geom.Point2D;
import java.io.File;
import javafx.application.Application;
import javafx.application.Platform;
import javafx.beans.Observable;
import javafx.geometry.Bounds;
import javafx.geometry.HPos;
 
import javafx.geometry.Rectangle2D;
import javafx.geometry.VPos;
import javafx.scene.Group;
import javafx.scene.Node;
import javafx.scene.Scene;
import javafx.scene.image.Image;
import javafx.scene.image.ImageView;
import javafx.scene.input.MouseEvent;
import javafx.scene.input.ScrollEvent;
import javafx.scene.layout.GridPane;
import javafx.scene.layout.Priority;
import javafx.scene.layout.Region;
import javafx.scene.transform.Scale;
import javafx.stage.Stage;
import pions.Pion;
 
public class TestPositionement extends Application {
 
	private Stage primaryStage;
	private Scene primaryScene;
 
	private final ImageView vueCarte = new ImageView();
	//private AnimationTimer timer;
 
	Group figurines = new Group();
	private GridPane vueRoot;
 
	private Region mapArea = new Region() {
		{
			getChildren().add(vueCarte);
			getChildren().add(figurines);
		}
	};
 
	private long t0 = -1;
	private double dir=60;
 
	@Override
	public void start(Stage primaryStage) {
 
		this.primaryStage = primaryStage;
 
		for (int fig = 0; fig < 3; fig++) {
			File file = new File("Images/Test/Fig" + fig + ".png");
			Image imgFig = new Image(file.toURI().toString(), false);
			ImageView vueFig = new ImageView();
			vueFig.setImage(imgFig);
			vueFig.getTransforms().add(scale);
			vueFig.relocate(100*(fig+1),200);
			vueFig.setRotate(dir);
			vueFig.visibleProperty().set(true);
			vueFig.setUserData(new Point2D.Double((fig+1) * 100, 200));
			figurines.getChildren().add(vueFig);
		}
 
		//
		File file = new File("Images/Test/Fond.png");
		Image image = new Image(file.toURI().toString(), false);
		vueCarte.setImage(image);
		final Rectangle2D viewport = new Rectangle2D(0, 0, 500, 500);
		vueCarte.setViewport(viewport);
		vueCarte.setOnMouseDragged(this::handleMouseDragged);
		vueCarte.setOnMouseMoved(this::handleMouseMoved);
		vueCarte.setOnScroll(this::handleZoom);
		vueCarte.getTransforms().add(scale);
		Platform.runLater(() ->
 
		{
			mapArea.widthProperty().addListener(this::mapAreaSizeChanged);
			mapArea.heightProperty().addListener(this::mapAreaSizeChanged);
		});
		vueRoot = new GridPane();
 
 
		vueRoot.add(mapArea, 1, 1);
		vueRoot.setConstraints(mapArea, 1, 1, 1, 1, HPos.LEFT, VPos.TOP, Priority.ALWAYS, Priority.ALWAYS);
 
		primaryScene = new Scene(vueRoot, 500, 500);
		primaryStage.setTitle("Test position");
		primaryStage.setScene(primaryScene);
		primaryStage.show();
		corrigeLocation(0, 0);
	}
	private double startX;
	private double startY;
 
	private double lastX;
	private double lastY;
 
	private void handleMouseMoved(MouseEvent e) {
		double XX = e.getX() + vueCarte.getViewport().getMinX();
		double YY = e.getY() + vueCarte.getViewport().getMinY();
		System.out.println(e.getX()+","+e.getY());
	}
 
 
 
	private void handleMouseDragged(MouseEvent e) {
		if (e.isPrimaryButtonDown()) {
 
			double draggedDistanceX = startX - e.getX();
			double draggedDistanceY = startY - e.getY();
 
			startX = e.getX();
			startY = e.getY();
 
 
			double viewWidth = mapArea.getWidth() / zoom;
			double viewHeight = mapArea.getHeight() / zoom;
 
			final Rectangle2D viewport = vueCarte.getViewport();
			double curMinX = viewport.getMinX();
			double curMinY = viewport.getMinY();
 
			double newMinX = curMinX + draggedDistanceX;
			double newMinY = curMinY + draggedDistanceY;
			newMinX = clamp(newMinX, 0, Math.max(0, vueCarte.getImage().getWidth() - viewWidth));
			newMinY = clamp(newMinY, 0, Math.max(0, vueCarte.getImage().getHeight() - viewHeight));
			vueCarte.setViewport(new Rectangle2D(newMinX, newMinY, viewWidth, viewHeight));
			corrigeLocation(newMinX, newMinY);
		}
	}
 
	double clamp(double min, double value, double max) {
		double result = Math.max(min, value);
		result = Math.min(result, max);
		return result;
	}
 
	private void mapAreaSizeChanged(Observable o) {
		double viewWidth = mapArea.getWidth() / zoom;
		double viewHeight = mapArea.getHeight() / zoom;
		final Rectangle2D viewport = vueCarte.getViewport();
		if (viewport.getWidth() != viewWidth || viewport.getHeight() != viewHeight) {
			double newMinX = viewport.getMinX();
			double newMinY = viewport.getMinY();
			newMinX = clamp(newMinX, 0, Math.max(0, vueCarte.getImage().getWidth() - viewWidth));
			newMinY = clamp(newMinY, 0, Math.max(0, vueCarte.getImage().getHeight() - viewHeight));
			vueCarte.setViewport(new Rectangle2D(newMinX, newMinY, viewWidth, viewHeight));
		}
	}
 
	private double zoom = 1.0;
	private Scale scale = new Scale(zoom, zoom);
	private static final double MIN_ZOOM = 0.5;
	private static final double MAX_ZOOM = 2.0;
 
	private void handleZoom(ScrollEvent event) {
		double delta = event.getDeltaY();
		double newZoom = zoom;
		if (delta < 0) {
			newZoom *= 2;
		}
		if (delta > 0) {
			newZoom /= 2;
		}
		newZoom = clamp(MIN_ZOOM, newZoom, MAX_ZOOM);
		if (newZoom == zoom) {
			return;
		}
 
		zoom = newZoom;
 
		scale.setX(zoom);
		scale.setY(zoom);
		double viewWidth = mapArea.getWidth() / zoom;
		double viewHeight = mapArea.getHeight() / zoom;
		final Rectangle2D viewport = vueCarte.getViewport();
 
		if (viewport.getWidth() != viewWidth || viewport.getHeight() != viewHeight) {
			double newMinX = viewport.getMinX();
			double newMinY = viewport.getMinY();
			newMinX = clamp(newMinX, 0, Math.max(0, vueCarte.getImage().getWidth() - viewWidth));
			newMinY = clamp(newMinY, 0, Math.max(0, vueCarte.getImage().getHeight() - viewHeight));
			vueCarte.setViewport(new Rectangle2D(newMinX, newMinY, viewWidth, viewHeight));
			corrigeLocation(newMinX, newMinY);
		}
	}
 
	private void corrigeLocation(double orgx, double orgy) {
 
		for (Node vueFig : figurines.getChildren()) {
			Point2D unite = (Point2D) vueFig.getUserData();
			double nx = (unite.getX() - orgx) * zoom;
			double ny = (unite.getY() - orgy) * zoom;
			int m=0;			
			if (nx >= 0 && ny >= 0) {
				Bounds bnd=vueFig.getLayoutBounds();		
				double xc=(bnd.getMinX()+bnd.getMaxX())/2;
				double yc=(bnd.getMinY()+bnd.getMaxY())/2;
				vueFig.setLayoutX(nx-xc*zoom);
				vueFig.setLayoutY(ny-yc*zoom);				
				vueFig.visibleProperty().set(true);
				} else
				vueFig.visibleProperty().set(false);
		}
	}
 
 
	public static void main(String[] args) {
		launch(args);
	}
 
 
}