public Branch(Path2D path, GameContent gameContent, World world, Branch nearestBranch) { this.gameContent = gameContent; dot = gameContent.dot; circle = gameContent.jointCircle; square = gameContent.jointSquare; cursor = gameContent.cursor; BodyDef bd = new BodyDef(); bd.position = path.Keys[0]; bd.type = BodyType.Dynamic; body = world.CreateBody(bd); fixtureCount = path.Keys.Count; for (int i = 0; i < path.Keys.Count; i++) CreateFixture(path.Keys[i] - path.Keys[0]); if (nearestBranch != null) { RevoluteJointDef revJd = new RevoluteJointDef(); revJd.bodyA = body; revJd.bodyB = nearestBranch.body; revJd.localAnchorA = Vector2.Zero; AABB aabb; nearestBranch.nearestFixture.GetAABB(out aabb); Vector2 p = aabb.GetCenter(); revJd.localAnchorB = nearestBranch.nearestFixture.GetBody().GetLocalPoint(p); revJd.enableMotor = true; revJd.referenceAngle = nearestBranch.nearestFixture.GetBody().Rotation; revoJoint = (RevoluteJoint)world.CreateJoint(revJd); revoJoint.SetUserData((Branch)nearestBranch); nearestBranch.nearestFixture.SetUserData((Branch)this); } newGrow = true; }
private void CreateStem() { AddBranch = true; AABB aabb = new AABB(); body.GetFixtureList().GetAABB(out aabb); Vector2 v = aabb.GetCenter() + new Vector2(0, 15); Path2D p = new Path2D(); p.AddPoint(v); p.AddPoint(v + new Vector2(0, -10)); stem = new Branch(p, gameContent, body.GetWorld(), null); RevoluteJointDef revJd = new RevoluteJointDef(); revJd.bodyA = stem.body; revJd.bodyB = ground; revJd.collideConnected = true; revJd.localAnchorA = Vector2.Zero; revJd.localAnchorB = stem.body.Position; revJd.enableMotor = true; stem.revoJoint = (RevoluteJoint)world.CreateJoint(revJd); // A Small rotation sets the body in motion stem.body.Rotation = (float)Math.PI / 360; }
public void Grow(Path2D path) { AABB aabb; body.GetFixtureList().GetAABB(out aabb); Vector2 p = aabb.GetCenter(); float d = Vector2.Distance(p, body.Position); float theta = (float)Math.Atan2((double)(p.Y - body.Position.Y), (double)(p.X - body.Position.X)); theta -= body.Rotation; Vector2 localEnd = d * new Vector2((float)Math.Cos(theta), (float)Math.Sin(theta)); fixtureCount += path.Keys.Count - 1; for (int i = 1; i < path.Keys.Count; i++) { d = Vector2.Distance(path.Keys[i], path.Keys[0]); theta = (float)Math.Atan2((double)(path.Keys[i].Y - path.Keys[0].Y), (double)(path.Keys[i].X - path.Keys[0].X)); theta -= body.Rotation; CreateFixture(localEnd + d * new Vector2((float)Math.Cos(theta), (float)Math.Sin(theta))); //CreateFixture(body.GetLocalPoint(p) + path.Keys[i] - path.Keys[0]); } newGrow = true; }
public void Update(GameTime gameTime) { bool groundContact = false; for (ContactEdge ce = body.GetContactList(); ce != null; ce = ce.Next) if (ce.Contact.IsTouching() && ce.Other.GetType() == BodyType.Static) groundContact = true; if (groundContact || body.Position.Y > gameContent.viewport.Height * 2) dTime += (float)gameTime.ElapsedGameTime.TotalSeconds; else dTime = 0; if (dTime > DestroyTime) body.GetWorld().DestroyBody(body); IsConnected = true; if (revoJoint == null) IsConnected = false; else { object o = revoJoint.GetUserData(); if (o is Branch) { IsConnected = ((Branch)o).IsConnected; if (((Branch)o).body.GetFixtureList() == null) IsConnected = false; } // If Ground is in contact if (groundContact) IsConnected = false; } DropAndGrowLeaves(gameTime); wasConnected = IsConnected; path = new Path2D(); for (Fixture f = body.GetFixtureList(); f != null; f = f.GetNext()) { // Clear if the other joint body is destroyed if (f.GetUserData() is Branch && ((Branch)f.GetUserData()).body.GetFixtureList() == null) f.SetUserData(null); AABB aabb; f.GetAABB(out aabb); path.Keys.Add(aabb.GetCenter()); } if (revoJoint != null && body.GetFixtureList() != null) { AABB aabb; body.GetFixtureList().GetAABB(out aabb); float length = Vector2.Distance(aabb.GetCenter(), body.Position); float angleError = revoJoint.GetJointAngle(); float gain = 0.5f; int torqueFactor = 10000; if (angleError != 0) { revoJoint.SetMotorSpeed(-gain * angleError); revoJoint.SetMaxMotorTorque(torqueFactor * (float)Math.Min(Math.Abs(angleError), Math.PI / 18) * (float)Math.Pow(length, 1.5f)); } } UpdateLeavesAndApples(gameTime); if (!IsConnected && body.Position.Y > gameContent.viewport.Height * 3) body.GetWorld().DestroyBody(body); }
public void HandleInput(InputState input, int playerIndex) { MouseState prevMouseState = input.LastMouseState[0]; MouseState mouseState = input.CurrentMouseState[0]; mousePos = new Vector2(mouseState.X, mouseState.Y); if (prevMouseState.LeftButton == ButtonState.Pressed && mouseState.LeftButton == ButtonState.Released && path.Keys.Count != 0) { if (path.Keys.Count > 1) { if (nearestBranch != null && nearestBranch.body.GetFixtureList() != null) { if (nearestBranch.body.GetFixtureList() == nearestBranch.nearestFixture) nearestBranch.Grow(path); else branches.Add(new Branch(path, GameContent, world, nearestBranch)); } //else branches.Add(new Branch(path, GameContent, world, null)); } path = new Path2D(); } if (prevMouseState.RightButton == ButtonState.Pressed && mouseState.RightButton == ButtonState.Released && nearestBranch != null && path.Keys.Count == 0) { nearestBranch.CutDown(nearestBranch.nearestFixture); } if (mouseState.LeftButton == ButtonState.Pressed) { if (GameContent.viewport.TitleSafeArea.Contains(new Point(mouseState.X, mouseState.Y))) path.AddPoint(mousePos); } else { nearestBranch = null; float nearestDist = 10; foreach (Branch b in branches) { float d = b.NearestFixtureDistance(mousePos, nearestDist); if (d < nearestDist) { if (nearestBranch != null) nearestBranch.nearestFixture = null; nearestBranch = b; nearestDist = d; } } } }