Skip to content

Instantly share code, notes, and snippets.

@havarnov
Created December 4, 2025 21:44
Show Gist options
  • Select an option

  • Save havarnov/308209c7f4d32a436cae863f8502bf5d to your computer and use it in GitHub Desktop.

Select an option

Save havarnov/308209c7f4d32a436cae863f8502bf5d to your computer and use it in GitHub Desktop.
Monogame + Box2d.Net - rectangle issue
/*
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<OutputType>Exe</OutputType>
<TargetFramework>net10.0</TargetFramework>
<RootNamespace>monogame_playground</RootNamespace>
<ImplicitUsings>enable</ImplicitUsings>
<Nullable>enable</Nullable>
</PropertyGroup>
<ItemGroup>
<PackageReference Include="Box2D.NET" Version="3.1.1.557" />
<PackageReference Include="MonoGame.Framework.DesktopGL" Version="3.8.4.1" />
</ItemGroup>
</Project>
*/
using Box2D.NET;
using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Graphics;
using Microsoft.Xna.Framework.Input;
using var game = new PlaygroundGame();
game.Run();
public class PlaygroundGame : Game
{
private SpriteBatch spriteBatch = null!;
private B2WorldId world;
private B2BodyId hero;
private B2DebugDraw draw;
public PlaygroundGame()
{
_ = new GraphicsDeviceManager(this);
}
protected override void Initialize()
{
var wDef = B2Types.b2DefaultWorldDef();
wDef.gravity = new B2Vec2(0, 0);
world = B2Worlds.b2CreateWorld(ref wDef);
draw = new B2DebugDraw()
{
DrawSolidPolygonFcn = (ref transform, vertices, count, radius, color, context) =>
{
var v = vertices.ToArray();
var maxX = v.Max(i => i.X);
var maxY = v.Max(i => i.Y);
var minX = v.Min(i => i.X);
var minY = v.Min(i => i.Y);
var size = new Point((int)(maxX - minX), (int)(maxY - minY));
var _texture = new Texture2D(GraphicsDevice, 1, 1);
_texture.SetData([Color.Blue]);
spriteBatch.Draw(
_texture,
new Rectangle(
new Point((int)(transform.p.X - (size.X / 2f)), (int)(transform.p.Y - (size.Y / 2f))),
size),
sourceRectangle: null,
Color.White,
rotation: 0,
origin: Vector2.Zero,
effects: SpriteEffects.None,
layerDepth: 0.1f);
},
};
draw.drawShapes = true;
{
var movableDef = B2Types.b2DefaultBodyDef();
movableDef.type = B2BodyType.b2_dynamicBody;
movableDef.position = new B2Vec2(150, 150);
var movableShapeDef = B2Types.b2DefaultShapeDef();
var movable = B2Bodies.b2CreateBody(world, ref movableDef);
var movablePolygon = B2Geometries.b2MakeBox(5, 5);
var movableShape = B2Shapes.b2CreatePolygonShape(movable, ref movableShapeDef, ref movablePolygon);
}
{
var wallDef = B2Types.b2DefaultBodyDef();
wallDef.type = B2BodyType.b2_staticBody;
wallDef.position = new B2Vec2(100, 100);
var wallShapeDef = B2Types.b2DefaultShapeDef();
var wall = B2Bodies.b2CreateBody(world, ref wallDef);
var wallPolygon = B2Geometries.b2MakeBox(20, 20);
var wallShape = B2Shapes.b2CreatePolygonShape(wall, ref wallShapeDef, ref wallPolygon);
}
{
var heroDef = B2Types.b2DefaultBodyDef();
heroDef.type = B2BodyType.b2_dynamicBody;
heroDef.position = new B2Vec2(10, 10);
var heroShapeDef = B2Types.b2DefaultShapeDef();
hero = B2Bodies.b2CreateBody(world, ref heroDef);
var heroPolygon = B2Geometries.b2MakeBox(15, 5);
var heroShape = B2Shapes.b2CreatePolygonShape(hero, ref heroShapeDef, ref heroPolygon);
}
base.Initialize();
}
protected override void LoadContent()
{
spriteBatch = new SpriteBatch(GraphicsDevice);
base.LoadContent();
}
protected override void Update(GameTime gameTime)
{
var position = B2Bodies.b2Body_GetPosition(hero);
Console.WriteLine($"{position.X}:{position.Y}");
var keyboardState = Keyboard.GetState();
var horizontalInput =
(keyboardState.IsKeyDown(Keys.Left) ? -1 : 0)
+ (keyboardState.IsKeyDown(Keys.Right) ? 1 : 0);
var verticalInput =
(keyboardState.IsKeyDown(Keys.Up) ? -1 : 0)
+ (keyboardState.IsKeyDown(Keys.Down) ? 1 : 0);
var moveVector = new Vector2(horizontalInput, verticalInput);
if (moveVector == Vector2.Zero)
{
// B2Bodies.b2Body_SetLinearDamping(hero, 4f);
}
else if (moveVector.X == 0)
{
var c = B2Bodies.b2Body_GetLinearVelocity(hero);
c.Y = moveVector.Y * 10;
var length = (float)Math.Sqrt(Math.Pow(c.X, 2) + Math.Pow(c.Y, 2));
var normalized = new B2Vec2(c.X / length, c.Y / length);
B2Bodies.b2Body_SetLinearVelocity(hero, new B2Vec2(normalized.X * 10f, normalized.Y * 10f));
B2Bodies.b2Body_SetLinearDamping(hero, 4f);
}
else if (moveVector.Y == 0)
{
var c = B2Bodies.b2Body_GetLinearVelocity(hero);
c.X = moveVector.X * 10;
var length = (float)Math.Sqrt(Math.Pow(c.X, 2) + Math.Pow(c.Y, 2));
var normalized = new B2Vec2(c.X / length, c.Y / length);
B2Bodies.b2Body_SetLinearVelocity(hero, new B2Vec2(normalized.X * 10f, normalized.Y * 10f));
B2Bodies.b2Body_SetLinearDamping(hero, 4f);
}
else
{
B2Bodies.b2Body_SetLinearVelocity(hero, new B2Vec2(moveVector.X * 10f, moveVector.Y * 10f));
}
B2Worlds.b2World_Step(world, gameTime.ElapsedGameTime.Milliseconds, 8);
base.Update(gameTime);
}
protected override void Draw(GameTime gameTime)
{
GraphicsDevice.Clear(Color.White);
spriteBatch.Begin(SpriteSortMode.FrontToBack, null, SamplerState.PointClamp);
B2Worlds.b2World_Draw(world, draw);
spriteBatch.End();
base.Draw(gameTime);
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment