Nesse vídeo criamos uma animação que pode servir como protótipo de introdução de jogo. O mais interessante é que tentamos mostrar código equivalente entre C++ e JavaScript.
O vídeo não tem fala, só música de fundo, efeitos de som e código passo a passo em ambas linguagens de programação.
animation.hpp
#pragma once
#include <SFML/Graphics.hpp>
#include <cmath>
#include <memory>
class Animation {
std::unique_ptr<sf::RenderWindow> window;
public:
Animation();
static constexpr int numpoints = 200;
struct Point {
sf::CircleShape shape;
float phase;
};
sf::VertexArray gradient;
std::vector<Point> points;
float time;
sf::Clock clock;
sf::Text h1, h2;
sf::Font font;
void background();
void update_points();
void events();
void draw();
void run();
};
animation.cpp
#include "animation.hpp"
Animation::Animation(){
window = std::make_unique<sf::RenderWindow>(
sf::VideoMode(1280,720),
"Animation :: C++ vs JS",
sf::Style::Titlebar | sf::Style::Close
);
background();
time = 0.f;
points.resize(numpoints);
for (size_t i {}; i < numpoints; ++i){
points[i].shape = sf::CircleShape(3);
points[i].phase = i * 0.3;
}
font.loadFromFile("./font.ttf");
h1.setFont(font);
h2 = h1;
h1.setString("Start Game");
h1.setCharacterSize(30);
h1.setPosition(window->getSize().x / 2.f - 150.f, window->getSize().y / 2.f);
h2.setString("Play");
h2.setCharacterSize(18);
h2.setPosition(window->getSize().x / 2.f - 50.f, window->getSize().y / 2.f + 50.f);
}
void Animation::background(){
gradient.setPrimitiveType(sf::TriangleFan);
gradient.append(
sf::Vertex(
sf::Vector2f(
window->getSize().x / 2.f,
window->getSize().y / 2.f),
sf::Color(63,94,251)
)
);
for (int angle {}; angle <= 360; angle += 5){
float rad = angle * 3.14159f / 180.f;
float x = window->getSize().x / 2.f + cos(rad) * window->getSize().x;
float y = window->getSize().y / 2.f + sin(rad) * window->getSize().y;
gradient.append(sf::Vertex(sf::Vector2f(x,y), sf::Color(252,70,107)));
}
}
void Animation::events(){
sf::Event event;
while(window->pollEvent(event)){
if(event.type == sf::Event::Closed){
window->close();
}
}
}
void Animation::run(){
while(window->isOpen()){
events();
time = clock.getElapsedTime().asSeconds() * 2.3f;
draw();
}
}
void Animation::draw(){
window->clear();
window->draw(gradient);
update_points();
for(const auto &var : points){
window->draw(var.shape);
}
window->draw(h1);
window->draw(h2);
window->display();
}
void Animation::update_points(){
for (int i {}; i < numpoints; ++i){
float x = std::sin(time + i * 0.3f) * 200 + window->getSize().x / 2.f;
float y = std::cos(time + i * 0.5f) * 200 + window->getSize().y / 2.f;
points[i].shape.setPosition(x, y);
float alpha = std::sin(i * 0.1f) * 0.5f + 0.5f;
points[i].shape.setFillColor(sf::Color(255, 255, 255, static_cast<sf::Uint8>(alpha * 255)));
}
}
main.cpp
#include "animation.hpp"
int main(){
auto anime = std::make_unique<Animation>();
anime->run();
return EXIT_SUCCESS;
}
Clique aqui para fazer download da fonte uttilizada
Compile rode:
g++ main.cpp animation.cpp -lsfml-graphics -lsfml-window -lsfml-system
./a.out
index.html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Animation :: C++ vs JS</title>
<link rel="stylesheet" href="./style.css">
</head>
<body>
<div class="background"></div>
<div class="content">
<h1>Start Game</h1>
<h2>Play</h2>
</div>
<script src="./main.js"></script>
</body>
</html>
style.css
@font-face {
font-family: 'Font';
src: url('./font.ttf');
}
body, html {
margin: 0;
padding: 0;
height: 100%;
overflow: hidden;
font-family: 'Font';
}
.background {
position: absolute;
width: 100%;
height: 100%;
background: radial-gradient(circle, rgba(63,94,251,1) 0%, rgba(252,70,107,1) 100%);
z-index: -1;
}
canvas {
position: absolute;
top: 0;
left: 0;
width: 100%;
height: 100%;
}
.content {
position: relative;
z-index: 1;
color: white;
text-align: center;
top: 50%;
transform: translateY(-50%);
}
main.js
class Animation{
constructor(){
this.canvas = document.createElement('canvas')
document.body.appendChild(this.canvas)
this.ctx = this.canvas.getContext('2d')
this.resizeCanvas()
window.addEventListener('resize', () => this.resizeCanvas())
}
resizeCanvas = () => {
this.canvas.width = window.innerWidth;
this.canvas.height = window.innerHeight;
}
animate = () => {
this.ctx.clearRect(0, 0, this.canvas.width, this.canvas.height)
const time = Date.now() * 0.002;
for (let i = 0; i < 200; i++) {
const x = Math.sin(time + i * 0.3) * 200 + this.canvas.width / 2
const y = Math.cos(time + i * 0.5) * 200 + this.canvas.height / 2
this.ctx.fillStyle = `rgba(255, 255, 255, ${Math.sin(i * 0.1) * 0.5 + 0.5})`
this.ctx.beginPath()
this.ctx.arc(x, y, 3, 0, Math.PI * 2)
this.ctx.fill()
}
requestAnimationFrame(this.animate)
}
}
const anime = new Animation()
anime.animate()
Abra no navegador:
xdg-open index.html