最初に
少し前に、SDL2で色変化プログラムを書いたのですが、
SFMLでも同じことできたらいいなと思って、
画像の色違いを表現するコードを考えてました
相変わらず説明下手ですがどうか
↓関連記事
【C# + SDL2】色調を用いて、画像の色違いを表現してみるサンプル
https://qiita.com/minion_cs_user/items/43147d3c6ff28cbbdf62
SFML.netを使ってみた
https://qiita.com/minion_cs_user/items/7ffe3b9042dc72152caf
コード全文
/*
レトロゲームでよくある、画像の色違いを表現する
プログラムです
コードはそんなに長くないけど、
一からこれ書くのは結構大変だね
このアルゴリズム、
SFMLの標準機能でついたりしないかな?
*/
using System;
using SFML.Graphics;
using System.IO;
using SFML.Window;
using System.Collections.Generic;
namespace TestProgram {
sealed class Program {
const string errorFilePath = "error.txt";
public static Program Obj { get; } = new Program();
static Random Random { get; } = new Random();
static void Main() {
try { Obj.Start(); }
catch (Exception e) {
File.WriteAllText(errorFilePath, e.Message);
Console.WriteLine(e.Message);
}
}
void Start() {
var window = new RenderWindow(new VideoMode(300, 300), "", Styles.Close);
window.Closed += (sender, e) => window.Close();
window.SetFramerateLimit(60);
//テクスチャ表示用スプライトを作成
var normal = new Sprite(LoadTextureNormal());
normal.Position = new SFML.System.Vector2f(20, 20);
//色違いテクスチャ表示用スプライトを作成
var custom = new Sprite(LoadTextureCustom());
custom.Position = new SFML.System.Vector2f(120, 20);
var group = new List<Sprite>();
//分割されたテクスチャのグループを作成
var group_textures = LoadTextureSplit();
//分割されたテクスチャのグループを表示する際の色配列を作成
var group_color_ary = new Color[group_textures.Length];
for (var i = 0; i < group_color_ary.Length; i++) group_color_ary[i] = GetColorRandom();
foreach (var i in group_textures) {
var sprite = new Sprite(i);
sprite.Position = new SFML.System.Vector2f(220, 20);
group.Add(sprite);
}
while (window.IsOpen) {
window.DispatchEvents();
window.Clear();
//テクスチャを表示
window.Draw(normal);
//テクスチャの色違いを表示
window.Draw(custom);
for(var i = 0; i < group.Count; i++) {
//表示テスト用として、毎フレーム色を変える
group_color_ary[i].R++;
//分割されたテクスチャの表示色を指定
group[i].Color = group_color_ary[i];
//分割されたテクスチャを1つずつ表示
window.Draw(group[i]);
}
window.Display();
}
}
static Color GetColorRandom() {
var r = (byte)Random.Next(byte.MaxValue);
var g = (byte)Random.Next(byte.MaxValue);
var b = (byte)Random.Next(byte.MaxValue);
return new Color(r, g, b);
}
//テクスチャを作成
static Texture LoadTextureNormal() {
return new Texture("test.png");
}
//テクスチャの色違いを作成
static Texture LoadTextureCustom() {
var image = new Image("test.png");
var color_ary2d = new Color[image.Size.X, image.Size.Y];
var old_colors = new List<Color>();
var new_colors = new List<Color>();
for (var i = 0; i < image.Size.X; i++) {
for (var n = 0; n < image.Size.Y; n++) {
var color = image.GetPixel((uint)i, (uint)n);
if (!old_colors.Contains(color)) {
old_colors.Add(color);
new_colors.Add(GetColorRandom());
}
//テクスチャ作成用配列に色を指定
color_ary2d[i, n] = new_colors[old_colors.IndexOf(color)];
}
}
//テクスチャ作成用配列からテクスチャを作成
return new Texture(new Image(color_ary2d));
}
//テクスチャのパーツを分割
static Texture[] LoadTextureSplit() {
var image = new Image("test.png");
var color_ary2d_list = new List<Color[,]>();
var old_colors = new List<Color>();
for (var i = 0; i < image.Size.X; i++) {
for (var n = 0; n < image.Size.Y; n++) {
var color = image.GetPixel((uint)i, (uint)n);
if (!old_colors.Contains(color)) {
old_colors.Add(color);
color_ary2d_list.Add(new Color[image.Size.X, image.Size.Y]);
}
//テクスチャの表示部分は全て白にする
//(色調による色変化ができるため)
color_ary2d_list[old_colors.IndexOf(color)][i, n] = Color.White;
}
}
var ary = new Texture[color_ary2d_list.Count];
for(var i = 0; i < color_ary2d_list.Count; i++) {
////テクスチャ作成用配列からテクスチャを作成
ary[i] = new Texture(new Image(color_ary2d_list[i]));
}
return ary;
}
}
}
最後に
これを一から書くなら
SFMLで書くよりSDL2で書くほうが楽なのかな?