Welcome, Guest. Please login or register. Did you miss your activation email?

Show Posts

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.


Messages - coltranenaima

Pages: [1]
1
General / Re: Vector of Vectors Collision Detection
« on: May 29, 2018, 04:09:00 am »
Thanks Hapax for helping me out again. I'm watching a youtube tutorial on auto (and glancing at my Stroustrup book), it's simply just ignorance on my part for not knowing useful keywords and how they work. At a glance it just appears to be magic and/or syntax sugar.

Anyway, one thing to consider applying to your function is to get the player bullet rectangle's global boundaries once at the beginning of the function and then use that to compare intersections. This avoids the 'getting' of the bounds for every collision check for every enemy. Note that this isn't a massive deal really but it seems wasteful if there are a lot of enemies to check.

I appreciate this advice, and I will try to make this happen.

What doesn't work in your second code? What is passed into enemyVectors? Should it not be a vector of references instead a vector of elements?

I have an initializer function (English not c++ lol) that loads "enemies" (rectangle shapes) into a vector of "enemy" type...and once that is loaded, I load that vector into a vector (the vector of vectors). I trimmed out the node functionality (enemy movement). I do realize I need to work on my naming conventions...it is confusing to say the least.

void Levels::LevelLoadNodes(Player& pO, Enemy& enemyObject, std::vector<Enemy>& enemy, int numberOfEnemies)
{
        enemyObject.loadEnemies(numberOfEnemies, enemy, enemyObject, pO);
        enemyVectors.push_back(enemy);
 

I am passing that vector of vectors by reference to the player bullet "move" function to check for collisions by iterating through all the enemies while the player bullet is "moving". The function BulletEnemyCollision is my original post.

void Bullet::BulletPlayerMove(float delta, std::vector<std::vector<Enemy> >& enemyVectors)
{
        for (unsigned int i = 0; i < bulletVector.size(); i++)
        {
                bulletVector[i].move(cos(bulletAngleVector[i]) * bulletSpeed * delta, sin(bulletAngleVector[i]) * bulletSpeed * delta);
                bulletTimeFVector[i] = bulletTimeVector[i].getElapsedTime().asSeconds();
                window.draw(bulletVector[i]);
                BulletEnemyCollision(bulletVector[i], enemyVectors);
        }
}

I am gonna take a stab at using auto, thanks again.


2
General / Vector of Vectors Collision Detection
« on: May 28, 2018, 04:28:06 am »
Hello,

I am having issues with collision detection of player bullets against enemies.

I have three "types" of enemies and plan on having many more with distinct characteristics.

enemyOne(sf::Color::Yellow, 20.f, 20.f)
enemyTwo(sf::Color::Red, 40.f, 40.f)
enemyThree(sf::Color::Cyan, 80.f, 80.f)

that feed into

std::vector<Enemy> enemiesOne;
std::vector<Enemy> enemiesTwo;
std::vector<Enemy> enemiesThree;

I currently have a not so elegant function that won't scale very well with my goal...however it does work.

void Bullet::BulletEnemyCollision(sf::RectangleShape playerBulletShape, std::vector<Enemy>& enemyVectorsOne, std::vector<Enemy>& enemyVectorsTwo, std::vector<Enemy>& enemyVectorsThree)
{
        for (unsigned int i = 0; i < enemyVectorsOne.size(); i++)
        {
                if (playerBulletShape.getGlobalBounds().intersects(enemyVectorsOne[i].enemyShape.getGlobalBounds()))
                {
                        enemyVectorsOne.erase(enemyVectorsOne.begin() + i);
                }
        }
        for (unsigned int i = 0; i < enemyVectorsTwo.size(); i++)
        {
                if (playerBulletShape.getGlobalBounds().intersects(enemyVectorsTwo[i].enemyShape.getGlobalBounds()))
                {
                        enemyVectorsTwo.erase(enemyVectorsTwo.begin() + i);
                }
        }
        for (unsigned int i = 0; i < enemyVectorsThree.size(); i++)
        {
                if (playerBulletShape.getGlobalBounds().intersects(enemyVectorsThree[i].enemyShape.getGlobalBounds()))
                {
                        enemyVectorsThree.erase(enemyVectorsThree.begin() + i);
                }
        }
}


An idea I have is to feed each enemy vector into a vector and simply have the function iterate through that vector of vectors. This currently does not work.

std::vector<std::vector<Enemy> >& enemyVectors


void Bullet::BulletEnemyCollision(sf::RectangleShape playerBulletShape, std::vector<std::vector<Enemy> >& enemyVectors)
{
        for (unsigned int i = 0; i < enemyVectors.size(); i++)
        {
                for (unsigned int j = 0; j < enemyVectors[i].size(); j++)
                {
                        if (playerBulletShape.getGlobalBounds().intersects(enemyVectors[i][j].enemyShape.getGlobalBounds()))
                        {
                                enemyVectors[i].erase(enemyVectors[i].begin() + j);
                        }
                }
        }
}

Below is a brief recording of the game with the not so elegant code in place.

https://gfycat.com/gifs/detail/LivelySpottedChevrotain

You may notice the lack of pointers and keywords like auto...etc. This game for me is an exercise in learning classes & functions at a basic level. The next game I plan on taking a stab at utilizing pointers and super useful keywords. The last game I made I was using header files for implementation...baby steps.

Thanks for reading and I appreciate the help.


3
General / Re: Fire Bullet At Angle
« on: April 23, 2018, 02:04:00 am »
I was able to get it to work, thanks Geheim. You mentioning radians helped fix the first issue and it helped me with tracking down the other issue by reading this thread:

https://en.sfml-dev.org/forums/index.php?topic=4951.0

from Nexus:

Quote
Note that the functions std::sin() and std::cos() take radians, not degrees.

cos and sin take radians, I was feeding it a rotation degree.

Thanks!!!!

4
General / Re: Fire Bullet At Angle
« on: April 23, 2018, 12:01:02 am »
rotation = atan2(dy, dx) * 180 / PI;
should just be:
rotation = atan2(dy, dx);
atan2 already gives you radians.  ;)

Thanks for your feedback! I tried your suggestion with the remaining code as is, unfortunately I am getting the same result. If that is the case where I do not need to convert from radians, maybe this piece of code is suspect?

                for (unsigned int i = 0; i < bulletVector.size(); i++)
                {
                        bulletVector[i].move(cos(bulletAngleVector[i]), sin(bulletAngleVector[i]));
                        window.draw(bulletVector[i]);
                }

I will be honest...I have not taken real trig classes....just simple review course on khan academy, soh cah toa! The movement is what I am leaning towards being the issue (with your suggestion in place).

5
General / Re: Fire Bullet At Angle
« on: April 22, 2018, 09:26:55 pm »
I recorded what is currently happening, see gif link below.

Thanks for reading and I appreciate any suggestions!

https://gfycat.com/LimpFrankBumblebee

6
General / Fire Bullet At Angle
« on: April 22, 2018, 03:31:14 am »
Hello,

I am working on a game that so far has:
  • A square moving around with a basic velocity system (wasd)
  • The Square also rotates based on mouse position

I am now trying to implement bullets that will fire in the direction the square (player) is rotated, I made a very simple system with the last game I made (thanks again Hapax) that only went in one direction.

The bullets fire (yay), just not at the right angle (boo). I debugged and looked at the rotation each time and the numbers matched....it just doesn't come out correctly visually.

Thanks!

This is main.cpp (I chopped a major chunk of code to isolate what the issue may be)

#include "Player.h"
#include "Bullet.h"
#include <iostream>

int main()
{
        //declare
        float delta, deltaCd, bulletTime, bulletCd, bulletSpeed, bulletAngle;
        float& dCd = deltaCd;
        sf::Clock gameClock, bulletClock;
        Player playerOne;
        Player& pO = playerOne;
        Bullet playerBullet;
        Bullet& pB = playerBullet;
        std::vector<sf::RectangleShape> bulletVector;
        std::vector<float> bulletAngleVector;

        //initialize
        delta = .0f;
        deltaCd = .25f;
        bulletTime = 1.0f;
        bulletCd = 2.0f;
        bulletSpeed = 1.5f;
        bulletAngle = .0f;

        playerBullet.bulletShape.setPosition(sf::Vector2f(playerOne.playerShape.getPosition().x,
       
        //window loop
        //TODO: Create game loop
        while (win.isOpen())
        {
                window.clear();
                delta = gameClock.restart().asSeconds();
                playerOne.PlayerRotation(win, pO.playerShape);
                playerBullet.BulletAngle(win, pB.bulletShape);

                if (sf::Mouse::isButtonPressed(sf::Mouse::Left) && bulletTime > bulletCd)
                {
                        bulletTime = bulletClock.restart().asSeconds();
                        playerBullet.bulletShape.setPosition(sf::Vector2f(playerOne.playerShape.getPosition().x, playerOne.playerShape.getPosition().y));
                        bulletAngle = playerBullet.bulletShape.getRotation();
                        bulletVector.push_back(playerBullet.bulletShape);
                        bulletAngleVector.push_back(bulletAngle);
                }              

                for (unsigned int i = 0; i < bulletVector.size(); i++)
                {
                        bulletVector[i].move(cos(bulletAngleVector[i]), sin(bulletAngleVector[i]));
                        window.draw(bulletVector[i]);
                }
               
                bulletTime = bulletClock.getElapsedTime().asSeconds();

                window.draw(pO.playerShape);
                window.display();
        }
}


bullet.cpp

#include "Bullet.h"

Bullet::Bullet()
{
        bulletSizeX = 5.f;
        bulletSizeY = 5.f;
        bulletShape.setSize(sf::Vector2f(bulletSizeX, bulletSizeY));
        bulletShape.setOrigin(sf::Vector2f(bulletShape.getGlobalBounds().width / 2.f, bulletShape.getGlobalBounds().height / 2.f));
        bulletShape.setFillColor(sf::Color::Red);
}

void Bullet::BulletAngle(sf::RenderWindow& win, sf::RectangleShape& bS)
{
        dx = 0.f;
        dy = 0.f;
        mouse = sf::Mouse::getPosition(win);
        mouseWorld = win.mapPixelToCoords(mouse);
        dx = mouseWorld.x - bS.getPosition().x;
        dy = mouseWorld.y - bS.getPosition().y;
        rotation = atan2(dy, dx) * 180 / PI;
        bS.setRotation(rotation);
}

bullet.h

#pragma once
#include <SFML/Graphics.hpp>

class Bullet
{
public:
        float bulletSizeX, bulletSizeY, dx, dy, rotation;
        const float PI = 3.14159265f;
        sf::Vector2i mouse;
        sf::Vector2f mouseWorld;
        sf::RectangleShape bulletShape;
        void BulletAngle(sf::RenderWindow& win, sf::RectangleShape& bS);
        Bullet();
};

7
General / Re: Multiple bullets with isKeyPressed
« on: February 14, 2017, 05:04:42 am »
I would like to just clarify that you are not actually using KeyPressed events, which are sent to the window when they happen; you check events using the pollEvent (usually) method.
You are using the real-time states of the keys. That is, you check to see - in real-time - the current state (pressed or not pressed) of a specific key at the time of checking.

Most common way to separate the two (for key presses) is to use events for single presses (i.e. do something when the key is pressed and not again while it is held - unless key repeat is still active, e.g. jump/shoot) and to use real-time states for held presses (e.g. move/fire continuously...)

I should totally have known what the difference is since I have the below header file for checking if the close event occurs. Sorry this is all new to me!

Slowly learning...I went from one massive int main (over 500 lines of code) to now using header files with functions and classes so that int main is 85 lines of code roughly. Now I struggle with when to use multiple .cpp files...(i get they are intended to define what is in the shared header file), but ah that goes out of the scope of this thread.

I appreciate your help Hapax!

I found the code drop down button as well for the tags lol.

#pragma once

#ifndef POLL_EVENT_H
#define POLL_EVENT_H

void close_event_checker(sf::RenderWindow &thatwindow)
{
        sf::Event close_event;
        thatwindow.pollEvent(close_event);
        if (close_event.type == sf::Event::Closed)
        {
                thatwindow.close();
        }
}

#endif

8
General / Re: Multiple bullets with isKeyPressed
« on: February 13, 2017, 05:51:06 am »
Well in-case anyone else has the same issue, the easiest fix is from
If you would like to fire at regular intervals, you can use a timer and realtime key states. If the timer is below the minimum interval/delay, don't fire. If the timer is above that delay, reset the timer and trigger the bullet.

I removed the vector erase for now until I find a better way to clean up excess bullets, but using a cool-down timer achieves the goal of one key press = one bullet.

Now I have two settings to tweak with power ups, either the speed of the bullet or the cool down for rate of fire.

Thanks Hapax!

See below (changes are bolded):

#include <SFML/Graphics.hpp>
#include <SFML/Poll_Event.h>
#include <SFML/Sprite_Creator.h>
#include <SFML/Key_logic.h>
#include <SFML/ast_randomizer.h>
#include <SFML/Levels.h>
#include <SFML/Move_the_background.h>
#include <SFML/Bullets.h>

int main()
{
   //make all the things
   sf::RenderWindow   main_window(sf::VideoMode(1920, 1080), "Game", sf::Uint32());
   main_window.setKeyRepeatEnabled(true);
   sprite_creator      create_space_ship,
                  create_asteroid,
                  create_background,
                  create_bullet;
   levels            start_level;
   key_logic         key_check;
   sf::Sprite         space_ship = create_space_ship.create_sprite("spaceship.png", true),
                   new_bullet = create_bullet.create_sprite("bullet.png", true),
                  main_background = create_background.create_sprite("main_game_background.png", false),
                  main_background2 = create_background.create_sprite("main_game_background.png", false);
                  std::vector<sf::Sprite> asteroid_sprites(100, sf::Sprite(create_asteroid.create_sprite("Asteroid.png", true)));
                  std::vector<sf::Sprite> bullet_sprites;
   main_background2.setPosition(sf::Vector2f(3820.f, 0.f));
   space_ship.setPosition(sf::Vector2f(300, 100));
   space_ship.setScale(sf::Vector2f(.8f, .8f));

   //clock
   sf::Clock delta_clock, bullet_clock;
   sf::Time bullet_cooldown;

   while (main_window.isOpen())
   {      
      float delta = delta_clock.restart().asSeconds();
      bullet_cooldown = bullet_clock.getElapsedTime();

      //clear...draw...
      main_window.clear();
      move_the_background(main_background, main_background2, delta, main_window);
      start_level.level_one(asteroid_sprites, main_window, delta, space_ship);
      start_level.level_two(asteroid_sprites, main_window, delta, space_ship);
      main_window.draw(space_ship);

      //keypress
      key_check.w_key(space_ship.getPosition(), space_ship);
      key_check.s_key(space_ship.getPosition(), space_ship);
      key_check.a_key(space_ship.getPosition(), space_ship);
      key_check.d_key(space_ship.getPosition(), space_ship);
      key_check.esc_key(main_window);

      if (sf::Keyboard::isKeyPressed(sf::Keyboard::Space) && bullet_cooldown.asSeconds() >= .5f)
      {
         bullet_clock.restart();

         sf::Sprite new_bullet = create_bullet.create_sprite("bullet.png", true);
         new_bullet.setPosition(space_ship.getPosition().x + 145.f, space_ship.getPosition().y + 0.f);
         bullet_sprites.push_back(new_bullet);
      }

      for (int j = 0; j < bullet_sprites.size(); j++)
      {
         main_window.draw(bullet_sprites[j]);
         create_bullet.move_sprite(1500.f, 0.f, delta, bullet_sprites[j], false, 0.f, false, 0.f, 0.f, "pos");
      }
      //display...
      main_window.display();
      
      //check to see if main window is closed
      close_event_checker(main_window);
   }
   return 0;
}

9
General / Re: Multiple bullets with isKeyPressed
« on: February 13, 2017, 02:25:47 am »
I'm an idiot...I am using the Key pressed events lol. I have space bar in main and a header file for all other events. If this is not a standard way of handling key press events, sorry!

Main.cpp

      if (sf::Keyboard::isKeyPressed(sf::Keyboard::Space))
      {
         fired_bullet = true;
      }

Key_logic.h

#pragma once
#include <SFML/Bullets.h>

#ifndef KEY_LOGIC_H
#define KEY_LOGIC_H

class key_logic {
private:
      int j = 0;
      int bullet_number = 0;
      bool space_pressed = false;
public:

   void w_key(sf::Vector2f position, sf::Sprite &sprite_name)
   {
      if ((sf::Keyboard::isKeyPressed(sf::Keyboard::W) || sf::Keyboard::isKeyPressed(sf::Keyboard::Up)) && position.y > 0)
      {
         sprite_name.setPosition(position.x + 0, position.y - .45);
      }
   }

   void s_key(sf::Vector2f position, sf::Sprite &sprite_name)
   {
      if ((sf::Keyboard::isKeyPressed(sf::Keyboard::S) || sf::Keyboard::isKeyPressed(sf::Keyboard::Down)) && position.y < 1080)
      {
         sprite_name.setPosition(position.x + 0, position.y + .45);
      }
   }

   void a_key(sf::Vector2f position, sf::Sprite &sprite_name)
   {
      if ((sf::Keyboard::isKeyPressed(sf::Keyboard::A) || sf::Keyboard::isKeyPressed(sf::Keyboard::Left)) && position.x > 0)
      {
         sprite_name.setPosition(position.x - .45, position.y + 0);
      }
   }

   void d_key(sf::Vector2f position, sf::Sprite &sprite_name)
   {
      if ((sf::Keyboard::isKeyPressed(sf::Keyboard::D) || sf::Keyboard::isKeyPressed(sf::Keyboard::Right)) && position.x < 1920)
      {
         sprite_name.setPosition(position.x + .45, position.y + 0);
      }
   }

   void esc_key(sf::RenderWindow &window)
   {
      if (sf::Keyboard::isKeyPressed(sf::Keyboard::Escape))
      {
         window.close();
      }
   }
};

#endif

10
General / Re: Multiple bullets with isKeyPressed
« on: February 13, 2017, 02:11:05 am »
What is the behaviour that you would like to happen?
Fire bullets at regular intervals? Fire only one bullet per keypress? Something else?

It sounds like you might want one bullet per keypress.

Possibly the simplest/best way to trigger something once and only once when a key is pressed is to use events. A keypress event is received whenever the key is pressed; you simply trigger a new bullet when you get the event and that will be that. Note that you may want to turn off key repeating to avoid multiple events.


Essentially one key press = one bullet is the goal. I would eventually like a real rate of fire where it's not reliant on the previous bullet being off screen to spawn the next bullet. It would be great if the user can also hold down space bar and a steady stream of bullets pours out, which can be sped up with power ups etc...

I will be giving your first suggestion a shot, I will try implementing this in my stripped down project and report back. If no luck, I will try your other suggestion.

Thanks!

11
General / Multiple bullets with isKeyPressed
« on: February 13, 2017, 12:41:56 am »
The bolded section is the area of concern. I am having a hard time wrapping my head around making a great bullet system that is easy to work with and manipulate when needed.

bullet_sprites is a vector of sprites, a new bullet sprite is pushed back into the vector when spacebar is pressed. I originally didn't have "&& bullet_sprites.size() == 0" in the first if statement, but it would create a stream of bullets and cause performance issues (see attached pic).

The bullet is erased when it is off screen and the issue I am having now is for one space bar keypress, two bullets are fired. When i say two, I mean one is fired and moved off screen and then a consecutive bullet is fired and moves off screen with only one keypress.

Thanks for any help, i can provide more code as well (like the header files being used). I watched youtube tutorials and even made a stripped down basic project that is having the same exact issue.

   while (main_window.isOpen())
   {      
      float delta = delta_clock.restart().asSeconds();
      if (sf::Keyboard::isKeyPressed(sf::Keyboard::Space))
      {
         fired_bullet = true;
      }
      //clear...draw...
      main_window.clear();
      move_the_background(main_background, main_background2, delta, main_window);
      start_level.level_one(asteroid_sprites, main_window, delta, space_ship);
      start_level.level_two(asteroid_sprites, main_window, delta, space_ship);
      main_window.draw(space_ship);

      //keypress
      key_check.w_key(space_ship.getPosition(), space_ship);
      key_check.s_key(space_ship.getPosition(), space_ship);
      key_check.a_key(space_ship.getPosition(), space_ship);
      key_check.d_key(space_ship.getPosition(), space_ship);
      key_check.esc_key(main_window);

      if (fired_bullet == true && bullet_sprites.size() == 0)
      {
         sf::Sprite new_bullet = create_bullet.create_sprite("bullet.png", true);
         new_bullet.setPosition(space_ship.getPosition().x + 145.f, space_ship.getPosition().y + 0.f);
         bullet_sprites.push_back(new_bullet);
         fired_bullet = false;
      }

      for (int j = 0; j < bullet_sprites.size(); j++)
      {
         main_window.draw(bullet_sprites[j]);
         create_bullet.move_sprite(1500.f, 0.f, delta, bullet_sprites[j], false, 0.f, false, 0.f, 0.f, "pos");
         if (bullet_sprites[j].getPosition().x > 1940)
         {
            bullet_sprites.erase (bullet_sprites.end() - 1);
         }   
      }


      //display...
      main_window.display();
      
      //check to see if main window is closed
      close_event_checker(main_window);
   }

Pages: [1]