Utilisation of SDL_KEYDOWN - c++

My program generates an image. I want to close the window by clicking on any key or by clicking with my pointer on the window cross.
It works only by clicking on the cross (Use of SDL_QUIT) but not with SDL_KEYDOWN. I tried also with SDL_SPACE, SDL_KEYUP but the result is the same.
So what am I missing in my code ?
I am using xcode.
int main(int argc, char *argv[])
{
SDL_Surface *ecran = NULL, *imageDeFond = NULL, *zozor = NULL;
SDL_Rect positionFond, positionZozor;
SDL_Event event;
int continuer = 1;
SDL_Init(SDL_INIT_VIDEO);
ecran = SDL_SetVideoMode(800, 600, 32, SDL_HWSURFACE);
imageDeFond = SDL_LoadBMP("lac_en_montagne.bmp");
SDL_BlitSurface(imageDeFond, NULL, ecran, &positionFond);
SDL_Flip(ecran);
while (continuer)
{
SDL_WaitEvent(&event);
switch(event.type)
{
case SDL_KEYDOWN:
{
printf("use of SDL_KEYDOWN");
continuer=0;
break;
}
case SDL_QUIT:
{
printf("use of SDL_QUIT");
continuer = 0;
break;
}
}
}
SDL_FreeSurface(imageDeFond);
SDL_Quit();
return EXIT_SUCCESS;
}

Related

How to use SDL_KeyCode to handle a key press each time?

I'm trying to generate a rectangle into a new position whenever I press the Right arrow key, I was able to get the 1st rectangle but now stuck at the 2nd one. As this is not a case of SDL_GetKeyboardState (to move the rectangle when key is pressed continuously), I'm completely clueless on how this should proceed. To create array for rectangles and pass it to poll event?
const int SCREEN_WIDTH = 640;
const int SCREEN_HEIGHT = 480;
SDL_Window *window = NULL;
SDL_Surface *screen = NULL;
SDL_Renderer *renderer;
SDL_Event e;
SDL_Rect one, two;
bool quit = false;
void init(){
SDL_Init(SDL_INIT_VIDEO);
window = SDL_CreateWindow("Testing", SDL_WINDOWPOS_UNDEFINED,
SDL_WINDOWPOS_UNDEFINED,
SCREEN_WIDTH, SCREEN_HEIGHT,
SDL_WINDOW_SHOWN);
renderer = SDL_CreateRenderer(window, -1, SDL_RENDERER_ACCELERATED | SDL_RENDERER_PRESENTVSYNC);
screen = SDL_GetWindowSurface(window);
}
void draw(){
SDL_SetRenderDrawColor(renderer,255, 255, 255, 255);
SDL_RenderClear(renderer);
SDL_SetRenderDrawColor( renderer, 255, 0, 0, 255);
SDL_RenderFillRect( renderer, &one);
SDL_SetRenderDrawColor( renderer, 0, 66, 255, 255);
SDL_RenderFillRect( renderer, &two);
SDL_RenderPresent(renderer);
}
void logic(){
Uint8 *state;
while (SDL_PollEvent(&e) !=0) {
if (e.type == SDL_KEYDOWN)
{
switch (e.key.keysym.sym)
{
case SDLK_RIGHT:
one = {2,2,124,124};
//two = {130,2,124,124};
break;
case SDLK_LEFT:
one = {0,0,0,0};
break;
}
}
else if (e.type == SDL_QUIT)
{
quit = true;
}
}
}
int main(int argc, char* args[]){
init();
while (!quit)
{
logic();
draw();
}
SDL_DestroyRenderer(renderer);
SDL_DestroyWindow(window);
renderer = NULL;
window = NULL;
SDL_Quit();
return 0;
}

keyboard event not loading in cpp for sdl

I am trying to make it my screen print hello when I click the a key... And switch images when I press the 2 key... however when I do, nothing happens, I'm not sure why... it does not give me an error for some weird reason... if you have any ideas please let me know in the comments below. I have listed the code there!
#include <SDL.h>
#include <iostream>
int main(int argc, char* argv[])
{
SDL_Window* window = nullptr;
SDL_Surface* WindowSurface = nullptr;
SDL_Surface* image1 = nullptr;
SDL_Surface* image2 = nullptr;
SDL_Surface* currentImage = nullptr;
SDL_Init(SDL_INIT_VIDEO);
window = SDL_CreateWindow("sdl Window",
SDL_WINDOWPOS_CENTERED, SDL_WINDOWPOS_CENTERED, 640, 480,
SDL_WINDOW_SHOWN);
WindowSurface = SDL_GetWindowSurface(window);
image1 = SDL_LoadBMP("Red_sheet_full_2.bmp");
image2 = SDL_LoadBMP("Red_sheet_fullA.bmp");
currentImage = image2;
bool isRunning = true;
SDL_Event ev;
while (isRunning)
{
while (SDL_PollEvent(&ev) != 0);
{
if (ev.type == SDL_QUIT)
isRunning = false;
else if (ev.type == SDL_KEYDOWN)
{
switch (ev.key.keysym.sym)
case SDLK_a:
printf("hello");
break;
switch (ev.key.keysym.sym)
case SDLK_2:
currentImage = image1;
break;
}
}
SDL_BlitSurface(currentImage, NULL, WindowSurface, NULL);
SDL_UpdateWindowSurface(window);
}
SDL_FreeSurface(image1);
SDL_FreeSurface(image2);
SDL_DestroyWindow(window);
currentImage = image1 = image2 = nullptr;
window = nullptr;
SDL_Quit();
return 0;
}
The problem is in the switch statement. The break is outside the switch so, if the first event you receive is not an SDLK_a, it will break out of the while loop before printing hello and exit.
Here's a simplified version of what's happening: https://godbolt.org/z/9eEcEYGhj
#include <iostream>
int main(int argc, char* argv[])
{
while (true)
{
char c{'p'};
switch (c)
case 'a':
std::cout << "a\n";
break; // exits without printing anything
switch (c)
case 'b':
std::cout << "b\n";
break;
std::cout << c;
}
}
You have different ways to fix it.
One would be to write the switch statement in a proper way: https://godbolt.org/z/99MohaTMx
#include <iostream>
int main(int argc, char* argv[])
{
while (true)
{
char c{'a'};
switch (c)
{
case 'a':
std::cout << "a\n"; // forever prints "a\n"
break;
case 'b':
std::cout << "b\n";
break;
default:
break;
}
}
}
Another one, just for your current implementation, would be to use an if-else if instead of a switch.

General SDL2 problems. MacOS, Xode

What I'm trying to do is make an SDL program that can write special symbols to a window I created. The keyboard can change between 4 layers each registering 32 keys. I just can't figure out how to actually make something appear on the screen and have no idea what I'm doing wrong.
#include <iostream>
#include <SDL2/SDL.h>
int main(int argc, const char * argv[])
{
//Setup
bool quit = false;
SDL_Event event;
int z = 0; //Layer
int x = 0;
int y = 0;
//Init
SDL_Init(SDL_INIT_VIDEO);
SDL_Window * window = SDL_CreateWindow("TPKB", SDL_WINDOWPOS_CENTERED, SDL_WINDOWPOS_CENTERED, 960, 640, SDL_WINDOW_SHOWN);
SDL_Rect rect = {x, y, 32, 32};
SDL_Renderer * renderer = SDL_CreateRenderer(window, -1, 0);
SDL_Surface * A_srf = SDL_LoadBMP("A.bmp"); SDL_Texture * A = SDL_CreateTextureFromSurface(renderer, A_srf); SDL_FreeSurface(A_srf);
SDL_SetRenderDrawColor(renderer, 0, 0, 0, 255);
//Events
while (!quit)
{
SDL_WaitEvent(&event);
switch (event.type)
{
case SDL_QUIT:
quit = true;
break;
case SDL_KEYUP:
{
if(z == 0)
{
switch(event.key.keysym.sym)
{
//case SDLK_1: SDL_BlitSurface(A_srf, NULL, surface, srfrect); break;
case SDLK_2: SDL_RenderCopy(renderer, A, NULL, &rect); if(x == 928){x = 0; y += 32;} else{x += 32;} rect.x = x; rect.y = y; SDL_RenderClear(renderer); SDL_RenderPresent(renderer); break;
case SDLK_LEFT: z = 1; std::cout << "1"; break;
}
}
if(z == 1)
{
switch(event.key.keysym.sym)
{
case SDLK_UP: z = 0; std::cout << "0"; break;
}
}
}
}
}
//Cleanup
SDL_DestroyRenderer(renderer);
SDL_DestroyTexture(A);
SDL_DestroyWindow(window);
SDL_Quit();
return 0;
}
I've tried moving the render clear render present stuff around but it hasn't seemed to be activating at all.

What Causes SDL_Renderer to be invalid?

I'm trying to make a 2D game where the background is a hockey rink. The error handler said the Render-er didn't initialize thus making the texture not initialize. I know the BMP loads because I don't get an error for that. Don't worry about the camera stuff. The background is supposed to scroll. I just need the background to render. The code may not be the best, but corrections are always appreciated.
#include <SDL/SDL.h>
#include <stdio.h>
#include <iostream>
#include <fstream>
#include <string>
using namespace std;
const int fps = 60;
SDL_Window *window;
int main(int argc, char **argv)
{
SDL_Init(SDL_INIT_EVERYTHING);
int x = 0, y = 0;
SDL_Surface *screen;
SDL_Surface *background = SDL_LoadBMP("hockeyrink.bmp");
if(background == NULL)
{
SDL_ShowSimpleMessageBox(0, "Background init error", SDL_GetError(), window);
}
SDL_Renderer *renderer = SDL_CreateRenderer(window, -1, 0);
if(renderer == NULL)
{
SDL_ShowSimpleMessageBox(0, "Renderer init error", SDL_GetError(), window);
}
SDL_Texture *texture = SDL_CreateTextureFromSurface(renderer,background);
if(texture == NULL)
{
SDL_ShowSimpleMessageBox(0, "Texture init error", SDL_GetError(), window);
}
const int speed = 5;
SDL_Rect camera;
camera.x = 0;
camera.y = 0;
camera.w = 800;
camera.h = 600;
bool b[2] = {0,0};
Uint32 start;
window = SDL_CreateWindow("", 300, 100, 1024, 800, SDL_WINDOW_OPENGL);
if (window == NULL)
{
cout << ("could not create window: %s/n", SDL_GetError());
return 1;
}
bool running = true;
while (running)
{
start = SDL_GetTicks();
SDL_Event event;
while(SDL_PollEvent(&event))
{
switch(event.type)
{
case SDL_QUIT:
running = false;
SDL_DestroyTexture(texture);
SDL_FreeSurface(background);
SDL_DestroyRenderer(renderer);
SDL_DestroyWindow(window);
SDL_Quit();
break;
case SDL_KEYDOWN:
switch(event.key.keysym.sym)
{
case SDLK_UP:
b[0]=1;
break;
case SDLK_LEFT:
b[1]=1;
break;
}
break;
case SDL_KEYUP:
switch(event.key.keysym.sym)
{
case SDLK_UP:
b[0]=0;
break;
case SDLK_LEFT:
b[1]=0;
break;
}
break;
}
}
if(b[0])
{
x+=speed;
camera.y+=speed;
if (camera.y > 3000-800)
{
camera.y=0;
}
}
else if(b[1])
{
x-=speed;
camera.y-=speed;
if (camera.y <= 0)
{
camera.y = 2000-800;
}
SDL_RenderCopy(renderer, texture, NULL, NULL);
SDL_RenderPresent(renderer);
}
if(1000/fps>SDL_GetTicks()-start)
{
SDL_Delay(1000/fps-(SDL_GetTicks() - start));
}
}
return 0;
}
When you create renderer, the window pointer does not point to anything(i.e. it is uninitialized).
You must create the window before creating the renderer.
So put the lines:
window = SDL_CreateWindow("", 300, 100, 1024, 800, SDL_WINDOW_OPENGL);
if (window == NULL)
{
cout << ("could not create window: %s/n", SDL_GetError());
return 1;
}
before the line: SDL_Renderer *renderer = SDL_CreateRenderer(window, -1, 0);

SDL, How can I make the background picture render?

I had a render problem, but I fixed that. The problem is, is that the picture won't actually show up. I know the picture gets loaded because I have an error handler if it isn't loaded. I know the code is messy, but I just need the picture to show up.
#include <SDL/SDL.h>
#include <stdio.h>
#include <iostream>
#include <fstream>
#include <string>
using namespace std;
const int fps = 60;
SDL_Window *window;
int main(int argc, char **argv)
{
SDL_Init(SDL_INIT_EVERYTHING);
window = SDL_CreateWindow("", 300, 100, 1024, 800, SDL_WINDOW_OPENGL);
if (window == NULL)
{
cout << ("could not create window: %s/n", SDL_GetError());
return 1;
}
SDL_Renderer *renderer = SDL_CreateRenderer(window, -1, 0);
int x = 0, y = 0;
SDL_Surface *screen;
SDL_Surface *background = SDL_LoadBMP("hockeyrink.bmp");
if(background == NULL)
{
SDL_ShowSimpleMessageBox(0, "Background init error", SDL_GetError(), window);
}
if(renderer == NULL)
{
SDL_ShowSimpleMessageBox(0, "Renderer init error", SDL_GetError(), window);
}
SDL_Texture *texture = SDL_CreateTextureFromSurface(renderer,background);
if(texture == NULL)
{
SDL_ShowSimpleMessageBox(0, "Texture init error", SDL_GetError(), window);
}
const int speed = 5;
SDL_Rect camera;
camera.x = 0; //Don't worry about this camera, I need this after i get the background working.
camera.y = 0;
camera.w = 800;
camera.h = 600;
bool b[2] = {0,0};
Uint32 start;
bool running = true;
while (running)
{
start = SDL_GetTicks();
SDL_Event event;
while(SDL_PollEvent(&event))
{
switch(event.type)
{
case SDL_QUIT:
running = false;
SDL_DestroyTexture(texture);
SDL_FreeSurface(background);
SDL_DestroyRenderer(renderer);
SDL_DestroyWindow(window);
SDL_Quit();
break;
case SDL_KEYDOWN:
switch(event.key.keysym.sym)
{
case SDLK_UP:
b[0]=1;
break;
case SDLK_LEFT:
b[1]=1;
break;
}
break;
case SDL_KEYUP:
switch(event.key.keysym.sym)
{
case SDLK_UP:
b[0]=0;
break;
case SDLK_LEFT:
b[1]=0;
break;
}
break;
}
}
if(b[0])
{
x+=speed;
camera.y+=speed;
if (camera.y > 3000-800)
{
camera.y=0;
}
}
else if(b[1])
{
x-=speed;
camera.y-=speed;
if (camera.y <= 0)
{
camera.y = 2000-800;
}
SDL_RenderCopy(renderer, texture, NULL, NULL);
SDL_RenderPresent(renderer);
}
if(1000/fps>SDL_GetTicks()-start)
{
SDL_Delay(1000/fps-(SDL_GetTicks() - start));
}
}
return 0;
}
You have initialized b[1] to 0 and the texture is rendered only when b[1] is 1 as in your code.
You should either put the lines:
SDL_RenderCopy(renderer, texture, NULL, NULL);
SDL_RenderPresent(renderer);
before the loop,
or press the left key of your keyboard(i.e. SDLK_LEFT)
to render and present the image on the screen.
It works in my system, so it should work in yours, too.