プラットフォームとして、C#+ XNA 4.0、およびレベルエディターのカスタム要素にWinFormsを選択しました。
VisualStudioでWindowsゲームプロジェクトを作成して、お試しください!

0.アーキテクチャ
レベルについては、ゲーム自体とエディターの両方で使用される個別のクラスを作成しました。 便宜上、別のプロジェクトに配置し、両方のソリューションに追加しました。 レベルオブジェクト自体はエディターで作成され、ファイルにシリアル化され、そのファイルからゲームに逆シリアル化されます。
1.インターフェース
先ほど言ったように、WindowsFormsで行ったインターフェイス。 System.Windows.Formsをプロジェクトに接続します。 一部のWindowsFormsクラス名はXnaの名前と競合する可能性があるため、これを実行しましょう
using WinForms = System.Windows.Forms;
MSDNには、WindowsFormsとそのすべてのウィジェットに関する優れた説明がありますので、ここで終わりではありません。 WindowsFormsとXNAの相互作用に問題はありませんでした。 Game1クラス(Xnaゲームクラスの標準名)でプロシージャを作成し、ウィンドウ、ウィジェットを作成してそれらをカスタマイズし、Initialize()メソッドで呼び出します。 私はこのようなものを得ました:

2.レベルクラス
レベルクラスを作成し、シリアル化可能であることを示します。
[Serializable]
public class Level
{
//...
}
このクラスには、すべてのオブジェクトのリストが含まれます(1つのタイプのオブジェクトのみを作成しましたが、他のオブジェクトを追加することは難しくありません)
public List<Block> Blocks = new List<Block>();
public Vector2 cameraPos;
ブロッククラス:
[Serializable]
public class Block
{
[NonSerialized]
public Texture2D tex;
public Rectangle rect;
public Block(Texture2D texture, Rectangle rectangle)
{
this.tex = texture;
this.rect = rectangle;
}
}
また、シリアル化可能である必要がありますが、テクスチャをシリアル化することはできません(そうでない場合はエラー)が、レベルをゲーム自体にロードするときに直接追加することに注意してください(このため、追加のプロパティString Texturename、int TextureTypeなどを作成できます)。
CameraPosは、レベルをスクロールするために必要なカメラの位置を示すベクトルです。
同じクラスで、画面から世界、またはその逆に調整を転送するためのメソッド:
public Vector2 ScreenToWorld(Vector2 vector)
{
Vector2 rvect;
rvect = cameraPos + vector;
return rvect;
}
public Vector2 WorldToScreen(Vector2 vector)
{
Vector2 rvect;
rvect = vector - cameraPos;
return rvect;
}

3.編集者自身
Game1クラスで、現在のツールの説明を作成します。
enum CurrentTool
{
None,
Brick,
Delete
}
CurrentTool currTool = CurrentTool.None;
そして、補助ウィンドウのツール切り替えイベントハンドラーで、currTool変数をユーザーが選択したものに変更します。
ブロックが選択されている場合は、ブロックを作成してウィンドウの周りにドラッグします。マウスでクリックすると、ブロックのリストに追加され、レベルが固定されます。
ブロックを作成するためのツールには、2つの操作モードがあります。自由な場所と、特定の場所、ブロックのサイズの倍数の距離にある場所です。これにより、レベルがより正確になります。
ウィンドウのスクロール:
if (Keyboard.GetState().IsKeyDown(Keys.Left) && lastKeyboardState.IsKeyUp(Keys.Left))
{
level.cameraPos += new Vector2(-10, 0);
}
//
必要な場合(描画、オブジェクトの追加など)に、画面座標から世界座標へ、またはその逆に変換するときは忘れないでください。
4.レベルの保存/読み込み。
[保存] / [ロード]ボタンをクリックするためのハンドラーで、ロードと保存を操作するクラスメソッドを呼び出します。
using System.Runtime.Serialization.Formatters.Binary;
using System.IO;
namespace LevelLib
{
public static class SaveOpenLevel
{
public static Level OpenLevel(string filename)
{
Level level;
if (filename == "")
{
return null;
}
if (!File.Exists(filename))
{
return null;
}
BinaryFormatter bf = new BinaryFormatter();
Stream fs = new FileStream(filename, FileMode.Open);
level = (Level)bf.Deserialize(fs);
fs.Close();
return level;
}
public static int SaveLevel(string filename, Level level)
{
if (filename == "")
{
return 1;
}
BinaryFormatter bf = new BinaryFormatter();
Stream fs = new FileStream(filename, FileMode.Create);
bf.Serialize(fs, level);
fs.Close();
return 0;
}
}
}
* This source code was highlighted with Source Code Highlighter.
レベルで作業するためのプロジェクトにこのクラスがあります(レベル、ブロックなどと同じ場所に)
ゲームではthis.level = OpenLevel( "foo.lvl")を実行しますが、ブロックにテクスチャを追加することを忘れないでください。
次に、レベルとプレイヤーの相互作用を処理します(現在のところ、これはこれに限定されています:
foreach(Block block in level.blocks)
{
if(block.Intersets(player.Rectangle)
return true;
}
)
5.あとがき
これが、レベルエディターのフレームワークの作成方法です。 これで、他のオブジェクトを追加し、展開できます。
ずさんな/ lyい/曲がったコードを誓わないでください。
スクリーンショット、これらのブロックをステージに投げることができるプロジェクトとゲーム自体を投稿します。レベルごとに実行することはできません。今はレイアウトできませんが、今は生です。 デフォルトでは、ゲームのバイナリックを持つフォルダーからTest.levという名前のevelをロードし、エディターはファイル全体を含むフォルダーにファイルを保存するため、レベルファイルを転送する必要があります。 それ以外の場合は、ソースのレベル名を修正する必要があります(すべてのソースが添付されます)。
skydriveへのリンク(7z形式のファイル)
narod.ru(zip形式のファイル)-7zipを持っていない人向け

UPD:記事にファイルを追加しました。