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

Author Topic: A few Questions..  (Read 22428 times)

0 Members and 2 Guests are viewing this topic.

Father_Sloth

  • Newbie
  • *
  • Posts: 48
    • View Profile
A few Questions..
« Reply #15 on: October 30, 2010, 09:18:26 pm »
thanks. I'm trying currently on the pong collision and I want to do something like this:

Code: [Select]
bool collison;

int angle, response_angle;

bool collision = false;

if (bool collision = true)
{
// Detect what angle it hit the boundary.

???

// Send the ball in the direction of the bounce.

Sprite.Move( //get it to go in response_angle direction.

}



Now that's just me trying to explain how I kinda guess the formats gonna be. Just so you don't think i'm being lazy and stuff.... :D

Heres a diagram:



Simon

Canadadry

  • Hero Member
  • *****
  • Posts: 1081
    • View Profile
A few Questions..
« Reply #16 on: October 30, 2010, 10:20:51 pm »
If the wall is horizontal or vertical, you just have to change a signe in your deplacement vector. Else you will have tu you dot product

Father_Sloth

  • Newbie
  • *
  • Posts: 48
    • View Profile
A few Questions..
« Reply #17 on: October 30, 2010, 10:27:42 pm »
sorry i didn't understand what you said last in that bit but could you write an example code? just so I get wat your saying.

priomsrb

  • Newbie
  • *
  • Posts: 38
    • View Profile
A few Questions..
« Reply #18 on: October 31, 2010, 01:10:56 am »
Actually it is very simple. If the ball hits a horizontal wall (like the ground) you just reverse it's y-velocity. And if the ball hits a vertical wall you reverse it's x-velocity.

Unless you have walls that are angled in different directions, you don't need to do calculations using collision angles and stuff.

Disch

  • Full Member
  • ***
  • Posts: 220
    • View Profile
A few Questions..
« Reply #19 on: October 31, 2010, 05:57:10 am »
you can use some linear algebra for this.

given two vectors A and B:

The dot product (dot(A,B)) = (A.x * B.x) + (A.y * B.y)
Perpendicular dot product (perpdot(A,B)) = (A.y * B.x) - (A.x * B.y)

The neat thing is, dot(A,B) is equal to sin(t)*length(A)*length(B)
and perpdot(A,B) is equal to cos(t)*length(A)*length(B)

(where 't' is the angle between the two vectors... so if the vectors are parallel, PerpDot is zero for example)

This means you can easily get the sin and cos of the impact angle between two lines if you have unit vectors (lines with a length of 1)


Knowing the impact angle, it's just a matter of rotating the "wall" line the opposite way at the same angle.  You can do this with a simple rotation matrix.


But don't let the heavy math jargon deceive you.  It's not really that complicated.  Here's some [untested!!!] code that I'm pretty sure will have the desired effect:

Code: [Select]

// first, some helper functions that no 2d game should be without....

// get's the length of a vector
float GetLength(const sf::Vector2f& v)
{
  return sqrt( (v.x*v.x) + (v.y*v.y) );
}

// dot product
float Dot(const sf::Vector2f& A, const sf::Vector2f& B)
{
  return (A.x*B.x) + (A.y*B.y);
}

// perp dot
float PerpDot(const sf::Vector2f& A, const sf::Vector2f& B)
{
  return (A.y*B.x) - (A.x*B.y);
}

//======================
//  now that those are out of the way....

sf::Vector2f BounceAngle(sf::Vector2f move,sf::Vector2f wall)
{
  // 'move' is how much the object is moving
  // 'wall' is the orientation of the wall
  //  (ie:  wall_point_B - wall_point_A)

  // first find the velocity that the ball is moving at
  float velocity = GetLength(move);

  // then make both move and wall unit vectors
  move /= velocity;
  wall /= GetLength(wall);

  // get the sin(angle) and cos(angle)
  float sintheta = PerpDot(move,wall);
  float costheta = Dot(move,wall);

  // invert the sine so that we rotate in opposite direction
  sintheta = -sintheta;

  // rotate the wall in the opposite direction with a simple rotation matrix
  sf::Vector2f r;
  r.x = (wall.x * costheta) - (wall.y * sintheta);
  r.y = (wall.x * sintheta) + (wall.y * costheta);

  // scale so it has the same velocity as move
  return r * velocity;
}


And there you have it.  BounceAngle will return a vector pointing to the direction the object it to bounce towards -- although it will be a unit vector, so multiply it by whatever speed you want to move the object at.


And again note this code is untested so I can't say for sure it will work without tweaking.  The concept is solid, I just might be off on my math somewheres.


EDIT:  Also, "BounceAngle" is poorly named since it doesn't return an angle.  But whatever.  It's late.

EDIT2:  Changed code so that the velocity is maintained.


EDIT3:  But holy crap this is for pong?  Yeah then this is all overkill.  Just invert the X or Y magnitude as someone else suggested.

Father_Sloth

  • Newbie
  • *
  • Posts: 48
    • View Profile
A few Questions..
« Reply #20 on: October 31, 2010, 11:18:04 am »
Thank you all very much :D.

Yes this is for pong but pong is just for me getting used to the library (as Priomsrb suggested). Immediatly after this I will implement this code into my ultimate project (for the moment at least :D ) which as you can see on page one will be a zombie top down shooter. I'm gonna keep this thread open until it's done and believe me will be asking questions throughout. Thank you for your patience with me and keep on Rocking.

Simon

Side note: Should I
1) Make the walls in like paint and just load them as a sprite.
2) Construct them using a simple shape made by SFML.
3) Do Number 1 but load them as an Image?

priomsrb

  • Newbie
  • *
  • Posts: 38
    • View Profile
A few Questions..
« Reply #21 on: October 31, 2010, 11:29:57 am »
Quote
Side note: Should I
1) Make the walls in like paint and just load them as a sprite.
2) Construct them using a simple shape made by SFML.
3) Do Number 1 but load them as an Image?


Do number 1. You will use sprites in most typical games so it's best to get use to them.

Father_Sloth

  • Newbie
  • *
  • Posts: 48
    • View Profile
A few Questions..
« Reply #22 on: October 31, 2010, 12:24:54 pm »
Also I'm stumped for what the scoring system should be. I want it to be like the typical pong where if you hit the ball behind the bat the opposite player gets +1 to his score. How would I do this. Maybe creating the horizontal boundaries vertical and instead of collision say if they ball and wall collide the opposite players score +1. Is there an easier route?

Simon

priomsrb

  • Newbie
  • *
  • Posts: 38
    • View Profile
A few Questions..
« Reply #23 on: October 31, 2010, 12:34:41 pm »
You could do it that way. Or you could check the ball's x position. If the x position is less than a certain value, say 0, then player 2 should get a point. If the x position is higher than a value, say 640(or whatever your game width is), then player 1 should get a point.

Father_Sloth

  • Newbie
  • *
  • Posts: 48
    • View Profile
A few Questions..
« Reply #24 on: October 31, 2010, 01:09:16 pm »
ahh thanks that's easier. also how do i get the ball to move from spawn/bounce off the players bat. should I just get a random number from a range and jut set that as the x or y of the ball? thanks a lot mate.

Simon

p.s. quick little note - i can't seem to find out how to spawn objects. I've read over the class of Sf:: sprite and it only mentions setPosition which I don't know how to use. Also where should I spawn it. I don't know where it would go without constantly resetting the images - creating a infinite loop.

Father_Sloth

  • Newbie
  • *
  • Posts: 48
    • View Profile
A few Questions..
« Reply #25 on: October 31, 2010, 02:54:48 pm »
hello? I'd like to get this project finished today ..

Canadadry

  • Hero Member
  • *****
  • Posts: 1081
    • View Profile
A few Questions..
« Reply #26 on: October 31, 2010, 05:02:32 pm »
Quote from: "Father_Sloth"
i can't seem to find out how to spawn objects.


I don't get it, what do you wanna do ?

Father_Sloth

  • Newbie
  • *
  • Posts: 48
    • View Profile
A few Questions..
« Reply #27 on: October 31, 2010, 05:08:02 pm »
ahh thank you for replying. When I spawn objects a window pops up momentarily and then closes. Is there any way to keep it open, am I doing anything? I worked out earlier with help from the ever helpful Laurent that it can't find my Graphics. You have xcode - how can I link them?

Simon

Father_Sloth

  • Newbie
  • *
  • Posts: 48
    • View Profile
A few Questions..
« Reply #28 on: October 31, 2010, 05:09:05 pm »
Code: [Select]

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

int main()
{
    // Create main window
    sf::RenderWindow App(sf::VideoMode(640, 480), "Pong");

bool playing;
float Width, Height;

// Load image.
    sf::Image BackgroundImage, BallImage, BoundaryImage, BatImage;
    if (!BackgroundImage.LoadFromFile("Background.bmp") ||
        !BallImage.LoadFromFile("Ball.bmp") ||
!BoundaryImage.LoadFromFile("Boundary.bmp") ||
!BatImage.LoadFromFile("Bat.bmp"))


    {
return EXIT_FAILURE;
    }


// Create the sprites of the background, the paddles and the ball
    sf::Sprite Background(BackgroundImage);
    sf::Sprite LeftPaddle(BatImage);
    sf::Sprite RightPaddle(BatImage);
    sf::Sprite Ball(BallImage);
sf::Sprite BoundaryTop(BoundaryImage);
sf::Sprite BoundaryBot(BoundaryImage);

    // Start game loop
    while (App.IsOpened())
    {
        // Process events
        sf::Event Event;
        while (App.GetEvent(Event))
        {
            // Close window : exit
            if (Event.Type == sf::Event::Closed)
                App.Close();


        }

if (Spawn == True)
{

// Spawn
Background.SetPosition(0.f, 0.f);
Ball.SetPosition(400.f, 300.f);
LeftPaddle.SetPosition(10.f, 300.f);
RightPaddle.SetPosition(760.f, 300.f);
BoundaryTop.SetPosition(10.f, 1.f);
BoundaryBot.SetPosition(10.f, 789.f)
}


if (playing)

{
// Draw Objects
App.Draw(Background);
        App.Draw(LeftPaddle);
        App.Draw(RightPaddle);
        App.Draw(Ball);
App.Draw(BoundaryTop);
App.Draw(BoundaryBot);

// Display Objects on Screen
App.Display();

}

    return EXIT_SUCCESS;
}
}


Please I'm so confused with what code should go where and i what loops.

I want it to go: open game, spawn objects, press spacebar, game starts, if a player scores, +1 to score, when a players score reaches 10 game ends. Once player has scored respawn again.

Simon

Canadadry

  • Hero Member
  • *****
  • Posts: 1081
    • View Profile
A few Questions..
« Reply #29 on: October 31, 2010, 07:19:28 pm »
Okay i get your problem. Your logic is wrong, there is some sophisticated and long way but i'll try to explain it to you.  You must have several main loop. First one which draw you window for selecting game or else. Then when use press space for example you jump into another main loop for playing the game.

Something like that
Code: [Select]

int main()
{
    // Create main window
    sf::RenderWindow App(sf::VideoMode(640, 480), "Pong");
   
   sf::Sprite backgroun; //a backgroun
   [..] //some other thing to make it your taste
   
    // Start game loop
    while (App.IsOpened())
    {
        // Process events
        sf::Event Event;
        while (App.GetEvent(Event))
        {
            // Close window : exit
            if (Event.Type == sf::Event::Closed)
                App.Close();
if(user press space)
{
play(App);
}
         
        }
       
      App.Clear();
      App.Draw(sprite);
      App.Display();
     
   }
   return EXIT_SUCCESS;
}

void play()
{
// creating your sprite for the game
sf::Sprite ball;
[…]

while (App.IsOpened())
    {
        // Process events
        sf::Event Event;
        while (App.GetEvent(Event))
        {
            // Close window : exit
            if (Event.Type == sf::Event::Closed)
                App.Close();
if(user win or loose)
{
return;
}
        }
       
      App.Clear();
      App.Draw(ball);
      App.Display();
   }
}


This this the simpliest way of doing that.

For Xcode you have to drag your data on the resources folder of your project. Normally they will be copied on the resources folder of your App, which must be (if i'm not mistaken) the working dir. I remember reading on the change log that ceylo has change it recently. There is one easy way to know where the working dir is, you should create an new file like "fopen("test","w");" then finding this file. I remember one other thing, last time i checked the working dir by launching manually the app and by lauching in xcode in not the same.