1

だから私はXNAのバウンディングボックスを見つけようとしていて、少し問題があります。以下は私のコードです。プログラムは、UDLR方式で移動できる長方形のオブジェクト(スーパーマリオゲームのThwompスプライトを使用)と、画面上で跳ね返るランダムに生成されたボックスのリスト(疑問符のボックススプライトを使用)で構成されています。 、マリオからも)。ボックスがThwompの側面で跳ね返るところまでコードがありますが、上下はありません(スプライトを通過するだけです)。そのため、現在、バウンディングボックスはボックスではなく、左右の壁になっています。ボックスをThwompの上部と下部からも跳ね返らせるために、コードに何ができますか?

ありがとう

ゲームクラス:

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


    GraphicsDeviceManager graphics;
    SpriteBatch spriteBatch;

    Sprite playerOne;

    static public int height;
    static public int width;

    static Random rand = new Random();

    KeyboardState keyboardState;

    List<Sprite> ballList = new List<Sprite>();
    int ballCount = 10;

    private void CheckPaddleWallCollision()
    {

    }


    private void CheckBallCollision(Sprite ball)
    {

        int MaxX =
            graphics.GraphicsDevice.Viewport.Width - ball.BoundingBox.Width;
        int MinX = 0;
        int MaxY =
            graphics.GraphicsDevice.Viewport.Height - ball.BoundingBox.Height;
        int MinY = 0;



        if (ball.BoundingBox.Intersects(playerOne.BoundingBox))
        {
            ball.Velocity.X *= -1;
            ball.Position += ball.Velocity;
        }

        if (ball.BoundingBox.Y > MaxY)
        {
            ball.Velocity.Y *= -1;
            ball.Position += ball.Velocity;
        }

        if (ball.BoundingBox.Y < MinY)
        {
            ball.Velocity.Y *= -1;
            ball.Position += ball.Velocity;
        }

        if (ball.BoundingBox.X < MinX)
        {
            ball.Velocity.X *= -1;
            ball.Position += ball.Velocity;
        }

        if (ball.BoundingBox.X > MaxX)
        {
            ball.Velocity.X *= -1;
            ball.Position += ball.Velocity;
        }
        /*if ((ball.Position.X < -ball.BoundingBox.Width)
            || (ball.Position.X > Window.ClientBounds.Width))
            SetInStartPostion(); */
    }

    /*private void SetInStartPostion()
    {
        playerOne.Position.Y = (
            Window.ClientBounds.Height -
            playerOne.BoundingBox.Height) / 2;


        ball.Position.X = playerOne.BoundingBox.Right + 1;

        ball.Position.Y = (
            Window.ClientBounds.Height -
            ball.BoundingBox.Height) / 2;

        ball.Velocity = new Vector2(8f, -8f);
    } */

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

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

        height = GraphicsDevice.Viewport.Height;
        width = GraphicsDevice.Viewport.Width;

        Texture2D paddleTexture = Content.Load<Texture2D>("Thwomp");
        Vector2 position;

        position = new Vector2(
            100,
            (Window.ClientBounds.Height - paddleTexture.Height) / 2);
        playerOne = new Sprite(paddleTexture, position);

        position = new Vector2(
            (Window.ClientBounds.Width - paddleTexture.Width),
            (Window.ClientBounds.Height - paddleTexture.Height) / 2);

        Texture2D ballTexture = Content.Load<Texture2D>("QuestionMarkBlock");

        position = new Vector2(
                 playerOne.BoundingBox.Right + 1,
                 (Window.ClientBounds.Height - ballTexture.Height) / 2);

        for (int i = 0; i < ballCount; i++)
        {
            position = new Vector2(rand.Next(Game1.width), rand.Next(Game1.height));
            Sprite ball = new Sprite(
                     ballTexture,
                    position,
                     new Vector2(4f, -4f));
            ballList.Add(ball);
        }
    }


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



        keyboardState = Keyboard.GetState();

        if (keyboardState.IsKeyDown(Keys.Up))
            playerOne.Position.Y -= 4f;

        if (keyboardState.IsKeyDown(Keys.Down))
            playerOne.Position.Y += 4f;

        if (keyboardState.IsKeyDown(Keys.Left))
            playerOne.Position.X -= 4f;

        if (keyboardState.IsKeyDown(Keys.Right))
            playerOne.Position.X += 4f;



        foreach (Sprite block in ballList)
        {
            block.Position += block.Velocity;
            CheckBallCollision(block);

        }

        CheckPaddleWallCollision();



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

        playerOne.Draw(spriteBatch);

        foreach (Sprite block in ballList)
        {
            block.Draw(spriteBatch);
        }

        spriteBatch.End();

        base.Draw(gameTime);
    }


    public static int vGameWidth { get; set; }
}
}

スプライトクラス:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

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

namespace BoundingBoxCollision
{
public class Sprite
{



    Texture2D texture;
    public Vector2 Position;
    public Vector2 Velocity;


    public Rectangle BoundingBox
    {
        get
        {
            return new Rectangle(
                (int)Position.X,
                (int)Position.Y,
                texture.Width,
                texture.Height);
        }
    }

    public Sprite(Texture2D texture, Vector2 position)
    {
        this.texture = texture;
        this.Position = position;
    }

    public Sprite(Texture2D texture, Vector2 position, Vector2 velocity)
    {
        this.texture = texture;
        this.Position = position;
        this.Velocity = velocity;
    }



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

}
}
4

2 に答える 2

1

最も簡単な方法は次のとおりです。

if (ball.BoundingBox.Intersects(playerOne.BoundingBox))
        {
            ball.Velocity.X *= -1;
            ball.Velocity.Y *= -1;
            ball.Position += ball.Velocity;
        }

これは完全な反省になります。より現実的な方法を使用する場合は、次のようにします (疑似コード):

  1. ボールとプレーヤーが衝突するかどうかを確認する
  2. 上/下、左/右、または正確なコーナーで衝突しているかどうかを判断します
    1. 左右 :ball.Velocity.X*= -1;
    2. 上/下:ball.Velocity.Y *= -1;
    3. コーナー:ball.Velocity.X *= -1;&&ball.Velocity.Y *= -1;

これが少し役立つことを願っています!

よろしく

フロア

于 2012-09-28T08:36:25.000 に答える
0

2番(上/下)については、次を使用して位置チェックを行うことができます

playerOne.BoundingBox.Top

playerOne.BoundingBox.Bottom?

.Top と .Bottom は、長方形の上部または下部の Y 座標を返す必要があります。

于 2012-10-27T17:48:19.450 に答える