Skip to content

Instantly share code, notes, and snippets.

@Reputeless
Last active June 10, 2021 13:07
Show Gist options
  • Save Reputeless/87a3656672a2b598999d5ae14c0d0f56 to your computer and use it in GitHub Desktop.
Save Reputeless/87a3656672a2b598999d5ae14c0d0f56 to your computer and use it in GitHub Desktop.
#include <Siv3D.hpp> // OpenSiv3D v0.4.3
// 1 セルのマップチップのサイズ
constexpr int32 ChipSize = 32;
// CSV ファイルからマップを読み込む関数
Grid<int32> LoadCSV(const FilePath& path)
{
CSVData csv(path); // OpenSiv3D v0.6 以降は CSV クラス
if (!csv)
{
throw Error(U"CSV の読み込みに失敗");
}
// 行数
const size_t yCount = csv.rows();
// 1 行目の列数
const size_t xCount = csv.columns(0);
// 二次元配列
Grid<int32> map(xCount, yCount);
for (size_t y = 0; y < yCount; ++y)
{
for (size_t x = 0; x < xCount; ++x)
{
map[y][x] = csv.get<int32>(y, x);
}
}
// 読み込んだマップをコンソールに表示
Console << path;
Console << U"{} x {}"_fmt(xCount, yCount);
Console << map;
return map;
}
// マップを描画する関数
void DrawMapChips(const Grid<int32>& grid, const Texture& texture)
{
for (int32 y = 0; y < grid.height(); ++y)
{
for (int32 x = 0; x < grid.width(); ++x)
{
const int32 mapChip = grid[y][x];
if (mapChip == 0)
{
continue;
}
const int32 chipX = ((mapChip - 1) % 8) * ChipSize;
const int32 chipY = ((mapChip - 1) / 8) * ChipSize;
texture(chipX, chipY, ChipSize, ChipSize).draw(x * ChipSize, y * ChipSize);
}
}
}
// 通過不能なセルを表示する関数
void DrawPassable(const Grid<int32>& grid)
{
// 通過不能なセルを青く塗り、✖ を描く
for (int32 y = 0; y < grid.height(); ++y)
{
for (int32 x = 0; x < grid.width(); ++x)
{
const int32 value = grid[y][x];
if (value == 0) // 通過可能なら何もしない
{
continue;
}
Rect(x * ChipSize, y * ChipSize, ChipSize, ChipSize)
.draw(ColorF(0, 0, 1.0, 0.5));
Shape2D::Cross(ChipSize * 0.3, 4, Vec2(x * ChipSize + ChipSize / 2, y * ChipSize + ChipSize / 2))
.draw(Palette::Red);
}
}
// マス目の線を描く
{
for (int32 y = 0; y < grid.height(); ++y)
{
const int32 yy = (y * ChipSize);
Line(0, yy, static_cast<int32>(grid.width()) * ChipSize, yy).draw(ColorF(0.25));
}
for (int32 x = 0; x < grid.width(); ++x)
{
const int32 xx = (x * ChipSize);
Line(xx, 0, xx, static_cast<int32>(grid.height()) * ChipSize).draw(ColorF(0.25));
}
}
}
void Main()
{
Window::Resize(512, 512);
Scene::SetBackground(ColorF(0, 0, 0));
// https://pipoya.net/sozai/assets/map-chip_tileset32/
Texture forestTile(U"map.png");
// https://github.com/lriki/Siv3D-PixelArt
Texture siv3d_kun(U"Siv3D-kun.png");
const Font font(50);
// 1次レイヤー (地面など)
const Grid<int32> mapLayer1 = LoadCSV(U"map0.csv");
// 2次レイヤー (装飾物など)
const Grid<int32> mapLayer2 = LoadCSV(U"map1.csv");
// 当たり判定
const Grid<int32> mapPassable = LoadCSV(U"map2.csv");
// 現在のセル座標
Point playerCell(1, 1);
// 次に進むセル座標
Point nextCell = playerCell;
// 歩行の速さ
constexpr double walkSpeed = 4.0;
// 歩行の進捗 (移動開始: 0.0, nextCell に到達: 1.0)
double walkProgress = 1.0;
while (System::Update())
{
/////////////////////////////////////
//
// デバッグ表示
//
/////////////////////////////////////
ClearPrint();
Print << U"スペースキーで通過判定可視化";
Print << U"playerCell: " << playerCell;
Print << U"nextCell: " << nextCell;
Print << U"walkProgress: " << walkProgress;
/////////////////////////////////////
//
// 移動に関する処理
//
/////////////////////////////////////
// 現在移動中でない場合、上下左右キーで次に進むセルを変更
if (playerCell == nextCell)
{
if (KeyDown.pressed()) // ↓ キー
{
++nextCell.y;
}
else if (KeyUp.pressed()) // ↑ キー
{
--nextCell.y;
}
else if (KeyLeft.pressed()) // ← キー
{
--nextCell.x;
}
else if (KeyRight.pressed()) // → キー
{
++nextCell.x;
}
// nextCell をマップの範囲内に収める
nextCell.x = Clamp(nextCell.x, 0, 15);
nextCell.y = Clamp(nextCell.y, 0, 15);
// nextCell が通過不能なセルの場合、移動しない
if (mapPassable[nextCell] == 1)
{
nextCell = playerCell;
}
if (playerCell != nextCell)
{
// 移動を開始する場合、歩行の進捗を戻す
walkProgress -= 1.0;
}
else
{
// 移動しない場合、歩行の進捗は 1.0
walkProgress = 1.0;
}
}
// 移動中の場合
if (playerCell != nextCell)
{
// 歩行の進捗を進める
walkProgress += (Scene::DeltaTime() * walkSpeed);
// 歩行の進捗が 1.0 以上になったら
if (1.0 <= walkProgress)
{
// 現在のセルを nextCell にして移動完了
playerCell = nextCell;
}
}
/////////////////////////////////////
//
// 描画処理
//
/////////////////////////////////////
// 1 次レイヤーの描画
DrawMapChips(mapLayer1, forestTile);
// 2 次レイヤーの描画
DrawMapChips(mapLayer2, forestTile);
// 当たり判定の部分に青色を塗る
if (KeySpace.pressed())
{
DrawPassable(mapPassable);
}
{
// テクスチャ拡大描画時にフィルタリングしないサンプラーステートを適用
ScopedRenderStates2D renderState(SamplerState::ClampNearest);
// 小数も含めたセル座標
const Vec2 cellPos = playerCell.lerp(nextCell, walkProgress);
Print << U"cellPos: " << cellPos;
// セル座標を描画座標に変換
const Vec2 pos = (cellPos * ChipSize) + Vec2(ChipSize / 2, ChipSize / 2);
// ノーマル状態 ((x, y) = (20, 0) から横 20, 縦 28) の
// Siv3D くんを 2 倍にして表示
siv3d_kun(20, 0, 20, 28)
.scaled(2.0)
.draw(Arg::bottomCenter(pos.movedBy(0, 14)))
.drawFrame(2, Palette::Red);
}
}
}
1 1 1 1 1 1 1 1 1 4 4 1 1 1 1 1
1 1 1 1 1 1 1 1 1 4 4 1 1 1 1 1
4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4
1 1 1 562 562 562 562 562 562 4 4 1 1 1 1 1
1 1 1 570 570 570 570 570 570 4 4 1 1 1 1 1
1 1 1 578 578 578 578 578 578 4 4 1 1 1 1 1
1 1 1 586 586 586 586 586 586 4 4 1 1 1 1 1
1 1 1 529 529 529 529 529 529 4 4 1 1 1 1 1
1 1 1 537 537 537 537 537 537 4 4 1 1 1 1 1
1 1 1 1 1 1 1 1 1 4 4 1 1 1 1 1
1 1 1 1 1 1 1 1 1 4 4 1 1 1 1 1
1 1 1 1 1 1 1 1 1 4 4 1 1 1 1 1
4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4
4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4
1 1 1 1 1 1 1 1 1 4 4 1 1 1 1 1
1 1 1 1 1 1 1 1 1 4 4 1 1 1 1 1
0 0 0 0 0 0 0 0 0 0 0 153 154 155 156 0
0 0 0 0 189 185 185 185 181 0 0 169 170 171 164 0
0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0 0 0 863 0 863 0
0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
0 0 657 0 594 641 642 594 0 0 0 0 863 0 863 0
0 0 0 0 602 649 650 602 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0 0 0 863 0 863 0
0 0 55 55 0 0 0 0 0 0 0 0 0 0 53 0
0 0 0 0 0 0 0 0 0 0 0 0 0 53 0 0
0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
0 56 56 0 0 0 0 53 53 0 0 0 0 55 0 0
0 0 0 0 0 0 0 0 0 0 0 0 0 0 55 0
0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0
0 0 0 0 1 1 1 1 1 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
0 0 0 1 1 1 1 1 1 0 0 0 0 0 0 0
0 0 0 1 1 1 1 1 1 0 0 0 0 0 0 0
0 0 0 1 1 1 1 1 1 0 0 0 1 0 1 0
0 0 0 1 1 1 1 1 1 0 0 0 0 0 0 0
0 0 0 1 1 1 1 1 1 0 0 0 1 0 1 0
0 0 0 1 1 1 1 1 1 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0 0 0 1 0 1 0
0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
0 1 1 0 0 0 0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment