SDL2 'Bullet' movement not working? - c++

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

Related

Cpp sdl game goes black screen after consistent amount of time [closed]

Closed. This question needs debugging details. It is not currently accepting answers.
Edit the question to include desired behavior, a specific problem or error, and the shortest code necessary to reproduce the problem. This will help others answer the question.
Closed 15 hours ago.
Improve this question
I am making a Cpp sdl game which launches as it should and is playable but only for about 7 second as after that the screen goes black. If I keep the game running with black screen it eventually shows LLVM ERROR: out of memory. While using local windows debugger in Visual Studio I get:
Exception thrown at 0x71002A85 (SDL2_ttf.dll) in game.exe: 0xC0000005: Access violation reading location 0x00000000
and/or
Unhandled exception at 0x7A6C3ED8 (nvoglv32.dll) in game.exe: Fatal program exit requested
Not sure if this information is of any use but changing SDL_Delay() from 1 to higher value e.g. 100, extends the amount of time it takes before the screen goes black. Also changing the SDL_CreateRenderer(window, -1, SDL_RENDERER_ACCELERATED) from '-1' to '1' extends the time it takes for the game to go black screen.
I tried different versions of SDL libraries and I don't think its a hardware issue. I used Visual Studio performance profiler and the CPU and GPU usage was normal. Performance profiler did show a 1.8 GB for process memory which did seem quite high, perhaps it's because of inefficient code(?).
I included some of the code and a snapshot.
main.cpp:
int main(int argc, char **argv)
{
/* initialize SDL */
if ( SDL_Init( SDL_INIT_VIDEO ) < 0 )
{
assert(0 && "Failed to initialize video!");
exit(-1);
}
SDL_Window* window = SDL_CreateWindow("Pacman", SDL_WINDOWPOS_UNDEFINED, SDL_WINDOWPOS_UNDEFINED, 1024, 768, SDL_WINDOW_OPENGL);
SDL_Renderer *renderer = SDL_CreateRenderer(window, -1, SDL_RENDERER_ACCELERATED); //changing from -1 to 1 increase the amout of time the app runs before black screen
if(!window)
{
assert(0 && "Failed to create window!");
exit(-1);
}
IMG_Init(IMG_INIT_JPG | IMG_INIT_PNG);
if (TTF_Init() == -1)
{
assert(0 && "Failed to create ttf!");
exit(-1);
}
Drawer* drawer = Drawer::Create(window, renderer);
Pacman* pacman = Pacman::Create(drawer);
float lastFrame = (float) SDL_GetTicks() * 0.001f;
SDL_Event event;
while (SDL_PollEvent(&event) >= 0)
{
float currentFrame = (float) SDL_GetTicks() * 0.001f;
float elapsedTime = currentFrame - lastFrame;
if (!pacman->Update(elapsedTime))
break;
SDL_SetRenderDrawColor(renderer, 0, 0, 0, 255);
SDL_RenderClear(renderer);
pacman->Draw();
lastFrame = currentFrame;
SDL_RenderPresent(renderer);
SDL_Delay(1);
}
delete pacman;
delete drawer;
TTF_Quit();
IMG_Quit();
SDL_Quit( );
return 0;
}
Drawer.cpp:
Drawer* Drawer::Create(SDL_Window* aWindow, SDL_Renderer* aRenderer)
{
Drawer* drawer = new Drawer(aWindow, aRenderer);
if (!drawer->Init())
{
delete drawer;
drawer = NULL;
}
return drawer;
}
Drawer::Drawer(SDL_Window* aWindow, SDL_Renderer* aRenderer)
: myWindow(aWindow)
, myRenderer(aRenderer)
, world()
{
}
Drawer::~Drawer(void)
{
}
bool Drawer::Init()
{
if (!myWindow)
return false;
return true;
}
void Drawer::Draw(const char* anImage, int aCellX, int aCellY)
{
SDL_Surface* surface = IMG_Load( anImage ) ;
if (!surface)
return;
SDL_Texture* optimizedSurface = SDL_CreateTextureFromSurface(myRenderer, surface);
SDL_Rect sizeRect;
sizeRect.x = 0 ;
sizeRect.y = 0 ;
sizeRect.w = surface->w ;
sizeRect.h = surface->h ;
SDL_Rect posRect;
posRect.x = aCellX;
posRect.y = aCellY;
posRect.w = sizeRect.w;
posRect.h = sizeRect.h;
SDL_RenderCopy(myRenderer, optimizedSurface, &sizeRect, &posRect);
}
void Drawer::DrawText(const char* aText, const char* aFontFile, int aX, int aY)
{
TTF_Font* font = TTF_OpenFont(aFontFile, 24);
if (font == nullptr) {
// Handle font loading error here (e.g. log an error message, throw an exception, etc.)
return;
}
SDL_Color fg = { 255, 0, 0, 255 };
SDL_Surface* surface = TTF_RenderText_Solid(font, aText, fg);
SDL_Texture* optimizedSurface = SDL_CreateTextureFromSurface(myRenderer, surface);
SDL_Rect sizeRect;
sizeRect.x = 0;
sizeRect.y = 0;
sizeRect.w = surface->w;
sizeRect.h = surface->h;
SDL_Rect posRect;
posRect.x = aX;
posRect.y = aY;
posRect.w = sizeRect.w;
posRect.h = sizeRect.h;
SDL_RenderCopy(myRenderer, optimizedSurface, &sizeRect, &posRect);
SDL_DestroyTexture(optimizedSurface);
SDL_FreeSurface(surface);
TTF_CloseFont(font);
}
world.cpp:
World::World(void)
{
}
World::~World()
{
for (auto tile : myPathmapTiles)
{
delete tile;
}
for (auto dot : myDots)
{
delete dot;
}
for (auto bigDot : myBigDots)
{
delete bigDot;
}
}
void World::Init()
{
InitPathmap();
InitDots();
InitBigDots();
}
bool World::InitPathmap()
{
std::string line;
std::ifstream myfile ("map.txt");
if (myfile.is_open())
{
int lineIndex = 0;
while (! myfile.eof() )
{
std::getline (myfile,line);
for (unsigned int i = 0; i < line.length(); i++)
{
PathmapTile* tile = new PathmapTile(i, lineIndex, (line[i] == 'x'));
myPathmapTiles.push_back(tile);
}
lineIndex++;
}
myfile.close();
}
return true;
}
bool World::InitDots()
{
std::string line;
std::ifstream myfile ("map.txt");
if (myfile.is_open())
{
int lineIndex = 0;
while (! myfile.eof() )
{
std::getline (myfile,line);
for (unsigned int i = 0; i < line.length(); i++)
{
if (line[i] == '.')
{
Dot* dot = new Dot(Vector2f(i * 22.0f, lineIndex * 22.0f));
myDots.push_back(dot);
}
}
lineIndex++;
}
myfile.close();
}
return true;
}
bool World::InitBigDots()
{
std::string line;
std::ifstream myfile ("map.txt");
if (myfile.is_open())
{
int lineIndex = 0;
while (! myfile.eof() )
{
std::getline (myfile,line);
for (unsigned int i = 0; i < line.length(); i++)
{
if (line[i] == 'o')
{
BigDot* dot = new BigDot(Vector2f(i * 22.0f, lineIndex * 22.0f));
myBigDots.push_back(dot);
}
}
lineIndex++;
}
myfile.close();
}
return true;
}
void World::Draw(Drawer* aDrawer)
{
aDrawer->Draw("playfield.png");
for(std::list<Dot*>::iterator list_iter = myDots.begin(); list_iter != myDots.end(); list_iter++)
{
Dot* dot = *list_iter;
dot->Draw(aDrawer);
}
for(std::list<BigDot*>::iterator list_iter = myBigDots.begin(); list_iter != myBigDots.end(); list_iter++)
{
BigDot* dot = *list_iter;
dot->Draw(aDrawer);
}
}
bool World::TileIsValid(int anX, int anY)
{
for(std::list<PathmapTile*>::iterator list_iter = myPathmapTiles.begin(); list_iter != myPathmapTiles.end(); list_iter++)
{
PathmapTile* tile = *list_iter;
if (anX == tile->myX && anY == tile->myY && !tile->myIsBlockingFlag)
return true;
}
return false;
}
bool World::HasIntersectedDot(const Vector2f& aPosition)
{
for(std::list<Dot*>::iterator list_iter = myDots.begin(); list_iter != myDots.end(); list_iter++)
{
Dot* dot = *list_iter;
if ((dot->GetPosition() - aPosition).Length() < 5.f)
{
myDots.remove(dot);
delete dot;
return true;
}
}
return false;
}
bool World::HasIntersectedBigDot(const Vector2f& aPosition)
{
for(std::list<BigDot*>::iterator list_iter = myBigDots.begin(); list_iter != myBigDots.end(); list_iter++)
{
BigDot* dot = *list_iter;
if ((dot->GetPosition() - aPosition).Length() < 5.f)
{
myBigDots.remove(dot);
delete dot;
return true;
}
}
return false;
}
bool World::HasIntersectedCherry(const Vector2f& aPosition)
{
return true;
}
void World::GetPath(int aFromX, int aFromY, int aToX, int aToY, std::list<PathmapTile*>& aList)
{
PathmapTile* fromTile = GetTile(aFromX, aFromY);
PathmapTile* toTile = GetTile(aToX, aToY);
for(std::list<PathmapTile*>::iterator list_iter = myPathmapTiles.begin(); list_iter != myPathmapTiles.end(); list_iter++)
{
PathmapTile* tile = *list_iter;
tile->myIsVisitedFlag = false;
}
Pathfind(fromTile, toTile, aList);
}
PathmapTile* World::GetTile(int aFromX, int aFromY)
{
for(std::list<PathmapTile*>::iterator list_iter = myPathmapTiles.begin(); list_iter != myPathmapTiles.end(); list_iter++)
{
PathmapTile* tile = *list_iter;
if (tile->myX == aFromX && tile->myY == aFromY)
{
return tile;
}
}
return NULL;
}
bool World::ListDoesNotContain(PathmapTile* aFromTile, std::list<PathmapTile*>& aList)
{
for(std::list<PathmapTile*>::iterator list_iter = aList.begin(); list_iter != aList.end(); list_iter++)
{
PathmapTile* tile = *list_iter;
if (tile == aFromTile)
{
return false;
}
}
return true;
}
bool SortFromGhostSpawn(PathmapTile* a, PathmapTile* b)
{
int la = abs(a->myX - 13) + abs(a->myY - 13);
int lb = abs(b->myX - 13) + abs(b->myY - 13);
return la < lb;
}
bool World::Pathfind(PathmapTile* aFromTile, PathmapTile* aToTile, std::list<PathmapTile*>& aList)
{
aFromTile->myIsVisitedFlag = true;
if (aFromTile->myIsBlockingFlag)
return false;
if (aFromTile == aToTile)
return true;
std::list<PathmapTile*> neighborList;
PathmapTile* up = GetTile(aFromTile->myX, aFromTile->myY - 1);
if (up && !up->myIsVisitedFlag && !up->myIsBlockingFlag && ListDoesNotContain(up, aList))
neighborList.push_front(up);
PathmapTile* down = GetTile(aFromTile->myX, aFromTile->myY + 1);
if (down && !down->myIsVisitedFlag && !down->myIsBlockingFlag && ListDoesNotContain(down, aList))
neighborList.push_front(down);
PathmapTile* right = GetTile(aFromTile->myX + 1, aFromTile->myY);
if (right && !right->myIsVisitedFlag && !right->myIsBlockingFlag && ListDoesNotContain(right, aList))
neighborList.push_front(right);
PathmapTile* left = GetTile(aFromTile->myX - 1, aFromTile->myY);
if (left && !left->myIsVisitedFlag && !left->myIsBlockingFlag && ListDoesNotContain(left, aList))
neighborList.push_front(left);
neighborList.sort(SortFromGhostSpawn);
for(std::list<PathmapTile*>::iterator list_iter = neighborList.begin(); list_iter != neighborList.end(); list_iter++)
{
PathmapTile* tile = *list_iter;
aList.push_back(tile);
if (Pathfind(tile, aToTile, aList))
return true;
aList.pop_back();
}
return false;
}
Snapshot:
Snapshot

Texture not displaying SDL2 [closed]

Closed. This question needs debugging details. It is not currently accepting answers.
Edit the question to include desired behavior, a specific problem or error, and the shortest code necessary to reproduce the problem. This will help others answer the question.
Closed 7 months ago.
Improve this question
I'm trying to make a game in C++ with SDL2, and I can't even get a texture displaying. SDL_GetError() returns nothing.
I'm on a windows 10 pro using Visual Studio.
Here are my 3 files:
main.cpp
#include "Classes.h"
int MouseX = 0;
int MouseY = 0;
int PlayerX = 0;
int PlayerY = 0;
SDL_Renderer* renderer;
Tile tile = Tile({10, 10, TileTypes::Tile_Grass}, renderer);
EventReturns HandleEvent(SDL_Event* event) {
switch (event->type) {
case SDL_QUIT:
return EventReturns::Event_QUIT;
case SDL_KEYDOWN:
switch (event->key.keysym.sym) {
case SDLK_ESCAPE:
return EventReturns::Event_TryQuit;
default:
return EventReturns::Event_None;
}
default:
return EventReturns::Event_None;
}
}
int mainLoop(EventReturns eventReturn) {
SDL_GetMouseState(&MouseX, &MouseY);
if (eventReturn == EventReturns::Event_QUIT || eventReturn == EventReturns::Event_TryQuit) {
return 1;
}
return 0;
}
void render() {
SDL_SetRenderDrawColor(renderer, 100, 200, 200, 255);
SDL_RenderClear(renderer);
SDL_SetRenderDrawColor(renderer, 0, 0, 0, 255);
tile.SetPos(0, 0);
if (tile.Draw(renderer) != 0) {
SDL_ShowSimpleMessageBox(0, "ERROR", "ERROR: Rect in tile has 0x0 size, Please close this with the task manager", NULL);
}
SDL_RenderPresent(renderer);
}
int main(int argc, char* argv[]) {
SDL_Window* window = SDL_CreateWindow("Game", SDL_WINDOWPOS_CENTERED, SDL_WINDOWPOS_CENTERED, 2880, 1600, SDL_WINDOW_SHOWN);
renderer = SDL_CreateRenderer(window, -1, SDL_RENDERER_ACCELERATED);
bool running = true;
EventReturns eventReturn = EventReturns::Event_None;
SDL_Event event;
int quit = 0;
while (running) {
while (SDL_PollEvent(&event)) {
eventReturn = HandleEvent(&event);
}
quit = mainLoop(eventReturn);
render();
if (quit == 1) {
running = false;
}
}
SDL_DestroyRenderer(renderer);
SDL_DestroyWindow(window);
SDL_Quit();
return 0;
}
Classes.h
#pragma once
#include <SDL.h>
#include <SDL_image.h>
#include <iostream>
#define SpriteSizeMult 1
enum class EventReturns {
Event_QUIT,
Event_None,
Event_TryQuit
};
enum class TileTypes {
Tile_Grass
};
struct TileStruct {
int x;
int y;
TileTypes type;
};
class Tile {
public:
Tile(int x, int y, char* TexturePath, SDL_Renderer* renderer);
Tile(TileStruct structure, SDL_Renderer* renderer);
Tile();
int Draw(SDL_Renderer* renderer);
void SetPos(int x, int y);
private:
int x = 0;
int y = 0;
int TextureWidth = 0;
int TextureHeight = 0;
SDL_Texture* texture;
SDL_Rect rect;
};
SDL_Point getsize(SDL_Texture* texture);
Classes.cpp
#include "Classes.h"
SDL_Point getsize(SDL_Texture* texture) {
SDL_Point size;
SDL_QueryTexture(texture, NULL, NULL, &size.x, &size.y);
return size;
}
Tile::Tile(int x, int y, char* TexturePath, SDL_Renderer* renderer)
{
this->x = x;
this->y = y;
this->texture = SDL_CreateTextureFromSurface(renderer, IMG_Load(TexturePath));
if (this->texture == nullptr) {
this->texture = SDL_CreateTextureFromSurface(renderer, IMG_Load("Assets/MissingTexture.png"));
std::cout << IMG_GetError();
}
SDL_Point point = getsize(this->texture);
this->TextureHeight = point.y;
this->TextureWidth = point.x;
this->rect = {this->x - ((this->TextureWidth * SpriteSizeMult) / 2), this->y - ((this->TextureHeight * SpriteSizeMult) / 2), this->TextureWidth * SpriteSizeMult, this->TextureHeight * SpriteSizeMult};
}
Tile::Tile(TileStruct structure, SDL_Renderer* renderer)
{
this->x = structure.x;
this->y = structure.y;
switch (structure.type) {
case TileTypes::Tile_Grass:
this->texture = SDL_CreateTextureFromSurface(renderer, IMG_Load("Assets/Tiles/Grass.png"));
default:
this->texture = SDL_CreateTextureFromSurface(renderer, IMG_Load("Assets/MissingTexture.png"));
}
if (this->texture == NULL) {
this->texture = SDL_CreateTextureFromSurface(renderer, IMG_Load("Assets/MissingTexture.png"));
if (this->texture == NULL) {
SDL_ShowSimpleMessageBox(0, "ERROR", "Failed to load texture", NULL);
SDL_ShowSimpleMessageBox(0, "ERROR", IMG_GetError(), NULL);
}
}
SDL_Point point = getsize(this->texture);
this->TextureHeight = point.y;
this->TextureWidth = point.x;
this->rect = { this->x - ((this->TextureWidth * SpriteSizeMult) / 2), this->y - ((this->TextureHeight * SpriteSizeMult) / 2), this->TextureWidth * SpriteSizeMult, this->TextureHeight * SpriteSizeMult };
}
Tile::Tile()
{
}
int Tile::Draw(SDL_Renderer* renderer)
{
if (rect.w == 0 || rect.h == 0) {
return -1;
}
this->rect.x = 0;
this->rect.y = 0;
SDL_RenderCopy(renderer, this->texture, NULL, &rect);
return 0;
}
void Tile::SetPos(int x, int y)
{
this->x = x;
this->y = y;
}
I'm sorry for the sheer amount of code that is, but I'd really appreciate the help. If there's any more info I need to put here, just let me know.
I'm fully aware that I should make a Minimal Reproducible Example, but as far as I'm aware, all the code listed here is necessary.
Finally, in case I've been unclear, when running the code the Missing Texture image that should appear isn't showing up.
I can't see SDL_INIT function in your code.
You should add this in the beginning of your main function.
if (SDL_Init(SDL_INIT_EVERYTHING) != 0)
return 1;
You are initialising tile before creating a renderer so the constructor is trying to create a texture without a renderer.
SDL_Renderer* renderer;
Tile tile = Tile({10, 10, TileTypes::Tile_Grass}, renderer);
You should do something like this
#include "Classes.h"
int MouseX = 0;
int MouseY = 0;
int PlayerX = 0;
int PlayerY = 0;
SDL_Renderer* renderer;
EventReturns HandleEvent(SDL_Event* event) {
switch (event->type) {
case SDL_QUIT:
return EventReturns::Event_QUIT;
case SDL_KEYDOWN:
switch (event->key.keysym.sym) {
case SDLK_ESCAPE:
return EventReturns::Event_TryQuit;
default:
return EventReturns::Event_None;
}
default:
return EventReturns::Event_None;
}
}
int mainLoop(EventReturns eventReturn) {
SDL_GetMouseState(&MouseX, &MouseY);
if (eventReturn == EventReturns::Event_QUIT || eventReturn == EventReturns::Event_TryQuit) {
return 1;
}
return 0;
}
void render(Tile tile) {
SDL_SetRenderDrawColor(renderer, 100, 200, 200, 255);
SDL_RenderClear(renderer);
SDL_SetRenderDrawColor(renderer, 0, 0, 0, 255);
tile.SetPos(0, 0);
if (tile.Draw(renderer) != 0) {
SDL_ShowSimpleMessageBox(0, "ERROR", "ERROR: Rect in tile has 0x0 size, Please close this with the task manager", NULL);
}
SDL_RenderPresent(renderer);
}
int main(int argc, char* argv[]) {
if (SDL_Init(SDL_INIT_EVERYTHING) != 0)
return 1;
SDL_Window* window = SDL_CreateWindow("Game", SDL_WINDOWPOS_CENTERED, SDL_WINDOWPOS_CENTERED, 2880, 1600, SDL_WINDOW_SHOWN);
renderer = SDL_CreateRenderer(window, -1, SDL_RENDERER_ACCELERATED);
Tile tile = Tile({ 10, 10, TileTypes::Tile_Grass }, renderer);
bool running = true;
EventReturns eventReturn = EventReturns::Event_None;
SDL_Event event;
int quit = 0;
while (running) {
while (SDL_PollEvent(&event)) {
eventReturn = HandleEvent(&event);
}
quit = mainLoop(eventReturn);
render(tile);
if (quit == 1) {
running = false;
}
}
SDL_DestroyRenderer(renderer);
SDL_DestroyWindow(window);
SDL_Quit();
return 0;
}

SDL_RenderCopy not rendering (Isn't NULL, none SDL/IMG Error too)

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

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

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))