How to use SDL_KeyCode to handle a key press each time? - c++

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;
}

Related

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.

SDL window shows incorrectly. On linux terminal

This is basically my code here, very simple just to load an image to display. But the first thing I open a window surface, the surface has characters like 'X','S' out of nowhere:
int main( int argc, char* args[] )
{
SDL_Init( SDL_INIT_VIDEO );
SDL_Surface* screen = SDL_SetVideoMode( WINDOW_WIDTH, WINDOW_HEIGHT, 0,
SDL_HWSURFACE | SDL_DOUBLEBUF );
SDL_WM_SetCaption( WINDOW_TITLE, 0 );
SDL_Surface* bitmap = SDL_LoadBMP("bat.bmp");
// Part of the bitmap that we want to draw
SDL_Rect source;
source.x = 24;
source.y = 63;
source.w = 65;
source.h = 44;
// Part of the screen we want to draw the sprite to
SDL_Rect destination;
destination.x = 100;
destination.y = 100;
destination.w = 65;
destination.h = 44;
SDL_Event event;
bool gameRunning = true;
int i=1000;
while (i)
{
if (SDL_PollEvent(&event))
{
if (event.type == SDL_QUIT)
{
gameRunning = false;
}
}
SDL_BlitSurface(bitmap, &source, screen, &destination);
SDL_Flip(screen);
i--;
}
SDL_FreeSurface(bitmap);
SDL_Quit();
return 0;
}

Error: Pointer to incomplete class type is not allowed. SDL/c++

So I'm new to SDL and in my code I'm getting this error:
pointer to incomplete class type is not allowed.
Here's the code:
main.cpp
#include <SDL.h>
#include "events.h"
int main(int argc, char ** argv)
{
SDL_Renderer* ro;
SDL_Texture* to;
SDL_Surface* so;
SDL_Window* wo;
SDL_FreeSurface(so->getImage());
SDL_SetRenderDrawColor(ro->getRenderer(), 255, 255, 255, 255); // error here
// handle events
events mo;
mo.handleEvents();
// cleanup SDL
SDL_DestroyTexture(to->getTexture()); // error here
SDL_DestroyRenderer(ro->getRenderer()); // error here
SDL_DestroyWindow(wo->getWindow()); // error here
SDL_Quit();
return 0;
}
events.h
#pragma once
class events
{
public:
events();
void handleEvents();
SDL_Renderer* getRenderer();
SDL_Texture* getTexture();
SDL_Surface* getImage();
SDL_Window* getWindow();
~events();
private:
SDL_Event event;
int x;
int y;
bool quit;
SDL_Renderer *renderer;
SDL_Texture *texture;
SDL_Surface *image;
SDL_Window *window;
};
events.cpp
#include "events.h"
#include <SDL.h>
events::events()
{
SDL_Event event;
int x = 288;
int y = 208;
bool quit = false;
SDL_Renderer *renderer = SDL_CreateRenderer(window, -1, 0);
SDL_Texture *texture = SDL_CreateTextureFromSurface(renderer, image);
SDL_Surface *image = SDL_LoadBMP("face.bmp");
SDL_Window *window = SDL_CreateWindow("SDL2 Keyboard/Mouse events", SDL_WINDOWPOS_UNDEFINED,SDL_WINDOWPOS_UNDEFINED, 640, 480, 0);
}
events::~events()
{
}
void events::handleEvents(){
SDL_Init(SDL_INIT_VIDEO);
while (!quit)
{
SDL_Delay(10);
SDL_PollEvent(&event);
switch (event.type)
{
case SDL_QUIT:
quit = true;
break;
case SDL_KEYDOWN:
switch (event.key.keysym.sym)
{
case SDLK_LEFT:
x -= 5;
break;
case SDLK_RIGHT:
x += 5;
break;
case SDLK_UP:
y -= 5;
break;
case SDLK_DOWN:
y += 5;
break;
}
break;
}
SDL_Rect dstrect = { x, y, 64, 64 };
SDL_RenderClear(renderer);
SDL_RenderCopy(renderer, texture, NULL, &dstrect);
SDL_RenderPresent(renderer);
}
}
SDL_Renderer* events::getRenderer(){
return renderer;
}
SDL_Texture* events::getTexture(){
return texture;
}
SDL_Surface* events::getImage(){
return image;
}
SDL_Window* events::getWindow(){
return window;
}
You are getting that error when compiling events.cpp because events.h does not include SDL.h before it uses SDL data types. Then in events.cpp, you have SDL.h included after events.h, hence the error.

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.