31
4

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

C++でゲーム開発をやってみた

Last updated at Posted at 2025-12-05

【C++17】まだ誰も使っていない!? 最新のSDL3でテトリスを作ってみた

はじめに

こんにちは!今回は、現在開発が進められている最新の SDL3 (Simple DirectMedia Layer 3) を使って、C++でテトリスを作ってみました。

SDL3はまだプレビュー段階(あるいは開発段階)ですが、SDL2から多くのAPIが刷新され、よりモダンで使いやすくなっています。この記事では、作成したリポジトリの紹介と、SDL3を導入する上でのポイントを共有します。

この記事のコードは全部GitHubにあります

作ったもの

シンプルかつモダンな設計のテトリスです。
Windows, macOS, Linux すべてで動作するように、クロスプラットフォームなビルド環境を整えました。

技術スタック (Tech Stack)

開発にあたって採用した技術は以下の通りです。

  • 言語: C++17
  • ライブラリ: SDL3 (Graphics, Input, Windowing)
  • ビルドツール: CMake
  • パッケージマネージャー: vcpkg

特にこだわったのは vcpkg と CMake の連携です。依存関係の解決を自動化し、git clone してすぐにビルドできる環境を目指しました。

実装のポイント

1. SDL3 の導入 (vcpkg)

SDL3はまだパッケージマネージャーによっては対応していない場合もありますが、vcpkgを使うことで簡単に導入できます。vcpkg.json は以下のように設定しました。

// vcpkg.json の中身をここに貼る(推奨)
{
  "name": "sdl3-tetris",
  "version-string": "0.1.0",
  "dependencies": [
    "sdl3"
  ]
}

2. SDL3 でのレンダリング

SDL2と比べて、SDL3ではレンダラーのAPI名や使い勝手がいくつか変更されています。 今回のプロジェクトでは renderer.cpp に描画周りを集約しました。

// renderer.cpp
void drawBlock(SDL_Renderer *renderer, int x, int y, int color) {
  SDL_FRect rect = {(float)x * BLOCK_SIZE, (float)y * BLOCK_SIZE,
                    (float)BLOCK_SIZE, (float)BLOCK_SIZE};
  SDL_Color blockColor = getColorForBlock(color);
  SDL_SetRenderDrawColor(renderer, blockColor.r, blockColor.g, blockColor.b,
                         blockColor.a);
  SDL_RenderFillRect(renderer, &rect);
  SDL_SetRenderDrawColor(renderer, 0, 0, 0, 255);
  SDL_RenderRect(renderer, &rect);
}

void drawGrid(SDL_Renderer *renderer) {
  for (int y = 0; y < grid.size(); ++y) {
    for (int x = 0; x < grid[y].size(); ++x) {
      if (grid[y][x] != 0) {
        drawBlock(renderer, x, y, grid[y][x]);
      }
    }
  }
}

void drawPiece(SDL_Renderer *renderer, const Piece &piece) {
  for (int y = 0; y < 4; ++y) {
    for (int x = 0; x < 4; ++x) {
      if (piece.shape[y][x] != 0) {
        drawBlock(renderer, piece.x + x, piece.y + y, piece.color);
      }
    }
  }
}

3. ゲームループの設計

game.cpp でメインループを管理し、tetris.cpp にテトリス固有のロジック(ミノの回転や衝突判定)を切り出しています。

// game.cpp
void updateGame(Uint64 &lastFallTime) {
  const Uint64 fallInterval = 500; // ms

  // Update Game State (Gravity)
  if (SDL_GetTicks() - lastFallTime > fallInterval) {
    Piece tempPiece = currentPiece;
    tempPiece.y++;
    if (!checkCollision(tempPiece)) {
      currentPiece = tempPiece;
    } else {
      lockPiece();

      int numCleard = clearLines();
      if (numCleard > 0) {
        switch (numCleard) {
        case 1:
          scores += 100;
          break;
        case 2:
          scores += 200;
          break;
        case 3:
          scores += 400;
          break;
        case 4:
          scores += 1000;
          break;
        }
        std::cout << "Current scores : " << scores << std::endl;
      }

      spawnNewPiece();

      if (checkCollision(currentPiece)) {
        currentState = STATE_GAME_OVER;
      }
    }
    lastFallTime = SDL_GetTicks();
  }
};

// Input
void handleInput(const SDL_Event &event) {
  Piece tempPiece = currentPiece;
  switch (event.key.key) {
  case SDLK_LEFT:
    tempPiece.x--;
    break;
  case SDLK_RIGHT:
    tempPiece.x++;
    break;
  case SDLK_DOWN:
    tempPiece.y++;
    break;
  case SDLK_UP:
    tempPiece.currentRotation = (tempPiece.currentRotation + 1) % 4;
    copyShape(tempPiece.shape,
              ALL_BLOCKS[currentPiece.color - 1][tempPiece.currentRotation]);
    break;
  }
  if (!checkCollision(tempPiece)) {
    currentPiece = tempPiece;
  }
}

苦労した点・ハマった点

  • SDL3の情報不足: まだドキュメントや記事が少ないため、ヘッダーファイルや公式のMigration Guideを読み込む必要がありました。
  • APIの変更: SDL2で慣れ親しんだ関数名が変わっていたり(例: SDL_RenderCopy → SDL_RenderTexture など)、引数の仕様が変わっている点に注意が必要でした。

ビルド方法

このプロジェクトは以下のコマンドだけで簡単にビルドできます。

git clone https://github.com/chirateep/sdl3-tetris.git
cd sdl3-tetris
cmake --preset=default
cmake --build build
./build/SDL3Tetris

おわりに

SDL3はパフォーマンスも向上しており、APIも整理されていて非常に書き心地が良いです。C++でゲームプログラミングを始めたい方、新しい技術に触れてみたい方は、ぜひリポジトリを参考にしてみてください!

GitHub: https://github.com/chirateep/sdl3-tetris

31
4
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
31
4

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?