feature image

2016年9月13日 | ブログ記事

MonoGameを使ってAndroidのゲームを作ろう その2

どうも、Namazuです。

前回の記事はこちら。まさか続くとは。
ということで、今回扱う内容は以下の通りです。

これだけ?と思うかもしれませんが、意外と構造が面倒くさいのです。
具体的な実装の話の前に、関連するクラスの説明から。

(MSDN公式サイトより引用)

よく分からないので、少しずつ整理していきます。

まず、私たちが欲しい情報は

などですね。
そこである一ヶ所のタッチについての情報をまとめているのがTouchLocationです。
しかし複数タッチに対応するためには複数のTouchLocationが必要です。
そこで、複数のTouchLocationをまとめたものがTouchCollectionです。
そして、タッチ情報は毎フレーム更新しなくては意味がありません。
画面からタッチ情報を受け取り、TouchCollectionを更新するために用いるのがTouchPanelです。

それではそれぞれのクラスの主要なメンバやメソッドを具体的な実装方法を交えてご紹介します。


//TouchPanelクラス
protected override void Update(GameTime gameTime)
{
if (GamePad.GetState(PlayerIndex.One).Buttons.Back == ButtonState.Pressed)
Exit();

touchCollection = TouchPanel.GetState();
//Update関数の中で記述する。
//TouchPanelは、Input.Touchクラスをインポート(using Microsoft.Xna.Framework.Input.Touch;)としておけば定義しなくてよい。

base.Update(gameTime);
}

//TouchCollectionクラス、TouchLocationクラス
protected override void Draw(GameTime gameTime)
{
for(var i=0;i<touchCollection.Count;i++){
TouchLocation touchLocation = touchCollection[i]; //これでタッチID昇順のi番目のTouchLocationが取得できる。
Point point = new Point((int)touchLocation.Position.X,(int)touchLocation.Position.Y); //Pointの中身はint型、Vector2の中身はfloat型
if(ayayaRect.Contains(point)) {}//ayayaRectはRectangleクラスのオブジェクト。Contains(point)でその領域にpointが含まれているか判定できる。
}

base.Update(gameTime);
}

タッチ入力を検出する流れは分かっていただけたでしょうか?
それでは、タッチしたら画面の背景色が変わるゲーム(?)を作ってみましょう。

Activity1.csは変更せずに、Game1.csを以下のように変更します。
Game1.cs


using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Audio;
using Microsoft.Xna.Framework.Graphics;
using Microsoft.Xna.Framework.Input;
using Microsoft.Xna.Framework.Input.Touch;
using System;

namespace TouchOnly
{
/// <summary>
/// This is the main type for your game.
/// </summary>
public class Game1 : Game
{
GraphicsDeviceManager graphics;
SpriteBatch spriteBatch;

Texture2D ayaya, yoko, alice, karen;
Vector2 touchPosition;
TouchCollection touchCollection;
Rectangle ayayarect = new Rectangle(300, 200, 200, 200);
Rectangle alicerect = new Rectangle(700, 200, 200, 200);
Rectangle yokorect = new Rectangle(300, 500, 200, 200);
Rectangle karenrect = new Rectangle(700, 500, 200, 200);

Color backGroundColor = Color.CornflowerBlue;
string[] text;

public Game1()
{
graphics = new GraphicsDeviceManager(this);
Content.RootDirectory = "Content";

graphics.IsFullScreen = true;
graphics.PreferredBackBufferWidth = 800;
graphics.PreferredBackBufferHeight = 480;
graphics.SupportedOrientations = DisplayOrientation.LandscapeLeft | DisplayOrientation.LandscapeRight;
}

/// <summary>
/// Allows the game to perform any initialization it needs to before starting to run.
/// This is where it can query for any required services and load any non-graphic
/// related content. Calling base.Initialize will enumerate through any components
/// and initialize them as well.
/// </summary>
protected override void Initialize()
{
// TODO: Add your initialization logic here

base.Initialize();
}

/// <summary>
/// LoadContent will be called once per game and is the place to load
/// all of your content.
/// </summary>
protected override void LoadContent()
{
// Create a new SpriteBatch, which can be used to draw textures.
spriteBatch = new SpriteBatch(GraphicsDevice);
ayaya = Content.Load<Texture2D>("ayaya2");
alice = Content.Load<Texture2D>("alice");
karen = Content.Load<Texture2D>("karen");
yoko = Content.Load<Texture2D>("yoko");

// TODO: use this.Content to load your game content here
}

/// <summary>
/// UnloadContent will be called once per game and is the place to unload
/// game-specific content.
/// </summary>
protected override void UnloadContent()
{
// TODO: Unload any non ContentManager content here
}

/// <summary>
/// Allows the game to run logic such as updating the world,
/// checking for collisions, gathering input, and playing audio.
/// </summary>
/// <param name="gameTime">Provides a snapshot of timing values.</param>
protected override void Update(GameTime gameTime)
{
if (GamePad.GetState(PlayerIndex.One).Buttons.Back == ButtonState.Pressed)
Exit();

// TODO: Add your update logic here

touchCollection = TouchPanel.GetState();

base.Update(gameTime);
}

/// <summary>
/// This is called when the game should draw itself.
/// </summary>
/// <param name="gameTime">Provides a snapshot of timing values.</param>
protected override void Draw(GameTime gameTime)
{
text = new string[touchCollection.Count];
for (var i = 0; i < touchCollection.Count; i++)
{

TouchLocation touchLocation = touchCollection[i];
touchPosition = touchLocation.Position;
Point point = new Point((int)touchPosition.X, (int)touchPosition.Y);
if (ayayarect.Contains(point))
{
backGroundColor = Color.RoyalBlue;
}
else if (alicerect.Contains(point))
{
backGroundColor = Color.Gold;
}
else if (yokorect.Contains(point))
{
backGroundColor = Color.Orange;
}
else if (karenrect.Contains(point))
{
backGroundColor = Color.Yellow;
}
else
{
backGroundColor = Color.CornflowerBlue;
}
text[i] = string.Format("id={0} X={1} Y={2} state={3} touch count={4}", touchLocation.Id, touchLocation.Position.X, touchLocation.Position.Y, touchLocation.State, touchCollection.Count);
Console.WriteLine(text[i]);
}

GraphicsDevice.Clear(backGroundColor);

spriteBatch.Begin();
spriteBatch.Draw(ayaya, ayayarect, Color.White);
spriteBatch.Draw(alice, alicerect, Color.White);
spriteBatch.Draw(yoko, yokorect, Color.White);
spriteBatch.Draw(karen, karenrect, Color.White);
spriteBatch.End();

base.Draw(gameTime);
}
}
}

簡単に説明します。

何か説明に不備または分かりにくい点等ありましたらコメントにてご指摘ください。

さて、ここからが重要ですがきんいろモザイクの映画「きんいろモザイク PrettyDays」が2016年11月12日に公開されますね。
今回の記事であややを始めとするきんいろモザイクのキャラの可愛さが伝わったと思うので是非見に行きましょう。
私はもう前売り券をゲットしました。特典ブロマイドはあややでした。完全に勝利です。

Namazu icon
この記事を書いた人
Namazu

Namazuです。 今まで制作に携わったゲームはTypingWar、EccentricEscape、進捗どうですか?、NinjaFlicker等です。 MonoGameにまつわる記事も書いています。

この記事をシェア

このエントリーをはてなブックマークに追加
共有

関連する記事

2023年11月21日
School Breakin' Tag -新感覚おにごっこ-
s9 icon s9
2024年9月20日
2024年 1-Monthonを開催しました!!
Synori icon Synori
2023年9月3日
タイピング&アクション『TypeTheCode』作りました
wal icon wal
2024年9月17日
1か月でゲームを作った #BlueLINE
Komichi icon Komichi
2023年4月25日
【驚愕】作曲4年目だった男が大学3年間ゲームサウンドに関わった末路...【ゲームサウンドのお仕事について】
tenya icon tenya
ERC20トークンを用いた宝探しゲーム(真)の提案【アドベントカレンダー2018 10日目】 feature image
2018年11月3日
ERC20トークンを用いた宝探しゲーム(真)の提案【アドベントカレンダー2018 10日目】
Azon icon Azon
記事一覧 タグ一覧 Google アナリティクスについて 特定商取引法に基づく表記