Bienvenue visiteur !
|
Statistiques
Liste des membres
Contact
Mentions légales
479 connectés actuellement
29679581 visiteurs depuis l'ouverture
16827 visiteurs aujourd'hui
Partenaires
Tous nos partenaires
Devenir partenaire
|
Mack -
posté le 07/03/2023 à 21:15:10 (2290 messages postés)
- | | Domaine concerné: Programmation Logiciel utilisé: c++ Salut !
J'suis en train de programme un système de Zoom en combat pour EasyRPG, et je galère comme un cochon pour faire le mouvement de caméra.
En gros, pour l'instant j'ai ça :
Donc le zoom marche, mais zoom toujours sur le centre de l'écran.
Or, moi je voudrais que quand je sélectionne Flammèche, ça zoom sur le monstre à gauche, quand je sélectionne Barrière ça zoom sur le monstre à droite.
J'ai essayé plein de truc, mais j'arrive à rien ...
Le mieux que j'ai réussi à faire c'est ça :
1
2
3
4
5
6
7
8
9
10
11
12
| int zt = 1;
if (zoomTimer > 0)
zt = zoomTimer;
double ax = (lastZoomX - 213) * startZoom / 100;
double ay = (lastZoomY - 120) * startZoom / 100;
double ddx = (destZoomX - 213) * destZoom / 100;
double ddy = (destZoomY - 120) * destZoom / 100;
zx = (ddx / zt - (ax * zoomTimer / 15.0));
zy = (ddy / zt - (ay * zoomTimer / 15.0)); |
( Les lastZoom c'est la position du dernier Zoom, startZoom c'est le taux de zoom avant le début du zoom, et les Dest c'est le point destination + le taux de zoom à atteindre )
Mais bon, c'est clairement pas terrible ><
|
( Je prend note de tout les commentaires, même si je n'y répond pas ) |
Moretto -
posté le 07/03/2023 à 21:26:34 (934 messages postés)
| | Je ne suis pas sur de comprendre ton problème mais il doit exister une fonction lerp ou équivalent pour interpoler tes valeurs de départ et d'arrivée.
Qu'est ce qui ne va pas dans le deuxième gif ? J'ai l'impression que tu as l'effet voulu ?
|
Mack -
posté le 07/03/2023 à 21:36:41 (2290 messages postés)
- | | Alors, on le voit pas forcément très bien, mais au dézoom, ça dézoom pas depuis le point zoomé, mais depuis le centre de l'écran, du coup y a une espèce de sautement de caméra vraiment pas terrible.
Mais surtout, et j'aurais dû commencé par là :
On peut voir quand je change d'ennemi, ben la caméra fait complétement n'importe quoi :/
|
( Je prend note de tout les commentaires, même si je n'y répond pas ) |
| The Inconstant Gardener | (peux pas t'aider mais j'avais juste envie de dire que les screens sont classes !)
|
Quel RPG Maker choisir ? • Ocarina of Time PC • Polaris 03 • Le matérialisme c'est quand tu as du matériel. |
Gaetz -
posté le 08/03/2023 à 09:34:28 (2379 messages postés)
| ...passe... | J'ai l'impresison qu'il manque beaucoup de code. On voit pas comment est géré le de zoomTimer par exemple.
A ta place, j'essaierais de mettre des points d'arrêt au moment du dezoom pour comprendre pourquoi ca part du centre de l'écran et pas de la cible du zoom.
|
Lije : démo 0.5 | Powered by Geex |
| Chanter l'hyperchleuasme | Pour que tes mouvements de caméra soient toujours fluides, au minimum tu dois avoir les variables :
x_ancien, y_ancien, zoom_ancien, <-- là où tu étais avant le mouvement de caméra
temps_ancien, <-- moment où a commencé le mouvement
x_actuel, y_actuel, zoom_actuel, <-- là où tu es pendant le mouvement de caméra, valeurs utilisées pour l'affichage
temps_actuel <-- maintenant
x_but, y_but, zoom_but <-- là où tu seras après avoir terminé le mouvement de caméra
temps_but <-- moment où le mouvement sera fini
Et à chaque frame, si temps_actuel < temps_but,
x_actuel, y_actuel, zoom_actuel
sont recalculés comme une moyenne pondérée entre
x_ancien, y_ancien, zoom_ancien
et
x_but, y_but, zoom_but.
La pondération se fait selon avancement = (temps_actuel - temps_ancien) / (temps_but - temps_ancien).
Spoiler (cliquez pour afficher) Moyenne pondérée :
x_actuel = avancement * x_but + (1 - avancement) * x_ancien
y_actuel = avancement * y_but + (1 - avancement) * y_ancien
zoom_actuel = avancement * zoom_but + (1 - avancement) * zoom_ancien Libre à toi d'avoir des mouvements accélérés ou ralentis (plutôt que des mouvements linéaires) en trifouillant ton avancement avec des fonctions, comme une parabole (mouvement accéléré : f(x)=x² ; mouvement ralenti : f(x)=1-(x-1)² ). Mais ça c'est dans un second temps. Assure-toi d'abord que la caméra marche bien en linéaire.
Lorsqu'un nouveau but est requis (cibler un nouvel ennemi), tu dois donner des valeurs à
x_ancien, y_ancien, zoom_ancien = x_actuel, y_actuel, zoom_actuel
temps_ancien = maintenant
x_but, y_but, zoom_but = ton nouvel objectif
temps_but = maintenant + duree_mouvement
|
L'essentialisme c'est quand ta voiture a un moteur essence. | Es-tu une star ? | Kujira no Hara | Polaris 03 | Planète Glutko |
Mack -
posté le 08/03/2023 à 19:00:46 (2290 messages postés)
- | | Nemau a dit: (peux pas t'aider mais j'avais juste envie de dire que les screens sont classes !) |
( Merci )
Gaetz a dit: J'ai l'impresison qu'il manque beaucoup de code. On voit pas comment est géré le de zoomTimer par exemple.
A ta place, j'essaierais de mettre des points d'arrêt au moment du dezoom pour comprendre pourquoi ca part du centre de l'écran et pas de la cible du zoom. |
Autant pour moi :
- zoomTimer qu'est un bête timer de TMax à -1 ( Si zoomTimer >= 0, un zoom est en cours, si zoomTimer == -1, pas de zoom ), ben y a l'intégralité du code qui est censé gérer le mouvement :/
- 213 : Centre en X de l'écran
- 120 : Centre en Y de l'écran
- 15.0 : TMax
Ouais, c'est ce que j'ai fini par faire, j'ai tracé toute mes positions pendant un mouvement.
Et donc, quand on dézoom, c'est "simplement" que les coordonnées sont inversées, si je pars d'un point à gauche de l'écran, il repars en symétrie vertical, donc les même coordonnées, mais à droite.
Donc ça, c'est pas compliqué à corriger, je détecte si c'est un dézoom et j'inverse les coordonnées.
Par contre, si je garde le même zoom, va savoir pourquoi, il me zoom au bon endroit, mais bouge très peu ses coordonnées, je suppose que c'est parce que j'utilise startZoom et destZoom pour le calcul des positions, et qu'il faudrait surement pas.
Roi of the Suisse a dit: Pour que tes mouvements de caméra soient toujours fluides, au minimum tu dois avoir les variables :
x_ancien, y_ancien, zoom_ancien, <-- là où tu étais avant le mouvement de caméra
temps_ancien, <-- moment où a commencé le mouvement
x_actuel, y_actuel, zoom_actuel, <-- là où tu es pendant le mouvement de caméra, valeurs utilisées pour l'affichage
temps_actuel <-- maintenant
x_but, y_but, zoom_but <-- là où tu seras après avoir terminé le mouvement de caméra
temps_but <-- moment où le mouvement sera fini
Et à chaque frame, si temps_actuel < temps_but,
x_actuel, y_actuel, zoom_actuel
sont recalculés comme une moyenne pondérée entre
x_ancien, y_ancien, zoom_ancien
et
x_but, y_but, zoom_but.
La pondération se fait selon avancement = (temps_actuel - temps_ancien) / (temps_but - temps_ancien).
Spoiler (cliquez pour afficher) Moyenne pondérée :
x_actuel = avancement * x_but + (1 - avancement) * x_ancien
y_actuel = avancement * y_but + (1 - avancement) * y_ancien
zoom_actuel = avancement * zoom_but + (1 - avancement) * zoom_ancien Libre à toi d'avoir des mouvements accélérés ou ralentis (plutôt que des mouvements linéaires) en trifouillant ton avancement avec des fonctions, comme une parabole (mouvement accéléré : f(x)=x² ; mouvement ralenti : f(x)=1-(x-1)² ). Mais ça c'est dans un second temps. Assure-toi d'abord que la caméra marche bien en linéaire.
Lorsqu'un nouveau but est requis (cibler un nouvel ennemi), tu dois donner des valeurs à
x_ancien, y_ancien, zoom_ancien = x_actuel, y_actuel, zoom_actuel
temps_ancien = maintenant
x_but, y_but, zoom_but = ton nouvel objectif
temps_but = maintenant + duree_mouvement |
- Ça j'ai ( lastZoom / destZoom / startZoom. Par contre, moi c'est les coordonnées réelles, pas celle zoomé, je sais pas trop desquelles tu parles, évidemment je peux facilement remplacer par les autres si besoin )
- Dans le cas ou ma gestion du temps c'est un timer de TMax à -1, et qu'il peut pas y avoir 2 zoom en même temps, on s'en fou non ?
- Le reste c'est bon ( destZoomX, destZoomY, destZoom )
Y a que le temps_but ou j'ai un doute, pour moi ça sera TMax non ?
Du coup, dans mon cas, l'avancement, c'est juste 1 / TMax ?
( Pour rappel : zoomTimer qu'est un bête timer de TMax à -1 ( Si zoomTimer >= 0, un zoom est en cours, si zoomTimer == -1, pas de zoom ) )
Dans tes calculs de positions, on devrait pas faire intervenir le zoom ?
Pareil, on devrait pas avoir les coordonnées centrale de l'écran qui rentrent dans l'équation ?
De ce que je comprend de tes équations, je devrait arriver à un truc comme ça :
1
2
3
| double a = 1 / 15.0;
zx = a * destZoomX * zoom + (1 - a) * lastZoomX * zoom - 213;
zy = a * destZoomY * zoom + (1 - a) * lastZoomY * zoom - 120; |
( J'me rend compte que mon avancement est pas bon du tout, j'vais essayer de le corriger )
Mais évidemment, ça marche absolument pas
( Et j'ai aussi essayer sans les trucs de zoom, ou de coordonnées centrales, ça change rien )
Le calcul du zoom, qui marche parfaitement, Anton m'a passé un coup de main, et je suis arrivé à ça :
double z = (destZoom + (startZoom - destZoom) * (zoomTimer / 15.0)) / 100.0;
Donc en développant, ça m'à l'air d'être le même truc que toi
|
( Je prend note de tout les commentaires, même si je n'y répond pas ) |
| Chanter l'hyperchleuasme | Quand je dis x_truc, y_truc, je parle des coordonnées du centre du cadrage caméra.
C'est le centre qui t'intéresse, parce que tu veux cibler un monstre / un héros en particulier.
Après, tu peux en déduire facilement les 4 sommets du rectangle de la caméra à partir de zoom_truc.
J'ai un truc du genre dans la version Java de Kujira no Hara, avec juste x et y, sans le zoom :
(prototype)
|
L'essentialisme c'est quand ta voiture a un moteur essence. | Es-tu une star ? | Kujira no Hara | Polaris 03 | Planète Glutko |
Mack -
posté le 09/03/2023 à 07:44:28 (2290 messages postés)
- | | Roi of the Suisse a dit: Quand je dis x_truc, y_truc, je parle des coordonnées du centre du cadrage caméra.
C'est le centre qui t'intéresse, parce que tu veux cibler un monstre / un héros en particulier.
Après, tu peux en déduire facilement les 4 sommets du rectangle de la caméra à partir de zoom_truc.
J'ai un truc du genre dans la version Java de Kujira no Hara, avec juste x et y, sans le zoom :
(prototype) |
Oui j'avais bien compris ^^
J'vais essayer de désactiver le zoom, pour déjà arriver à faire en sorte que la caméra mette le bon point au centre de l'écran
|
( Je prend note de tout les commentaires, même si je n'y répond pas ) |
moretto -
posté le 09/03/2023 à 10:17:05 (934 messages postés)
| | J'ai fait un test sur Godot (en GDScript avec les fonctions associées...) :
Vector2 => un vecteur en 2D qui contient x et y, position est un Vector2
lerp => interpolation lineraire du genre a+t(b−a) avec t entre 0 et 1, si proche 0 c'est plus lent
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
|
var zoom #zoom visé
var coordFinal :Vector2 #coordonnées visées
var camera #la camera..
var coordZoomOut #les coordonnées dézoomé, le centre de l'écran
var zoomMag = 1 #les grandissement du zoom en cours
func _ready():
camera =$Camera2D
coordZoomOut = camera.position
zoom = 0
func call_zoom(target):
#mon target c'est juste des sprites que j'ai mi sur ma scène, j'appelle la fonction call_zoom avec un bouton
#si dézoomé je zoome vers la cible
if camera.position == coordZoomOut:
coordFinal = target.position
zoom = 0.5
#Si sur la cible je dézoome
elif camera.position == target.position:
coordFinal = coordZoomOut
zoom = 1
func _process(delta):
#fonction appelée chaque frame
if zoom != 0:
if camera.position != coordFinal && zoomMag != zoom:
camera.position = lerp(camera.position,coordFinal,0.1)
if abs(camera.position.x-coordFinal.x) <= 0.3 : #le lerp donne des floats donc c'est pas pile pile !
camera.position = coordFinal
zoomMag = lerp(zoomMag,zoom,0.08)
camera.set_zoom(Vector2(zoomMag,zoomMag))
else:
zoom = 0 |
Vu que j'ai des fonctions et des méthodes de godot je ne sais pas si ça peut t'aider :x
|
Mack -
posté le 09/03/2023 à 20:39:10 (2290 messages postés)
- | | moretto a dit: J'ai fait un test sur Godot (en GDScript avec les fonctions associées...) :
Vector2 => un vecteur en 2D qui contient x et y, position est un Vector2
lerp => interpolation lineraire du genre a+t(b−a) avec t entre 0 et 1, si proche 0 c'est plus lent
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
|
var zoom #zoom visé
var coordFinal :Vector2 #coordonnées visées
var camera #la camera..
var coordZoomOut #les coordonnées dézoomé, le centre de l'écran
var zoomMag = 1 #les grandissement du zoom en cours
func _ready():
camera =$Camera2D
coordZoomOut = camera.position
zoom = 0
func call_zoom(target):
#mon target c'est juste des sprites que j'ai mi sur ma scène, j'appelle la fonction call_zoom avec un bouton
#si dézoomé je zoome vers la cible
if camera.position == coordZoomOut:
coordFinal = target.position
zoom = 0.5
#Si sur la cible je dézoome
elif camera.position == target.position:
coordFinal = coordZoomOut
zoom = 1
func _process(delta):
#fonction appelée chaque frame
if zoom != 0:
if camera.position != coordFinal && zoomMag != zoom:
camera.position = lerp(camera.position,coordFinal,0.1)
if abs(camera.position.x-coordFinal.x) <= 0.3 : #le lerp donne des floats donc c'est pas pile pile !
camera.position = coordFinal
zoomMag = lerp(zoomMag,zoom,0.08)
camera.set_zoom(Vector2(zoomMag,zoomMag))
else:
zoom = 0 |
Vu que j'ai des fonctions et des méthodes de godot je ne sais pas si ça peut t'aider :x |
En vrai j'me suis pas du tout servi de ton algo, mais voir que toi aussi tu mettais le Lerp, bah j'ai persévéré, j'ai juste fait un lerp pour le calcul de la position, et après pour déplacer les images dans l'écran, j'ai fait 6 fois la même chose, ça à jamais marché, et j'ai fait une 7ème fois le même algo, et cette fois ça marche :
En vrai c'est pas parfait ( Genre des fois le zoom saute un peu si on passe d'un niveau de zoom à un autre , et parfois la caméra sors un peu du cadre on peut voir que y a genre 1px de turquoise sur la gauche de l'écran de temps en temps ), mais pour l'instant, je m'en contenterais x)
Merci à tous de m'avoir aider
|
( Je prend note de tout les commentaires, même si je n'y répond pas ) |
Moretto -
posté le 09/03/2023 à 20:55:35 (934 messages postés)
| | Le résultat est cool, gg !
|
| Chanter l'hyperchleuasme | La colonne de pixels turquoise à gauche, Pokémon Violet/Ecarlate a le même bug dans les cinématiques, si ça peut te rassurer
Le résultat est cool, bravo
|
L'essentialisme c'est quand ta voiture a un moteur essence. | Es-tu une star ? | Kujira no Hara | Polaris 03 | Planète Glutko | Index du forum > Entraide > [RESOLU] [c++] Faire un effet de Zoom
|
|
|