I have been working on this game using SDL2.0 and C++ and have hit a snag. I have created the move function and am calling the right rectangle. And have called the move function in the main loop and it just doesn't move.
Here is the code.
//
// Window.cpp
// Galaxy Shooter
//
// Created by Samrith on 02/03/14.
// Copyright (c) 2014 Sam Shankar. All rights reserved.
//
#include "Window.h"
void Window::create() {
Resources r;
SDL_Init(SDL_INIT_EVERYTHING);
window = SDL_CreateWindow("Galaxy Shooter", SDL_WINDOWPOS_UNDEFINED, SDL_WINDOWPOS_UNDEFINED, SCREEN_WIDTH, SCREEN_HEIGHT, SDL_WINDOW_SHOWN);
screen = SDL_GetWindowSurface(window);
if(window == NULL)
std::cout << " Window cannot be created. Error: " << SDL_GetError();
else {
r.load();
SDL_UpdateWindowSurface(window);
}
}
void Window::destroy() {
Resources r;
SDL_DestroyWindow(window);
r.free();
SDL_Quit();
}
void Window::run() {
bool done = false;
Resources r;
create();
while(!done)
{
while(SDL_PollEvent(&event) != 0)
{
if(event.type == SDL_QUIT)
{
done = true;
destroy();
}
r.move(event); //This is the move function
SDL_UpdateWindowSurface(window);
}
r.projectile();
SDL_UpdateWindowSurface(window);
}
}
SDL_Window * Window::getWindow() {
return window;
}
SDL_Surface * Window::getSurface() {
return screen;
}
And here is the resources source file which contains the move function:
//
// Resources.cpp
// Galaxy Shooter
//
// Created by Samrith on 06/03/14.
// Copyright (c) 2014 Sam Shankar. All rights reserved.
//
#include "Resources.h"
bool b[4] = {0, 0, 0, 0};
void Resources::load() {
background();
rocket();
//r.create();
}
void Resources::free() {
Sound s;
SDL_FreeSurface(bgimage);
SDL_FreeSurface(rimage);
//SDL_FreeSurface(screen);
s.destroy();
}
//void Resources::run() {
// Window w;
// w.run();
//}
void Resources::background() {
Window w;
Sound s;
//Load screen
screen = SDL_GetWindowSurface(w.getWindow());
if(screen == NULL)
std::cout << "Surface (background) error: " << SDL_GetError();
//Load image
bgimage = IMG_Load("bg2.jpg");
if(bgimage == NULL)
std::cout << "Image (background) error: " << SDL_GetError();
//Load rectangle and set values
bgrect.x = 0;
bgrect.y = 0;
bgrect.h = w.screenH();
bgrect.w = w.screenW();
//Blit image to screen
SDL_BlitScaled(bgimage, NULL, screen, &bgrect);
s.init(1);
}
void Resources::rocket() {
Window w;
Sound s;
//Load screen
screen = SDL_GetWindowSurface(w.getWindow());
if(screen == NULL)
std::cout << "Surface (rocket) error: " << SDL_GetError();
//Load image
rimage = IMG_Load("rocket.png");
if(rimage == NULL)
std::cout << "Image (rocket) error: " << SDL_GetError();
//Load rectangle and set values
rrect.x = 15;
rrect.y = w.screenH()/2;
rrect.h = 75;
rrect.w = 75;
//Blit image to screen
SDL_BlitScaled(rimage, NULL, screen, &rrect);
//s.init(2);
}
void Resources::move(SDL_Event event) {
//bool done = false;
Window w;
switch(event.type)
{
case SDL_KEYDOWN:
switch(event.key.keysym.sym)
{
case SDLK_UP:
b[0] = 1; break;
case SDLK_DOWN:
b[1] = 1; break;
case SDLK_RIGHT:
b[2] = 1; break;
case SDLK_LEFT:
b[3] = 1; break;
}
break;
case SDL_KEYUP:
switch(event.key.keysym.sym)
{
case SDLK_UP:
b[0] = 0; break;
case SDLK_DOWN:
b[1] = 0; break;
case SDLK_RIGHT:
b[2] = 0; break;
case SDLK_LEFT:
b[3] = 0; break;
}
break;
}
if(b[0]==true)
rrect.y += 10;
if(b[1]==true)
rrect.y -= 10;
if(b[2]==true)
rrect.x += 10;
if(b[3]==true)
rrect.x -= 10;
}
void Resources::projectile() {
Window w;
SDL_PumpEvents();
int x, y;
SDL_GetMouseState(&x, &y);
if(SDL_GetMouseState(&x, &y) & SDL_BUTTON(1))
{
rrect.x = x;
rrect.y = y;
SDL_BlitScaled(rimage, NULL, screen, &rrect);
for(int i=rrect.x; i<=w.screenW(); i++)
rrect.x+=2;
}
}
Also, I have Googled this problem and tried out various tutorials and docs. This is my last resort and not the first place I turned to for this problem. So please be kind. :)
by declaring Resource r in every function you create a new instance of the Resource class every time thus creating many different Resource objects.
The same goes for the Window w variable you declare in every function of the class Resource: each function call will create a new window.
I suggest you to read about Object Oriented Programming and variable scoping.
Also, C++ is not the most friendly language to start learning about Object Oriented Programming.
If you are starting out, I suggest you to switch to a simpler language such as Java or C#.
Good luck.
Related
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.
I'm trying to make a simple Snake game. The self collision and a lot of things aren't ready. The problem is: Even with no errors, running just fine, changing "close()" to "endGame()" and reverting, rebuilding the entire program, i could not render anything with SDL_RenderCopy. You will see many unnecessary things in my code and some Brazilian-Portuguese comments, prepare yourself.
The image is a 16x16 png spritesheet, using the color #ff00ff as ColorKey. There are only 4 sprites in this spritesheet, respectively: Apple, Snake's Body, Snake's Head and Snake's Tail (still unused).
Whole code:
#include <iostream>
#include <SDL2/SDL.h>
#include <SDL2/SDL_image.h>
#include <stdlib.h>
#include <time.h>
#include <stdio.h>
using namespace std;
const int CELL_SIZE = 16;
const int CELL_WIDTH = 16;
const int CELL_HEIGHT = 16;
const int SCREEN_WIDTH = CELL_SIZE * (CELL_WIDTH-1);
const int SCREEN_HEIGHT = CELL_SIZE * (CELL_HEIGHT-1);
SDL_Window* gWindow = NULL;
SDL_Renderer* gRenderer = NULL;
void loadTexture(string path);
SDL_Texture* spriteSheet = NULL;
void loadMedia();
void init();
class Snake {
int initialLength = 3; //from body (head incluse)
int length = initialLength;
int facing = DIR_UP;
//Head position in CELLS (multiplied for CELL_SIZE when drawed)
int x = 5;
int y = 5;
//UNUSED TEMPORARY COLORS - IGNORE
Uint8 color[3] = {0x22,0x88,0x44}; //Snake Color, em RGB
Uint8 headColor[3] = {0x11,0x44,0x44}; //Color for the Head of the Snek
int stepDelay = 60; //time in frames that the Snakes waits till move
int stepFramesRemaining = stepDelay;
int stepDelayReduction = 1; //reduces stepDelay every time the Snakes eats the apple
const int minStepDelay = 15; //the minimum delay
//For clipping the image (its an 16x16 png image)
const SDL_Rect clipHead = {0,8,8,8};
const SDL_Rect clipBody = {8,0,8,8};
const SDL_Rect clipTail = {8,8,8,8};
public:
enum direction { //direções nas quais a cobra pode se mover
DIR_UP,
DIR_RIGHT,
DIR_DOWN,
DIR_LEFT
};
/* The following var stores the entire Snake's body in an 2D Array. The number stored means how much "steps" it will survive.
When the value is zero, it means that there is no body in the place. The bodypart with value equivalent to "length" is the Head.
*/
int body[CELL_WIDTH][CELL_HEIGHT];
void init(); //initializes some vars
void tick(); //tick function
void stepFoward(); //moves Snake foward
void faceTo(int dir); //alters which direction Snake is faced
void eat(); //eats the apple
void draw(); //renders (or at least tries) to render the snake
int getLength(){
return length;
};
int getFacing(){
return facing;
};
} Snake;
class Food {
Uint8 color[3] = {0x85,0x22,0x10}; //RGB color of the Apple
bool visible = true;
public:
int x = 2;
int y = 2;
void respawn();
void destroy();
void draw();
} Food;
void Food::respawn(){
//teleports the apple to a random spot
x = rand() % (CELL_WIDTH-2);
y = rand() % (CELL_HEIGHT-2);
visible = true;
}
void Food::destroy(){
//Reset values
x = 0;
y = 0;
visible = false;
//resets
respawn();
}
void Food::draw(){
if(visible){
SDL_Rect rect = {x*CELL_SIZE,y*CELL_SIZE,CELL_SIZE,CELL_SIZE};
SDL_SetRenderDrawColor(gRenderer,color[0],color[1],color[2],0xff);
SDL_RenderFillRect(gRenderer, &rect);
}
}
void Snake::init(){
//Spawns in a vertical line
for(int i=0; i<length; i++){
body[x][y+i] = length-i;
}
}
void Snake::tick(){
if(stepFramesRemaining > 0){
stepFramesRemaining--;
} else {
//when 0, moves the snake
stepFramesRemaining = stepDelay;
stepFoward();
}
}
void Snake::eat(){
//increases the body size by 1
for(int i=0; i<CELL_HEIGHT; i++){
for(int j=0; j<CELL_WIDTH; j++){
if(body[j][i] > 0){
body[j][i]++;
}
}
}
length++;
if(stepDelay > minStepDelay){
stepDelay -= stepDelayReduction;
}
Food.destroy();
}
void Snake::draw(){
//SDL_SetRenderDrawColor(gRenderer,color[0],color[1],color[2],0xff);
SDL_Rect rect = {0,0,0,0}; //for later use
//Draws the body and head
for(int i=0; i<CELL_HEIGHT; i++){
for(int j=0; j<CELL_WIDTH; j++){
if(body[j][i] == length){
rect = {j*CELL_SIZE,i*CELL_SIZE,CELL_SIZE,CELL_SIZE};
SDL_SetRenderDrawColor(gRenderer,0x33,0xff,0x22,0xff);
SDL_RenderFillRect(gRenderer,&rect);
SDL_RenderCopy(gRenderer, spriteSheet, &clipHead, &rect);
} else if (body[j][i] > 0){
rect = {j*CELL_SIZE,i*CELL_SIZE,CELL_SIZE,CELL_SIZE};
//SDL_SetRenderDrawColor(gRenderer,color[0],color[1],color[2],0xff);
SDL_RenderCopyEx(gRenderer, spriteSheet, &clipBody, &rect, 0, NULL, SDL_FLIP_NONE);
SDL_SetRenderDrawColor(gRenderer,0x66,0xee,0x22,0xff);
SDL_RenderFillRect(gRenderer,&rect);
}
SDL_RenderFillRect(gRenderer,&rect);
}
}
//SDL_RenderFillRect(gRenderer,&rect);
}
void Snake::stepFoward(){
int headMoved = 0; //informs if the head already moved
//decreases the "body" lifespan and moves head
for(int i=0; i<CELL_HEIGHT; i++){
for(int j=0; j<CELL_WIDTH; j++){
if(body[j][i] > 0){
//Verifica se é a cabeça, para movê-la logo em seguida
if(body[j][i] == length && headMoved < 2){
//moves head position, looping if needed
switch(facing){
case DIR_UP:
if(y == 0){
body[x][CELL_HEIGHT-1] = length;
y = CELL_HEIGHT-1;
} else {
body[x][y-1] = length;
y--;
}
break;
case DIR_DOWN:
if(y == CELL_HEIGHT-2){
body[x][0] = length+1; //(+1 to avoid being subtracted twice)
y = 0;
} else {
body[x][y+1] = length+1;
y++;
}
break;
case DIR_LEFT:
if(x == 0){
body[CELL_WIDTH-1][y] = length;
x = CELL_WIDTH-1;
} else {
body[x-1][y] = length;
x--;
}
break;
case DIR_RIGHT:
if(x == CELL_WIDTH-2){
body[0][y] = length+1; //avoiding again the "-2" subtraction.
x = 0;
} else {
body[x+1][y] = length+1;
x++;
}
break;
}
headMoved++;
}
body[j][i]--; //decreases the "body" lifespan
}
}
}
//verifies if can eat (head in the same position as the apple)
if(x == Food.x && y == Food.y){
eat();
}
}
void Snake::faceTo(int dir){
facing = dir;
}
void init();
void close();
void init(){ //Initializes the game
gWindow = SDL_CreateWindow("· Snake ·", SDL_WINDOWPOS_CENTERED, SDL_WINDOWPOS_CENTERED, SCREEN_WIDTH, SCREEN_HEIGHT, SDL_WINDOW_SHOWN);
gRenderer = SDL_CreateRenderer( gWindow, -1, SDL_RENDERER_ACCELERATED );
if( gRenderer == NULL ){
printf( "Renderer could not be created! SDL Error: %s\n", SDL_GetError() );
}
int imgFlags = IMG_INIT_PNG;
if(!(IMG_Init(imgFlags) & imgFlags)){
cout << "IMG INIT error!" << endl;
}
loadMedia();
Snake.init();
}
void close(){ //Closes the program
SDL_DestroyTexture(spriteSheet);
spriteSheet = NULL;
SDL_DestroyRenderer(gRenderer);
gRenderer = NULL;
IMG_Quit();
SDL_Quit();
}
void loadTexture(string path){ //Almost the same function from LazyFoo tutorial
//The final texture
SDL_Texture* newTexture = NULL;
//Load image at specified path
SDL_Surface* loadedSurface = IMG_Load( path.c_str() );
if( loadedSurface == NULL )
{
printf( "Unable to load image %s! SDL_image Error: %s\n", path.c_str(), IMG_GetError() );
}
else
{
//Color key image
SDL_SetColorKey( loadedSurface, SDL_TRUE, SDL_MapRGB( loadedSurface->format, 0xff, 0x00, 0xff));
//Create texture from surface pixels
newTexture = SDL_CreateTextureFromSurface( gRenderer, loadedSurface);
if( newTexture == NULL ){
printf( "Unable to create texture from %s! SDL Error: %s\n", path.c_str(), SDL_GetError() );
}
//Get rid of old loaded surface
SDL_FreeSurface( loadedSurface );
}
spriteSheet = newTexture;
}
void loadMedia(){ //loads everything (it will load sound too, when i make the sounds of course)
loadTexture("spritesheet.png");
if(spriteSheet == NULL){
cout << "ERRO" << endl;
}
}
void tick(){
Snake.tick();
}
void draw(){ //Render Function
//Background
SDL_SetRenderDrawColor(gRenderer, 0xee, 0xf2, 0xf0, 0xff);
SDL_RenderClear(gRenderer);
Snake.draw();
Food.draw();
//Aplica as alterações
SDL_RenderPresent(gRenderer);
}
int main(){
srand (time (NULL));
init();
bool quit = false;
SDL_Event e; //Event Handling
while(!quit){
while(SDL_PollEvent(&e) != 0){
if(e.type == SDL_QUIT){
quit = true;
} else if(e.type == SDL_KEYDOWN){
switch(e.key.keysym.sym){
case SDLK_UP:
Snake.faceTo(Snake.DIR_UP);
break;
case SDLK_DOWN:
Snake.faceTo(Snake.DIR_DOWN);
break;
case SDLK_LEFT:
Snake.faceTo(Snake.DIR_LEFT);
break;
case SDLK_RIGHT:
Snake.faceTo(Snake.DIR_RIGHT);
break;
}
}
}
//Tick function
tick();
//Renders everything
draw();
SDL_RenderCopy(gRenderer, spriteSheet, NULL, NULL);
//Slows down the program just a bit (its not a time based frame system... yet)
SDL_Delay(3);
}
close(); //ends
return 0;
}
The portion of code who should be working, but isn't:
//Draws the body and head
for(int i=0; i<CELL_HEIGHT; i++){
for(int j=0; j<CELL_WIDTH; j++){
if(body[j][i] == length){
rect = {j*CELL_SIZE,i*CELL_SIZE,CELL_SIZE,CELL_SIZE};
SDL_SetRenderDrawColor(gRenderer,0x33,0xff,0x22,0xff);
SDL_RenderFillRect(gRenderer,&rect);
SDL_RenderCopy(gRenderer, spriteSheet, &clipHead, &rect);
} else if (body[j][i] > 0){
rect = {j*CELL_SIZE,i*CELL_SIZE,CELL_SIZE,CELL_SIZE};
//SDL_SetRenderDrawColor(gRenderer,color[0],color[1],color[2],0xff);
SDL_RenderCopyEx(gRenderer, spriteSheet, &clipBody, &rect, 0, NULL, SDL_FLIP_NONE);
SDL_SetRenderDrawColor(gRenderer,0x66,0xee,0x22,0xff);
SDL_RenderFillRect(gRenderer,&rect);
}
SDL_RenderFillRect(gRenderer,&rect);
}
}
//SDL_RenderFillRect(gRenderer,&rect);
}
the following program runs until SDL_GetRendererInfo is called (in function RenderInit()), and then stops working before SDL_GetError can do anything. replacing global_renderer with a null SDL_Renderer pointer doesn't cause a crash and the expected sdl error is gotten.
#include <iostream>
#include <list>
#include "SDL.h"
using namespace std;
//global variables:
bool run = true; // whether or not the program should be running
int global_window_width = 50; //width of window in tiles
int global_window_height = 35; //height of window in tiles
SDL_Window* global_window = NULL; //points to primary window
SDL_Renderer* global_renderer = NULL; //points to renderer for main window
SDL_RendererInfo* global_renderer_info = NULL; //points to info about above renderer once it's initialized
SDL_Texture* spritesheet = NULL; //holds the spritesheet
SDL_Event event; //for holding currently in-handling event
//function declarations:
int init(); //initialize SDL
int windowInit(); //initialize window
int renderInit(); //create renderers
int viewInit(); //manages all window, rendering, etc stuff
int loadSpritesheet(); //loads spritesheet
void cleanup(); //free up memory, etc
void dispatchEvent(); //main event handling
//function definitions:
int init()
{
if ( SDL_Init(SDL_INIT_EVERYTHING) !=0 )
{
cout << "could not initialize SDL. " << SDL_GetError();
return 1;
}
return 0;
}
int windowInit()
{
global_window = SDL_CreateWindow("roguelike",
SDL_WINDOWPOS_UNDEFINED,
SDL_WINDOWPOS_UNDEFINED,
global_window_width * 10,
global_window_height * 10,
SDL_WINDOW_SHOWN);
if(global_window == NULL)
{
cout << "could create window. " << SDL_GetError();
return 1;
}
return 0;
}
int renderInit()
{
global_renderer = SDL_CreateRenderer(global_window,
-1,
SDL_RENDERER_TARGETTEXTURE | SDL_RENDERER_ACCELERATED );
if (global_renderer == NULL)
{
cout << "could not create renderer" << SDL_GetError();
return 1;
}
SDL_SetRenderDrawColor(global_renderer,0xFF,0xFF,0xFF,0xFF);
if (SDL_GetRendererInfo(global_renderer, global_renderer_info) != 0)
{
cout << "could not get renderer info" << SDL_GetError();
return 1;
}
return 0;
}
int viewInit()
{
if (windowInit() == 1)
{
return 1;
}
else if(renderInit() == 1)
{
return 1;
}
else if(loadSpritesheet() == 1)
{
return 1;
}
return 0;
}
int loadSpritesheet()
{
SDL_Surface* tempsurf = NULL; //using surface to get image initially, but since surfaces use cpu rendering we switch to textures immediately
tempsurf = SDL_LoadBMP("spritesheet.bmp"); //puts image in the surface
if (tempsurf == NULL)
{
cout << "failed to load spritesheet";
SDL_FreeSurface(tempsurf); //we don't need tempsurf anymore
return 1;
}
spritesheet = SDL_CreateTextureFromSurface(global_renderer, tempsurf);
if (spritesheet == NULL)
{
cout << "failed to create spritesheet texture";
SDL_FreeSurface(tempsurf); //we don't need tempsurf anymore
return 1;
}
SDL_FreeSurface(tempsurf); //we don't need tempsurf anymore
return 0;
}
void cleanup()
{
SDL_DestroyWindow(global_window);
global_window = NULL;
SDL_DestroyRenderer(global_renderer);
global_renderer = NULL;
SDL_DestroyTexture(spritesheet);
spritesheet = NULL;
global_renderer_info = NULL;
SDL_Quit();
}
void dispatchEvent()
{
SDL_PollEvent(&event); //stores current event information
switch(event.type)
{
case SDL_QUIT:
{
run = false;
break;
}
}
}
//classes:
class Layer // each layer holds visuals for a certain subset of what is to be displayed; environment, HUD, menu, etc.
{
Layer(){};
};
class Camera //renders environment, ui, etc in a series of layers
{
int width, height; //in tiles
SDL_Texture* texture_draw; //texture the camera draws to and sends to be displayed
list<Layer*> layer_list; //list of layers to be rendered, back --> front
public:
Camera(int x, int y, SDL_Renderer* renderer): width(x), height(y) //(width, height, renderer for camera to use)
{
texture_draw = SDL_CreateTexture(global_renderer,global_renderer_info->texture_formats[0] , SDL_TEXTUREACCESS_TARGET, 10*width, 10*height);
};
};
//main loop
int main(int argc, char *argv[]) //main function, needed by SDL
{
if(init() == 0)
{
if(viewInit() == 0)
{
while(run)
{
dispatchEvent();
}
}
}
cleanup();
return 0;
}
You're asking SDL_GetRendererInfo to write renderer info to location global_renderer_info points to, which is NULL. Writing to NULL causes segmentation fault. This should be expected behaviour.
Correct code should allocate memory for renderer info (preferably on stack or in global area) and write to that location, e.g.:
SDL_RendererInfo info = {0};
SDL_GetRendererInfo(global_renderer, &info);
// ... use info fields
Fixed by: instead of declaring global_renderer_info as a pointer to an SDL_RendererInfo, I instead declared the object directly and changed the rest of the code accordingly.
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);
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.