RPGDXThe center of Indie-RPG gaming
Not logged in. [log in] [register]
 
 
Post new topic Reply to topic  
View previous topic - View next topic  
Author Message
Chrono
Lowly Slime


Joined: 29 Aug 2007
Posts: 3

PostPosted: Sun Sep 09, 2007 2:51 am    Post subject: C++ Need help with Diagonal Movement [quote]

Well me and a friend made a great walking engine for our game but we didn't manage to add diagonal movement like the zelda game.

If you could help that'd be great, heres the code.

Code:
#include <stdlib>
#include <stdio>
#include <SDL>

/* Test : réaliser une animation de sprite. Par Bestguigui.
La planche utilisée est celle du sprite de Duran de Seiken 3
Chaque ligne fait 32 pixels de haut, chaque case 25 pixels de large.

L'ordre est le suivant, de haut en bas :
- droite
- gauche
- bas
- haut
Le sprite le plus à gauche est toujours la position à l'arrêt de la direction correspondante.
L'animation commence donc à la seconde case en partant de la gauche, dans toutes les directions.
*/

int main(int argc, char *argv[])
{

// On crée les surfaces de l'écran et du personnage
SDL_Surface *ecran = NULL, *perso = NULL, *background;

SDL_Rect positionPerso, positionRectif, positionBackground; //La position rectif correspond à la portion à découper
positionPerso.x = 10;
positionPerso.y = 100;
positionBackground.x = 0;
positionBackground.y = 0;

positionRectif.x = 0;
positionRectif.y = 0;
positionRectif.w = 25;
positionRectif.h = 32;


/*
Ici nous avons placé des coordonnéees temporaires pour le personnage (position de départ).
Nous avons aussi configuré les quatre valeurs de découpage pour la fonction blitte du perso,
correpondant aux caractéristiques de la planche du sprite.
*/

// initialisation de la SDL
SDL_Init(SDL_INIT_VIDEO);

// Masquer curseur souris
SDL_ShowCursor(SDL_DISABLE);

// Création de l'écran
ecran = SDL_SetVideoMode(256, 223, 32, SDL_HWSURFACE | SDL_DOUBLEBUF | SDL_RESIZABLE);
SDL_WM_SetCaption("Yu Yu Hakusho", NULL);

// Préparation de la boucle principale
int continuer = 1; // initialisation d'un bouléen
SDL_Event event; // et d'un évènement

// Chargement du bitmap du perso et transparence
perso = SDL_LoadBMP("images/duran_full.bmp");
SDL_SetColorKey(perso, SDL_SRCCOLORKEY, SDL_MapRGB(perso->format, 64, 255, 64));

// Chargement du background
background = SDL_LoadBMP("images/fond_seiken3.bmp");

// Activation de la répétition de touches
SDL_EnableKeyRepeat(90, 90);

// BOUCLE PRINCIPALE
while(continuer)
      {
       SDL_WaitEvent(&event);
       switch(event.type)
           { // Début EVENT.TYPE
           
            case SDL_QUIT: // Si la croix est fermée
            continuer=0;
            break;
           
            case SDL_KEYDOWN: // Si une touche est pressée
           
                 switch(event.key.keysym.sym) // Analyse de la touche pressée
                 { // Début analyse touche pressée
                 
                       case SDLK_ESCAPE: // Touche ECHAP pressée
                       continuer=0;
                       break;
                       
                       case SDLK_UP: // Touche HAUT pressée
                       positionPerso.y-=3;
                       // On place le curseur découpage
                       positionRectif.y = 96;
                       positionRectif.x+=25;
                       break;
                       
                       case SDLK_DOWN: // Touche BAS pressée
                       positionPerso.y+=3;
                       // On place le curseur découpage
                       positionRectif.y = 64;
                       positionRectif.x+=25;
                       break;
                       
                       case SDLK_LEFT: // Touche GAUCHE pressée
                       positionPerso.x-=3;
                       // On place le curseur découpage
                       positionRectif.y = 32;
                       positionRectif.x+=25;
                       break;
                       
                       case SDLK_RIGHT: // Touche DROITE pressée
                       positionPerso.x+=3;
                       // On place le curseur découpage
                       positionRectif.y = 0;
                       positionRectif.x+=25;
                       break;
                           
                 } // Fin analyse touche pressée             
           
           break; // Break du case SDL_KEYDOWN
           
           default: // Position arrêt si aucune touche pressée
           positionRectif.x = 0;
           break;
                                 
           } // Fin EVENT.TYPE
     
      // Affichage du sprite
     
      if (positionRectif.x>150) // On s'assure de ne pas sortir de la planche du sprite
      positionRectif.x=25;
     
      SDL_UpdateRects(perso, 1, &positionRectif); // Actualisation du découpage de la planche de sprites
     
      SDL_FillRect(ecran, NULL, SDL_MapRGB(ecran->format, 0, 0, 0)); // Effacement de l'écran
      SDL_BlitSurface(background, NULL, ecran, &positionBackground); // Affichage du background
      SDL_BlitSurface(perso, &positionRectif, ecran, &positionPerso); // Blitte du perso sur l'écran
      SDL_Flip(ecran); // Actualisation de l'écran
                     
      } // FIN BOUCLE PRINCIPALE

SDL_FreeSurface(perso);
SDL_FreeSurface(background);
SDL_Quit();

return EXIT_SUCCESS;
}


XD We're having allot more fun writing this from scratch than using a game engine.. this fun^^!
Back to top  
Rainer Deyke
Demon Hunter


Joined: 05 Jun 2002
Posts: 672

PostPosted: Sun Sep 09, 2007 6:55 am    Post subject: [quote]

Do not use key repeat.

At regular intervals, check if the arrow keys are pressed. Move if they are.

Relevant functions: SDL_GetTicks and SDL_GetKeyState.
Back to top  
Scrim
Mandrake's Little Slap Bitch


Joined: 05 Apr 2007
Posts: 69
Location: Canada

PostPosted: Sun Sep 09, 2007 5:57 pm    Post subject: [quote]

Rainer is right, you are better off checking whether keys are down at regular intervals. There are a couple of advantages:

One, the rate of movement of your sprites isn't tied to the key repeat rate. You can have a separate game loop using its own timing logic to keep all your sprites moving consistently. This is especially important if you want NPCs to move around while the player is standing still, for example. Also, I have no idea if the key repeat rate is something you can count on to be exactly the same on all OS's / hardware (though I assume SDL_EnableKeyRepeat takes that into account).

For another, diagonal movement is handled fairly easily: when you check for input and determine that a pair of keys are down simultaneously (up and right, say), you can perform a diagonal move. This is a bit harder to do if you are detecting individual key presses (or repeats) in series.

Another option is to only catch key_pressed and key_released events (or whatever the equivalent terminology is in SDL): when you detect that a key has been pressed, you put your sprite in the appropriate a "moving" state and update its position every frame. Once the key is released, movement in that direction stops. This is basically equivalent to Rainer's suggestion in that you would have a game loop with its own timing driving the rate of sprite movement. It's a bit more complex though, since you have to keep track of the state of the arrow keys so you can tell when a pair of them are down at once.
Back to top  
Post new topic Reply to topic Page 1 of 1 All times are GMT
 



Display posts from previous:   
Jump to:  
You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum
You cannot vote in polls in this forum