I'll include the entirety of the code I have so far, because I've ran over it and over it and over it and can't find what I'm doing wrong.
First, I'll describe the intention, where I'm at, and what's happening.
My intention, is ultimately, to set a bool on a Unit class that is checked in it's MoveToDestination(), to determine if the rest of the function runs. The trigger for this will be either Unit AI or player input of a mouse click.
For now, because retrieving the mouse click is trivial, I'm just setting the Unit's sprite (Unit::GFX) destination to the current mouse position as a simplified placeholder to help debug this (what I thought would be simple) bit of code.
The runtime behavior I'm getting, that I've looked at over and over again and cannot figure out the cause of, is that the sprite is repeatedly drawn between two locations; the RenderWindow's (0,0) and where it would be drawn at if the code functioned as intended. I've scoured this repeatedly and cannot figure out where a 0 is, periodically, getting multiplied into the X and Y deltas for the sprite's movement.
As a note, this behavior occurs in my complete code and this heavily stripped down code. These bits reproduce any of the functions related to the Unit class's movement, as well as the basic gameloop function (or not entirely basic...sorry if the framerate stuff is in the way of the problem...included it though because I'm not sure if it IS the problem).
Anyways, here are the pieces of code utilized;
First, the game's main .ccp
#include "stdafx.h"
#include "Units.h"
void Startup();
void GameLoop();
sf::RenderWindow Window;
sf::RenderWindow& GameWindow = Window;
sf::Vector2f MouseCoords;
void Startup() //will eventually call a splash screen and then the title menu
{
std::cout<<"Temporary filler for a splash screen.\n";
std::vector<sf::VideoMode> mode = sf::VideoMode::getFullscreenModes();
GameWindow.create(mode[0], "Chronicle", sf::Style::Fullscreen);
GameWindow.clear(sf::Color::White);
GameLoop();
}
void GameLoop() //
{
//Framerate management here
sf::Clock RenderClock, UpdateClock;
sf::Time UpdateTime;
//Player Input Event
sf::Event PlayerInput;
//Player Object
Unit Player;
Unit& PC = Player;
//Player Start Position
PC.GFX.setPosition(650,350);
while(GameWindow.isOpen())
{
GameWindow.clear(sf::Color::Green);
//more framerate management
const long long int FrameTime = 16667;
sf::Time t=RenderClock.getElapsedTime();
long long int nextFrameTime = t.asMicroseconds()+FrameTime;
int loops = 0;
while(t.asMicroseconds()<nextFrameTime && loops < 10)
{
//PlayerInput
//goes here
/*
basic interfact idea is that a left mouse click will move the character towards a position, or move and attack an enemy if targeted, or attack
at range with a bow, etc.
a right click will perform a large variety of special attacks and spells that the player can change through a menu interface...hotkey S
Hotkeys at present are not planned for implementation until a basic combat system is in place and working.
*/
while(GameWindow.pollEvent(PlayerInput))
{
//Close Game
if(PlayerInput.type == sf::Event::Closed || sf::Keyboard::isKeyPressed(sf::Keyboard::Escape))
GameWindow.close();
//Set Movement Point
if(PlayerInput.type==sf::Event::MouseLeft)
{
//Player.SetDestination(sf::Mouse::getPosition());
}
}
//process events here
//no more than setting the bools and numbers for updating frames, positions, stats, etc., and testing if a spell/ability is ready to produce its effect
MouseCoords=sf::Vector2f::Vector2(sf::Mouse::getPosition());
PC.SetDestination(MouseCoords);
PC.SetVelocity();
PC.GFX.setPosition(PC.MoveRatio.x*UpdateTime.asMicroseconds(),PC.MoveRatio.y*UpdateTime.asMicroseconds());
//this is where units are all tested against the range of AoE effects (spell effect will check if unit is in range and target as appropriate)
//these two functions produce a movement factor for each loop of updating
UpdateTime=UpdateClock.getElapsedTime();
UpdateClock.restart();
//draw units here
GameWindow.draw(Player.GFX);
t=RenderClock.getElapsedTime();
loops++;
}
GameWindow.display();
}
return;
}
int _tmain(int argc, _TCHAR* argv[])
{
Startup();
return 0;
}
The stripped down Unit class to debug movement problem:
#pragma once
#include "stdafx.h"
class Unit
{
public:
Unit();
void SetDestination(sf::Vector2f& Mousey); //used to set unit's destination with a mouse click
void SetVelocity(); //alters the angle of a unit's movement, as well as the ratio of change between x and y
sf::Vector2f MoveRatio;
sf::Sprite GFX;
protected:
private:
sf::Vector2f Location;
sf::Image Base;
sf::Texture Text;
sf::Vector2f Destination;
float Speed;
};
and lastly, the Unit.cpp file.
#include "stdafx.h"
#include "Units.h"
void Unit::SetVelocity() //something in here is the problem...I think...might also be a problem with grabbing the mouse position?
{
//Initialize
Location.x = GFX.getPosition().x;
Location.y = GFX.getPosition().y;
float DX = Destination.x-Location.x;
float DY = Destination.y-Location.y;
float RadAngle = atan(DY/DX);
//Rotate sprite
GFX.setRotation((RadAngle*180.0)/3.14159); //works always
//Normalize
float Distance = sqrt(DX*DX+DY*DY);
if(Distance != 0)
{
DX /= Distance;
DY /= Distance;
}
//Normalized Move Ratio
MoveRatio.x = cos(RadAngle)*DX;
MoveRatio.y = sin(RadAngle)*DY;
MoveRatio.x *= (Speed/1000);
MoveRatio.y *= (Speed/1000);
return;
}
void Unit::SetDestination(sf::Vector2f& MouseClicker) //DON'T FORGET TO CHANGE CALL TO USE MOUSECLICK LATER!!!
{
Destination.x = MouseClicker.x;
Destination.y = MouseClicker.y;
return;
}
Unit::Unit()
{
//simplified graphics, don't forget to implement the animation sprite later on
Base.loadFromFile("GFX/fight_still.png");
Base.createMaskFromColor(sf::Color::White);
Text.loadFromImage(Base);
GFX.setTexture(Text);
Speed=96.0000; //adjust later as needed
}
If anyone can help me identify the source of the problem, I would appreciate it in absurd ways...like, you'll be thanked in the credits of anything I ever do.