私は現在、等尺性ゲームを開発する必要がある学校のプロジェクトに取り組んでいます。残念ながら、私の先生はゲーム開発について何も知らないので (すでに新しい学校への切り替えに集中しています)、行き詰まっています。
今は簡単にゲーム マップを描くことができますが、そこで止まってしまいます。キャラクターを追加すると、レンダリングされているのがわかりますが、動かすことができません。おそらく、IsoToScreen と ScreenToIso の数学的問題を台無しにしてしまったのでしょう。
キャラクターを 1px だけ動かそうとすると、何らかの理由ですぐに画面から外れてしまいます。
これは、単純な 2D を 2.5D Isometric に変換するために使用する IsoMath クラスです。
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Audio;
using Microsoft.Xna.Framework.Content;
using Microsoft.Xna.Framework.GamerServices;
using Microsoft.Xna.Framework.Graphics;
using Microsoft.Xna.Framework.Input;
using Microsoft.Xna.Framework.Media;
namespace Beowulf
{
class IsoMath
{
private double tw, th, tx, ty, sx, sy;
public IsoMath(double width, double height)
{
tw = width;
th = height;
}
public Vector2 ScreenToIsoTile(Vector2 start, Vector2 offset, Vector2 screenOriginPoint)
{
Vector2 ret = new Vector2(0, 0);
sx = start.X - (screenOriginPoint.X + offset.X);
sy = start.Y - (screenOriginPoint.Y + offset.Y);
tx = System.Math.Round((sx / (tw * 2)) + (sy / (th * 2))) - 1;
ty = System.Math.Round((-sx / (tw * 2)) + (sy / (th * 2)));
ret.X = (float)tx;
ret.Y = (float)ty;
return ret;
}
public Vector2 ScreenToIsoPoint(float x, float y)
{
Vector2 ret = new Vector2(0, 0);
tx = (x - y) * tw;
ty = (x + y) * th;
ret.X = (float)tx * .5f;
ret.Y = (float)ty * .5f;
return ret;
}
public Vector2 IsoToScreenPoint(float x, float y)
{
Vector2 ret = new Vector2(0, 0);
tx = (x + y) / tw;
ty = (x - y) / th;
ret.X = (float)tx / .5f;
ret.Y = (float)ty * -1;
return ret;
}
public Vector2 ScreenToIso(float x, float y)
{
Vector2 ret = new Vector2(0, 0);
tx = (x - y);
ty = (x + y);
ret.X = (float)tx;
ret.Y = (float)ty;
return ret;
}
public Vector2 IsoToScreen(float x, float y)
{
Vector2 ret = new Vector2(0, 0);
tx = (x + y);
ty = (x - y);
ret.X = (float)tx * .5f;
ret.Y = -(float)ty / 2;
return ret;
}
}
}
私の Player クラスは、 Draw(SpriteBatch sp, vector2 playerPostition); を持つ単なるプレースホルダーです。名前が示すように、指定された位置に文字を描画するメソッド (この位置は、メインの Draw メソッドで事前に計算されます)
これが私のキャラクターを画面に描く方法です。固定された x14,y14 位置 (浮動小数点数) で動作しますが、これら 2 つの値のいずれかに 1f を追加すると、文字がどこにも見つかりません。
Vector2 plPos = isoMath.ScreenToIsoPoint(pl.X, pl.Y);
plPos.X += x;
plPos.Y += y;
pl.Draw(spriteBatch, plPos);
そして、(キャラクターが描画される前に) 次のコードを使用してマップをレンダリングします。大規模な if ステートメントは、画面のタイルをカリングするためのものです。
for (int i = 0; i < scene.width; i++)
{
for (int j = 0; j < scene.height; j++)
{
Vector2 p = isoMath.ScreenToIsoPoint(i, j);
Rectangle r = new Rectangle(0, 0, graphics.PreferredBackBufferWidth, graphics.PreferredBackBufferHeight);
if (r.Contains(new Point((int)(((p.X) + x)), (int)((p.Y) + y))) || r.Contains(new Point((int)((p.X) + x) + tile.Width, (int)((p.Y) + y + tile.Height))) || r.Contains(new Point((int)((p.X) + x) + tile.Width, (int)((p.Y) + y))) || r.Contains(new Point((int)((p.X) + x), (int)((p.Y) + y + tile.Height))))
{
spriteBatch.Draw(tile, new Rectangle((int)((p.X) + x), (int)((p.Y) + y), (int)(tile.Width * 1.02), (int)(tile.Height * 1.02)), Color.White);
}
}
}
十分な情報が提供されていないと思われる場合は、ここ (1.13Mb) をクリックして、プロジェクト全体の zip アーカイブをダウンロードできます。