0
votes

I have been messing around in Monogame while I teach myself c#. I followed Microsofts XNA tutorial for detecting collision in a 2d. Here

In what I have done in Monogame so far is very very basic. There are 2 sprites. A player and a coal texture. The coal appears in a random spot when you start the game and you can move the player around. I have scaled up my textures.

The Microsoft tutorial doesn't deal with scaling and I was wondering if there was a way to get the amount I scaled the texture by into the collision detection method.

Here is my code.

This is the Game1 class. The collision detection method is at the bottom.

#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");
        }

    }
}
}

And these are my classes for my player and coal.

Player

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);
    }
}
}
2
What do you mean by amount I scaled the texture by? In your code I don't see any kind of scale variable. If you scaled the textures yourself, then your code should still work. - Jashaszun
Do you just mean making the 2 and 4 that you're multiplying with the Player's and Coal's Width and Height into scale variables? - Jashaszun
In the player and coal class the Draw method has a property for scaling. Right before Sprite effects. In player it's 2f so it's scaled up 2X and in coal it's 4f so it's scaled up 4X. - DarthIrule
Please add that to your code then. - Jashaszun
Instead of hardcoding them why don't you simply make a private field and use that for both Draw and multiplying width/height? I don't understand what's the problem here. - Pierre-Luc Pineault

2 Answers

0
votes

Don't hardcode your scales.

You should add a float scale; to both class Player and class Coal, and then simply use that member in all of the places that you are currently using the scales 2 and 4.

0
votes

Make a private field for your scaling and use it in both Draw and Height/Width. That way you won't have to use any scaling at all in your collision detection

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

If they are prone to change and/or used at multiple places (Usually there's a lot of tweaking involved when making a game), you can also make a static class containing all your scales :

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

Which would change the calls from (for example) return coalTexture.Width * scale; to return coalTexture.Width * ScaleConstants.Coal;