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 - Dimple

Pages: 1 [2]
16
General / How to use "Simple Collision Detection?"
« on: May 02, 2011, 06:15:29 pm »
OK, I'll try to go the function through in detail now (had a busy weekend :P).
Code: [Select]

static bool checkCollision(sf::Sprite sprite1, sf::Sprite sprite2) {

     if(sprite1.GetPosition().x  + sprite1.GetSize().x > sprite2.GetPosition().x && sprite1.GetPosition().x < sprite2.GetPosition().x + sprite2.GetSize().x && sprite1.GetPosition().y + sprite1.GetSize().y > sprite2.GetPosition().y && sprite1.GetPosition().y < sprite2.GetPosition().y + sprite2.GetSize().y)
         return true;

     return false;
 }

The idea is very simple: compare the coordinates to determine whether the rectangle around the sprite is on top of the other sprite's rectangle. To do that I actually rule out all the possibilities how the rectangles could be positioned so that they aren't overlapping. If they can be ruled out, the rectangles are on top of each other.

The rectangle is formed using the sprite's coordinates and the sprite's size. So the upper left corner of sprite1's rectangle is at (sprite1.GetPosition().x, sprite1.GetPosition().y), right upper corner is at (sprite1.GetPosition().x + sprite1.GetSize().x, sprite1.GetPosition().y), left lower corner is at (sprite1.GetPosition().x + sprite1.GetSize().x, sprite1.GetPosition().y) and the lower right corner is at (sprite1.GetPosition().x + sprite1.GetSize().x, sprite1.GetPosition().y + sprite1.GetSize().x). The same is done for sprite2.

Now that we have formed the rectangles we only need to figure out whether they are on top of each other or not. Let's go through the x-axis first. The rectangles can't possibly be on top of each other if the sprite1 is too far to the left from sprite2 (ie. "the right side" of the sprite1's rectangle is on the left of "the left side" of the sprite2's rectangle). So we want to compare
Code: [Select]

sprite1.GetPosition().x  + sprite1.GetSize().x

with
Code: [Select]

sprite2.GetPosition().x

to rule out the possibility that the sprite1 would be too far to the left for the rectangles to collide. So in code it looks like this:
Code: [Select]

if(sprite1.GetPosition().x  + sprite1.GetSize().x > sprite2.GetPosition().x)

Now if the sprite1 is too far to the left, that expression is false (a collision isn't possible). Now the same is done for the other side: we rule out the possibility that the sprite1 is too far to the right from the sprite2.
Code: [Select]

if(sprite1.GetPosition().x < sprite2.GetPosition().x + sprite2.GetSize().x)

Combining the two we get:
Code: [Select]

if(sprite1.GetPosition().x  + sprite1.GetSize().x > sprite2.GetPosition().x && sprite1.GetPosition().x < sprite2.GetPosition().x + sprite2.GetSize().x)

Which already works for the x-axis. The only thing left is to do the same with the y-axis and the function is complete. It's exactly the same thing: you can actually copy and paste the first part and just change the x's to y's and that's it.

I hope I got everything about right. Ask if you didn't understand something. Oh, and if you want some help with what to do with the information that the objects are indeed colliding, tell me what would you would want to happen when the collision occurs and I can help you implement it.

17
General / How to use "Simple Collision Detection?"
« on: April 30, 2011, 01:48:16 pm »
Here's one that I wrote in maybe two minutes. I'll try to explain it to you later (gotta go right now) but the idea is exactly the same that I tried to explain to you in the other thread.

Add this before your main-function
Code: [Select]

static bool checkCollision(sf::Sprite sprite1, sf::Sprite sprite2) {

    if(sprite1.GetPosition().x  + sprite1.GetSize().x > sprite2.GetPosition().x && sprite1.GetPosition().x < sprite2.GetPosition().x + sprite2.GetSize().x && sprite1.GetPosition().y + sprite1.GetSize().y > sprite2.GetPosition().y && sprite1.GetPosition().y < sprite2.GetPosition().y + sprite2.GetSize().y)
        return true;

    return false;
}

It's used like this
Code: [Select]
if(checkCollision(Object1, Object2))
             std::cout << "Collision!";

18
General / How to use "Simple Collision Detection?"
« on: April 30, 2011, 01:20:43 pm »
You can't manually set the size of the bounding box without modifying the BoundingBoxTest-function (unless there's something you can do with the sprites themselves that I'm not aware of). What are the dimensions of your images?

Do you need to rotate the sprites btw? If not then writing your own detection function is really easy.

19
General / How to use "Simple Collision Detection?"
« on: April 30, 2011, 01:06:17 pm »
It doesn't matter whether the objects are on the screen or not, the detection works exactly the same. I wanted you to put them far from each other so that you could see if the program closes no matter where the objects are (ie. the collision detection function doesn't work).

20
General / How to use "Simple Collision Detection?"
« on: April 30, 2011, 12:49:59 pm »
If adding that causes the program exit, it means that the function returns true so there should be a collision. Try to put the sprites further away from each other. Put them on opposite edges of the screen.

21
General / How to use "Simple Collision Detection?"
« on: April 30, 2011, 12:35:49 pm »
Quote from: "Girby2K11"

For some reason i can't see my character and ball. Actually i can see the objects now but the program quickly starts then ends when i add if(Collision::BoundingBoxTest(Object1, Object2))
         return EXIT_FAILURE;

Are the objects on top of each other in the beginning? I added that part only to test if the detection worked. It causes the program to exit if the sprites are on top of each other.

22
General / How to use "Simple Collision Detection?"
« on: April 30, 2011, 11:45:53 am »
This works for me:
Code: [Select]

#include <SFML/Graphics.hpp>
#include "Collision.h"

int main()
{

     sf::RenderWindow App(sf::VideoMode(800, 600, 32), "SFML Failing");

     sf::Image iCharacter;
     if (!iCharacter.LoadFromFile("character.png"))
     return EXIT_FAILURE;
     sf::Sprite Object1(iCharacter);

     Object1.SetPosition(100.f,100.f);

     sf::Image iBall;
     if (!iBall.LoadFromFile("Ball.png"))
     return EXIT_FAILURE;

     sf::Sprite Object2(iBall);

     Object2.SetPosition(300.f,300.f);

     while (App.IsOpened())
     {
         sf::Event Event;

         while (App.GetEvent(Event))
         {
             if (Event.Type == sf::Event::Closed)
             App.Close();

             if ((Event.Type == sf::Event::KeyPressed) && (Event.Key.Code == sf::Key::Escape))
             App.Close();
         }


         float ElapsedTime = App.GetFrameTime();

         if (App.GetInput().IsKeyDown(sf::Key::Right)) Object1.Move(100 * ElapsedTime, 0);
         if (App.GetInput().IsKeyDown(sf::Key::Left)) Object1.Move(-100 * ElapsedTime, 0);
         if (App.GetInput().IsKeyDown(sf::Key::Up)) Object1.Move( 0, -100 * ElapsedTime);
         if (App.GetInput().IsKeyDown(sf::Key::Down)) Object1.Move(0, 100 * ElapsedTime);

         if(Collision::BoundingBoxTest(Object1, Object2)) {

             return EXIT_SUCCESS;
         }

         App.Clear(sf::Color::Red);
         App.Draw(Object2);

         App.Draw(Object1);
        App.Display();
     }


    return EXIT_SUCCESS;
}

Copy and paste the exact error messages.

23
Graphics / Sprite Help
« on: April 27, 2011, 06:35:32 pm »
You are right, I never thought about that. I assumed that he just wanted to execute some code when shift-key is pressed, not to do anything as fancy as that. :D

24
Graphics / Re: Events
« on: April 27, 2011, 05:38:45 pm »
Quote from: "David"
Your explaination helped

And for the Events part, I just want to know how can you program a key listener so the user can press the SHIFT key and make it do something

There is no need for a key listener (Java programmer?). If you want something to happen when the user presses shift, you can do this (inside the event-loop):
Code: [Select]

if ((Event.Type == sf::Event::KeyPressed) && (Event.Key.Code == sf::Key::LShift)) {
    // Do here what you want to happen when the user presses shift
}

25
General / I need help with this game i am trying to make.
« on: April 26, 2011, 05:22:27 pm »
Yes, if you downloaded the full SDK or the SFML 2.0 snapshot.

26
General / I need help with this game i am trying to make.
« on: April 26, 2011, 03:50:30 pm »
Then I would advice you to take a really good look at the Pong example that comes with the library and ask here if there's something that you don't understand. It has pretty much everything you need for basic physics (at least for a start).

27
General / Memory Leaks?
« on: April 26, 2011, 08:43:05 am »
You actually had two pointers in the first example that you didn't delete (Proto *proto and RenderWindow   *window) but they have nothing to do with the leak.

I tried the shorter version and all seems to be fine for me. I'm running Ubuntu 10.10 x64 and my memory usage hasn't gone up although I have kept it running for almost an hour. I gotta try the same with Windows later.

EDIT:
I have Ati Mobility Radeon HD 5650 btw.

28
General / I need help with this game i am trying to make.
« on: April 25, 2011, 07:30:34 pm »
Quote from: "Girby2K11"
Thanks for your help I'm going to try it. Also do you know collision detection?

Yes, I know something about collision detection, too.

First it would be useful to know which collisions you would exactly want to detect and how would you want to react to them. You could start by telling what kind of game you are making. :)

It would also be  useful to know how familiar you are with vectors and trigonometric functions. Vectors can sometimes provide really nice solutions.

In the Pong example the collision with the edges of the screen is very simple: when the ball reaches the edge of the screen, either the game ends or the ball's direction is negated. For example, this is the code what happens when the ball hits the top:
Code: [Select]

if (ball.GetPosition().y < 0.f)  // This checks if the ball has reached the top
            {
                ballSound.Play();   // Play the sound
                ballAngle = -ballAngle;   // negate the ball's angle to make it appear as if it bounces off the wall
                ball.SetY(0.1f);  // I'm guessing this is needed to make sure that the ball can't get stuck outside the game area. I tested without it and it appeared to work without it (at least with this setup).
            }


The collision between the paddle and the ball, on the other hand, is a simple box-to-box collision detection. You know the coordinates of the objects and you know their sizes so you can just compare the coordinates taking the sizes into account, and determine whether those objects are on top of each other. In semi-pseudo code it would be something like this (assuming that the images are drawn so that the coordinates are on the upper left corner):
Code: [Select]

If object1.x + object1.width > object2.x And object1.x < object2.x + object2.width And object1.y + object1.height > object2.y And object1.y < object2.y + object2.height Then
    Objects_1_and_2_are_on_top_of_each_other
EndIf

So the detection is basically just comparing x and y coordinates taking the sizes of the objects into account.

I really can't help you more than that before you tell me what you actually want to do. :)

29
Graphics / Sprite rotating problem
« on: April 25, 2011, 03:40:15 pm »
Is this what you want?
Code: [Select]

#include <SFML/Graphics.hpp>
 #include <SFML/Window.hpp>
 #include <SFML/System.hpp>
 #include <cmath>
 #include <sstream>
 #include <string>

 static inline std::string int2Str(float x)
 {
       std::stringstream type;
       type << x;
       return type.str();
 }

 #define PI 3.14159265

 int main()
 {
     sf::RenderWindow App(sf::VideoMode(800, 600), "ShootingGun");

     sf::Image imgGun;
     imgGun.LoadFromFile("bar.png");
     imgGun.SetSmooth(false);
     sf::Sprite Gun(imgGun);

     float x = 400, y = 300, angle = 0, lenght = 5;

     App.SetFramerateLimit(200);

     while(App.IsOpened())
     {
         sf::Event Event;
         while (App.GetEvent(Event))
                 {
                         if (Event.Type == sf::Event::Closed)
                         {
                             App.Close();
                         }

                         if(Event.Type == sf::Event::KeyPressed && Event.Key.Code == sf::Key::Up)
                         {
                             x = x + lenght * cos(angle*PI/180);
                             y = y - lenght * sin(angle*PI/180);

                         }

                         if(Event.Type == sf::Event::KeyPressed && Event.Key.Code == sf::Key::Down)
                         {
                             x = x - lenght * cos(angle*PI/180);
                             y = y + lenght * sin(angle*PI/180);
                         }

                         if(Event.Type == sf::Event::KeyPressed && Event.Key.Code == sf::Key::Right)
                         {
                             angle += 1;

                             Gun.Rotate(1);
                         }
                         
                         if(Event.Type == sf::Event::KeyPressed && Event.Key.Code == sf::Key::Left)
                         {
                             angle -= 1;

                             Gun.Rotate(-1);
                         }
                 }

         Gun.SetPosition(x,y);

         App.Clear();
         
         sf::String text("x: " + int2Str(x) + "y: " + int2Str(y) + "angle: " + int2Str(angle)
         + "sprite angle: " + int2Str(Gun.GetRotation()), sf::Font::GetDefaultFont());
         text.SetPosition(0.f,0.f);
         App.Draw(text);
         App.Draw(Gun);
         App.Display();
     }

     return 0;
 }


In math you would do this:
Code: [Select]

x = x + cos(angle)*speed
y = y + sin(angle)*speed

But because in SFML (like in most libraries/languages) the y-coordinate goes down instead of going up like in math, you have to negate the y-coordinate change. So what you actually want to do when the user presses up is this:
Code: [Select]

x = x + cos(angle)*speed
y = y - sin(angle)*speed

And when going backwards, you negate them both
Code: [Select]

x = x - cos(angle)*speed
y = y + sin(angle)*speed

30
General / I need help with this game i am trying to make.
« on: April 25, 2011, 11:03:53 am »
Moving the ball on the certain angle is pretty simple. In the Pong example it's done like this:
Code: [Select]

// Move the ball
            float factor = ballSpeed * window.GetFrameTime();
            ball.Move(std::cos(ballAngle) * factor, std::sin(ballAngle) * factor);

But I find it more natural to do it like this:
Code: [Select]

// Move the ball
            float factor = ballSpeed * window.GetFrameTime();
            ball.Move(std::cos(ballAngle) * factor, -std::sin(ballAngle) * factor);

The only difference is the minus sign. It affects the direction where the ball is going at a certain angle. For example, let's say that the ballAngle is 45. In the first piece of code the ball would travel to the bottom right corner. On the second example it would travel to the upper right corner.

Here's a modification of your code that only moves the ball:
Code: [Select]

include<SFML/Graphics.hpp>
#include <cmath>

#define PI 3.14159

 int main()
 {

     sf::RenderWindow App(sf::VideoMode(1024, 768, 32), "SFML/Graphics");

     sf::Image iBall;
     if (!iBall.LoadFromFile("Ball.png"))
     return EXIT_FAILURE;

     iBall.SetSmooth(false);

     sf::Sprite sBall(iBall);

     sBall.SetRotation(45.f);   // Set some angle to demonstrate that it actually moves as it should
     sBall.SetPosition(App.GetWidth()/2, App.GetHeight()/2);  // Put the ball on the center of the screen

     while (App.IsOpened())
     {
         sf::Event Event;

         while (App.GetEvent(Event))
         {
               
             if (Event.Type == sf::Event::Closed) {
                App.Close(); }
               
             if ((Event.Type == sf::Event::KeyPressed) && (Event.Key.Code == sf::Key::Escape))
                App.Close();
         }

         float speed = 80.f * App.GetFrameTime();    // Calculate the speed to move the ball
         
         sBall.Move(cos(sBall.GetRotation()/180*PI)*speed, -sin(sBall.GetRotation()/180*PI)*speed);  // Move the ball (sBall.GetRotation() gives the angle in degrees so it has to be converted to radians. The formula is degrees/180*PI)

         App.Clear();
         App.Draw(sBall);
         App.Display();
     }



     return EXIT_SUCCESS;
 }


EDIT:
Actually it doesn't really make sense to rotate the ball when there's absolutely no need for it. So this:
Code: [Select]

sBall.SetRotation(45.f);   // Set some angle to demonstrate that it actually moves as it should

Could be changed to this:
Code: [Select]

float ballAngle = 45.f;  // Set some angle to demonstrate that it actually moves as it should

And this:
Code: [Select]

sBall.Move(cos(sBall.GetRotation()/180*PI)*speed, -sin(sBall.GetRotation()/180*PI)*speed);  // Move the ball (sBall.GetRotation() gives the angle in degrees so it has to be converted to radians. The formula is degrees/180*PI)

To this:
Code: [Select]

sBall.Move(cos(ballAngle/180*PI)*speed, -sin(ballAngle/180*PI)*speed);  // Move the ball

Pages: 1 [2]
anything