I want to use class BoundingBox in XNA 4.0 to check collision between cube with cube or cube with sphere? I know about BoundingSphere but I don't know use to BoundingBox. Have any good sample about this! Thanks!
You make boundingboxes like this:
Vector3 CenterOfBox = new Vector3(10,10,10);
int Width = 10;
int Height = 10;
BoundingBox BoundingBox1 = new BoundingBox(CenterOfBox - new Vector(Width/2,Height/2,Width/2),CenterOfBox + new Vector(Width/2,Height/2,Width/2));
More info: http://msdn.microsoft.com/en-us/library/microsoft.xna.framework.boundingbox.boundingbox.aspx
Lets say you have BoundingBox1 and BoundingBox2
Then you can check if they intersect with:
if(BoundingBox1.Intersect(BoundingBox2))
{
//They hit
}
else
{
//They don't hit
}
You can also pass a BoundingSphere in the Intersect function
More info: http://msdn.microsoft.com/en-us/library/microsoft.xna.framework.boundingbox.intersects.aspx
Related
I'm trying to achieve this kind of shadow, my research led me to using the CGPathRefto draw the shadow myself, but I can't figure out how it actually works.
Drawing the label.layer.shadowPath looks like a good plan, can anyone show me/point me to how I should proceed?
EDIT : I'm now to the point of trying to draw a UIBezierPath based on the string in the current label, the path being the actual shape of the shadow I need. I'm not sure that's the best option but it looks more promising.
EDIT 2 : Here is the code i'm now working with. this outlines the text of the label as an image, but it's pretty much the exact same text as the label itself, i still have to work my way around making it look like a shadow. Note, we're using Xamarin
public override void Draw (CoreGraphics.CGRect rect)
{
base.Draw (rect);
using (CGContext g = UIGraphics.GetCurrentContext ()) {
UIBezierPath completePath = UIBezierPath.Create ();
g.ScaleCTM (1, -1);
g.TranslateCTM (2, -(this.Bounds.Height / 2) - (this.Font.LineHeight / 3));
CTLine line = new CTLine (this.AttributedText);
CTRun[] runs = line.GetGlyphRuns ();
for (int i = 0; i < runs.Length; i++) {
CTRun run = runs [i];
CTFont font = run.GetAttributes ().Font;
for (int j = 0; j < run.GlyphCount; j++) {
NSRange currentRange = new NSRange (j, 1);
CGPoint[] positions = run.GetPositions (currentRange);
ushort[] glyphs = run.GetGlyphs (currentRange);
CGPath letter = font.GetPathForGlyph (glyphs [0]);
CGAffineTransform transform = CGAffineTransform.MakeTranslation (positions [0].X, positions [0].Y);
CGPath path = new CGPath (letter, transform);
UIBezierPath newPath = UIBezierPath.FromPath (path);
completePath.AppendPath (newPath);
}
}
completePath.LineWidth = 1;
UIColor.Red.SetStroke ();
UIColor.Blue.SetFill ();
completePath.Stroke ();
completePath.Fill ();
completePath.ClosePath ();
//Here I will try to loop over my current points and go down & right at every step of the loop, see how it goes performance-wise. Instead of one complex drawing I'll just have a very simple drawing that has thousands of points :o
g.AddPath (completePath.CGPath);
g.DrawPath (CGPathDrawingMode.FillStroke);
}
There is no built in way to achieve this effect. You have to implement the drawing code on your own.
Here are two ideas to create the shadow:
Draw the text in dark blue color, repeated n times, starting from the original position in 0.5 pt. steps shifted down right. This has bad performance but is really easy to implement.
Find the text outline using Core Text and implement some algorithm that creates the actual outline of the shadow. This could then be used as the shadowPath property.
I essentially want the "sprites" to collide when they stick together. However, I don't want the "joint" to be rigid; I essentially want the sprites to be able to move around as long as they are in contact with each other. Imagine two circles connected, and you can move one circle around the other, as long as it remains in contact.
I found this question: How to make one body stick to another moving object in SpriteKit and a lot of other resources that explain how to make sprites stick upon collision, but they all use SKJoints, which are rigid are not really flexible.
I guess another way to phrase it would be to say that I want the sprites to stick, but I want them to be able to "slide" on each other.
Well, I can think of one workaround, but this wouldn't work with non-normal polygons.
Sticking (pun unintended) with your circles example, what if you lock the position of the circle?
let circle1 = center circle
let circle2 = movable circle
Knowing the width of both circles, you can place in the update function that the position should be exactly the distance of:
((circle1.frame.width / 2) + (circle2.frame.width / 2))
If you're up to it, here's some code to help you on your way.
override func update(currentTime: CFTimeInterval) {
{
let distance = hypotf(Float(circle1.position.x - circle2.position.x), Float(circle1.position.y - circle2.position.y))
//calculate circle distances from each other
let radius = ((circle1.frame.width / 2) + (circle2.frame.width / 2))
//distance of circle positions
if distance != radius
{
//if distance is less or more than radius
let pointA = circle1.position
let pointB = circle2.position
let pointC = CGPointMake(pointB.x + 2, pointB.y)
let angle_ab = atan2(pointA.y - pointB.y, pointA.x - pointB.x)
let angle_cb = atan2(pointC.y - pointB.y, pointC.x - pointB.x)
let angle_abc = angle_ab - angle_cb
//get angle of circles from each other using atan2
let vectorx = cos(angle_abc)
let vectory = sin(angle_abc)
//convert angle into vectors
let x = circle1.position.x + radius * vectorx
let y = circle1.position.y + radius * vectory
//get new coordinates from vector, radius and center circle position
circle2.position = CGPointMake(x, y)
//set new position
}
}
Well you need to write code to make sure the movable circle, is well movable.
But, this should work.
I haven't tested this yet though, and I haven't even learned geometry let alone trig in school yet.
If I'm reading your question as you intended it, you can still use joints- just create actions with Inverse Kinematic constraints that allow rotation and translation around the contacting circles' joint.
https://developer.apple.com/library/prerelease/ios/documentation/SpriteKit/Reference/SKAction_Ref/index.html#//apple_ref/doc/uid/TP40013017-CH1-SW72
I made a 2D isometric renderer. It works fine but now I want to show my scene from 4 differents point of view (NO NW SE SW) but, on a 90° rotation, my camera cannot keep the center of my scene on screen.
What's working :
I calcul new projection of scene to match the new viewport (x y z in my world).
I reorganise part of my scene(chunk) to draw them in a correct order
I reorganise 'tiles' of 'chunks' to draw them in a correct order
I can keep the correct center with a 180 degres rotation.
What's do not working :
I cannot find a correct translation to apply to my camera after a 90 degres rotation.
What I know :
To keep the same center on a 180° rotation with my camera I have to do this :
camera.Position -= new Vector2(2 * camera.Position.X + camera.Width, 2 * camera.Position.Y + camera.Height);
Illustration
If the center of your map is origo (0,0,0), this gets easy:
First you store your default camera position in a Vector3 CameraOffset, then you calculate position using a rotation-matrix. 90* in redians is half a Pi, so we will use PiOverTwo. We will also use an enum to decide what direction to be pointing, so you can say
Camera.Orientation = Orientation.East;
and the camera should fix itself :)
public enum Orientation
{
North, East, South, West
}
in camera:
public Vector3 Position { get; protected set; }
Vector3 _CameraOffset = new Vector3(0, 20, 20);
public Vector3 CameraOffset
{
get
{
return _Orientation;
}
set
{
_Orientation = value;
UpdateOrientation();
}
}
Orientation _Orientation = Orientation.North;
public Orientation Orientation
{
get
{
return _Orientation;
}
set
{
_Orientation = value;
UpdateOrientation();
}
}
private void UpdateOrientation()
{
Position = Vector3.Transform(CameraOffset, Matrix.CreateRotationY(MathHelper.PiOverTwo * (int)Orientation));
}
If you want a gliding movement between positions, I think I can help too ;)
If your camera does not focus on Vector3.Zero and should not rotate around it, you just need to change:
Position = Vector3.Transform(CameraOffset, Matrix.CreateRotationY(MathHelper.PiOverTwo * (int)Orientation));
to:
Position = Vector3.Transform(CameraOffset, Matrix.CreateRotationY(MathHelper.PiOverTwo * (int)Orientation) * Matrix.CreateTranslation(FocusPoint));
Here, FocusPoint is the point in 3D that you rotate around (your worlds center). And now you also know how to let your camera move around, if you call UpdateOrientation() in your Camera.Update() ;)
EDIT; So sorry, totally missed the point that you use 2D. I'll be back later to see if I can help :P
I'm looking for the best option on how to handle snapping sprites to a tilemap. I'm trying to make a Chu Chu Rocket clone. If you dont know the game. It is a tilebased game where you place arrows on a specfic tile to direct unts around the maps. So I need to snap the sprites to the center of the tile at all times and then detect a collision with either an arrow which takes up a whole tile or a wall or other obstruction. Any ideas on what the based way would be to detect those things since it would require different kinds of collision detection i believe.
The easiest way to snap the sprites to a tile is to draw them centered at a tile. The collision detection can be done in your update function by checking against your level object.
class Mouse
{
public int XTile;
public int YTile;
public int XDelta;
public int YDelta;
}
//in Update
if (Level[mouse.YTile][mouse.XTile] == Tiles.Arrow)
{
//change mouse.XDelta and mouse.YDelta based on the direction of the arrow
}
if (Level[mouse.YTile + YDelta][mouse.XTile + XDelta] == Tiles.Wall)
{
//change mouse.XDelta and mouse.YDelta based on wall rules
}
//in Draw
int tileSize = 32; //or whatever size tile you are using
spriteBatch.Draw(mouseSprite, new Vector2(mouse.XTile * tileSize,
mouse.YTile * tileSize), Color.White);
//or, if the mouseSprite doesn't take up the whole tile
int sizeDifference = tileSize - mouseSprite.Width;
spriteBatch.Draw(mouseSprite, new Vector2(mouse.XTile * tileSize + sizeDifference / 2f,
mouse.YTile * tileSize + sizeDifference / 2f), Color.White);
I am pulling my hair out over this mouse picking thing. I do not know if the problem lies in my Ray calculation or my BoundingSpheres, anyway here's the code for my ray calculations:
public Ray CalculateRay(InputManager input)
{
Vector3 nearSource = new Vector3(input.CurrentMousePosition, 0f);
Vector3 farSource = new Vector3(input.CurrentMousePosition, 1f);
Vector3 nearPoint = Engine.Device.Viewport.Unproject(nearSource, _projectionMatrix,
_viewMatrix, Matrix.Identity);
Vector3 farPoint = Engine.Device.Viewport.Unproject(farSource,
_projectionMatrix, _viewMatrix, Matrix.Identity);
Vector3 direction = farPoint - nearPoint;
direction.Normalize();
return new Ray(nearPoint, direction);
}
and for the intersection check:
public bool RayIntersectsModel()
{
foreach (ModelMesh mesh in _model.Meshes)
{
BoundingSphere sphere = mesh.BoundingSphere;
sphere.Center = _position;
Ray ray = Engine.Camera.CalculateRay(Engine.Input);
if (sphere.Intersects(ray) != null)
{
return true;
}
}
return false;
}
It's not like it isn't working at all but it seems to be very inaccurate... or something. The models are just spheres, very simple. Any help or insight would be greatly appreciated!
Thanks!
Well, when I was transforming my bounding sphere I was first applying the world matrix then the bone transforms. This seems to put the bounding sphere in the wrong place. Switching it to first applying the bone transforms THEN the world matrix did it.