My code won't display sprite SDL2 - c

The screen is always black. Tell me how to display the sprites correctly.
This is my code:
#define SHAPE_SIZE 32
void aff_map(SDL_Renderer *renderer)
{
SDL_Surface *img;
SDL_Texture *Tfloor
int x = 0;
int y = 0;
int map[4][8] = {{0,0,0,0,0,0,0,0},
{0,0,0,0,0,0,0,0},
{0,0,0,0,0,0,0,0},
{0,0,0,0,0,0,0,0}};
SDL_Rect SrcR;
SDL_Rect DestR;
DestR.x = 0;
DestR.y = 0;
DestR.w = SHAPE_SIZE;
DestR.h = SHAPE_SIZE;
img = IMG_Load("floor.bmp");
Tfloor = SDL_CreateTextureFromSurface(renderer, img);
while (y < 4)
{
x = 0;
while (x < 8)
{
if (map[y][x] == 0)
SDL_RenderCopy(renderer, Tfloor, NULL, &DestR);
x++;
DestR.x = DestR.x + 32;
}
DestR.x = 0;
DestR.y = DestR.y + 32;
y++;
}
SDL_RenderPresent(renderer);
}
int main()
{
SDL_Window *screen;
SDL_Event evenements;
SDL_Renderer *renderer;
screen = SDL_CreateWindow("Zappy", SDL_WINDOWPOS_UNDEFINED, SDL_WINDOWPOS_UNDEFINED, 8 * SHAPE_SIZE -32, 4 * SHAPE_SIZE, 0);
renderer = SDL_CreateRenderer(screen, -1, SDL_RENDERER_ACCELERATED);
SDL_RenderClear(renderer);
while (42)
{
SDL_WaitEvent(&evenements);
if (evenements.window.event == SDL_WINDOWEVENT_CLOSE ||
evenements.key.keysym.sym == SDLK_ESCAPE)
{
SDL_DestroyWindow(screen);
SDL_Quit();
break;
}
aff_map(renderer);
}
return 0;
}

The error message is explicit.
It says that the "floor.bmp" has not been converted to a surface.
It means that 'img' parameter is NULL.
Try the following :
Specify the full path to your picture in IMG_Load(), for example "/home/quentin/floor.bmp"
Check the return value of IMG_Load().

Related

How can I perfectly manage my memory of my C project?

I am working on an object of SDL Tetris. When I ran my code, it first worked fine. But it automatically stopped displaying my text a few minutes later. I guessed there must be some problem on the memory management and I proved that I was right via Task Manager.
I look over my source code but found nothing wrong. (at least I didn't find it) Every heap object I delcared was freed and textures were destroyed. So, what can be the problem?
Here's my source code:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <math.h>
#include <time.h>
#include <stdbool.h>
#define SDL_MAIN_HANDLED
#include <SDL2/SDL.h>
#include <SDL2/SDL_ttf.h>
SDL_Window * window;
SDL_Renderer * renderer;
SDL_Surface * text;
TTF_Font* font;
bool running = true;
#define ScreenWidth 60
#define ScreenHeight 30
#define CharWidth 14
#define CharHeight 24
char screen[ScreenHeight][ScreenWidth + 1];
SDL_Color color = {192, 192, 192};
SDL_Rect rect;
int score = 0;
char shapes[7][17];
typedef struct Block {
int type;
char shape[17];
int x, y;
int width, height;
} Block;
Block * newBlock(int type) {
Block * block = malloc(sizeof(Block));
return block;
}
void CheckEvents() {
SDL_Event event;
while (SDL_PollEvent(&event)) {
if (event.type == SDL_QUIT) {
running = false;
} else if (event.type == SDL_KEYDOWN) {
switch (event.key.keysym.sym) {
case SDLK_w:
;
break;
case SDLK_a:
;
break;
case SDLK_d:
;
break;
case SDLK_s:
;
break;
case SDLK_SPACE:
;
break;
default:
break;
}
}
}
free(&event);
}
void UpdateBoard() {
for (int i = 0; i < ScreenHeight; ++i) {
for (int j = 0; j < ScreenWidth; ++j) {
screen[i][j] = ' ';
}
}
for (int i = 0; i != 20; ++i) {
screen[i + 2][1] = '#';
screen[i + 2][1 + 10 + 1] = '#';
}
for (int i = 0; i != 10 + 2; ++i) {
screen[22][i + 1] = '#';
}
sprintf(&(screen[0][1]), "Score: %d", score);
for (int i = 0; i != ScreenHeight; i++) {
for (int j = 0; j != ScreenWidth; j++) {
if (screen[i][j] == '\0') {
screen[i][j] = ' ';
}
}
}
}
void UpdateScreen() {
SDL_SetRenderDrawColor(renderer, 0, 0, 0, 255);
SDL_RenderClear(renderer);
for (int i = 0; i < ScreenHeight; ++i) {
text = TTF_RenderText_Solid(font, screen[i], color);
SDL_Texture * texture;
texture = SDL_CreateTextureFromSurface(renderer, text);
rect.x = 0;
rect.y = i * CharHeight;
rect.w = strlen(screen[i]) * CharWidth;
rect.h = CharHeight;
SDL_RenderCopy(renderer, texture, NULL, &rect);
free(texture);
SDL_DestroyTexture(texture);
}
SDL_RenderPresent(renderer);
}
void Init() {
SDL_Init(SDL_INIT_EVERYTHING);
TTF_Init();
window = SDL_CreateWindow("Tetris", SDL_WINDOWPOS_CENTERED, SDL_WINDOWPOS_CENTERED,
ScreenWidth * CharWidth, ScreenHeight * CharHeight, 0);
renderer = SDL_CreateRenderer(window, -1, 0);
font = TTF_OpenFont("s8514oem.fon", 0);
sprintf(shapes[0], "OOOO............");
sprintf(shapes[1], "OO...OO.........");
sprintf(shapes[2], ".OO.OO..........");
sprintf(shapes[3], "O...OOO.........");
sprintf(shapes[4], "..O.OOO.........");
sprintf(shapes[5], "OO..OO..........");
sprintf(shapes[6], "OOO..O..........");
}
int main(int argc, char ** argv) {
Init();
while (running) {
CheckEvents();
UpdateBoard();
UpdateScreen();
SDL_Delay(1000/16);
}
TTF_Quit();
SDL_Quit();
return 0;
}
My Makefile:
tetris:
gcc -std=c99 -Wall -Isrc/include -Lsrc/lib -o Tetris main.c -lSDL2main -lSDL2 -lSDL2_ttf
Several things:
Don't try to free() stack-allocated variables like event:
//free(&event);
text needs to be freed with SDL_FreeSurface() before replacing its pointer value with a new one from TTF_RenderText_Solid():
if(text) {
SDL_FreeSurface(text);
}
text = TTF_RenderText_Solid(font, screen[i], color);
Don't use free() on the textures returned by SDL_CreateTextureFromSurface(), only use SDL_DestroyTexture():
texture = SDL_CreateTextureFromSurface(renderer, text);
...
//free(texture);
SDL_DestroyTexture(texture);

How do I remove the Terminal Output in C

Situation
I am working on an SDL2 program and I want to remove the black terminal window that shows up everytime I fire the program,
its kinda annoying to have a black window randomly in my screen :/
What I've Tried
I've tried looking up in Google but nothing actually shows up that can fix my situation
Here's The Rest Of My Code
#include <stdio.h>
#include <SDL.h>
int main(int argc, char **args) {
// SDL Window Declaration
SDL_Surface* screen;
SDL_Window* window;
SDL_Rect plrBox;
SDL_Rect plrMot;
plrMot.x = 1;
plrMot.y = 1;
plrBox.x = 0;
plrBox.y = 0;
plrBox.w = 10;
plrBox.h = 10;
// SDL Initialization
if (SDL_Init(SDL_INIT_EVERYTHING) < 0) {
printf("Fail At SDL_Init()\n");
return 1;
}
// Window Creation
window = SDL_CreateWindow(
"Paint",
SDL_WINDOWPOS_UNDEFINED,
SDL_WINDOWPOS_UNDEFINED,
400,
300,
SDL_WINDOW_SHOWN
);
if (!window) {
printf("Fail at SDL_CreateWindow\n");
}
// Surface Creation
screen = SDL_GetWindowSurface(window);
if (!screen) {
printf("Fail at Screen\n");
return 1;
}
int run = 1;
while (run) {
SDL_FillRect(screen, NULL, SDL_MapRGB(screen->format, 255, 255, 255));
SDL_FillRect(screen, &plrBox, SDL_MapRGB(screen->format, 0, 0, 0));
plrBox.x += plrMot.x;
plrBox.y += plrMot.y;
if (plrBox.y > 300) {
plrMot.y = -plrMot.y;
}
if (plrBox.x > 400) {
plrMot.x = -plrMot.x;
}
if (plrBox.y < 0) {
plrMot.y = -plrMot.y;
}
if (plrBox.x < 0) {
plrMot.x = -plrMot.x;
}
SDL_Event events;
while (SDL_PollEvent(&events)){
switch (events.type) {
case SDL_QUIT:
run = 0;
}
}
SDL_UpdateWindowSurface(window);
}
// Quit
window = NULL;
screen = NULL;
SDL_Quit();
return 0;
}
I use mingw for all the comments out there

How to change direction smoothly using SDL2 and how to keep moving when I press shift after holding a key?

It's my Code, it's a very simple tank games, I have 2 problems:
use WSAD to move with speed 4, when I pressing and holding shift, the speed change to 8, when I release shift, speed back to 4. But, with my code, when I press shift after holding WSAD, the tank stop, I must repress the key to move it.
When I press WSAD, the tank just change the direction, but not move,so when I holding d, the tank first change it's direction to right for about 0.5 second, then start to move. How to get it move smoothly?
#include <SDL2/SDL.h>
#include <SDL2/SDL_image.h>
#include <stdio.h>
const int WINDOW_WIDTH = 960; //窗体宽度
const int WINDOW_HEIGHT = 640; //窗体高度
//使用旋转角度定义方向
const int UP = 0;
const int DOWN = 180;
const int LEFT = 270;
const int RIGHT = 90;
//-------------------
typedef struct {
int x;
int y;
int width;
int height;
int direction;
SDL_Texture *texture;
} Player;
void RenderPlayer(Player player, SDL_Renderer *renderer) {
SDL_Rect srcRect = {.x = 0, .y = 0, .w = player.width, .h = player.height};
SDL_Rect destRect = {.x = player.x, .y = player.y, .w = player.width / 2, .h = player.height / 2};
SDL_RenderCopyEx(renderer, player.texture, &srcRect, &destRect, player.direction, NULL, SDL_FLIP_NONE);
}
int main(int argc, char *argv[]) {
SDL_Window *window;
SDL_Renderer *renderer;
if (SDL_Init(SDL_INIT_EVERYTHING)) {
printf("SDL对象初始化失败!\n");
return -1;
}
if (!(window = SDL_CreateWindow("坦克大战", SDL_WINDOWPOS_CENTERED, SDL_WINDOWPOS_CENTERED, WINDOW_WIDTH, WINDOW_HEIGHT, SDL_WINDOW_OPENGL))) {
printf("窗体创建失败!\n");
return -1;
}
if (!(renderer = SDL_CreateRenderer(window, -1, SDL_RENDERER_ACCELERATED | SDL_RENDERER_TARGETTEXTURE))) {
printf("渲染器创建失败!\n");
return -1;
}
SDL_SetRenderDrawColor(renderer, 76, 110, 150, 255);
SDL_RenderClear(renderer);
SDL_RenderPresent(renderer);
SDL_Surface *surface = IMG_Load("Tank01.png");
if (!surface) {
printf("像素集创建失败:%s\n", IMG_GetError());
return -1;
}
printf("宽度:%d\n高度:%d\n", surface->w, surface->h);
Player player1 = {(WINDOW_WIDTH - surface->w) / 2, WINDOW_HEIGHT - surface->h, surface->w, surface->h, UP, SDL_CreateTextureFromSurface(renderer, surface)};
int speed;
const Uint8 *state = SDL_GetKeyboardState(NULL);
SDL_Event sdlEvent;
while (1) {
int flag1 = 0;
while (SDL_PollEvent(&sdlEvent)) {
speed = 4;
switch (sdlEvent.type) {
case SDL_KEYDOWN:
if (state[SDL_SCANCODE_LSHIFT] && (state[SDL_SCANCODE_W] || state[SDL_SCANCODE_S] || state[SDL_SCANCODE_A] || state[SDL_SCANCODE_D])) {
speed = 8;
}
switch (sdlEvent.key.keysym.sym) {
case SDLK_w:
if (player1.y > 0) {
player1.y -= speed;
}
player1.direction = UP;
break;
case SDLK_s:
if (player1.y < WINDOW_HEIGHT - player1.height / 2) {
player1.y += speed;
}
player1.direction = DOWN;
break;
case SDLK_a:
if (player1.x > 0) {
player1.x -= speed;
}
player1.direction = LEFT;
break;
case SDLK_d:
if (player1.x < WINDOW_WIDTH - player1.width / 2) {
player1.x += speed;
}
player1.direction = RIGHT;
break;
case SDLK_ESCAPE:
SDL_Quit();
flag1 = 1;
break;
}
break;
case SDL_QUIT:
SDL_Quit();
flag1 = 1;
break;
}
}
SDL_RenderClear(renderer);
RenderPlayer(player1, renderer);
SDL_RenderPresent(renderer); //使用渲染器更新窗体
if (flag1) {
break;
}
}
return 0;
}
I couldn't reproduce your first problem with the code you provided, if I hold any of wasd and press shift the tank keeps moving.
The problem here is a bit hard to understand, but you're basically moving the tank only on SDL_Pressed events, meaning that the only reason your tank is moving at all is because SDL repeats the same events over and over, and because it doesn't do this very fast (polling events is kinda slow), your movement is choppy/laggy/steppy whatever you want to call it.
A fix for this is to remove the actual movement step outside your SDL_Event loop, also you should filter out repeat events since you've already checked them.
Meaning your code should look should be something like this
while (1) {
while (SDL_Event(e)) {
if (event is repeated)
skip event
if (UP Key is pressed)
up_state = 1;
if (UP key is released)
up_state = 0;
// etc..
}
// Outside the event loop
if (up_state == 1) // if its 0 we don't add anything
player.x -= speed;
// and so on..
}
For this to work properly you'll also need to read about how to implement a delta time in your loop, because this will run as fast as your processor can meaning that your speed wont be regular, it might add more or less speed depending on how fast is running, which is bad.
Here is your code with these problems fixed, except the delta time, since I actually don't which platform you're on and I was too lazy to do it in C, I capped the framerate at 60fps with a sleep at the end, which is a very bad idea.
#include <SDL2/SDL.h>
#include <SDL2/SDL_image.h>
// I don't know if you're on windows or linux
#ifdef _WIN32
#include <Windows.h>
#else
#include <unistd.h>
#endif
const int WINDOW_WIDTH = 960; //窗体宽度
const int WINDOW_HEIGHT = 640; //窗体高度
//使用旋转角度定义方向
const int UP = 0;
const int DOWN = 180;
const int LEFT = 270;
const int RIGHT = 90;
//-------------------
typedef struct {
int x;
int y;
int width;
int height;
int direction;
SDL_Texture *texture;
} Player;
int m_up = 0;
int m_down = 0;
int m_left = 0;
int m_right = 0;
void RenderPlayer(Player player, SDL_Renderer *renderer) {
SDL_Rect srcRect = {.x = 0, .y = 0, .w = player.width, .h = player.height};
SDL_Rect destRect = {.x = player.x,
.y = player.y,
.w = player.width / 2,
.h = player.height / 2};
SDL_RenderCopyEx(renderer, player.texture, &srcRect, &destRect,
player.direction, NULL, SDL_FLIP_NONE);
}
int main(int argc, char *argv[]) {
SDL_Window *window;
SDL_Renderer *renderer;
if (SDL_Init(SDL_INIT_EVERYTHING)) {
return -1;
}
if (!(window = SDL_CreateWindow("Game", SDL_WINDOWPOS_CENTERED,
SDL_WINDOWPOS_CENTERED, WINDOW_WIDTH,
WINDOW_HEIGHT, SDL_WINDOW_OPENGL))) {
return -1;
}
if (!(renderer = SDL_CreateRenderer(window, -1,
SDL_RENDERER_ACCELERATED |
SDL_RENDERER_TARGETTEXTURE))) {
return -1;
}
SDL_SetRenderDrawColor(renderer, 76, 110, 150, 255);
SDL_RenderClear(renderer);
SDL_RenderPresent(renderer);
SDL_Surface *surface = IMG_Load("tank.png");
if (!surface) {
return -1;
}
Player player1 = {(WINDOW_WIDTH - surface->w) / 2,
WINDOW_HEIGHT - surface->h,
surface->w,
surface->h,
UP,
SDL_CreateTextureFromSurface(renderer, surface)};
int speed = 4;
SDL_Event sdlEvent;
int run = 1;
while (run) {
while (SDL_PollEvent(&sdlEvent)) {
// Now we skip over repeat events
if ((sdlEvent.type == SDL_KEYDOWN || sdlEvent.type == SDL_KEYUP) &&
sdlEvent.key.repeat == 0) {
SDL_Keycode key = sdlEvent.key.keysym.sym;
int is_pressed = sdlEvent.key.state == SDL_PRESSED;
if (key == SDLK_LSHIFT && is_pressed) {
speed = 8;
} else if (key == SDLK_LSHIFT && !is_pressed) {
speed = 4;
}
if (key == SDLK_w && is_pressed) {
m_up = 1;
} else if (key == SDLK_w) {
m_up = 0;
}
if (key == SDLK_s && is_pressed) {
m_down = 1;
} else if (key == SDLK_s) {
m_down = 0;
}
if (key == SDLK_a && is_pressed) {
m_left = 1;
} else if (key == SDLK_a) {
m_left = 0;
}
if (key == SDLK_d && is_pressed) {
m_right = 1;
} else if (key == SDLK_d) {
m_right = 0;
}
if (key == SDLK_ESCAPE) {
run = 0;
}
if (sdlEvent.type == SDL_QUIT) {
run = 0;
}
}
}
// Handle the movement outside the event loop
if (m_up && player1.y > 0)
player1.y -= speed;
if (m_down && player1.y < WINDOW_HEIGHT - player1.height / 2)
player1.y += speed;
if (m_left && player1.x > 0)
player1.x -= speed;
if (m_right && player1.x < WINDOW_WIDTH - player1.width / 2)
player1.x += speed;
SDL_RenderClear(renderer);
RenderPlayer(player1, renderer);
SDL_RenderPresent(renderer);
#ifdef _WIN32
sleep(0.016); // asume 60 fps, horrible idea
#else
usleep(16000);
#endif
}
SDL_Quit();
return 0;
}
the test image I was using as 'tank.png' https://i.imgur.com/qlUagLp.png

SDL2 doesn't render multiple viewports

I'm working through Lazy Foo's SDL2 tutorials and stuck trying to render multiple viewports. The idea is to load a PNG as a texture, create SDL_Rect structs for 3 different viewports (top left, top right, bottom), then copy the texture onto each viewport, and finally render all 3 viewports. My code is only rendering the first viewport.
I've tried changing the order - in every case, whichever viewport is defined first is the only one that renders.
I also tried changing the viewport dimensions, in case overlap was the issue - same problem.
The only question I found about multiple viewports didn't point me in the right direction. But it did start me thinking - my code is written in C, the tutorial in C++. Although I think I'm translating everything correctly (the other lessons work fine), maybe I'm missing something obvious here?
I'm compiling with CFLAGS = -Wall -Wextra -pedantic -std=c99 - no warnings or errors.
Edit: I tried rendering filled rectangles instead of a loaded PNG, but the issue is the same - only the first one renders.
Here's my code:
#include <SDL2/SDL.h>
#include <SDL2/SDL_image.h>
#include <stdio.h>
#define SCREEN_WIDTH 640
#define SCREEN_HEIGHT 480
int init_renderer();
int load_media();
SDL_Texture *load_texture(char *);
void close_renderer();
SDL_Window *g_window = NULL;
SDL_Renderer *g_renderer = NULL;
SDL_Texture *g_texture = NULL;
int main()
{
if (init_renderer() != 1) {
return -1;
}
if (!SDL_SetHint(SDL_HINT_RENDER_SCALE_QUALITY, "1")) {
printf("Warning: Linear texture filtering not enabled!\n");
}
if (load_media() != 1) {
return -1;
}
int quit = 0;
SDL_Event e;
while (quit != 1) {
while (SDL_PollEvent(&e) != 0) {
if (e.type == SDL_QUIT || e.key.keysym.sym == SDLK_q) {
quit = 1;
}
}
SDL_SetRenderDrawColor(g_renderer, 0xff, 0xff, 0xff, 0xff);
SDL_RenderClear(g_renderer);
SDL_Rect top_left_vp;
top_left_vp.x = 0;
top_left_vp.y = 0;
top_left_vp.w = SCREEN_WIDTH / 2;
top_left_vp.h = SCREEN_HEIGHT / 2;
SDL_RenderSetViewport(g_renderer, &top_left_vp);
SDL_RenderCopy(g_renderer, g_texture, NULL, NULL);
SDL_Rect top_right_vp;
top_right_vp.x = SCREEN_WIDTH / 2;
top_right_vp.y = 0;
top_right_vp.w = SCREEN_WIDTH / 2;
top_right_vp.h = SCREEN_HEIGHT / 2;
SDL_RenderSetViewport(g_renderer, &top_right_vp);
SDL_RenderCopy(g_renderer, g_texture, NULL, NULL);
SDL_Rect bottom_vp;
bottom_vp.x = 0;
bottom_vp.y = SCREEN_HEIGHT / 2;
bottom_vp.w = SCREEN_WIDTH;
bottom_vp.h = SCREEN_HEIGHT / 2;
SDL_RenderSetViewport(g_renderer, &bottom_vp);
SDL_RenderCopy(g_renderer, g_texture, NULL, NULL);
SDL_RenderPresent(g_renderer);
}
close_renderer();
return 0;
}
int init_renderer()
{
if (SDL_Init(SDL_INIT_VIDEO) < 0) {
printf("Failed to initialize SDL. Error: %s\n", SDL_GetError());
return 0;
}
g_window = SDL_CreateWindow("SDL Tuts",
SDL_WINDOWPOS_UNDEFINED,
SDL_WINDOWPOS_UNDEFINED,
SCREEN_WIDTH,
SCREEN_HEIGHT,
SDL_WINDOW_SHOWN);
if (g_window == NULL) {
printf("Failed to create window. Error: %s\n", SDL_GetError());
return 0;
}
g_renderer = SDL_CreateRenderer(g_window, -1, SDL_RENDERER_ACCELERATED);
if (g_renderer == NULL) {
printf("Failed to create renderer. Error: %s\n", SDL_GetError());
return 0;
}
SDL_SetRenderDrawColor(g_renderer, 0x29, 0xAB, 0x87, 0xFF);
int img_flags = IMG_INIT_PNG;
if (!(IMG_Init(img_flags) & img_flags)) {
printf("Failed to initialize SDL Image. SDL_Image Error: %s\n", IMG_GetError());
return 0;
}
return 1;
}
int load_media()
{
g_texture = load_texture("assets/texture.png");
if (g_texture == NULL) {
return 0;
}
return 1;
}
SDL_Texture *load_texture(char *path)
{
SDL_Texture *new_texture = NULL;
SDL_Surface *loaded_surface = IMG_Load(path);
if (loaded_surface == NULL) {
printf("Failed to load image. SDL_Image Error: %s\n", IMG_GetError());
} else {
new_texture = SDL_CreateTextureFromSurface(g_renderer, loaded_surface);
if (new_texture == NULL) {
printf("Failed to create texture from %s. Error: %s\n", path, SDL_GetError());
}
SDL_FreeSurface(loaded_surface);
}
return new_texture;
}
void close_renderer()
{
SDL_DestroyTexture(g_texture);
g_texture = NULL;
SDL_DestroyRenderer(g_renderer);
SDL_DestroyWindow(g_window);
g_renderer = NULL;
g_window = NULL;
IMG_Quit();
SDL_Quit();
}
To check for more errors, you should see what the calls to SDL_RenderSetViewPort are returning. According to the docs, it returns an int, which is 0 on success or a negative int if there's an error. It's entirely possible that something deeper in SDL is having a fit.
Additional pro tips: you can define the SDL_Rect structs outside of your while loop to save a miniscule margin of processing power. And to spare yourself some typing, you can initialize a SDL_Rect using a list constructor instead of manually punching each property. E.G.:
SDL_Rect top_left_vp;
top_left_vp.x = 0;
top_left_vp.y = 0;
top_left_vp.w = SCREEN_WIDTH / 2;
top_left_vp.h = SCREEN_HEIGHT / 2;
is more simply
SDL_Rect top_left_vp = {
0,
0,
SCREEN_WIDTH / 2,
SCREEN_HEIGHT / 2
};

Displaying the rectangle using a for loop in SDL2 C

I'm currently using a for loop to create 4 rectangles along the x-axis. When I run the program the image of the rectangle appears for a few millisecond before it disappears. Can you show me what I have to do in order for the image to display on the screen permanently.
When I create individual rectangles it display's the image without vanishing.
An example will be helpful. Thanks
int main(){
int barrack1_xposition = 167,i=1;
int cnt_barrack=0;
SDL_Window *o = NULL;
SDL_Renderer *r = NULL;
SDL_Rect bar1[4];
SDL_Event e;
SDL_Init(SDL_INIT_VIDEO);
o = SDL_CreateWindow("SPACE INVADERS",
SDL_WINDOWPOS_UNDEFINED,
SDL_WINDOWPOS_UNDEFINED,
1024,
800,
SDL_WINDOW_SHOWN | SDL_WINDOW_RESIZABLE);
r = SDL_CreateRenderer(o, -1,SDL_RENDERER_ACCELERATED | SDL_RENDERER_PRESENTVSYNC);
while(i)
{
while(SDL_PollEvent(&e) !=0)
{
if(e.type == SDL_QUIT)
i=0;
}
for(cnt_barrack = 0; cnt_barrack < 4; cnt_barrack++)
{
bar1[cnt_barrack].x=barrack1_xposition;
bar1[cnt_barrack].y=250;
bar1[cnt_barrack].h=50;
bar1[cnt_barrack].w=50;
barrack1_xposition += 200;
}
SDL_SetRenderDrawColor(r,255,255,255,255);
SDL_RenderFillRect(r,&bar1[0]);
SDL_RenderFillRect(r,&bar1[1]);
SDL_RenderFillRect(r,&bar1[2]);
SDL_RenderFillRect(r,&bar1[3]);
SDL_RenderPresent(r);
}
SDL_DestroyWindow(o);
SDL_DestroyRenderer(r);;
SDL_Quit();
}
Your problem caused by the fact you didn't reset barrack1_xposition on each frame, so it keeps going higher and higher. I initially didn't notice that because there was no RenderClear so it seemed to be fine but actually wasn't.
#include "SDL.h"
int main(){
int barrack1_xposition,i=1;
int cnt_barrack=0;
SDL_Window *o = NULL;
SDL_Renderer *r = NULL;
SDL_Rect bar1[4];
SDL_Event e;
SDL_Init(SDL_INIT_VIDEO);
o = SDL_CreateWindow("SPACE INVADERS",
SDL_WINDOWPOS_UNDEFINED,
SDL_WINDOWPOS_UNDEFINED,
1024,
800,
SDL_WINDOW_SHOWN | SDL_WINDOW_RESIZABLE);
r = SDL_CreateRenderer(o, -1,SDL_RENDERER_ACCELERATED | SDL_RENDERER_PRESENTVSYNC);
while(i)
{
while(SDL_PollEvent(&e) !=0)
{
if(e.type == SDL_QUIT)
i=0;
}
barrack1_xposition=167;
for(cnt_barrack = 0; cnt_barrack < 4; cnt_barrack++)
{
bar1[cnt_barrack].x=barrack1_xposition;
bar1[cnt_barrack].y=250;
bar1[cnt_barrack].h=50;
bar1[cnt_barrack].w=50;
barrack1_xposition += 200;
}
SDL_SetRenderDrawColor(r,0,0,0,0);
SDL_RenderClear(r);
SDL_SetRenderDrawColor(r,255,255,255,255);
SDL_RenderFillRect(r,&bar1[0]);
SDL_RenderFillRect(r,&bar1[1]);
SDL_RenderFillRect(r,&bar1[2]);
SDL_RenderFillRect(r,&bar1[3]);
SDL_RenderPresent(r);
}
SDL_DestroyWindow(o);
SDL_DestroyRenderer(r);;
SDL_Quit();
return 0;
}

Resources