トップ回答者
xna4.0を利用したVisual C# Express 2010によるゲーム開発について

質問
-
【プラットフォーム】
Visual C# 2010 Express +Xna4.0
独学でXna4.0を使ったC#2010によるゲーム開発をしている者です。プログラムの知識はまだ初心者です。ゲームジャンルはトレーディングカードゲームです。画面遷移についてですが以下のようなシーンを管理するクラスとゲーム本体を管理するクラスを準備しましたが、マウスクリックによる画面遷移がうまくいきません。流れ的にはタイトル画面(オプション画面)→ゲームメイン画面→戦闘画面→リザルト画面という流れを考えています。不足している部分があれば追加してくれると助かります。
【ゲーム本体(ソース)Game1.cs】
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;//ゲームメイン
namespace WeibScbwarz
{
//メインプログラム
public class Game1 : Microsoft.Xna.Framework.Game
{
//sceneクラスの宣言
SceneManager s;
GraphicsDeviceManager graphics;
SpriteBatch spriteBatch;
private SceneManager title;
public Game1()
{
graphics = new GraphicsDeviceManager(this);
Content.RootDirectory = "Content";
//解像度を変える
graphics.PreferredBackBufferWidth = 1280;//幅
graphics.PreferredBackBufferHeight = 800;//高さ
//すべてのクラスを使えるようにする}
//初期化プロテクトオーバーライド
protected override void Initialize()
{
base.Initialize();
}
//読み込みプロテクトオーバーライド
protected override void LoadContent()
{
//テクスチャロード
spriteBatch = new SpriteBatch(GraphicsDevice);}
//アンロード(再利用プロテクトオーバーライド)
protected override void UnloadContent()
{
//
}
//更新処理プロテクトオーバーライド
protected override void Update(GameTime gameTime)
{
if (GamePad.GetState(PlayerIndex.One).Buttons.Back == ButtonState.Pressed) this.Exit();
//アップデート
base.Update(gameTime);
}
//ゲームタイムプロテクトオーバーライド
protected override void Draw(GameTime gameTime)
{
base.Draw(gameTime);
}
}
}【シーンクラス(画面遷移ソース)SceneManager.cs】
using Microsoft.Xna.Framework;
namespace WeibScbwarz
{
//シーンマネージャークラス
public class SceneManager : Game1
{
public static void main(string[] args)
{
//タイトル画面
using (Game1 title = new Game1())
{
title.Run();
}
//オプション画面
using (Game1 option = new Game1())
{
option.Run();
}
//ゲームメイン画面
using (Game1 main = new Game1())
{
main.Run();
}
//戦闘画面
using (Game1 battle = new Game1())
{
battle.Run();
}
//リザルト画面
using (Game1 result = new Game1())
{
result.Run();
}}
}
}わかりやすく回答をお願いします。
回答
-
不足している部分があれば追加してくれると助かります。
わかりやすく回答をお願いします。
初めから他人にやってもらおうという態度はやめましょう。
マウスクリックによる画面遷移がうまくいきません
どのように上手くいかないのか書きましょう。
コードにはマウスクリックの処理がどうなっているかが記述されていません。ゆえにあなたの判らないことが他の人には判りません。
シーンを管理するクラスも無いのでどのように管理したいのかも伝わりません。提示されているコードだと、Game1クラスをインスタンス化してRunすることでウィンドウを開いて、閉じるとまたGame1クラスを作って新規でウィンドウを開く、という事を繰り返しているように見えます。
普通はウィンドを何度も作ることはしないのですが、そのように作りたいのであれば、閉じる前に次に実行することを決めるパラメーターをどこかに保持しておいて、それで判定するという方法は取れるでしょう。画面遷移の方法などはいろいろな方法が思いつきますが、以下は毎回ウィンドウを閉じない場合での一例です
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; namespace WindowsGame1 { /// <summary> /// ゲーム内で保持しておくデータ /// </summary> class ButtleData { public int? Enemy { get; set; } public int? Player { get; set; } public object Option { get; set; } public bool YouWin { get { return Player > Enemy; } } public string ResultString() { string e = Enemy == null ? "" : Enemy.ToString(); string p = Player == null ? "" : Player.ToString(); string res = string.Empty; if (Enemy != null && Player != null) { if (Enemy.Value < Player.Value) { res = "WIN"; } else { res = "LOSE"; } } return string.Format("ENEMY={0} , PLAYER={1} ,{2}", e, p, res); } } #region 各状態の動作を記述 class Title : Microsoft.Xna.Framework.DrawableGameComponent { private ButtleData data; public Title(Game game, ButtleData data) : base(game) { this.data = data; } public override void Update(GameTime gameTime) { base.Update(gameTime); Game.Window.Title = "Title [Space]:開始 [右クリック]:オプション"; //マウスやキーボード操作があったら現在の状態を終了して次の動作を実行させる //ゲームのデータは次の動作にも引き継ぐ if (Mouse.GetState().RightButton == ButtonState.Pressed) { this.Game.Components.Remove(this); this.Game.Components.Add(new Option(this.Game, data)); } else if (Keyboard.GetState().IsKeyDown(Keys.Space)) { this.Game.Components.Remove(this); this.Game.Components.Add(new Main(this.Game, data)); } } public override void Draw(GameTime gameTime) { Game.GraphicsDevice.Clear(Color.LightBlue); base.Draw(gameTime); } } class Option : Microsoft.Xna.Framework.DrawableGameComponent { private ButtleData data; public Option(Game game, ButtleData data) : base(game) { this.data = data; } public override void Update(GameTime gameTime) { base.Update(gameTime); Game.Window.Title = "Option [Enter]:Start"; if (Keyboard.GetState().IsKeyDown(Keys.Enter)) { this.Game.Components.Remove(this); this.Game.Components.Add(new Title(this.Game, data)); } } public override void Draw(GameTime gameTime) { Game.GraphicsDevice.Clear(Color.LightSeaGreen); base.Draw(gameTime); } } class Main : Microsoft.Xna.Framework.DrawableGameComponent { private ButtleData data; public Main(Game game, ButtleData data) : base(game) { this.data = data; } public override void Update(GameTime gameTime) { base.Update(gameTime); Game.Window.Title = "Main [左クリック]:開始"; if (Mouse.GetState().RightButton == ButtonState.Pressed) { this.Game.Components.Remove(this); this.Game.Components.Add(new Title(this.Game, data)); } else if (Mouse.GetState().LeftButton == ButtonState.Pressed) { this.Game.Components.Remove(this); this.Game.Components.Add(new Buttle(this.Game, data)); data.Enemy = new Random().Next(100); } } public override void Draw(GameTime gameTime) { Game.GraphicsDevice.Clear(Color.LightYellow); base.Draw(gameTime); } } class Buttle : Microsoft.Xna.Framework.GameComponent { private ButtleData data; public Buttle(Game game, ButtleData data) : base(game) { this.data = data; } public override void Update(GameTime gameTime) { base.Update(gameTime); data.Player = new Random().Next(100); Game.Window.Title = "[右クリック]:決定 " + data.ResultString(); if (Mouse.GetState().RightButton == ButtonState.Pressed) { this.Game.Components.Remove(this); this.Game.Components.Add(new Result(this.Game, data)); } } } class Result : Microsoft.Xna.Framework.DrawableGameComponent { private ButtleData data; public Result(Game game, ButtleData data) : base(game) { this.data = data; } public override void Update(GameTime gameTime) { base.Update(gameTime); Game.Window.Title = "[左クリック]:再戦 " + data.ResultString(); if (Mouse.GetState().LeftButton == ButtonState.Pressed) { this.Game.Components.Remove(this); this.Game.Components.Add(new Main(this.Game, data)); } else if (Keyboard.GetState().IsKeyDown(Keys.Escape)) { this.Game.Components.Remove(this); this.Game.Components.Add(new Title(this.Game,data)); } } public override void Draw(GameTime gameTime) { base.Draw(gameTime); if (data.Enemy < data.Player) { this.GraphicsDevice.Clear(Color.White); } else { this.GraphicsDevice.Clear(Color.Black); } } } #endregion /// <summary>ゲームのメインオブジェクト</summary> public class Game1 : Microsoft.Xna.Framework.Game { GraphicsDeviceManager graphics; SpriteBatch spriteBatch; ButtleData data = new ButtleData();//ゲームの結果などのデータは常に存在する public Game1() { graphics = new GraphicsDeviceManager(this); Content.RootDirectory = "Content"; } protected override void Initialize() { var title = new Title(this, data); this.Components.Add(title);//タイトル画面を表示するように登録 base.Initialize(); this.IsMouseVisible = true; } protected override void LoadContent() { spriteBatch = new SpriteBatch(GraphicsDevice); } protected override void UnloadContent() { } protected override void Update(GameTime gameTime) { base.Update(gameTime); } protected override void Draw(GameTime gameTime) { base.Draw(gameTime); } } #if WINDOWS || XBOX static class Program { static void Main(string[] args) { //何度もゲームのメインオブジェクトを生成しない //Microsoft.Xna.Framework.GameオブジェクトをRunする度に新規ウィンドウを作ってしまう using (Game1 game = new Game1()) { game.Run(); } } } #endif }
#XNAを初めて使ってみた個別に明示されていない限りgekkaがフォーラムに投稿したコードにはフォーラム使用条件に基づき「MICROSOFT LIMITED PUBLIC LICENSE」が適用されます。(かなり自由に使ってOK!)
- 回答としてマーク はるか2015 2015年5月25日 10:36
すべての返信
-
不足している部分があれば追加してくれると助かります。
わかりやすく回答をお願いします。
初めから他人にやってもらおうという態度はやめましょう。
マウスクリックによる画面遷移がうまくいきません
どのように上手くいかないのか書きましょう。
コードにはマウスクリックの処理がどうなっているかが記述されていません。ゆえにあなたの判らないことが他の人には判りません。
シーンを管理するクラスも無いのでどのように管理したいのかも伝わりません。提示されているコードだと、Game1クラスをインスタンス化してRunすることでウィンドウを開いて、閉じるとまたGame1クラスを作って新規でウィンドウを開く、という事を繰り返しているように見えます。
普通はウィンドを何度も作ることはしないのですが、そのように作りたいのであれば、閉じる前に次に実行することを決めるパラメーターをどこかに保持しておいて、それで判定するという方法は取れるでしょう。画面遷移の方法などはいろいろな方法が思いつきますが、以下は毎回ウィンドウを閉じない場合での一例です
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; namespace WindowsGame1 { /// <summary> /// ゲーム内で保持しておくデータ /// </summary> class ButtleData { public int? Enemy { get; set; } public int? Player { get; set; } public object Option { get; set; } public bool YouWin { get { return Player > Enemy; } } public string ResultString() { string e = Enemy == null ? "" : Enemy.ToString(); string p = Player == null ? "" : Player.ToString(); string res = string.Empty; if (Enemy != null && Player != null) { if (Enemy.Value < Player.Value) { res = "WIN"; } else { res = "LOSE"; } } return string.Format("ENEMY={0} , PLAYER={1} ,{2}", e, p, res); } } #region 各状態の動作を記述 class Title : Microsoft.Xna.Framework.DrawableGameComponent { private ButtleData data; public Title(Game game, ButtleData data) : base(game) { this.data = data; } public override void Update(GameTime gameTime) { base.Update(gameTime); Game.Window.Title = "Title [Space]:開始 [右クリック]:オプション"; //マウスやキーボード操作があったら現在の状態を終了して次の動作を実行させる //ゲームのデータは次の動作にも引き継ぐ if (Mouse.GetState().RightButton == ButtonState.Pressed) { this.Game.Components.Remove(this); this.Game.Components.Add(new Option(this.Game, data)); } else if (Keyboard.GetState().IsKeyDown(Keys.Space)) { this.Game.Components.Remove(this); this.Game.Components.Add(new Main(this.Game, data)); } } public override void Draw(GameTime gameTime) { Game.GraphicsDevice.Clear(Color.LightBlue); base.Draw(gameTime); } } class Option : Microsoft.Xna.Framework.DrawableGameComponent { private ButtleData data; public Option(Game game, ButtleData data) : base(game) { this.data = data; } public override void Update(GameTime gameTime) { base.Update(gameTime); Game.Window.Title = "Option [Enter]:Start"; if (Keyboard.GetState().IsKeyDown(Keys.Enter)) { this.Game.Components.Remove(this); this.Game.Components.Add(new Title(this.Game, data)); } } public override void Draw(GameTime gameTime) { Game.GraphicsDevice.Clear(Color.LightSeaGreen); base.Draw(gameTime); } } class Main : Microsoft.Xna.Framework.DrawableGameComponent { private ButtleData data; public Main(Game game, ButtleData data) : base(game) { this.data = data; } public override void Update(GameTime gameTime) { base.Update(gameTime); Game.Window.Title = "Main [左クリック]:開始"; if (Mouse.GetState().RightButton == ButtonState.Pressed) { this.Game.Components.Remove(this); this.Game.Components.Add(new Title(this.Game, data)); } else if (Mouse.GetState().LeftButton == ButtonState.Pressed) { this.Game.Components.Remove(this); this.Game.Components.Add(new Buttle(this.Game, data)); data.Enemy = new Random().Next(100); } } public override void Draw(GameTime gameTime) { Game.GraphicsDevice.Clear(Color.LightYellow); base.Draw(gameTime); } } class Buttle : Microsoft.Xna.Framework.GameComponent { private ButtleData data; public Buttle(Game game, ButtleData data) : base(game) { this.data = data; } public override void Update(GameTime gameTime) { base.Update(gameTime); data.Player = new Random().Next(100); Game.Window.Title = "[右クリック]:決定 " + data.ResultString(); if (Mouse.GetState().RightButton == ButtonState.Pressed) { this.Game.Components.Remove(this); this.Game.Components.Add(new Result(this.Game, data)); } } } class Result : Microsoft.Xna.Framework.DrawableGameComponent { private ButtleData data; public Result(Game game, ButtleData data) : base(game) { this.data = data; } public override void Update(GameTime gameTime) { base.Update(gameTime); Game.Window.Title = "[左クリック]:再戦 " + data.ResultString(); if (Mouse.GetState().LeftButton == ButtonState.Pressed) { this.Game.Components.Remove(this); this.Game.Components.Add(new Main(this.Game, data)); } else if (Keyboard.GetState().IsKeyDown(Keys.Escape)) { this.Game.Components.Remove(this); this.Game.Components.Add(new Title(this.Game,data)); } } public override void Draw(GameTime gameTime) { base.Draw(gameTime); if (data.Enemy < data.Player) { this.GraphicsDevice.Clear(Color.White); } else { this.GraphicsDevice.Clear(Color.Black); } } } #endregion /// <summary>ゲームのメインオブジェクト</summary> public class Game1 : Microsoft.Xna.Framework.Game { GraphicsDeviceManager graphics; SpriteBatch spriteBatch; ButtleData data = new ButtleData();//ゲームの結果などのデータは常に存在する public Game1() { graphics = new GraphicsDeviceManager(this); Content.RootDirectory = "Content"; } protected override void Initialize() { var title = new Title(this, data); this.Components.Add(title);//タイトル画面を表示するように登録 base.Initialize(); this.IsMouseVisible = true; } protected override void LoadContent() { spriteBatch = new SpriteBatch(GraphicsDevice); } protected override void UnloadContent() { } protected override void Update(GameTime gameTime) { base.Update(gameTime); } protected override void Draw(GameTime gameTime) { base.Draw(gameTime); } } #if WINDOWS || XBOX static class Program { static void Main(string[] args) { //何度もゲームのメインオブジェクトを生成しない //Microsoft.Xna.Framework.GameオブジェクトをRunする度に新規ウィンドウを作ってしまう using (Game1 game = new Game1()) { game.Run(); } } } #endif }
#XNAを初めて使ってみた個別に明示されていない限りgekkaがフォーラムに投稿したコードにはフォーラム使用条件に基づき「MICROSOFT LIMITED PUBLIC LICENSE」が適用されます。(かなり自由に使ってOK!)
- 回答としてマーク はるか2015 2015年5月25日 10:36