using System; using System.Collections.Generic; using System.Linq; 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; using Microsoft.Xna.Framework.Net; using Microsoft.Xna.Framework.Storage; namespace MainMap2DTest { /// /// This is a game component that implements IUpdateable. /// public class MainMap : Microsoft.Xna.Framework.GameComponent { // ゲームクラスの宣言 private Game1 thisGame = null; // 共通クラスの宣言 private Common common = null; // 入力管理クラスの宣言 private InputManager inputManager = null; // メインマップ画像の宣言 private Texture2D mainMap01 = null; // コンソール表示領域の設定(x座標、y座標、幅、高さ) private Rectangle consoleRec = Rectangle.Empty; public Rectangle ConsoleRec { get { return consoleRec; } } // マップ表示位置の宣言 private Vector2 mapViewPos = Vector2.Zero; public Vector2 MapViewPos { get { return mapViewPos; } } // マップ表示スケールの宣言 private Vector2 mapViewScale = Vector2.Zero; public Vector2 MapViewScale { get { return mapViewScale; } } // 最奥の縮小率(奥の画像を縮小して遠近感を演出する) private float minRate = 0; public float MinRate { get { return minRate; } } // コンストラクタ public MainMap(Game game, Common common, InputManager inputManager) : base(game) { // TODO: Construct any child components here thisGame = (Game1)game; this.common = common; this.inputManager = inputManager; } /// /// Allows the game component to perform any initialization it needs to before starting /// to run. This is where it can query for any required services and load content. /// public override void Initialize() { // TODO: Add your initialization code here // コンソール表示領域の初期設定(x座標、y座標、幅、高さ) consoleRec = new Rectangle(0, 0, 800, 600); // マップ表示位置の初期設定 mapViewPos = new Vector2(0, 0); // マップ表示スケールの初期設定 mapViewScale = new Vector2(2.0f, 2.0f * (9.0f / 16.0f)); // 最奥の縮小率の初期設定(奥の画像を縮小して遠近感を演出する) minRate = 0.3f; base.Initialize(); } /// /// Allows the game component to update itself. /// /// Provides a snapshot of timing values. public override void Update(GameTime gameTime) { // TODO: Add your update code here // 上キーで上スクロール if (inputManager.KeyboardState.IsKeyDown(Keys.Up)) mapViewPos.Y--; // 下キーで下スクロール if (inputManager.KeyboardState.IsKeyDown(Keys.Down)) mapViewPos.Y++; // 左キーで左スクロール if (inputManager.KeyboardState.IsKeyDown(Keys.Left)) mapViewPos.X--; // 右キーで右スクロール if (inputManager.KeyboardState.IsKeyDown(Keys.Right)) mapViewPos.X++; // Pキーで拡大 if (inputManager.KeyboardState.IsKeyDown(Keys.P)) { // 拡大後のスケールを算出 Vector2 newMapViewScale = mapViewScale; newMapViewScale.X += 0.02f; newMapViewScale.Y = newMapViewScale.X * (9.0f / 16.0f); // 上限チェック if (newMapViewScale.X < 5.0f && newMapViewScale.Y < 5.0f) { // 拡大前の中央座標を算出 Vector2 oldCenter; oldCenter.X = (((float)consoleRec.Width * minRate) / 2.0f) / mapViewScale.X; oldCenter.X += ((float)consoleRec.Width / 2.0f) / mapViewScale.X; oldCenter.Y = mapViewPos.Y + ((float)consoleRec.Height / 2.0f) / mapViewScale.Y; // 拡大後の中央座標を算出 Vector2 newCenter; newCenter.X = (((float)consoleRec.Width * minRate) / 2.0f) / newMapViewScale.X; newCenter.X += ((float)consoleRec.Width / 2.0f) / newMapViewScale.X; newCenter.Y = mapViewPos.Y + ((float)consoleRec.Height / 2.0f) / newMapViewScale.Y; // 表示開始座標の修正 mapViewPos.X += oldCenter.X - newCenter.X; mapViewPos.Y += oldCenter.Y - newCenter.Y; // 拡大後のスケールを設定 mapViewScale = newMapViewScale; } } // Lキーで縮小 if (inputManager.KeyboardState.IsKeyDown(Keys.L)) { // 縮小後のスケールを算出 Vector2 newMapViewScale = mapViewScale; newMapViewScale.X -= 0.02f; newMapViewScale.Y = newMapViewScale.X * (9.0f / 16.0f); // 下限チェック if (newMapViewScale.X >= 0.3f && newMapViewScale.Y >= 0.3f) { // 縮小前の中央座標を算出 Vector2 oldCenter; oldCenter.X = (((float)consoleRec.Width * minRate) / 2.0f) / mapViewScale.X; oldCenter.X += ((float)consoleRec.Width / 2.0f) / mapViewScale.X; oldCenter.Y = mapViewPos.Y + ((float)consoleRec.Height / 2.0f) / MapViewScale.Y; // 縮小後の中央座標を算出 Vector2 newCenter; newCenter.X = (((float)consoleRec.Width * minRate) / 2.0f) / newMapViewScale.X; newCenter.X += ((float)consoleRec.Width / 2.0f) / newMapViewScale.X; newCenter.Y = mapViewPos.Y + ((float)consoleRec.Height / 2.0f) / newMapViewScale.Y; // 表示開始座標の修正 mapViewPos.X += oldCenter.X - newCenter.X; mapViewPos.Y += oldCenter.Y - newCenter.Y; // 縮小後のスケールを設定 mapViewScale = newMapViewScale; } } base.Update(gameTime); } // メインマップ関連呼び出し public void Load(ContentManager content) { mainMap01 = content.Load("MainMap01"); } // メインマップ関連表示 public void Draw(SpriteBatch spriteBatch) { // ラスタースクロール for (int i = 0; i < (float)consoleRec.Height / mapViewScale.Y; i++) { // 奥行きに応じて縮小率を算出(minRate = 0.3 の場合、scaleDownRate = 0 〜 0.3 の範囲) float scaleDownRate = ((float)i / ((float)consoleRec.Height / mapViewScale.Y)) * minRate; // 表示開始座標の設定 Vector2 pos = new Vector2((float)consoleRec.X, (float)consoleRec.Y + (float)i * mapViewScale.Y); // 抽出元画像領域の設定 int sourceRecPosX = (int)mapViewPos.X + (int)((((float)consoleRec.Width * scaleDownRate) / 2) / mapViewScale.X); int sourceRecPosY = (int)mapViewPos.Y + i; int sourceRecWidth = (int)(((float)consoleRec.Width / (1.0 - (minRate - scaleDownRate))) / mapViewScale.X); int sourceRecHeight = (int)mapViewScale.Y + 1; Rectangle sourceRectangle = new Rectangle(sourceRecPosX, sourceRecPosY, sourceRecWidth, sourceRecHeight); // 表示スケールの設定 Vector2 drawScale = new Vector2(((float)consoleRec.Width / (float)sourceRectangle.Width), 1.0f); // 1ライン毎に表示する spriteBatch.Draw(mainMap01, pos, sourceRectangle, Color.White, 0, Vector2.Zero, drawScale, SpriteEffects.None, 1.0f); } // メッセージ表示 spriteBatch.DrawString(common.Font1, "mapViewPos.X = " + mapViewPos.X, new Vector2(10, 500), Color.Red); spriteBatch.DrawString(common.Font1, "mapViewPos.Y = " + mapViewPos.Y, new Vector2(10, 525), Color.Red); spriteBatch.DrawString(common.Font1, "mapViewScale.X = " + mapViewScale.X, new Vector2(10, 550), Color.Red); spriteBatch.DrawString(common.Font1, "mapViewScale.Y = " + mapViewScale.Y, new Vector2(10, 575), Color.Red); // 中央を示す spriteBatch.DrawString(common.Font1, "L", new Vector2(consoleRec.Width / 2 + consoleRec.X, consoleRec.Height / 2 + consoleRec.Y), Color.Red); spriteBatch.DrawString(common.Font1, "L", new Vector2(consoleRec.Width / 2 + consoleRec.X, consoleRec.Height / 2 + consoleRec.Y), Color.Red, MathHelper.ToRadians(90.0f), new Vector2(0, 0), new Vector2(1.0f, 1.0f), SpriteEffects.None, 0); spriteBatch.DrawString(common.Font1, "L", new Vector2(consoleRec.Width / 2 + consoleRec.X, consoleRec.Height / 2 + consoleRec.Y), Color.Red, MathHelper.ToRadians(180.0f), new Vector2(0, 0), new Vector2(1.0f, 1.0f), SpriteEffects.None, 0); spriteBatch.DrawString(common.Font1, "L", new Vector2(consoleRec.Width / 2 + consoleRec.X, consoleRec.Height / 2 + consoleRec.Y), Color.Red, MathHelper.ToRadians(270.0f),new Vector2(0, 0),new Vector2(1.0f, 1.0f),SpriteEffects.None, 0); } } }