by: 呂家睿
| difficulty | limit | editor/GUI | |
|---|---|---|---|
| Game Engine | dependent, large | full set | |
| Game Framework | fine but depend on libraries | no or minimal | |
| Graphic API | same but free-er | not at all |
Simple Fast Multimedia Library
WHY SFML????
based on C99(a version of C)
can do both 2D and 3D
More Details For SFML
(can skip for school)
1-1. search "vscode" and click the website
1-2. click the download button on the top right
(can skip for school)
1-3. download the one for your OS
1-4. open the thing you downloaded, hit agree, and just keep going next step, and finally hit install
(can skip for school)
2-1. install c++ extensions in vscode
2-2. install MinGW-x64 on windows
basically, just open the installer and follow it.
**This is for windows OS only**
(can skip for school)
2-3.MinGW command prompt stuff
once you finished the download, a command prompt will appear
do the following:
pacman -S --needed base-devel mingw-w64-ucrt-x86_64-toolchain
(can skip for school)
2-4.adding path
//the path for default settings will be:
C:\msys64\ucrt64\bin(can skip for school)
2-5.checking
gcc --version
g++ --version
gdb --versionstill can't figure out?
Step 3. Install the library
3-2. unzip the file you downloaded to a location you will remember
3-3. create a folder for sfml project
inside the folder create a main.cpp file
run it
Yes you can also use visual studio
its good but not for this class
4-1. dependencies
inside your sfml project folder create a folder called dependencies and paste your include and lib folders inside it.
ignore this
4-2.paste the tutorial code in your main.cpp file (it's normal that you see an error)
//this is the tutorial code
#include <SFML/Graphics.hpp>
int main()
{
sf::RenderWindow window(sf::VideoMode({200, 200}), "SFML works!");
sf::CircleShape shape(100.f);
shape.setFillColor(sf::Color::Green);
while (window.isOpen())
{
while (const std::optional event = window.pollEvent())
{
if (event->is<sf::Event::Closed>())
window.close();
}
window.clear();
window.draw(shape);
window.display();
}
}4-3.put your mouse on the error
vscode will show a recommendation
click quick fix -> include path settings
-> c_cpp_properties.json
4-4. in the c_cpp_properties json file
there's an "includePath" section
add in this:
"${workspaceFolder}/dependencies/include"
don't forget the comma and to save
4-4.open the tasks.json file
<------paste this in the arg section
"-fdiagnostics-color=always",
"-g",
"${file}",
"-I\"${workspaceFolder}/dependencies/include\"",
"-DSFML_STATIC",
"-o",
"${fileDirname}\\${fileBasenameNoExtension}.exe",
"-L\"${workspaceFolder}/dependencies/lib\"",
"-lsfml-graphics-s",
"-lsfml-window-s",
"-lsfml-audio-s",
"-lsfml-network-s",
"-lsfml-system-s",
"-lfreetype",
"-lopengl32",
"-lwinmm",
"-lgdi32",
"-lflac",
"-lvorbisenc",
"-lvorbisfile",
"-lvorbis",
"-logg",
"-lws2_32"you should find your tasks.json here
If you did it, congrats!!!
if you didn't, its normal to fail at first,
be sure to follow the steps, if you still can't figure it out, check out the videos and resources
This window should pop out after you run main.cpp
(maybe not that simple)
Practice!!!!
Pizza ordering program:
You’re running a small pizza shop and want to analyze your daily orders. Write a program that:
Asks how many pizza orders were made that day (max 50).
For each order, enter how many slices the customer ordered.
After all orders:
Calculate total slices sold
Calculate average slices
Find the largest single order
Count how many customers ordered more than 10 slices
Sample Answer:
#include <iostream>
int main()
{
const int MAX_ORDERS = 50;
int order_count;
int slices[MAX_ORDERS];
int total_slices = 0;
int max_slices = 0;
int eat_a_lot = 0;
do
{
std::cout << "Enter number of pizza orders today (max 50): ";
std::cin >> order_count;
} while (order_count < 1 || order_count > MAX_ORDERS);
for (int i = 0; i < order_count; i++)
{
std::cout << "Enter slices ordered for customer " << (i + 1) << ": ";
std::cin >> slices[i];
total_slices += slices[i];
if (slices[i] > max_slices)
{
max_slices = slices[i];
}
if (slices[i] > 10)
{
eat_a_lot++;
}
}
float average_slices = static_cast<float>(total_slices) / order_count;
std::cout << "\n--------------- Pizza Order Summary ---------------\n";
std::cout << "Total slices sold: " << total_slices << '\n';
std::cout << "Average slices per order: " << average_slices << '\n';
std::cout << "Largest order: " << max_slices << " slices\n";
std::cout << "Customers who ordered more than 6 slices: " << eat_a_lot << '\n';
return 0;
}
a chunk of code that can do sth
can be used repeatedly
makes your code neat
arguments and parameters
ex: printf(), sum()
#include <iostream>
#include <cmath>
double hypotenuse(double side_1, double side_2)//declaration
{
//definition
double hyp = sqrt(side_1*side_1 + side_2*side_2);
return hyp;
}
void hello()//declaration
{
//definition
std::cout << "Hello~~~!\n";
}
int main()
{
double a, b;
hello();
std::cout << "Enter side a of the right triangle: ";
std::cin >> a;
std::cout << "Enter side b of the right triangle: ";
std::cin >> b;
std::cout << "The hypotenuse of the triangle is " << hypotenuse(a,b);
return 0;
}built in library, just using it for the square root funciton
function's return type
function's name
parameters ( or variables declared inside a function) are used to pass arguments into the function
things that you do inside the function
return's the value(hyp in this case) and ends the function
the void type means the function returns nothing
a and b are arguments passed into the function
#include <iostream>
#include <cmath>
double hypotenuse(double side_1, double side_2);
void hello();
int main()
{
double a, b;
hello();
std::cout << "Enter side a of the right triangle: ";
std::cin >> a;
std::cout << "Enter side b of the right triangle: ";
std::cin >> b;
std::cout << "The hypotenuse of the triangle is " << hypotenuse(a,b);
}
double hypotenuse( double side_1, double side_2)
{
double hyp = sqrt(side_1*side_1 + side_2*side_2);
return hyp;
}
void hello()
{
std::cout << "Hello~~~!\n";
}You can also define them below the main function
But remember to declare them at the top or an error will occur
#include <iostream>
class Car
{
public:
std::string brand;
std::string color;
int price = 0;
int horse_power = 0;
void check();
};
void Car::check()
{
std::cout << "This is a " << color << ' ' << brand << '\n';
std::cout << "It is " << price << "$ "<< "and has a horse power of " << horse_power << '\n';
}
int main()
{
Car a;
a.brand = "Toyota";
a.color = "red";
a.price = 500000;
a.horse_power = 100;
Car b;
b.brand = "Benz";
b.color = "white";
b.price = 3000000;
b.horse_power = 250;
a.check();
b.check();
return 0;
}Defining a class
the class' (Car's) variable
the class' (Car's)
function
let a be an object of the Car class
an object can has its own variable(it needs to be in the class)
defining Car's check function
#include <iostream>
class Cup
{
public:
Cup(std::string c, std::string s);
std::string color;
std::string size;
};
Cup::Cup(std::string c = "white", std::string s = "big")
{
color = c;
size = s;
std::cout << "Hmm seems like you have a " << size << " " << color << " cup!\n";
}
int main(){
Cup glass_cup("red", "big");
std::cout << glass_cup.color << '\n';
return 0;
}the constructor function
the constructor function has the same name as the class
creating an object
it doesn't have a type(not even void)
#include <iostream>
class Cup
{
public:
Cup(std::string c, std::string s);
~Cup();
std::string color;
std::string size;
};
Cup::Cup(std::string c , std::string s)
{
color = c;
size = s;
std::cout << "Hmm seems like you have a " << size << " " << color << " cup!\n";
}
Cup::~Cup()
{
std::cout << "Nooooo~~~\n";
std::cout << "You killed a " << size << " " << color << " cup\n";
}
int main()
{
Cup glass_cup("red", "big");
std::cout << glass_cup.color << '\n';
return 0;
}the destructor function
~(class name)
cannot take arguments
also no return type
(just a little bit)
#include <SFML/Graphics.hpp>
int main()
{
sf::RenderWindow window(sf::VideoMode({800, 600}), "Makin Shapes");
sf::CircleShape circle(100.f);
while (window.isOpen())
{
window.clear(sf::Color(0, 170, 255, 100));
window.draw(circle);
window.display();
}
}Creating a window
class
object
size of window
name of window
Creating a shape
radius
Game Loop
clear window
draw on buffer
display(switch buffer)
Initialization
Code Result
sf::CircleShape circle(100.f);
circle.setPosition({200.f, 300.f});
circle.setFillColor(sf::Color(0, 150, 150));
circle.setOutlineColor(sf::Color::Black);
circle.setOutlineThickness(10.f);
circle.setScale({2.f, 1.f});
circle.setRotation(sf::degrees(45)); sf::CircleShape circle(100.f);
circle.setPosition({200.f, 300.f});
circle.setOrigin({100.f, 100.f});
circle.setFillColor(sf::Color(0, 150, 150));
circle.setOutlineColor(sf::Color::Black);
circle.setScale({2.f, 1.f});
circle.setOutlineThickness(10.f);
circle.setRotation(sf::degrees(45));(200,300)
(200,300)
sf::RectangleShape rect({200.f, 100.f});
rect.setOrigin({100.f, 50.f});
rect.setFillColor(sf::Color(255,215,0));
rect.setOutlineColor(sf::Color::Yellow);
rect.setOutlineThickness(-5.f);
// rect.setScale({0.5f, 1.5f});
// rect.setRotation(sf::degrees(90));
rect.setPosition({400.f, 300.f});sf::CircleShape pentagon(100.f, 5);
pentagon.setPosition({400.f, 300.f});
pentagon.setOrigin({100.f, 100.f});
pentagon.setFillColor(sf::Color(0, 150, 150));
pentagon.setOutlineColor(sf::Color(255, 215, 0));
pentagon.setOutlineThickness(10.f);number of vertice
sf::CircleShape circle(100.f, 20);
circle.setPosition({400.f, 300.f});
circle.setOrigin({100.f, 100.f});sf::CircleShape rounder_circle(100.f);
rounder_circle.setPosition({400.f, 300.f});
rounder_circle.setOrigin({100.f, 100.f});sf::ConvexShape shape;
shape.setPointCount(5);
shape.setPoint(0, {60.f, 20.f});
shape.setPoint(1, {20.f, 100.f});
shape.setPoint(2, {100.f, 100.f});
shape.setPoint(3, {150.f, 60.f});
shape.setPoint(4, {100.f, 20.f});Order!!!
Point number
coords
sf::ConvexShape triangle;
triangle.setPointCount(3);
triangle.setPoint(0, {60.f, 20.f});
triangle.setPoint(1, {500.f, 100.f});
triangle.setPoint(2, {100.f, 350.f});sf::ContextSettings settings;
settings.antiAliasingLevel = 8;
sf::RenderWindow window(sf::VideoMode({800, 600}), "Makin Shapes", sf::Style::Default, sf::State::Windowed, settings);+
Location
same layer
sf::Texture player_texture;
player_texture.loadFromFile("Assets/Player/Texture/sprite_sheet.png");
sf::Sprite player_sprite(player_texture);Location
bool
Better pic maybe?
sf::Texture player_texture;
sf::Sprite player_sprite(player_texture);
if(player_texture.loadFromFile("Assets/sprite_sheet.png"))
{
std::cout << "Player Image Loaded\n";
player_sprite.setTexture(player_texture);
player_sprite.setTextureRect(sf::IntRect({0, 0}, {64, 64}));
player_sprite.setScale({2.f, 2.f});
}
else
{
std::cout << "Player Image Failed to Load\n";
}No default constructor
(0, 0)
64px
64px
for debugging
#include <SFML/Graphics.hpp>
#include <iostream>
int main()
{
sf::ContextSettings settings;
settings.antiAliasingLevel = 8;
sf::RenderWindow window(sf::VideoMode({800, 600}), "Makin Shapes", sf::Style::Default, sf::State::Windowed, settings);
sf::Texture player_texture;
sf::Sprite player_sprite(player_texture);
if(player_texture.loadFromFile("Assets/sprite_sheet.png"))
{
std::cout << "Player Image Loaded\n";
player_sprite.setTexture(player_texture);
player_sprite.setTextureRect(sf::IntRect({0, 0}, {64, 64}));
player_sprite.setScale({2.f, 2.f});
}
else
{
std::cout << "Player Image Failed to Load\n";
}
while (window.isOpen())
{
window.clear(sf::Color(0, 170, 255, 100));
window.draw(player_sprite);
window.display();
}
}Loop
clear
draw
display
Init
window
player
while (window.isOpen())
{
while (std::optional event = window.pollEvent())
{
if (event->is<sf::Event::Closed>())
{
window.close();
}
}
window.clear(sf::Color(0, 170, 255, 100));
window.draw(player_sprite);
window.display();
}Closed
Resized
Poll Event
if (const auto* keyPressed = event->getIf<sf::Event::KeyPressed>())
{
if (keyPressed->scancode == sf::Keyboard::Scan::D)
{
sf::Vector2f player_position = player_sprite.getPosition();
player_sprite.setPosition(player_position + sf::Vector2f(1.f, 0.f));
}
}Slow
Polling Rate
while (window.isOpen())
{
while (const std::optional event = window.pollEvent())
{
if (event->is<sf::Event::Closed>())
{
window.close();
}
}
if (sf::Keyboard::Key::D)
{
sf::Vector2f player_position = player_sprite.getPosition();
player_sprite.setPosition(player_position + sf::Vector2f(1.f, 0.f));
}
window.clear(sf::Color(0, 170, 255, 100));
window.draw(player_sprite);
window.display();
}Fast & Smooth
#include <SFML/Graphics.hpp>
#include <iostream>
int main()
{
sf::ContextSettings settings;
settings.antiAliasingLevel = 8;
sf::RenderWindow window(sf::VideoMode({800, 600}), "Makin Shapes", sf::Style::Default, sf::State::Windowed, settings);
window.setVerticalSyncEnabled(true);
sf::Texture player_texture;
sf::Sprite player_sprite(player_texture);
if(player_texture.loadFromFile("Assets/sprite_sheet.png"))
{
std::cout << "Player Image Loaded\n";
player_sprite.setTexture(player_texture);
player_sprite.setTextureRect(sf::IntRect({0, 0}, {64, 64}));
player_sprite.setScale({2.f, 2.f});
}
else
{
std::cout << "Player Image Failed to Load\n";
}
while (window.isOpen())
{
while (const std::optional event = window.pollEvent())
{
if (event->is<sf::Event::Closed>())
{
window.close();
}
}
if (sf::Keyboard::isKeyPressed(sf::Keyboard::Key::D))
{
sf::Vector2f player_position = player_sprite.getPosition();
player_sprite.setPosition(player_position + sf::Vector2f(1.f, 0.f));
}
window.clear(sf::Color(0, 170, 255, 100));
window.draw(player_sprite);
window.display();
}
}
Frame Rate Control
sfml simple stuff - video
sfml rpg game(visual studio) - video
sfml tutorial -official website
OpenGameArt- open access game art
**remember to pay attention to every information's version**