Autoit [HELP] Isometric tiles dans D@fus

Inscrit
14 Decembre 2012
Messages
48
Reactions
2
#1


Coucou, comment est-ce que je peux obtenir le cellID d'un carreau d'une map juste avec la position de ma souris (avec (0,0) comme top left) et la taille du carreau (60 long et 30 hauteur)?

Merci beaucoup,
Ashlanfox.
 

BlueDream

Administrateur
Membre du personnel
Inscrit
8 Decembre 2012
Messages
2 010
Reactions
149
#2
Bonjour,

Le problème c'est que l'on ne peut pas te répondre sans plus d'informations.
On ne calcule pas cela de la même manière partout, cela dépend comment tu as dessiné ta grille.
Cependant ce que tu peux faire c'est te référer aux quatre extrémités des cellules.
 
Inscrit
14 Decembre 2012
Messages
48
Reactions
2
#3
BlueDream a dit:
Bonjour,

Le problème c'est que l'on ne peut pas te répondre sans plus d'informations.
On ne calcule pas cela de la même manière partout, cela dépend comment tu as dessiné ta grille.
Cependant ce que tu peux faire c'est te référer aux quatre extrémités des cellules.
C'est celle de D@fus, j'ai une résolution de 900 sur 745, et j'ai la position de la souris qui équivaut à 0,0 tout en haut à gauche de la map. J'aurais bien voulu utilisé un simple Floor avec ma position de souris divisé par la longeur et la largeur du carreau, mais je me retrouve avec des rectangles et pas des carreaux.

Je suis un peu perdu, j'ai cherché pendant plusieurs heures, j'ai essayé un petit coup de matrice, rien ne sort :s
 
Dernière édition par un modérateur:

BlueDream

Administrateur
Membre du personnel
Inscrit
8 Decembre 2012
Messages
2 010
Reactions
149
#4
Tu as le calcule dans les sources dans ce cas, cherches bien.
Je ne suis pas sur mon ordinateur je ne peux pas te donner le fichier.
 

Labo

Membre Actif
Inscrit
16 Aout 2013
Messages
799
Reactions
15
#5
Regarde les sources de mon tuto pour bot pixel, il y a une fonction qui peut t'aider !
 
Inscrit
14 Decembre 2012
Messages
48
Reactions
2
#6
Labo a dit:
Regarde les sources de mon tuto pour bot pixel, il y a une fonction qui peut t'aider !
Quand tu démarres du cellID oui, mais si tu veux faire le procédé inverse tu ne saurais pas le trouver (il faudrait déduire le reste du modulo).
 

Labo

Membre Actif
Inscrit
16 Aout 2013
Messages
799
Reactions
15
#7
Non, pas du tout, réfléchis un peu !

1. Même si je ne donnais pas mon code, à partir d'une fonction quelconque bijective vers un ensemble fini, tu peux calculer très facilement son inverse (pas en un temps optimal sauf si tu veux calculer toutes les valeurs, je le concède)
2. Comme je donne mon code, t'as qu'à essayer de le comprendre !
 
Inscrit
14 Decembre 2012
Messages
48
Reactions
2
#8
Labo a dit:
Non, pas du tout, réfléchis un peu !

1. Même si je ne donnais pas mon code, à partir d'une fonction quelconque bijective vers un ensemble fini, tu peux calculer très facilement son inverse (pas en un temps optimal sauf si tu veux calculer toutes les valeurs, je le concède)
2. Comme je donne mon code, t'as qu'à essayer de le comprendre !
Donc divmod est bijective? si je prends l'id 397 (x, y = divmod(id, 14)) j'aurais 28 comme retour. Et maintenant de 28, trouvons 397? Tendu, surtout que cette fonction est plutôt surjective.
En plus de ça tu ne pourrais utiliser cette technique que si je démarrais du centre du carreau, maintenant si je donne les coordonnées un peu à gauche/droite/haut/bas ...

C'est comme la relation dérivé/primitive elles sont liées à une constante près.
 

Labo

Membre Actif
Inscrit
16 Aout 2013
Messages
799
Reactions
15
#9
Il me semble que tu n'es pas très familiarisé avec le concept de tuple en Python... Ni avec celui de division euclidienne... Ce n'est pas de ta faute, mais celle de l'enseignement actuel.
Code:
>>> x, y = divmod(397, 14)
>>> x
28
>>> y
5
Je ne m'abaisserai même pas à essayer de t'expliquer pourquoi divmod est bijective.
C'est quand même marrant de connaître des mots compliqués comme "surjective" et de ne pas savoir faire une division euclidienne ! Tu pourrais devenir inspecteur de l'éducation nationale.

Ashlanfox a dit:
En plus de ça tu ne pourrais utiliser cette technique que si je démarrais du centre du carreau, maintenant si je donne les coordonnées un peu à gauche/droite/haut/bas ...
Tu es parti tellement loin que je ne te suis plus, mais bon courage, tu y arriveras peut-être : c'est mathématiquement prouvé.
 
Dernière édition par un modérateur:

BlueDream

Administrateur
Membre du personnel
Inscrit
8 Decembre 2012
Messages
2 010
Reactions
149
#10
Miskine
 
Inscrit
14 Decembre 2012
Messages
48
Reactions
2
#11
Labo a dit:
Il me semble que tu n'es pas très familiarisé avec le concept de tuple en Python... Ni avec celui de division euclidienne... Ce n'est pas de ta faute, mais celle de l'enseignement actuel.
Code:
>>> x, y = divmod(397, 14)
>>> x
28
>>> y
5
Je ne m'abaisserai même pas à essayer de t'expliquer pourquoi divmod est bijective.
C'est quand même marrant de connaître des mots compliqués comme "surjective" et de ne pas savoir faire une division euclidienne ! Tu pourrais devenir inspecteur de l'éducation nationale.

Ashlanfox a dit:
En plus de ça tu ne pourrais utiliser cette technique que si je démarrais du centre du carreau, maintenant si je donne les coordonnées un peu à gauche/droite/haut/bas ...
Tu es parti tellement loin que je ne te suis plus, mais bon courage, tu y arriveras peut-être : c'est mathématiquement prouvé.
D'accord, au temps pour moi, non je ne connais pas trop python. J'ai regardé dans la doc et je partais du principe que divmod allait juste retourner la première composante soit l'identique du Mod en autoit. Mais avec le reste de la division on peut, j'aurais du plus m'informer.
Le Mod de autoIt n'est pas bijective mais le divmod de python lui l'est bien. Mea culpa.

Code:
$xhg = 43
$yhg = 45

$dx = 60
$dy = 30

$cellIDx = ($x - $xhg) / $dx
$cellIDy = ($y - $yhg) / $dy
$cellIDy *= 2

If Mod($cellIDy, 2) = 1 Then $cellIDx -= 0.5

$cellID = ($cellIDy * 14) + $cellIDx
Comme je l'ai dit, ça marche depuis le cellID vers une position car ça retournera l'exacte centre du carreau, mais si je fais le sens inverse et que je cherche depuis un point du carreau qui n'est pas le centre, il retourne une valeur proche de cellID mais pas la bonne.
 
Dernière édition par un modérateur:

Labo

Membre Actif
Inscrit
16 Aout 2013
Messages
799
Reactions
15
#12
Pas de problème, on a tous le droit à l'erreur !

Ok, là j'ai compris ton problème :D
Si tu as la valeur de dx et de dy, tu as juste besoin de décrire (c'est juste des équations de droites) un "motif élémentaire". Et alors, tu enlèves dx tant que tu peux, puis dy tant que tu peux (cad tant que tu restes dans la fenêtre). Et alors, tu te retrouves dans un rectangle élémentaire correspondant à cette image:
En fait, ce n'est pas exactement ça, ce rectangle n'est pas élémentaire car il est coupé en haut, il faut que tu fasses comme s'il se prolongeait comme ça :
Maintenant, s'il est dans le rectangle 0, c'est bon, si il est dans le coin en bas à droite, il est dans la cellule 15, si il est dans le coin en haut à gauche, tu rajoutes 1 dx et 1 dy pour le mettre dans la cellule 15, s'il est en bas à gauche, 1 dx et en haut à droite 1 dy. Ensuite, tu as juste à compter combien de dx et de dy tu as retranché en tout pour retrouver la cellule de départ !
Le mieux, c'est que tu n'as plus à gérer les "cas particuliers" de déplacement en diagonale, puisque tu es soit dans le réseau de 0, soit dans celui de 15 et tu n'as plus qu'à ajouter un nombre fixe (29 je crois) de cellId pour ajouter dy.
 
Inscrit
14 Decembre 2012
Messages
48
Reactions
2
#13
Oui, c'est justement ce que j'ai essayé de faire hier! Je suis arrivé à ça:

Code:
Func IsometricTiles($mouse_x, $mouse_y)

;On enlève 8 et 30 pour le FormBorder
$mouse_x -= 8
$mouse_y -= 30  
   
$cell_width = 60
$cell_height = 30

$cell_id = Floor($mouse_x/$cell_width) + (Floor($mouse_y/$cell_height) * 14)

$cell_x_relative = $mouse_x - (Floor($mouse_x/$cell_width) * $cell_width)
$cell_y_relative = $mouse_y - (Floor($mouse_y/$cell_height) * $cell_height)

If $cell_x_relative < 30 Then
   If $cell_y_relative < 15 Then	  
	  Debug("HAUT - GAUCHE")
	  If $cell_y_relative < ((30 - $cell_x_relative ) / 2) Then
		 $cell_id -= 15
	  EndIf 

   Else	  
	  $cell_y_relative -= 15
	  Debug("BAS - GAUCHE")
	  If $cell_y_relative > ($cell_x_relative) / 2 Then
		 $cell_id += 14
	  EndIf
   EndIf
Else
   If $cell_y_relative < 15 Then	  
	  Debug("HAUT - DROITE")	
	  $cell_x_relative -= 30
	  If $cell_y_relative < ($cell_x_relative) / 2 Then
		 $cell_id -= 14
	  EndIf
   Else	  
	  $cell_x_relative -= 30
	  $cell_y_relative -= 15
	  Debug("BAS - DROITE")
	  If $cell_y_relative > ((30 - $cell_x_relative ) / 2) Then
		 $cell_id += 15
	  EndIf
   EndIf
EndIf

Return $cell_id

EndFunc
Je vais essayer d'expliquer:
1) Je trouve la cellID du rectangle comme sur ta photo
2) Je la réduis à une échelle de 0-60 et 0-30
3) Je détermine dans quelle partie ce trouve la souris
4) Par rapport à la droite d'équation x/2 je détermine si la souris est dans le carreau ou dans le triangle hors zone
5) Je laisse cellID intacte, je l'incrémente ou je lui soustrais une valeur en fonction de 4) et 5)

ça marche plus ou moins bien mais je me retrouve souvent avec une marge d'erreur, dans certains cas. Je suis un peu perdu :'(
 
Dernière édition par un modérateur:

Labo

Membre Actif
Inscrit
16 Aout 2013
Messages
799
Reactions
15
#14
Peut-être que ces erreurs sont justement dues à la petite bande manquante dans le rectangle. Essaye de tester juste en-dessous du rectangle (c'est-à-dire la zone de la bande manquante translatée de un dy vers le bas).

Je n'ai pas compris ce qu'était le form border.
 
Haut Bas