Snake - problem z rozjeżdżaniem się węża
Ostatnio zmodyfikowano 2012-02-27 06:38
programista12 Temat założony przez niniejszego użytkownika |
Snake - problem z rozjeżdżaniem się węża » 2012-02-26 20:04:18 Próbuję napisać snake'a w SDL. Udało mi się już zrobić dodawanie segmentów węża i poruszanie się. Jednak z poruszaniem się węża mam problem. Normalnie wąż chodzi prawidłowo, ale jeżeli szybko nacisnę np. strzałkę w górę i w lewo, to jego ciało się rozjeżdża - pierwszy i czasami drugi segment (od głowy licząc) idą prawidłowo, a reszta idzie w starym kierunku. Tu na forum wyczytałem, że to wina nadpisujących się eventów. Próbowałem zapamiętać wciśnięty klawisz, ale to nic nie dało. Może algorytm poruszania segmentami jest zły? Oto klasa węża: #pragma once #include <vector> #include <SDL/SDL.h> #include <SDL/SDL_ttf.h> #include <SDL/SDL_gfxPrimitives.h> #include "timer.h" #include "functions.h"
using namespace std;
enum DIRECTION { LEFT, RIGHT, UP, DOWN };
struct Segment { int x, y; DIRECTION dir; Segment( int nx, int ny, DIRECTION ndir ) { x = nx; y = ny; dir = ndir; } Segment() { } void Move( int speed ) { if( dir == UP ) y -= 10; if( dir == DOWN ) y += 10; if( dir == LEFT ) x -= 10; if( dir == RIGHT ) x += 10; } void Show( SDL_Surface * dst ) { boxRGBA( dst, x, y, x + 10, y + 10, 0, 255, 0, 255 ); } };
class Snake { private: int x, y, speed; vector < Segment > segments; DIRECTION dir; void SetUpSegments(); public: Snake(); void HandleEvents( SDL_Event e ); void Show( SDL_Surface * dst, TTF_Font * f ); void Move( SDL_Surface * dst ); void Eat(); SDL_Rect GetRect(); };
#include "Snake.h"
Snake::Snake() { x = y = 450; speed = 150; dir = UP; segments.push_back( Segment( 450, 460, UP ) ); }
void Snake::HandleEvents( SDL_Event e ) { static SDLKey k; if( e.type == SDL_KEYDOWN ) { if( e.key.keysym.sym == SDLK_LEFT && dir != RIGHT ) k = SDLK_LEFT; if( e.key.keysym.sym == SDLK_RIGHT && dir != LEFT ) k = SDLK_RIGHT; if( e.key.keysym.sym == SDLK_UP && dir != DOWN ) k = SDLK_UP; if( e.key.keysym.sym == SDLK_DOWN && dir != UP ) k = SDLK_DOWN; if( e.key.keysym.sym == SDLK_a ) speed++; if( e.key.keysym.sym == SDLK_z ) speed--; } if( k == SDLK_LEFT ) dir = LEFT; else if( k == SDLK_RIGHT ) dir = RIGHT; else if( k == SDLK_UP ) dir = UP; else if( k == SDLK_DOWN ) dir = DOWN; else return; }
void Snake::Show( SDL_Surface * dst ) { boxRGBA( dst, x, y, x + 10, y + 10, 50, 128, 0, 255 ); for( unsigned i = 0; i < segments.size(); i++ ) segments[ i ].Show( dst ); }
void Snake::Move( SDL_Surface * dst ) { static Timer t; static bool a = false; if( !a ) { t.start(); a = true; } if( t.get_ticks() >= speed ) { if( dir == LEFT ) x -= 10; if( dir == RIGHT ) x += 10; if( dir == UP ) y -= 10; if( dir == DOWN ) y += 10; for( unsigned i = 0; i < segments.size(); i++ ) segments[ i ].Move( speed ); SetUpSegments(); t.start(); } }
void Snake::Eat() { Segment s = segments.back(); int nx, ny; DIRECTION ndir; if( dir == UP ) { if( s.dir == UP ) { nx = s.x; ny = s.y + 10; ndir = UP; } if( s.dir == DOWN ) { nx = s.x; ny = s.y - 10; ndir = DOWN; } if( s.dir == LEFT ) { nx = s.x + 10; ny = s.y; ndir = LEFT; } if( s.dir == RIGHT ) { nx = s.x - 10; ny = s.y; ndir = RIGHT; } } if( dir == DOWN ) { if( s.dir == UP ) { nx = s.x; ny = s.y + 10; ndir = UP; } if( s.dir == DOWN ) { nx = s.x; ny = s.y - 10; ndir = DOWN; } if( s.dir == LEFT ) { nx = s.x - 10; ny = s.y; ndir = LEFT; } if( s.dir == RIGHT ) { nx = s.x + 10; ny = s.y; ndir = RIGHT; } } if( dir == LEFT ) { if( s.dir == UP ) { nx = s.x; ny = s.y + 10; ndir = UP; } if( s.dir == DOWN ) { nx = s.x; ny = s.y - 10; ndir = UP; } if( s.dir == LEFT ) { nx = s.x + 10; ny = s.y; ndir = LEFT; } if( s.dir == RIGHT ) { nx = s.x - 10; ny = s.y; ndir = RIGHT; } } if( dir == RIGHT ) { if( s.dir == UP ) { nx = s.x; ny = s.y + 10; ndir = UP; } if( s.dir == DOWN ) { nx = s.x; ny = s.y - 10; ndir = DOWN; } if( s.dir == LEFT ) { nx = s.x + 10; ny = s.y; ndir = LEFT; } if( s.dir == RIGHT ) { nx = s.x - 10; ny = s.y; ndir = RIGHT; } } segments.push_back( Segment( nx, ny, ndir ) ); }
void Snake::SetUpSegments() { for( int i = 0; i < segments.size(); i++ ) { if( i == 0 ) { if( dir == UP || dir == DOWN ) { if( segments[ i ].dir == LEFT || segments[ i ].dir == RIGHT ) { if( segments[ i ].x == x ) segments[ i ].dir = dir; } else { if( segments[ i ].y == y ) segments[ i ].dir = dir; } } if( dir == LEFT || dir == RIGHT ) { if( segments[ i ].dir == UP || segments[ i ].dir == DOWN ) { if( segments[ i ].y == y ) segments[ i ].dir = dir; } else { if( segments[ i ].x == x ) segments[ i ].dir = dir; } } } else { if( segments[ i - 1 ].dir == UP || segments[ i - 1 ].dir == DOWN ) { if( segments[ i ].dir == LEFT || segments[ i ].dir == RIGHT ) { if( segments[ i ].x == segments[ i - 1 ].x ) segments[ i ].dir = segments[ i - 1 ].dir; } else { if( segments[ i ].y == segments[ i - 1 ].y ) segments[ i ].dir = segments[ i - 1 ].dir; } } if( segments[ i - 1 ].dir == LEFT || segments[ i - 1 ].dir == RIGHT ) { if( segments[ i ].dir == UP || segments[ i ].dir == DOWN ) { if( segments[ i ].y == segments[ i - 1 ].y ) segments[ i ].dir = segments[ i - 1 ].dir; } else { if( segments[ i ].x == segments[ i - 1 ].x ) segments[ i ].dir = segments[ i - 1 ].dir; } } } } }
SDL_Rect Snake::GetRect() { SDL_Rect r; r.x = x; r.y = y; r.w = r.h = 10; return r; }
Z góry dzięki za pomoc. |
|
RazzorFlame |
» 2012-02-26 20:41:52 emm nie wiem czy to zadziala ale zmien na Uint8 * keystate = SDL_GetKeyState( NULL ); i pózniej uzywaj tego: if( keystate[ SDLK_ < klawisz > ] )
Zreszta tak jest w kursie |
|
programista12 Temat założony przez niniejszego użytkownika |
» 2012-02-27 06:38:37 Niestety, nie działa. |
|
« 1 » |