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.
Related
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.
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.
#include<stdio.h>
#include<SDL2/SDL.h>
#include<SDL2/SDL_timer.h>
#define SCREEN_WIDTH 1280
#define SCREEN_HEIGHT 720
#define SPEED 250
#define FPS 60
int main(int argc,char* args[])
{
SDL_Surface *imageSurface = NULL;
SDL_Surface *windowSurface = NULL;
/*Initializing Graphics and Timer System*/
if(SDL_Init(SDL_INIT_VIDEO|SDL_INIT_TIMER)!=0){
printf("Error Initializing SDL: %s\n",SDL_GetError());
return 1;
}
/*Creating a Window*/
SDL_Window* window = NULL;
window = SDL_CreateWindow("HELI",
SDL_WINDOWPOS_CENTERED,
SDL_WINDOWPOS_CENTERED,
SCREEN_WIDTH,SCREEN_HEIGHT,
SDL_WINDOW_RESIZABLE);
windowSurface = SDL_GetWindowSurface(window);
if(window == NULL){
printf("Error Creating Window: %s\n",SDL_GetError());
SDL_Quit();
return 1;
}
/*Creating a Renderer, Which Sets Up the Graphics Hardware*/
Uint32 render_flags = SDL_RENDERER_ACCELERATED;
SDL_Renderer* renderer = NULL;
renderer = SDL_CreateRenderer(window,-1,render_flags);
if(renderer == NULL){
printf("Error Creating Renderer: %s\n",SDL_GetError());
SDL_DestroyWindow(window);
SDL_Quit();
return 1;
}
/*Loading the Player image into memory using SDL Image Library Function*/
SDL_Surface* player = NULL;
player = SDL_LoadBMP("/home/betmon69/Documents/Heli/Images/player.bmp");
if(player == NULL){
printf("Error Creating Player\n");
SDL_DestroyRenderer(renderer);
SDL_DestroyWindow(window);
SDL_Quit();
return 1;
}
/*Loading the Player Image Data Into the Graphics Hardware's Memory*/
SDL_Texture* player_tex = NULL;
player_tex = SDL_CreateTextureFromSurface(renderer,player);
SDL_FreeSurface(player);
if(player_tex == NULL){
printf("Error Creating Player Texture: %s\n",SDL_GetError());
SDL_DestroyRenderer(renderer);
SDL_DestroyWindow(window);
SDL_Quit();
return 1;
}
/*Structure to Hold the Position and Size of the Player*/
SDL_Rect dest;
/*Get the Dimensions of Player*/
SDL_QueryTexture(player_tex,NULL,NULL,&dest.w,&dest.h);
dest.w;
dest.h;
/* Start the Player in Center of Screen(ami nije korbo eta)*/
float x_pos = (SCREEN_WIDTH - dest.w)/2;
float y_pos = (SCREEN_HEIGHT - dest.h);
float x_vel = 0;
float y_vel = 0;
/*Keep Track of Which Inputs are given*/
int up = 0;
int down = 0;
int left = 0;
int right = 0;
/*Animation Loop*/
SDL_Event event;
imageSurface = SDL_LoadBMP("/home/betmon69/Documents/Heli/Images/background.bmp");
if(imageSurface == NULL){
printf("SDL Could Not Load Background! SDL Error: %s\n",SDL_GetError());
}
bool running = true;
while(running){
while(SDL_PollEvent(&event)){
switch(event.type){
case SDL_QUIT:
running = false;
break;
case SDL_KEYDOWN:
switch(event.key.keysym.scancode){
case SDL_SCANCODE_W:
case SDL_SCANCODE_UP:
up = 1;
break;
case SDL_SCANCODE_A:
case SDL_SCANCODE_LEFT:
left = 1;
break;
case SDL_SCANCODE_S:
case SDL_SCANCODE_DOWN:
down = 1;
break;
case SDL_SCANCODE_D:
case SDL_SCANCODE_RIGHT:
right = 1;
break;
}
break;
case SDL_KEYUP:
switch(event.key.keysym.scancode){
case SDL_SCANCODE_W:
case SDL_SCANCODE_UP:
up = 0;
break;
case SDL_SCANCODE_A:
case SDL_SCANCODE_LEFT:
left = 0;
break;
case SDL_SCANCODE_S:
case SDL_SCANCODE_DOWN:
down = 0;
break;
case SDL_SCANCODE_D:
case SDL_SCANCODE_RIGHT:
right = 0;
break;
}
break;
}
}
SDL_BlitSurface(imageSurface,NULL,windowSurface,NULL);
SDL_UpdateWindowSurface(window);
/*Determine the Velocity*/
x_vel = 0;
y_vel = 0;
if(up && !down) y_vel = -SPEED;
if(down && !up) y_vel = SPEED;
if(left && !right) x_vel = -SPEED;
if(right && !left) x_vel = SPEED;
/*Update Positions*/
x_pos += x_vel/60;
y_pos +=y_vel/60;
/*Collision Detection with Borders*/
if(x_pos<=0) x_pos = 0;
if(y_pos<=0) y_pos = 0;
if(x_pos>=SCREEN_WIDTH - dest.w) x_pos = SCREEN_WIDTH - dest.w;
if(y_pos>=SCREEN_HEIGHT - dest.h) y_pos = SCREEN_HEIGHT - dest.h;
/*Set the Positions in the Structure*/
dest.y = (int) y_pos;
dest.x = (int) x_pos;
/*Clear the Window*/
SDL_RenderClear(renderer);
/*Draw the Player to the Window*/
SDL_RenderCopy(renderer,player_tex,NULL,&dest);
SDL_RenderPresent(renderer);
SDL_Delay(1000/60);
}
/*Clean Up Resources Before Exiting*/
SDL_DestroyTexture(player_tex);
SDL_FreeSurface(imageSurface);
SDL_FreeSurface(windowSurface);
SDL_DestroyRenderer(renderer);
SDL_DestroyWindow(window);
SDL_Quit();
return 0;
}
So in my code you can see that i have created player which can freely roam around and collision also happens. I just want to create a background for the player i just have created. But the background doesn't create. I have used SDL_Surface and also used SDL_GetWindowSurface(). but the error i am getting is "Error Creating Renderer: Renderer already associated with window". What should i change to have a background for my player? Please Help.
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;
}
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);