SDL crashing when calling SDL_CreateTextureFromSurface - c++

I'm really new to c++ programming with SDL and I've got a really strange problem when running my program: SDL crashes when it arrives to SDL_CreateTextureFromSurface and then I couldn't even close the window using Task Manager! I'm very confused because the code worked so well and I didn't change anything before having this problem! Tried even to use debugger but it failed to locate the error:
After googling for hours and hours, didn't find any satisfying result. Here's my code:
#include <SDL.h>
#include <SDL_ttf.h>
#include <string>
#include <sstream>
#include <stdlib.h>
#include <stdio.h>
#include <time.h>
#include <vector>
const int WIN_W = 1000;
const int WIN_H = 550;
const int CEN_W = 511;
const int CEN_H = 511;
const int CEN_X = (WIN_W - CEN_W) / 2;
const int CEN_Y = (WIN_H - CEN_H) / 2;
const int SEP_W = 3;
const int MAX_X = 4;
const int MAX_Y = 4;
const int nbImages = 11;
int numbers[MAX_X][MAX_Y];
int winNumbers[MAX_X][MAX_Y];
TTF_Font* gameNbFont = NULL;
TTF_Font* textFont = NULL;
TTF_Font* pixelFont = NULL;
SDL_Window* window = NULL;
SDL_Renderer* renderer = NULL;
SDL_Texture* numbersTextures[MAX_X * MAX_Y - 1];
SDL_Texture* bgImage = NULL;
SDL_Texture* bgImages[nbImages];
SDL_Rect* numbersContsRectsPos[MAX_X][MAX_Y];
SDL_Rect* numbersContsRectsCrops[MAX_X * MAX_Y - 1];
SDL_Rect* restartButtonRect = NULL;
SDL_Texture* timeStringTexture = NULL;
SDL_Texture* timeIntTexture = NULL;
SDL_Texture* movesStringTexture = NULL;
SDL_Texture* movesIntTexture = NULL;
SDL_Texture* restartButtonTexture;
enum texturesSizesEnum{
TIME_STRING,
TIME_INT,
MOVES_STRING,
MOVES_INT,
TEXTURES_SIZES_TOTAL
};
std::pair<int, int> texturesSizes[TEXTURES_SIZES_TOTAL];
std::pair<int, int> numbersTexturesSizes[MAX_X * MAX_Y - 1];
int currentTime = -1;
int nbMoves = -1;
int timeFraction = 0;
bool stop;
void updateTime(){
if (currentTime == 999){
return;
}
currentTime ++;
std::ostringstream sm;
sm << currentTime;
std::string time = std::string(3-sm.str().length(), '0') + sm.str();
SDL_Surface* timeIntSurface = TTF_RenderText_Solid(pixelFont, time.c_str(), SDL_Color({0XFF, 0XFF, 0XFF}));
timeIntTexture = SDL_CreateTextureFromSurface(renderer, timeIntSurface);
texturesSizes[TIME_INT] = std::make_pair(timeIntSurface->w, timeIntSurface->h);
}
void updateMoves(){
if (nbMoves == 999){
return;
}
nbMoves ++;
std::ostringstream sm;
sm << nbMoves;
std::string moves = std::string(3-sm.str().length(), '0') + sm.str();
SDL_Surface* movesIntSurface = TTF_RenderText_Solid(pixelFont, moves.c_str(), SDL_Color({0XFF, 0XFF, 0XFF}));
movesIntTexture = SDL_CreateTextureFromSurface(renderer, movesIntSurface);
texturesSizes[MOVES_INT] = std::make_pair(movesIntSurface->w, movesIntSurface->h);
}
bool initTextures(){
printf("started\n");
bool success=false;
gameNbFont = TTF_OpenFont("data/fonts/gothic.ttf", 40);
if (gameNbFont == NULL){
printf("Couldn't load data/fonts/gothic.ttf font! TTF_Error: %s\n", TTF_GetError());
}
else{
printf("breakpoint1\n");
for (int i=1; i<MAX_X * MAX_Y; i++){
printf("breakpoint1.%i.1\n", i);
std::ostringstream stm;
printf("breakpoint1.%i.2\n", i);
stm << i;
printf("breakpoint1.%i.3\n", i);
SDL_Surface* number = TTF_RenderText_Solid(gameNbFont, stm.str().c_str(), SDL_Color({0X4E, 0XCD, 0XC4}));
printf("breakpoint1.%i.4\n", i); //program crashes after printing this :(
numbersTextures[i-1] = SDL_CreateTextureFromSurface(renderer, number);
printf("breakpoint1.%i.5\n", i);
SDL_FreeSurface(number);
printf("breakpoint1.%i.6\n", i);
numbersTexturesSizes[i-1] = std::make_pair(number->w, number->h);
}
printf("breakpoint2\n");
textFont = TTF_OpenFont("data/fonts/PlayfairDisplay.ttf", 50);
if (textFont == NULL){
printf("Couldn't load data/fonts/PlayfairDisplay.ttf font! TTF_Error: %s", TTF_GetError());
}
else{
printf("breakpoint3");
SDL_Surface* timeStringSurface = TTF_RenderText_Solid(textFont, "TIME:", SDL_Color({0XFF, 0xFF, 0XFF}));
timeStringTexture = SDL_CreateTextureFromSurface(renderer, timeStringSurface);
texturesSizes[TIME_STRING] = std::make_pair(timeStringSurface->w, timeStringSurface->h);
SDL_Surface* movesStringSurface = TTF_RenderText_Solid(textFont, "MOVES:", SDL_Color({0XFF, 0xFF, 0XFF}));
movesStringTexture = SDL_CreateTextureFromSurface(renderer, movesStringSurface);
texturesSizes[MOVES_STRING] = std::make_pair(movesStringSurface->w, movesStringSurface->h);
pixelFont = TTF_OpenFont("data/fonts/pixels.ttf", 40);
if (pixelFont == NULL){
printf("Couldn't load data/fonts/pixels.ttf font! TTF_Error: %s", TTF_GetError());
}
else{
bool loadedAllImages = true;
for (int i=1; i<=nbImages; i++){
std::ostringstream sm;
sm << "data/images/examples/image" << i << ".bmp";
SDL_Surface* image = SDL_LoadBMP(sm.str().c_str());
if (image == NULL){
printf("Couldn't load %s! SDL_Error: %s", sm.str().c_str(), SDL_GetError());
loadedAllImages = false;
break;
}
else{
image = SDL_ConvertSurface(image, image->format, 0);
SDL_Surface* scaledImage = SDL_CreateRGBSurface(0, CEN_W, CEN_H, 32, 0, 0, 0, 0);
SDL_Rect* stretchRect = new SDL_Rect({0, 0, CEN_W, CEN_H});
SDL_BlitScaled(image, NULL, scaledImage, stretchRect);
bgImages[i] = SDL_CreateTextureFromSurface(renderer, scaledImage);
}
}
if (loadedAllImages){
bgImage = bgImages[rand() % nbImages + 1];
for (int i=0; i<MAX_X * MAX_Y - 1; i++){
numbersContsRectsCrops[i] = new SDL_Rect({
numbersContsRectsPos[0][0]->w * (i % MAX_Y),
numbersContsRectsPos[0][0]->h * (i / MAX_Y),
numbersContsRectsPos[0][0]->w,
numbersContsRectsPos[0][0]->h});
}
SDL_Surface* restartButton = SDL_LoadBMP("data/images/restart.bmp");
if (restartButton == NULL){
printf("Couldn't load data/images/restart.bmp! SDL_Error: %s)", SDL_GetError());
}
else{
restartButton = SDL_ConvertSurface(restartButton, restartButton->format, 0);
restartButtonTexture = SDL_CreateTextureFromSurface(renderer, restartButton);
restartButtonRect = new SDL_Rect({(CEN_X + CEN_W + WIN_W - restartButton->w) / 2,
CEN_Y,
restartButton->w,
restartButton->h});
updateTime();
updateMoves();
success = true;
}
}
}
}
}
return success;
}
void shuffle(std::vector<int> *arr){
srand(time(0));
std::vector<int> workspace;
for (int i=0; i<MAX_X*MAX_Y-1; i++){
workspace.push_back(i);
}
for (int i=0; i<MAX_X*MAX_Y-1; i++){
int rv = rand() % (MAX_X * MAX_Y - 1 - i);
arr->push_back(workspace[rv]);
workspace.erase(workspace.begin() + rv);
}
}
void initNumbers(){
std::vector<int> shuffledNumbers;
shuffle(&shuffledNumbers);
for (int x=0; x<MAX_X; x++){
for (int y=0; y<MAX_Y; y++){
numbers[x][y] = shuffledNumbers[x + y * MAX_X];
}
}
numbers[MAX_X-1][MAX_Y-1] = -1;
for (int x=0; x<MAX_X; x++){
for (int y=0; y<MAX_Y; y++){
winNumbers[x][y] = x + y * MAX_X;
numbersContsRectsPos[x][y] = new SDL_Rect({CEN_X + SEP_W + ((CEN_W - SEP_W) / MAX_X) * x,
CEN_Y + SEP_W + ((CEN_H - SEP_W) / MAX_Y) * y,
(CEN_W - SEP_W) / MAX_X - SEP_W,
(CEN_H - SEP_W) / MAX_Y - SEP_W});
}
}
winNumbers[MAX_X][MAX_Y] = -1;
}
bool init(){
bool success = false;
if (SDL_Init(SDL_INIT_EVERYTHING) < 0){
printf("SDL couldn't init! SDL_Error: %s\n", SDL_GetError());
}
else if (TTF_Init() < 0){
printf("TTF couldn't init! TTF_Error: %s\n", TTF_GetError());
}
else{
window = SDL_CreateWindow("Sliding Puzzle", SDL_WINDOWPOS_CENTERED, SDL_WINDOWPOS_CENTERED, WIN_W, WIN_H, SDL_WINDOW_SHOWN);
if (window==NULL){
printf("SDL Window couldn't be created! SDL_Error: %s\n", SDL_GetError());
}
else{
renderer = SDL_CreateRenderer(window, -1, SDL_RENDERER_ACCELERATED);
if (renderer == NULL){
printf("SDL Renderer couldn't be created! SDL_Error: %s\n", SDL_GetError());
}
else{
SDL_Surface* icon = SDL_LoadBMP("data/images/icon.bmp");
if (icon == NULL){
printf("Couldn't load data/images/icon.bmp! SDL_Error: %s\n", SDL_GetError());
}
else{
SDL_SetWindowIcon(window, icon);
initNumbers();
success = initTextures();
}
}
}
}
return success;
}
void mouseClick(int mouseX, int mouseY){
int rx1 = restartButtonRect->x;
int ry1 = restartButtonRect->y;
int rx2 = restartButtonRect->w + rx1;
int ry2 = restartButtonRect->h + ry1;
if (mouseX >= rx1 && mouseX <= rx2 &&
mouseY >= ry1 && mouseY <= ry2){
std::vector<int> shuffledNumbers;
shuffle(&shuffledNumbers);
for (int x=0; x<MAX_X; x++){
for (int y=0; y<MAX_Y; y++){
numbers[x][y] = shuffledNumbers[x + y * MAX_X];
}
}
numbers[MAX_X-1][MAX_Y-1] = -1;
currentTime = -1;
updateTime();
timeFraction = 0;
nbMoves = 0;
bgImage = bgImages[rand() % nbImages + 1];
}
else{
std::pair<int, int> collCoor = {-1, -1};
for (int x=0; x<MAX_X; x++){
for (int y=0; y<MAX_Y; y++){
if (numbers[x][y] != -1){
int nbx1 = numbersContsRectsPos[x][y]->x;
int nby1 = numbersContsRectsPos[x][y]->y;
int nbx2 = numbersContsRectsPos[x][y]->w + nbx1;
int nby2 = numbersContsRectsPos[x][y]->h + nby1;
if (mouseX >= nbx1 && mouseX <= nbx2 &&
mouseY >= nby1 && mouseY <= nby2){
collCoor.first = x;
collCoor.second = y;
}
}
}
}
if (collCoor.first != -1){
std::pair<int, int> swapCoor = {-1, -1};
for (int x=-1; x<=1; x+=2){
if (collCoor.first + x >= 0 && collCoor.first + x <MAX_X){
if (numbers[collCoor.first + x][collCoor.second] == -1){
swapCoor.first = collCoor.first + x;
swapCoor.second = collCoor.second;
}
}
}
for (int y=-1; y<=1; y+=2){
if (collCoor.second + y >= 0 && collCoor.second + y <MAX_Y){
if (numbers[collCoor.first][collCoor.second + y] == -1){
swapCoor.first = collCoor.first;
swapCoor.second = collCoor.second + y;
}
}
}
if (swapCoor.first != -1){
std::swap(numbers[collCoor.first][collCoor.second], numbers[swapCoor.first][swapCoor.second]);
updateMoves();
}
}
}
}
int main(int argc, char **argv){
if (init()){
bool quit = false;
stop = false;
SDL_Event e;
int mouseX, mouseY;
while (!quit){
while (SDL_PollEvent(&e) != 0){
switch(e.type){
case SDL_QUIT:
quit = true;
break;
case SDL_MOUSEBUTTONDOWN:
SDL_GetMouseState(&mouseX, &mouseY);
mouseClick(mouseX, mouseY);
break;
}
}
SDL_SetRenderDrawColor(renderer, 0XFF, 0X6B, 0X6B, SDL_ALPHA_OPAQUE);
SDL_RenderClear(renderer);
SDL_Rect* fillRect = new SDL_Rect({CEN_X, CEN_Y, CEN_W, CEN_H});
SDL_SetRenderDrawColor(renderer, 0XFF, 0XFF, 0XFF, SDL_ALPHA_OPAQUE);
SDL_RenderFillRect(renderer, fillRect);
SDL_SetRenderDrawColor(renderer, 0XFF, 0XFF, 0XFF, SDL_ALPHA_OPAQUE);
for (int x=0; x<MAX_X; x++){
for (int y=0; y<MAX_Y; y++){
if (numbers[x][y] != -1){
//SDL_RenderFillRect(renderer, numbersContsRectsPos[x][y]);
SDL_RenderCopy(renderer, bgImage,
numbersContsRectsCrops[numbers[x][y]],
numbersContsRectsPos[x][y]);
}
}
}
SDL_Rect* numberRect;
for (int x=0; x<MAX_X; x++){
for (int y=0; y<MAX_Y; y++){
if (numbers[x][y] != -1){
numberRect = new SDL_Rect({numbersContsRectsPos[x][y]->x + 5,
numbersContsRectsPos[x][y]->y + 5,
numbersTexturesSizes[numbers[x][y]].first,
numbersTexturesSizes[numbers[x][y]].second});
SDL_RenderCopy(renderer, numbersTextures[numbers[x][y]], NULL, numberRect);
}
}
}
SDL_Rect* posRect;
posRect = new SDL_Rect({10, 10, texturesSizes[TIME_STRING].first, texturesSizes[TIME_STRING].second});
SDL_RenderCopy(renderer, timeStringTexture, NULL, posRect);
posRect = new SDL_Rect({10, posRect->y + texturesSizes[TIME_STRING].second + 5,
texturesSizes[TIME_INT].first, texturesSizes[TIME_INT].second});
SDL_RenderCopy(renderer, timeIntTexture, NULL, posRect);
posRect = new SDL_Rect({10, posRect->y + texturesSizes[TIME_INT].second + 15,
texturesSizes[MOVES_STRING].first, texturesSizes[MOVES_STRING].second});
SDL_RenderCopy(renderer, movesStringTexture, NULL, posRect);
posRect = new SDL_Rect({10, posRect->y + texturesSizes[MOVES_STRING].second + 5,
texturesSizes[MOVES_INT].first, texturesSizes[MOVES_INT].second});
SDL_RenderCopy(renderer, movesIntTexture, NULL, posRect);
SDL_RenderCopy(renderer, restartButtonTexture, NULL, restartButtonRect);
SDL_RenderPresent(renderer);
SDL_ShowWindow(window);
SDL_Delay(10);
if (!stop){
timeFraction += 10;
if (timeFraction == 1000){
updateTime();
timeFraction = 0;
}
if (winNumbers == numbers){
stop = true;
}
}
}
}
SDL_Quit();
return 0;
}
I'm using mingw compiler with code::blocks (Sorry for my bad English)

Just repaired it. The error was very simple: I was trying to access winNumbers wich has a length of MAX_X with index MAX_X (it should be MAX_X - 1). However, I didn't know why the debugger did not detect the error.

Related

C++ SDL image gets black and disappears

I started writing a little game but something with the image is not working. They're working fine at the beginning but after some moments there become black and then they disappear.
Don't be worried about the long code the relevant things with the images happen mostly in the following methods: build_mode_draw() and play_mode_draw().
I tested the program with a blue cube instead of a image and it worked fine
Probably I don't really understand how the image gets loaded
#include <SDL2/SDL.h>
#define WindowWidth 1500
#define WindowHight 800
#define ArrayGrosseBuildMode 100
#define StartFensterBlockmenge 10 // in Plockgröße bezüglich der kleineren Achse
bool end = false;
bool programm_part_run = true;
unsigned int play_mode_speed = 0;
unsigned int counter;
unsigned int counter_2;
unsigned int counter_3;
unsigned int blocksize;
unsigned int blocks_fit_in_X;
unsigned int blocks_fit_in_Y;
unsigned int play_mode_blockamount;
//unsigned int blockamount = 0;
bool build_mode_block_pos[ArrayGrosseBuildMode][ArrayGrosseBuildMode];
unsigned int play_mode_block_pos_X[WindowWidth]; // Fächer beschreiben
unsigned int play_mode_block_pos_Y[WindowHight]; // ||
//mouse variables
unsigned short int pressed_mouse_button = 0; // 0 = no , 1 = left , mouse Button pressed
unsigned int MouseX;
unsigned int MouseY;
//keyboard variables
//set window
SDL_Window* window = NULL;
//set renderer
SDL_Renderer* renderer = NULL;
//set event
SDL_Event event;
void input()
{
SDL_PollEvent(&event);
// reset variables
pressed_mouse_button = 0; // set to no mouse button pressed
switch(event.type)
{
case SDL_QUIT:
end = true;
programm_part_run = false;
break;
case SDL_MOUSEMOTION:
MouseX = event.motion.x;
MouseY = event.motion.y;
break;
case SDL_MOUSEBUTTONDOWN:
switch(event.button.button)
{
case SDL_BUTTON_LEFT:
pressed_mouse_button = 1;
break;
}
break;
case SDL_KEYDOWN:
switch(event.key.keysym.sym)
{
case SDLK_SPACE:
programm_part_run = false;
break;
}
}
}
void put_build_mode_grid_in_renderer()
{
SDL_SetRenderDrawColor(renderer, 0, 0, 0, 0);
for(counter = 0; counter <= blocks_fit_in_Y; counter = counter + 1)
{
SDL_RenderDrawLine(renderer,0,counter * blocksize,blocks_fit_in_X*blocksize,counter * blocksize);
}
for(counter = 0; counter <= blocks_fit_in_X; counter = counter + 1)
{
SDL_RenderDrawLine(renderer,counter * blocksize,0,counter * blocksize,blocks_fit_in_Y*blocksize);
}
}
void build_mode_draw()
{
SDL_SetRenderDrawColor(renderer, 255, 255, 255, 0);
SDL_RenderClear(renderer);
put_build_mode_grid_in_renderer();
SDL_Surface * image = SDL_LoadBMP("stealcube.bmp");
SDL_Texture * texture = SDL_CreateTextureFromSurface(renderer,image);
SDL_FreeSurface(image);
for(counter = 0; counter <= blocks_fit_in_X; counter = counter + 1)
{
for(counter_2 = 0; counter_2 <= blocks_fit_in_Y; counter_2 = counter_2 + 1)
{
if(build_mode_block_pos[counter][counter_2] == true)
{
SDL_Rect dstrect = { counter * blocksize, counter_2 * blocksize, blocksize, blocksize};
SDL_RenderCopy(renderer, texture, NULL, &dstrect);
}
}
}
SDL_RenderPresent(renderer);
}
void build_mode()
{
while(programm_part_run)
{
input();
if(pressed_mouse_button == 1)
{
build_mode_block_pos[MouseX/blocksize][MouseY/blocksize] = true;
}
build_mode_draw();
}
}
void play_mode_draw()
{
SDL_SetRenderDrawColor(renderer, 255, 255, 255, 0);
SDL_RenderClear(renderer);
SDL_Surface * image = SDL_LoadBMP("stealcube.bmp");
SDL_Texture * texture = SDL_CreateTextureFromSurface(renderer,image);
SDL_FreeSurface(image);
for(counter = 0; counter < play_mode_blockamount; counter = counter + 1)
{
SDL_Rect dstrect = { play_mode_block_pos_X[counter], play_mode_block_pos_Y[counter], blocksize, blocksize};
SDL_RenderCopy(renderer, texture, NULL, &dstrect);
}
SDL_RenderPresent(renderer);
}
void play_mode()
{
counter_3 = 0;
for(counter = 0; counter <= blocks_fit_in_X; counter = counter + 1)
{
for(counter_2 = 0; counter_2 <= blocks_fit_in_Y; counter_2 = counter_2 + 1)
{
if(build_mode_block_pos[counter][counter_2] == true)
{
play_mode_block_pos_X[counter_3] = counter*blocksize;
play_mode_block_pos_Y[counter_3] = counter_2*blocksize;
counter_3 = counter_3 + 1;
}
}
}
play_mode_blockamount = counter_3;
while(programm_part_run)
{
for(counter = 0; counter < play_mode_speed; counter = counter + 1)
{
input();
SDL_Delay(1);
}
for(counter = 0; counter <= play_mode_blockamount; counter = counter + 1)
{
if(play_mode_block_pos_Y[counter] < blocks_fit_in_Y * blocksize - blocksize)
{
play_mode_block_pos_Y[counter] = play_mode_block_pos_Y[counter] + 1;
}
}
play_mode_draw();
}
}
int main (int argc, char** argv)
{
SDL_Init(SDL_INIT_VIDEO);
window = SDL_CreateWindow
(
"Test Fenster :)", SDL_WINDOWPOS_UNDEFINED,
SDL_WINDOWPOS_UNDEFINED,
WindowWidth,
WindowHight,
SDL_WINDOW_SHOWN
);
renderer = SDL_CreateRenderer( window, -1, SDL_RENDERER_ACCELERATED);
//setup
if(WindowWidth < WindowHight)
{
blocksize = WindowWidth/StartFensterBlockmenge;
}
else
{
blocksize = WindowHight/StartFensterBlockmenge;
}
blocks_fit_in_X = WindowWidth/blocksize;
blocks_fit_in_Y = WindowHight/blocksize;
while(!end)
{
programm_part_run = true;
build_mode();
programm_part_run = true;
play_mode();
}
}

Allegro 5 Audio Assertion Fail

I'm wondering if anyone can point me in the right direction for this error.
I am learning 2D game programming using Allegro 5 installed in Visual Studio 2010.
I have been following a tutorial series and everything has been fine until the last lesson.
The final code will build successfully. The executable will load but will crash out when I hit the space bar to fire a bullet (it's a side shooter game). I get the following error:
"Assertion failed: spl, file allegro-git\addons\audio\kgm_sample.c line 321"
It obviously has something to do with the bullet sample sound linked in with the key press.
If I comment out the line: al_play_sample(shot, 1, 0, 1, ALLEGRO_PLAYMODE_ONCE, 0); in the FireBullet() function, then the game will play fine (without the bullet sound).
I have searched everywhere and cannot find a solution.
Here is the complete code for the game:
#include <allegro5\allegro.h>
#include <allegro5\allegro_primitives.h>
#include <allegro5\allegro_font.h>
#include <allegro5\allegro_ttf.h>
#include <allegro5\allegro_image.h>
#include <allegro5\allegro_audio.h>
#include <allegro5\allegro_acodec.h>
#include "objects.h"
//GLOBALS==============================
const int WIDTH = 800;
const int HEIGHT = 400;
const int NUM_BULLETS = 5;
const int NUM_COMETS = 10;
const int NUM_EXPLOSIONS = 5;
enum STATE{TITLE, PLAYING, LOST};
enum KEYS{UP, DOWN, LEFT, RIGHT, SPACE};
bool keys[5] = {false, false, false, false, false};
SpaceShip ship;
Bullet bullets[NUM_BULLETS];
Comet comets[NUM_COMETS];
Explosion explosions[NUM_EXPLOSIONS];
ALLEGRO_SAMPLE *shot = NULL;
ALLEGRO_SAMPLE *boom = NULL;
ALLEGRO_SAMPLE *song = NULL;
ALLEGRO_SAMPLE_INSTANCE *songInstance = NULL;
//prototypes
void InitShip(SpaceShip &ship, ALLEGRO_BITMAP *image);
void ResetShipAnimation(SpaceShip &ship, int position);
void DrawShip(SpaceShip &ship);
void MoveShipUp(SpaceShip &ship);
void MoveShipDown(SpaceShip &ship);
void MoveShipLeft(SpaceShip &ship);
void MoveShipRight(SpaceShip &ship);
void InitBullet(Bullet bullet[], int size);
void DrawBullet(Bullet bullet[], int size);
void FireBullet(Bullet bullet[], int size, SpaceShip &ship);
void UpdateBullet(Bullet bullet[], int size);
void CollideBullet(Bullet bullet[], int bSize, Comet comets[], int cSize, SpaceShip &ship, Explosion explosions[], int eSize);
void InitComet(Comet comets[], int size, ALLEGRO_BITMAP *image);
void DrawComet(Comet comets[], int size);
void StartComet(Comet comets[], int size);
void UpdateComet(Comet comets[], int size);
void CollideComet(Comet comets[], int cSize, SpaceShip &ship, Explosion explosions[], int eSize);
void InitExplosions(Explosion explosions[], int size, ALLEGRO_BITMAP *image);
void DrawExplosions(Explosion explosions[], int size);
void StartExplosions(Explosion explosions[], int size, int x, int y);
void UpdateExplosions(Explosion explosions[], int size);
void InitBackground(Background &back, float x, float y, float velX, float velY, int width, int height, int dirX, int dirY, ALLEGRO_BITMAP *image);
void UpdateBackground(Background &back);
void DrawBackground(Background &back);
void ChangeState(int &state, int newState);
int main(void)
{
//primitive variable
bool done = false;
bool redraw = true;
const int FPS = 60;
int state = -1;
//object variables
Background BG;
Background MG;
Background FG;
//Allegro variables
ALLEGRO_DISPLAY *display = NULL;
ALLEGRO_EVENT_QUEUE *event_queue = NULL;
ALLEGRO_TIMER *timer = NULL;
ALLEGRO_FONT *font18 = NULL;
ALLEGRO_BITMAP *shipImage;
ALLEGRO_BITMAP *cometImage;
ALLEGRO_BITMAP *expImage;
ALLEGRO_BITMAP *title = NULL;
ALLEGRO_BITMAP *lost = NULL;
ALLEGRO_BITMAP *bgImage = NULL;
ALLEGRO_BITMAP *mgImage = NULL;
ALLEGRO_BITMAP *fgImage = NULL;
//Initialization Functions
if(!al_init()) //initialize Allegro
return -1;
display = al_create_display(WIDTH, HEIGHT); //create our display object
if(!display) //test display object
return -1;
al_init_primitives_addon();
al_install_keyboard();
al_init_font_addon();
al_init_ttf_addon();
al_init_image_addon();
al_install_audio();
al_init_acodec_addon();
event_queue = al_create_event_queue();
timer = al_create_timer(1.0 / FPS);
shipImage = al_load_bitmap("spaceship_by_arboris.png");
al_convert_mask_to_alpha(shipImage, al_map_rgb(255, 0, 255));
cometImage = al_load_bitmap("asteroids.png");
expImage = al_load_bitmap("explosion.png");
title = al_load_bitmap("Shooter_Title.png");
lost = al_load_bitmap("Shooter_Lose.png");
bgImage = al_load_bitmap("starBG.png");
mgImage = al_load_bitmap("starMG.png");
fgImage = al_load_bitmap("starFG.png");
al_reserve_samples(10);
shot = al_load_sample("shot.ogg");
boom = al_load_sample("explosion.wav");
song = al_load_sample("war.wav");
songInstance = al_create_sample_instance(song);
al_set_sample_instance_playmode(songInstance, ALLEGRO_PLAYMODE_LOOP);
al_attach_sample_instance_to_mixer(songInstance, al_get_default_mixer());
srand(time(NULL));
ChangeState(state, TITLE);
InitShip(ship, shipImage);
InitBullet(bullets, NUM_BULLETS);
InitComet(comets, NUM_COMETS, cometImage);
InitExplosions(explosions, NUM_EXPLOSIONS, expImage);
InitBackground(BG, 0, 0, 1, 0, 800, 400, -1, 1, bgImage);
InitBackground(MG, 0, 0, 2, 0, 2400, 400, -1, 1, mgImage);
InitBackground(FG, 0, 0, 4, 0, 2400, 400, -1, 1, fgImage);
font18 = al_load_font("arial.ttf", 18, 0);
al_register_event_source(event_queue, al_get_keyboard_event_source());
al_register_event_source(event_queue, al_get_timer_event_source(timer));
al_register_event_source(event_queue, al_get_display_event_source(display));
al_start_timer(timer);
while(!done)
{
ALLEGRO_EVENT ev;
al_wait_for_event(event_queue, &ev);
if(ev.type == ALLEGRO_EVENT_TIMER)
{
redraw = true;
if(keys[UP])
MoveShipUp(ship);
else if(keys[DOWN])
MoveShipDown(ship);
else
ResetShipAnimation(ship, 1);
if(keys[LEFT])
MoveShipLeft(ship);
else if(keys[RIGHT])
MoveShipRight(ship);
else
ResetShipAnimation(ship, 2);
if(state == TITLE)
{}
else if(state == PLAYING)
{
UpdateBackground(BG);
UpdateBackground(MG);
UpdateBackground(FG);
UpdateExplosions(explosions, NUM_EXPLOSIONS);
UpdateBullet(bullets, NUM_BULLETS);
StartComet(comets, NUM_COMETS);
UpdateComet(comets, NUM_COMETS);
CollideBullet(bullets, NUM_BULLETS, comets, NUM_COMETS, ship, explosions, NUM_EXPLOSIONS);
CollideComet(comets, NUM_COMETS, ship, explosions, NUM_EXPLOSIONS);
if(ship.lives <= 0)
ChangeState(state, LOST);
}
else if(state == LOST)
{}
}
else if(ev.type == ALLEGRO_EVENT_DISPLAY_CLOSE)
{
done = true;
}
else if(ev.type == ALLEGRO_EVENT_KEY_DOWN)
{
switch(ev.keyboard.keycode)
{
case ALLEGRO_KEY_ESCAPE:
done = true;
break;
case ALLEGRO_KEY_UP:
keys[UP] = true;
break;
case ALLEGRO_KEY_DOWN:
keys[DOWN] = true;
break;
case ALLEGRO_KEY_LEFT:
keys[LEFT] = true;
break;
case ALLEGRO_KEY_RIGHT:
keys[RIGHT] = true;
break;
case ALLEGRO_KEY_SPACE:
keys[SPACE] = true;
if(state == TITLE)
ChangeState(state, PLAYING);
else if(state ==PLAYING)
FireBullet(bullets, NUM_BULLETS, ship);
else if(state == LOST)
ChangeState(state, PLAYING);
break;
}
}
else if(ev.type == ALLEGRO_EVENT_KEY_UP)
{
switch(ev.keyboard.keycode)
{
case ALLEGRO_KEY_ESCAPE:
done = true;
break;
case ALLEGRO_KEY_UP:
keys[UP] = false;
break;
case ALLEGRO_KEY_DOWN:
keys[DOWN] = false;
break;
case ALLEGRO_KEY_LEFT:
keys[LEFT] = false;
break;
case ALLEGRO_KEY_RIGHT:
keys[RIGHT] = false;
break;
case ALLEGRO_KEY_SPACE:
keys[SPACE] = false;
break;
}
}
if(redraw && al_is_event_queue_empty(event_queue))
{
redraw = false;
if(state == TITLE)
{
al_draw_bitmap(title, 0, 0, 0);
}
else if(state == PLAYING)
{
DrawBackground(BG);
DrawBackground(MG);
DrawBackground(FG);
DrawShip(ship);
DrawBullet(bullets, NUM_BULLETS);
DrawComet(comets, NUM_COMETS);
DrawExplosions(explosions, NUM_EXPLOSIONS);
al_draw_textf(font18, al_map_rgb(255, 0, 255), 5, 5, 0, "Player has %i lives left. Player has destroyed %i objects", ship.lives, ship.score);
}
else if(state == LOST)
{
al_draw_bitmap(lost, 0, 0, 0);
al_draw_textf(font18, al_map_rgb(0, 255, 255), WIDTH - 10, 20, ALLEGRO_ALIGN_RIGHT, "Final Score: %i", ship.score);
}
al_flip_display();
al_clear_to_color(al_map_rgb(0,0,0));
}
}
al_destroy_sample(shot);
al_destroy_sample(boom);
al_destroy_sample(song);
al_destroy_sample_instance(songInstance);
al_destroy_bitmap(bgImage);
al_destroy_bitmap(mgImage);
al_destroy_bitmap(fgImage);
al_destroy_bitmap(title);
al_destroy_bitmap(lost);
al_destroy_bitmap(expImage);
al_destroy_bitmap(cometImage);
al_destroy_bitmap(shipImage);
al_destroy_event_queue(event_queue);
al_destroy_timer(timer);
al_destroy_font(font18);
al_destroy_display(display); //destroy our display object
return 0;
}
void InitShip(SpaceShip &ship, ALLEGRO_BITMAP *image = NULL) {
ship.x = 20;
ship.y = HEIGHT / 2;
ship.ID = PLAYER;
ship.lives = 3;
ship.speed = 6;
ship.boundx = 10;
ship.boundy = 12;
ship.score = 0;
ship.maxFrame = 3;
ship.curFrame = 0;
ship.frameCount = 0;
ship.frameDelay = 50;
ship.frameWidth = 44;
ship.frameHeight = 41;
ship.animationColumns = 3;
ship.animationDirection = 1;
ship.animationRow = 1;
if(image != NULL)
ship.image = image;
}
void ResetShipAnimation(SpaceShip &ship, int position)
{
if(position == 1)
ship.animationRow = 1;
else
ship.curFrame = 0;
}
void DrawShip(SpaceShip &ship)
{
int fx =(ship.curFrame % ship.animationColumns) * ship.frameWidth;
int fy = ship.animationRow * ship.frameHeight;
al_draw_bitmap_region(ship.image, fx, fy, ship.frameWidth,
ship.frameHeight, ship.x - ship.frameWidth / 2, ship.y - ship.frameHeight / 2, 0);
/*al_draw_filled_rectangle(ship.x - ship.boundx, ship.y - ship.boundy, ship.x + ship.boundx,
ship.y + ship.boundy, al_map_rgba(255, 0, 255, 100));*/
}
void MoveShipUp(SpaceShip &ship)
{
ship.animationRow = 0;
ship.y -= ship.speed;
if(ship.y < 0)
ship.y = 0;
}
void MoveShipDown(SpaceShip &ship)
{
ship.animationRow = 2;
ship.y += ship.speed;
if(ship.y > HEIGHT)
ship.y = HEIGHT;
}
void MoveShipLeft(SpaceShip &ship)
{
ship.curFrame = 2;
ship.x -= ship.speed;
if(ship.x < 0)
ship.x = 0;
}
void MoveShipRight(SpaceShip &ship)
{
ship.curFrame = 1;
ship.x += ship.speed;
if(ship.x > 300)
ship.x = 300;
}
void InitBullet(Bullet bullet[], int size)
{
for(int i = 0; i < size; i++)
{
bullet[i].ID = BULLET;
bullet[i].speed = 10;
bullet[i].live = false;
}
}
void DrawBullet(Bullet bullet[], int size)
{
for( int i = 0; i < size; i++)
{
if(bullet[i].live)
al_draw_filled_circle(bullet[i].x, bullet[i].y, 2, al_map_rgb(255, 255, 255));
}
}
void FireBullet(Bullet bullet[], int size, SpaceShip &ship)
{
for( int i = 0; i < size; i++)
{
if(!bullet[i].live)
{
bullet[i].x = ship.x + 17;
bullet[i].y = ship.y;
bullet[i].live = true;
al_play_sample(shot, 1, 0, 1, ALLEGRO_PLAYMODE_ONCE, 0);
break;
}
}
}
void UpdateBullet(Bullet bullet[], int size)
{
for(int i = 0; i < size; i++)
{
if(bullet[i].live)
{
bullet[i].x += bullet[i].speed;
if(bullet[i].x > WIDTH)
bullet[i].live = false;
}
}
}
void CollideBullet(Bullet bullet[], int bSize, Comet comets[], int cSize, SpaceShip &ship, Explosion explosions[], int eSize)
{
for(int i = 0; i < bSize; i++)
{
if(bullet[i].live)
{
for(int j =0; j < cSize; j++)
{
if(comets[j].live)
{
if(bullet[i].x > (comets[j].x - comets[j].boundx) &&
bullet[i].x < (comets[j].x + comets[j].boundx) &&
bullet[i].y > (comets[j].y - comets[j].boundy) &&
bullet[i].y < (comets[j].y + comets[j].boundy))
{
bullet[i].live = false;
comets[j].live = false;
ship.score++;
StartExplosions(explosions, eSize, bullet[i].x, bullet[i].y);
al_play_sample(boom, 1, 0, 1, ALLEGRO_PLAYMODE_ONCE, 0);
}
}
}
}
}
}
void InitComet(Comet comets[], int size, ALLEGRO_BITMAP *image = NULL)
{
for(int i = 0; i < size; i++)
{
comets[i].ID = ENEMY;
comets[i].live = false;
comets[i].speed = 5;
comets[i].boundx = 35;
comets[i].boundy = 35;
comets[i].maxFrame = 143;
comets[i].curFrame = 0;
comets[i].frameCount = 0;
comets[i].frameDelay = 2;
comets[i].frameWidth = 96;
comets[i].frameHeight = 96;
comets[i].animationColumns = 21;
if(rand() % 2)
comets[i].animationDirection = 1;
else
comets[i].animationDirection = -1;
if(image != NULL)
comets[i].image = image;
}
}
void DrawComet(Comet comets[], int size)
{
for(int i = 0; i < size; i++)
{
if(comets[i].live)
{
int fx = (comets[i].curFrame % comets[i].animationColumns) * comets[i].frameWidth;
int fy = (comets[i].curFrame / comets[i].animationColumns) * comets[i].frameHeight;
al_draw_bitmap_region(comets[i].image, fx, fy, comets[i].frameWidth,
comets[i].frameHeight, comets[i].x - comets[i].frameWidth / 2, comets[i].y - comets[i].frameHeight / 2, 0);
/*al_draw_filled_rectangle(comets[i].x - comets[i].boundx, comets[i].y - comets[i].boundy, comets[i].x + comets[i].boundx,
comets[i].y + comets[i].boundy, al_map_rgba(255, 0, 255, 100));*/
}
}
}
void StartComet(Comet comets[], int size)
{
for(int i = 0; i < size; i++)
{
if(!comets[i].live)
{
if(rand() % 500 == 0)
{
comets[i].live = true;
comets[i].x = WIDTH;
comets[i].y = 30 + rand() % (HEIGHT - 60);
break;
}
}
}
}
void UpdateComet(Comet comets[], int size)
{
for(int i = 0; i < size; i++)
{
if(comets[i].live)
{
if(++comets[i].frameCount >= comets[i].frameDelay)
{
comets[i].curFrame += comets[i].animationDirection;
if(comets[i].curFrame >= comets[i].maxFrame)
comets[i].curFrame = 0;
else if( comets[i].curFrame <= 0)
comets[i].curFrame = comets[i].maxFrame - 1;
comets[i].frameCount = 0;
}
comets[i].x -= comets[i].speed;
}
}
}
void CollideComet(Comet comets[], int cSize, SpaceShip &ship, Explosion explosions[], int eSize)
{
for(int i = 0; i < cSize; i++)
{
if(comets[i].live)
{
if(comets[i].x - comets[i].boundx < ship.x + ship.boundx &&
comets[i].x + comets[i].boundx > ship.x - ship.boundx &&
comets[i].y - comets[i].boundy < ship.y + ship.boundy &&
comets[i].y + comets[i].boundy > ship.y - ship.boundy)
{
ship.lives--;
comets[i].live = false;
StartExplosions(explosions, eSize, ship.x, ship.y);
al_play_sample(boom, 1, 0, 1, ALLEGRO_PLAYMODE_ONCE, 0);
}
else if(comets[i].x < 0)
{
comets[i].live = false;
ship.lives--;
}
}
}
}
void InitExplosions(Explosion explosions[], int size, ALLEGRO_BITMAP *image = NULL)
{
for(int i = 0; i < size; i++)
{
explosions[i].live = false;
explosions[i].maxFrame = 31;
explosions[i].curFrame = 0;
explosions[i].frameCount = 0;
explosions[i].frameDelay = 1;
explosions[i].frameWidth = 128;
explosions[i].frameHeight = 128;
explosions[i].animationColumns = 8;
explosions[i].animationDirection = 1;
if(image != NULL)
explosions[i].image = image;
}
}
void DrawExplosions(Explosion explosions[], int size)
{
for(int i = 0; i < size; i++)
{
if(explosions[i].live)
{
int fx = (explosions[i].curFrame % explosions[i].animationColumns) * explosions[i].frameWidth;
int fy = (explosions[i].curFrame / explosions[i].animationColumns) * explosions[i].frameHeight;
al_draw_bitmap_region(explosions[i].image, fx, fy, explosions[i].frameWidth,
explosions[i].frameHeight, explosions[i].x - explosions[i].frameWidth / 2, explosions[i].y - explosions[i].frameHeight / 2, 0);
}
}
}
void StartExplosions(Explosion explosions[], int size, int x, int y)
{
for(int i = 0; i < size; i++)
{
if(!explosions[i].live)
{
explosions[i].live = true;
explosions[i].x = x;
explosions[i].y = y;
break;
}
}
}
void UpdateExplosions(Explosion explosions[], int size)
{
for(int i = 0; i < size; i++)
{
if(explosions[i].live)
{
if(++explosions[i].frameCount >= explosions[i].frameDelay)
{
explosions[i].curFrame += explosions[i].animationDirection;
if(explosions[i].curFrame >= explosions[i].maxFrame)
{
explosions[i].curFrame = 0;
explosions[i].live = false;
}
explosions[i].frameCount = 0;
}
}
}
}
void InitBackground(Background &back, float x, float y, float velx, float vely, int width, int height, int dirX, int dirY, ALLEGRO_BITMAP *image)
{
back.x = x;
back.y = y;
back.velX = velx;
back.velY = vely;
back.width = width;
back.height = height;
back.dirX = dirX;
back.dirY = dirY;
back.image = image;
}
void UpdateBackground(Background &back)
{
back.x += back.velX * back.dirX;
if(back.x + back.width <= 0)
back.x = 0;
}
void DrawBackground(Background &back)
{
al_draw_bitmap(back.image, back.x, back.y, 0);
if(back.x + back.width < WIDTH)
al_draw_bitmap(back.image, back.x + back.width, back.y, 0);
}
void ChangeState(int &state, int newState)
{
if(state == TITLE)
{}
else if(state == PLAYING)
{
al_stop_sample_instance(songInstance);
}
else if(state == LOST)
{}
state = newState;
if(state == TITLE)
{}
else if(state == PLAYING)
{
InitShip(ship);
InitBullet(bullets, NUM_BULLETS);
InitComet(comets, NUM_COMETS);
InitExplosions(explosions, NUM_EXPLOSIONS);
al_play_sample_instance(songInstance);
}
else if(state == LOST)
{}
}
Check that a pointer you are using is not NULL when you try to load the file. If it stays NULL then that exception is always thrown because the system will try to read from memory address 0x0 which frankly does not exist

SDL2 'Bullet' movement not working?

I am attempting to make a simple scrolling shooter game with SDL2. I have a moving player on a screen, and I am trying to make the player shoot a bullet using an array (so they can shoot multiple bullets) however, when I press the space bar, nothing happens, and instead the bullet image sort of flashes in the top left corner.
Heres the same code in codepad: http://codepad.org/rOhE1AqY
#include <SDL.h>
#include <stdio.h> //use for things like printf, same as cout
#include <iostream>
#include <string>
#include <time.h>
using namespace std;
//screend dimensions& sprtie dimensions
const int SCREEN_HEIGHT = 600;
const int SCREEN_WIDTH = 400;
const int SPRITE_WIDTH = 60;
const int SPRITE_HEIGHT = 80;
const int MAX_BULLETS = 50;
SDL_Window* Window = NULL;//the window rendering to
SDL_Surface* ScreenSurface = NULL;//surface contained by window
SDL_Surface* Background = NULL;
SDL_Surface* Player = NULL;
SDL_Surface* Enemy = NULL;
SDL_Surface* Bullet = NULL;
SDL_Surface* newBullet = NULL;
SDL_Rect posPlayer, posEnemy, posBullet, posnewBullet;
const Uint8* keystate = SDL_GetKeyboardState(NULL);
SDL_Event event;
class thePlayer
{
public:
thePlayer();
void player_movement();
void show_player();
private:
};
class theBullet
{
public:
theBullet();
bool isActive;
int x_position;
int y_position;
void bullet_movement();
void add_new_bullet();
void show_bullet();
private:
};
theBullet arrayofBullets[MAX_BULLETS];
class theEnemy
{
public:
theEnemy();
void enemy_movement();
void show_enemy();
private:
};
thePlayer::thePlayer()
{
posPlayer.x = 170;
posPlayer.y = SCREEN_HEIGHT;
posPlayer.w = 20;
posPlayer.h = 30;
}
void thePlayer::player_movement()
{
if(keystate[SDL_SCANCODE_LEFT])
{
posPlayer.x -= 2;
}
if(keystate[SDL_SCANCODE_RIGHT])
{
posPlayer.x += 2;
}
if(keystate[SDL_SCANCODE_UP])
{
posPlayer.y -= 2;
}
if(keystate[SDL_SCANCODE_DOWN])
{
posPlayer.y += 2;
}
if ((posPlayer.x + SPRITE_WIDTH) > SCREEN_WIDTH)
{
posPlayer.x = (SCREEN_WIDTH - SPRITE_WIDTH);
}
if ((posPlayer.y + SPRITE_HEIGHT) > SCREEN_HEIGHT)
{
posPlayer.y = (SCREEN_HEIGHT - SPRITE_HEIGHT);
}
}
void thePlayer::show_player()
{
SDL_BlitSurface(Player, NULL, ScreenSurface, &posPlayer);
SDL_SetColorKey(Player, SDL_TRUE, SDL_MapRGB(Player->format, 255, 255, 255));
}
theBullet::theBullet()
{
/*posBullet.x;
posBullet.y;
posBullet.w = 10;
posBullet.h = 15;*/
}
void theBullet::bullet_movement()
{
/*if(keystate[SDL_SCANCODE_SPACE])
{
posBullet.x = posPlayer.x + 25;
posBullet.y = posPlayer.y + 10;
}
posBullet.y -= 2;
if(posBullet.y < 0)
{
posBullet.y = -50;
}*/
}
void theBullet::show_bullet()
{
//SDL_BlitSurface(Bullet, NULL, ScreenSurface, &posBullet);
//SDL_SetColorKey(Bullet, SDL_TRUE, SDL_MapRGB(Player->format, 255, 255, 255));//removes white background
}
theEnemy::theEnemy()
{
srand (time(NULL));
posEnemy.x = rand() % 300 + 50;
posEnemy.y =0;
posEnemy.w = 35;
posEnemy.h = 60;
}
void theEnemy::enemy_movement()
{
posEnemy.y += 1;
if(posEnemy.y > SCREEN_HEIGHT)
{
posEnemy.y = SCREEN_HEIGHT +50;
}
}
void theEnemy::show_enemy()
{
SDL_BlitSurface(Enemy, NULL, ScreenSurface, &posEnemy);
SDL_SetColorKey(Enemy, SDL_TRUE, SDL_MapRGB(Player->format, 255, 255, 255));
}
bool initialise()
{
bool success = true;
if (SDL_Init(SDL_INIT_EVERYTHING) !=0)
{
cout<<"SDL_Init Error."<<SDL_GetError()<<endl;
success = false;
}
else
{
//create the window for game
Window = SDL_CreateWindow("Scrolling Shooter Game", SDL_WINDOWPOS_UNDEFINED, SDL_WINDOWPOS_UNDEFINED, SCREEN_WIDTH, SCREEN_HEIGHT, SDL_WINDOW_SHOWN);
if (Window == NULL)
{
cout<<"Window Error"<<SDL_GetError()<<endl;
success = false;
}
else
{
//get window surface
ScreenSurface = SDL_GetWindowSurface(Window);
}
}
return success;
}
bool LoadingMedia()
{
bool success = true;
Background = SDL_LoadBMP("background.bmp");
if (Background == NULL)
{
cout<<"Error in loading background."<<SDL_GetError()<<endl;
success = false;
}
Player = SDL_LoadBMP("spaceship.bmp");
if (Player == NULL)
{
cout<<"Error in loading player."<<SDL_GetError()<<endl;
success = false;
}
Enemy = SDL_LoadBMP("enemy.bmp");
if (Enemy == NULL)
{
cout<<"Error in loading enemy."<<SDL_GetError()<<endl;
success = false;
}
Bullet = SDL_LoadBMP("bullet.bmp");
if (Bullet == NULL)
{
cout<<"Error in loading bullet."<<SDL_GetError()<<endl;
success = false;
}
return success;
}
void closedown()
{
SDL_FreeSurface(Background);
Background = NULL;
SDL_FreeSurface(Player);
Player = NULL;
SDL_FreeSurface(Enemy);
Enemy = NULL;
SDL_DestroyWindow(Window);
Window = NULL;
SDL_Quit();
}
int main(int argc, char** argv)
{
bool quit = false;
thePlayer myPlayer;
theEnemy myEnemy;
theBullet myBullet;
if (!initialise())
{
cout<<"Failed to initialise"<<SDL_GetError()<<endl;
}
else
{
if (!LoadingMedia())
{
cout<<"Error loading media"<<SDL_GetError()<<endl;
}
}
//makes all bullets false
for (int i=0; i<MAX_BULLETS; i++)
{
arrayofBullets[i].isActive = false;
}
//GAME LOOP
while (quit == false)
{
SDL_BlitSurface(Background, NULL, ScreenSurface, NULL);
myPlayer.show_player();
myPlayer.player_movement();
while (SDL_PollEvent(&event))
{
if( event.type == SDL_QUIT )
{
quit = true;
break;
}
if(keystate[SDL_SCANCODE_SPACE])
{
for (int i=0; i<MAX_BULLETS; i++)
{
if (arrayofBullets[i].isActive == false)
{
arrayofBullets[i].x_position = posPlayer.x + 25;
arrayofBullets[i].y_position = posPlayer.y + 10;
arrayofBullets[i].isActive = true;
break;
}
}
}
//update game objects
for (int i=0; i<MAX_BULLETS; i++)
{
if (arrayofBullets[i].isActive == true)
{
arrayofBullets[i].y_position -= 2;
if (arrayofBullets[i].y_position < 0)
{
arrayofBullets[i].isActive = false;
}
}
}
for (int i=0; i<MAX_BULLETS; i++)
{
if (arrayofBullets[i].isActive == true)
{
SDL_BlitSurface(Bullet, NULL, ScreenSurface, NULL);
}
}
}
//myPlayer.show_player();
//myBullet.show_bullet();
//myEnemy.show_enemy();
//myPlayer.player_movement();
//myBullet.bullet_movement();
//myEnemy.enemy_movement();
SDL_UpdateWindowSurface(Window); //updates screen
}
closedown();
return 0;
}
SDL_BlitSurface(Bullet, NULL, ScreenSurface, NULL);
You haven't specified destination rect, so it will blit on left-top corner.
It should be
SDL_Rect dstrect;
dstrect.x = arrayofBullets[i].x_position;
dstrect.y = arrayofBullets[i].y_position;
dstrect.w = Bullet->w;
dstrect.h = Bullet->h;
SDL_BlitSurface(Bullet, NULL, ScreenSurface, &dstrect);

SDL Tiling situation

I am making a TBS game, at least im trying to.
So i've started off by following a tutorial on lazyfoo.net (lesson 29) on how to make a tiled environment and making my own changes along the way.
Every time i try to compile it it gives me two main errors:
No. 1: 255 error: expected primary-expression before ',' token
No. 2: 267 error: expected ';' before 'myUnit'
Here is the source code, i am fairly certain the that the problem is not with the images or the map.
CODE:
#include "SDL/SDL_image.h"
#include "SDL/SDL.h"
#include <string>
#include <fstream>
const int SCREEN_WIDTH = 600;
const int SCREEN_HEIGHT = 600;
const int SCREEN_BPP = 32;
const int FPS = 30;
const int UNIT_WIDTH = 50;
const int UNIT_HEIGHT = 50;
const int LEVEL_WIDTH = 600;
const int LEVEL_HEIGHT = 600;
const int TILE_WIDTH = 60;
const int TILE_HEIGHT = 60;
const int TOTAL_TILES = 100;
const int TILE_SPRITES = 3;
const int TILE_GRASS = 0;
const int TILE_WATER = 1;
const int TILE_MOUNTAIN = 2;
SDL_Surface *screen = NULL;
SDL_Surface *Unit = NULL;
SDL_Surface *tileMap = NULL;
SDL_Rect clips[ TILE_SPRITES ];
SDL_Event occur;
class Tile
{
private:
SDL_Rect box;
int type;
public:
Tile(int x, int y, int tileType);
void show();
int get_type();
SDL_Rect get_box();
};
class Unit
{
private:
SDL_Rect Box;
bool movement;
public:
Unit();
void handle_input();
void move( Tile *tiles[]);
void show();
};
SDL_Surface *load_image(std::string filename)
{
SDL_Surface* loadedImage = NULL;
SDL_Surface* optimizedImage = NULL;
loadedImage = IMG_Load(filename.c_str());
if(loadedImage != NULL)
{
optimizedImage = SDL_DisplayFormat( loadedImage );
SDL_FreeSurface( loadedImage );
if(optimizedImage != NULL)
{
SDL_SetColorKey(optimizedImage, SDL_SRCCOLORKEY, SDL_MapRGB(optimizedImage->format, 0,0xff,0xff));
}
}
return optimizedImage;
}
void apply_surface(int x, int y, SDL_Surface* source, SDL_Surface* destination, SDL_Rect* clip = NULL)
{
SDL_Rect offset;
offset.x = x;
offset.y = y;
SDL_BlitSurface(source, clip, destination, &offset);
}
bool init()
{
if(SDL_Init(SDL_INIT_EVERYTHING) == -1)
{
return false;
}
screen = SDL_SetVideoMode(SCREEN_WIDTH,SCREEN_HEIGHT,SCREEN_BPP,SDL_SWSURFACE);
if(screen == NULL)
{
return false;
}
SDL_WM_SetCaption("Strategy Game", NULL);
return true;
}
bool load_files()
{
Unit = load_image("infantry_red.png");
if(Unit == NULL)
{
return false;
}
tileMap = load_image("tilemap.png");
if( tileMap == NULL)
{
return false;
}
return 0;
}
void clean_up(Tile *tiles[])
{
SDL_FreeSurface(Unit);
SDL_FreeSurface(tileMap);
for(int t = 0;t < TOTAL_TILES; t++)
{
delete tiles[ t ];
}
SDL_Quit();
}
void clip_tiles()
{
clips[TILE_GRASS].x = 0;
clips[TILE_GRASS].y = 0;
clips[TILE_GRASS].w = TILE_WIDTH;
clips[TILE_GRASS].h = TILE_HEIGHT;
clips[TILE_WATER].x = 60;
clips[TILE_WATER].y = 0;
clips[TILE_WATER].w = TILE_WIDTH;
clips[TILE_WATER].h = TILE_HEIGHT;
clips[TILE_MOUNTAIN].x = 120;
clips[TILE_MOUNTAIN].y = 0;
clips[TILE_MOUNTAIN].w = TILE_WIDTH;
clips[TILE_MOUNTAIN].h = TILE_HEIGHT;
}
bool set_tiles( Tile *tiles[])
{
int x = 0, y = 0;
std::ifstream map("strategy_game.map");
if(map == NULL)
{
return false;
}
for(int t = 0; y < TOTAL_TILES; t++)
{
int tileType = -1;
map >> tileType;
if(map.fail() == true)
{
map.close();
return false;
}
if( (tileType >= 0) && (tileType < TILE_SPRITES))
{
tiles[t] = new Tile(x,y,tileType);
}
else
{
map.close();
return false;
}
x += TILE_WIDTH;
if(x >= LEVEL_WIDTH)
{
x = 0;
y += TILE_HEIGHT;
}
}
map.close();
return true;
}
Tile::Tile(int x, int y, int tileType)
{
box.x = x;
box.y = y;
box.w = TILE_WIDTH;
box.h = TILE_HEIGHT;
type = tileType;
}
void Tile::show()
{
apply_surface(box.x, box.y, tileMap, screen, &clips[type]);
}
int Tile::get_type()
{
return type;
}
SDL_Rect Tile::get_box()
{
return box;
}
Unit::Unit()
{
Box.x = 0;
Box.y = 0;
Box.w = UNIT_WIDTH;
Box.h = UNIT_HEIGHT;
}
SDL_Rect rect;
int mouseX,mouseY;
void Unit::handle_input()
{
if(occur.type == SDL_MOUSEBUTTONDOWN)
{
mouseX = occur.button.x;
mouseY = occur.button.y;
}
}
void Unit::move(Tile *tiles[])
{
Box.x += mouseX;
if( Box.x < 0 || Box.x + UNIT_WIDTH > LEVEL_WIDTH )
{
Box.x -= mouseX;
}
Box.y -= mouseY;
if( Box.y < 0 || Box.y + UNIT_HEIGHT > LEVEL_HEIGHT)
{
Box.y -= mouseY;
}
}
void Unit::show()
{
int BoxX;
int BoxY;
Box.x = BoxX;
Box.y = BoxY;
SDL_Rect unitOffset;
unitOffset.x = BoxX;
unitOffset.y = BoxY;
SDL_BlitSurface(Unit,NULL,screen,unitOffset);
}
Uint32 start;
int main(int argc, char* args[])
{
bool quit = false;
Unit myUnit;
Tile *tiles[TOTAL_TILES];
if(init() == false)
{
return 1;
}
if(load_files() == false)
{
return 1;
}
clip_tiles();
if( set_tiles(tiles) == false)
{
return 1;
}
while(quit == false)
{
start = SDL_GetTicks();
while(SDL_PollEvent(&occur));
{
myUnit.handle_input();
switch(occur.type)
{
case SDL_QUIT:
quit = false;
break;
}
}
myUnit.move(tiles);
for(int t = 0;t<TOTAL_TILES;t++)
{
tiles[t]->show();
}
myUnit.show();
//render
SDL_FillRect(screen,&screen->clip_rect,0);
SDL_Flip(screen);
if(1000/FPS > SDL_GetTicks() - start ){
SDL_Delay(1000/FPS - (SDL_GetTicks()-start));
}
}
clean_up( tiles );
return 0;
}
Remove semi-colon from while(SDL_PollEvent(&occur))
Change: SDL_Surface *Unit = NULL; to `SDL_Surface *unitSurf = NULL;'
Change:
Unit = load_image("infantry_red.png");
if(Unit == NULL)
{
return false;
}
to
unitSurf = load_image("infantry_red.png");
if(unitSurf == NULL)
{
return false;
}
Change: SDL_BlitSurface(Unit,NULL,screen,unitOffset); to SDL_BlitSurface(unitSurf,NULL,screen,unitOffset);
Remove the semicolon after while(SDL_PollEvent(&occur))

Create space between characters blitted on screen - SDL

I have a bmp-file of numbers and characters. My program reads keypresses and blits the appropriate character/number from the bitmap onto the screen. The only problem is if i press 'A' - 'A' will show on screen, but if I press 'B', it will take 'A's place. So I will never have more than one character on screen.
Here's my code:
#include <SDL/SDL.h>
#include <iostream>
#include <string>
#include <vector>
#include <SDL_image/SDL_image.h>
using namespace std;
const Uint32 FRAMES_PER_SECOND = 60;
const int SCREEN_WIDTH = 640;
const int SCREEN_HEIGHT = 480;
const int WIDTH = 21;
const int HEIGHT = 25;
SDL_Event sdlEvent;
char getAsciiKey(const SDL_Event &sdlEvent);
int main( int argc, char* args[] )
{
//The surfaces
SDL_Surface* image[2] = {NULL};
SDL_Surface* screen = NULL;
//Start SDL
SDL_Init( SDL_INIT_EVERYTHING );
//Set up screen
screen = SDL_SetVideoMode( SCREEN_WIDTH, SCREEN_HEIGHT, 32, SDL_SWSURFACE | SDL_DOUBLEBUF );
char filename[256]; //create a large enough C-string
for(int index = 0; index < 2; index++)
{
sprintf(filename, "Text-types/Arial%d.bmp", index); //Arial0 and Arial1
//Load the image
image[index] = IMG_Load( filename );
if(image == NULL)
{
cout << "Error loading image: " << filename << endl;
exit(1);
}
}
Uint32 color = SDL_MapRGB(screen->format, 0xff,0xff,0xff); //White
SDL_FillRect(screen, &screen->clip_rect, color); //Backgroundcolor -> White
bool quit = false;
//Main program loop
while(quit == false)
{
//Process any events from the event queue - such as key presses or mouse movements
while(SDL_PollEvent(&sdlEvent))
{
if(sdlEvent.type == SDL_QUIT)
{
quit = true;
}
if (sdlEvent.type == SDL_KEYDOWN) //A key has just pressed
{
int x, y, temp;
SDL_Rect srcRect;
SDL_Rect dstRect;
//char letter = getAsciiKey(sdlEvent); //Getting keypress
temp = (static_cast<int>(getAsciiKey(sdlEvent)) - 12);
x = (temp % 20); //X-axis postion
y = (temp / 20); //Y-axis position
srcRect.x = (x - 1) * WIDTH;
srcRect.y = (y - 1) * HEIGHT;
//PIXELSIZE
srcRect.w = WIDTH;
srcRect.h = HEIGHT;
dstRect.x = 0;
dstRect.y = 0;
dstRect.w = WIDTH;
dstRect.h = HEIGHT;
SDL_BlitSurface(image[1] , &srcRect, screen, &dstRect ); //Putting image up on screen
//Update Screen
SDL_Flip( screen );
//Pause
SDL_Delay( 2000 );
}
}
}
//Free any loaded images
for(int index = 0; index < 2; index++)
{
SDL_FreeSurface( image[index] );
}
//Quit SDL
SDL_Quit();
return 0;
}
char getAsciiKey(const SDL_Event &sdlEvent)
{
char key = 0;
if(sdlEvent.key.keysym.sym >= SDLK_a && sdlEvent.key.keysym.sym <= SDLK_z)
{
if(sdlEvent.key.keysym.mod & KMOD_SHIFT)
{
key = 'A' + char(sdlEvent.key.keysym.sym - SDLK_a);
}
else
{
key = 'a' + char(sdlEvent.key.keysym.sym - SDLK_a);
}
}
else if(sdlEvent.key.keysym.sym >= SDLK_0 && sdlEvent.key.keysym.sym <= SDLK_9)
{
key = '0' + char(sdlEvent.key.keysym.sym - SDLK_0);
}
return key;
}
dstRect.x = 0;
dstRect.y = 0;
This is the position you're blitting to, and I don't see you changing it anywhere. Update it for each new character.
Also, this:
dstRect.w = WIDTH;
dstRect.h = HEIGHT;
is redundant, width and height of destination are ignored when blitting (at least the reference for SDL_BlitSurface says so).