SDL2: Why a figure "blinks"? - c

I'm trying to move a square in a rectangle in SDL, but when i launch it, the rectangle and the square "blinks" until I move the square with up, left, right or down. When the square moves, the rectangle stop blinking and only the square keeps blinking. How can i move it without the blink?
Edit: The problem was that i put SDL_RenderPresent twice after the main loop. Thanks for your help.
#include <SDL2/SDL.h>
#include <stdio.h>
#include <stdbool.h>
#include <string.h>
#include <SDL2/SDL_image.h>
const int SCREEN_WIDTH = 640;
const int SCREEN_HEIGHT = 500;
int main() {
SDL_Init(SDL_INIT_VIDEO);
SDL_Window* window = SDL_CreateWindow("", SDL_WINDOWPOS_UNDEFINED, SDL_WINDOWPOS_UNDEFINED, SCREEN_WIDTH, SCREEN_HEIGHT, SDL_WINDOW_OPENGL);
SDL_Renderer* renderer = SDL_CreateRenderer(window, -1, SDL_RENDERER_ACCELERATED | SDL_RENDERER_PRESENTVSYNC);
bool out = false;
SDL_Event event;
SDL_Rect grid;
grid.x = 25;
grid.y = 25;
grid.w = 300;
grid.h = 450;
SDL_Rect square;
square.x = 175;
square.y = 25;
square.w = 25;
square.h = 25;
//Main loop
while (out==false){
while (SDL_PollEvent(&event)){
if (event.type==SDL_QUIT){out=true;}
else if (event.type==SDL_KEYDOWN){
// Keys
switch (event.key.keysym.sym){
case SDLK_m:
out=true;
break;
case SDLK_LEFT:
square.x-=25;
SDL_RenderPresent(renderer);
break;
case SDLK_RIGHT:
square.x+=25;
SDL_RenderPresent(renderer);
break;
default:
break;
}
}
}
SDL_SetRenderDrawColor(renderer,0,255,0,0);
SDL_RenderFillRect(renderer, &grid);
SDL_RenderPresent(renderer);
SDL_SetRenderDrawColor(renderer,255,0,0,255);
SDL_RenderFillRect(renderer,&square);
SDL_RenderPresent(renderer);
}
SDL_DestroyRenderer(renderer);
SDL_DestroyWindow(window);
SDL_Quit();
return 0;
}

As #HolyBlackCat pointed out, you should only call SDL_RenderPresent() once per frame, not once per shape or keypress:
#include <SDL.h>
#include <SDL_image.h>
#include <stdbool.h>
int main()
{
SDL_Init( SDL_INIT_VIDEO );
SDL_Window* window = SDL_CreateWindow(
"",
SDL_WINDOWPOS_UNDEFINED,
SDL_WINDOWPOS_UNDEFINED,
640,
500,
SDL_WINDOW_OPENGL );
SDL_Renderer* renderer = SDL_CreateRenderer(
window,
-1,
SDL_RENDERER_ACCELERATED | SDL_RENDERER_PRESENTVSYNC );
bool out = false;
SDL_Event event;
SDL_Rect grid;
grid.x = 25;
grid.y = 25;
grid.w = 300;
grid.h = 450;
SDL_Rect square;
square.x = 175;
square.y = 25;
square.w = 25;
square.h = 25;
//Main loop
while( out == false )
{
while( SDL_PollEvent( &event ) )
{
if( event.type == SDL_QUIT )
{
out = true;
}
else if( event.type == SDL_KEYDOWN )
{
// Keys
switch( event.key.keysym.sym )
{
case SDLK_m:
out = true;
break;
case SDLK_LEFT:
square.x -= 25;
break;
case SDLK_RIGHT:
square.x += 25;
break;
default:
break;
}
}
}
SDL_SetRenderDrawColor( renderer, 0, 255, 0, 0 );
SDL_RenderFillRect( renderer, &grid );
SDL_SetRenderDrawColor( renderer, 255, 0, 0, 255 );
SDL_RenderFillRect( renderer, &square );
SDL_RenderPresent( renderer );
}
SDL_DestroyRenderer( renderer );
SDL_DestroyWindow( window );
SDL_Quit();
return 0;
}

Related

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

C SDL VS Code image is not displaying

I have recently started learning game programming in C. I am using a virtual studio code on linux Ubuntu, and image star.png is not displaying on the screen, there are no errors or problems reported by vs code. I have tried reinstalling sdl2-dev and sdl2-image-dev libraries. Maybe it is a problem with SDL, or maybe with my code (it was written in 2013).
The code should draw a white ractangl, which i can move around, on a blue screen and place a star in upper left corner of a window. It does everything except placing a star.
The code: (doesn't show "Cannot dinf star.png!" so I guess it is not that)
#include <SDL2/SDL.h>
#include <SDL2/SDL_image.h>
#include <stdio.h>
typedef struct
{
int x, y;
short life;
char *name;
}Man;
typedef struct
{
//players
Man man;
//image
SDL_Texture *star;
} GameState;
/////////////////////////////////////////////////////////////////////processEvents
int processEvents(SDL_Window *window , GameState *game)
{
SDL_Event event;
int done = 0;
//Check for events
while (SDL_PollEvent(&event))
{
switch (event.type)
{
case SDL_WINDOWEVENT_CLOSE:
{
if (window)
{
SDL_DestroyWindow(window);
window = NULL;
done = 1;
}
}
break;
case SDL_KEYDOWN:
{
switch (event.key.keysym.sym)
{
case SDLK_ESCAPE:
done = 1;
break;
}
}
break;
case SDL_QUIT:
done = 1;
break;
}
}
const Uint8 *state = SDL_GetKeyboardState(NULL);
if(state[SDL_SCANCODE_LEFT])
{
game->man.x -= 1;
}
if(state[SDL_SCANCODE_RIGHT])
{
game->man.x += 1;
}
if(state[SDL_SCANCODE_UP])
{
game->man.y -= 1;
}
if(state[SDL_SCANCODE_DOWN])
{
game->man.y += 1;
}
SDL_Delay(10);
return done;
}
/////////////////////////////////////////////////////////////////////////////////////doRender
void doRedner(SDL_Renderer *renderer, GameState *game)
{
SDL_SetRenderDrawColor(renderer , 0, 0, 255, 255); //blue
//screen clean up into blue
SDL_RenderClear(renderer);
//set color
SDL_SetRenderDrawColor(renderer, 255, 255, 255, 255);
SDL_Rect rect = {game->man.x, game->man.y, 80, 80};
SDL_RenderFillRect(renderer, &rect);
//draw a star
SDL_Rect starRect = { 50, 50, 64, 64 };
SDL_RenderCopy(renderer, game->star, NULL, &starRect);
SDL_RenderPresent(renderer);
}
/////////////////////////////////////////////////////////////////////////////////////main funkction
int main(int argc, char *argv[])
{
GameState gameState;
SDL_Window *window = NULL;
SDL_Renderer *renderer = NULL;
SDL_Surface *starSurface = NULL;
SDL_Init(SDL_INIT_VIDEO);
gameState.man.x = 340-40;
gameState.man.y = 240-40;
window = SDL_CreateWindow("Game Widnow",
SDL_WINDOWPOS_UNDEFINED,
SDL_WINDOWPOS_UNDEFINED,
640,
480,
0
);
renderer = SDL_CreateRenderer(window, -1, SDL_RENDERER_ACCELERATED | SDL_RENDERER_PRESENTVSYNC);
//load image
starSurface = IMG_Load("star.png");
if(starSurface = NULL)
{
printf("Cannot find star.png!\n\n");
SDL_Quit();
return 1;
}
gameState.star = SDL_CreateTextureFromSurface(renderer, starSurface);
SDL_FreeSurface(starSurface);
int done = 0;
while(!done)
{
//check events
done = processEvents(window, &gameState);
//render
doRedner(renderer, &gameState);
}
SDL_Delay(1000);
//exit game and free memory
SDL_DestroyTexture(gameState.star);
//destroy and close window
SDL_DestroyWindow(window);
SDL_DestroyRenderer(renderer);
SDL_Quit();
return 0;
}
TL;DR: Your intention is to perform a comparison, but you are using the assignment operator (i.e., =) instead of the comparison operator ==.
The conditional expression in your if statement:
if(starSurface = NULL)
{
...
}
does not check whether starSurface is NULL. The expression starSurface = NULL assigns NULL to starSurface and evaluates to NULL. Therefore, the condition evaluates to false and no error message is displayed.
Instead, you should write (note the double = below):
if (starSurface == NULL)
or just:
if (!starSurface)

Pixel Manipulation in SDL2.0

I can not display pixels in SDL 2.0.
#include<SDL2/SDL.h>
#include<stdbool.h>
void end( SDL_Window *Window, SDL_Surface *Surface);
void drawPixel( SDL_Surface *Surface, int x, int y);
void main(){
Uint32 start;
const int FPS = 60;
bool running = true;
SDL_Event event;
SDL_Window *main_window = NULL;
SDL_Surface *main_screen = NULL;
SDL_Init( SDL_INIT_EVERYTHING );
main_window = SDL_CreateWindow("Pixel", SDL_WINDOWPOS_UNDEFINED,
SDL_WINDOWPOS_UNDEFINED,800,600,
SDL_WINDOW_RESIZABLE);
main_screen = SDL_GetWindowSurface ( main_window );
SDL_UpdateWindowSurface( main_window );
//printf("%d\n",main_screen->pixels);
SDL_FillRect( main_screen, NULL, SDL_MapRGB(main_screen->format, 255, 255, 255));
SDL_UpdateWindowSurface( main_window );
for(int i = 0; i <= 3000; i++ ){
drawPixel( main_screen, i, 0);
//break;
}
// SDL_UpdateWindowSurface( main_window );
while( running ) {
// start = SDL_GetTicks();
while ( SDL_PollEvent( &event ) ){
switch( event.type ){
case SDL_QUIT:
running = false;
break;
}
}
}
end( main_window, main_screen);
}
void end(SDL_Window *Window, SDL_Surface *Surface){
SDL_FreeSurface( Surface );
SDL_DestroyWindow( Window );
}
void drawPixel(SDL_Surface *Surface, int x, int y){
Uint8 *pixel_array = (Uint8 *) Surface->pixels;
Uint8 *pixel = pixel_array + Surface->pitch * y + x;
*pixel = SDL_MapRGB(Surface->format, 0, 0, 0 );
}`
I tried to locate pixel position and try to color the pixel black while background color white, but it does not print anything.
Although I tried to create a line in case i am not unable to see the pixel, but it turned out to be not working. I see only white screen.

My code won't display sprite SDL2

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().

SDL and C keyboard or touch event

I'm programming in c4droid but I can't get the touch event to work.
Tried switch or if statement but nothing works im sure rendering is ok because if I delete the switch then its renders normally
Here I the code:
#include <SDL2/SDL.h>
int main()
{
SDL_Window *window = NULL;
window = SDL_CreateWindow("Shooter", SDL_WINDOWPOS_UNDEFINED,
SDL_WINDOWPOS_UNDEFINED, 640, 480, SDL_WINDOW_SHOWN);
// Setup renderer
SDL_Renderer *renderer = NULL;
renderer = SDL_CreateRenderer(window, 0, SDL_RENDERER_ACCELERATED);
// Set render color to red ( background will be rendered in this color )
SDL_SetRenderDrawColor(renderer, 0, 255, 25, 255);
// Clear winow
SDL_RenderClear(renderer);
// Creat a rect at pos ( 50, 50 ) that's 50 pixels wide and 50 pixels
// high.
SDL_SetRenderDrawColor(renderer, 255, 0, 255, 255);
SDL_Rect r;
r.x = 500;
r.y = 500;
r.w = 50;
r.h = 50;
SDL_Rect e;
e.x = 5;
e.y = 5;
e.w = 50;
e.h = 50;
SDL_Event event;
while(SDL_PollEvent(&event) != 0) {
switch (event.type) {
case SDL_FINGERDOWN :
e.x = e.x + 10;
SDL_RenderFillRect(renderer, &r);
SDL_RenderFillRect(renderer, &e);
SDL_RenderPresent(renderer);
break;
}
}
// Wait for 5 sec
SDL_Delay(50000);
SDL_DestroyWindow(window);
SDL_Quit();
}
You need to make sure to poll the event.
while(true) {
while(SDL_PollEvent(&event) != 0) {
switch (event.type) {
case SDL_FINGERDOWN :
e.x = e.x + 10;
SDL_RenderFillRect(renderer, &r);
SDL_RenderFillRect(renderer, &e);
SDL_RenderPresent(renderer);
break;
// Render rect
}
}
}
Provided event is not NULL, SDL_PollEvent will take the next event from the queue and store it in the SDL_Event that event is pointing at.
Edit: Don't remove the while(true) loop, put this one inside it. Sorry, I probably should have been a bit more clear in the beginning.

Resources