Batalha da Animação: C++ vs JavaScript

⚡ Nesse vídeo criamos uma animação que pode servir como protótipo de introdução de jogo.


Batalha da Animação: C++ vs JavaScript


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.


▶️ Assista ao vídeo


💻 Código C++ criado no vídeo:

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


💻 Código JavaScript

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



cpp javascript sfml html css


Compartilhe


Nosso canal no Youtube

Inscreva-se


Marcos Oliveira

Marcos Oliveira

Desenvolvedor de software
https://github.com/terroo


Crie Aplicativos Gráficos para Linux e Windows com C++

Aprenda C++ Moderno e crie Games, Programas CLI, GUI e TUI de forma fácil.

Saiba Mais

Receba as novidades no seu e-mail!

Após cadastro e confirmação do e-mail, enviaremos semanalmente resumos e também sempre que houver novidades por aqui para que você mantenha-se atualizado!