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 に答える