Hey, everybody. :] Since I'm new at making games and also new with using SFML, I thought I'd share my first (well, second...) game that I've made using it. (The first game could hardly be called a game. It was just a little "game" where you shoot a devil sprite that follows you around. That project was more of an experiment with different techniques that just evolved into a crappy little program eventually. :p
But I made Pong, at least a watered-down version of it. Here's the source, if anyone wants to compile it and have a mess-around with it:
/* This game is basically a simple remake of Pong. It will be for two players. */
#include <SFML/Graphics.hpp>
#include <SFML/Window.hpp>
#include <SFML/System.hpp>
// Function prototypes
int distance(int, int, int, int);
void getInput(int&, int&, int&, int&, sf::Clock&, sf::Clock&);
void calculateBall(int&, int&, sf::Clock&, int&, int&, int&);
// ENUMS
enum BallDirection // Different directions/velocities
{
UpRight, DownRight, UpLeft, DownLeft
};
enum PaddleDirection // Different directions/velocities
{
Up, Down, Still
};
// ************ //
// Paddle structure declaration
struct Paddle
{
int x, y; // Paddle coordinates, upper left
int botx, boty; // Paddle coordinates, bottom right
int direction; // Paddle going up or down?
sf::Clock PaddleTimer; // Movement timer
Paddle(int xcoord, int ycoord, int bottomx, int bottomy, PaddleDirection direc) // Constructor
{
x = xcoord;
y = ycoord;
botx = bottomx;
boty = bottomy;
direction = direc;
}
};
// Ball structure declaration
struct Ball
{
int x, y; // Ball's position in the field
int size; // Ball's size
int direction; // Ball's current direction/velocity
double speed; // Speed (less is more)
sf::Clock BallTimer; // Movement timer
Ball(int xcoord, int ycoord, int ballSize, double ballSpeed = 0.7)
{
x = xcoord;
y = ycoord;
size = ballSize;
}
};
// Render window declaration
sf::RenderWindow App(sf::VideoMode(800, 600), "T4 Pong");
// View declaration -- Atari resolution
sf::View View(sf::FloatRect(0, 0, 192, 160));
// Event Receiver
sf::Event Event;
// Input Receiver
const sf::Input& Input = App.GetInput();
// Player and ball declarations
// **PLAYER 1**
Paddle Player1(5, 60, 7, 70, Still);
// **PLAYER 2**
Paddle Player2(184, 60, 186, 70, Still);
// **BALL**
Ball Ball(80, 80, 2);
int main()
{
// Score variable
int score1 = 0, score2 = 0;
// Start initialization / escape sequences (events)
while (App.IsOpened())
{
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();
}
// Game loop activities
// Process input
getInput(Player1.y, Player1.boty, Player2.y, Player2.boty, Player1.PaddleTimer, Player2.PaddleTimer);
// Calculate ball
calculateBall(Ball.x, Ball.y, Ball.BallTimer, Ball.direction, score1, score2);
// Clear previous screen
App.Clear();
// Draw the paddles and the ball
App.Draw(sf::Shape::Rectangle(Player1.x, Player1.y, Player1.botx, Player1.boty, sf::Color::White));
App.Draw(sf::Shape::Rectangle(Player2.x, Player2.y, Player2.botx, Player2.boty, sf::Color::White));
App.Draw(sf::Shape::Circle(Ball.x, Ball.y, Ball.size, sf::Color::Blue));
// Set the View
App.SetView(View);
// Display final image
App.Display();
} // End loop
return EXIT_SUCCESS;
} // end main
// Functions and their declarations
// Distance formula
int distance(int x1, int y1, int x2, int y2)
{
int temp = pow((x2 - x1), 2) + pow((y2 - y1), 2);
return sqrt(temp);
}
// Process inputs and move players accordingly
void getInput(int &y1, int &boty1, int &y2, int &boty2, sf::Clock &Pad1, sf::Clock &Pad2)
{
App.GetInput();
if ((Input.IsKeyDown(sf::Key::Up)) && (Pad1.GetElapsedTime() >= 0.01))
{
if (y1 > 0)
{
y1--;
boty1--;
}
Pad1.Reset();
}
else if ((Input.IsKeyDown(sf::Key::Down)) && (Pad1.GetElapsedTime() >= 0.01))
{
if (y1 < 150)
{
y1++;
boty1++;
}
Pad1.Reset();
}
if ((Input.IsKeyDown(sf::Key::Q)) && (Pad2.GetElapsedTime() >= 0.01))
{
if (y2 > 0)
{
y2--;
boty2--;
}
Pad2.Reset();
}
else if ((Input.IsKeyDown(sf::Key::A)) && (Pad2.GetElapsedTime() >= 0.01))
{
if (y2 < 150)
{
y2++;
boty2++;
}
Pad2.Reset();
}
}
// Calculate ball and its movement
void calculateBall(int &x, int &y, sf::Clock& ballTime, int &direc, int &score1, int &score2)
{
if (ballTime.GetElapsedTime() >= 0.03)
{
if (direc == UpRight) // Ball traveling up and to the right?
{
if (x >= 192)
{
score1++;
x = y = 80;
ballTime.Reset();
direc = UpLeft;
}
else if (y <= 3)
{
direc = DownRight;
ballTime.Reset();
}
else if ((x >= 184 && x <= 186) && (y >= Player2.y && y <= Player2.boty))
{
direc = UpLeft;
ballTime.Reset();
}
else
{
y--;
x++;
ballTime.Reset();
}
return;
}
if (direc == DownRight) // Ball traveling down and to the right?
{
if (x >= 192)
{
score1++;
x = y = 80;
ballTime.Reset();
direc = UpLeft;
}
else if (y >= 158)
{
direc = UpRight;
ballTime.Reset();
}
else if ((x >= 184 && x <= 186) && (y >= Player2.y && y <= Player2.boty))
{
direc = DownLeft;
ballTime.Reset();
}
else
{
y++;
x++;
ballTime.Reset();
}
return;
}
if (direc == UpLeft) // Ball traveling up and to the left?
{
if (x <= 0)
{
score2++;
x = y = 80;
ballTime.Reset();
direc = UpRight;
}
else if (y <= 3)
{
direc = DownLeft;
ballTime.Reset();
}
else if ((x >= 5 && x <= 7) && (y >= Player1.y && y <= Player1.boty))
{
direc = UpRight;
ballTime.Reset();
}
else
{
x--;
y--;
ballTime.Reset();
}
return;
}
if (direc == DownLeft) // Ball traveling down and to the left?
{
if (x <= 0)
{
score2++;
x = y = 80;
ballTime.Reset();
direc = UpRight;
}
else if (y >= 158)
{
direc = UpLeft;
ballTime.Reset();
}
else if ((x >= 5 && x <= 7) && (y >= Player1.y && y <= Player1.boty))
{
direc = DownRight;
ballTime.Reset();
}
else
{
y++;
x--;
ballTime.Reset();
}
return;
}
else
return;
}
}
Any critiques of my code would be appreciated. I'm just now getting into classes and objects so I was more comfortable using structures to bundle all the data together. I'm fairly new at C++, so I expect I have much to learn. One of the things I really want to learn is how to make my code as efficient and memory-conserving as possible.
Appreciate the read, guys, and thanks for making such a great library, Laurent! :]
Colton