Bienvenue visiteur !
|
Statistiques
Liste des membres
Contact
Mentions légales
356 connectés actuellement
30738106 visiteurs depuis l'ouverture
1691 visiteurs aujourd'hui
Partenaires
Tous nos partenaires
Devenir partenaire
|
Messages postés par Tassle Nombre de messages référencés sur Oniromancie (non supprimés): 2786 Aller à la page: 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
Posté dans Forum - Discussion Générale de making |
Tassle -
posté le 16/03/2022 à 10:40:26. (5274 messages postés) |
| Citation: C'est aussi ce que j'aurais proposé, mais là ça pose un problème de ligne de vue.
Genre, si en X-1 t'as une case impraticable, le joueur devrait pas pouvoir attaquer en X-2. Or, avec cette méthode, c'est plus compliqué à gérer. |
Ah je pensais que les attaques à distance ignoraient le terrain, mais j'ai ptêt' mal compris.
Citation: Ah je suis curieux oui, pourquoi pas ! |
Tu peux faire comme ça:
- T'as ton tableau 2D "Dist" qui représente les distances de chaque case depuis le personnage. Au début il est initialisé partout à 99, sauf la case du perso qui est à 0.
- T'as un deuxième tableau (à une seule dimension) "Q" qui représente une file d'attente des cases à explorer (ou "queue" en anglais). La longueur de ce tableau est égale à deux fois le nombre de cases sur la map (et au départ osef de ce qu'il y a dedans).
Ensuite tu procède comme ça:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
|
On pose la variable startQ := 0 et endQ := 2.
On met Q[0] := xp et Q[1] := yp, où xp, yp sont les coordonnées de ton perso.
Tant que startQ < endQ:
x := Q[startQ]
startQ := startQ+1
y := Q[startQ]
startQ := startQ+1
Pour chaque case (xv, yv) voisine de (x,y):
Si (xv, yv) est passable et Dist[xv, yv] == 99:
Dist[xv, yv] := Dist[x, y] + 1
Q[endQ] := xv
endQ := endQ + 1
Q[endQ] := yv
endQ := endQ + 1
Fin du Si...
Fin du Pour chaque...
Fin du Tant que...
|
À la fin de la procédure, tu auras la distance de toutes les cases de ta map depuis le perso stockées dans "Dist".
Si tu veux laisser à 99 les distances supérieures à 7 par exemple, tu peux exécuter la boucle "Pour chaque case (xv, yv) voisine de (x,y)" seulement si Dist[x,y] < 7 (et dans le cas Dist[x,y] >= 7 tu skip cette boucle).
Dans ce cas tu peux aussi économiser un peu de place en utilisant un tableau Q de longueur 4*7*(7+1)+2 (si ce nombre est plus petit que deux fois le nombre total de cases sur la map, sinon ça sert à rien). Mais bon le gain ne sera jamais très significatif par rapport aux autres trucs stockés pour la map, donc tu peux ignorer cette petite optimisation si tu veux.
Edit: Citation: Je sais que Tass avait l'air d'être un export dans le domaine donc je me dis qu'avec un peu de chance il aura une idée efficace |
C'est pas exactement mon domaine d'expertise (mon truc c'est la géométrie algorithmique) mais ça reste de l'algorithmie donc je peux me faire passer comme expert auprès des non-experts (À vrai dire même dans "mon" domaine je reste un débutant par rapport à ceux qui ont vraiment de la bouteille !)
|
~~ |
Posté dans Forum - Discussion Générale de making |
Tassle -
posté le 16/03/2022 à 09:48:34. (5274 messages postés) |
| Citation: Pour les déplacements de mon jeu, j'utilise un algorithme qui se rapproche de A*, je crois si je dis pas de bétises que c'est le principe de l'algorithme de Dikstra, qui est la base du A*. |
Perso j’appellerais pas ce que tu fais l'algo de Dijkstra, parce que tu ne suis pas l'ordre de "relaxation" des arrêtes du graphe typique de l'algo de Dijkstra ("relaxation" est la terminologie anglaise et peut-être que ça s'appelle "détente" en français, je suis plus sûr). C'est encore moins du A* parce qu'il n'y a pas d'heuristique de distance utilisée (et que de toute façon A* ne s'applique qu'au cas où on veut la distance entre deux points donnés, pas quand on veut la distance d'un point à tous les autres).
Edit: C'est Bellman–Ford en fait l'algo que t'utilises.
Citation: Jusqu'à la tout fonctionne plutôt bien, je ne sais pas si c'est la méthode optimale, probablement pas étant donné que je suis une bille en programmation, mais c'est une méthode qui fonctionne et qui semble correspondre aux articles que j'ai lu sur cet algorithme, le chemin est bon et ca calcule toujours le plus court. |
Dans le cas d'un jeu sur une grille et sans déplacement diagonaux on peut effectivement faire mieux sans trop de difficulté (en gros ici tu regarde chaque case de la map 5 fois, même celles qui sont loin et qui ne seront donc pas accessibles, alors qu'avec la bonne stratégie tu peux te contenter de regarder chaque case une seule fois). Je peux élaborer si tu veux, mais si c'est assez rapide en l'état tu peux laisser comme ça.
Citation: Bon, ca fonctionne !
Le seul soucis c'est qu'il y a un micro lag de quelques secondes, voir une seconde quand le personnage a beaucoup de mouvements.
C'est pas très grave honnêtement, ce n'est pas ultra fréquent, mais disons que si vous avez une meilleure idée je prends, sinon ça fera le taff. |
Si tu veux garder la base que t'as, tu peux essayer l'amélioration suivante qui évitera de refaire toute la procédure pour chaque case bleue:
Une fois que t'as déterminé toutes les cases bleues, réinitialises ton tableau (ou un nouveau tableau si tu veux pas perdre celui-ci) pour qu'il ait toutes les valeurs à 99, sauf les cases bleues que tu mets toutes à 0. Ensuite, tu lances ta procédure habituelle pour calculer les cases à distance 2 (en ignorant les collisions) en partant de ce tableau. En gros, ça te permet de dire à ton algo que le bonhomme peut se déplacer vers n'importe quelle case bleue avant d'attaquer, ce qui te permet donc de calculer toutes les cases qui sont à une distance d'au plus 2 d'une case bleue.
Ça marche pour les patterns d'attaques qui sont du type "toutes les cases à distance au plus k". Si t'as des patterns plus compliqués tu risque de devoir réfléchir à d'autres stratégies.
Autre stratégie plus générale : Ici pour chaque case bleue de coordonnées (x,y) tu sais que les cases suivantes peuvent être attaquées :
(x-2,y)
(x-1,y-1)
(x-1,y)
(x-1,y+1)
(x,y-2)
(x,y-1)
(x,y+1)
(x,y+2)
(x+1,y-1)
(x+1,y)
(x+1,y+1)
(x+2,y)
Il suffit donc pour chaque case bleue (ou mieux: chaque case bleue du bord) de regarder ces 12 cases et de les marquer en rouge si elles ne sont pas déjà marquées en bleu. Cette stratégie s'adapte facilement à d'autres patterns d'attaque et est rapide à exécuter tant que le pattern d'attaque ne contient pas trop de cases.
Une autre amélioration possible serait de calculer dès le début du combat les distances entre toutes les paires de cases (et pas seulement la distance d'une case particulière à toutes les autres). Ça prendra un peu de temps au début (mais pas beaucoup plus que le lag que tu as avec ta stratégie actuelle) mais ensuite t'as plus jamais à recalculer des distances après chaque déplacement vu que t'as tout précalculé au départ.
Tu peux même faire ça pendant la phase de développement pour chaque map et ensuite le stocker "en dur" dans les données de la map. Comme ça les distances n'auront jamais à être calculées en jeu, tout a été calculé avant même de compiler. Ça devrait pas représenter grand chose en terme de poids sur le DD par rapport au reste du jeu.
|
~~ |
Posté dans Forum - Topic du Cinéma |
Tassle -
posté le 07/03/2022 à 11:28:59. (5274 messages postés) |
| C'est vrai qu'elle est très bien Olivia Colman ! J'ai pas vu The Father mais je l'ai bien aimée dans tous les rôles qui me viennent en tête (Broadchurch, The Favourite, Fleabag, et sans doute d'autres qui me viennent pas là). Ma copine est fan.
|
~~ |
Posté dans Forum - Tilesetify |
Tassle -
posté le 18/02/2022 à 17:41:01. (5274 messages postés) |
| Le papier est écrit Je peux partager par MP si certains sont curieux.
Si j'ai pas une autre idée de papier d'ici la semaine pro je vais pouvoir me remettre à l'implémentation de l'algo pour Tilesetify
|
~~ |
Posté dans Forum - Tilesetify |
Tassle -
posté le 16/02/2022 à 11:12:26. (5274 messages postés) |
| En fait j'ai réussi à prouver que le sous-problème sur lequel j'étais tombé (ou plutôt une variante de celui-ci) n'est pas résoluble beaucoup plus vite que ce que j'ai réussi à trouver. Du coup j'écris un papier sur le sujet que je vais soumettre à une conférence pour publication. La deadline étant cette semaine je suis pas mal en rush.
Mais du coup je suis toujours dessus, plus ou moins
|
~~ |
Posté dans Forum - Tilesetify |
Tassle -
posté le 07/02/2022 à 16:00:19. (5274 messages postés) |
| Je préfère celui de RotS aussi ^^ (le truc que j'aime moins c'est qu'il est en hauteur, je préférerais un truc aussi large que haut)
Pour l'algo je garantis rien, c'est juste une idée qui pourrait donner quelque chose pour le moment !
|
~~ |
Posté dans Forum - Tilesetify |
Tassle -
posté le 06/02/2022 à 09:16:51. (5274 messages postés) |
| Là je suis sur une piste mais qui demande un peu de sophistication algorithmique pour être implémentée efficacement. Pour l'instant il y a de la programmation dynamique, des segment trees et un algo d'approximation pour le problème du voyageur de commerce, mais il y a un problème intéressant sur lequel je butte pour avoir une complexité en temps sous-quadratique. En vrai c'est pas important et je pourrais faire une méthode bourrine à la place mais j'ai vraiment envie de le résoudre, ne serait-ce qu'en théorie.
Edit: AH je crois que j'ai réussi à trouver une méthode fonctionnant en temps n^(3/2)*(log(n))^2 en utilisant n^(1/2) segment trees différents, ce qui est nettement mieux que ma solution précédente en n^2*log(n) (et beaucoup mieux que la méthode naïve de bourrin en n^3). Du coup ça va mettre un peu de temps à implémenter tout ça mais je partagerai une fois que c'est fait.
|
~~ |
Posté dans Forum - Topic de la politique |
Tassle -
posté le 04/02/2022 à 15:45:59. (5274 messages postés) |
| Le monde diplo je lis les trucs accessibles sans abonnement (ça fait longtemps que je veux m’abonner et j'ai même reçu de l'argent spécifiquement pour ça à un anniv, mais s'abonner à quelque chose ça ressemble trop à une démarche administrative pour mon cerveau de procrastinateur). Je lis aussi Acrimed mais ça parle de médias (donc indirectement on en apprends sur l'actualité quand même). Sinon des podcasts, avant tout américains donc qui parlent plus de l'actualité US (les seuls trucs français que j'écoute c'est France Inter). Sinon ma copine lis (lisait, là ça fait un moment) The Guardian, donc parfois je lis avec elle ou elle me raconte des trucs qu'elle a lu. Sinon effectivement Youtube pas mal aussi (Blast, Le Media, Mediapart + diverses chaines d'individus)
|
~~ |
Posté dans Forum - Discussion Générale de making |
Tassle -
posté le 02/02/2022 à 15:44:12. (5274 messages postés) |
| Pas de souci, de toute façon j'ai plein de choses à faire pour le taf et ce truc c'est une des excuses que je me donne pour procrastiner (donc une excuse en moins pendant quelques jours !)
|
~~ |
Posté dans Forum - Discussion Générale de making |
Tassle -
posté le 02/02/2022 à 09:39:05. (5274 messages postés) |
| Azra: Je vais sans doute faire des tests de différentes approches mais si je trouve un truc qui marche bien je peux te filer les codes pour que tu les adaptes à ton truc si tu veux. J'ai la flemme de faire une joli interface graphique, ça m'intéresse pas trop ce côté des choses ^^
|
~~ |
Posté dans Forum - Discussion Générale de making |
Tassle -
posté le 01/02/2022 à 16:20:43. (5274 messages postés) |
| Ouais \o/ Perso je suis en train de réflechir à comment arranger les tiles de manière à ce que ce soit un peu plus cohérent que juste l'ordre dans lequel ils ont été vu de droite à gauche de haut en bas.
J'ai quelques débuts d'idées pour ça:
- Parcourir la map dans l'ordre donné par une courbe de Hilbert puis de les replacer dans l'ordre d'une seconde courbe de Hilbert dans le tileset. Ça devrait déjà augmenter un peu la cohérence spatiale.
- Permuter localement l'arrangement de tiles de manière à maximiser le nombre de tiles qui se trouvent dans la même configuration relative après suppression des doublons (par exemple, si un tile A se retrouve toujours juste à gauche d'un tile B dans la map ça serait bien que ça reste le cas dans le tileset).
- Supprimer tous les doublons mais de laisser les tiles uniques là où ils sont, puis de faire "tomber" tous les tiles dans une certaine direction à la manière d'un Tetris ou de Puissance 4.
- À partir de la map, créer un graphe dont les sommets sont les tiles et une arrête relie deux tiles si ils se retrouvent l'un à côté de l'autre quelque part dans la map de départ. Ensuite essayer de partitionner ce graphe en parties très connectées (en terme de densité d’arêtes, de k-connectivité ou que sais-je). Des techniques de détection de communauté peuvent s'avérer utiles ici.
On peut aussi essayer de combiner ces différentes approches (commencer par une méthodes globale puis faire des optimisations locales par exemple).
|
~~ |
Posté dans Forum - Discussion Générale de making |
Tassle -
posté le 01/02/2022 à 10:04:33. (5274 messages postés) |
| Cool
Mais je pense qu'on peut faire mieux au niveau de la disposition des tiles ! Ah tous ces efforts dispersés alors qu'ensemble on pourrait faire un outil parfait tel Cell absorbant C-17 et C-18
|
~~ |
Posté dans Forum - Tilesetify |
Tassle -
posté le 31/01/2022 à 11:22:27. (5274 messages postés) |
| Tkt, j'ai été pas mal occupé et je voulais apprendre un peu le Golang pour essayer avant de coder ça
Citation: En ce qui concerne le rechargement de l'image à chaque fois c'est parce qu'à ma connaissance je ne peux pas charger juste un bout d'image directement et qu'après avoir chargé mon image, complète, donc, et avoir découpé mon tile dedans ça n'est plus l'image complète. |
Mais ça ne serait pas plus rapide de simplement garder une copie de la valeur retournée par Jimp.read(map) plutôt que de rappeler la fonction à chaque fois ?
Quand je disais "Et tu fais ces mêmes trucs plus loin dans ton code" c'était pour dire que ces problèmes se répètent plus loin, c'était pas un commentaire sur la duplication de code ^^
Edit: Du coup j'ai codé un truc pour tester et je peux effectivement trouver les 2285 de l'image en environ une seconde :V
Le code en golang:
Spoiler (cliquez pour afficher)
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
| package main
import (
"fmt"
"image"
"image/draw"
"image/png"
"os"
)
func readImage(filePath string) (*image.RGBA, error) {
f, err := os.Open(filePath)
if err != nil {
return nil, err
}
defer f.Close()
img, _, err := image.Decode(f)
b := img.Bounds()
rgba_img := image.NewRGBA(image.Rect(0, 0, b.Dx(), b.Dy()))
draw.Draw(rgba_img, rgba_img.Bounds(), img, b.Min, draw.Src)
return rgba_img, err
}
func cropImage(img *image.RGBA, crop image.Rectangle) *image.RGBA {
simg := img.SubImage(crop)
b := simg.Bounds()
rgba_img := image.NewRGBA(image.Rect(0, 0, b.Dx(), b.Dy()))
draw.Draw(rgba_img, rgba_img.Bounds(), simg, b.Min, draw.Src)
return rgba_img
}
func writeImage(img image.Image, name string) error {
fd, err := os.Create(name)
if err != nil {
return err
}
defer fd.Close()
return png.Encode(fd, img)
}
func main() {
complete_img, err := readImage("azdu.png")
if err != nil {
os.Exit(1)
}
bounds := complete_img.Bounds()
pixel_width := bounds.Dx()
pixel_height := bounds.Dy()
tiles := make(map[[4 * 16 * 16]uint8]struct{})
count := 0
for x := 0; x < pixel_width; x += 16 {
for y := 0; y < pixel_height; y += 16 {
simg := cropImage(complete_img, image.Rect(x, y, x+16, y+16))
var pix_array [4 * 16 * 16]uint8
copy(pix_array[:], simg.Pix)
if _, ok := tiles[pix_array]; !ok {
tiles[pix_array] = struct{}{}
count += 1
}
}
}
fmt.Printf("count %d\n", count)
} |
(C'est du viteuf pour tester, j'ai codé tous les paramètres en dur dedans)
|
~~ |
Posté dans Forum - Tilesetify |
Tassle -
posté le 31/01/2022 à 09:27:36. (5274 messages postés) |
| Bien ouej C'est plus user-friendly que ce que j'aurais fait (j'aurais juste eu un .txt ou tu configures ce que tu veux puis tu lances un .exe sans interface graphique). C'est quand même chelou le temps d'execution, je me serais attendu à quelque chose de l'ordre de quelques secondes. T'as essayer de detecter quelle partie cause tant de soucis?
Je connais pas le JS et je trouve ça illisible mais en survolant j'ai l'impression qu'il y a des endroits de ton code qui peuvent être optimisés très facilement:
Spoiler (cliquez pour afficher)
1
2
3
4
5
6
|
for (let j=0; j<nbreVerticChunks; j++) {
console.log('Preparing file. Reading line '+(j+1)+'/'+(nbreVerticChunks)+'...')
for (let i=0; i<nbreHorizChunks; i++) {
const chunk = await Jimp.read(map)
|
Là on dirait que tu recharges l'image à chaque passage de la boucle au lieu de le faire une seule fois en dehors de la boucle.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
| let repeatingPixels;
if (chunksImgs.length > 0) {
for (let k=0; k<chunksImgs.length; k++) {
repeatingPixels = 0;
if (chunk[1] === chunksHash[k]) {
for (let m=0; m<chunckWidth; m++) {
for (let n=0; n<chunkHeight; n++) {
if (chunk[0].getPixelColor(m, n) === chunksImgs[k].getPixelColor(m, n)) {
repeatingPixels++;
}
}
}
}
if (repeatingPixels === chunckWidth*chunkHeight) {
break;
}
}
} |
Là tu comptes le nombre de pixels identiques alors que tu peux t'arrêter dès que tu en trouves deux différents. Et puis tu compares le hash de l'image avec tous les hash precedements créés. Faut utiliser un conteneur plus approprié (une table de hashage justement) ! Il doit bien y avoir une implémentation d'une table de hashage (ou d'un autre type de conteneur qui permet de tester si un objet est déjà dedans) en JS ? Là tu perds la moitié des avantages du hashage.
Et tu fais ces mêmes trucs plus loin dans ton code.
|
~~ |
Posté dans Forum - Discussion Générale de making |
Tassle -
posté le 19/01/2022 à 12:26:42. (5274 messages postés) |
| C'est quoi les contraintes pour un chispet valide ? Seulement avoir une certaine largeur et qu'il n'y ait pas deux fois le même tile ? Organiser les tiles pour que les trucs similaires soient proches ?
Je peux ptet programmer ça si j'ai une demi-heure à remplir ^^
|
~~ |
Posté dans Forum - Topic des énigmes BDM |
Tassle -
posté le 28/12/2021 à 16:05:16. (5274 messages postés) |
| Bravo, 8 points c'est le minimum
Ta technique est intéressante. Quand tu agrèges pour tous les points, tu prends le point qui diminue le plus le nombre de pairs visibles ou celui qui diminue le plus le nombre points visibles depuis un certain point ?
Pour des exemples comme celui que j'ai donné (un seul point par ligne et par colonne), on ne connait pas de méthode efficace qui trouve toujours la meilleure solution (c'est une question qui a été posée en 2009 par Demain, Harmon, Iacono, Kane et Pătraşcu). On sait en revanche que si on impose pas cette restriction (un seul point par ligne et par colonne), alors il n'existe pas de solution efficace*. Je pense que c'est également le cas pour le problème restreint mais personne n'a su le prouver en une douzaine d'années. Une autre question intéressante est: est-ce qu'on peut au moins approximer efficacement la meilleure solution ? (par exemple, toujours trouver une solution qui utilise au plus le double du nombre de points minimum). Ici le consensus semble pencher vers oui, mais on a pas non-plus su démontrer qu'il existe une telle méthode.
C'est un problème en apparence simple mais qui est profondément relié à un problème qui résiste aux efforts des mathématiciens et informaticiens depuis 1985 (la conjecture de Sleator et Tarjan concernant l'optimalité dynamique pour les arbres binaires de recherche).
*Sauf si P=NP.
|
~~ |
Posté dans Forum - Anime : best of (>o _ o)> |
Tassle -
posté le 07/12/2021 à 14:29:07. (5274 messages postés) |
| Je suis pas sûr que les deux descriptions de RotS entrent en contradiction. Si je choisis de nommer un personnage qui se révélera être un traitre Daju (verlant de Judas) ça a bien un lien avec la référence en question, mais si ça se limite qu'à ça on peut bien qualifier ça de "poudre de perlimpinpin" pour faire plaisir au joueur qui se sentira intelligent en captant la réf. (et c'est pas mal en soi, c'est juste pas très profond)
Edit: grilled
|
~~ |
Posté dans Forum - [RM2003] Création d'un simili-Mode 7 |
Tassle -
posté le 04/12/2021 à 18:43:52. (5274 messages postés) |
| Oki je vois merci
(t'as une erreur max d'eviron 34 pixels par rapport à quelque chose de plus réaliste Edit: 12.6 pixels en fait, je m'étais gouré)
|
~~ |
Posté dans Forum - [RM2003] Création d'un simili-Mode 7 |
Tassle -
posté le 03/12/2021 à 15:47:51. (5274 messages postés) |
| J'ai encore amélioré la formule pour trouver l'angle (ton problème original)
La nouvelle formule est:
(x*(45*y+31*(y-x)/2)+y*y/2)/(y*y)
Ça donne une garantie d'erreur de 0.749 pour pour des valeurs 0 <= x <= y <= 939 (et y différent de 0).
De manière plus générale, pour ceux qui veulent calculer atan2(y,x) (en degrés) pour des valeurs de y et x allant de -9 999 999 à 9 999 999 vous pouvez utiliser une des deux méthodes suivantes:
Méthode 1:
Spoiler (cliquez pour afficher)
Garantie d'erreur de 0.783 (je crois) et 0.749 pour des valeurs de x et de y entre -939 et 939 (ça j'en suis sûr).
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
|
y: = y_entree
x: = x_entree
IF y < 0:
y: * -1
END IF
IF x < 0:
x: * -1
END IF
s = 0
IF x < y:
s: = x
x: = y
y: = s
s: = 1
END IF
IF x = 0:
ANGLE = 0
Jump to Label 2
END IF
a: = x
a: + 938
a: / 939
b: = a
b: / 2
x: + b
y: + b
x: / a
y: / a
ANGLE: = x
ANGLE: - y
ANGLE: * 31
ANGLE: / 2
x: * 45
ANGLE: + x
x: / 45
ANGLE: * y
x: * x
a: x
a: / 2
ANGLE: + a
ANGLE: / x
IF s > 0:
ANGLE: * -1
ANGLE: + 90
END IF
IF x_entree < 0:
ANGLE: * -1
ANGLE: + 180
END IF
IF y_entree < 0:
ANGLE: * -1
END IF
Label 2
|
Si vous êtes sûr que les valeurs de x et y sont toujours entre -939 et 939 vous pouvez supprimer les lignes suivantes:
1
2
3
4
5
6
7
8
9
10
11
|
a: = x
a: + 938
a: / 939
b: = a
b: / 2
x: + b
y: + b
x: / a
y: / a
|
Méthode 2:
Spoiler (cliquez pour afficher)
Garantie d'erreur de 0.595 (je crois). En tout cas pour des valeurs de x et de y entre -22503 et 22503 j'en suis sûr.
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
|
y: = y_entree
x: = x_entree
IF y < 0:
y: * -1
END IF
IF x < 0:
x: * -1
END IF
s = 0
IF x < y:
s: = x
x: = y
y: = s
s: = 1
END IF
IF x = 0:
ANGLE = 0
Jump to Label 3
END IF
a: = x
a: + 22502
a: / 22503
x: / a
y: / a
a: = y
a: * 2
a: / x
IF a = 0:
a: = y
a: * 33
a: / 2
a: / x
IF a = 0:
a: = 57
b: = 0
c: = 1
Jump to Label 2
END IF
a: = y
a: * 31
a: / 10
a: / x
IF a = 0:
a: = 220
b: = 1
c: = 4
Jump to Label 2
END IF
a: = 294
b: = 13
c: = 6
Jump to Label 2
ELSE:
a: = y
a: * 35
a: / 23
a: / x
IF a = 0:
a: = 308
b: = 32
c: = 7
Jump to Label 2
END IF
a: = y
a: * 13
a: / 11
a: / x
IF a = 0:
a: = 407
b: = 100
c: = 11
Jump to Label 2
END IF
a: = 31
b: = 14
c: = 1
Jump to Label 2
END IF
Label 2
a: * y
b: * x
c: * x
ANGLE: = c
ANGLE: / 2
ANGLE: + b
ANGLE: + a
ANGLE: / c
IF s > 0:
ANGLE: * -1
ANGLE: + 90
END IF
IF x_entree < 0:
ANGLE: * -1
ANGLE: + 180
END IF
IF y_entree < 0:
ANGLE: * -1
END IF
Label 3
|
Si vous êtes sûr que les valeurs de x et y sont toujours entre -22503 et 22503 vous pouvez supprimer les lignes suivantes:
1
2
3
4
5
6
7
|
a: = x
a: + 22502
a: / 22503
x: / a
y: / a
|
|
~~ |
Posté dans Forum - [RM2003] Création d'un simili-Mode 7 |
Tassle -
posté le 02/12/2021 à 08:23:07. (5274 messages postés) |
| Oui oui ça je me souviens Mais après tu fais quoi avec cet angle ?
Parce que normalement la position de l'île sur l'écran (par rapport au centre) est proportionnelle au sinus de l'angle que t'as calculé.
|
~~ |
Posté dans Forum - [RM2003] Création d'un simili-Mode 7 |
Tassle -
posté le 01/12/2021 à 18:33:21. (5274 messages postés) |
| Ma déception est immense (nan tkt, tu fais ce que tu veux)
Mais du coup je suis curieux, t'utilises quelle formule pour savoir où placer une ile sur l'écran sans calculer de sinus ?
|
~~ |
Posté dans Tutoriels - Cosinus et Sinus, avec (+ - * /) |
Tassle -
posté le 01/12/2021 à 17:18:07. (5274 messages postés) |
| J'ai expérimenté un peu et j'ai trouvé une meilleure méthode:
Spoiler (cliquez pour afficher)
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
|
a = Angle
IF : a < 0
a *= -1
END IF
a %= 360
a -= 180
IF : a < 0
a *= -1
END IF
sign = -1
IF : a > 90
sign = 1
a *= -1
a += 180
END IF
a *= a
b = 32151
b += a
b //= 4
outputCos = 8097
outputCos -= a
outputCos *= 994
outputCos //= b
outputCos *= sign
a = 90
a -= Angle
IF : a < 0
a *= -1
END IF
a %= 360
a -= 180
IF : a < 0
a *= -1
END IF
sign = -1
IF : a > 90
sign = 1
a *= -1
a += 180
END IF
a *= a
b = 32151
b += a
b //= 4
outputSin = 8097
outputSin -= a
outputSin *= 994
outputSin //= b
outputSin *= sign
|
La vitesse est exactement la même que pour la méthode d'Anton (si on supprime ses commentaires, parce que oui chaque commentaire coûte quasi autant de temps que tout autre instruction) mais l'erreur max est de 1.35 (au lieu de 1.91 avec la méthode d'Anton).
Si a1 et a2 sont des variables d'id consécutives, de même que b1 et b2, sign1 et sign2, outputCos et outputSin, on peut améliorer très légerement la vitesse d'execution en utilisant le fait que RM2k3 permet de modifier plusieurs variables en même temps (ce qui est aussi rapide que de modifier une seule variable):
Spoiler (cliquez pour afficher)
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
|
a1 = Angle
a2 = 90
a2 -= Angle
IF : a1 < 0
a1 *= -1
END IF
IF : a2 < 0
a2 *= -1
END IF
a1, a2 %= 360
a1, a2 -= 180
IF : a1 < 0
a1 *= -1
END IF
IF : a2 < 0
a2 *= -1
END IF
sign1, sign2 = -1
IF : a1 > 90
sign1 = 1
a1 *= -1
a1 += 180
END IF
IF : a2 > 90
sign2 = 1
a2 *= -1
a2 += 180
END IF
a1 *= a1
a2 *= a2
b1, b2 = 32151
b1 += a1
b2 += a2
b1, b2 //= 4
outputCos, outputSin = 8097
outputCos -= a1
outputSin -= a2
outputCos, outputSin *= 994
outputCos //= b1
outputSin //= b2
outputCos *= sign1
outputSin *= sign2
|
(ce code est environ 11% plus rapide que le précédent, mais on utilise plus de variables différentes)
Edit: Pour ceux que ça intéresse, j'utilise une approximation par une fonction rationnelle plutôt que polynomiale. En gros cos(x) ~ 994*(8097-x^2)/((32151+x^2)/4) pour x entre -90 et 90 (avec des divisions entières). On pourrait enlever le /4 et remplacer 994 par 4*994 (= 3976) mais après les valeurs des variables pourraient dépasser le max de RM2k3.
|
~~ |
Posté dans Forum - [RM2003] Création d'un simili-Mode 7 |
Tassle -
posté le 30/11/2021 à 10:19:56. (5274 messages postés) |
| Citation: Chez moi la direction du bateau est noté à partir du nord (angle 0) puis dans le sens des aiguilles d'une montre jusqu'à l'angle 358 (les angles impairs n'existent pas, le bateau pivote de 2 en 2 sinon il tournait trop lentement). Est-ce que ça a des répercussions par rapport au code d'Anton et/ou au tien ? |
Il suffit d'ajuster dans ce cas. Si ton angle est A, mon angle c'est t = 90-A (pas de souci ci c'est négatif, le code d'Anton fonctionnera tout bien comme il faut si tu remplaces la variable qu'il appelle "Angle" par t).
Citation: L'axe des y pointe vers le bas, ça change quoi du coup ? |
Remplace y_v = y_v + (D*s/1000) par y_v = y_v - (D*s/1000).
Citation: est-ce que le système que tu me proposes compense le fait que plus le bateau se déplace en "diagonale" (sur la map virtuelle) plus sa vitesse de déplacement (d'un point à un autre) se rapproche de 1,414 fois celle obtenue lors d'un déplacement sur l'axe Nord-Sud ou Ouest-Est ? |
Yep, à erreur d'arrondie près (c'est pour ça qu'on travaille sur une grosse grille virtuelle, pour que les erreurs d'arrondie se voient pas).
En gros imaginons que 1 pas vers l'est correspond à augmenter la coordonnée x réelle de 2 (donc +2000 pour la coordonnée virtuelle). Alors si tu te déplaces en diagonale, le bateau va de temps en temps avancer de 2 en diagonale et de temps en temps de 1, pour compenser le fait que la distance en diagonale est plus grande (si tu te déplaces de 1 en diagonale tu parcours une distance de 1.4142, si t'avances de 2 tu parcours une distance de 2.8284, donc si tu fais de temps en temps l'un et de temps en temps l'autre tu peux te débrouiller pour en moyenne avancer d'une distance d'environ 2, et c'est ce que cette méthode fera).
Exemple: Si tu commences à (0,0) et que tu fais 10 pas vers le sud-est à une vitesse de 2 carreaux par pas, les coordonnées successives avec cette méthode seront:
(0, 0)
(1, 1)
(2, 2)
(4, 4)
(5, 5)
(7, 7)
(8, 8)
(9, 9)
(11, 11)
(12, 12)
(14, 14)
Au final on a parcouru une distance totale de racine(14*14 + 14*14) = 19.8 (comparé à une distance de 20 si on avait avancé droit vers le sud). Parfois la distance totale sera un peu au dessus, parfois un peu en dessous, mais globalement de manière négligeable.
Edit:
À noter que ce qu'Anton appelle outputCos et outputSin c'est déjà ce que j'appelle c et s (c'est à dire cos(t)*1000 et sin(t)*1000), pas besoin de multiplier par 1000.
|
~~ |
Posté dans Forum - [RM2003] Création d'un simili-Mode 7 |
Tassle -
posté le 30/11/2021 à 08:46:55. (5274 messages postés) |
| Citation: Tassle ( xD)
|
Au rapport
Je pense pas que ça soit compliqué de faire un déplacement à 360 degrés. L'idée c'est de faire se déplacer le bateau sur une grille virtuelle plus fine (comme dans Super Mario Bros où les coordonnées sont stockées à une échelle plus petite que le pixel).
En gros, supposons qu'on travaille sur une grille virtuelle de 240 000 * 240 000 et une grille "réelle" de 240*240.
Notons t l'angle en degrés que la direction du bateau fait depuis l'axe qui pointe vers l'est, dans le sens inverse des aiguilles d'une montre. Notons x_v et y_v les coordonnées du bateau sur la grille virtuelle et x, y les coordonnées réelles. Notons D la distance que tu veux que le bateau parcours sur la grille virtuelle en un "pas".
Quand tu veux faire un pas en avant, tu commences par utiliser le tuto d'Anton pour calculer les valeurs c = 1000*cos(t) et s = 1000*sin(t). Puis tu mets à jour les coordonnées virtuelles en faisant:
x_v = x_v + (D*c/1000)
y_v = y_v + (D*s/1000)
Puis tu mets à jour les coordonnées réelles en faisant:
x = x_v / 1000
y = y_v / 1000
(là j'ai supposé que l'axe des x pointe vers la droite et l'axe des y vers le haut, faudra changer quelques signes si c'est pas le cas chez toi)
Un autre truc:
Citation: À noter que mon code est blindé de commentaires et que mon projet sera librement copiable et modifiable par qui veut, donc ceux qui veulent pousser le truc plus loin pourront le faire. :3 |
Apparemment l’interpréteur des events RM est un peu con et il lit tous les commentaires. Ça veut dire que chaque commentaire coute à peu près autant en temps qu'une vraie commande. Donc si ça ram, supprimer tous les commentaires peut être une solution.
|
~~ |
Posté dans Forum - [RM2003] Création d'un simili-Mode 7 |
Tassle -
posté le 29/11/2021 à 18:19:17. (5274 messages postés) |
| Du coup je me suis chauffé pour coder des algos de tri plus rapides
J'ai toujours pas RM (et pas moyen de l'installer simplement sur Mac) donc j'ai toujours rien testé.
Quicksort:
Spoiler (cliquez pour afficher)
s,t,u,v,x,y,i,j,first,last et pivot sont des variables RM
N est le nombre d'objet à trier.
A et B sont des id de variables définis comme précédemment.
Q est une id de variable. L'algorithme utilise les variables d'id Q, Q+1, Q+2, ..., Q+2xN. Donc il faut être sur que modifier ces variables ne va rien casser pour les autres events. On peut par exemple mettre Q à 6000 ou un truc du genre, vu qu'on a peu tendance a utiliser des variables avec des id aussi grand (si j'ai bien compris on ne peut accéder à ces variables que par pointage par d'autres variables, pas directement)
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
| s: = Q
variable pointée par s: = 0
s: + 1
t: = N
t: - 1
variable pointée par s: = t
s: + 1
Label A
[condition] Si s>0:
s: -1
last: = variable pointée par s
s: -1
first: = variable pointée par s
[condition] Si first < last:
pivot: = valeur aléatoire entre first et last
t: = A
t: + pivot
x: = variable pointée par t
y: = A
y: + last
variable pointée par t: = variable pointée par y
variable pointée par y: = x
j: = first
i: = first
Label B
[condition] Si i < last:
t: = A
t: + i
x: = variable pointée par t
y: = A
y: + last
y: = variable pointée par y
u: = B
u: + x
u: = variable pointée par u
v: = B
v: + y
v: = variable pointée par v
[condition] si u < v:
Saut vers LabelC
[fin condition]
[condition] si u == v:
[condition] si x < y:
Saut vers LabelC
[fin condition]
[fin condition]
Saut vers Label D
Label C
y: = A
y: + j
variable pointée par t = variable pointée par y
variable pointée par y: = x
j += 1
Label D
i: + 1
Saut vers Label B
[fin condition]
t: = A
t: + j
x: = variable pointée par t
y: = A
y: + last
variable pointée par t: = variable pointée par y
variable pointée par y: = x
pivot: = j
variable pointée par s: = first
s: + 1
variable pointée par s: = pivot-1
s: + 1
variable pointée par s: = pivot+1
s: + 1
variable pointée par s: = last
s: + 1
[fin condition]
Saut vers Label A
[fin condition] |
Un hybride Quicksort/Insertion Sort (normalement encore plus rapide, voir commentaire plus bas):
Spoiler (cliquez pour afficher)
s,t,u,v,x,y,i,j,first,last et pivot sont des variables RM
N est le nombre d'objet à trier.
A et B sont des id de variables définis comme précédemment.
Q est une id de variable. L'algorithme utilise les variables d'id Q, Q+1, Q+2, ..., Q+2xN. Donc il faut être sur que modifier ces variables ne va rien casser pour les autres events. On peut par exemple mettre Q à 6000 ou un truc du genre, vu qu'on a peu tendance a utiliser des variables avec des id aussi grand (si j'ai bien compris on ne peut accéder à ces variables que par pointage par d'autres variables, pas directement)
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
| s: = Q
variable pointée par s: = 0
s: + 1
t: = N
t: - 1
variable pointée par s: = t
s: + 1
Label A
[condition] Si s>0:
s: -1
last: = variable pointée par s
s: -1
first: = variable pointée par s
first: + 9
[condition] Si first < last:
first: - 9
pivot: = valeur aléatoire entre first et last
t: = A
t: + pivot
x: = variable pointée par t
y: = A
y: + last
variable pointée par t: = variable pointée par y
variable pointée par y: = x
j: = first
i: = first
Label B
[condition] Si i < last:
t: = A
t: + i
x: = variable pointée par t
y: = A
y: + last
y: = variable pointée par y
u: = B
u: + x
u: = variable pointée par u
v: = B
v: + y
v: = variable pointée par v
[condition] si u < v:
Saut vers LabelC
[fin condition]
[condition] si u == v:
[condition] si x < y:
Saut vers LabelC
[fin condition]
[fin condition]
Saut vers Label D
Label C
y: = A
y: + j
variable pointée par t = variable pointée par y
variable pointée par y: = x
j += 1
Label D
i: + 1
Saut vers Label B
[fin condition]
t: = A
t: + j
x: = variable pointée par t
y: = A
y: + last
variable pointée par t: = variable pointée par y
variable pointée par y: = x
pivot: = j
variable pointée par s: = first
s: + 1
variable pointée par s: = pivot-1
s: + 1
variable pointée par s: = pivot+1
s: + 1
variable pointée par s: = last
s: + 1
[fin condition]
Saut vers Label A
[fin condition]
i: =1
Label 1
[condition] Si i < N:
t: = A
t: + i
x: = variable pointée par t
t: = B
t: + x
y: = variable pointée par t
j: = i
Label 2
j: - 1
[condition] Si j >= 0:
t: = A
t: + j
t: = variable pointée par t
t: + B
t: = variable pointée par t
[condition] Si t > y:
j: + A
t: = j
t: + 1
variable pointée par t: = variable pointée par j
j: - A
Saut vers label 2
[fin condition]
[fin condition]
j: + 1
j: + A
variable pointée par j: = x
i: + 1
Saut vers label 1
[fin condition] |
Dans ce code hybride je fait à un moment "first: + 9" puis plus loin "first: - 9". Ce nombre 9 peut influencer la vitesse du tri, mais la bonne valeur ne peut pas vraiment être déterminé théoriquement, faut des tests empiriques. Si vous implémentez ce code vous pouvez tester avec différentes valeurs (disons entre 5 et 20) pour voir ce qui est le plus rapide sur RM.
J'ai fait en sorte que ces tris soient également stables (l'ordre relatifs d'objets de même valeur n'est pas modifié).
Pour ton cas Nemau le code que tu as devrait être plus rapide que ces variantes plus compliquées (surtout si l'ordre n'est pas constamment chamboulé). Ces codes deviennent plus efficaces pour des grands nombres d'objets à trier. Je dirais qu'on peut envisager de changer d'algo autour d'une quarantaine/cinquantaine d'objets à trier (un peu au pif). Si on a plusieurs centaines de trucs à trier là c'est sûr que ça vaut le coup (sauf si les objets sont déjà presque triés, là il n'y aura pas beaucoup de diff).
|
~~ |
Posté dans Forum - [RM2003] Création d'un simili-Mode 7 |
Tassle -
posté le 28/11/2021 à 17:53:32. (5274 messages postés) |
| Yay \o/
Peut-être oui, j'ai pensé ça aussi:
Moi a dit: Ah je t'ai peut-être confus en parlant de numéro de variable plutôt que d'id, déso. |
Mais tant mieux si maintenant tout marche bien
|
~~ |
Posté dans Forum - [RM2003] Création d'un simili-Mode 7 |
Tassle -
posté le 28/11/2021 à 17:14:45. (5274 messages postés) |
| Nan je voulais dire "le nombre A" et "le nombre B", dans ma tête A et B n'ont jamais été des variables de RM ^^ (la variable d'id A = la variable d'id 0121)
C'est juste que je savais pas que dans ton cas ces nombres allaient être 121 et 141, donc je les ai appelés A et B (et le nombre d'iles je l'ai appelé N). Mais je vois comment tu as pu croire que c'était des variables RM, dans la vie de tous les jours c'est pas forcément commun de donner un nom à un nombre dont tu connais pas la valeur (déformation professionnelle ).
|
~~ |
Posté dans Forum - [RM2003] Création d'un simili-Mode 7 |
Tassle -
posté le 28/11/2021 à 12:16:46. (5274 messages postés) |
| Non on est pas d'accord ^^
Je crois qu'il y a confusion sur ce qu'est A. A est juste un nombre que tu remplaces par ce que tu veux (ici 121). De même que B (qui pour toi doit valoir 141).
Je t'ai fait les changements pour que t'y vois plus clair:
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
| [/code][code]
i: =1
Label 1
[condition] Si i < N:
t: = 121
t: + i
x: = variable pointée par t
t: = 141
t: + x
y: = variable pointée par t
j: = i
Label 2
j: - 1
[condition] Si j >= 0:
t: = 121
t: + j
t: = variable pointée par t
t: + 141
t: = variable pointée par t
[condition] Si t > y:
j: + 121
t: = j
t: + 1
variable pointée par t: = variable pointée par j
j: - 121
Saut vers label 2
[fin condition]
[fin condition]
j: + 1
j: + 121
variable pointée par j: = x
i: + 1
Saut vers label 1
[fin condition]
|
Et comme tu disais au début du jeu tu initialises la variable d'id 0121 à 0, celle d'id 0122 à 1, et ainsi de suite jusqu'à la variable d'id 140.
Et tu stockes tout le temps la distance de l'ile numero 0 dans la variable d'id 141, la distance de l'ile numero 1 dans la variable d'id 142, etc.
|
~~ |
Posté dans Forum - [RM2003] Création d'un simili-Mode 7 |
Tassle -
posté le 28/11/2021 à 05:38:46. (5274 messages postés) |
| Mon chat m'a réveillé et j'ai plus sommeil, donc levé tôt aujourd'hui
Citation: Bon, on est d'accord qu'au départ (dans un event qui n'est exécuté qu'une fois) il faut que je paramètre mes variables pour que vrbl_A0 = 0, vrbl_A1 = 1 etc ?
|
Yep !
|
~~ |
Posté dans Forum - [RM2003] Création d'un simili-Mode 7 |
Tassle -
posté le 28/11/2021 à 05:18:34. (5274 messages postés) |
| Ah je t'ai peut-être confus en parlant de numéro de variable plutôt que d'id, déso.
A n'est pas le numéro de la première ile ! C'est l'id de la première variable à contenir un numéro d'Ile (donc A = 121 dans ton cas, et B=141).
|
~~ |
Posté dans Forum - [RM2003] Création d'un simili-Mode 7 |
Tassle -
posté le 27/11/2021 à 22:51:23. (5274 messages postés) |
| Bah, x = la valeur de la variable A+i, non ?
C'est à toi de choisir A pour que les numéros des N iles soient stockées dans les variables numéro A, A+1, ..., A+N-1.
Concernant les égalités, le tri par insertion est ce qu'on appelle un algorithme de tri stable, c'est à dire que si deux objets ont la même valeur, ils gardent le même ordre relatif avant le tri qu'après.
|
~~ |
Posté dans Forum - [RM2003] Création d'un simili-Mode 7 |
Tassle -
posté le 27/11/2021 à 14:59:31. (5274 messages postés) |
| Faut aussi une texture pour la mer et des nuages dans le ciel \o/
Si tu veux faire ça les rotations seront faciles à gérer (suffit de translater les textures vers la gauche ou la droite), les déplacements avant/arrière demanderons peut-être plus d'effort (après tu peux avoir une animation fait main constitué de 3 ou 4 images de mer différentes).
|
~~ |
Posté dans Forum - [RM2003] Création d'un simili-Mode 7 |
Tassle -
posté le 27/11/2021 à 09:45:50. (5274 messages postés) |
| J'ai pas RM donc je peux pas tester mais voilà une proposition (c'est un tri par insertion).
On numérote les N iles 0,1,2,...,N-1.
Supposons que les numéros des N iles sont stockées dans les variables numéro A, A+1, ..., A+N-1 (au départ dans un ordre arbitraire)
Supposons que les distances des N iles sont stockées dans les variables numéro B, B+1, ..., B+N-1 (plus précisément, la distance de l'ile numéro k est stockée dans la variable numéro B+k)
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
|
i: =1
Label 1
[condition] Si i < N:
t: = A
t: + i
x: = variable pointée par t
t: = B
t: + x
y: = variable pointée par t
j: = i
Label 2
j: - 1
[condition] Si j >= 0:
t: = A
t: + j
t: = variable pointée par t
t: + B
t: = variable pointée par t
[condition] Si t > y:
j: + A
t: = j
t: + 1
variable pointée par t: = variable pointée par j
j: - A
Saut vers label 2
[fin condition]
[fin condition]
j: + 1
j: + A
variable pointée par j: = x
i: + 1
Saut vers label 1
[fin condition]
|
Si je me suis pas gouré, à la fin de ce processus les numéros des N iles seront stockées dans les variables numéro A, A+1, ..., A+N-1, dans l'ordre croissant des distances (si tu veux l'ordre décroissant, remplace la condition t > y par t < y).
(Mais il y a des chances que ça bug, je suis pas habitué à coder en events).
Je sais pas si ce code prendra du temps à être exécuté sur RM. Mais si l'ordre des distances entre les iles n'a pas (ou peu) changé, ça devrait s’exécuter rapidement. C'est une bonne nouvelle parce que quand tu te déplaces sur la map l'ordre des distances ne devrait pas être complètement chamboulé d'un coup (sauf si tu te téléportes d'un bout à l'autre de la map).
Edit:
J'ai essayé de reproduire le comportement de ce code du mieux que je peux sur Python (il y a pas de "goto" ou de sauts vers des labels sur Python) et ça à l'air de fonctionner. Après il est encore possible que j'ai mal compris le comportement de "variable pointée par machin" sur RM.
|
~~ |
Posté dans Forum - [RM2003] Création d'un simili-Mode 7 |
Tassle -
posté le 26/11/2021 à 22:46:21. (5274 messages postés) |
| Yay ça avance
Le problème c'est sans doute qu'en division entière 100/106 ça fait 0, donc quelle que soit la taille de l'île avec un zoom de 0 elle se verra pas.
En ce qui concerne le tri des distances pour un si petit nombre d'iles c'est les algo les plus simples qui sont les plus rapides (tri par sélection ou tri par insertion). Faut voir lequel est le plus simple à coder en events (le tri bulle est sans doute aussi un bon candidat pour coder en events). Les algos plus sophistiqués se justifient pas pour ce nombre d'objets à trier. Je vais pas me lancer dedans maintenant (je suis sur mon portable) mais je proposerai un truc demain si personne l'a fait entre temps.
|
~~ |
Posté dans Forum - [RM2003] Création d'un simili-Mode 7 |
Tassle -
posté le 26/11/2021 à 18:58:32. (5274 messages postés) |
| Euh j'ai décidé d'allumer mon cerveau et en fait c'est pas difficile d'avoir toujours la valeur entière la plus proche (donc une garantie d'erreur de 0.5) stockée dans x:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
| x: = d
y: = 1
Label 1
[conditon] Si x > y :
x: +y
x: /2
y: =d
y: /x
Saut vers label 1
[fin de conditon]
y: = x
y: +1
y: *x
[conditon] Si y < d :
x: +1
[fin de conditon] |
L'explication (pas la plus directe a posteriori, mais c'était mon chemin de pensée):
Spoiler (cliquez pour afficher) À la fin de la boucle, je veux tester si x+1 est plus proche de la vraie racine que x. Ça revient à tester si x+1/2 < racine(d), c'est à dire :
(x+1/2)^2 < d
Ce qui revient à:
x^2 + x + 1/4 < d
Comme je sais que x^2 + x est un entier, que d aussi et que 0 < 1/4 < 1, cette condition est vraie si et seulement si:
x^2 + x < d.
Ou autrement dit si (x+1)*x < d. Donc je stock (x+1)*x dans y et je regarde si y<d. Si c'est le cas, je dois rajouter 1 à x.
On pouvait aussi tester (2x+1)^2 < 4*d ou 4x^2 + 4x + 1 < 4d mais ça demande plus d'opérations et je voyais pas comment faire ça en modifiant seulement les variables x et y. J'ai essayé d'être économe en nombres d'opérations et variables utilisées.
|
~~ |
Posté dans Forum - [RM2003] Création d'un simili-Mode 7 |
Tassle -
posté le 26/11/2021 à 10:04:19. (5274 messages postés) |
| Le résultat le plus proche de racine(v) sera toujours x ou x+1. Tu peux tester lequel est le plus proche en regardant lequel de x*x ou (x+1)*(x+1) est le plus proche de v.
Mais si tu prends toujours x t'as déjà la garantie d'avoir une erreur de moins de 1, donc à toi de voir si ça vaut le coup de faire ce calcul supplémentaire (qui te garantira que l'erreur est d'au plus 0.5).
Edit: Il arrive que l'erreur de y soit plus que 1 (par exemple pour v = 63, où y = 9 contrairement à ce qu'à dit RotS), donc c'est pas toujours safe de prendre y. Par contre si tu prends le minimum de y et de x+1 tu seras très souvent au plus proche, et t'as encore la garantie d'avoir une erreur d'au plus 1.
Edit2: Prendre le minimum de x+1 et de y semble même garantir une erreur d'au plus 0.586, sauf pour v = 0 où l'erreur est de 1. Et comme dit RotS tu sera presque tout le temps au plus proche possible. Donc ça à l'air d'être une très bonne méthode pour faire ça simplement (sachant que la meilleure garantie possible sur l'erreur est 0.5, donc 0.586 c'est très bien)
Edit3: (Suite au dernier edit de RotS) Prendre le min de x+1 et y ne souffre pas de l'irrégularité de y, ça ne diminue jamais quand v grandit.
Et si tu veux ces qualités (presque toujours le plus proche, ne décroit jamais) sans te faire chier tu peux simplement prendre x+1 (tu perds la garantie d'erreur de 0.586 mais tu as toujours une garantie d'erreur de 1).
|
~~ |
Posté dans Forum - [RM2003] Création d'un simili-Mode 7 |
Tassle -
posté le 25/11/2021 à 22:49:13. (5274 messages postés) |
| Nope c'est pas normal ! x devrait toujours être pile l'entier le plus proche en dessous de la vraie racine (ou exactement la vraie racine si elle est entière). Et y à la fin devrait être soit égal à x, à x+1 où à x+2 il me semble (jamais x+3 ou plus).
Mais t'as pas besoin de deux copies de r1 et r2 (et la valeur de r2, càd v, ne devrait jamais changer).
En gros dans la boucle t'aurais juste :
r1: +r3
r1: /2
r3: =r2
r3: /r1
Édit : ah j'ai pas rafraîchi, grilled
Par contre ma version marche bien avec la division euclidienne, à la fin t'as x<y donc tu boucles pas à l'infini.
|
~~ |
Posté dans Forum - [RM2003] Création d'un simili-Mode 7 |
Tassle -
posté le 25/11/2021 à 18:00:52. (5274 messages postés) |
| Mathématiquement ça revient un peu au même, dans les deux cas (ta formule et celle de RotS) c'est une hyperbole (d'asymptote y=0). C'est juste que la tienne est un peu décalée vers la gauche (l'effet du +120) et qu'elle est normalisée pour valoir 100 en x=0 (l'effet du *120).
Mais en vrai un objet collé à ton œil il prend tout ton champ de vision (même si t'avais un champ de vision à 180 degrés), donc son image sur ta rétine est bien de taille infinie (en vrai quand tu passes en dessous de la distance focale minimale il n'y a même plus à proprement parler d'image, la lentille ne focalise plus les rayons lumineux venant d'un même point de l'objet et ceux-ci divergent).
|
~~ |
Aller à la page: 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
|
|
|