Glydion

Members
  • Content count

    28
  • Joined

  • Last visited

Community Reputation

117 Neutral

About Glydion

  • Rank
    Member

Personal Information

Social

  • Steam
    glydion
  1. Hey Satharis, Thanks for providing a prototype of how to implement the "swap and pop" method with respect to the code I provided. It really helped me understand how to delete the desired missile, and now the missiles are popped out properly and they are now being deleted to free the memory, hopefully preventing any memory leaks. Since this is just a "version 1" of this Missile Command game, I'm okay with swap and pop to remove missiles at this point as I will be returning to this game a tiny bit later and re-factoring it (as AlphaProgDes recommends in his article). I'll practice "iterating" through the vector the second time around, as per Beer Nut's suggestion. Yeah, so the issue was indeed the fact that "pop_back" on its own just removes the last missile that was added at the end, without realizing that the missile I wanted deleted was the "older" missile that was already in the vector container. I'll be moving on to creating and managing falling asteroids next as part of the Missile Command game, and I'll post an update later on once I've made progress. Thanks to everyone who posted a response to help me out, I'm going to read up on memory management until I understand it. Have a good night.
  2. Hey Marcus, Oh right, pop_back removes the last element, which is not the first Missile if I click the left button more than once, hmmm. I actually tried to place a delete statement in my code after destroyNow is set to true, but then I figured out that newMissile only exists within the scope of the if( isFiring == true ) block and falls out of scope when the If block is done, so I pushed it into the Vector in the code above because I didn't want the missile to be lost (that was my thinking at the time). And my program freezes if I try to call delete missileVec within the loop so yes, I seriously have to reconsider my Missile container. Hi Satharis, I wasn't kidding when I said I was an absolute beginner, and I would have never realized what I was doing without someone pointing it out for me. As I mentioned to Marcus, my worry with newMissile was that it would be out of scope as soon as the isFiring IF block was completed, which is why I thought that adding it to the vector was the only way to save the missile data so I can update it in a For loop further down. I didn't even consider that I had two pointers instead of just one, so thanks for letting me know. That also lended itself to my delete issue with a missile that was to be destroyed, I tried earlier to call destroy missileVec but it just ends up crashing the program. So I need to figure out how to delete the memory after popping off the pointers. The "swap and pop" method for deleting objects from a vector sounds like a good idea and I would get some good practice in to implement it in my game. I'll give it a shot. But first things first, I'll have to look at how to free the memory for destroyed missiles. Yes, I definitely need to research memory management. Can you clarify what you mean by ownership in this context? Thank you. Hello Smoker, I'm not 100% sure what you mean. The missile destructor frees the memory that was used by its own missile texture upon deletion. Don't objects have to be responsible for deleting their own resources? Please clarify. Yes, I do load the same texture every time a new missile is created. Hmmm, how would I go about loading the texture only one time if a missile is created when a Left mouse click occurs? I can't seem to visualize how to load the missile texture only once if I'm calling the constructor with each new missile. Thanks.
  3. I loved this article. I'm actually following it right now and I've been at it since March of this year. Currently on Missile Command.
  4. Hi everyone, an update to the new bug in my program. I can't seem to figure out why all the missiles are popping out of the vector at the exact same time. Here's another GIF to illustrate and the pertinent code below. https://i.imgur.com/4dZjEJv.gifv The only case where the missiles don't all disappear concurrently is if the first missile path is very far away from the cannon, as shown in the 1st launch test in the GIF above. In this example, I'm able to get 4 quick shots off before the original 1st missile reaches the top of the screen. Here's what I got for code: Game.cpp void Game::Update(float delta) { // Game logic int mX, mY; SDL_GetMouseState(&mX,&mY); float vectorX = mX - cannon->x; float vectorY = mY - cannon->y; SetCannonAngle( vectorX, vectorY ); if( isFiring == true ) { Missile* newMissile = new Missile(renderer, cannon->x, cannon->y, clickedX, clickedY); missileVec.push_back(newMissile); isFiring = false; } // If there are missiles in the vector container, set their direction // angle, fire them and update the missile positions for( int i = 0; i < missileVec.size(); i++ ) { float targetX = missileVec[i]->endX - missileVec[i]->x; float targetY = missileVec[i]->endY - missileVec[i]->y; missileVec[i]->angle = SetMissileAngle(targetX,targetY); missileVec[i]->Update(delta); if( missileVec[i]->destroyNow == true ) { missileVec.pop_back(); } } } Missile.cpp void Missile::Update(float delta) { // Call move function Move(); // If the missile is moving, // update its position this->x += directionX * speed * delta; this->y += directionY * speed * delta; // If the missile goes BEYOND the // destination x and y (endX and endY), // set the missile's position to endX // and endY and stop movement if( sqrt( pow( this->x - startX, 2) + pow( this->y - startY, 2) ) >= distance ) { this->x = endX; this->y = endY; this->destroyNow = true; } } As per the above code, each missile has a Boolean destroy flag (destroyNow) that signals when to pop the missile out of the vector, which I have set to when the missile reaches its destination on the screen. So this works when the first missile has to travel a longer distance than the subsequent missiles that succeed it, but when the first missile has a short path and then you click the Left mouse button to set a longer path for the next missile, both of them are popped out of the vector and disappear at the same time, when their destruction should be independent of each other. I've been racking my brain trying to figure it out for 2 days' straight so my brain is now mush lol. How would you all go about removing missiles independently of each other given my code above? I appreciate all feedback, thank you in advance.
  5. Hey guys, just wanted to update on this topic. Lactose hit the nail right on the head, as soon as I passed the clickedX and clickedY into the constructor, the missiles no longer "re-aligned" themselves to the next missile but continued on their original path niiiice. Here's an animated GIF for a visual: https://i.imgur.com/2ZsL5in.gifv Now I have a new bug hehe, all of the missiles, regardless of how many have been fired, will all be destroyed (disappear) at the exact same time lol. Let me try to fix that and I'll post an update about it later. Thanks again to all who responded. Have a good one.
  6. Hey Alpha! Thank you for writing that article about the journey for beginner programmers and the 10 "must make" games to break into the industry. It has been a big inspiration for me in my journey to become a 2D game programmer so far and has helped me not get burnt out when learning this stuff. It's been a great way to learn how to program 2D games incrementally and I've found it is easy to stay motivated with this model of progress. My dream is to start my own indie company, Glydion, and make my own 2D games that remind players of the 16-bit era (Super Nintendo, Sega, Neo-Geo, etc.) which is where my passion is. Yes lol, I'll make this "homing" feature a powerup for when I go through these 10 games again and make (version 2.0) versions of these games in the future. Hey Lactose, thank you for your feedback. Yeah I think you're right, I do seem to be commenting on lines that are pretty self-explanatory, which must make it hard for others to sift through it. I think I took that "comment everywhere" feedback from my early programming courses too seriously lol . Hmm, I've never thought of passing the clickedX and clickedY in the missile constructor. I'll change it up with your suggestions and run some tests. Thank you. Hey Marcus! Hope you've been doing well, friend. I didn't even realize that the code I inserted was in HTML hehe. I've changed it to C++ now for enhanced readability. My bad.
  7. Hey everybody, A little over a month ago, I made a post asking for help with my Missile Command game that I was making with regards to getting the Cannon to angle properly, and I was very pleased with all of the support. It really lit a fire under me (even moreso before I worked up the courage to ask the first time). Well, the game is not finished yet, but I have made a lot of progress since then ( it's very motivating ) and I've been able to work through the code and logic for shooting missiles from the cannon. The missile logic is almost ready, but there is one small bug that I discovered last week that has been wracking my brain non-stop, so I'm posting a new topic here. Here is an animated GIF of the missile behavior so far, in this shot, it's working as expected when you click the Left mouse button to fire one missile at a time: https://i.imgur.com/WyM2oxi.gifv But what I didn't expect to happen, was here, when you click the Left button to fire a new missile when the other missile is still in transit: https://i.imgur.com/PFJTDV1.gifv When the next missile is fired, the original missile changes course, re-angles itself and flies towards the next clicked spot, abandoning it's first clicked target, which is not what I wanted lol. It's like the missiles turn into smart missiles all of a sudden. The good news is that they're being destroyed when they hit the spot anyways, so that's something. So, for anyone reading this post, how can I make the previous missiles stay on their original target, even if I click the mouse to summon a new missile? Each missile's path should be independent of each other. This will also play into the logic for the upcoming falling Asteroid class I'll be adding, so solving this one for me will also allow me to make independent asteroids and I'm almost done the game! lol Here's the code: Game.h #ifndef GAME_H_ #define GAME_H_ // Preprocessors #include "SDL.h" #include "SDL_image.h" #include "SDL_ttf.h" #include "SDL_mixer.h" #include <iostream> #include <sstream> #include <stdio.h> #include <math.h> #include <cmath> #include <vector> // Inclusions for game objects #include "Cannon.h" #include "Missile.h" #include "Ground.h" #include "Silo.h" #define FPS_DELAY 500 #define SCREEN_WIDTH 800 #define SCREEN_HEIGHT 600 #define MAX_ROTATION 0 #define MIN_ROTATION 180 #define DEG_TO_RAD(deg) degrees * ( 3.141592653589793238 / 180) #define RAD_TO_DEG(rad) radians * ( 180 / 3.141592653589793238 ) #define OVER_PI ( 180 / 3.141592653589793238 ) class Game { public: Game(); ~Game(); bool Init(); void Run(); private: SDL_Window* window; SDL_Renderer* renderer; SDL_Texture* texture; // Timing unsigned int lastTick, fpsTick, fps, frameCount; // Test float testX, testY; /* Fonts for testing */ TTF_Font* fontMouseX; TTF_Font* fontMouseY; TTF_Font* fontCannonAngle; TTF_Font* fontFire; TTF_Font* fontAmmo; std::stringstream xValue; std::stringstream yValue; std::stringstream angleValue; std::stringstream fireValue; std::stringstream ammoValue; SDL_Texture* xTexture; SDL_Texture* yTexture; SDL_Texture* aTexture; SDL_Texture* fTexture; SDL_Texture* ammoTexture; int xWidth, xHeight, yWidth, yHeight, aWidth, aHeight; int fWidth, fHeight, ammoWidth, ammoHeight; /* END */ // Game objects Cannon* cannon; // The cannon, both the pipe and the base std::vector<Missile*> missileVec; // A vector of missiles Silo* silo; Ground* ground; // The ground SDL_Cursor* cursor; // The crosshair cursor // Flag to check if the cannon // is currently firing a missile bool isFiring; int clickedX; int clickedY; void Clean(); // Cleanup function void Update(float delta); // Update game elements void Render(float delta); // Render game elements void NewGame(); // Start a new game void SetCannonAngle( float vecX, float vecY); // Set the angle of cannon pipe double SetMissileAngle( float vecX, float vecY); // Set the angle of missile double ConvertDegrees(double radians); // Convert radians to degrees double ConvertRadians(double degrees); // Convert degrees to radians void ExplodeMissile(); // Explode the missile once it // has reached the target void CheckAsteroidCollisions(); // See if missile hits asteroid void CheckSiloCollisions(); // See if asteroid hits silo int GetSiloCount(); // Check if there are silos remaining }; #endif // GAME_H_ Game.cpp #include "Game.h" Game::Game() { window = 0; renderer = 0; } Game::~Game() { } bool Game::Init() { // Initialize the SDL video and audio subsystems SDL_Init(SDL_INIT_VIDEO | SDL_INIT_AUDIO); // Create window window = SDL_CreateWindow("Missile Command v1.0", SDL_WINDOWPOS_CENTERED, SDL_WINDOWPOS_CENTERED, 800, 600, SDL_WINDOW_SHOWN | SDL_WINDOW_OPENGL); if(!window) { std::cout << "Error creating window: " << SDL_GetError() << std::endl; return false; } // Create renderer renderer = SDL_CreateRenderer(window, -1, SDL_RENDERER_ACCELERATED); if(!renderer) { std::cout << "Error creating renderer: " << SDL_GetError() << std::endl; return false; } // Enable TTF loading TTF_Init(); // Load the fonts fontMouseX = TTF_OpenFont("lato.ttf", 14); fontMouseY = TTF_OpenFont("lato.ttf", 14); fontCannonAngle = TTF_OpenFont("lato.ttf", 14); fontFire = TTF_OpenFont("lato.ttf", 14); fontAmmo = TTF_OpenFont("lato.ttf", 14); // Initialize resources SDL_Surface* surface = IMG_Load("test.png"); texture = SDL_CreateTextureFromSurface(renderer,surface); SDL_FreeSurface(surface); // Set mouse cursor to crosshair cursor = SDL_CreateSystemCursor(SDL_SYSTEM_CURSOR_CROSSHAIR); SDL_SetCursor(cursor); // Initialize timing lastTick = SDL_GetTicks(); fpsTick = lastTick; fps = 0; // Set starting FPS value frameCount = 0; // Set starting frame count testX = 0; testY = 0; return true; } void Game::Clean() { // Clean resources SDL_DestroyTexture(texture); SDL_FreeCursor(cursor); SDL_DestroyRenderer(renderer); SDL_DestroyWindow(window); // Clean test data SDL_DestroyTexture(xTexture); SDL_DestroyTexture(yTexture); SDL_DestroyTexture(aTexture); SDL_DestroyTexture(fTexture); SDL_DestroyTexture(ammoTexture); } void Game::Run() { // Create game objects cannon = new Cannon(renderer); ground = new Ground(renderer); silo = new Silo(renderer); // Start a new game NewGame(); // Main loop while(1) { // Event handler SDL_Event e; // If event is a QUIT event, stop the program if(SDL_PollEvent(&e)) { if(e.type == SDL_QUIT) { break; } // If a mouse button was pressed... else if(e.type == SDL_MOUSEBUTTONDOWN) { // If the left mouse button was pressed, // set the "fire" flag to TRUE and // record x,y position of click if(e.button.button == SDL_BUTTON_LEFT) { clickedX = e.button.x; clickedY = e.button.y; isFiring = true; } } } // Calculate delta and fps unsigned int curTick = SDL_GetTicks(); float delta = (curTick - lastTick) / 1000.0f; // Cap FPS delay to specific amount if(curTick - fpsTick >= FPS_DELAY) { fps = frameCount * (1000.0f / (curTick - fpsTick)); fpsTick = curTick; frameCount = 0; //std::cout << "FPS: " << fps << std::endl; char buf[100]; snprintf(buf,100,"Missile Command v1.0 (fps: %u)", fps); SDL_SetWindowTitle(window,buf); } else { frameCount++; } lastTick = curTick; // Update and render the game Update(delta); Render(delta); } delete cannon; //missileVec.clear(); delete ground; delete silo; Clean(); // Close the fonts TTF_CloseFont(fontMouseX); TTF_CloseFont(fontMouseY); TTF_CloseFont(fontCannonAngle); TTF_CloseFont(fontFire); TTF_CloseFont(fontAmmo); TTF_Quit(); SDL_Quit(); } void Game::NewGame() { } void Game::Update(float delta) { // Game logic // Input, get mouse position to determine // the cannon pipe's angle for rendering int mX, mY; SDL_GetMouseState(&mX,&mY); // Assign the vector to variables float vectorX = mX - cannon->x; float vectorY = mY - cannon->y; // "Snap" the cannon angle to the angle between // cannon and mouse SetCannonAngle( vectorX, vectorY ); // If cannon is firing, create a missile and add // it to the missile vector container, and set // "isFiring" to false again if( isFiring == true ) { Missile* newMissile = new Missile(renderer, cannon->x, cannon->y); missileVec.push_back(newMissile); isFiring = false; } // If there are missiles in the vector container, set their direction // angle, fire them and update the missile positions for( int i = 0; i < missileVec.size(); i++ ) { // Update the missile's trajectory upon travel missileVec[i]->endX = clickedX; missileVec[i]->endY = clickedY; // Set a vector between the clicked location // and the missile float targetX = clickedX - missileVec[i]->x; float targetY = clickedY - missileVec[i]->y; // Set facing angle for missile missileVec[i]->angle = SetMissileAngle(targetX,targetY); // Update the missile's position missileVec[i]->Update(delta); // If the missile is triggered to be destroyed, // destroy it if( missileVec[i]->destroyNow == true ) { // Remove the destroyed missile // from the vector missileVec.pop_back(); } } /*// If there are no more silos, // start a new game if(GetSiloCount() == 0) { NewGame(); }*/ // Check if the cannon has fired a missile //cannon->missile->Update(delta, mX - cannon->x, mY - cannon->y); /* Test Data */ // Stream the X, Y, Angle and isFired values xValue.str(""); // Clear the stream before piping the xValue xValue << "X: " << mX; yValue.str(""); // Clear the stream before piping the yValue yValue << "Y: " << mY; angleValue.str(""); // Clear the stream before piping the angleValue angleValue << "Angle: " << cannon->angle; fireValue.str(""); // Clear the stream before piping the fireValue fireValue << "isFiring: " << std::boolalpha << isFiring; ammoValue.str(""); // Clear the stream before piping the ammoValue ammoValue << "Missiles in Vector: " << missileVec.size(); // Set font color to WHITE SDL_Color textColor = {255,255,255}; //*************************************** // DEBUG - Prepare the fonts for testing //*************************************** // Render the X-coordinate text SDL_Surface* temp = TTF_RenderText_Solid( fontMouseX, xValue.str().c_str(), textColor ); xTexture = SDL_CreateTextureFromSurface( renderer, temp ); xWidth = temp->w; xHeight = temp->h; SDL_FreeSurface(temp); // Render the Y-coordinate text temp = TTF_RenderText_Solid( fontMouseY, yValue.str().c_str(), textColor ); yTexture = SDL_CreateTextureFromSurface( renderer, temp ); yWidth = temp->w; yHeight = temp->h; SDL_FreeSurface(temp); // Render the angle text temp = TTF_RenderText_Solid( fontCannonAngle, angleValue.str().c_str(), textColor ); aTexture = SDL_CreateTextureFromSurface( renderer, temp ); aWidth = temp->w; aHeight = temp->h; SDL_FreeSurface(temp); // Render the isFiring text temp = TTF_RenderText_Solid( fontFire, fireValue.str().c_str(), textColor ); fTexture = SDL_CreateTextureFromSurface( renderer, temp ); fWidth = temp->w; fHeight = temp->h; SDL_FreeSurface(temp); // Render the missileVec.size() text temp = TTF_RenderText_Solid( fontAmmo, ammoValue.str().c_str(), textColor ); ammoTexture = SDL_CreateTextureFromSurface( renderer, temp ); ammoWidth = temp->w; ammoHeight = temp->h; SDL_FreeSurface(temp); } void Game::SetCannonAngle(float vecX, float vecY) { // "Snap" cannon angle to angle where mouse // cursor is located in order to track it double theAngle = atan2(vecY, vecX); // Pass radian angle to convert to degrees theAngle = ConvertDegrees(theAngle); // Convert degrees format from -180 to 180 // to 0 to 360 if( theAngle < 0 ) { theAngle = 360 - (-theAngle); } if(theAngle > MAX_ROTATION && theAngle < 90) { cannon->angle = MAX_ROTATION; } else if(theAngle < MIN_ROTATION && theAngle > 90) { cannon->angle = MIN_ROTATION; } else { cannon->angle = theAngle; } } double Game::SetMissileAngle(float vecX, float vecY) { // "Snap" missile angle to angle where mouse // cursor is located in order to track it double theAngle = atan2(vecY,vecX); // Pass radian angle to convert to degrees theAngle = ConvertDegrees(theAngle); // Convert degrees format from -180 to 180 // to 0 to 360 if( theAngle < 0 ) { theAngle = 360 - (-theAngle); } return theAngle; } double Game::ConvertDegrees(double radians) { // Convert the angle from radians to // degrees and return the value return RAD_TO_DEG(rad); } double Game::ConvertRadians(double degrees) { // Convert the angle from degrees to // radians and return the value return DEG_TO_RAD(deg); } int Game::GetSiloCount() { int siloCount = 0; // If the current silo is still alive, // the game is not over if(silo->state) { siloCount = 1; } return siloCount; } void Game::Render(float delta) { // Clear the renderer SDL_RenderClear(renderer); // Render the game objects cannon->Render(delta); ground->Render(delta); silo->Render(delta); // If there is a missile in the vector, // render it for( int i = 0; i < missileVec.size(); i++ ) { missileVec[i]->Render(delta); } /* Setting source rectangles and then rendering the x, y and angle fonts */ // For x SDL_Rect rect; rect.x = 20; rect.y = 20; rect.w = xWidth; rect.h = xHeight; SDL_RenderCopy(renderer, xTexture, 0, &rect); // For y rect.x = 20; rect.y = 40; rect.w = yWidth; rect.h = yHeight; SDL_RenderCopy(renderer, yTexture, 0, &rect); // For angle rect.x = 20; rect.y = 60; rect.w = aWidth; rect.h = aHeight; SDL_RenderCopy(renderer, aTexture, 0, &rect); // For isFired rect.x = 20; rect.y = 80; rect.w = fWidth; rect.h = fHeight; SDL_RenderCopy(renderer, fTexture, 0, &rect); // For isFired rect.x = 20; rect.y = 100; rect.w = ammoWidth; rect.h = ammoHeight; SDL_RenderCopy(renderer, ammoTexture, 0, &rect); // Present the renderer to display SDL_RenderPresent(renderer); } Missile.h #ifndef MISSILE_H_INCLUDED #define MISSILE_H_INCLUDED #include "Entity.h" #include <math.h> class Missile : public Entity { public: Missile(SDL_Renderer* renderer, float cX, float cY); ~Missile(); void Update(float delta); void Render(float delta); void Fire(); void Move(); // Starting and ending positions for missile float startX, startY, endX, endY; float directionX, directionY; float distance, speed; // The missile's angle double angle; // Flag to have missile destroyed // when certain conditions are met bool destroyNow; private: SDL_Texture* texture; // Texture for missile SDL_Point center; }; #endif // MISSILE_H_INCLUDED Missile.cpp #include "Missile.h" Missile::Missile(SDL_Renderer* renderer, float cX, float cY) : Entity(renderer) { // Create missile texture SDL_Surface* surface = IMG_Load("images/missile.png"); texture = SDL_CreateTextureFromSurface(renderer,surface); SDL_FreeSurface(surface); // Set angle variable default, // width, height angle = 0.0f; width = 34; height = 13; // Set missile offset for positioning relative to cannon float xOffset = 8; // Set starting x,y position x = cX + xOffset; y = cY; // Set the missile's starting x and y position // and speed startX = x; startY = y; speed = 150; // Set the missile's center for rotation center.x = ( width / 2 ); center.y = ( height / 2 ); // Set destruction flag to false destroyNow = false; } Missile::~Missile() { // Clean resources SDL_DestroyTexture(texture); } void Missile::Move() { // Determine the distance from the starting // position to the ending position distance = sqrt( pow(endX - startX, 2) + pow(endY - startY, 2)); // Determine direction of movement directionX = (endX - startX) / distance; directionY = (endY - startY) / distance; } void Missile::Update(float delta) { // Call move function Move(); // If the missile is moving, // update its position this->x += directionX * speed * delta; this->y += directionY * speed * delta; // If the missile goes BEYOND the // destination x and y (endX and endY), // set the missile's position to endX // and endY and stop movement if( sqrt( pow( this->x - startX, 2) + pow( this->y - startY, 2) ) >= distance ) { this->x = endX; this->y = endY; this->destroyNow = true; } } void Missile::Render(float delta) { // Render the missile SDL_Rect rect; rect.x = (int)(x + 0.5f); rect.y = (int)(y + 0.5f); rect.w = width; rect.h = height; // Render the missile at given angle SDL_RenderCopyEx(renderer,texture,0,&rect,angle,&center,SDL_FLIP_NONE); } I appreciate any feedback, guys. Thanks in advance. Also, let me know if you need more information about this post and I can provide it when I can.
  8. Help with Missile Command

    Thanks for letting me know jpetrie, and I believe it's an awesome system for doing things, so others in the future can benefit from my post (and vice versa). Have a good one.
  9. Help with Missile Command

    Hey Marcus, Sorry for the delay, I'll use that to control the range of movement for the cannon, thank you. Ok Aero, if I need help in the future, I'll just post a new topic. Once this Missile Command game is ready for review, I'll submit a code review at that time. I appreciate everyone's help with my post. EDIT: I looked and apparently, there doesn't seem to be a way to close this post now that my issue has been solved. This may be intended behavior so I'll just let the post go stale by not posting to it anymore.
  10. Help with Missile Command

    Hey guys, here's an update on my Missile Command game: I did some sketches on graph paper to flesh out my thoughts so the logic wasn't so abstract for me, and after 2-3 days of just working through it, I finally got the cannon to follow the mouse! Yay! It's not perfect but it's a start. Here's a screenshot GIF of it: http://i.imgur.com/sEV0XKU.gifv Man that took me over 2 weeks to figure out, and I wanted to thank MarcusAseth, Aerodactyl55 and cmac for their wonderful feedback in helping me out. What finally got it to work was actually my center point, it was in the wrong position! Instead of the "center bottom" of the cannon pipe, I changed it to the dead center of the pipe (width / 2, height / 2), relative to the drawing rectangle of the cannon itself, called atan2 with the displacement between the mouse x and y and the cannon's actual x and y and voila it worked! Here's the updated code: Game.cpp void Game::Update(float delta) { // Game logic // Input, get mouse position to determine // the cannon pipe's angle for rendering int mX, mY; SDL_GetMouseState(&mX,&mY); // "Snap" the cannon angle to the angle between // cannon and mouse SetCannonAngle( mX - cannon->x, mY - cannon->y ); // If there are no more silos, // start a new game if(GetSiloCount() == 0) { NewGame(); } // Update the cannon's angle cannon->Update(delta); /* Test Data */ // Stream the X, Y, Angle and Center values xValue.str(""); // Clear the stream before piping the xValue xValue << "X: " << mX; yValue.str(""); // Clear the stream before piping the yValue yValue << "Y: " << mY; angleValue.str(""); // Clear the stream before piping the angleValue angleValue << "Angle: " << cannon->angle; // Set font color to WHITE SDL_Color textColor = {255,255,255}; //*************************************** // DEBUG - Prepare the fonts for testing //*************************************** // Render the X-coordinate text SDL_Surface* temp = TTF_RenderText_Solid( fontMouseX, xValue.str().c_str(), textColor ); xTexture = SDL_CreateTextureFromSurface( renderer, temp ); xWidth = temp->w; xHeight = temp->h; SDL_FreeSurface(temp); // Render the Y-coordinate text temp = TTF_RenderText_Solid( fontMouseY, yValue.str().c_str(), textColor ); yTexture = SDL_CreateTextureFromSurface( renderer, temp ); yWidth = temp->w; yHeight = temp->h; SDL_FreeSurface(temp); // Render the angle text temp = TTF_RenderText_Solid( fontCannonAngle, angleValue.str().c_str(), textColor ); aTexture = SDL_CreateTextureFromSurface( renderer, temp ); aWidth = temp->w; aHeight = temp->h; SDL_FreeSurface(temp); } This was the game changer - I initialized the center coordinates to the very center of the texture: Cannon.cpp // Set the cannon pipe's rotation pivot point, // relative to the cannon pipe center.x = (width / 2); center.y = (height / 2); After this, the angling worked. Now I have to figure out how to get the cannon to not angle beyond 0 and 180 degrees and stay above ground. Oh and I'm not sure if these coordinate values are correct or not, but when the angle is 45 degrees, it is facing bottom-right, straight down at 90, to the left at 180, top left at 225, straight up at 270 and top-right at 315 degrees respectively. Is this correct? EDIT: The above degrees were from my test data and not actually shown in the animated GIF. For some reason the angle value shows negative values for the angles, and right now I'm not sure how to convert that so it shows values from 0 to 360 degrees. As my game is not done, is it proper convention to continue the post? Or do I open a new post regarding the next logic challenge of my Missile Command game when I run into trouble? Once again, I appreciate everybody's help. I'll go to sleep now, goodnight.
  11. Help with Missile Command

    Hey Marcus, sorry it took a while to respond, it's been crazy the past few days. It's good to just have some graph paper and some pencils to start sketching this logic out, it's not as foreign as it was before thanks to all of the helpful responses so far. I'm getting closer, as cmac mentioned, I'm now inverting the y-coordinate for the mouse and I think I have to do the same for the cannon's center-y as well. Tonight when I get home, I'll try implementing this and see what happens.
  12. Help with Missile Command

    Ahhh, thanks for the great explanation cmac, I believe I'm beginning to get the hang of this. Yes I think I need to re-work my code as when the cannon angle is at 0, it actually is pointing straight up instead of the right. @MarcusAseth Hi Marcus, for some reason, once you discovered that my cannon's center was set to 16,48, I decided to change it to its position in the world coordinates, which is 401, 553, as per the following code: // Set the cannon pipe's rotation pivot point center.x = 401; center.y = 553; When I entered my center coordinates as per the above, the 'rotating' of the texture got messed up and the cannon actually rotated (in an arc) and flew away from the cannon base (lol) and only came back when I moved my mouse cursor to an arbitrary position, which wasn't right. I then decided to switch the cannon's center position to my original value here: // Set the cannon pipe's rotation pivot point center.x = (width / 2); center.y = height; When I switched the center back to my original values, the cannon stayed on the center and pivoted sub-normally (as per the original post) as it was taking the cannon pipe's x and then adding (center.x) to it and then moving down (center.y) to reach the bottom-middle of the cannon, though the angling was still not the one I wanted. I did some digging into my render function with rotate, SDL_RenderCopyEX, and I came to the conclusion that when rendering in this function, the parameter for center (SDL_Point) takes into account the cannon x,y coordinates as the origin and then locates 16,48 based off of the texture's destination rect of the texture being displayed, not the world coordinates, as per the wiki page for the function. int SDL_RenderCopyEx(SDL_Renderer* renderer, SDL_Texture* texture, const SDL_Rect* srcrect, const SDL_Rect* dstrect, const double angle, const SDL_Point* center, const SDL_RendererFlip flip) center - a pointer to a point indicating the point around which dstrect will be rotated (if NULL, rotation will be done around dstrect.w/2, dstrect.h/2) It must have been how SDL programmed this function. This is what I think. I'm getting closer to a solution to this issue so I'm pretty excited about that, but it's now 1am and my eyes are falling out, so I'll hit the hay for now.
  13. Help with Missile Command

    I did a lookup of the question and there's a nice explanation on sin/cos here when looking for direction vector. http://www.cplusplus.com/forum/beginner/49639/ Sorry I should have looked it up first before asking.
  14. Help with Missile Command

    Hey cmac, Yes, for this basic version of Missile Command, you're right I'm okay with snapping the cannon to the desired angle. When I've completed the game, I would like to tackle gradual rotation for more 'realism'. @Aerodactyl55 Hey Aerodactyl, I had a question about one of your last posts. I know understand the importance of having 2 vectors so I can get the angle between them. I know how to get the vector from cannon to cursor now, but how would I get the cannon's orientation for the second vector? When I initialized the cannon, I set it to a starting x and y and it pretty much just faces 'straight up' upon creation. Would this 'facing up' be its orientation in this context?
  15. Help with Missile Command

    Wow Marcus, that's one pretty big animated GIF lol. That's so neat, I can only imagine being able to do that right now, so I still have a ways to go. Yeah, you're right, I'm trying to figure out logic with so many objects and variables all at once, it's giving me a headache. Hey Aerodactyl (my favorite Pokemon btw), yes I was looking up other posts about angles and yes I found it odd that i was trying to get an angle from only one vector, as angles are between two vectors *slaps forehead*. I didn't factor in direction, which should be my other vector. Ok, I'll design a small program specifically for this logic issue (with 2 vector lines, not one) and just use basic shapes when I get home. Gracias.