Hi,
I would like to ask you for a little help or advise with my class. In short, what is it supposed to do is to draw a texture which works well. Further it is supposed to follow the mouse position.
Also (here is the problem) it is supposed to check for collision with Rectangle objects (argument in Update() -> _obstacleList). Once it does collide with a rectangle it is supposed to ‘bounce’ in the other direction. Right now when bouncing back the mouse position is also changed via Mouse.SetPosition().
My problem is sometimes the collision checks simply do not work. It feels like collision checks fail if I move the mouse to fast. I am also not sure whether my CheckMinkowskiSum method does the calculations right. It would be great if somebody more experienced could have a look at my class. I know it is a mess right now but I guess it is still readable:
using System.Collections.Generic;
using System.Diagnostics;
using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Graphics;
using Microsoft.Xna.Framework.Input;
using System;
using System.Windows.Forms;
using MonoTest.Environment;
using ButtonState = Microsoft.Xna.Framework.Input.ButtonState;
namespace MonoTest
{
public class Companion
{
private Texture2D texture;
private Vector2 position;
private MouseState oldMouseState;
private GraphicsDevice graphics;
private List<ITriggerObject> triggerObjList;
private int xBounceVelocity = 0;
private int yBounceVelocity = 0;
private int maxBounceVelocity = 5;
private bool isBouncing = false;
private int maxBounceFactor = 15;
private int currenBounceFactor = 0;
public Companion(Texture2D _texture, Vector2 _position, GraphicsDevice _graphics, List<ITriggerObject> _triggerObjList)
{
this.texture = _texture;
this.position = _position;
this.graphics = _graphics;
this.triggerObjList = _triggerObjList;
Mouse.SetPosition(graphics.Viewport.Width / 2, graphics.Viewport.Height / 2); //Set the mouse to a position where no collision appears!
}
public void Update(List<Obstacle> _obstacleList)
{
MouseState mState = Mouse.GetState();
if (!isBouncing)
{
CheckCollision(_obstacleList, mState);
}
else
{
Bounce();
}
oldMouseState = mState;
}
//Called while still bouncing
private void Bounce()
{
if (currenBounceFactor == maxBounceFactor)
{
isBouncing = false;
currenBounceFactor = 0;
xBounceVelocity = 0;
yBounceVelocity = 0;
}
else
{
currenBounceFactor++;
position = new Vector2(position.X+xBounceVelocity,position.Y+yBounceVelocity);
Mouse.SetPosition((int)position.X + xBounceVelocity, (int)position.Y + yBounceVelocity);
}
}
//Checks for collision with all Rectangles in the level
private void CheckCollision(List<Obstacle> _obstacleList, MouseState mState)
{
position = new Vector2(mState.X,mState.Y);
bool collides = false;
string collisionFrom = string.Empty;
Rectangle collisionRectangle = new Rectangle();
foreach (Obstacle obstacle in _obstacleList)
{
if (obstacle.BoundRectangle.Intersects(this.BoundingRect))
{
collides = true;
collisionFrom = CheckMinkowskiSum(this.BoundingRect, obstacle.BoundRectangle);
collisionRectangle = obstacle.BoundRectangle;
break;
}
}
//If a collision occured mark bouncing = true
if (collides)
{
switch (collisionFrom)
{
case "bottom":
yBounceVelocity = -maxBounceVelocity;
isBouncing = true;
break;
case "top":
yBounceVelocity = maxBounceVelocity;
isBouncing = true;
break;
case "left":
case "right":
if (collisionRectangle.Center.X < this.BoundingRect.Center.X) //Left
{
xBounceVelocity = maxBounceVelocity;
isBouncing = true;
}
else //right
{
xBounceVelocity = -maxBounceVelocity;
isBouncing = true;
}
break;
}
}
}
//Returns the direction from which the collision took place
public string CheckMinkowskiSum(Rectangle pRectangle, Rectangle oRectangle)
{
//http://gamedev.stackexchange.com/questions/24078/which-side-was-hit/24091#24091
float wy = ((pRectangle.Width + oRectangle.Width) * (pRectangle.Center.Y - oRectangle.Center.Y));
float hx = ((pRectangle.Height + oRectangle.Height) * (pRectangle.Center.X - oRectangle.Center.X));
if (wy > hx)
{
if (wy > (hx * -1))
{
return "top";
}
else
{
return "left";
}
}
else
{
if (wy > (-1 * hx))
{
return "right";
}
else
{
return "bottom";
}
}
}
public void Draw(SpriteBatch spriteBatch)
{
spriteBatch.Draw(texture,position,Color.White);
}
public Rectangle BoundingRect {
get { return new Rectangle((int)position.X, (int)position.Y, texture.Width, texture.Height); }
}
}
}
Thanks in advance!