You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

MonoGame Pong复刻项目按键控制精灵上下移动问题求助

核心问题说明

  • 你没有在Update方法里更新键盘状态变量,currentKBState一直保留程序启动时的初始值,完全检测不到后续的按键操作
  • 当前的按键判断逻辑是「按键按下的瞬间移动一次」,不是按住按键时持续移动,而且单次移动500像素的数值过大,会直接让挡板飞出屏幕
  • 缺少W、S、下方向键的控制逻辑,也没有做边界限制,挡板容易移出游戏窗口看不到

可直接运行的修改后代码

using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Graphics;
using Microsoft.Xna.Framework.Input;

namespace Pong
{
    public class Game1 : Game
    {
        private GraphicsDeviceManager _graphics;
        SpriteBatch spriteBatch;
        Texture2D RightPlayer;
        Texture2D LeftPlayer;
        Texture2D Ball;
        Vector2 LeftPos;
        Vector2 RightPos;
        Vector2 BallPos;
        KeyboardState currentKBState, previousKBState = Keyboard.GetState();
        int Ypos1;
        // 新增:移动速度参数,方便后续调整
        const float MoveSpeed = 300f;
        
        public Game1()
        {
            _graphics = new GraphicsDeviceManager(this);
            Content.RootDirectory = "Content";
            IsMouseVisible = true;
        }

        protected override void Initialize()
        {
            Ypos1 = 50;
            base.Initialize();
        }

        protected override void LoadContent()
        {
            spriteBatch = new SpriteBatch(GraphicsDevice);
            RightPlayer = Content.Load<Texture2D>("rodeSpeler");
            LeftPlayer = Content.Load<Texture2D>("blauweSpeler");
            Ball = Content.Load<Texture2D>("Bal");
        }

        protected override void Update(GameTime gameTime)
        {
            if (GamePad.GetState(PlayerIndex.One).Buttons.Back == ButtonState.Pressed || Keyboard.GetState().IsKeyDown(Keys.Escape))
                Exit();
            
            // 改动1:每一帧先更新最新的键盘状态
            previousKBState = currentKBState;
            currentKBState = Keyboard.GetState();
            
            // 改动2:获取增量时间,保证不同设备上移动速度一致
            float deltaTime = (float)gameTime.ElapsedGameTime.TotalSeconds;
            
            // 改动3:改为按住按键就持续移动,加上W/S和下方向键的判断
            if (currentKBState.IsKeyDown(Keys.Up) || currentKBState.IsKeyDown(Keys.W))
            {
                // 向上移动Y坐标减小
                Ypos1 -= (int)(MoveSpeed * deltaTime);
            }
            if (currentKBState.IsKeyDown(Keys.Down) || currentKBState.IsKeyDown(Keys.S))
            {
                // 向下移动Y坐标增大
                Ypos1 += (int)(MoveSpeed * deltaTime);
            }
            
            // 改动4:增加边界限制,不让挡板移出屏幕
            // 上方边界:不能小于0
            if (Ypos1 < 0)
                Ypos1 = 0;
            // 下方边界:不能超过窗口高度减去挡板自身高度,这里假设挡板高度是100,你可以换成你实际图片的高度
            if (Ypos1 > _graphics.PreferredBackBufferHeight - 100)
                Ypos1 = _graphics.PreferredBackBufferHeight - 100;
            
            LeftPos = new Vector2(0, Ypos1);
            base.Update(gameTime);
        }
        
        protected override void Draw(GameTime gameTime)
        {
            GraphicsDevice.Clear(Color.CornflowerBlue);
            spriteBatch.Begin();
            spriteBatch.Draw(LeftPlayer, LeftPos, Color.White);
            spriteBatch.End();    
            base.Draw(gameTime);
        }
    }
}

关键改动说明

  1. 每次执行Update的时候先更新键盘状态,这样才能拿到你当前按了什么键
  2. 把按键判断从「按下瞬间触发」改成「按住就持续触发」,符合Pong游戏的操作习惯
  3. 加入了增量时间计算,不管你的游戏跑60帧还是30帧,挡板移动速度都是一样的
  4. 加了边界判断,挡板不会移出屏幕外看不到
  5. 把单次移动的数值改成了可调整的速度参数,你可以修改MoveSpeed的数值调整移动快慢,数值越大移动越快

如果你的挡板图片高度不是100,把边界判断里的100换成你实际的图片高度就可以了。

内容的提问来源于stack exchange,提问作者Eke Reus

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.10.04 05:09:01