ページ 11

当たり判定について

Posted: 2012年7月31日(火) 14:53
by 変態
このプログラムで実行デバックすると、キャラクターとマップがずれて、のめりこんだり、行けるところが行けなかったり、右に行けたのに左に行けないなどわけわからない動作になってしまいます。
マップチップの1が障害物で27が通れるところなのですが、さらにチップの種類を増やしたいのでその時の方法も教えてください。
また、Game1クラスがいっぱいで、見にくいので良い方法があったら教えてください。
開発環境はVisualStudio2010のXNAです

コード:

using System;
using System.Collections.Generic;
using System.Linq;
using System.IO;
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>
    /// Game1
    /// </summary>
    public class Game1 : Microsoft.Xna.Framework.Game
    {
        GraphicsDeviceManager graphics;
        SpriteBatch spriteBatch;
        BackGround backGround;
        Player player;
        int direct = 0;
        int[,] map = new int[10, 10]{
            {1,1,1,1,1,1,1,1,1,1},
            {1,1,1,1,1,1,1,1,1,1},
            {1,1,1,1,1,1,1,1,1,1},
            {1,1,1,1,1,1,1,1,1,1},
            {1,1,1,1,1,1,1,1,1,1},
            {1,1,1,1,1,1,1,1,1,1},
            {1,1,1,1,1,1,1,1,1,1},
            {1,1,1,1,1,1,1,1,1,1},
            {1,1,1,1,1,1,1,1,1,1},
            {27,27,27,27,27,27,27,27,27,27}};

        /// <summary>
        /// コンストラクタ
        /// </summary>
        public Game1()
        {
            graphics = new GraphicsDeviceManager(this);
            graphics.PreferredBackBufferWidth = 320;
            graphics.PreferredBackBufferHeight = 320;
        }

        /// <summary>
        /// デバック情報
        /// </summary>
        /// <param name="x"></param>
        /// <param name="y"></param>
        public void VerMsg(int x, int y)
        {
            string str;
            str = "x=" + x.ToString() + "y=" + y.ToString();
            base.Window.Title = str;
        }

        /// <summary>
        /// 初期化
        /// </summary>
        protected override void Initialize()
        {
            base.Window.Title = "山崎春のパーン祭り";
            backGround = new BackGround(Content, 32);
            player = new Player(Content, 3, 4, 96, 128);
            base.Initialize();
        }

        /// <summary>
        /// 読み込み
        /// </summary>
        protected override void LoadContent()
        {
            spriteBatch = new SpriteBatch(GraphicsDevice);
            backGround.LoadTexture();
            player.LoadTexture();
            player.sp_no = 0;
            player.position = new Vector2(0, 288);
        }

        /// <summary>
        /// 破棄
        /// </summary>
        protected override void UnloadContent()
        {
            
        }

        /// <summary>
        /// 更新
        /// </summary>
        /// <param name="gameTime"></param>
        protected override void Update(GameTime gameTime)
        {
            if (GamePad.GetState(PlayerIndex.One).Buttons.Back == ButtonState.Pressed
                || Keyboard.GetState().IsKeyDown(Keys.Escape))
                this.Exit();

            int x = 0, y = 0;

            KeyboardState keyState = Keyboard.GetState();
            if (keyState.IsKeyDown(Keys.Down))
            {
                x = ((int)player.position.X) / 32;
                y = ((int)player.position.Y) / 32 + 2;
                if (y < 10 && map[y, x] == 27) player.position.Y += 2;
                direct = 0;
            }
            if (keyState.IsKeyDown(Keys.Left))
            {
                x = ((int)player.position.X) / 32 - 2;
                y = ((int)player.position.Y) / 32;
                if (x >= 0 && map[y, x] == 27) player.position.X -= 2;
                direct = 1;
            }
            if (keyState.IsKeyDown(Keys.Right))
            {
                x = ((int)player.position.X) / 32 + 2;
                y = ((int)player.position.Y) / 32;
                if (y < 10 && map[y, x] == 27) player.position.X += 2;
                direct = 2;
            }
            if (keyState.IsKeyDown(Keys.Up))
            {
                x = ((int)player.position.X) / 32;
                y = ((int)player.position.Y) / 32 - 2;
                if (y >= 0 && map[y, x] == 27) player.position.Y -= 2;
                direct = 3;
            }
            VerMsg(x, y);
            base.Update(gameTime);
        }

        /// <summary>
        /// 表示
        /// </summary>
        /// <param name="gameTime"></param>
        protected override void Draw(GameTime gameTime)
        {
            GraphicsDevice.Clear(Color.CornflowerBlue);

            spriteBatch.Begin();
            backGround.Draw(spriteBatch, map);
            player.Draw(spriteBatch);
            player.Loop(gameTime, 200);
            player.sp_no = (player.sp_no % 3) + direct + direct + direct;
            spriteBatch.End();

            base.Draw(gameTime);
        }

    }
}

コード:

using System;
using System.Collections.Generic;
using System.Linq;
using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Content;
using Microsoft.Xna.Framework.Graphics;

namespace WindowsGame1
{
    /// <summary>
    /// 背景描画
    /// </summary>
    class BackGround
    {
        public Texture2D img;
        private ContentManager contentManager;
        public int size;
        public int xn, yn;

        /// <summary>
        /// コンストラクタ
        /// </summary>
        public BackGround(ContentManager content, int Size)
        {
            contentManager = content;
            contentManager.RootDirectory = "Content";
            size = Size;
        }

        /// <summary>
        /// 読み込み
        /// </summary>
        public void LoadTexture()
        {
            img = contentManager.Load<Texture2D>("mapChip");
        }

        /// <summary>
        /// 画像の描画
        /// <param name="spriteBatch"></param>
        /// </summary>
        public void Draw(SpriteBatch spriteBatch)
        {
            spriteBatch.Draw(img, new Vector2(0, 0), Color.White);
        }

        /// <summary>
        /// マップチップの描画
        /// <param name="spriteBatch"></param>
        /// <param name="position"></param>
        /// <param name="No"></param>
        /// </summary>
        public void Draw(SpriteBatch spriteBatch, Vector2 position, int No)
        {
            int xw, yw;
            xn = img.Width / size;
            yn = img.Height / size;

            if (No < xn * yn)
            {
                xw = No % xn;
                yw = No / xn;
                spriteBatch.Draw(img, position,
                    new Rectangle(xw * size, yw * size, size, size), Color.White);
            }
        }

        /// <summary>
        /// マップテーブルの描画
        /// </summary>
        /// <param name="spriteBatch"></param>
        /// <param name="t"></param>
        public void Draw(SpriteBatch spriteBatch, int[,] t)
        {
            int x, y;
            Vector2 position;

            for (y = 0; y < t.GetLength(0); y++)
                for (x = 0; x < t.GetLength(1); x++)
                {
                    position.Y = y * size;
                    position.X = x * size;
                    Draw(spriteBatch, position, t[y, x]);
                }
        }
    }
}

コード:

using System;
using System.Collections.Generic;
using System.Linq;
using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Content;
using Microsoft.Xna.Framework.Graphics;

namespace WindowsGame1
{
    /// <summary>
    /// 自機処理
    /// </summary>
    class Player
    {
        private ContentManager contentManager;
        public int sp_no;
        public Texture2D img;
        public int xn, yn;
        public int xs, ys;
        public Vector2 position;
        public Vector2 vect;
        private double time;
        private int width;
        private int height;

        /// <summary>
        /// コンストラクタ
        /// </summary>
        /// <param name="Img"></param>
        /// <param name="Xn"></param>
        /// <param name="Yn"></param>
        /// <param name="Width"></param>
        /// <param name="Height"></param>
        public Player(ContentManager content, int Xn, int Yn, int Width, int Height)
        {
            contentManager = content;
            contentManager.RootDirectory = "Content";
            Init(Xn, Yn, Width, Height);
        }

        /// <summary>
        /// 初期値
        /// </summary>
        /// <param name="Img"></param>
        /// <param name="Xn"></param>
        /// <param name="Yn"></param>
        /// <param name="Width"></param>
        /// <param name="Height"></param>
        private void Init(int Xn, int Yn, int Width, int Height)
        {
            sp_no = 99;
            xn = Xn;
            yn = Yn;
            position = Vector2.Zero;
            vect = Vector2.Zero;
            time = 0;
            width = Width;
            height = Height;
        }

        /// <summary>
        /// 読み込み
        /// </summary>
        public void LoadTexture()
        {
            img = contentManager.Load<Texture2D>("player");
        }

        /// <summary>
        /// 描画
        /// <param name="spriteBatch"></param>
        /// </summary>
        public void Draw(SpriteBatch spriteBatch)
        {
            Draw(spriteBatch, position, sp_no);
        }

        /// <summary>
        /// 描画
        /// </summary>
        /// <param name="spriteBatch"></param>
        /// <param name="position"></param>
        public void Draw(SpriteBatch spriteBatch, Vector2 Position)
        {
            Draw(spriteBatch, Position, sp_no);
        }

        /// <summary>
        /// 描画
        /// </summary>
        /// <param name="spriteBatch"></param>
        /// <param name="Position"></param>
        /// <param name="No"></param>
        public void Draw(SpriteBatch spriteBatch, Vector2 Position, int No)
        {
            int xw, yw;
            xs = img.Width / xn;
            ys = img.Height / yn;

            if (No < xn * yn)
            {
                xw = No % xn;
                yw = No / xn;
                spriteBatch.Draw(img, Position,
                    new Rectangle(xw * xs, yw * ys, xs, ys), Color.White);
            }
        }

        /// <summary>
        /// 移動
        /// </summary>
        /// <param name="rect"></param>
        public void Move(Rectangle rect)
        {
            if (sp_no < xn * yn)
            {
                position = position + vect;

                if (position.X < rect.Left || position.X > rect.Right
                    || position.Y < rect.Top || position.Y > rect.Bottom)
                    sp_no = 99;
            }
        }

        /// <summary>
        /// 次の画像番号
        /// </summary>
        /// <param name="gameTime"></param>
        /// <param name="Time"></param>
        public void Next(GameTime gameTime, double Time)
        {
            double nowtime = gameTime.TotalGameTime.TotalMilliseconds;
            if (sp_no < xn * yn && time + Time < nowtime)
            {
                time = nowtime;
                sp_no = (sp_no + 1) % (xn * yn);
            }
        }

        /// <summary>
        /// ループ
        /// </summary>
        /// <param name="gameTime"></param>
        /// <param name="Time"></param>
        public void Loop(GameTime gameTime, double Time)
        {
            double nowtime = gameTime.TotalGameTime.TotalMilliseconds;

            if (sp_no < xn * yn && time + Time < nowtime)
            {
                time = nowtime;
                sp_no = (sp_no + 1) % (xn * yn);
            }
        }

        /// <summary>
        /// 当たり判定
        /// </summary>
        /// <param name="target"></param>
        /// <param name="length"></param>
        /// <returns></returns>
        public bool Hit(Vector2 target, float length)
        {
            float dist;
            float wx;
            float wy;

            if (sp_no > xn * yn) return false;

            wx = position.X - target.X;
            wy = position.Y - target.Y;
            dist = (float)Math.Sqrt((double)(wx * wx + wy * wy));

            if (dist < length) return true;

            return false;
        }

        /// <summary>
        /// 回転
        /// </summary>
        /// <param name="rt"></param>
        /// <param name="length"></param>
        public void Rot(float rt, float length)
        {
            vect.X = (float)(Math.Sin(rt / 180 * 3.14)) * length;
            vect.Y = (float)(Math.Cos(rt / 180 * 3.14)) * length;
        }
    }
}