Jump to content
  • Advertisement

2D Skeletal animated character and transparency

Recommended Posts

I have a character in a game, made of multiple sprites in a hierarchy for skeletal animation (also called cutout animation by some).

I want to make that character semi-transparent for a while, like a ghost.

The problem is, when I naïvely set the transparency on the top-most sprite and all of its children, it doesn't look as I expected, because the parts of the sprites that were supposed to be occluded by other sprites can now be seen through their occluders :P  Like, for example, you can see the body through the clothes, or parts of the limbs inside the body, etc. (#3 in the picture below).

I'd rather like it to be made transparent as a whole, as if it were a single image (#2 in the picture below).

OpacityProblem1.png

So my question is, how is this effect usually achieved in video games?
(Preferably in OpenGL, but I'd like to know the general approach, so that I could apply it to whatever tool I'll use.)

My first thought of how to fix it, was to render the sprite chierarchy to texture first, and then map that texture onto a simple rectangular mesh, and apply opacity to that.
But this approach would have some drawbacks. One of them I guess being the additional overhead required for rendering to texture, especially if there will be more "ghosts" on the screen at the same time, all with different transparencies. Another one is of course the overhead in code – it would require a framework of managing these hierarchies and their associated render targets – in other words: a MESS! :P

Is there any other, better way to do that than rendering the entire character to texture?

If there isn't one, then maybe you could give me some advices about how to organize that mess in the code?

Edited by SasQ
Attached a picture of the problem

Share this post


Link to post
Share on other sites
Advertisement

Another option, since I'm not exactly sure what your issue is (images would be a good thing to post), would be to render to texture but instead of multiple render to textures for multiple ghosts... Figure out how many you have to render and enlarge the texture and turn it into a texture atlas of sorts.  It would reduce resource and switching costs at least.

Share this post


Link to post
Share on other sites

Yeah rendering all the ghosts to a texture atlas wouldn't be out of the ordinary. 

You could also use the stencil buffer. Clear it to zero at the start of the frame, then for the first ghost, configure the stencil test to enabled=true, reference=1, pass if stencil is not reference, on pass: set to reference, on fail: keep previous. Then for the second ghost, set reference=2, etc. 

Then draw your character's cut-out parts in front to back order. The stencil test will ensure that each ghost can only write to a pixel once (the first triangle to cover that pixel). 

If you've got over 255 ghosts, then after the 255th, clear the stencil to 0 again and set the stencil ref back to 1 (and count up again). 

Share this post


Link to post
Share on other sites
4 hours ago, Mike2343 said:

images would be a good thing to post

OK I added a picture that shows the essence of the problem in the original post.

#1 is the fully opaque version.
#2 is what I want to get: the image of the entire hierarchy being semi-transparent, and whatever has been occluded in the original (opaque) image, stays occluded in the transparent one.
#3 is what I actually get when I naively set the transparency on each of the constituent parts - they become transparent, but then they no longer occlude each other in the way they were supposed to do, and I can see their internals (imagine one of these balls being the clothes, and the other one being the body of a character; or one of them being the body, and the other being a limb that sticks out of it, partially occluded by the body).

I may composite the image first by rendering it to a texture and then rendering a quad with that texture applied, along with transparency on that quad, and it works the way I want, but I'm worried that this might not scale well if there will be more such "ghosts" on the screen. (BTW how many render targets is considered too much? :q )

4 hours ago, Mike2343 said:

but instead of multiple render to textures for multiple ghosts... Figure out how many you have to render and enlarge the texture and turn it into a texture atlas of sorts.  It would reduce resource and switching costs at least.

Interesting idea. So you're saying that I should render all those "ghosts" to one texture and then use it to render the quads as single sprites? Hmm... would it still be possible for each of them having a different opacity? Or will it only work if all these ghosts are at the same opacity level?

Nevertheless, I'm afraid this approach will be a mess to code in order to manage all those render targets, unless there's some organized way to do it. (Any tutorials perchance? It's not that this is something extraordinary, right? I've seen such effects being used in video games for the last 10 years or so :q ) But I guess I would have to go with that approach anyway if I wanted to add some more effects to the hierarchy, such as glow, blur, waving or some other shader effects... Am I right? :q

4 hours ago, Hodgman said:

You could also use the stencil buffer.

Hmm.... Sounds interesting. At least it wouldn't require keeping track of all those render targets kicking around with each sprite hierarchy. Switching rendering parameters seems easier. But I've never used stencil buffers before, so I guess I have some learning to do, because I don't quite understand all the details of how your solution works. Is it supposed to prevent the pixels of the transparent parts of the same character from overwriting each other or something? Then maybe it would suffice with just one index? I could reset it to zero after drawing each hierarchy.

Wouldn't it mess up the antialiased pixels on the edges of the sprites though? :q Once they've been drawn to the stencil from the top sprite, it would protect these pixels from mixing with the pixels of the next sprite underneath, right?

Edited by SasQ
Antialiasing?

Share this post


Link to post
Share on other sites
1 hour ago, SasQ said:

Hmm.... Sounds interesting. At least it wouldn't require keeping track of all those render targets kicking around with each sprite hierarchy. Switching rendering parameters seems easier. But I've never used stencil buffers before, so I guess I have some learning to do, because I don't quite understand all the details of how your solution works. Is it supposed to prevent the pixels of the transparent parts of the same character from overwriting each other or something? Then maybe it would suffice with just one index? I could reset it to zero after drawing each hierarchy.

Yeah.

The stencil test occurs before pixel shading and looks something like

if stencilTestEnabled then
  if stencilTest(stencilBuffer[x,y], stencilReference) then
    stencilBuffer[x,y] = onPass(stencilBuffer[x,y], stencilReference)
    frameBuffer[x,y] = pixelShader()
  else
    stencilBuffer[x,y] = onFail(stencilBuffer[x,y], stencilReference)
  end
else
  frameBuffer[x,y] = pixelShader()
end

You can use OpenGL's API to configure

Set "stencilTestEnabled=true":
glEnable(GL_STENCIL_TEST);

Set "stencilTest(buffer, reference)" to "return buffer != reference", and set "reference=0":
glStencilFunc(GL_NOTEQUAL, 0, 0xFF)

Set "onPass(buffer, reference)" to "return reference", and "onFail(buffer, reference)" to "return buffer":
glStencilOp(GL_KEEPGL_REPLACE, GL_KEEP)

You then end up with a stencil test that looks something like:

if stencilBuffer[x,y] != stencilReference then
  stencilBuffer[x,y] = stencilReference
  frameBuffer[x,y] = pixelShader()
end

 

Clearing the stencil buffer to zero is kind of expensive (at 1080p, there's two million pixels in a fullscreen buffer...), hence my suggestion to simply use a different "stencilReference" value for each ghost.

Having this kind of stencil test as a condition on running the pixel shader, means that for each pixel in the ghost, it first checks to see if the "ghost ID" (stencil reference value) is already present at that pixel location. If it's not, then the ghost draws itself there and also saves the "ghost ID" into the stencil buffer. If another polygon with the same "ghost ID" then comes along afterwards (e.g. the body underneath the clothes), it will realize that the current "ghost ID" has already been written at this pixel location, so will skip running the pixel shader / will early exit.

Share this post


Link to post
Share on other sites
7 hours ago, SasQ said:

The problem is, when I naïvely set the transparency on the top-most sprite and all of its children, it doesn't look as I expected, because the parts of the sprites that were supposed to be occluded by other sprites can now be seen through their occluders

If you want "occlusion" from top-most sprites, then couldn't you just have the transparent sprites write to the depth mask and let depth-testing take care of it? The second sphere would then automatically depth-fail against the previous sprites, giving the result in #2.

Edited by Styves

Share this post


Link to post
Share on other sites

Not if the sprites have some areas that are supposed to be semi-transparent over each other.

Suppose that these spheres have some glowing auras around them. This aura should blend with the sprites underneath, but the balls should occlude each other, even if I make the entire hierarchy semi-transparent.

OpacityProblem2.png

Now when I think of it, this may also render the stencil buffer solution inapplicable. Too bad, I guess the only way to go for me is with the "composite first, transparency next" approach :/ and rendering the entire hierarchy to a texture cannot be avoided.

(Correct me if I'm wrong, though. I'm pretty new to those additional buffers. I'm here to learn how those effects are usually done in video games.)

Edited by SasQ
Added image

Share this post


Link to post
Share on other sites
48 minutes ago, SasQ said:

This aura should blend with the sprites underneath, but the balls should occlude each other, even if I make the entire hierarchy semi-transparent.

You could probably get away with this with some depth output tweaks, but I see what you mean. I don't think it'd be worth the hassle.

One option is to do the same thing Hodgman suggested but manually using shaders and MRT rather than the stencil buffer. Done this way you have full control of where this "occlusion" should be.

50 minutes ago, SasQ said:

Too bad, I guess the only way to go for me is with the "composite first, transparency next" approach :/ and rendering the entire hierarchy to a texture cannot be avoided.

(Correct me if I'm wrong, though. I'm pretty new to those additional buffers. I'm here to learn how those effects are usually done in video games.)

8 hours ago, SasQ said:

One of them I guess being the additional overhead required for rendering to texture, especially if there will be more "ghosts" on the screen at the same time, all with different transparencies. Another one is of course the overhead in code – it would require a framework of managing these hierarchies and their associated render targets – in other words: a MESS!

Well, you don't need a complex framework for several render targets to do this unless you want to cache those results somewhere. I wouldn't particularly suggest it since you'll have to fight resolution mis-match with the main image.

A better approach might be to simply have a single full-screen temporary render target in which you render each object to. Use scissors + viewport + clear between each object draw to clean up the region the next object is going to be rendered to, and composite that region back onto the main render target after the sprites for that object are drawn.

Share this post


Link to post
Share on other sites
18 hours ago, SasQ said:

Interesting idea. So you're saying that I should render all those "ghosts" to one texture and then use it to render the quads as single sprites? Hmm... would it still be possible for each of them having a different opacity? Or will it only work if all these ghosts are at the same opacity level?

Just to answer this question, if you create the FBO in RGBA format then yes each ghost could have different values for alpha.

Tutorials/Information on Frame Buffer Objects (or Render to Texture):

http://www.songho.ca/opengl/gl_fbo.html

http://www.opengl-tutorial.org/intermediate-tutorials/tutorial-14-render-to-texture/

This one is in Java but the OpenGL commands are the same:

http://www.swiftless.com/tutorials/opengl/framebuffer.html

 

Share this post


Link to post
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now

  • Advertisement
  • Advertisement
  • Popular Tags

  • Popular Now

  • Advertisement
  • Similar Content

    • By LuigiLuigi
      I've been working on my own Metroidvania via GameMaker Studio for the past few years. You play as a bat named Ralph as he goes on an adventure to obtain 7 Crystal Medallions hidden in dungeons with the help of a cult known as the Crimson Fog. Along the way, there will be quests unlocked in Cedrus Village as you progress through the game. I've managed to complete a demo of the game up to the first dungeon and boss fight.
      I have only a PC build available, and the only gamepads I managed to install were Logitech Precision and Xbox PC gamepads. I had some trouble on gamepad detection though, so they may have connection issues. The desktop controls are similar to Terarria's control scheme if it's too much trouble. I don't have any music at this point, I'll need to get someone else to compose it later on. The music I make isn't bad, but it doesn't fit the aesthetic that well.
      I'm really hoping I can get feedback regarding the general content.
      Crimson Fog.0.2.zip
    • By Alexander Winter
      Jumpaï is a game about creating platformer levels and playing them online with everyone. Will you become the most popular level maker or will you be a speedrunner holding world records on everyone's levels? More into casual play? No problem! You can happily play through the giant level database or chill at people's hub. Meet new people, make new friends, learn to master the game by asking pros or ask for people's favorite tricks on level making. Download here: https://jumpai.itch.io/jumpai Discord: https://discord.gg/dwRTNCG   Trailer:      (The following screenshots are older but still a bit representative)  





      Unlike other games of its genre, Jumpaï is about playing levels with everyone in real time. You have the fun to see how other people are playing and get to realize you are not the only one failing that jump!

      The game is currently into development and still have lots to do. I am looking for people willing to help how they can. Developer? Graphist? Play tester? Sound designer? Game designer? I'm welcoming any talent. The project is so big I have a lot of work to do in all areas. Server backend, UI/UX, Game networking, Gameplay and even the website some day. As you can see from the default buttons, the game has been made with LibGDX. This project is a perfect opportunity for you to get better in various fields as well as showing off your skills.

      If you plan to take an important role into the development of the game, we will discuss how you will get paid once the game generates money. Note that I'm not working on the game full-time. I'm studying full-time and working on it is a hobby. The project has started in november 2016 and experiences heavy progress.

      So, are you interested? If so join me on my discord https://discord.gg/dwRTNCG and I'll answer all your questions.

      Additionnal screenshots:
       



       
    • By Shtabbbe
      I've had a game idea for a while, and I wanted to finally try to create it.
      Its a 2D open-world tile-based MMO. The concept is it is one world and multiplayer only, so everyone shares one world no matter region, platform, etc.
      I am having problems finding out what to use to start development, I tried Unity but saw some of the negatives and refrained and now im stuck, could anyone recommend some intermediate friendly 2D engines that can support what I am looking for? Preferably in languages that are or are somewhat like Java, C#, Python, JavaScript, Lua.
      Thanks for your help, im very new at this if you cant tell
    • By Adrian Bigaj
      Hello!

      The game: https://www.combo-clicks.com/
      DEV blog (so everyone can read the journey and some history):
      http://www.combo-clicks-dev.com/
      TL;DR
      Feedback for Combo Clicks and also IDEAS for future games will be super appreciated (Hyper Casuals done in 3-4 weeks, each game with React Native).
      I will try to post on my blog atleast on weekly basis (both for gamers and developers) 
      Thank you!




    • By babaliaris
      Hello Everyone!
      I'm learning openGL, and currently i'm making a simple 2D game engine to test what I've learn so far.  In order to not say to much, i made a video in which i'm showing you the behavior of the rendering.
      Video: 
       
      What i was expecting to happen, was the player moving around. When i render only the player, he moves as i would expect. When i add a second Sprite object, instead of the Player, this new sprite object is moving and finally if i add a third Sprite object the third one is moving. And the weird think is that i'm transforming the Vertices of the Player so why the transformation is being applied somewhere else?
       
      Take a look at my code:
      Sprite Class
      (You mostly need to see the Constructor, the Render Method and the Move Method)
      #include "Brain.h" #include <glm/gtc/matrix_transform.hpp> #include <vector> struct Sprite::Implementation { //Position. struct pos pos; //Tag. std::string tag; //Texture. Texture *texture; //Model matrix. glm::mat4 model; //Vertex Array Object. VertexArray *vao; //Vertex Buffer Object. VertexBuffer *vbo; //Layout. VertexBufferLayout *layout; //Index Buffer Object. IndexBuffer *ibo; //Shader. Shader *program; //Brains. std::vector<Brain *> brains; //Deconstructor. ~Implementation(); }; Sprite::Sprite(std::string image_path, std::string tag, float x, float y) { //Create Pointer To Implementaion. m_Impl = new Implementation(); //Set the Position of the Sprite object. m_Impl->pos.x = x; m_Impl->pos.y = y; //Set the tag. m_Impl->tag = tag; //Create The Texture. m_Impl->texture = new Texture(image_path); //Initialize the model Matrix. m_Impl->model = glm::mat4(1.0f); //Get the Width and the Height of the Texture. int width = m_Impl->texture->GetWidth(); int height = m_Impl->texture->GetHeight(); //Create the Verticies. float verticies[] = { //Positions //Texture Coordinates. x, y, 0.0f, 0.0f, x + width, y, 1.0f, 0.0f, x + width, y + height, 1.0f, 1.0f, x, y + height, 0.0f, 1.0f }; //Create the Indicies. unsigned int indicies[] = { 0, 1, 2, 2, 3, 0 }; //Create Vertex Array. m_Impl->vao = new VertexArray(); //Create the Vertex Buffer. m_Impl->vbo = new VertexBuffer((void *)verticies, sizeof(verticies)); //Create The Layout. m_Impl->layout = new VertexBufferLayout(); m_Impl->layout->PushFloat(2); m_Impl->layout->PushFloat(2); m_Impl->vao->AddBuffer(m_Impl->vbo, m_Impl->layout); //Create the Index Buffer. m_Impl->ibo = new IndexBuffer(indicies, 6); //Create the new shader. m_Impl->program = new Shader("Shaders/SpriteShader.shader"); } //Render. void Sprite::Render(Window * window) { //Create the projection Matrix based on the current window width and height. glm::mat4 proj = glm::ortho(0.0f, (float)window->GetWidth(), 0.0f, (float)window->GetHeight(), -1.0f, 1.0f); //Set the MVP Uniform. m_Impl->program->setUniformMat4f("u_MVP", proj * m_Impl->model); //Run All The Brains (Scripts) of this game object (sprite). for (unsigned int i = 0; i < m_Impl->brains.size(); i++) { //Get Current Brain. Brain *brain = m_Impl->brains[i]; //Call the start function only once! if (brain->GetStart()) { brain->SetStart(false); brain->Start(); } //Call the update function every frame. brain->Update(); } //Render. window->GetRenderer()->Draw(m_Impl->vao, m_Impl->ibo, m_Impl->texture, m_Impl->program); } void Sprite::Move(float speed, bool left, bool right, bool up, bool down) { if (left) { m_Impl->pos.x -= speed; m_Impl->model = glm::translate(m_Impl->model, glm::vec3(-speed, 0, 0)); } if (right) { m_Impl->pos.x += speed; m_Impl->model = glm::translate(m_Impl->model, glm::vec3(speed, 0, 0)); } if (up) { m_Impl->pos.y += speed; m_Impl->model = glm::translate(m_Impl->model, glm::vec3(0, speed, 0)); } if (down) { m_Impl->pos.y -= speed; m_Impl->model = glm::translate(m_Impl->model, glm::vec3(0, -speed, 0)); } } void Sprite::AddBrain(Brain * brain) { //Push back the brain object. m_Impl->brains.push_back(brain); } pos *Sprite::GetPos() { return &m_Impl->pos; } std::string Sprite::GetTag() { return m_Impl->tag; } int Sprite::GetWidth() { return m_Impl->texture->GetWidth(); } int Sprite::GetHeight() { return m_Impl->texture->GetHeight(); } Sprite::~Sprite() { delete m_Impl; } //Implementation Deconstructor. Sprite::Implementation::~Implementation() { delete texture; delete vao; delete vbo; delete layout; delete ibo; delete program; }  
      Renderer Class
      #include "Renderer.h" #include "Error.h" Renderer::Renderer() { } Renderer::~Renderer() { } void Renderer::Draw(VertexArray * vao, IndexBuffer * ibo, Texture *texture, Shader * program) { vao->Bind(); ibo->Bind(); program->Bind(); if (texture != NULL) texture->Bind(); GLCall(glDrawElements(GL_TRIANGLES, ibo->GetCount(), GL_UNSIGNED_INT, NULL)); } void Renderer::Clear(float r, float g, float b) { GLCall(glClearColor(r, g, b, 1.0)); GLCall(glClear(GL_COLOR_BUFFER_BIT)); } void Renderer::Update(GLFWwindow *window) { /* Swap front and back buffers */ glfwSwapBuffers(window); /* Poll for and process events */ glfwPollEvents(); }  
      Shader Code
      #shader vertex #version 330 core layout(location = 0) in vec4 aPos; layout(location = 1) in vec2 aTexCoord; out vec2 t_TexCoord; uniform mat4 u_MVP; void main() { gl_Position = u_MVP * aPos; t_TexCoord = aTexCoord; } #shader fragment #version 330 core out vec4 aColor; in vec2 t_TexCoord; uniform sampler2D u_Texture; void main() { aColor = texture(u_Texture, t_TexCoord); } Also i'm pretty sure that every time i'm hitting the up, down, left and right arrows on the keyboard, i'm changing the model Matrix of the Player and not the others.
       
      Window Class:
      #include "Window.h" #include <GL/glew.h> #include <GLFW/glfw3.h> #include "Error.h" #include "Renderer.h" #include "Scene.h" #include "Input.h" //Global Variables. int screen_width, screen_height; //On Window Resize. void OnWindowResize(GLFWwindow *window, int width, int height); //Implementation Structure. struct Window::Implementation { //GLFW Window. GLFWwindow *GLFW_window; //Renderer. Renderer *renderer; //Delta Time. double delta_time; //Frames Per Second. int fps; //Scene. Scene *scnene; //Input. Input *input; //Deconstructor. ~Implementation(); }; //Window Constructor. Window::Window(std::string title, int width, int height) { //Initializing width and height. screen_width = width; screen_height = height; //Create Pointer To Implementation. m_Impl = new Implementation(); //Try initializing GLFW. if (!glfwInit()) { std::cout << "GLFW could not be initialized!" << std::endl; std::cout << "Press ENTER to exit..." << std::endl; std::cin.get(); exit(-1); } //Setting up OpenGL Version 3.3 Core Profile. glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, 3); glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, 3); glfwWindowHint(GLFW_OPENGL_PROFILE, GLFW_OPENGL_CORE_PROFILE); /* Create a windowed mode window and its OpenGL context */ m_Impl->GLFW_window = glfwCreateWindow(width, height, title.c_str(), NULL, NULL); if (!m_Impl->GLFW_window) { std::cout << "GLFW could not create a window!" << std::endl; std::cout << "Press ENTER to exit..." << std::endl; std::cin.get(); glfwTerminate(); exit(-1); } /* Make the window's context current */ glfwMakeContextCurrent(m_Impl->GLFW_window); //Initialize GLEW. if(glewInit() != GLEW_OK) { std::cout << "GLEW could not be initialized!" << std::endl; std::cout << "Press ENTER to exit..." << std::endl; std::cin.get(); glfwTerminate(); exit(-1); } //Enabling Blending. GLCall(glEnable(GL_BLEND)); GLCall(glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA)); //Setting the ViewPort. GLCall(glViewport(0, 0, width, height)); //**********Initializing Implementation**********// m_Impl->renderer = new Renderer(); m_Impl->delta_time = 0.0; m_Impl->fps = 0; m_Impl->input = new Input(this); //**********Initializing Implementation**********// //Set Frame Buffer Size Callback. glfwSetFramebufferSizeCallback(m_Impl->GLFW_window, OnWindowResize); } //Window Deconstructor. Window::~Window() { delete m_Impl; } //Window Main Loop. void Window::MainLoop() { //Time Variables. double start_time = 0, end_time = 0, old_time = 0, total_time = 0; //Frames Counter. int frames = 0; /* Loop until the user closes the window */ while (!glfwWindowShouldClose(m_Impl->GLFW_window)) { old_time = start_time; //Total time of previous frame. start_time = glfwGetTime(); //Current frame start time. //Calculate the Delta Time. m_Impl->delta_time = start_time - old_time; //Get Frames Per Second. if (total_time >= 1) { m_Impl->fps = frames; total_time = 0; frames = 0; } //Clearing The Screen. m_Impl->renderer->Clear(0, 0, 0); //Render The Scene. if (m_Impl->scnene != NULL) m_Impl->scnene->Render(this); //Updating the Screen. m_Impl->renderer->Update(m_Impl->GLFW_window); //Increasing frames counter. frames++; //End Time. end_time = glfwGetTime(); //Total time after the frame completed. total_time += end_time - start_time; } //Terminate GLFW. glfwTerminate(); } //Load Scene. void Window::LoadScene(Scene * scene) { //Set the scene. m_Impl->scnene = scene; } //Get Delta Time. double Window::GetDeltaTime() { return m_Impl->delta_time; } //Get FPS. int Window::GetFPS() { return m_Impl->fps; } //Get Width. int Window::GetWidth() { return screen_width; } //Get Height. int Window::GetHeight() { return screen_height; } //Get Input. Input * Window::GetInput() { return m_Impl->input; } Renderer * Window::GetRenderer() { return m_Impl->renderer; } GLFWwindow * Window::GetGLFWindow() { return m_Impl->GLFW_window; } //Implementation Deconstructor. Window::Implementation::~Implementation() { delete renderer; delete input; } //OnWindowResize void OnWindowResize(GLFWwindow *window, int width, int height) { screen_width = width; screen_height = height; //Updating the ViewPort. GLCall(glViewport(0, 0, width, height)); }  
      Brain Class
      #include "Brain.h" #include "Sprite.h" #include "Window.h" struct Brain::Implementation { //Just A Flag. bool started; //Window Pointer. Window *window; //Sprite Pointer. Sprite *sprite; }; Brain::Brain(Window *window, Sprite *sprite) { //Create Pointer To Implementation. m_Impl = new Implementation(); //Initialize Implementation. m_Impl->started = true; m_Impl->window = window; m_Impl->sprite = sprite; } Brain::~Brain() { //Delete Pointer To Implementation. delete m_Impl; } void Brain::Start() { } void Brain::Update() { } Window * Brain::GetWindow() { return m_Impl->window; } Sprite * Brain::GetSprite() { return m_Impl->sprite; } bool Brain::GetStart() { return m_Impl->started; } void Brain::SetStart(bool value) { m_Impl->started = value; } Script Class (Its a Brain Subclass!!!)
      #include "Script.h" Script::Script(Window *window, Sprite *sprite) : Brain(window, sprite) { } Script::~Script() { } void Script::Start() { std::cout << "Game Started!" << std::endl; } void Script::Update() { Input *input = this->GetWindow()->GetInput(); Sprite *sp = this->GetSprite(); //Move this sprite. this->GetSprite()->Move(200 * this->GetWindow()->GetDeltaTime(), input->GetKeyDown("left"), input->GetKeyDown("right"), input->GetKeyDown("up"), input->GetKeyDown("down")); std::cout << sp->GetTag().c_str() << ".x = " << sp->GetPos()->x << ", " << sp->GetTag().c_str() << ".y = " << sp->GetPos()->y << std::endl; }  
      Main:
      #include "SpaceShooterEngine.h" #include "Script.h" int main() { Window w("title", 600,600); Scene *scene = new Scene(); Sprite *player = new Sprite("Resources/Images/player.png", "Player", 100,100); Sprite *other = new Sprite("Resources/Images/cherno.png", "Other", 400, 100); Sprite *other2 = new Sprite("Resources/Images/cherno.png", "Other", 300, 400); Brain *brain = new Script(&w, player); player->AddBrain(brain); scene->AddSprite(player); scene->AddSprite(other); scene->AddSprite(other2); w.LoadScene(scene); w.MainLoop(); return 0; }  
       
      I literally can't find what is wrong. If you need more code, ask me to post it. I will also attach all the source files.
      Brain.cpp
      Error.cpp
      IndexBuffer.cpp
      Input.cpp
      Renderer.cpp
      Scene.cpp
      Shader.cpp
      Sprite.cpp
      Texture.cpp
      VertexArray.cpp
      VertexBuffer.cpp
      VertexBufferLayout.cpp
      Window.cpp
      Brain.h
      Error.h
      IndexBuffer.h
      Input.h
      Renderer.h
      Scene.h
      Shader.h
      SpaceShooterEngine.h
      Sprite.h
      Texture.h
      VertexArray.h
      VertexBuffer.h
      VertexBufferLayout.h
      Window.h
  • Advertisement
×

Important Information

By using GameDev.net, you agree to our community Guidelines, Terms of Use, and Privacy Policy.

Participate in the game development conversation and more when you create an account on GameDev.net!

Sign me up!