1

我正在尝试制作一个简单的乒乓球游戏,但我陷入了与桨的碰撞和添加到分数上的问题。这是我的球类代码:

namespace Pong
{
class Ball
{
    Game1 game;
    Player player;
    Computer computer;

    public Texture2D Texture;
    public Vector2 Position;

    public Vector2 Motion;
    float Speed;

    Rectangle ballRectangle;
    Rectangle playerPaddle;
    Rectangle computerPaddle;

    Random random = new Random();

    public void Initialize()
    {
        game = new Game1();
        player = new Player();
        computer = new Computer();

        Start();
    }

    public void Start()
    {
        Motion = Vector2.Zero;
        Position = new Vector2(391, 215);

        Speed = 0.8f;

        Motion = new Vector2(random.Next(-1, 1), random.Next(-1, 1));
    }

    public void Update()
    {
        Position += Motion * Speed;

        CheckForCollision();
    }

    public void CheckForCollision()
    {
        ballRectangle = new Rectangle((int)Position.X, (int)Position.Y, 20, 20);
        playerPaddle = new Rectangle((int)player.Position.X, (int)player.Position.Y, 25, 105);
        computerPaddle = new Rectangle((int)computer.Position.X, (int)computer.Position.Y, 25, 105);

        if (ballRectangle.Intersects(playerPaddle))
        {
            Motion.X *= -1;
        }
        if (ballRectangle.Intersects(computerPaddle))
        {
            Motion.X *= -1;
        }
        if (Position.Y < 0)
        {
            Motion.Y *= -1;
        }
        if (Position.Y > 450)
        {
            Motion.Y *= -1;
        }
        if (Position.X < 0)
        {
            game.computerScore += 1;
            Start();
        }
        if (Position.X > 800)
        {
            game.playerScore += 1;
            Start();
        }
    }

    public void LoadContent(ContentManager Content)
    {
        Texture = Content.Load<Texture2D>("ball");
    }

    public void Draw(SpriteBatch spriteBatch)
    {
        spriteBatch.Draw(Texture, Position,Color.White);
    }
}
}

在矩形中,我使用了图像的实际像素而不是 player.texture.width

这是我的游戏课:

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

    Texture2D bgtexture;
    Vector2 BGpos = new Vector2(0, 0);

    Ball ball;
    Player player;
    Computer computer;

    SpriteFont Score;
    Vector2 scorePosition = new Vector2(375, 5);
    public int playerScore;
    public int computerScore;
    string scoreOutput;

    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()
    {
        ball = new Ball();
        player = new Player();
        computer = new Computer();

        ball.Initialize();
        player.Initialze();
        computer.Initialize();

        this.graphics.PreferredBackBufferHeight = 450;
        this.graphics.PreferredBackBufferWidth = 800;
        this.graphics.ApplyChanges();

        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);

        bgtexture = Content.Load<Texture2D>("PongBG");
        Score = Content.Load<SpriteFont>("Score");

        ball.LoadContent(this.Content);
        player.LoadContent(this.Content);
        computer.LoadContent(this.Content);
    }

    /// <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
    }

    /// <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();

        scoreOutput = playerScore + " " + computerScore;

        ball.Update();
        player.Update();
        computer.Update();

        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.Black);

        spriteBatch.Begin();

        spriteBatch.Draw(bgtexture, BGpos, Color.White);

        ball.Draw(this.spriteBatch);
        player.Draw(this.spriteBatch);
        computer.Draw(this.spriteBatch);

        spriteBatch.DrawString(Score, scoreOutput, scorePosition, Color.AntiqueWhite);

        spriteBatch.End();

        base.Draw(gameTime);
    }
}
}

球在顶部和底部很好地从屏幕边缘反弹,但它只是直接穿过桨。同样,一旦它击中桨后面的边缘,它就会像它应该的那样开始,但它不会将分数添加到玩家和计算机的分数上。

4

1 回答 1

0

由于您正在进行逐像素碰撞,因此球的移动速度总是有可能比更新方法计算出的碰撞速度更快。如果球移动得太快,则可能始终是碰撞前的帧,球位于桨之前,并且在下一次更新中,应用速度并且球的新位置在桨后面。只是一个想法-这在我身上发生了几次。

于 2012-08-08T15:04:29.840 回答