zoukankan      html  css  js  c++  java
  • 跟我一起学XNA(2)让物体动起来②(附源码)

    加载一个静态图片,左右移动,真没啥意思,鼠标单击上去都没反应,这也太山寨了吧。
    来点稍微给力的,\(^o^)/

    新建项目,加载图片,和第一章是一样的

            Texture2D people;
            protected override void LoadContent()
            {
                // Create a new SpriteBatch, which can be used to draw textures.
                spriteBatch = new SpriteBatch(GraphicsDevice);
                people = Content.Load<Texture2D>(@"Image/PlayerMagic");
                // TODO: use this.Content to load your game content here
            }

    这里有一个地方,就是当你加载Body0这个gif的时候,最好转换成png或者jpg之类的,而且最好不要太大,因为它加载图片大会出现一个这样的异常

    意思都能看懂,就是图片太大,Textrue2D容积小,当然有解决办法,我还没想到,以后知道了补上,如果是程序无法识别的图片格式,他会报格式不识别这个错误

            //这里是图片中每一帧图片的大小
            Point pictureSize = new Point(150, 150);
            Point currentFrame = new Point(0, 0);
            //这里是你的图片有几帧,10是行,1是列,因为图片只有一行,所以列没啥用,那个Body0可以用得着
            Point pictureNum = new Point(10, 1);
            public Game1()
            {
                graphics = new GraphicsDeviceManager(this);
                Content.RootDirectory = "Content";
                //因为程序1秒刷新60次,你可以自定义刷新的时间,这里是每0.12秒刷新
                TargetElapsedTime = new TimeSpan(0, 0, 0, 0, 120);
                //鼠标可见
                IsMouseVisible = true;
            }

    因为是从一张图片动态取帧,所以才有Point pictureNum = new Point(10, 1);这样的变量10列1行,其实用两个变量记录也行,一个记录行,一个记录列

     protected override void Draw(GameTime gameTime)
            {
                GraphicsDevice.Clear(Color.CornflowerBlue);
    
                // TODO: Add your drawing code here
                spriteBatch.Begin(SpriteSortMode.FrontToBack, BlendState.AlphaBlend);
                spriteBatch.Draw(people, Vector2.Zero,
                new Rectangle(currentFrame.X * pictureSize.X,
                currentFrame.Y * pictureSize.Y,
                pictureSize.X,
                pictureSize.Y),
                Color.White, 0, Vector2.Zero,
                1, SpriteEffects.None, 0);
                spriteBatch.End();
                base.Draw(gameTime);
            }

    Draw这里,要使用重载函数来动态的用new Rectangle来获取显示的位置了

            protected override void Update(GameTime gameTime)
            {
                // Allows the game to exit
                if (GamePad.GetState(PlayerIndex.One).Buttons.Back == ButtonState.Pressed)
                    this.Exit();
    
                // TODO: Add your update logic here
                ++currentFrame.X;
                if (currentFrame.X >= pictureNum.X)
                {
                    currentFrame.X = 0;
                }
                base.Update(gameTime);
            }

    Update这里加入一个判断,当Rectangle超过图片大小时候,清零重来
    运行,左上角会有一个gif图片,当然,还有另外一种方法

    我这里面加了8张图片,可以再Draw中这么处理

            protected override void Draw(GameTime gameTime)
            {
                GraphicsDevice.Clear(Color.CornflowerBlue);
    
                // TODO: Add your drawing code here
                spriteBatch.Begin(SpriteSortMode.FrontToBack, BlendState.AlphaBlend);
                //spriteBatch.Draw(people, Vector2.Zero,
                //new Rectangle(currentFrame.X * pictureSize.X,
                //currentFrame.Y * pictureSize.Y,
                //pictureSize.X,
                //pictureSize.Y),
                //Color.White, 0, Vector2.Zero,
                //1, SpriteEffects.None, 0);
                spriteBatch.Draw(list[currentFrame.X], Vector2.Zero, null, Color.White);
                ++currentFrame.X;
                if (currentFrame.X >=8)
                {
                    currentFrame.X = 0;
                }
                spriteBatch.End();
                base.Draw(gameTime);
            }

    之前我有这样的操作,也能达到相同效果

    List<Texture2D> list = new List<Texture2D>();
            protected override void LoadContent()
            {
                // Create a new SpriteBatch, which can be used to draw textures.
                spriteBatch = new SpriteBatch(GraphicsDevice);
                people = Content.Load<Texture2D>(@"Image/PlayerMagic");
                for (int i = 0; i < 8; i++)
                {
                    list.Add(Content.Load<Texture2D>(string.Format(@"Image/{0}",i)));
                }
                // TODO: use this.Content to load your game content here
            }

    两个方法一样的,注意的是如果用第二种方法,你要把Update中的方法先注释掉

    进入下一个问题

    图片随鼠标移动

            //记录前一个鼠标的位置
            MouseState preMouseState;
            //图片的位置
            Vector2 ringsPosition = Vector2.Zero;
            //移动的速度
            const float ringsSpeed = 4;

    我们新加几个变量

        protected override void Update(GameTime gameTime)
            {
                // Allows the game to exit
                if (GamePad.GetState(PlayerIndex.One).Buttons.Back == ButtonState.Pressed)
                    this.Exit();
    
                // TODO: Add your update logic here
                ++currentFrame.X;
                if (currentFrame.X >= pictureNum.X)
                {
                    currentFrame.X = 0;
                }
    
                MouseState mouseState = Mouse.GetState();
                if (mouseState.X != preMouseState.X ||
                mouseState.Y != preMouseState.Y)
                    ringsPosition = new Vector2(mouseState.X-75, mouseState.Y-75);
                preMouseState = mouseState;
                base.Update(gameTime);
            }

    Update的时候记录一下鼠标的位置,说白了就是把图片移动到当前鼠标位置呗,这里也要改一下

      protected override void Draw(GameTime gameTime)
            {
                GraphicsDevice.Clear(Color.CornflowerBlue);
    
                // TODO: Add your drawing code here
                spriteBatch.Begin(SpriteSortMode.FrontToBack, BlendState.AlphaBlend);
                spriteBatch.Draw(people, ringsPosition,
                new Rectangle(currentFrame.X * pictureSize.X,
                currentFrame.Y * pictureSize.Y,
                pictureSize.X,
                pictureSize.Y),
                Color.White, 0, Vector2.Zero,
                1, SpriteEffects.None, 0);
                //spriteBatch.Draw(list[currentFrame.X], ringsPosition, null, Color.White);
                //++currentFrame.X;
                //if (currentFrame.X >= 8)
                //{
                //    currentFrame.X = 0;
                //}
    
                spriteBatch.End();
                base.Draw(gameTime);
            }

    红色也要改一下

     spriteBatch.Draw(list[currentFrame.X], Vector2.Zero, null, Color.White);
                ++currentFrame.X;
                if (currentFrame.X >=8)
                {
                    currentFrame.X = 0;
                }

    还有这个东西也要改一下,红色的那个,我程序已经改过了,如果注释错了可能会报错

    声明一下(图片是从别的地方拿过来的,当时玩wpf的时候看过深蓝的教程,顺手把图片牵过来了)
    源代码:files.cnblogs.com/fish124423/XNA.rar

  • 相关阅读:
    [黑防VIP课程]汇编基础一日一学习2
    立即释放.net下的com组件
    WinExec,ShellExecute ,CreateProcess 区别
    .Net中如何操作IIS(原理篇)+实现类
    全用存储过程和全用SQL思考笔记
    C# 中的常用正则表达式总结
    .Net中窗体间传递值的一种方法
    [黑防VIP课程]汇编基础一日一学习1
    [黑防VIP课程]汇编基础一日一学习2
    浮点指令
  • 原文地址:https://www.cnblogs.com/fish124423/p/2739291.html
Copyright © 2011-2022 走看看