2016-01-13

意識が高いと失敗する

他人に見せれるように整えるのはかなり労力が掛かってしまう。

そこで力尽きるくらいなら、雑にガンガンやって形になってから整理したら良い。

どうせ形になってなけば、他人から興味もそうそう持たれない。

gtkmmとSDL2をくみあわせる

以下のようなコードをLinuxでg++ -std=c++14 a.cpp $(pkg-config sdl2 gtkmm-3.0 --cflags --lib)とコンパイルすれば動く。

Mac, Windows上でも色々修正すれば多分動く。

#include <type_traits>
#include <sigc++/sigc++.h>
#include <iostream>
#include <cmath>
#include <gtkmm.h>
#include <gtkmm/socket.h>
#include <iostream>
#include <cmath>
#include <SDL.h>
#include <X11/Xlib.h>
namespace sigc
{
  template <typename Functor>
    struct functor_trait<Functor, false>
    {
      typedef decltype (::sigc::mem_fun (std::declval<Functor&> (), 
            &Functor::operator())) _intermediate;

      typedef typename _intermediate::result_type result_type;
      typedef Functor functor_type;
    };
}
double spd = 0.05;
int sdl_init(::Window windowid);
bool sdl_loop();

void on_button() { std::cout << "Button" << std::endl; spd += 0.02; }

int main(int argc, char **argv) {
  Gtk::Main kit(argc, argv);

  Gtk::Window main_window;
  Gtk::VBox *vbox = manage(new Gtk::VBox());

  Gtk::Socket *sock = manage(new Gtk::Socket());
  sock->set_size_request(400, 300);
  vbox->pack_start(*sock, true, true);

  auto spin = manage(new Gtk::SpinButton(0.01, 3));
  spin->set_range( 0.0, 100.0);
  spin->set_increments( 0.01, 0.1);
  spin->signal_value_changed().connect([=](){
    spd = spin->get_value();
  });
  vbox->pack_start(*spin, true, true);

  main_window.add(*vbox);
  main_window.show_all();

  Glib::signal_timeout().connect([&]() -> bool {
    std::cout << "Window ID: " << sock->get_id() << std::endl;
    sdl_init(sock->get_id());
    std::cout << "inited!\n";

    Glib::signal_timeout().connect(&sdl_loop, 16);

    return false;
  }, 200);

  Gtk::Main::run(main_window);
  return 0;
}
SDL_Window* window;
SDL_Renderer* render;
int sdl_init(::Window windowid) {


  if (SDL_VideoInit(NULL) < 0) {
    std::cerr << "Couldn't initialize SDL video: " << SDL_GetError()
              << std::endl;
    exit(1);
  }
  window = SDL_CreateWindowFrom((void *)windowid);
  if (!window) {
    std::cerr << "Couldn't create SDL window: " << SDL_GetError() << std::endl;
    exit(1);
  }

  render = SDL_CreateRenderer(window, -1, SDL_RENDERER_SOFTWARE);
  if (!render) {
    std::cerr << "Couldn't create renderer: " << SDL_GetError() << std::endl;
    exit(1);
  }
  SDL_EventState(SDL_SYSWMEVENT, SDL_ENABLE);
  SDL_SetRenderDrawColor(render, 0xA0, 0xA0, 0xA0, 0xFF);
  SDL_RenderClear(render);
  return 0;
}
bool sdl_loop() {

  int const center_x = 200;
  int const center_y = 150;
  int const radius = 100;
  static double rotate = 0.0;

    SDL_Event ev;
    while (SDL_PollEvent(&ev)) {
      if (ev.type == SDL_QUIT)
        return false;
    }
    SDL_SetRenderDrawColor(render, 0, 0, 0, 255);
    SDL_RenderClear(render);
    SDL_SetRenderDrawColor(render, 255, 0, 0, 255);
    rotate += spd;
    SDL_RenderDrawLine(render, center_x + radius * std::cos(rotate),
                       center_y + radius * std::sin(rotate),
                       center_x - radius * std::cos(rotate),
                       center_y - radius * std::sin(rotate));
    SDL_RenderPresent(render);
    //SDL_Delay(12);
    return true;
}

描画はSDL2で行い、そこにgtkmmでGUI部品を付けている。

ゲーム作る時にデバッグ用フォームをこれで出したりとかに良さそうだ。

もちろん、それ目的ならば何かゲームエンジンを使った方が良いが、僕はチマチマ車輪の再実装するのが好きなのだ。

ひとつ上へ