Hi,
I'm working on an ant simulation project for school. I'm trying to recreate this youtube video
https://youtu.be/X-iSQQgOd1A?t=329. At the moment my ant goes in one direction and never changes steering whatever variable I change (maxSpeed, steerStrength, wanderStrength, etc.)... It's my first SFML project so I don't know if I got something wrong in the ant movement logic or wrong use of SFML methods. Any help is appreciated! Thanks.
(I attached theresoruce files if anyone wants to try.)
Here is the code:
#include <SFML/Graphics.hpp>
#include <vector>
#include <iostream>
#include <math.h>
#include <Windows.h>
#define M_PI 3.141592653
#define rad2deg 360 / (M_PI * 2)
sf::Vector2f position, velocity, desiredDirection, oneandone(1.0f, 1.0f);
int ct = 0;
float sqrMagnitudeFunc(sf::Vector2f vector){
return vector.x * vector.x + vector.y * vector.y;
}
sf::Vector2f ClampMagnitude(sf::Vector2f vector, float maxLength)
{
float sqrMagnitude = sqrMagnitudeFunc(vector);
if (sqrMagnitude > maxLength * maxLength)
{
float mag = (float)sqrt(sqrMagnitude);
float normalized_x = vector.x / mag;
float normalized_y = vector.y / mag;
return sf::Vector2f(normalized_x * maxLength,
normalized_y * maxLength);
}
return vector;
}
sf::Vector2f normalize(const sf::Vector2f &source){
float length = sqrt((source.x * source.x) + (source.y * source.y));
if (length != 0)
return sf::Vector2f(source.x / length, source.y / length);
else
return source;
}
sf::Vector2f randPoint(float rad, float xc, float yc) {
//srand(420);
float ang, hyp, adj, opp;
ang = (float)rand() / RAND_MAX * 2 * M_PI;
hyp = sqrt((float)rand() / RAND_MAX) * rad;
adj = cos(ang) * hyp;
opp = sin(ang) * hyp;
sf::Vector2f v(xc + adj, yc + opp);
return v;
}
void draw(std::vector<sf::Sprite> &shapes, sf::RenderWindow &window) {
for (auto s : shapes) {
window.draw(s);
//std::cout << s.getPosition().x << " " << s.getPosition().y << std::endl;
}
}
void move(std::vector<sf::Sprite> &shapes, sf::Time dt, sf::RenderWindow &window) {
float maxSpeed = 0.5;
float steerStrength = 2;
float wanderStrength = 1;
std::cout << ct << std::endl;
for (auto& s : shapes) {
desiredDirection = normalize(desiredDirection + randPoint(1.0, 0.0, 0.0) * wanderStrength);
sf::Vector2f desiredVelocity = desiredDirection * maxSpeed;
sf::Vector2f desiredSteeringForce = (desiredVelocity - velocity) * steerStrength;
sf::Vector2f acceleration = ClampMagnitude(desiredSteeringForce, steerStrength);
//std::cout << desiredDirection.x << " direction " << desiredDirection.y << std::endl;
//std::cout << acceleration.x << " acc " << acceleration.y << std::endl;
velocity = ClampMagnitude(velocity + acceleration * dt.asSeconds(), maxSpeed);
//std::cout << dt.asSeconds() << "delta" << std::endl;
position += velocity * dt.asSeconds();
//std::cout << velocity.x <<" "<<velocity.y << std::endl;
float angle = (float)atan2(velocity.y, velocity.x) * (float)rad2deg;
s.setPosition(position.x + s.getPosition().x, position.y + s.getPosition().y);
s.setRotation(angle + 90);
std::cout << position.x << " " << position.y << " " <<angle << std::endl;
}
}
int main()
{
sf::RenderWindow window(sf::VideoMode(1280, 720), "Mravi9000");
std::vector<sf::Sprite> shapes;
//mravinjak
sf::Texture tMravinjak;
if (!tMravinjak.loadFromFile("res/marker.png"))
return -1;
tMravinjak.setSmooth(true);
sf::Sprite sMravinjak;
sMravinjak.setTexture(tMravinjak);
sMravinjak.setScale(1.5f, 1.5f);
sMravinjak.setColor(sf::Color(165, 42, 42));
sMravinjak.setPosition(1280/2 - tMravinjak.getSize().x / 2 * 1.5f, 720 / 2 - tMravinjak.getSize().y / 2 * 1.5f);
//mrav
sf::Texture tMrav;
if (!tMrav.loadFromFile("res/ant_2.png"))
return -1;
tMrav.setSmooth(true);
sf::Sprite sMrav;
sMrav.setTexture(tMrav);
sMrav.setScale(0.2f, 0.2f);
sMrav.setColor(sf::Color(255, 0, 0));
sMrav.setPosition(1280 / 2 - tMrav.getSize().x / 2 * 0.2f, 720 / 2 - tMrav.getSize().y / 2 * 0.2f);
sMrav.setOrigin(tMrav.getSize().x / 2 * 0.2f, tMrav.getSize().y / 2 * 0.2f);
std::cout << 1280 / 2 - tMrav.getSize().x / 2 * 0.2f << " " << 720 / 2 - tMrav.getSize().y / 2 * 0.2f << std::endl;
shapes.push_back(sMrav);
sf::Vector2f v;
sf::Clock deltaClock;
while (window.isOpen()){
sf::Event event;
while (window.pollEvent(event)){
if (event.type == sf::Event::Closed)
window.close();
}
//clear
window.clear(sf::Color(49,99,0));
window.draw(sMravinjak);
//moving
move(shapes, deltaClock.getElapsedTime(), window);
draw(shapes, window);
v = randPoint(1.0, 0.0, 0.0);
//std::cout << v.x << " " << v.y << std::endl;
//display
window.display();
deltaClock.restart();
}
return 0;
}