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 testGame
{
    /// <summary>
    /// This is the main type for your game
    /// </summary>
    public class Game1 : Microsoft.Xna.Framework.Game
    {
        GraphicsDeviceManager graphics;
        SpriteBatch spriteBatch;

        //The imgage to draw
        Texture2D blockTexture;
        Texture2D boardTexture;

        //person
        Vector2 blockPosition;
        const int blockSpeed = 10;
        int blockJumpSpeed = 20;

        //blocks
        List<Vector2> boardsPositions = new List<Vector2>();
        const float boardSpawnOdds = 0.01f;
        const int boardSpeed = 2;

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

        /// <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();
            //blockPosition = new Vector2((Window.ClientBounds.Width - blockTexture.Width) / 2,
            //    Window.ClientBounds.Height - blockTexture.Height);
        }

        /// <summary>
        /// LoadContent will be called once per game and is the place to load
        /// all of your content.
        /// </summary>
        protected override void LoadContent()
        {
            blockTexture = Content.Load<Texture2D>("block");
            boardTexture = Content.Load<Texture2D>("broad");

            blockPosition = new Vector2((Window.ClientBounds.Width - blockTexture.Width) / 2,
                Window.ClientBounds.Height - blockTexture.Height);
            // Create a new SpriteBatch, which can be used to draw textures.
            spriteBatch = new SpriteBatch(GraphicsDevice);

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

        /// <summary>
        /// UnloadContent will be called once per game and is the place to unload
        /// all content.
        /// </summary>
        protected override void UnloadContent()
        {
            // TODO: Unload any non ContentManager content here
        }
        bool jumpState = false;
        int downSpeed = 0;
        bool hit = false;
        Random random = new Random();
        Vector2 boardIntersects = Vector2.Zero;
        /// <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)
        {
            // Allows the game to exit
            if (GamePad.GetState(PlayerIndex.One).Buttons.Back == ButtonState.Pressed)
                this.Exit();

            KeyboardState keyBoard = Keyboard.GetState();
            //这里定义的是电脑键盘状态，
            //如果考虑到XBOX360需要GamePadState gamePad = GamePad.GetState(PlayerIndex.One);

            if (keyBoard.IsKeyDown(Keys.Left))//按左
            {
                blockPosition.X -= blockSpeed;
            }
            if (keyBoard.IsKeyDown(Keys.Right))//按右
            {
                blockPosition.X += blockSpeed;
            }

            blockPosition.X = MathHelper.Clamp(blockPosition.X,
                0, Window.ClientBounds.Width - blockTexture.Width);
            //限制方块的左右移动范围


            if (keyBoard.IsKeyDown(Keys.Up))//按上
            {
                jumpState = true;
            }


            if (jumpState)//跳跃状态为true时
            {
                blockJumpSpeed = blockJumpSpeed - 1;
                blockPosition.Y -= blockJumpSpeed;
            }

            if (blockPosition.Y > Window.ClientBounds.Height - blockTexture.Height)
            {
                blockPosition.Y = Window.ClientBounds.Height - blockTexture.Height;
                blockJumpSpeed = 20;
                jumpState = false;
                downSpeed = 0;
            }//当方块坠落到最下方时则停住，并且初始化跳跃加速度和非跳跃下降加速度

            if (hit)//如果发生碰撞
            {
                if (keyBoard.IsKeyDown(Keys.Up) &&
                    blockPosition.Y == boardIntersects.Y - blockTexture.Height + 1)
                {//只有方块落在跳板上之后按方向键“上”才会跳，防止只碰撞遍继续向上跳
                    blockJumpSpeed = 20;
                    jumpState = true;
                }
                else if (blockJumpSpeed < 0 || blockJumpSpeed == 20)
                {//当向下落的时候才会掉到跳板上，防止向上跳时碰撞到即到了跳板上
                    blockPosition.Y = boardIntersects.Y - blockTexture.Height + 1;
                    blockPosition.X += boardSpeed;
                    blockJumpSpeed = 20;
                    jumpState = false;
                }
            }
            else//未碰撞时
            {
                if (!jumpState)//未跳跃时
                {
                    if (blockPosition.Y < Window.ClientBounds.Height - blockTexture.Height)
                    {//当方块位置高于地面时，向下加速度掉落
                        downSpeed = downSpeed - 1;
                        blockPosition.Y -= downSpeed;
                    }
                }
            }

            if (random.NextDouble() < boardSpawnOdds)
            {
                float y = (float)random.NextDouble() * (Window.ClientBounds.Height - boardTexture.Height);
                boardsPositions.Add(new Vector2(-boardTexture.Width, y));
            }//随机一个数如果符合则向boardsPositions中添加一个随机位置的方块

            //for (int i = 0; i < boardsPositions.Count; i++)
            //{
            //    boardsPositions[i] = new Vector2(boardsPositions[i].X + boardSpeed, boardsPositions[i].Y);
            //    if (boardsPositions[i].X > Window.ClientBounds.Width)
            //    {
            //        boardsPositions.RemoveAt(i);
            //        i--;
            //    }
            //}//移动boardsPositions集合中每个方块的位置

            Rectangle blockRectangle = new Rectangle((int)blockPosition.X,
                (int)blockPosition.Y, blockTexture.Width, blockTexture.Height);

            hit = false;
            for (int i = 0; i < boardsPositions.Count; i++)
            {
                boardsPositions[i] = new Vector2(boardsPositions[i].X + boardSpeed, boardsPositions[i].Y);

                Rectangle boardRectangle = new Rectangle((int)boardsPositions[i].X,
                    (int)boardsPositions[i].Y, boardTexture.Width, boardTexture.Height);

                if (boardsPositions[i].X > Window.ClientBounds.Width)
                {
                    boardsPositions.RemoveAt(i);
                    i--;
                }
                if (blockRectangle.Intersects(boardRectangle))
                {
                    boardIntersects = boardsPositions[i];
                    hit = true;
                }
            }



            // TODO: Add your update logic here

            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)
        {
            GraphicsDevice.Clear(Color.CornflowerBlue);

            spriteBatch.Begin();//准备画画

            spriteBatch.Draw(blockTexture, blockPosition, Color.White);//画方块
            foreach (Vector2 blocksPosition in boardsPositions)
            {
                spriteBatch.Draw(boardTexture, blocksPosition, Color.White);
            }//遍历boardsPositions集合，画出各个跳板

            spriteBatch.End();//结束画画
            // TODO: Add your drawing code here

            base.Draw(gameTime);
        }
    }
}
