Panel użytkownika
Nazwa użytkownika:
Hasło:
Nie masz jeszcze konta?

[SDL] Kafelki + przewijanie mapy

Ostatnio zmodyfikowano 2011-04-28 22:10
Autor Wiadomość
kamillo121
» 2011-04-26 14:51:47

dpowiada za ruch tła przy naciśnięciu strzałki w prawo. Bez tego stałoby nieruchomo,
Tak ?  może jak wszystko wiesz gdzie tkwi problem to nie pytaj nas tylko sam rusz tyłek i to napraw..
Co rozumiesz przez "poruszanie mapą", wprawianie w ruch itd  ?  kafelki rysowane są zależnie od pozycji kamery a potem jeszcze cały bufor rysowany jest w zależności od scrolla w twoim przypadku, może od razu wpraw w ruch monitor będzie szybciej ?


Twój kod:

Struktura sdl_rect której używasz przy blitowaniu bufora na ekran ma niby określać kwadrat pozycji twojej mapy, więc powinieneś go tylko używać do rysowania mapy a nie do rysowania bufora na właściwą powierzchnię video, twoja mapa ma się składać z kafli a nie z jednej dużej bitmapy dlatego też rysujesz poszczególne kafle.
Ty podajesz strukturę przy rysowaniu bufora na ekran dzięki czemu, gdy wykonasz ruch strzałką np w lewo kwadrat "przesunie" się w lewo i ileś tam pikseli czyli wynikiem powinny być nałożony obraz bufora o ileś tam pikseli w lewo a reszta zostanie taka jak była w wyniku czego może powstać rozmazany obraz w pewnej części ekranu (w zależności w którą stronę przesuniesz)


Poza tym nie ustawiaj dwóch powierzchni video, jeżeli chcesz mieć bufor to utwórz sobie na nim powierzchnie zwykłą.

Przeanalizuj dokładnie kod, to co inni ci napisali a potem odpisz...
P-32009
mundzio123
Temat założony przez niniejszego użytkownika
» 2011-04-26 16:05:40
Aha... to już przynajmniej wiem co robiłem źle. Próbowałem jeszcze zrobić to sam, lecz wyszedł mi taki kod i takie coś:
C/C++
#include <SDL/SDL.h>
#include "czas.hpp"

SDL_Surface * ekran = NULL;
SDL_Surface * grass = NULL;

SDL_Rect rPole, MapaDestination;

SDL_Surface * ziemia = NULL;

SDL_Event zdarzenie;


//Tablica z mapą
int pole[ 10 ][ 19 ] = {
    { 1, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0 },
    { 1, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0 },
    { 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 1, 1 },
    { 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0 },
    { 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 0 },
    { 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 0, 0 },
    { 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 0, 0, 0 },
    { 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 0, 0, 0, 0, 0 },
    { 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 },
    { 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1 },
};

const int FRAMES_PER_SECOND = 20;
bool koniec = false, cap = true;
Uint8 * keystate = SDL_GetKeyState( NULL );
Timer fps;

//Funkcja rysująca mape
void ruch()
{
    for( int i = 0; i < 10; i++ )
    {
        for( int j = 0; j < 19; j++ )
        {
            if( pole[ i ][ j ] == 0 )
            {
                SDL_BlitSurface( ziemia, NULL, ekran, & rPole );
            }
            if( pole[ i ][ j ] == 1 )
            {
                SDL_BlitSurface( grass, NULL, ekran, & rPole );
            }
            rPole.x = rPole.x + 50;
        }
        rPole.y = rPole.y + 50;
        rPole.x = 0;
    }
}


int main( int argc, char * args[] )
{
    SDL_Init( SDL_INIT_EVERYTHING );
    ekran = SDL_SetVideoMode( 500, 500, 32, SDL_DOUBLEBUF | SDL_SWSURFACE );
    grass = SDL_LoadBMP( "sprite/grass.bmp" );
    ziemia = SDL_LoadBMP( "sprite/ziemia.bmp" );
    ruch();
   
    while( koniec != true )
    {
        fps.start();
        while( SDL_PollEvent( & zdarzenie ) )
        {
            if( zdarzenie.type == SDL_QUIT )
            {
                koniec = true;
            }
        }
        if( fps.get_ticks() < 1000 / FRAMES_PER_SECOND )
        { SDL_Delay(( 1000 / FRAMES_PER_SECOND ) - fps.get_ticks() ); }
       
        if( keystate[ SDLK_RIGHT ] ) {
            rPole.x--;
            ruch();
        }
       
        SDL_Flip( ekran );
       
    }
}

Po dłuższym przytrzymaniu prawej strzałki z ekranem dzieją się te dziwne rzeczy

[url]
http://www.speedyshare.com/files/28155606/p003.exe
[/url]
P-32026
Gabes
» 2011-04-26 16:26:47
Jaka wersja SDL.
aha 1.2.13.0
P-32028
kamillo121
» 2011-04-26 17:10:06
Po zagłębieniu się w kod stwierdzam, że to jest źle zaprojektowane.
Zerknij w ten link który ci wysłałem do lazyfoo albo przemyśl wszystko na spokojnie.

Np rPole to kwadrat, który jest używany przy rysowaniu kafli, po pierwszym rysowaniu kwadrat ma wartości skrajne (czyli wychodzące za powierzchnie ekranu) potem przy następnym rysowaniu zaczynasz rysowanie od końcówki czyli tylko "draśnie ekran".
Przeczytaj ten artykuł lazyfoo.

http://www.easykoder.vot.pl/arty/wyswietlanie_mapy Jest tam prosty przykład scrollowania mapy w Allegro, popatrz na samą idee tworzenia scrollowanych map kafelkowych.
P-32036
mundzio123
Temat założony przez niniejszego użytkownika
» 2011-04-28 12:30:31
C/C++
#include <SDL/SDL.h>
#include "czas.hpp"

SDL_Surface * ekran = NULL;
SDL_Surface * grass = NULL;

SDL_Rect rPole, MapaDestination;

SDL_Surface * ziemia = NULL;

SDL_Event zdarzenie;


//Tablica z mapą
int pole[ 10 ][ 19 ] = {
    { 1, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0 },
    { 1, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0 },
    { 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 1, 1 },
    { 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0 },
    { 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 0 },
    { 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 0, 0 },
    { 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 0, 0, 0 },
    { 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 0, 0, 0, 0, 0 },
    { 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 },
    { 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1 },
};

const int FRAMES_PER_SECOND = 20;
bool koniec = false, cap = true;
Uint8 * keystate = SDL_GetKeyState( NULL );
Timer fps;

int map_x, map_y;

//Funkcja rysująca mape
void ruch()
{
    rPole.y = 0;
    for( int i = 0; i < 10; i++ )
    {
        for( int j = 0; j < 10; j++ )
        {
            if( pole[ i ][ j ] == 0 )
            {
                SDL_BlitSurface( ziemia, NULL, ekran, & rPole );
            }
            if( pole[ i ][ j ] == 1 )
            {
                SDL_BlitSurface( grass, NULL, ekran, & rPole );
            }
            rPole.x = rPole.x + 50;
        }
        rPole.y = rPole.y + 50;
        rPole.x = 0;
    }
}


int main( int argc, char * args[] )
{
    SDL_Init( SDL_INIT_EVERYTHING );
    ekran = SDL_SetVideoMode( 500, 500, 32, SDL_DOUBLEBUF | SDL_SWSURFACE );
    grass = SDL_LoadBMP( "sprite/grass.bmp" );
    ziemia = SDL_LoadBMP( "sprite/ziemia.bmp" );
    ruch();
   
    while( koniec != true )
    {
        fps.start();
        while( SDL_PollEvent( & zdarzenie ) )
        {
            if( zdarzenie.type == SDL_QUIT )
            {
                koniec = true;
            }
        }
        if( fps.get_ticks() < 1000 / FRAMES_PER_SECOND )
        { SDL_Delay(( 1000 / FRAMES_PER_SECOND ) - fps.get_ticks() ); }
       
        if( keystate[ SDLK_RIGHT ] ) {
            map_x++;
            ruch();;
        }
       
        SDL_Flip( ekran );
       
    }
}

Taki mam kod i jestem w kropce... Allegro to troche co innego niż SDL i nie wiem jak mam zrobić coś takiego jak w tutorialu easycodera. Za mało w tym jest argumentów ? Wiem że musze zacząć rysowanie mapy od punktu map_x. Tylko nie mam kompletnego pojęcia jak. Czy mógłby ktoś podać gotowy kod tego ? Bo mi się pomysły już wyczerpały. Z lazyfoo prawie nic nie rozumiem, bo tam wszystkie lekcje to jest kod, który zaczyna się w pierwszej a kończy na ostatniej i kawałek z kodu ciężko jest wziąść i wszystko jest na klasy a to troche mnie przerasta ;/
P-32141
kamillo121
» 2011-04-28 21:46:55
Jest tyle gotowych rozwiązań, że wątpię by ktoś ci podał gotowy kod.

Jeżeli klasy/struktury cię obecnie przerastają no to zrób tak, masz ustalone szerokość i wysokość kafla czyli wiesz ile kafli zmieści się na szerokość i wysokość.

Teraz trzeba obmyślić jak wyświetlać kafle względem pozycji.
Skoro wszystkie kafle masz umieszczone w jednej tablicy to będzie ci potrzebna zmienna, która będzie określać pozycję aktualną:
żeby sobie ułatwić i nie namieszać w kodzie utworzymy prostą strukturę

C/C++
struct kamera
{
    int x, y;
   
    kamera()
    {
        x = 0;
        y = 0;
    }
};

Teraz tworzysz obiekt takiej struktury i gdy naciśniesz strzałką w dół to zwiększysz y jak w lewo to zmniejszysz x itd.

C/C++
kamera nowa_kamera;

if( keystate[ SDLK_RIGHT ] )
{
    nowa_kamera.x += jakas_wartosc;
}

if( keystate[ SDLK_LEFT ] )
{
    if( nowa_kamera.x - jakas_wartosc >= 0 )
         nowa_kamera.x -= jakas_wartosc;
   
}

if( keystate[ SDLK_DOWN ] )
{
    nowa_kamera.y += jakas_wartosc;
}


if( keystate[ SDLK_UP ] )
{
    if( nowa_kamera.y - jakas_wartosc >= 0 )
         nowa_kamera.y -= jakas_wartosc;
   
}


Teraz przejdźmy do wyświetlania, jeżeli wiesz jakie wymiary ma każdy kafel (przyjmijmy że każdy ma takie same), wiesz na jakiej pozycji jest "kamera" to teraz wystarczy obliczyć od którego indeksu zacznie się wyświetlanie, jak to zrobić ?

C/C++
x = floor( nowa_kamera.x / szerokosc_kafla );
y = floor( nowa_kamera.y / wysokosc_kafla );

Mamy indeksy teraz tylko wyświetlić:

C/C++
SDL_Rect kwadrat_kl;

kwadrat_kl.w = szerokosc_kafla;
kwadrat_kl.h = wysokosc_kafla;

void rysuj_mape( int x_ind, int y_ind )
{
    static int x, y;
   
    for( int fy = y_ind, int fyk = fy + ilosc_kafli_na_wysokosc; fy < fyk; fy++ )
    for( int fx = x_ind, int fxy = fx + ilosc_kafli_na_szerokosc; fx < fxy; fx++ )
    {
        kwadrat_kl.x = fx * szerokosc_kafla;
        kwadrat_kl.y = fy * wysokosc_kafla;
       
        x = floor( nowa_kamera.x / szerokosc_kafla );
        y = floor( nowa_kamera.y / wysokosc_kafla );
       
        SDL_BlitSurface( /*POWIERZCHNIA z kaflem*/, NULL, erkan, & kwadrat_kl );
        // do nr kafla możesz uzyskać dostęp po przez  mapa[fy][fx]
       
    }
}


Tylko teraz w tej funkcji musiałbyś jeszcze dodać sprawdzanie czy taki indeks tablicy istnieje bo jak wyjdzie poza zakres to się program wysypie ale to już zostawiam tobie

To tak pisane trochę pseudo kodem trochę normalnym więc sobie to teraz napisz i powinno działać (nie sprawdzałem tego).

Widzę, że kilka osób ma problem z wyświetlaniem, wczytywaniem mapy w sdl to może napiszę mały art o tym w przyszłym tyg.
P-32211
JarekKatowice
» 2011-04-28 22:10:06
@mundzio123
Nie chce być złośliwy anie nie chce by to zbyt dosadnie zabrzmialo. Powiem tak
Do rozwiazania tego problemu masz
1)artykuł lazyfoo
2) artykul easykodera
czyli masz absolutnie WSZYSTKO a nawet wiecej niz potrzeba do rozwiazania Twojego problemu. Jezeli nie potrafisz usiasc i tak dlugo analizować by sobie dac z tym rade to poprostu proponuje poswięcic czas na inne zainteresowania do ktorych bedziesz posiadał wiecej zdolności. Nie wszyscy musza być programistami. NAprawde nie mowie tego złośliwie. Albo nie masz zdolnosci by sobie dac z tym rade albo masz, ale nie masz wystarczajaco duzo uporu w Sobie by rozwiazac problem. W tej branzy rozwiazywanie problemow jest codziennoscia tak jak analizowanie roznych dokumentacji, artykułow, tutoriali itd. itp. Rozwiazanie problemu przypomocy własnej pracy (nie czyjejś pomocy) jest jedna z wielu satysfakcji, które kryje to zainteresowanie. Albo sie to czuje albo sie marnuje czas.
pozdr
    
P-32214
1 2 « 3 »
Poprzednia strona Strona 3 z 3