Проблемы с блитованием поверхности в SDL из вектора SDL_Rect - PullRequest
0 голосов
/ 24 августа 2011
#include "main.h"

SDL_Surface* screen; //The screen Surface
SDL_Surface* Snake_Body; //The snake surface (shape to draw)

SDL_Rect rectangle1; //Red border
SDL_Rect rectangle2; //Black Board

SDL_Event event;    //Keyboard handling
direction facing;

std::vector<SDL_Rect> snake (3); //Snake body locations



SDL_Surface *LoadSnake()
{
    SDL_Surface* temporary;

    Uint32 rmask,gmask,bmask,amask;

    #if SDL_BYTEORDER == SDL_BIG_ENDIAN
        rmask = 0xff000000;
        gmask = 0x00ff0000;
        bmask = 0x0000ff00;
        amask = 0x000000ff;
    #else
        rmask = 0x000000ff;
        gmask = 0x0000ff00;
        bmask = 0x00ff0000;
        amask = 0xff000000;
    #endif

    temporary = SDL_CreateRGBSurface(SDL_SWSURFACE,5,5,32,rmask,gmask,bmask,amask); //Make an empty surface

    SDL_FillRect(temporary,NULL,SDL_MapRGB(screen->format,0,255,0)); //Fill it with color

    return temporary; //return it
}


bool init()
{
    if(SDL_Init(SDL_INIT_EVERYTHING) == -1 )
        return false;

    screen = SDL_SetVideoMode(SCREEN_WIDTH,SCREEN_HEIGHT,SCREEN_BPP,SDL_SWSURFACE);

    if(!screen)
        return false;

    SDL_WM_SetCaption("Snake v0.1",NULL);

    Snake_Body = LoadSnake();

    rectangle1.x = 0;  //Red border
    rectangle1.y = 0;
    rectangle1.w = 500;
    rectangle1.h = 500;

    rectangle2.x = 25; //Black background
    rectangle2.y = 25;
    rectangle2.w = 450;
    rectangle2.h = 450;

    return true;
}

SDL_Surface *loadImage(const char* filename)
{
    SDL_Surface *loadedImage = NULL;
    SDL_Surface *optimizedImage = NULL;

    loadedImage = SDL_LoadBMP(filename);

    if (loadedImage)
    {
        optimizedImage = SDL_DisplayFormat(loadedImage);
        SDL_FreeSurface(loadedImage);
    }

    return optimizedImage;
}

void pollInput()
{
    while(SDL_PollEvent(&event))
    {
        if(event.type == SDL_QUIT)
        {
            end = true;
        }

        if(event.type == SDL_KEYUP)
        {
            switch(event.key.keysym.sym)
            {
            case SDLK_ESCAPE:
                end = true; break;
            case SDLK_UP:
                facing = up; break;
            case SDLK_DOWN:
                facing = down; break;
            case SDLK_RIGHT:
                facing = right; break;
            case SDLK_LEFT:
                facing = left; break;
            }
        }
    }
}

void Update()
{
    for(unsigned int i = 1; i < snake.size(); i++)
    {
        snake[i] = snake[i-1];
    }

    switch(facing)
    {
    case up:
        snake[0].y -= 5; break;
    case down:
        snake[0].y += 5; break;
    case left:
        snake[0].x -= 5; break;
    case right:
        snake[0].x += 5; break;
    }

}

void SetUp()
{
    snake[0].x = 250;
    snake[0].y = 250;


    snake[1].x = 250 + 15;
    snake[1].y = 250;

    snake[2].x = 250 + 15 + 15;
    snake[2].y = 250;
}

void Draw()
{
    unsigned short i;
    int x;

    SDL_FillRect(screen,&rectangle1,SDL_MapRGB(screen->format,255,0,0)); //Red Border

    SDL_FillRect(screen,&rectangle2,SDL_MapRGB(screen->format,0,0,0)); //Black Board

    for(i = 0; i < snake.size(); i++)
    {
        assert(SDL_BlitSurface(Snake_Body,NULL,screen,&snake[i]) == 0);
    }

    SDL_Flip(screen);
}

void Finish()
{
    SDL_FreeSurface(Snake_Body);

    SDL_Quit();
}

У меня есть этот код, это игра со змеей, написанная на SDL, над которой я работаю, но, похоже, у меня проблема.

SDL хорошо рисует фон, но по какой-то причине он не рисует змею. Я установил там утверждение, чтобы проверить, успешно ли выполнялась функция SDL_BlitSurface, и она возвращает нормальное значение (0), даже если на экране ничего не отображается.

Я установил текстуру узла snake в виде единого зеленого прямоугольника, Snake_Body, и я закодировал места, которые необходимо нарисовать, в контейнере std :: vector, чтобы я мог вызвать функцию SDL_BlitSurface () для Каждый из элементов в векторе, я отслеживал значения, и они корректно меняются, но по какой-то причине изображение по-прежнему не рисуется. Я также пытался заменить мою функцию SDL_BlitSurface () на SDL_FillRect () в той же позиции, но это ничего не меняет.

РЕДАКТИРОВАТЬ: я добавил свой основной цикл ниже этого редактирования:

#include "main.h"

bool end = false;
Uint32 time;

int main(int argc,char* argv[])
{
    if(!init())
        return 1;

    SetUp();

    time = SDL_GetTicks();

    while(!end)
    {
        if(time+1000<SDL_GetTicks())
        {
            Update();
            time = SDL_GetTicks();
        }

        pollInput();
        Draw();
    }

    Finish();

    return 0;
}

Ответы [ 2 ]

1 голос
/ 24 августа 2011

Похоже, вы не проводите никаких проверок границ змеи, чтобы убедиться, что она остается на экране. Поэтому, когда он уходит с экрана, он остается выключенным и никогда не возвращается. Я предполагаю, что вы не регулируете частоту кадров должным образом, или вы не регулируете ее вообще (мне нужно было бы увидеть ваш основной цикл), поэтому змея отходит от экрана так быстро, что вы даже не видите его *. 1001 *

Что произойдет, если вы не вызовете функцию Update?

0 голосов
/ 24 августа 2011

Если вы опубликовали весь код, значит, отсутствует вызов SetUp.Это не настроит змею, и это, вероятно, где-то за пределами экрана, поскольку вектор содержит мусор.Кроме того, хотя SDL_BlitSurface игнорирует ширину и высоту dstrect, рекомендуется инициализировать их некоторыми значимыми значениями.

...