Why is the sprite not animating

Started by
2 comments, last by AtomicWinter 4 years, 6 months ago

Hi I'm working on the book SDL Game Development by Shaun Mitchell trying to build his game engine for my own use. I am a c++ and sdl noob, I had problems getting the include statements right for this section of the book but I managed to get an executable in the end by making my object files first then linking them together with g++ e.g g++ -c main.cpp, g++ Game.cpp, g++ TextureManager.cpp then g++ TextureManager.o Game.o main.o to get my executable, I managed to run it and it shows a dog in the top left over a red background, the only thing is the dog is supposed to be animated as a running dog. Can anybody explain to me what I have done wrong in the coding or the linking/compilation process that stops the dog moving? Thanks.

 

main.cpp


#include "Game.h"

//our game object
Game* g_game = 0;

int main(int argc, char* argv[])
{
g_game = new Game(); // on the freestore

g_game->init("Chapter 1",100,100,640,480,SDL_WINDOW_SHOWN);
//game loop
while(g_game->running())
{
g_game->handleEvents();
g_game->update();
g_game->render();
}
g_game->clean();
return 0;
}

Game.h


#ifndef __Game__
#define __Game__

#include "TextureManager.h"
#include<SDL2/SDL.h>
#include<SDL2/SDL_image.h>

class Game
{
public:
Game() {}
~Game() {}

// init function passed to SDL_CreateWindow
bool init(const char* title, int xpos, int ypos, int width,
    int height, int flags);

void render();
void update();
void handleEvents();
void clean();

// a function to access the private running variable
bool running() { return m_bRunning; }

private:

SDL_Window* m_pWindow = 0;
SDL_Renderer* m_pRenderer = 0;

SDL_Texture* m_pTexture= 0; // the new SDL_Texture variable
//SDL_Rect m_sourceRectangle; // the first rectangle
//SDL_Rect m_destinationRectangle; // another rectangle
bool m_bRunning;

int m_currentFrame;
TextureManager m_textureManager;

};

#endif /* defined(__Game__) */

 

Game.cpp


#include <iostream>
#include "Game.h"
    bool Game::init(const char* title, int xpos, int ypos, int width,
    int height, int flags)
    {
		m_bRunning = true; 
		//attempt to initialize SDL
			if(SDL_Init(SDL_INIT_EVERYTHING) == 0)
			{
			std::cout<<"SDL init sucess\n";
            //init the window
            m_pWindow = SDL_CreateWindow(title, xpos, ypos,
            width, height, flags);
				if(m_pWindow !=0) // window init success
				{
				std::cout << "window creation success\n";
				m_pRenderer = SDL_CreateRenderer(m_pWindow, -1, 0);
    
					if(m_pRenderer !=0) // renderer init success
					{
					std::cout << "renderer creation success\n";
					SDL_SetRenderDrawColor(m_pRenderer,
					255,0,0,255);
					}
					else
					{
					std::cout<<"renderer init fail\n";
					return false; // renderer init fail
					}
				}
				else
				{
				std::cout <<"window init fail\n";
				return false; // window init fail
				}
			}
			else
			{
			std::cout<<"SDL init fail\n";
			return false; // SDL init fail
			}

		std::cout <<"init success\n";
		m_bRunning= true; // everything inited successfully,
		//start the main loop
		
		m_textureManager.load("assets/animate-alpha.png","animate",
		m_pRenderer);
		
		//SDL_Surface* pTempSurface = IMG_Load("assets/animate-alpha.png");
		
		//m_pTexture = SDL_CreateTextureFromSurface(m_pRenderer, pTempSurface);
		
		//SDL_FreeSurface(pTempSurface);
		
		//SDL_QueryTexture(m_pTexture, NULL, NULL,
		//&m_sourceRectangle.w, &m_sourceRectangle.h);
		
		//m_destinationRectangle.x = m_sourceRectangle.x = 0;
		//m_destinationRectangle.y = m_sourceRectangle.y = 0;
		//m_destinationRectangle.w = 128;
		//m_destinationRectangle.h = 82;
		//m_sourceRectangle.w = 128;
		//m_sourceRectangle.h = 82;
		//m_sourceRectangle.x = 0;
		//m_sourceRectangle.y = 0;
		//m_destinationRectangle.x = 0;
		//m_destinationRectangle.y = 0;
		
		return true;
		
		}

void Game::render()
{
SDL_RenderClear(m_pRenderer); // clear the renderer to the
// draw color

m_textureManager.draw("animate", 0,0,128,82, m_pRenderer);

m_textureManager.drawFrame("animate",100,100,128,82,
1, m_currentFrame, m_pRenderer);

//SDL_RenderCopy(m_pRenderer, m_pTexture, &m_sourceRectangle,
//&m_destinationRectangle);

SDL_RenderPresent(m_pRenderer); // draw to the screen
}

void Game::update()
{
	m_currentFrame = int(((SDL_GetTicks() / 100) % 6));
}
 
void Game::handleEvents()
{
SDL_Event event;
if(SDL_PollEvent(&event))
{
    switch (event.type)
    {
    case SDL_QUIT:
        m_bRunning = false;
    break;

    default:
    break;
}
}
}


void Game::clean()
{
std::cout<<"cleaning game\n";
SDL_DestroyWindow(m_pWindow);
SDL_DestroyRenderer(m_pRenderer);
SDL_Quit();
}

TextureManager.h


#ifndef __TextureManager__
#define __TextureManager__

#include<map>
#include<string>
#include<SDL2/SDL.h>

class TextureManager
{
	public:
bool load(std::string filename, std::string id,
SDL_Renderer* pRenderer);

//draw
void draw(std::string id, int x, int y, int width, int
height, SDL_Renderer* pRenderer, SDL_RendererFlip flip =
SDL_FLIP_NONE);

//draw function

void drawFrame(std::string id, int x, int y, int width, int
height, int currentRow, int currentFrame, SDL_Renderer*
pRenderer, SDL_RendererFlip flip= SDL_FLIP_NONE);

std::map<std::string, SDL_Texture*> m_textureMap;
	
	private:
};

#endif /* defined(__TextureManager__) */

TextureManager.cpp


#include "TextureManager.h"
#include<SDL2/SDL_image.h>

bool TextureManager::load(std::string fileName, std::string
id, SDL_Renderer* pRenderer)
{
	SDL_Surface* pTempSurface = IMG_Load(fileName.c_str());
	
	if(pTempSurface == 0)
	{	
	return false;
	}
	
	SDL_Texture* pTexture =
	SDL_CreateTextureFromSurface(pRenderer, pTempSurface);
	
	SDL_FreeSurface(pTempSurface);
	
	// everything went ok, add the texture to our list
	if(pTexture != 0)
	{
	m_textureMap[id] = pTexture;
	return true;
	}

	// reaching here means something went wrong

	return false;

	}	

void TextureManager::draw(std::string id, int x, int y,
int width, int height, SDL_Renderer* pRenderer, SDL_RendererFlip flip)
{
	SDL_Rect srcRect;
	SDL_Rect destRect;
	
	srcRect.x = 0;
	srcRect.y = 0;
	srcRect.w = destRect.w = width;
	srcRect.h = destRect.h = height;
	destRect.x = x;
	destRect.y = y;
	
	SDL_RenderCopyEx(pRenderer, m_textureMap[id], &srcRect,
	&destRect, 0, 0, flip);
}

void TextureManager::drawFrame(std::string id, int x, int y,
int width, int height, int currentRow, int currentFrame,
SDL_Renderer *pRenderer, SDL_RendererFlip flip)
{
	SDL_Rect srcRect;
	SDL_Rect destRect;
	srcRect.x = width * currentFrame;
	srcRect.y = height * currentRow -1;
	srcRect.w = destRect.w = width;
	srcRect.h = destRect.h = height;
	destRect.x = x;
	destRect.y = y;
	
	SDL_RenderCopyEx(pRenderer, m_textureMap[id], &srcRect,
	&destRect, 0, 0, flip);
} 

 

Advertisement

I fail to see code that actually moves something, like a change in position etc. It appears to me that the draw functions just draw a static scene. But i may have overseen something.

Use a debugger ... ?

Look's like you're trying to animate via a sprite sheet and not necessarily position. The drawFrame function looks fine to me, without testing, but the suspicious part to me is where you calculate the current frame:


m_currentFrame = int(((SDL_GetTicks() / 100) % 6));

From this it looks like your sprite sheet has a total of 6 images (or frames), which is fine. However, what is


SDL_GetTicks() / 100

returning? I would debug that part and make sure it's calculating 1, 2, 3, 4, 5, 6, 1, 2, 3, etc. as desired. If not then your frame calculations will be thrown off. The index may be waayyy out of range.

[EDIT]

It looks like it return milliseconds. How fast is your loop? After 10 seconds you're looking at (10,000 / 100) % 6 = 4, but you're running that at 60 frames per second it could be changing so fast that you're not even noticing? Definitely do a debug and step through it. Make sure the frame index is fine and make sure that source/destination rects are calculated properly.  

This topic is closed to new replies.

Advertisement