Voir la version complète : [GBA][Aide] Sudoku... probleme de curseur
plourdee
01/06/2008, 17h04
Bonjour, je fais presentement un jeu de style sudoku. Petite exlication quant au fonctionnement. La grille a 81 cases 16x16. J'utilise un sprite 16x16(un style de curseur) qui permet de sélectionner la case voulu pour modifier la valeur (1 à 9).
J'ai des problemes avec ce sprite. J'aimerais bien qu'il avance par intervalle de 16 pixels, mais lorsque j'appuie sur le bouton de droite par exemple, il saute 4- 5 cases. Est-ce qu'il y a une méthode possible pour empecher cela c'est-à-dire avoir une pause entre la lecture des boutons ou qqch du genre.
J'ai une fontion MoveSprite standanrd:
void MoveSprite(OAMEntry* sp, int x, int y)
{
sp->attribute1 = sp->attribute1 & 0xFE00;
sp->attribute1 = sp->attribute1 | x;
sp->attribute0 = sp->attribute0 & 0xFF00;
sp->attribute0 = sp->attribute0 | y;
}
et ma fonction MoveCurseur:
void MoveCurseur(void)
{
if(keyDown(KEY_UP))
yCurseur-=16;
if(keyDown(KEY_DOWN))
yCurseur += 16;
if(keyDown(KEY_LEFT))
xCurseur-=16;
if(keyDown(KEY_RIGHT))
xCurseur+=16;
}
Merci
Salut ^^,
En fait la fonction/macro keyDown(D) retourne TRUE si la direction D est actuellement appuyée. Donc même si tu relâches très rapidement la touche, ta boucle principale sera exécutée plusieurs fois ; dans ton cas donc 4 ou 5 fois apparemment.
Une idée "simple" serait d'associer un boolean à chaque direction, genre :
char bool_direction[4];
puis réimplémenter les fonction keyDown(*) :
int ma_keyDown(int d)
{
bool_direction[d] = keyDown(d);
return keyDown(d);
}
après tes tests deviendrais :
if( !bool_direction[KEY_UP] && ma_keyDown(KEY_UP))
yCurseur-=16;
L'idée est donc de vérifier si bool_direction est à FALSE (ce qui voudrait dire que soit la touche * vient juste d'être pressée , soit elle ne l'est pas). On lève l'indétermination avec la fonction réimplémentée ma_keyDown(*), qui va retourner TRUE si la touche * est actuellement pressée est mettre à vrai le boolean associée (ce qui signifiera à la prochaine exécution de la boucle que la touche à DEJA était pressée).
Voilà en gros ce que j'aurais fais (je crois :fleur:) ... pas sûr-sûr que ça fonctionne nickel, faut tester :).
Il reste le problème des constantes KEY_UP, KEY_DOWN , ... qui sont surement pas défini comme étant 0, 1, 2, 3 (je me rappel plus trop) et donc ne correspondrait pas une case du tableau bool_direction[ ].
Y'aurait juste à definir des nouvelles constantes OU une fonction/macro qui associe les constantes KEY_* à leurs images 0, 1, 2, 3.
Il me semble que les bits associé au touches directionnelles sur le R_CTRLINPUT était les bits 4,5,6,7. Si c'est ça pour toi aussi alors la fonction de correspondance est toute simple ^^ :
int correspondance(int KEY)
{
return KEY-4;
}
et donc on aurait les tests et fonction :
int ma_keyDown(int d)
{
bool_direction[ correspondance(d) ] = keyDown(d);
return keyDown(d);
}
if( !bool_direction[correspondance(KEY_UP)] && ma_keyDown(KEY_UP))
yCurseur-=16;
---
Bon j'viens de relire ton post :whst: et si tu veux faire avancer le curseur au pas et non à chaque pression d'une direction (comme j'viens d'essayer de l'expliquer), avec les même fonctions tu peux faire ça :
int ma_keyDown(int d)
{
bool_direction[ correspondance(d) ] = (bool_direction[ corredpondance(d) ] +1)* keyDown(d);
return keyDown(d);
}
La seule différence est que bool_direction[ ] sert à présent de compteur ( compteur en "char" donc de 0 à 255 ). Sa valeur s'incrémente tant que la touche est pressée et revient de lui même à 0 ( après le 255 ). Si le délai est trop lent ainsi, essaye de changer le +1 en +2. Si le délai est trop rapide passe le tableau bool_direction[ ] en "int" et modifie l'incrément selon la vitesse que tu souhaites :).
Bizarre... keyDown (à la différence de keyHeld) n'est censé rapporter la touche qu'au moment où elle est pressée :huh:
Le problème est peut être ailleurs :ninja:
Bizarre... keyDown (à la différence de keyHeld) n'est censé rapporter la touche qu'au moment où elle est pressée :huh:
Le problème est peut être ailleurs :ninja:
:huh: ... bah ouais ^^ ! Mais j'étais parti du principe qu'il avait écrit-lui même la fonction keyDown() ( vu qu'il avait écrit la fonction MoveSprite() ).
A confirmer :) !
plourdee
01/06/2008, 19h44
en fait ma fonction keydown est comme suit:
#define KEYS *(volatile u16*)0x04000130
#define keyDown(k) (~KEYS & k)
Donc c'est bien ce que dit Kyros.
Il faut soit que tu définisse un timer pour la répétition, soit que tu oblige le joueur a lâcher la touche (voir méthode de Kyros ci dessus)...
Je t'invite a regarder Picross Advance, le curseur est ce que je préfère dans ce jeu :p (je ne sais plus si je le dois a Brunni ou a YodaJr...)
plourdee
02/06/2008, 01h17
j'ai essayé l;a solution de klyros mais ca ne fonctionne pas. le curseur bouge une fois et c'est terminé...
j'ai essayé l;a solution de klyros mais ca ne fonctionne pas. le curseur bouge une fois et c'est terminé...
Dommage :lol: ! Ca me paraissait pas mal pourtant ^^ ...
---
whé en fait l'erreur vient du fait qu'une fois que la fonction réimplémentée ma_keyDown() est déclanchée, alors la variable bool_direction[ ] s'incrémente donc elle est supérieur à 0 (elle est même égale à 1 :D) et donc la condition "!bool_direction[ ]" ( qu'il faudrait d'ailleurs changé en "bool_direction[ ] == 0" ) sera toujours fausse ... tout ça pour dire que du fait du "et puis ~ &&" la fonction ma_keyDown() ne sera plus jamais executée et donc la variable bool_direction[ ] restera bloquée à 1.
Ouf >_< !
Donc là tout de suite j'te dirais de remplacer le "&&" par un "&" simple pour que les deux conditions/fonctions soient toujours évaluées.
Mais pareil, j'te dis ça sans pouvoir vérifier :ange: - j'pense quand même pas que ça soit archi-faux, mais j'énonce ça de tête quoi :whst:.
Si j'ai le temps je resors HAM de son carton à midi et je test quand même :).
---
Bah ca fonctionne - j'ai juste crée une constante DELAY ... et la condition c'est "0 < bool_direction[ ] <= DELAY" et non "bool_direction[ ] == 0".
#include <mygba.h>
void vbl(void);
int newFrame;
char bool_direction[4];
#define input(v) ((~R_CTRLINPUT & (1<<v))>>v)
#define T_A 0
#define T_B 1
#define T_SELECT 2
#define T_START 3
#define T_RIGHT 4
#define T_LEFT 5
#define T_UP 6
#define T_DOWN 7
#define T_R 8
#define T_L 9
#define DELAY 20
int correspondance( int KEY )
{
return KEY-4;
}
int ma_input( int d )
{
bool_direction[ correspondance(d) ] = (bool_direction[ correspondance(d) ] + DELAY )*input(d);
return input(d);
}
int main(void)
{
ham_Init();
ham_StartIntHandler(INT_TYPE_VBL,(void*)&vbl);
while(TRUE)
{
if( newFrame )
{
if( (bool_direction[ correspondance(T_RIGHT) ] > 0) &
(bool_direction[ correspondance(T_RIGHT) ] <= DELAY) &
(ma_input(T_RIGHT)) )
{
ham_VBAText("RIGHT\n");
}
newFrame = 0;
}
}
return 0;
}
void vbl(void)
{
ham_CopyObjToOAM();
newFrame = 1;
}
vBulletin® v.3.7.2, Copyright ©2000-2008, Jelsoft Enterprises Ltd. Tous droits réservés - Version française vbulletin-fr.org