I. D'où vient ce concept▲
L'idée derrière la manette de jeu à touché unique découle de la pratique de quelques jeux à vue subjective et à vue objective sur mon iPad d'Apple* et le sentiment de contrainte lors de l'interaction avec ceux-ci. Nos appareils mobiles sont maintenant assez puissants pour afficher des univers 3D complets et riches, pourtant le manque de boutons physiques constitue un obstacle important pour certains types de jeux.
En revanche, le touché excelle à créer de bonnes expériences pour les jeux qui sont adaptés à cela, donc il me semblait logique d'étudier s'il y avait un moyen innovant pouvant être utilisé dans les jeux à vue subjective.
Pour commencer, j'ai énuméré les facteurs limitants de la méthode de contrôle actuelle pour les jeux à vue subjective sur le toucher : les doubles joysticks. Après des recherches sur des jeux populaires, je ramène cela aux deux points suivants.
- En raison de la façon dont les joueurs tiennent généralement les appareils tactiles, seuls leurs pouces sont libres. Les doubles joysticks nécessitent l'utilisation de deux pouces simultanément, ce qui rend impossible de faire une autre action sans perdre brusquement un certain niveau de contrôle sur votre personnage.
- Les pouces des joueurs cachent la représentation des joysticks sur l'écran, et comme il n'y a pas de retour haptique (pas encore), il devient très difficile de positionner les pouces avec précision.
En plus de cela, je voulais essayer et développer quelque chose qui pourrait facilement convenir aux joueurs gauchers, et aussi aux gens qui ne peuvent utiliser qu'une seule main.
La motivation principale pour ce concept était le sentiment tatillon qu'il doit y avoir quelque chose de mieux que d'essayer de copier la méthode de commande à partir d'une manette de console, qui est, en soi, souvent considérée comme la deuxième meilleure façon après l'utilisation d'un clavier et d'une souris.
II. Développement de l'idée▲
Après avoir fait la recherche sur les défauts des implémentations actuelles, j'ai commencé à regarder ce que vous faites réellement lorsque vous jouez un jeu à la première ou la troisième personne sur un PC ou une console, dans le but d'essayer de comprendre ce que le nouveau système devrait permettre.
Si vous regardez des novices jouer à ces types de jeu, il apparaît très vite qu'ils se déplacent souvent à une position, puis ajustent leur vue, puis passent à une autre position. Ils font rarement les deux actions en même temps, alors que les joueurs expérimentés vont fusionner les deux actions.
Cependant, regardez encore et vous remarquerez une autre tendance : une fois qu'un joueur se déplace dans une direction, les autres continueront souvent dans cette direction et n'utiliseront que la direction du regard pour ajuster la leur.
S'ils veulent changer la direction du mouvement, disons lors d'une esquive, c'est généralement très réfléchi. La réalisation de cela m'a amené à la notion de cercle interne/externe : une fois qu'un joueur s'est mis dans une direction, vous pouvez assumer qu'il souhaite continuer dans cette direction ?
Je pensais que la réponse est généralement oui, j'ai donc conçu un prototype rapide. J'ai été surpris de voir à quel point les premiers tests étaient bons et j'ai continué à les affiner. Après avoir montré le concept à quelques amis et obtenu de bons retours, j'ai décidé de consacrer quelques jours pour vraiment essayer de trouver un mécanisme raffiné dans l'ensemble.
Les étapes supplémentaires, prises du premier prototype jusqu'à la version actuelle, étaient toutes des petites itérations.
J'ai ajouté le recouvrement central du HUD afin que vous puissiez voir ce que vous êtes en train de faire, et les flèches de direction pour renforcer le message au joueur sur ce que le système est en train de faire (un bon ami m'a donné l'idée d'éclairer le sens suivant lequel le joueur tourne).
J'ai fait quelques impasses aussi. Une version antérieure vous permettait de commencer à toucher n'importe où - ce qui était agréable - mais vous empêchait d'être capable de tourner sur place. J'ai aussi essayé d'inverser les cercles, de sorte que vous vous tourniez avant de vous déplacer, mais cela était vraiment bizarre. Maintenant Ron va discuter des détails d'implémentation de l'idée.
III. Mise en œuvre de l'idée▲
La mise en œuvre comprend deux étapes : l'interprétation du gadget à son état actuel et la manipulation de la matrice de visualisation pour refléter l'état du gadget. Le gadget est modal, ce qui signifie qu'il a deux états entre lesquels l'utilisateur peut transiter.
Initialement, le gadget est juste une manette de mouvement. L'utilisateur déplace la manette virtuelle verticalement ou horizontalement, et cela modifie la matrice de translation.
La modification que nous avons faite sur le gadget tel que décrit dans l'article original d'Alex, était d'ajouter une zone de transition entre les zones de translation et de rotation. Cette zone de transition facilite le passage de la translation à la rotation, et rend le gadget un peu plus indulgent.
Pour afficher l'emplacement du contact de l'utilisateur sur le gadget, nous définissons un « nœud » qui représente la pointe de la manette virtuelle. Lorsque l'utilisateur déplace ce nœud plus loin du centre du gadget, nous augmentons la vitesse de translation. La vitesse de translation est maximisée lorsque le nœud atteint la zone de transition.
Lorsque l'utilisateur accède à la zone de transition, on active le nœud de rotation. Tant que l'entrée de l'utilisateur est en dehors de la zone de translation pure, nous fournissons deux nœuds. L'un (le rouge) représente le vecteur de vitesse et est bloqué dans l'anneau intérieur. Le second nœud (le jaune) est le nœud de rotation.
Lorsque l'utilisateur déplace le nœud plus loin, on calcule une valeur d'interpolation linéaire entre les anneaux intérieurs et extérieurs de la zone de transition. Nous utilisons cette valeur pour réduire la vitesse de translation lorsque l'utilisateur se déplace vers le bord de la zone de translation, tout en augmentant simultanément la mise à l'échelle de la rotation. Quand l'entrée de l'utilisateur atteint le bord extérieur de la zone de transition, l'effet de translation est mis à zéro, et l'effet de rotation est maximisé.
Plus l'angle est à la verticale, ou « en avant » de la direction, plus la rotation est ajoutée au mouvement de la perspective. Dans notre implémentation, il y a un certain chevauchement entre les modes de translation et de rotation. Nous avons une zone de transition où nous effectuons la translation et la rotation ensemble. Finalement, lorsque l'utilisateur pousse la manette de jeu plus loin, l'élément de translation se met à zéro et l'utilisateur tourne uniquement la vue.
La vitesse de rotation est proportionnelle à l'angle du vecteur de direction initial. Une fois que l'utilisateur entre dans la zone de transition, le nœud de la translation est verrouillé, et l'écart angulaire à partir du vecteur de direction (l'angle α) est celui qui contrôle la vitesse de rotation. Lorsque l'utilisateur tourne sur 180 degrés, le sens de rotation change brusquement, mais dans la pratique, l'utilisateur tourne à un bon rythme d'environ 45 degrés, de sorte que nous nous retrouvons rarement dans cette situation.
IV. Détails de l'implémentation▲
La mise en œuvre est assez simple. Il existe un certain code qui gère le traitement des données entrées par l'utilisateur. Fondamentalement, il fait la saisie des coordonnées x, y du point de touché et permet au code du gadget de les traiter. Le gadget se réinitialise lorsque les utilisateurs lèvent leurs doigts, mais quand ils font un nouveau contact avec leurs doigts nous traitons l'entrée, en calculant à partir du centre du gadget. Quand le point de contact se déplace et dépasse le cercle intérieur, nous verrouillons le nœud de translation et nous commençons à traiter le nœud de rotation. Plus le nœud de translation est loin du centre, plus la translation est rapide et plus le nœud de rotation est loin du cercle intérieur, plus la rotation est rapide.
Plus il y a une déviation de direction du nœud de translation, plus la rotation atténue également la translation, offrant une transition en douceur du déplacement vers la rotation. Ces valeurs sont calculées pour chaque entrée tactile. Quand nous voulons afficher le gadget, nous calculons une transformation de translation à partir du nœud de translation et une transformation de rotation à partir du nœud de rotation. Le code est simple. Les valeurs de translation et de rotation sont utilisées pour calculer la matrice de vue/modèle qui est ensuite transmise au shader et est utilisée pour actionner la scène 3D.
Le traitement du gadget est entièrement cédé au pixel shader. Nous l'avons fait pour le prototypage rapide comme il est facile d'interpréter des cercles et des gradients dans le code du shader. Il rend également facile d'échanger différents types de contrôles de gadget si vous voulez essayer avec différents paramètres. Une des demandes initiales était que le gadget s'affiche où l'utilisateur peut le voir, plutôt que sous le pouce où il est caché.
Le fragment shader affiche juste les positions des nœuds, puis les anneaux du gadget en utilisant la distance à partir du centre. Les coordonnées de texture sont mises à l'échelle dans l'en-tête du shader afin qu'elles varient entre [-1, -1] et [1, 1], ce qui rend l'affichage assez simple. Voici le code du shader GLSL OpenGL ES 2.0.
precision mediump float
;
varying vec2 v_UV1;
varying vec3 v_Normal;
// 2 nœuds assemblés dans un vec4 - x,y pour nub1, z,w pour nub2
uniform vec4 u_NubPos;
// paramètres du gizmo, seulement x est utilisé pour l'anneau intérieur
uniform vec4 u_widgetParams;
const
vec4 innerColor =
vec4
(
1
.0
, 1
.0
, 1
.0
, 0
.4
);
const
vec4 outerColor =
vec4
(
0
.2
, 0
.8
, 0
.8
, 0
.4
);
const
vec4 innerRingColor =
vec4
(
1
.0
, 0
.0
, 0
.0
, 0
.5
);
const
vec4 outsideCircleColor =
vec4
(
0
.0
, 0
.0
, 0
.0
, 1
.0
);
const
vec4 nub0Color =
vec4
(
1
.0
, 0
.0
, 0
.0
, 0
.5
);
const
vec4 nub1Color =
vec4
(
0
.0
, 0
.0
, 0
.0
, 0
.5
);
const
float
ringWidth =
0
.05
;
void
main
(
)
{
float
inner =
u_widgetParams.x;
// calcul de la position des centres des nœuds
// si invalide, ils sont définis à 1,1 (provoquant le clipping)
vec2 nub0 =
vec2
(
v_UV1.x-
u_NubPos.x,v_UV1.y-
u_NubPos.y);
vec2 nub1 =
vec2
(
v_UV1.x-
u_NubPos.z,v_UV1.y-
u_NubPos.w);
// distance entre le fragment actuel et la position des nœuds
float
lenNub0 =
length
(
nub0);
float
lenNub1 =
length
(
nub1);
// les coordonnées de texture sont redimensionnées dans le vertex
// l'échelle du shader va de -1,-1 à 1,1, donc le centre est 0,0
// où est le fragment courant par rapport au centre ?
float
len =
length
(
v_UV1);
// il est en dehors du carré, oublions-le
if
(
len >
1
.0
)
{
discard;
}
// dessine les deux nœuds, s'ils sont dans leurs rayons
// nub0 est dessiné en premier
else
if
(
lenNub0 <
0
.10
)// taille du nœud en dur
{
gl_FragColor =
nub0Color;
return
;
}
else
if
(
lenNub1 <
0
.10
)
{
gl_FragColor =
nub1Color;
return
;
}
// sinon, dessine les anneaux
else
if
(
len >=
inner &&
len <=
inner+
ringWidth)
{
gl_FragColor =
innerRingColor;
}
else
if
(
len <
inner )
{
gl_FragColor =
innerColor;
}
else
// dessine une couleur mélangée
{
float
m =
1
.0
-(
len-
inner/(
inner+
ringWidth));
gl_FragColor =
mix
(
vec4
(
0
,0
,0
,1
),outerColor,m);
}
}
V. Quelle est la suite▲
Le prototype actuel est encore loin d'être finalisé,avant de pouvoir l'utiliser dans un jeu : il y a encore beaucoup de travail à faire. Le plus gros problème à résoudre, est de savoir comment faire ces changements particuliers pour rendre le mécanisme plus souple, afin que les joueurs puissent passer rapidement du déplacement latéral gauche à celui vers la droite, ce qui est beaucoup utilisé dans les jeux auxquels ce contrôleur est destiné. Nous avons essayé de fournir un cadre dans lequel nous pouvons prototyper différents types de gadgets ou les affiner avec un minimum d'effort. Certaines personnes n'ont aucun mal à s'adapter aux contrôles et à se familiariser avec. D'autres pensent que nous les avons broyés ensemble d'une manière étrange et non naturelle. Voilà ce qu'est le travail d'innovation pour de nouveaux concepts d'interface utilisateur.
L'étape suivante est de concevoir un jeu autour de ce concept pour s'assurer que ses limitations, telles que la suppression du pouvoir de regarder en haut et en bas, ne sont pas remarquées ou manquantes. Cela pourrait être l'endroit où vous entrez en jeu. Nous avons fait l'expérimentation et trouvé qu'il est assez facile d'essayer différentes implémentations et de les affiner pour obtenir une mise en œuvre de concepts d'interface utilisateur très pratique, bien que cela présente une nouvelle technique d'entrée de l'utilisateur. Mais c'est aussi où le plaisir commence. Donc, essayez de trouver une nouvelle implémentation de la manette de jeu. Peut-être que vous pouvez améliorer ce que nous avons construit ici. Faites-nous savoir comment cela fonctionne pour vous !
Cet article est offert par la zone des développeurs Intel, un programme en ligne dont le but est d'encourager et soutenir les développeurs indépendants. Il regroupe tous les outils dont les développeurs ont besoin pour créer des applications innovantes pour Android.
Retrouvez l'ensemble des outils de développement Android sur la plate-forme Intel Developer Zone.
VI. À propos des auteurs ▲
Alex Moore conçoit des jeux vidéo depuis 1999, et est crédité sur 14 jeux publiés. Il a été designer en Chef dans quatre d'entre eux, incluant Aliens Vs Predator avec ses deux millions de vente. En tant que designer indépendant, il a travaillé sur plusieurs titres - en plus de projets personnels sur les appareils mobiles, il a récemment travaillé sur des titres de lancement pour les deux consoles : Xbox One (Xbox Fitness) et PlayStation 4 (The Playroom).
Ron Fosner fait de la programmation graphique professionnellement depuis 1995, et est un ingénieur de Jeux et de Performance Graphique chez Intel, spécialisé sur les plates-formes mobiles. Il est un expert dans le graphisme et le multithreading, et aide les entreprises de jeux à optimiser ceux-ci sur l'architecture Intel depuis 2008. Il travaille actuellement sur la création de contenu captivant pour OpenGL et OpenGL-ES, et pousse les plates-formes graphiques mobiles jusqu'à leur dernier retranchement.
VII. Références ▲
Un nouveau type de manette à écran tactile, Moore, Alex.
VIII. Notes▲
*D'autres noms et marques peuvent être revendiqués comme propriété d'autrui.