计算缩放到碰撞检测

本文关键字:碰撞检测 缩放 计算 | 更新日期: 2023-09-27 18:16:26

当我自学c#时,我一直在摆弄Monogame。我遵循微软的XNA教程来检测2d中的碰撞。

到目前为止,我在《一夫一妻》中所做的都是非常非常基本的。有两个精灵。一个播放器和一个煤质纹理。当你开始游戏时,煤会出现在一个随机的位置,你可以移动玩家。我已经放大了我的纹理。

微软教程没有处理缩放,我想知道是否有一种方法可以通过碰撞检测方法获得我缩放纹理的数量。

这是我的代码。

这是Game1类。碰撞检测方法在底部。

#region Using Statements
using System;
using System.Collections.Generic;
using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Content;
using Microsoft.Xna.Framework.Graphics;
using Microsoft.Xna.Framework.Input;
using Microsoft.Xna.Framework.Storage;
using Microsoft.Xna.Framework.GamerServices;
using Microsoft.Xna.Framework.Input.Touch;
using System.Diagnostics;
#endregion
namespace Supersum
{
/// <summary>
/// This is the main type for your game
/// </summary>
public class Game1 : Game
{
    GraphicsDeviceManager graphics;
    SpriteBatch spriteBatch;
    Player player;
    Coal coal;
    Random random;
    KeyboardState currentKeyboardState;
    KeyboardState previousKeyboardState;
    GamePadState currentGamePadState;
    GamePadState previousGamePadState;

    float playerMoveSpeed;
    public Game1()
        : base()
    {
        graphics = new GraphicsDeviceManager(this);
        graphics.PreferredBackBufferWidth = 800;
        graphics.PreferredBackBufferHeight = 480;
        graphics.ApplyChanges();
        Content.RootDirectory = "Content";
    }

    protected override void Initialize()
    {
        player = new Player();
        coal = new Coal();
        random = new Random();

        playerMoveSpeed = 8.0f;
        base.Initialize();
    }

    protected override void LoadContent()
    {
        // Create a new SpriteBatch, which can be used to draw textures.
        spriteBatch = new SpriteBatch(GraphicsDevice);
        Vector2 playerPosition = new Vector2(GraphicsDevice.Viewport.TitleSafeArea.X, GraphicsDevice.Viewport.TitleSafeArea.Y + GraphicsDevice.Viewport.TitleSafeArea.Height / 2);
        Vector2 coalPosition = new Vector2(random.Next(800), random.Next(480));
        player.Initialize(Content.Load<Texture2D>("tempChar"), playerPosition);
        coal.Initialize(Content.Load<Texture2D>("Coal"), coalPosition);

    }

    protected override void UnloadContent()
    {
        // TODO: Unload any non ContentManager content here
    }

    protected override void Update(GameTime gameTime)
    {
        if (GamePad.GetState(PlayerIndex.One).Buttons.Back == ButtonState.Pressed || Keyboard.GetState().IsKeyDown(Keys.Escape))
            Exit();

        previousGamePadState = currentGamePadState;
        previousKeyboardState = currentKeyboardState;
        currentKeyboardState = Keyboard.GetState();
        currentGamePadState = GamePad.GetState(PlayerIndex.One);

        UpdatePlayer(gameTime);
        UpdateCollision();
        base.Update(gameTime);
    }

    protected override void Draw(GameTime gameTime)
    {
        GraphicsDevice.Clear(Color.CornflowerBlue);
        spriteBatch.Begin(SpriteSortMode.BackToFront, BlendState.AlphaBlend, SamplerState.PointWrap, null, null, null);
        coal.Draw(spriteBatch);
        player.Draw(spriteBatch);
        spriteBatch.End();

        base.Draw(gameTime);
    }
    private void UpdatePlayer(GameTime gameTime)
    {
        if (currentKeyboardState.IsKeyDown(Keys.Left)||currentKeyboardState.IsKeyDown(Keys.A))
        {
            player.Position.X -= playerMoveSpeed;
        }
        if (currentKeyboardState.IsKeyDown(Keys.Right)||currentKeyboardState.IsKeyDown(Keys.D))
        {
            player.Position.X += playerMoveSpeed;
        }
        if (currentKeyboardState.IsKeyDown(Keys.Up)||currentKeyboardState.IsKeyDown(Keys.W))
        {
            player.Position.Y -= playerMoveSpeed;
        }
        if (currentKeyboardState.IsKeyDown(Keys.Down)||currentKeyboardState.IsKeyDown(Keys.S))
        {
            player.Position.Y += playerMoveSpeed;
        }
    }
    private void UpdateCollision()
    {
        Rectangle rectangle1;
        Rectangle rectangle2;
        rectangle1 = new Rectangle((int)player.Position.X, (int)player.Position.Y, player.Width * 2, player.Height * 2);
        rectangle2 = new Rectangle((int)coal.Position.X, (int)coal.Position.Y, coal.Width * 4, coal.Height * 4);
        if (rectangle1.Intersects(rectangle2))
        {
            Console.Write("Intersected'n");
        }
        else {
            Console.Write("Not Intersected'n");
        }
    }
}
}

这些是我的播放器和煤的类。

玩家

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Graphics;
namespace Supersum
{
class Player
{
    public Texture2D PlayerTexture;
    public Vector2 Position;
    public bool Active;
    public int Health;
    public int Width
    {
        get { return PlayerTexture.Width; }
    }
    public int Height
    {
        get { return PlayerTexture.Height; }
    }
    public void Initialize(Texture2D texture, Vector2 position)
    {
        PlayerTexture = texture;
        Position = position;
        Active = true;
        Health = 100;
    }
    public void Update()
    {
    }
    public void Draw(SpriteBatch spriteBatch)
    {
        spriteBatch.Draw(PlayerTexture, Position, null, Color.White, 0f, Vector2.Zero, 2f, SpriteEffects.None, 0f);
    }
 }
}

And now Coal

 using System;
 using System.Collections.Generic;
 using System.Linq;
 using System.Text;
 using Microsoft.Xna.Framework;
 using Microsoft.Xna.Framework.Graphics;
namespace Supersum
{
class Coal
{
    public Texture2D coalTexture;
    public Vector2 Position;
    public int Width
    {
        get { return coalTexture.Width; }
    }
    public int Height
    {
        get { return coalTexture.Height; }
    }
    public void Initialize(Texture2D texture, Vector2 position)
    {
        coalTexture = texture;
        Position = position;
    }
    public void Update()
    {
    }
    public void Draw(SpriteBatch spriteBatch)
    {
        spriteBatch.Draw(coalTexture, Position, null, Color.White, 0f, Vector2.Zero, 4f, SpriteEffects.None, 0f);
    }
}
}

计算缩放到碰撞检测

为您的缩放创建一个私有字段,并在绘制和高度/宽度中使用它。这样你就不需要在碰撞检测中使用任何缩放

class Coal
{
    public Texture2D coalTexture;
    public Vector2 Position;
    private float scale = 4f;
    public int Width
    {
        get { return coalTexture.Width * scale; }
    }
    public int Height
    {
        get { return coalTexture.Height * scale; }
    }
    [...]
    public void Draw(SpriteBatch spriteBatch)
    {
        spriteBatch.Draw(coalTexture, Position, null, Color.White, 0f, Vector2.Zero, scale, SpriteEffects.None, 0f);
    }
}

如果它们很容易改变和/或在多个地方使用(通常在制作游戏时需要进行很多调整),你也可以制作一个包含所有尺度的静态类:

public static class ScaleConstants
{
    public static float Player = 2f;
    public static float Coal = 4f;
}

这会将调用从(例如)return coalTexture.Width * scale;更改为return coalTexture.Width * ScaleConstants.Coal;

不要硬编码你的秤。

你应该在class Playerclass Coal中添加一个float scale;,然后在你当前使用24的所有地方简单地使用该成员。