protected override void OnUpdate(SAMTime gameTime, InputState istate) { BulletPosition = ConvertUnits2.ToDisplayUnitsPoint(PhysicsBody.Position); BulletRotation = PhysicsBody.Rotation; for (int i = _ignoredPortals.Count - 1; i >= 0; i--) { if (MonoSAMGame.GameCycleCounter - _ignoredPortals[i].LastCollidedCycle > 16) { _ignoredPortals[i].LastCollidedCycle = CollisionIgnoreObjectDecayCycles; _ignoredPortals.RemoveAt(i); } } if (Lifetime > MAXIMUM_LIFETIME) { VanishOutOfTime(); } if (GDOwner.WrapMode == GameWrapMode.Death && !Manager.BoundingBox.Contains(BulletPosition)) { if (!GDOwner.MapFullBounds.Contains(BulletPosition)) { VanishOutOfBounds(); } } if (GDOwner.WrapMode == GameWrapMode.Donut && !GDOwner.MapFullBounds.Contains(BulletPosition)) { DonutWrap(); } this.GDOwner().LaserNetwork.SemiDirty = true; }
private void AddEdgeMarker() { var mw = MapFullBounds.Width; var mh = MapFullBounds.Height; var ex = 2 * GDConstants.TILE_WIDTH; var rn = new FRectangle(-ex, -ex, mw + 2 * ex, ex); var re = new FRectangle(+mw, -ex, ex, mh + 2 * ex); var rs = new FRectangle(-ex, +mh, mw + 2 * ex, ex); var rw = new FRectangle(-ex, -ex, ex, mh + 2 * ex); var dn = new MarkerCollisionBorder { Side = FlatAlign4.NN }; var de = new MarkerCollisionBorder { Side = FlatAlign4.EE }; var ds = new MarkerCollisionBorder { Side = FlatAlign4.SS }; var dw = new MarkerCollisionBorder { Side = FlatAlign4.WW }; var bn = BodyFactory.CreateBody(GetPhysicsWorld(), ConvertUnits2.ToSimUnits(rn.Center), 0, BodyType.Static, dn); var be = BodyFactory.CreateBody(GetPhysicsWorld(), ConvertUnits2.ToSimUnits(re.Center), 0, BodyType.Static, de); var bs = BodyFactory.CreateBody(GetPhysicsWorld(), ConvertUnits2.ToSimUnits(rs.Center), 0, BodyType.Static, ds); var bw = BodyFactory.CreateBody(GetPhysicsWorld(), ConvertUnits2.ToSimUnits(rw.Center), 0, BodyType.Static, dw); var fn = FixtureFactory.AttachRectangle(ConvertUnits.ToSimUnits(rn.Width), ConvertUnits.ToSimUnits(rn.Height), 1, Vector2.Zero, bn, dn); var fe = FixtureFactory.AttachRectangle(ConvertUnits.ToSimUnits(re.Width), ConvertUnits.ToSimUnits(re.Height), 1, Vector2.Zero, be, de); var fs = FixtureFactory.AttachRectangle(ConvertUnits.ToSimUnits(rs.Width), ConvertUnits.ToSimUnits(rs.Height), 1, Vector2.Zero, bs, ds); var fw = FixtureFactory.AttachRectangle(ConvertUnits.ToSimUnits(rw.Width), ConvertUnits.ToSimUnits(rw.Height), 1, Vector2.Zero, bw, dw); }
public override void OnInitialize(EntityManager manager) { PhysicsBody = BodyFactory.CreateBody(this.GDManager().PhysicsWorld, ConvertUnits2.ToSimUnits(Position), 0, BodyType.Static); PhysicsFixture = FixtureFactory.AttachRectangle(ConvertUnits.ToSimUnits(_length), ConvertUnits.ToSimUnits(WIDTH), 1, Vector2.Zero, PhysicsBody, this); PhysicsBody.Rotation = _rotation; }
public override void OnInitialize(EntityManager manager) { PhysicsBody = BodyFactory.CreateBody(this.GDManager().PhysicsWorld, ConvertUnits2.ToSimUnits(Position), 0, BodyType.Static); PhysicsFixture = FixtureFactory.AttachRectangle(ConvertUnits.ToSimUnits(Length), ConvertUnits.ToSimUnits(WIDTH), 1, Vector2.Zero, PhysicsBody, this); PhysicsBody.Rotation = Normal + FloatMath.RAD_POS_090; Owner.Entities.AddEntity(new PortalParticleEmitter(this)); }
protected override void CreatePhysics() { PhysicsBody = BodyFactory.CreateBody(this.GDManager().PhysicsWorld, ConvertUnits2.ToSimUnits(Position), 0, BodyType.Static); PhysicsFixtureBase = FixtureFactory.AttachCircle( ConvertUnits.ToSimUnits(Scale * CANNON_DIAMETER / 2), 1, PhysicsBody, Vector2.Zero, this); { var offset = new Vector2(ConvertUnits.ToSimUnits(Scale * CANNON_DIAMETER / 2), 0); var density = 1; var width = ConvertUnits.ToSimUnits(Scale * BARREL_WIDTH); var height = ConvertUnits.ToSimUnits(Scale * BARREL_HEIGHT); Vertices rectangleVertices = PolygonTools.CreateRectangle(width / 2, height / 2, Vector2.Zero, -TRISHOT_BARREL_ANGLE); var r = offset.Rotate(-TRISHOT_BARREL_ANGLE); rectangleVertices.Translate(ref r); PolygonShape rectangleShape = new PolygonShape(rectangleVertices, density); PhysicsBody.CreateFixture(rectangleShape, this); } { var offset = new Vector2(ConvertUnits.ToSimUnits(Scale * CANNON_DIAMETER / 2), 0); var density = 1; var width = ConvertUnits.ToSimUnits(Scale * BARREL_WIDTH); var height = ConvertUnits.ToSimUnits(Scale * BARREL_HEIGHT); Vertices rectangleVertices = PolygonTools.CreateRectangle(width / 2, height / 2, Vector2.Zero, 0); var r = offset; rectangleVertices.Translate(ref r); PolygonShape rectangleShape = new PolygonShape(rectangleVertices, density); PhysicsBody.CreateFixture(rectangleShape, this); } { var offset = new Vector2(ConvertUnits.ToSimUnits(Scale * CANNON_DIAMETER / 2), 0); var density = 1; var width = ConvertUnits.ToSimUnits(Scale * BARREL_WIDTH); var height = ConvertUnits.ToSimUnits(Scale * BARREL_HEIGHT); Vertices rectangleVertices = PolygonTools.CreateRectangle(width / 2, height / 2, Vector2.Zero, +TRISHOT_BARREL_ANGLE); var r = offset.Rotate(+TRISHOT_BARREL_ANGLE); rectangleVertices.Translate(ref r); PolygonShape rectangleShape = new PolygonShape(rectangleVertices, density); PhysicsBody.CreateFixture(rectangleShape, this); } }
protected override void CreatePhysics() { PhysicsBody = BodyFactory.CreateBody(this.GDManager().PhysicsWorld, ConvertUnits2.ToSimUnits(Position), 0, BodyType.Static); PhysicsFixtureBase = FixtureFactory.AttachCircle( ConvertUnits.ToSimUnits(Scale * CANNON_DIAMETER / 2), 1, PhysicsBody, Vector2.Zero, this); FixtureFactory.AttachRectangle( ConvertUnits.ToSimUnits(Scale * BARREL_WIDTH), ConvertUnits.ToSimUnits(Scale * BARREL_HEIGHT), 1, new Vector2(ConvertUnits.ToSimUnits(Scale * CANNON_DIAMETER / 2), 0), PhysicsBody, this); }
protected override void OnUpdate(SAMTime gameTime, InputState istate) { BulletPosition = ConvertUnits2.ToDisplayUnitsPoint(PhysicsBody.Position); BulletVelocity = ConvertUnits.ToDisplayUnits(PhysicsBody.LinearVelocity); if (Lifetime > MAXIMUM_LIFETIME) { PredictKill(RemoteBulletState.Dying_FadeSlow); } if (GDOwner.WrapMode == GameWrapMode.Donut && !GDOwner.MapFullBounds.Contains(BulletPosition)) { DonutWrap(); } this.GDOwner().LaserNetwork.SemiDirty = true; }
public override void OnInitialize(EntityManager manager) { PhysicsBody = BodyFactory.CreateCircle(this.GDManager().PhysicsWorld, ConvertUnits.ToSimUnits(Scale * Bullet.BULLET_DIAMETER / 2), 1, ConvertUnits2.ToSimUnits(BulletPosition), BodyType.Dynamic, this); PhysicsBody.LinearVelocity = ConvertUnits.ToSimUnits(BulletVelocity); PhysicsBody.CollidesWith = Category.All; PhysicsBody.Restitution = 1f; // Bouncability, 1=bounce always elastic PhysicsBody.AngularDamping = 1f; // Practically no angular rotation PhysicsBody.Friction = 0f; PhysicsBody.LinearDamping = 0f; // no slowing down PhysicsBody.OnCollision += OnCollision; PhysicsBody.AngularVelocity = 0; //Body.Mass = Scale * Scale; // Weight dependent on size }
public void RemoteUpdate(RemoteBulletState state, float px, float py, Vector2 veloc, Fraction fraction, float scale, long seq, float sendertime) { if (Math.Abs(Scale - scale) > 0.01f) { SAMLog.Error("RBULL::CHANGE-SCALE", $"Remote changed scale from {Scale} to {scale} "); } if (fraction != Fraction) { SAMLog.Error("RBULL::CHANGE-FRAC", $"Remote changed fraction from {Fraction} to {fraction} "); } Scale = scale; Fraction = fraction; var delta = GDOwner.LevelTime - sendertime; if (state == RemoteBulletState.Normal) { if (PredictionState == RemoteBulletState.Normal) { // all good BulletVelocity = veloc; var newpos = new FPoint(px, py) + BulletVelocity * delta * GDOwner.GameSpeed; ClientPredictionMiss = (newpos - BulletPosition).LengthSquared() > 1f; BulletPosition = newpos; LastRemotePosition = new FPoint(px, py); PhysicsBody.Position = ConvertUnits2.ToSimUnits(BulletPosition); PhysicsBody.LinearVelocity = ConvertUnits.ToSimUnits(veloc); RemoteState = state; } else { if (sendertime - DEATH_PREDICTION_TOLERANCE >= TimeOfPredictedDeath) { // prediction said we should be death - was wrong SAMLog.Debug("Revert prediction-miss: (Revive wrongfully killed bullet)"); // Well, I'm sorry ... I guess AbortAllOperations(o => o.Name == BulletShrinkAndDieOperation.NAME); AbortAllOperations(o => o.Name == BulletFadeAndDieOperation.NAME); BulletAlpha = 1f; BulletExtraScale = 1f; BulletVelocity = veloc; BulletPosition = new FPoint(px, py) + BulletVelocity * delta * GDOwner.GameSpeed; ClientPredictionMiss = true; LastRemotePosition = new FPoint(px, py); PhysicsBody.Position = ConvertUnits2.ToSimUnits(BulletPosition); PhysicsBody.LinearVelocity = ConvertUnits.ToSimUnits(veloc); RemoteState = state; PredictionState = state; } else { // we will (predictably) die in the future } } } else { if (PredictionState != RemoteBulletState.Normal) { if (state != PredictionState) { // Prediction was correct but death cause was wrong (wtf??) AbortAllOperations(o => o.Name == BulletShrinkAndDieOperation.NAME); AbortAllOperations(o => o.Name == BulletFadeAndDieOperation.NAME); BulletAlpha = 1f; BulletExtraScale = 1f; BulletPosition = new FPoint(px, py); BulletVelocity = veloc; LastRemotePosition = BulletPosition; PhysicsBody.Position = ConvertUnits2.ToSimUnits(BulletPosition); PhysicsBody.LinearVelocity = ConvertUnits.ToSimUnits(veloc); RemoteState = state; PredictionState = state; PredictKill(state, true); } else { // Prediction was right (lucky path) BulletPosition = new FPoint(px, py); BulletVelocity = veloc; LastRemotePosition = BulletPosition; PhysicsBody.Position = ConvertUnits2.ToSimUnits(BulletPosition); PhysicsBody.LinearVelocity = ConvertUnits.ToSimUnits(veloc); RemoteState = state; MakePredictionKillReal(state); } } else { // dead but no death prediction BulletPosition = new FPoint(px, py); BulletVelocity = veloc; LastRemotePosition = BulletPosition; PhysicsBody.Position = ConvertUnits2.ToSimUnits(BulletPosition); PhysicsBody.LinearVelocity = ConvertUnits.ToSimUnits(veloc); RemoteState = state; PredictionState = state; PredictKill(state, true); MainGame.Inst.GDSound.PlayEffectCollision(); } if (GDOwner.RemoteBulletMapping[BulletID] == this) { GDOwner.RemoteBulletMapping[BulletID] = null; } } LastUpdateBigSeq = seq; }
private void DonutWrap() { BulletPosition = BulletPosition.ModuloToToSize(GDOwner.MapFullBounds.Size); PhysicsBody.Position = ConvertUnits2.ToSimUnits(BulletPosition); }
private World CreateRayWorld(LevelBlueprint lvl, float extend, float cannonEnlarge) { var world = new World(Vector2.Zero); ConvertUnits.SetDisplayUnitToSimUnitRatio(1); foreach (var elem in lvl.AllCannons) { if (elem.Diameter < 0.01f) { throw new Exception("Invalid Physics"); } var body = BodyFactory.CreateBody(world, new Vector2(elem.X, elem.Y), 0, BodyType.Static, elem); FixtureFactory.AttachCircle(cannonEnlarge * elem.Diameter / 2f + extend, 1, body, Vector2.Zero, elem); } foreach (var elem in lvl.BlueprintGlassBlocks) { if (elem.Width < 0.01f) { throw new Exception("Invalid Physics"); } if (elem.Height < 0.01f) { throw new Exception("Invalid Physics"); } var body = BodyFactory.CreateBody(world, new Vector2(elem.X, elem.Y), FloatMath.ToRadians(elem.Rotation), BodyType.Static, elem); FixtureFactory.AttachRectangle(elem.Width + extend, elem.Height + extend, 1, Vector2.Zero, body, elem); var pw = world; var w = ConvertUnits.ToSimUnits(elem.Width + extend); var h = ConvertUnits.ToSimUnits(elem.Height + extend); var p = ConvertUnits2.ToSimUnits(new FPoint(elem.X, elem.Y)); var rot = FloatMath.ToRadians(elem.Rotation); var mw = GlassBlock.MARKER_WIDTH; var cw = 10 * GlassBlock.CORNER_WIDTH * REFRAC_CORNER_ENLARGE_FAC; var bodyN = BodyFactory.CreateBody(pw, p, rot, BodyType.Static, marker_rn); FixtureFactory.AttachRectangle(w, mw, 1, new Vector2(0, -(h - mw) / 2f), bodyN, marker_rn); var bodyE = BodyFactory.CreateBody(pw, p, rot, BodyType.Static, marker_re); FixtureFactory.AttachRectangle(mw, h, 1, new Vector2(+(w - mw) / 2f, 0), bodyE, marker_re); var bodyS = BodyFactory.CreateBody(pw, p, rot, BodyType.Static, marker_rs); FixtureFactory.AttachRectangle(w, mw, 1, new Vector2(0, +(h - mw) / 2f), bodyS, marker_rs); var bodyW = BodyFactory.CreateBody(pw, p, rot, BodyType.Static, marker_rw); FixtureFactory.AttachRectangle(mw, h, 1, new Vector2(-(w - mw) / 2f, 0), bodyW, marker_rw); var bodyNE = BodyFactory.CreateBody(pw, p, rot, BodyType.Static, marker_rne); FixtureFactory.AttachRectangle(cw, cw, 1, new Vector2(+w / 2, -h / 2), bodyNE, marker_rne); var bodySE = BodyFactory.CreateBody(pw, p, rot, BodyType.Static, marker_rse); FixtureFactory.AttachRectangle(cw, cw, 1, new Vector2(+w / 2, +h / 2), bodySE, marker_rse); var bodySW = BodyFactory.CreateBody(pw, p, rot, BodyType.Static, marker_rsw); FixtureFactory.AttachRectangle(cw, cw, 1, new Vector2(-w / 2, +h / 2), bodySW, marker_rsw); var bodyNW = BodyFactory.CreateBody(pw, p, rot, BodyType.Static, marker_rnw); FixtureFactory.AttachRectangle(cw, cw, 1, new Vector2(-w / 2, -h / 2), bodyNW, marker_rnw); } foreach (var elem in lvl.BlueprintVoidCircles) { if (elem.Diameter < 0.01f) { throw new Exception("Invalid Physics"); } var body = BodyFactory.CreateBody(world, new Vector2(elem.X, elem.Y), 0, BodyType.Static, elem); FixtureFactory.AttachCircle(elem.Diameter / 2f + extend, 1, body, Vector2.Zero, elem); } foreach (var elem in lvl.BlueprintVoidWalls) { if (elem.Length < 0.01f) { throw new Exception("Invalid Physics"); } var body = BodyFactory.CreateBody(world, new Vector2(elem.X, elem.Y), 0, BodyType.Static, elem); FixtureFactory.AttachRectangle(elem.Length + extend, VoidWallBlueprint.DEFAULT_WIDTH + extend, 1, Vector2.Zero, body, elem); body.Rotation = FloatMath.DegRad * elem.Rotation; } foreach (var elem in lvl.BlueprintBlackHoles) { if (elem.Diameter < 0.01f) { throw new Exception("Invalid Physics"); } var body = BodyFactory.CreateBody(world, new Vector2(elem.X, elem.Y), 0, BodyType.Static, elem); FixtureFactory.AttachCircle(elem.Diameter * 0.5f * 0.3f, 1, body, Vector2.Zero, elem); } foreach (var elem in lvl.BlueprintPortals) { if (elem.Length < 0.01f) { throw new Exception("Invalid Physics"); } var body = BodyFactory.CreateBody(world, new Vector2(elem.X, elem.Y), 0, BodyType.Static, elem); FixtureFactory.AttachRectangle(elem.Length + extend, PortalBlueprint.DEFAULT_WIDTH + extend, 1, Vector2.Zero, body, elem); body.Rotation = FloatMath.DegRad * (elem.Normal + 90); } foreach (var elem in lvl.BlueprintMirrorBlocks) { if (elem.Width < 0.01f) { throw new Exception("Invalid Physics"); } if (elem.Height < 0.01f) { throw new Exception("Invalid Physics"); } var body = BodyFactory.CreateBody(world, new Vector2(elem.X, elem.Y), FloatMath.ToRadians(elem.Rotation), BodyType.Static, elem); FixtureFactory.AttachRectangle(elem.Width + extend, elem.Height + extend, 1, Vector2.Zero, body, elem); } foreach (var elem in lvl.BlueprintMirrorCircles) { if (elem.Diameter < 0.01f) { throw new Exception("Invalid Physics"); } var body = BodyFactory.CreateBody(world, new Vector2(elem.X, elem.Y), 0, BodyType.Static, elem); FixtureFactory.AttachCircle(elem.Diameter / 2f + extend, 1, body, Vector2.Zero, elem); } foreach (var elem in lvl.BlueprintLaserCannons) { if (elem.Diameter < 0.01f) { throw new Exception("Invalid Physics"); } var body = BodyFactory.CreateBody(world, new Vector2(elem.X, elem.Y), 0, BodyType.Static, elem); FixtureFactory.AttachCircle(cannonEnlarge * elem.Diameter / 2f + extend, 1, body, Vector2.Zero, elem); } if (lvl.WrapMode == LevelBlueprint.WRAPMODE_SOLID || lvl.WrapMode == LevelBlueprint.WRAPMODE_DONUT) { var mw = lvl.LevelWidth; var mh = lvl.LevelHeight; var ex = 2 * GDConstants.TILE_WIDTH; var rn = new FRectangle(-ex, -ex, mw + 2 * ex, ex); var re = new FRectangle(+mw, -ex, ex, mh + 2 * ex); var rs = new FRectangle(-ex, +mh, mw + 2 * ex, ex); var rw = new FRectangle(-ex, -ex, ex, mh + 2 * ex); var bn = BodyFactory.CreateBody(world, ConvertUnits.ToSimUnits(rn.VecCenter), 0, BodyType.Static, marker_dn); var be = BodyFactory.CreateBody(world, ConvertUnits.ToSimUnits(re.VecCenter), 0, BodyType.Static, marker_de); var bs = BodyFactory.CreateBody(world, ConvertUnits.ToSimUnits(rs.VecCenter), 0, BodyType.Static, marker_ds); var bw = BodyFactory.CreateBody(world, ConvertUnits.ToSimUnits(rw.VecCenter), 0, BodyType.Static, marker_dw); var fn = FixtureFactory.AttachRectangle(ConvertUnits.ToSimUnits(rn.Width), ConvertUnits.ToSimUnits(rn.Height), 1, Vector2.Zero, bn, marker_dn); var fe = FixtureFactory.AttachRectangle(ConvertUnits.ToSimUnits(re.Width), ConvertUnits.ToSimUnits(re.Height), 1, Vector2.Zero, be, marker_de); var fs = FixtureFactory.AttachRectangle(ConvertUnits.ToSimUnits(rs.Width), ConvertUnits.ToSimUnits(rs.Height), 1, Vector2.Zero, bs, marker_ds); var fw = FixtureFactory.AttachRectangle(ConvertUnits.ToSimUnits(rw.Width), ConvertUnits.ToSimUnits(rw.Height), 1, Vector2.Zero, bw, marker_dw); } return(world); }
public override void OnInitialize(EntityManager manager) { PhysicsBody = BodyFactory.CreateBody(this.GDManager().PhysicsWorld, ConvertUnits2.ToSimUnits(Position), 0, BodyType.Static); PhysicsFixture = FixtureFactory.AttachCircle(ConvertUnits.ToSimUnits(_diameter / 2f), 1, PhysicsBody, this); }
public override void OnInitialize(EntityManager manager) { var pw = this.GDManager().PhysicsWorld; var w = ConvertUnits.ToSimUnits(_width); var h = ConvertUnits.ToSimUnits(_height); var p = ConvertUnits2.ToSimUnits(Position); PhysicsBody = BodyFactory.CreateBody(pw, p, _rotation, BodyType.Static, this); PhysicsFixture = FixtureFactory.AttachRectangle(w, h, 1, Vector2.Zero, PhysicsBody, this); var rn = new MarkerRefractionEdge { Source = this, Side = FlatAlign4.NN }; var re = new MarkerRefractionEdge { Source = this, Side = FlatAlign4.EE }; var rs = new MarkerRefractionEdge { Source = this, Side = FlatAlign4.SS }; var rw = new MarkerRefractionEdge { Source = this, Side = FlatAlign4.WW }; var rne = new MarkerRefractionCorner { Source = this, Side = FlatAlign4C.NE }; var rse = new MarkerRefractionCorner { Source = this, Side = FlatAlign4C.SE }; var rsw = new MarkerRefractionCorner { Source = this, Side = FlatAlign4C.SW }; var rnw = new MarkerRefractionCorner { Source = this, Side = FlatAlign4C.NW }; var bodyN = BodyFactory.CreateBody(pw, p, _rotation, BodyType.Static, rn); FixtureFactory.AttachRectangle(w, MARKER_WIDTH, 1, new Vector2(0, -(h - MARKER_WIDTH) / 2f), bodyN, rn); var bodyE = BodyFactory.CreateBody(pw, p, _rotation, BodyType.Static, re); FixtureFactory.AttachRectangle(MARKER_WIDTH, h, 1, new Vector2(+(w - MARKER_WIDTH) / 2f, 0), bodyE, re); var bodyS = BodyFactory.CreateBody(pw, p, _rotation, BodyType.Static, rs); FixtureFactory.AttachRectangle(w, MARKER_WIDTH, 1, new Vector2(0, +(h - MARKER_WIDTH) / 2f), bodyS, rs); var bodyW = BodyFactory.CreateBody(pw, p, _rotation, BodyType.Static, rw); FixtureFactory.AttachRectangle(MARKER_WIDTH, h, 1, new Vector2(-(w - MARKER_WIDTH) / 2f, 0), bodyW, rw); var bodyNE = BodyFactory.CreateBody(pw, p, _rotation, BodyType.Static, rne); FixtureFactory.AttachRectangle(CORNER_WIDTH, CORNER_WIDTH, 1, new Vector2(+w / 2, -h / 2), bodyNE, rne); var bodySE = BodyFactory.CreateBody(pw, p, _rotation, BodyType.Static, rse); FixtureFactory.AttachRectangle(CORNER_WIDTH, CORNER_WIDTH, 1, new Vector2(+w / 2, +h / 2), bodySE, rse); var bodySW = BodyFactory.CreateBody(pw, p, _rotation, BodyType.Static, rsw); FixtureFactory.AttachRectangle(CORNER_WIDTH, CORNER_WIDTH, 1, new Vector2(-w / 2, +h / 2), bodySW, rsw); var bodyNW = BodyFactory.CreateBody(pw, p, _rotation, BodyType.Static, rnw); FixtureFactory.AttachRectangle(CORNER_WIDTH, CORNER_WIDTH, 1, new Vector2(-w / 2, -h / 2), bodyNW, rnw); }
private List <Tuple <List <Vector2>, ICannonBlueprint, float> > FindBulletPaths(LevelBlueprint lvl, World world, int sourceID, FPoint spawnPoint, Vector2 spawnVeloc, List <Vector2> fullpath, float scale, float lifetime) { var none = new List <Tuple <List <Vector2>, ICannonBlueprint, float> >(); // path, cannon, quality fullpath = fullpath.ToList(); object collisionUserObject = null; Contact collisionContact = null; var farseerBullet = BodyFactory.CreateCircle(world, ConvertUnits.ToSimUnits(scale * Bullet.BULLET_DIAMETER / 2), 1, ConvertUnits2.ToSimUnits(spawnPoint), BodyType.Dynamic, null); farseerBullet.LinearVelocity = ConvertUnits.ToSimUnits(spawnVeloc); farseerBullet.CollidesWith = Category.All; farseerBullet.Restitution = 1f; // Bouncability, 1=bounce always elastic farseerBullet.AngularDamping = 1f; // Practically no angular rotation farseerBullet.Friction = 0f; farseerBullet.LinearDamping = 0f; // no slowing down farseerBullet.OnCollision += (fa, fb, cobj) => { collisionUserObject = fb.UserData; collisionContact = cobj; if (fb.UserData is GlassBlockBlueprint) { return(true); } if (fb.UserData is MirrorBlockBlueprint) { return(true); } if (fb.UserData is MirrorCircleBlueprint) { return(true); } if (fb.UserData is MarkerCollisionBorder) { return(true); } return(false); }; farseerBullet.AngularVelocity = 0; fullpath.Add(spawnPoint.ToVec2D()); for (;;) { collisionUserObject = null; foreach (var bh in lvl.BlueprintBlackHoles) { var pp = ConvertUnits.ToDisplayUnits(farseerBullet.Position) - new Vector2(bh.X, bh.Y); var force = bh.Power / pp.LengthSquared(); var vecForce = pp.WithLength(force); farseerBullet.ApplyForce(ConvertUnits.ToSimUnits(vecForce)); } world.Step(1 / SIMULATION_UPS); // x UPS lifetime += 1 / SIMULATION_UPS; fullpath.Add(ConvertUnits2.ToDisplayUnitsPoint(farseerBullet.Position).ToVec2D()); if (collisionUserObject is PortalBlueprint) { var veloc = ConvertUnits.ToDisplayUnits(farseerBullet.LinearVelocity); world.RemoveBody(farseerBullet); var fPortal = (PortalBlueprint)collisionUserObject; Vector2 normal; FixedArray2 <Vector2> t; collisionContact.GetWorldManifold(out normal, out t); bool hit = FloatMath.DiffRadiansAbs(normal.ToAngle(), FloatMath.ToRadians(fPortal.Normal)) < FloatMath.RAD_POS_001; if (!hit) { return(none); } var dat = new List <Tuple <List <Vector2>, ICannonBlueprint, float> >(); foreach (var outportal in lvl.BlueprintPortals.Where(p => p.Side != fPortal.Side && p.Group == fPortal.Group)) { var stretch = outportal.Length / fPortal.Length; var cIn = new FPoint(fPortal.X, fPortal.Y); var cOut = new FPoint(outportal.X, outportal.Y); var cInVecNormal = Vector2.UnitX.RotateDeg(fPortal.Normal); var cInVecDirection = cInVecNormal.RotateWithLength(FloatMath.RAD_POS_090, fPortal.Length / 2f); var cOutVecNormal = Vector2.UnitX.RotateDeg(outportal.Normal); var cOutVecDirection = cOutVecNormal.RotateWithLength(FloatMath.RAD_POS_090, outportal.Length / 2f); var rot = FloatMath.ToRadians(outportal.Normal - fPortal.Normal) + FloatMath.RAD_POS_180; var projec = ConvertUnits.ToDisplayUnits(farseerBullet.Position).ProjectOntoLine(cIn, cInVecDirection); var newVelocity = ConvertUnits.ToDisplayUnits(farseerBullet.LinearVelocity).Rotate(rot); var newStart = cOut + cOutVecDirection * (-projec) + cOutVecNormal * (Portal.WIDTH / 2f) + newVelocity.WithLength(scale * Bullet.BULLET_DIAMETER / 2 + 4); var sub = FindBulletPaths(lvl, world, sourceID, newStart, newVelocity, fullpath, scale * stretch, lifetime); dat.AddRange(sub); } return(dat); } if (collisionUserObject is ICannonBlueprint) { world.RemoveBody(farseerBullet); var tgcannon = (ICannonBlueprint)collisionUserObject; if (tgcannon.CannonID == sourceID) { return(none); } var quality = Math2D.LinePointDistance(ConvertUnits2.ToDisplayUnitsPoint(farseerBullet.Position), ConvertUnits2.ToDisplayUnitsPoint(farseerBullet.Position) + ConvertUnits.ToDisplayUnits(farseerBullet.LinearVelocity), new FPoint(tgcannon.X, tgcannon.Y)); return(new List <Tuple <List <Vector2>, ICannonBlueprint, float> > { Tuple.Create(fullpath, tgcannon, quality) }); } bool oow = (farseerBullet.Position.X < 0 - 64) || (farseerBullet.Position.Y < 0 - 64) || (farseerBullet.Position.X > ConvertUnits.ToSimUnits(lvl.LevelWidth) + 64) || (farseerBullet.Position.Y > ConvertUnits.ToSimUnits(lvl.LevelHeight) + 64); bool ool = (lifetime >= Bullet.MAXIMUM_LIFETIME * LIFETIME_FAC); //if (collisionUserObject != null || oow || ool) //{ // world.RemoveBody(farseerBullet); // return new List<Tuple<List<Vector2>, CannonBlueprint, float>> { Tuple.Create(fullpath, new CannonBlueprint(farseerBullet.Position.X, farseerBullet.Position.Y, 64, 1, 0, FloatMath.GetRangedIntRandom(0, 9999999)), 1f) }; //} if (collisionUserObject is VoidWallBlueprint) { world.RemoveBody(farseerBullet); return(none); } if (collisionUserObject is VoidCircleBlueprint) { world.RemoveBody(farseerBullet); return(none); } if (collisionUserObject is BlackHoleBlueprint) { world.RemoveBody(farseerBullet); return(none); } if (oow || ool) { world.RemoveBody(farseerBullet); return(none); } if (lvl.WrapMode == LevelBlueprint.WRAPMODE_DONUT) { var pbullet = ConvertUnits.ToDisplayUnits(farseerBullet.Position); pbullet.X = (pbullet.X + lvl.LevelWidth) % lvl.LevelWidth; pbullet.Y = (pbullet.Y + lvl.LevelHeight) % lvl.LevelHeight; farseerBullet.Position = ConvertUnits.ToSimUnits(pbullet); } } }
protected virtual void CreateShieldPhysics() { var shieldObj = new ShieldCollisionMarker(this); PhysicsShieldBody = BodyFactory.CreateBody(this.GDManager().PhysicsWorld, ConvertUnits2.ToSimUnits(Position), 0, BodyType.Static); FixtureFactory.AttachCircle( ConvertUnits.ToSimUnits(Scale * CANNON_SHIELD_DIAMETER / 2), 1, PhysicsBody, Vector2.Zero, shieldObj); }