16
General / Re: Space Invaders - Enemy Movement Logic
« on: November 21, 2019, 05:59:52 pm »
I have restructured the code, I will try and use vectors instead of arrays
This section allows you to view all posts made by this member. Note that you can only see posts made in areas you currently have access to.
// Default Constructor
Enemy::Enemy()
{
//set alive
mIsAlive = true;
//set speed
enemySpeed = 10.f;
// Load an enemy texture
if (!mEnemyTexture.loadFromFile("Media/Textures/PixelSpaceships/red_01.png")) {
// Handle loading error
std::cout << "Oh No! File not loaded." << std::endl;
}
//scale sprite and set texture so we know size
enemySprite.setTexture(mEnemyTexture);
}
// Enemy
Enemy alienArray[NUMBER_OF_ALIENS];
// Loading Enemy
enemy.enemyLoader(NUMBER_OF_ALIENS, alienArray);
void Enemy::enemyBehaviour(std::vector<sf::Sprite>& enemyList) {
float direction = 1.f;
//sf::Sprite tempEnemy;
sf::Vector2f enemyMovement(1.f, 0.f);
float yOffset = 50.f;
float xOffset = 60.f;
for (sf::Sprite& enemy : enemyList) // CAUTION & solved everything again - lesson in C++, if we don't get address, we always create a copy and modify it, which is not what we want
{
std::cout << "Direction before working move " << direction << std::endl;
enemy.move(enemyMovement * direction); // Issue detected direction only changing sign if greater or less than screen bounds once
if (enemy.getPosition().x + enemy.getLocalBounds().width / 2 >= 640.f ||
enemy.getPosition().x - enemy.getLocalBounds().width / 2 <= 0.f) { // can be improved by calling getWidth method
direction = -(direction);
enemy.setPosition(enemy.getPosition().x, enemy.getPosition().y + yOffset);
std::cout << "Direction inside if statement " << direction << std::endl;
//enemy.setPosition(enemy.getPosition().x, enemy.getPosition().y + yOffset); // y axis is inverted in SFML
return;
}
/*
if (enemy.getPosition().x - enemy.getLocalBounds().width / 2 <= 0.f) {
direction = -direction;
//enemy.setPosition(enemy.getPosition().x, enemy.getPosition().y + yOffset);
}
*/
//std::cout << "Direction now has value of " << direction << std::endl;
std::cout << enemy.getPosition().x << " " << enemy.getPosition().y << std::endl;
/*
std::cout << "Temp Enemy has " << enemy.getPosition().x << " " << enemy.getPosition().y << std::endl;
enemy.move(10.f, 0.f);
std::cout << "Temp Enemy has " << enemy.getPosition().x << " " << enemy.getPosition().y << std::endl;
*/
}
/*
for (auto it = enemyList.begin(); it != enemyList.end()
{
//enemyMovement.x += enemySpeed;
tempEnemy = *it;
cout << "Temp Enemy has for iterator " << tempEnemy.getPosition().x << " " << tempEnemy.getPosition().y << endl;
/*
if (tempEnemy.getPosition().x + tempEnemy.getLocalBounds().width/2 > windowWidth) {
direction = -direction;
tempEnemy.setPosition(tempEnemy.getPosition().x, tempEnemy.getPosition().y + yOffset); // y axis is inverted in SFML
}
if (tempEnemy.getPosition().x - tempEnemy.getLocalBounds().width / 2 < 0.f) {
direction = -direction;
tempEnemy.setPosition(tempEnemy.getPosition().x, tempEnemy.getPosition().y + yOffset);
}
tempEnemy.move(enemyMovement * direction);
}
*/
//enemyMovement.x += enemySpeed;
// Pseudo
/*
if we are at end of move rotation, change direction (-/+) from current position
and increment position by move.
*/
}
void Enemy::enemyInstantiator(int noOfEnemies, float xPosition, float yPosition) {
sf::Sprite tempEnemy;
int tracker = 0;
float yOffset = 50.f;
float xOffset = 60.f;
for (int i = 0; i < noOfEnemies; i++) {
tempEnemy.setTexture(mEnemyTexture);
tempEnemy.setOrigin(24.f, 24.f);
tempEnemy.setPosition(xPosition + (i * xOffset), yPosition);
tempEnemy.setRotation(180.f);
if (i >= noOfEnemies / 2) {
// set position for remainder, problem is that every loop is overiding position and drawing last batch of 5
for (int j = 0; j < noOfEnemies / 2; j++) {
tempEnemy.setTexture(mEnemyTexture);
tempEnemy.setOrigin(24.f, 24.f);
tempEnemy.setPosition(xPosition + (j * xOffset), yPosition + yOffset);
tempEnemy.setRotation(180.f);
std::cout << "Enemy inside 2nd for loop position " << tempEnemy.getPosition().x << " " << tempEnemy.getPosition().y << std::endl;
// we were not pushing each and every tempEnemy but only the last one when exiting the for loop, therefore we were only printing the last one
mEnemies.push_back(tempEnemy);
tracker++;
if (tracker >= noOfEnemies/2) {
return;
}
}
}
std::cout << "Enemy inside 1st for loop position " << tempEnemy.getPosition().x << " " << tempEnemy.getPosition().y << std::endl;
mEnemies.push_back(tempEnemy);
}
}
void Enemy::enemyBehaviour(std::vector<sf::Sprite>& enemyList) {
float direction = 1.f;
//sf::Sprite tempEnemy;
sf::Vector2f enemyMovement(1.f, 0.f);
float yOffset = 50.f;
float xOffset = 60.f;
for (sf::Sprite& enemy : enemyList) // CAUTION & solved everything again - lesson in C++, if we don't get address, we always create a copy and modify it, which is not what we want
{
if (enemy.getPosition().x + enemy.getLocalBounds().width / 2 > 640.f) { // can be improved by calling getWidth method
direction = -direction;
enemy.setPosition(enemy.getPosition().x, enemy.getPosition().y + yOffset); // y axis is inverted in SFML
}
if (enemy.getPosition().x - enemy.getLocalBounds().width / 2 < 0.f) {
direction = -direction;
enemy.setPosition(enemy.getPosition().x, enemy.getPosition().y + yOffset);
}
enemy.move(enemyMovement * direction);
std::cout << enemy.getPosition().x << " " << enemy.getPosition().y << std::endl;
/*
std::cout << "Temp Enemy has " << enemy.getPosition().x << " " << enemy.getPosition().y << std::endl;
enemy.move(10.f, 0.f);
std::cout << "Temp Enemy has " << enemy.getPosition().x << " " << enemy.getPosition().y << std::endl;
*/
}
}
void Enemy::render(sf::RenderWindow& window) {
for (int i = 0; i < mEnemies.size(); i++)
{
sf::Sprite temp = mEnemies.at(i);
window.draw(temp);
}
}
// Creates two rows of enemies: takes even noOfEnemies, start xPosition and yPosition
void Game::enemyInstantiator(int noOfEnemies, float xPosition, float yPosition) {
//int noOfEnemies = 10;
sf::Sprite tempEnemy;
int tracker = 0;
for (int i = 0; i < noOfEnemies; i++) {
tempEnemy.setTexture(mEnemyTexture);
tempEnemy.setOrigin(24.f, 24.f);
tempEnemy.setPosition(xPosition + (i * 60.f), yPosition);
tempEnemy.setRotation(180.f);
if (i >= noOfEnemies / 2) {
// set position for remainder, problem is that every loop is overiding position and drawing last batch of 5
for (int j = 0; j < noOfEnemies/2; j++) {
tempEnemy.setTexture(mEnemyTexture);
tempEnemy.setOrigin(24.f, 24.f);
tempEnemy.setPosition(xPosition + (j * 60.f), yPosition + 50.f);
tempEnemy.setRotation(180.f);
cout << "Enemy inside 2nd for loop position" << tempEnemy.getPosition().x << " " << tempEnemy.getPosition().y << endl;
// we were not pushing each and every tempEnemy but only the last one when exiting the for loop, therefore we were only printing the last one
mEnemies.push_back(tempEnemy);
tracker++;
if (tracker >= 5) {
return;
}
}
}
cout << "Enemy inside 1st for loop position" << tempEnemy.getPosition().x << " " << tempEnemy.getPosition().y << endl;
mEnemies.push_back(tempEnemy);
}
}
void Game::enemyInstantiator() {
int noOfEnemies = 10;
sf::Sprite tempEnemy;
for (int i = 0; i < noOfEnemies; i++) {
tempEnemy.setTexture(mEnemyTexture);
tempEnemy.setOrigin(24.f, 24.f);
tempEnemy.setPosition(100.f + (i * 60.f), 100.f);
tempEnemy.setRotation(180.f);
if (i >= noOfEnemies / 2) {
for (int j = 0; j < i; j++) {
tempEnemy.setTexture(mEnemyTexture);
tempEnemy.setOrigin(24.f, 24.f);
tempEnemy.setPosition(100.f + (j * 60.f), 150.f);
tempEnemy.setRotation(180.f);
}
}
mEnemies.push_back(tempEnemy);
}
}
// Render
void Game::render()
{
// Remember draw order is important
mWindow.clear();
mWindow.draw(mBackground);
mWindow.draw(mPlayer);
mWindow.draw(mStatisticsText);
for (int i = 0; i < mEnemies.size(); i++)
{
sf::Sprite temp = mEnemies.at(i);
mWindow.draw(temp);
}
mWindow.display();
}