やねうらおさんが、とある企画で10分でプログラムを書いて、音ゲーを開発しました。
https://twitter.com/yaneuraou/status/1207452237867274241
C#で書かれたソースコードを簡単に解説します。
以下のファイルをダウンロードします。
https://drive.google.com/file/d/12nwe7rtlxSi0km4w8kjK3QFZpxUijvF4/view
ブロックを解除し、解凍します。[遊び方.txt]は説明書、[YomiiMusicGame.exe]は音ゲー本体、[sourse\Form1.cs]はプログラムのメインとなるソースコードです。
[bmp]フォルダには表示する画像が格納されています。全部で10枚あり、[0.bmp]から連番になっています。
using System;using System.Collections.Generic;using System.Diagnostics;using System.Drawing;using System.IO;using System.Windows.Forms;namespace YomiiMusicGame{ public partial class Form1 : Form { const int IMAGE_WIDTH = 1024; // 流してくる画像の横幅 const int FPS = 30; // ゲームの1秒間の描画フレーム数 const int SCROLL_OFFSET = 256; // ゲーム開始時のX軸方向のオフセット量 public Form1() { InitializeComponent(); // 画像ファイル名。bmpフォルダにある、0.bmp , 1.bmp , … Func<int, string> bmp_name = i => "bmp/" + i.ToString() + ".bmp"; using (var formG = this.CreateGraphics()) { bg = new Bitmap(bmp_name(0)); // 背景画像は"0.bmp" bg.SetResolution(formG.DpiX, formG.DpiY); // dpi independentにする // 番号に対応する画像ファイルが見つからなくなるまで画像を読み込み続ける。 for (int i = 1; File.Exists(bmp_name(i)); ++i) { var bitmap = new Bitmap(bmp_name(i)); bitmap.MakeTransparent(Color.FromArgb(34, 177, 76)); // MS Paintの緑色を抜き色とする bitmap.SetResolution(formG.DpiX, formG.DpiY); // dpi independentにする bitmaps.Add(bitmap); } NUMBER_OF_IMAGES = bitmaps.Count; } } private void Button1_Click(object sender, EventArgs e) { button1.Enabled = false; timer = new System.Windows.Forms.Timer(); timer.Interval = 1000/FPS; timer.Tick += new EventHandler(Timer1_Tick); timer.Start(); bpm = int.Parse(textBox1.Text); textBox1.Enabled = false; pictureBox1.Image = new Bitmap(pictureBox1.Width, pictureBox1.Height); pictureBox1.Paint += new PaintEventHandler(PictureBox_Paint); sw = new Stopwatch(); sw.Start(); } private void Timer1_Tick(object Sender, EventArgs e) { pictureBox1.Invalidate(); } private void PictureBox_Paint(object sender, PaintEventArgs e) { var g = e.Graphics; g.DrawImage(bg, 0, 0); double elapsed = sw.Elapsed.TotalMilliseconds; // スクロールさせるドット数を計算する。1枚の画像は4小節(4/4で16拍分)であるとする。 int scroll = (int)(IMAGE_WIDTH * (bpm / 16) * elapsed / (1000 * 60)); int page = scroll / IMAGE_WIDTH; int x = scroll % IMAGE_WIDTH; if (page < bitmaps.Count) g.DrawImage(bitmaps[page], - x + SCROLL_OFFSET, 0); if (page + 1 < bitmaps.Count) g.DrawImage(bitmaps[page + 1], - x + SCROLL_OFFSET + IMAGE_WIDTH, 0); } // 画像の枚数("1.bmp","2.bmp",…と、ファイルが存在する分だけすべて使う) int NUMBER_OF_IMAGES = 0; // 背景画像 Bitmap bg; // 流す画像 List<Bitmap> bitmaps = new List<Bitmap>(); // 1分間の4分音符の数 int bpm; // 描画用interval timer System.Windows.Forms.Timer timer; // スクロール計測用のGame Timer Stopwatch sw; }}