Pour avoir des boutons de jeux il faut des booléens up/down,
Est-ce qu'il suffit de remettre ces booléens à chaque touch event à zero, puis mettre à 1 ceux qui renvoient un test positif point/rectangle, ou la manoeuvre est-elle plus complexe ?
Pour avoir des boutons de jeux il faut des booléens up/down,
Est-ce qu'il suffit de remettre ces booléens à chaque touch event à zero, puis mettre à 1 ceux qui renvoient un test positif point/rectangle, ou la manoeuvre est-elle plus complexe ?
heu... je n'ai absolument rien compris a la problematique ...
comme on dit : un probleme bien expose est a moitie resolu
La forme des pyramides prouve que l'Homme a toujours tendance a en faire de moins en moins.
Venez discuter sur le Chat de Développez !
Bon je crois qu'il faut que je fasse des tests.
C'est plus compliqué que de gérer la souris et le clavier https://developer.mozilla.org/en-US/...I/Touch_events
Bon donc apparemment comme je le pensais, c'est plus compliqué que ça,
Il faudrait capturer les events stard/end/move/cancel avec toutes les listes d'ellipses,
Ensuite tester les hits d'ellipses contre celles des boutons affichés dans le canvas,
après si je dis pas de bêtises:
- touchstart met les boutons à 1
- touchmove met les boutons à 1 si contact ou 0
- touchend/touchcancel met les boutons à 0
Bon... en fait l'algo va entièrement dépendre du contexte,
Là je pars sur un truc simple, une croix et A B (comme la gameboy)
Si contact avec la croix, il faut faire centreDoigt - centreCroix pour trouver le vecteur directionnel converti en 8 directions,
Pour les boutons tester l'ellipse du pouce suffit, normalement, pour savoir si elle couvre" A, B ou les 2.
Je teste ça et je vous dis si ça marche.
Alors je découvre les subtilités du truc:
1/ Les ellipses sont toutes petites, donc repérer le point central suffit.
2/ Les smartphones d'entrée de gamme ne détectent que deux doigts maximum.
Pour le pouce à droite faudrait donc que j'essaye un rectangle à 3 cases (A, A+B, B) on verra ce que ça donne.
Voilà, je continue mes tests, maintenant je passe aux maths, la difficulté ne réside pas dans les events de touch qui permettent de faire facilement un pseudo-paint, mais dans les calculs géométriques pour simuler une manette.
Il faudrait peut-être que je fasse cet exercice qui consiste à simuler deux curseurs de souris, ça simplifierait la logique dans un premier temps... je ne sais pas je débute en gestion des touch.
je n'ai toujours pas compris ce que tu voulais faire ... mais peut-etre que cette video peu t'aider (en anglais)
La forme des pyramides prouve que l'Homme a toujours tendance a en faire de moins en moins.
Venez discuter sur le Chat de Développez !
- A gauche: une croix à 8 directions. Forme géométrique: un cercle.
- A droite: deux boutons, et si le pouce est entre les deux ça met les deux à true. Forme géométrique: un rectangle.
Côté tests point/cercle/rect je connais les formules de maths, c'est pas là où j'ai une difficulté. Ca pourrait être n'importe quelles autres formes géométriques, peu importe.
La difficulté est de savoir quand les deux pouces entrent et sortent des deux formes. Pour start/end j'ai un event par pouce. Pour move j'ai un event pour deux pouces avec un tableau touch à 2 cases. Y'a rien qui me permet de savoir si c'est le pouce gauche ou droit.
Peut-être bêtement faire un test gauche/droite par rapport au centre du canvas, je vais essayer ça.
Pour l'instant un test simple, je me contente de voir si les doigts sont sur les deux zones.
Çà fonctionne la plupart du temps mais il y a des cas rares où j'arrive à faire planter le truc (la zone droite reste en on alors qu'il n'y a plus de doigt dessus), il faut que je fasse encore des tests.
Code html : 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 <!DOCTYPE html> <!-- Click nbfs://nbhost/SystemFileSystem/Templates/Licenses/license-default.txt to change this license Click nbfs://nbhost/SystemFileSystem/Templates/Other/html.html to edit this template --> <html> <head> <title>TODO supply a title</title> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <script src="main.js"></script> </head> <body onLoad="main()"> <div align="center"> <canvas id="draw" width="480" height="320"></canvas> <div id="tracer"></div> </div> </body> </html>
Code Javascript : 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 // render context test var CAN = null; var CTX2D = null; // colors const CO = ['#0000FF', '#FF0000']; // left buttons zone: 8-directions cross const CROSS_X = 64; const CROSS_Y = 320 - 64; const CROSS_RAD = 64; var CROSS_ON = 0; // right buttons zone: A B const AB_W = 64 * 3; const AB_X = 480 - AB_W; const AB_H = 64 * 2; const AB_Y = CROSS_Y - AB_H / 2; var AB_ON = 0; // show txt function trace(s) { document.getElementById('tracer').innerHTML += s + '<br/>'; } function main() { //alert("main"); CAN = document.getElementById('draw'); CTX2D = CAN.getContext('2d'); //console.log(CTX2D); CTX2D.strokeStyle = '#FFFFFF'; CTX2D.fillRect(0, 0, 720, 480); // draw button zones CTX2D.fillStyle = CO[0]; CTX2D.arc(CROSS_X, CROSS_Y, CROSS_RAD, 0, Math.PI * 2); CTX2D.fill(); CTX2D.rect(AB_X, AB_Y, AB_W, AB_H); CTX2D.fill(); // touch events CAN.ontouchstart = OnTouchStart; CAN.ontouchend = OnTouchEnd; CAN.ontouchmove = OnTouchMove; } function Touch(e, on) { e.preventDefault(); const tl = e.changedTouches; const r = e.target.getBoundingClientRect(); const halfWidth = (r.right - r.left) / 2; for (let i = 0; i < 2; i++) { const x = tl[i].clientX - r.left; const y = tl[i].clientY - r.top; if ( x < halfWidth ) { // left: test against cross CROSS_ON = 0; if (on) { // test point / circle const dx = x - CROSS_X; const dy = y - CROSS_Y; CROSS_ON = 0 + ( Math.sqrt(dx*dx + dy*dy) <= CROSS_RAD ); } CTX2D.fillStyle = CO[ CROSS_ON ]; CTX2D.beginPath(); CTX2D.arc(CROSS_X, CROSS_Y, CROSS_RAD, 0, Math.PI * 2); CTX2D.fill(); } else { // right: test against AB AB_ON = 0; if (on) { // test point / AABB const dx = x - AB_X; const dy = y - AB_Y; AB_ON = 0 + ( dx >= 0 && dx <= AB_W && dy >= 0 && dy <= AB_H ); } CTX2D.fillStyle = CO[ AB_ON ]; CTX2D.beginPath(); CTX2D.rect(AB_X, AB_Y, AB_W, AB_H); CTX2D.fill(); } } } function OnTouchStart(e) { Touch(e, 1); } function OnTouchEnd(e) { Touch(e, 0); } function OnTouchMove(e) { Touch(e, 1); }
Ca y'est je viens de réussir à identifier le bug.
Quand un "start/move" vire trop vite vers la gauche ou la droite, le programme n'a pas le temps de voir que le doigt a quitté les zones cercle/rect car il retient le dernier move event, donc les booléens restent bloqués sur "on".
Il faut que je réfléchisse comment corriger ça.
Je vais tester une approche plus bête où mes deux zones sont juste des <div>.
Bon donc là je me suis bêtement rabattu sur le comportement par défaut des <div>, je n'ai plus ce bug.
Code HTML : 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 <!DOCTYPE html> <!-- Click nbfs://nbhost/SystemFileSystem/Templates/Licenses/license-default.txt to change this license Click nbfs://nbhost/SystemFileSystem/Templates/Other/html.html to edit this template --> <html> <head> <title>TODO supply a title</title> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <script src="main.js"></script> </head> <body onLoad="main()"> <div align="center"> <div id="container" align="left" style="width:480px;height:320px;background-color:#000000;"> <canvas id="draw" width="480" height="320"></canvas> </div> <div id="tracer"></div> </div> </body> </html>
Code Javascript : 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 // div container var CON = null; // render context test var CAN = null; var CTX2D = null; // colors const CO = ['#0000FF', '#FF0000']; // left buttons zone: 8-directions cross var CROSS_DIV = null; // right buttons zone: A B var AB_DIV = null; // show txt function trace(s) { document.getElementById('tracer').innerHTML += s + '<br/>'; } function main() { //alert("main"); CON = document.getElementById('container'); const conR = CON.getBoundingClientRect(); const cost = CON.style; cost.position='relative'; //alert(conR); // drawing canvas CAN = document.getElementById('draw'); CTX2D = CAN.getContext('2d'); // CROSS BUTTONS CROSS_DIV = document.createElement('div'); const cst = CROSS_DIV.style; cst.backgroundColor = '#0000FF'; cst.width = '128px'; cst.height = '128px'; cst.top = (320-128)+'px'; cst.left ='0px'; cst.position = 'absolute'; //cst.zIndex = 2; CON.appendChild(CROSS_DIV); CROSS_DIV.ontouchstart = CrossStart; CROSS_DIV.ontouchend = CrossEnd; // AB BUTTONS AB_DIV = document.createElement('div'); const ast = AB_DIV.style; ast.backgroundColor = '#0000FF'; ast.width = '128px'; ast.height = '128px'; ast.top = (320-128)+'px'; ast.left =(480-128)+'px'; ast.position = 'absolute'; //ast.zIndex = 3; CON.appendChild(AB_DIV); AB_DIV.ontouchstart = ABStart; AB_DIV.ontouchend = ABEnd; } function CrossStart(e) { e.preventDefault(); CROSS_DIV.style.backgroundColor = '#FF0000'; } function CrossEnd(e) { e.preventDefault(); CROSS_DIV.style.backgroundColor = '#0000FF'; } function ABStart(e) { e.preventDefault(); AB_DIV.style.backgroundColor = '#FF0000'; } function ABEnd(e) { e.preventDefault(); AB_DIV.style.backgroundColor = '#0000FF'; }
Bon... faut que je finisse l'exercice jusqu'au bout... je vois que c'est pas si simple et ça pourra servir aux autres.
Faut que j'ajoute là:
- Détection sur onmove quand les doigts sortent/entrent dans les rectangles
- Bouton fullscreen en haut à droite car il faut recalculer la position des boutons
- Dessiner les boutons
- Faire les calculs qui simulent cross & AB
Bonjour,
sans regarder plus avant ton projet, oublie les touchxxxx et passe aux pointerxxxx.
Il te faut factoriser tes fonctions et ne pas en créer une par élément.
Si l'on prend ce code :
seule la cible change donc une seule fonction est nécessaire, par exemple :
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
8
9
10 function CrossStart(e) { e.preventDefault(); CROSS_DIV.style.backgroundColor = '#FF0000'; } function ABStart(e) { e.preventDefault(); AB_DIV.style.backgroundColor = '#FF0000'; }
cela fera pour les deux.
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6 function CrossStart(e) { const target = e.target; e.preventDefault(); target/*CROSS_DIV*/.style.backgroundColor = '#FF0000'; }
Les joies du CSS | Réponses sur forum | Simple comme JS | Essais libres autour de l'API G$$gle Maps
✂ ---------------------------------------------
developpez.net c'est aussi :
✔ Les meilleurs cours et tutoriels pour apprendre le CSS
✔ Les meilleurs cours et tutoriels pour apprendre le (X)HTML
✔ Les meilleurs cours et tutoriels pour apprendre le JavaScript
Merci, je viens de voir que les events pointer calculent automatiquement over/out, ça va me permettre de simplifier tout ça.
Et oui pour la factorisation de fonction tu as raison j'y pensais hier mais c'était la fin de journée, j'étais fatigué et j'ai un peu bâclé mon test. Il faut que je fasse comme pour le premier, tout condenser sur une fonction PaddleEvent.
bon c'est pas si simple...
onpointerenter/onpointerover fonctionne avec la souris mais pas le touch
les event pointer ne permettent pas d'indifférencier souris et touch, ce sont bien deux input device différents
j'y arrive pas là je crois que je vais me contenter des events touch
Pour l'instant ce petit bout de code a l'air de fonctionner à peu près mais je suis réceptif à vos critiques.
Code Javascript : 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 // div container var CON = null; // render context test var CAN = null; var CTX2D = null; // colors const CO = ['#0000FF', '#FF0000']; // left buttons zone: 8-directions cross var CROSS_DIV = null; // right buttons zone: A B var AB_DIV = null; // show txt function trace(s) { document.getElementById('tracer').innerHTML += s + '<br/>'; } function main() { //alert("main"); CON = document.getElementById('container'); const conR = CON.getBoundingClientRect(); const cost = CON.style; cost.position = 'relative'; //alert(conR); // drawing canvas CAN = document.getElementById('draw'); CAN.ontouchmove = function (e) { e.preventDefault(); }; CTX2D = CAN.getContext('2d'); // CROSS BUTTONS CROSS_DIV = document.createElement('div'); const cst = CROSS_DIV.style; cst.backgroundColor = CO[0]; cst.width = '128px'; cst.height = '128px'; cst.top = (320 - 128) + 'px'; cst.left = '0px'; cst.position = 'absolute'; //cst.zIndex = 2; CON.appendChild(CROSS_DIV); CROSS_DIV.ontouchstart = function (e) { PadEvent(e, 1, 0); }; CROSS_DIV.ontouchmove = function (e) { PadEvent(e, 1, 0); }; CROSS_DIV.ontouchend = function (e) { PadEvent(e, 0, 0); }; // AB BUTTONS AB_DIV = document.createElement('div'); const ast = AB_DIV.style; ast.backgroundColor = CO[0]; ast.width = '128px'; ast.height = '128px'; ast.top = (320 - 128) + 'px'; ast.left = (480 - 128) + 'px'; ast.position = 'absolute'; //ast.zIndex = 3; CON.appendChild(AB_DIV); AB_DIV.ontouchstart = function (e) { PadEvent(e, 1, 1); }; AB_DIV.ontouchmove = function (e) { PadEvent(e, 1, 1); }; AB_DIV.ontouchend = function (e) { PadEvent(e, 0, 1); }; } function PadEvent(e, on, zone) { e.preventDefault(); const div = e.target; const st = div.style; const rec = div.getBoundingClientRect(); const touch = e.changedTouches[0]; var pressed = 0; * if (on) { const x = touch.clientX - rec.left; const y = touch.clientY - rec.top; if ( x >=0 && x <= rec.width && y >= 0 && y <= rec.height ) { pressed = 1; } } st.backgroundColor = CO[pressed]; }
Bon... hé bien non, c'est toujours pas bon, quand je touchmove les deux boutons en même temps y'en a un qui fait planter l'autre.
Bon pour le moment avec les <div> je m'en sors pas, je ne trouve pas mes erreurs.
J'ai repris le premier test en réduisant la zone de droite à 128x128 histoire de réduire au max le risque du bug, je n'arrive pas à faire mieux pour le moment.
Bon pour l'instant ça semble fonctionner.
Code HTML : 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 <!DOCTYPE html> <!-- Click nbfs://nbhost/SystemFileSystem/Templates/Licenses/license-default.txt to change this license Click nbfs://nbhost/SystemFileSystem/Templates/Other/html.html to edit this template --> <html> <head> <title>TODO supply a title</title> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <script src="main.js"></script> </head> <body onLoad="main()"> <div align="center"> <div id="container" style="width:480px;height:320px;background-color:#0000FF;" > </div> <div id="tracer"></div> </div> </body> </html>
Code Javascript : 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
217
218
219
220 // canvas dimensions var SW = 480; var SH = 320; // render context test var CONTAINER = null; var CAN = null; var CTX2D = null; // colors const CO = ['#0000FF', '#FF0000']; // left buttons zone: 8-directions cross const CROSS_X = 64; const CROSS_Y = SH - 64; const CROSS_RAD = 64; var CROSS_ON = 0; // right buttons zone: A B const AB_W = 64 * 2; const AB_X = SW - AB_W; const AB_H = 64 * 2; const AB_Y = CROSS_Y - AB_H / 2; var AB_ON = 0; // fullscreen button const FULLSCREEN_RECT = {left: SW - 32, width: 32, top: 0, height: 32}; // show txt function trace(s) { document.getElementById('tracer').innerHTML += s + '<br/>'; } // coordinates relative to canvas function Cx(x) { return x * CAN.width / CONTAINER.offsetWidth; } function Cy(y) { return y * CAN.height / CONTAINER.offsetHeight; } function main() { //alert("main"); CONTAINER = document.getElementById('container'); CAN = document.createElement('canvas'); CAN.width = SW; CAN.height = SH; CAN.style.backgroundColor = '#000000'; CAN.style.width = "100%"; CAN.style.height = "100%"; CONTAINER.appendChild(CAN); CTX2D = CAN.getContext('2d'); //console.log(CTX2D); CTX2D.strokeStyle = '#FFFFFF'; CTX2D.fillRect(0, 0, SW, SH); // draw button zones CTX2D.fillStyle = CO[0]; CTX2D.beginPath(); CTX2D.arc(CROSS_X, CROSS_Y, CROSS_RAD, 0, Math.PI * 2); CTX2D.closePath(); CTX2D.fill(); CTX2D.beginPath(); CTX2D.rect(AB_X, AB_Y, AB_W, AB_H); CTX2D.closePath(); CTX2D.fill(); CTX2D.beginPath(); CTX2D.rect(FULLSCREEN_RECT.left, FULLSCREEN_RECT.top, FULLSCREEN_RECT.width, FULLSCREEN_RECT.height); CTX2D.closePath(); CTX2D.fill(); // touch events CAN.ontouchstart = OnTouchStart; CAN.ontouchend = OnTouchEnd; CAN.ontouchmove = OnTouchMove; } function Touch(e, on) { e.preventDefault(); const tl = e.changedTouches; const r = e.target.getBoundingClientRect(); const halfWidth = Cx((r.right - r.left) / 2); //let inLeft = 0, inRight = 0; for (let i = 0; i < tl.length; i++) { const x = Cx(tl[i].clientX - r.left); const y = Cy(tl[i].clientY - r.top); if (x < halfWidth) { // left: test against cross CROSS_ON = 0; if (on) { //inLeft = 1; // test point / circle const dx = x - CROSS_X; const dy = y - CROSS_Y; CROSS_ON = 0 + (Math.sqrt(dx * dx + dy * dy) <= CROSS_RAD); } } else { // right: test against AB AB_ON = 0; if (on) { //inRight = 1; // test point / AABB const dx = x - AB_X; const dy = y - AB_Y; AB_ON = 0 + (dx >= 0 && dx <= AB_W && dy >= 0 && dy <= AB_H); } } } // colorization test CTX2D.fillStyle = CO[ CROSS_ON ]; CTX2D.beginPath(); CTX2D.arc(CROSS_X, CROSS_Y, CROSS_RAD, 0, Math.PI * 2); CTX2D.closePath(); CTX2D.fill(); CTX2D.fillStyle = CO[ AB_ON ]; CTX2D.beginPath(); CTX2D.rect(AB_X, AB_Y, AB_W, AB_H); CTX2D.closePath(); CTX2D.fill(); } function OnTouchStart(e) { Touch(e, 1); } function OnTouchEnd(e) { Touch(e, 0); OnMouseUp(e); } function OnTouchMove(e) { Touch(e, 1); } function ToggleFullScreen() { if (!document.fullscreen) { CONTAINER.requestFullscreen(); } else { document.exitFullscreen(); } } function OnMouseUp(e) { const rec = e.target.getBoundingClientRect(); const tl = e.changedTouches; const fsr = FULLSCREEN_RECT; for (let i = 0; i < tl.length; i++) { const x = Cx(tl[i].clientX - rec.left); const y = Cy(tl[i].clientY - rec.top); // check fullscreen button const dx = x - fsr.left; const dy = y - fsr.top; //trace(dx + ':' + dy); //console.log(fsr.width+':'+fsr.height); if (dx >= 0 && dx < fsr.width && dy >= 0 && dy < fsr.height) { ToggleFullScreen(); } } }
Vous avez un bloqueur de publicités installé.
Le Club Developpez.com n'affiche que des publicités IT, discrètes et non intrusives.
Afin que nous puissions continuer à vous fournir gratuitement du contenu de qualité, merci de nous soutenir en désactivant votre bloqueur de publicités sur Developpez.com.
Partager