public void killRope(string levelUid, int entityId) { RopeComponent ropeComponent = (RopeComponent)_entityManager.getComponent(levelUid, entityId, ComponentType.Rope); List <int> ropeGrabEntities = _entityManager.getEntitiesPosessing(levelUid, ComponentType.RopeGrab); // Detach any rope grab components from this rope for (int i = 0; i < ropeGrabEntities.Count; i++) { RopeGrabComponent ropeGrabComponent = (RopeGrabComponent)_entityManager.getComponent(levelUid, ropeGrabEntities[i], ComponentType.RopeGrab); if (ropeGrabComponent.ropeEntityId == entityId) { detachAll(ropeGrabComponent); _entityManager.removeComponent(levelUid, ropeGrabEntities[i], ropeGrabComponent); } } if (ropeComponent != null) { RopeNode current = ropeComponent.ropeNodeHead; while (current != null) { if (current.anchorJoint != null) { int entityIdA = (int)current.anchorJoint.BodyA.UserData; int entityIdB = (int)current.anchorJoint.BodyB.UserData; MetamerComponent metamerComponentA = _entityManager.getComponent(levelUid, entityIdA, ComponentType.Metamer) as MetamerComponent; MetamerComponent metamerComponentB = _entityManager.getComponent(levelUid, entityIdB, ComponentType.Metamer) as MetamerComponent; if (metamerComponentA != null) { metamerComponentA.metamer.anchorCount--; if (metamerComponentA.metamer.anchorCount <= 0) { current.anchorJoint.BodyA.World.RemoveBody(current.anchorJoint.BodyA); metamerComponentA.metamer.body = null; } } if (metamerComponentB != null) { metamerComponentB.metamer.anchorCount--; if (metamerComponentB.metamer.anchorCount <= 0) { current.anchorJoint.BodyB.World.RemoveBody(current.anchorJoint.BodyB); metamerComponentB.metamer.body = null; } } } // Destroy body current.body.World.RemoveBody(current.body); current = current.next; } _entityManager.killEntity(levelUid, entityId); } }
// update public void update(GameTime gameTime) { if (_singleStep || !_paused) { string levelUid = LevelSystem.currentLevelUid; LevelSystem levelSystem = _systemManager.getSystem(SystemType.Level) as LevelSystem; if (levelSystem.finalized) { PlayerSystem playerSystem = _systemManager.getSystem(SystemType.Player) as PlayerSystem; RopeSystem ropeSystem = _systemManager.getSystem(SystemType.Rope) as RopeSystem; PhysicsComponent playerPhysicsComponent = _entityManager.getComponent(levelUid, PlayerSystem.PLAYER_ID, ComponentType.Physics) as PhysicsComponent; List <int> toolbarEntities = _entityManager.getEntitiesPosessing(levelUid, ComponentType.Toolbar); // Player equipment if (playerSystem != null) { ToolbarComponent playerToolbar = _entityManager.getComponent(levelUid, PlayerSystem.PLAYER_ID, ComponentType.Toolbar) as ToolbarComponent; WorldPositionComponent playerPositionComponent = _entityManager.getComponent(levelUid, PlayerSystem.PLAYER_ID, ComponentType.WorldPosition) as WorldPositionComponent; ItemComponent selectedItem = playerToolbar.selectedItem; if (selectedItem != null) { selectedItem.primaryContinuousAction = InputSystem.newMouseState.LeftButton == ButtonState.Pressed; selectedItem.primarySingleAction = selectedItem.primaryContinuousAction && InputSystem.oldMouseState.LeftButton == ButtonState.Released; selectedItem.secondaryContinuousAction = InputSystem.newMouseState.RightButton == ButtonState.Pressed; selectedItem.secondarySingleAction = selectedItem.secondaryContinuousAction && InputSystem.oldMouseState.RightButton == ButtonState.Released; //bool leftTriggerDown = InputSystem.usingGamepad && InputSystem.newGamepadState.Triggers.Left > 0.5f && InputSystem.oldGamepadState.Triggers.Left <= 0.5f; //bool rightTriggerDown = InputSystem.usingGamepad && InputSystem.newGamepadState.Triggers.Right > 0.5f && InputSystem.oldGamepadState.Triggers.Right <= 0.5f; AimComponent aimComponent = _entityManager.getComponent(levelUid, PlayerSystem.PLAYER_ID, ComponentType.Aim) as AimComponent; if (selectedItem.definition.hasAimingComponent && aimComponent != null) { WorldPositionComponent worldPositionComponent = _entityManager.getComponent(levelUid, PlayerSystem.PLAYER_ID, ComponentType.WorldPosition) as WorldPositionComponent; if (worldPositionComponent != null) { Vector2 worldPosition = worldPositionComponent.position; if (InputSystem.usingGamepad) { Vector2 vector = InputSystem.newGamepadState.ThumbSticks.Left * selectedItem.state.currentRangeLimit; vector.Y *= -1; aimComponent.angle = (float)Math.Atan2(vector.Y, vector.X); aimComponent.length = vector.Length(); aimComponent.vector = vector; } else { Vector2 relative = (InputSystem.worldMouse - worldPosition); aimComponent.angle = (float)Math.Atan2(relative.Y, relative.X); aimComponent.length = Math.Min(relative.Length(), selectedItem.state.currentRangeLimit); aimComponent.vector = relative; } } } } } // All toolbars for (int i = 0; i < toolbarEntities.Count; i++) { ToolbarComponent toolbarComponent = _entityManager.getComponent(levelUid, toolbarEntities[i], ComponentType.Toolbar) as ToolbarComponent; ItemComponent selectedItem = toolbarComponent.selectedItem; if (selectedItem != null) { if (selectedItem.secondarySingleAction) { Console.WriteLine("secondary action"); } switch (selectedItem.definition.uid) { // RopeGun case "ropegun": if (selectedItem.primarySingleAction) { AimComponent aimComponent = _entityManager.getComponent(levelUid, toolbarEntities[i], ComponentType.Aim) as AimComponent; Vector2 initialPointA = (_entityManager.getComponent(levelUid, toolbarEntities[i], ComponentType.WorldPosition) as WorldPositionComponent).position; Vector2 initialPointB = initialPointA + new Vector2((float)Math.Cos(aimComponent.angle), (float)Math.Sin(aimComponent.angle)) * aimComponent.length; int ropeEntityId = _entityManager.factory.createSingleAnchorRope(levelUid, initialPointA, initialPointB, _defaultRopeMaterial, true); if (ropeEntityId != -1) { RopeGrabComponent ropeGrabComponent = _entityManager.getComponent(levelUid, toolbarComponent.entityId, ComponentType.RopeGrab) as RopeGrabComponent; RopeComponent ropeComponent = _entityManager.getComponent(levelUid, ropeEntityId, ComponentType.Rope) as RopeComponent; PhysicsComponent physicsComponent = _entityManager.getComponent(levelUid, toolbarEntities[i], ComponentType.Physics) as PhysicsComponent; RopeGrabComponent newRopeGrabComponent = null; Vector2 initialVelocity = physicsComponent.body.LinearVelocity; RopeNode currentNode = null; int ropeSegmentCount; if (physicsComponent == null) { break; } // Handle initial velocity currentNode = ropeComponent.ropeNodeHead; ropeSegmentCount = currentNode.count; System.Diagnostics.Debug.Assert(ropeSegmentCount != 0); int count = ropeSegmentCount; while (currentNode != null) { float weight = (float)count / (float)ropeSegmentCount; currentNode.body.LinearVelocity = currentNode.body.LinearVelocity + initialVelocity * weight; count--; currentNode = currentNode.next; } // Handle previous grabs if (ropeGrabComponent != null) { RopeComponent previouslyGrabbedRope = _entityManager.getComponent(levelUid, ropeGrabComponent.ropeEntityId, ComponentType.Rope) as RopeComponent; ropeSystem.releaseRope(ropeGrabComponent, physicsComponent.body); if (previouslyGrabbedRope.destroyAfterRelease) { previouslyGrabbedRope.timeToLive = 100; } _entityManager.removeComponent(levelUid, toolbarComponent.entityId, ropeGrabComponent); ropeGrabComponent = null; } newRopeGrabComponent = new RopeGrabComponent(ropeEntityId, ropeComponent.ropeNodeHead, 0f, ropeComponent.reverseClimbDirection); ropeSystem.grabRope(newRopeGrabComponent, physicsComponent.body); _entityManager.addComponent(levelUid, toolbarComponent.entityId, newRopeGrabComponent); } } break; // Dynamite case "dynamite": if (selectedItem.primarySingleAction) { AimComponent aimComponent = _entityManager.getComponent(levelUid, toolbarEntities[i], ComponentType.Aim) as AimComponent; _entityManager.factory.createDynamite(levelUid, playerPhysicsComponent.body.Position, aimComponent.vector * 80f); } break; // Water gun case "watergun": if (selectedItem.primaryContinuousAction) { FluidSystem fluidSystem = _systemManager.getSystem(SystemType.Fluid) as FluidSystem; AimComponent aimComponent = _entityManager.getComponent(levelUid, toolbarEntities[i], ComponentType.Aim) as AimComponent; Vector2 aimUnitVector = Vector2.Normalize(aimComponent.vector); Vector2 particlePosition = playerPhysicsComponent.body.Position + aimUnitVector + new Vector2(StasisMathHelper.floatBetween(-0.1f, 0.1f, _rng), StasisMathHelper.floatBetween(-0.1f, 0.1f, _rng)); Vector2 particleVelocity = aimUnitVector * 0.4f; fluidSystem.createParticle(particlePosition, particleVelocity); } break; } selectedItem.primarySingleAction = false; selectedItem.secondarySingleAction = false; selectedItem.primaryContinuousAction = false; selectedItem.secondaryContinuousAction = false; } } } } _singleStep = false; }
public void update(GameTime gameTime) { if (!_paused || _singleStep) { string levelUid = LevelSystem.currentLevelUid; LevelSystem levelSystem = _systemManager.getSystem(SystemType.Level) as LevelSystem; if (levelSystem.finalized) { List <int> ropeEntities = _entityManager.getEntitiesPosessing(levelUid, ComponentType.Rope); for (int i = 0; i < ropeEntities.Count; i++) { RopeComponent ropeComponent = _entityManager.getComponent(levelUid, ropeEntities[i], ComponentType.Rope) as RopeComponent; RopeGrabComponent ropeGrabComponent = _entityManager.getComponent(levelUid, ropeEntities[i], ComponentType.RopeGrab) as RopeGrabComponent; RopeNode head = ropeComponent.ropeNodeHead; RopeNode current = head; RopeNode tail = head.tail; // Check segment length if (head.count < 3 && ropeGrabComponent == null) { ropeComponent.startTTLCountdown(); } // Check anchors if (head.anchorJoint == null && tail.anchorJoint == null) { ropeComponent.startTTLCountdown(); } // Check time to live if (ropeComponent.timeToLive == 0) { killRope(levelUid, ropeEntities[i]); ropeComponent.timeToLive--; } else if (ropeComponent.timeToLive > -1) { ropeComponent.timeToLive--; } while (current != null) { // Check tensions if (current.joint != null) { Vector2 relative; if (current == head || current == tail) { // Check anchor joint if (current.anchorJoint != null) { relative = current.anchorJoint.BodyA.GetWorldPoint(current.anchorJoint.LocalAnchorA) - current.anchorJoint.BodyB.GetWorldPoint(current.anchorJoint.LocalAnchorB); if (relative.Length() > 0.8f || current.anchorJoint.GetReactionForce(60f).Length() > 400f) { breakAnchor(current); } } } // Check other joints relative = current.joint.BodyA.GetWorldPoint(current.joint.LocalAnchorA) - current.joint.BodyB.GetWorldPoint(current.joint.LocalAnchorB); if (relative.Length() > 1.2f || current.joint.GetReactionForce(60f).Length() > 300f) { breakJoint(levelUid, ropeEntities[i], current); } } current = current.next; } } } } _singleStep = false; }
public void attemptRopeGrab(string levelUid, int characterId, CharacterMovementComponent characterMovementComponent, PhysicsComponent physicsComponent, RopeGrabComponent existingRopeGrabComponent) { float margin = 0.5f; AABB region = new AABB(); RopeNode ropeNode = null; int nodeCount = 0; region.LowerBound = physicsComponent.body.Position - new Vector2(margin, margin); region.UpperBound = physicsComponent.body.Position + new Vector2(margin, margin); if (physicsComponent == null) { return; } // Query the world for a body, and check to see if it's a rope physicsComponent.body.World.QueryAABB((fixture) => { int ropeEntityId = (int)fixture.Body.UserData; RopeComponent ropeComponent = (RopeComponent)_entityManager.getComponent(levelUid, ropeEntityId, ComponentType.Rope); RopeGrabComponent ropeGrabComponent = null; if (ropeComponent != null && !ropeComponent.doubleAnchor) { RopeNode current = ropeComponent.ropeNodeHead; characterMovementComponent.allowRopeGrab = false; while (current != null) { if (current.body == fixture.Body) { ropeNode = current; break; } nodeCount++; current = current.next; } if (existingRopeGrabComponent != null) { RopeComponent existingRopeComponent = (RopeComponent)_entityManager.getComponent(levelUid, existingRopeGrabComponent.ropeEntityId, ComponentType.Rope); if (existingRopeComponent.destroyAfterRelease) { existingRopeComponent.timeToLive = 100; } _ropeSystem.releaseRope(existingRopeGrabComponent, physicsComponent.body); _entityManager.removeComponent(levelUid, characterId, existingRopeGrabComponent); } ropeGrabComponent = new RopeGrabComponent(ropeEntityId, ropeNode, (float)nodeCount, ropeComponent.reverseClimbDirection); _ropeSystem.grabRope(ropeGrabComponent, physicsComponent.body); _entityManager.addComponent(levelUid, characterId, ropeGrabComponent); return(false); } return(true); }, ref region); }
public void update(GameTime gameTime) { if (!_paused || _singleStep) { LevelSystem levelSystem = _systemManager.getSystem(SystemType.Level) as LevelSystem; if (levelSystem.finalized) { string levelUid = LevelSystem.currentLevelUid; List <int> characterEntities = _entityManager.getEntitiesPosessing(levelUid, ComponentType.CharacterMovement); for (int i = 0; i < characterEntities.Count; i++) { PhysicsComponent physicsComponent = _entityManager.getComponent(levelUid, characterEntities[i], ComponentType.Physics) as PhysicsComponent; ParticleInfluenceComponent particleInfluenceComponent = _entityManager.getComponent(levelUid, characterEntities[i], ComponentType.ParticleInfluence) as ParticleInfluenceComponent; CharacterMovementComponent characterMovementComponent = _entityManager.getComponent(levelUid, characterEntities[i], ComponentType.CharacterMovement) as CharacterMovementComponent; RopeGrabComponent ropeGrabComponent = _entityManager.getComponent(levelUid, characterEntities[i], ComponentType.RopeGrab) as RopeGrabComponent; Body body = physicsComponent.body; float currentSpeed = body.LinearVelocity.Length(); // Handle fluid properties characterMovementComponent.inFluid = particleInfluenceComponent.particleCount > 2; // Handle rope grabs if (characterMovementComponent.allowRopeGrab && characterMovementComponent.doRopeGrab) { attemptRopeGrab(levelUid, characterEntities[i], characterMovementComponent, physicsComponent, ropeGrabComponent); } // Calculate movement vector if (characterMovementComponent.collisionNormals.Count > 0) { characterMovementComponent.movementUnitVector = Vector2.Zero; for (int j = 0; j < characterMovementComponent.collisionNormals.Count; j++) { characterMovementComponent.movementUnitVector += characterMovementComponent.collisionNormals[j] / characterMovementComponent.collisionNormals.Count; } characterMovementComponent.movementUnitVector = new Vector2(characterMovementComponent.movementUnitVector.Y, -characterMovementComponent.movementUnitVector.X); characterMovementComponent.movementUnitVector.Normalize(); } else { characterMovementComponent.movementUnitVector = new Vector2(-1, 0); } // On surface movement if (characterMovementComponent.onSurface) { if (characterMovementComponent.walkLeft || characterMovementComponent.walkRight) { // Adjust friction if (body.LinearVelocity.X < -0.1f && characterMovementComponent.walkRight) { body.Friction = 10f; } else if (body.LinearVelocity.X > 0.1f && characterMovementComponent.walkLeft) { body.Friction = 10f; } else { body.Friction = 0.1f; } // Walk if (currentSpeed <= characterMovementComponent.speedLimit) { Vector2 impulse = characterMovementComponent.movementUnitVector * _baseWalkMultiplier; if (characterMovementComponent.walkRight) { impulse *= -1; } if (characterMovementComponent.inFluid) { impulse *= 0.5f; } body.ApplyLinearImpulse(ref impulse); } } else { body.Friction = 10f; } } else // In-air movement { if (characterMovementComponent.walkLeft || characterMovementComponent.walkRight) { if (ropeGrabComponent != null) { // Swing Vector2 impulse = characterMovementComponent.movementUnitVector * _baseSwingMultiplier; if (characterMovementComponent.walkRight) { impulse *= -1; } body.ApplyLinearImpulse(ref impulse); } else { // Air walk if ((body.LinearVelocity.X < 0 && characterMovementComponent.walkRight) || (body.LinearVelocity.X > 0 && characterMovementComponent.walkLeft) || (body.LinearVelocity.X > -characterMovementComponent.speedLimit && characterMovementComponent.walkLeft) || (body.LinearVelocity.X < characterMovementComponent.speedLimit && characterMovementComponent.walkRight)) { Vector2 impulse = characterMovementComponent.movementUnitVector * _baseAirWalkMultiplier; if (characterMovementComponent.walkRight) { impulse *= -1; } body.ApplyLinearImpulse(ref impulse); } } } } // Jump if (characterMovementComponent.attemptJump) { // While holding rope if (ropeGrabComponent != null) { RopeComponent ropeComponent = _entityManager.getComponent(levelUid, ropeGrabComponent.ropeEntityId, ComponentType.Rope) as RopeComponent; Vector2 impulse = new Vector2(0, -1.2f); if (ropeComponent != null && ropeComponent.destroyAfterRelease) { ropeComponent.timeToLive = 100; } _ropeSystem.releaseRope(ropeGrabComponent, physicsComponent.body); _entityManager.removeComponent(levelUid, characterEntities[i], ropeGrabComponent); ropeGrabComponent = null; body.ApplyLinearImpulse(ref impulse); } if (characterMovementComponent.onSurface) { Vector2 impulse = new Vector2(0, -2f); float adjustment = 0f; // Try to limit the impulse based on the current y velocity. // This is done to prevent jumps from contributing too much to the y velocity when // the player is already moving upwards too fast (which results in a super-jump). adjustment = (body.LinearVelocity.Y / 6f); impulse.Y -= adjustment; body.ApplyLinearImpulse(ref impulse); characterMovementComponent.attemptJump = false; } } // Swim if (characterMovementComponent.inFluid && characterMovementComponent.swimUp) { Vector2 impulse = new Vector2(0, -0.25f); body.ApplyLinearImpulse(ref impulse); } // Climbing if (ropeGrabComponent != null) { float climbSpeed = characterMovementComponent.climbAmount * CLIMB_SPEED; if (characterMovementComponent.climbUp) { _ropeSystem.moveAttachedBody(ropeGrabComponent, physicsComponent.body, climbSpeed); } else if (characterMovementComponent.climbDown) { _ropeSystem.moveAttachedBody(ropeGrabComponent, physicsComponent.body, -climbSpeed); } } } } } _singleStep = false; }
// draw public void draw(GameTime gameTime) { string levelUid = LevelSystem.currentLevelUid; FluidSystem fluidSystem = (FluidSystem)_systemManager.getSystem(SystemType.Fluid); List <int> primitiveRenderEntities = _entityManager.getEntitiesPosessing(levelUid, ComponentType.PrimitivesRender); List <int> ropeEntities = _entityManager.getEntitiesPosessing(levelUid, ComponentType.Rope); List <int> characterRenderEntities = _entityManager.getEntitiesPosessing(levelUid, ComponentType.CharacterRender); List <int> characterMovementEntities = _entityManager.getEntitiesPosessing(levelUid, ComponentType.CharacterMovement); List <int> treeEntities = _entityManager.getEntitiesPosessing(levelUid, ComponentType.Tree); List <int> aimEntities = _entityManager.getEntitiesPosessing(levelUid, ComponentType.Aim); List <int> explosionEntities = _entityManager.getEntitiesPosessing(levelUid, ComponentType.Explosion); List <RopeGrabComponent> ropeGrabComponents = _entityManager.getComponents <RopeGrabComponent>(levelUid, ComponentType.RopeGrab); List <TooltipComponent> tooltipComponents = _entityManager.getComponents <TooltipComponent>(levelUid, ComponentType.Tooltip); Vector2 screenCenter = _cameraSystem.screenCenter; // Temporary debug draw if (LoderGame.debug) { Vector2 debugOffset = new Vector2(0f, 5f); _graphicsDevice.SetRenderTarget(_debugFluid); _graphicsDevice.Clear(Color.Black); _spriteBatch.Begin(); // Cells foreach (KeyValuePair <int, Dictionary <int, List <int> > > row1Pair in fluidSystem.fluidGrid) { foreach (KeyValuePair <int, List <int> > row2Pair in row1Pair.Value) { int gridSize = (int)(FluidSystem.CELL_SPACING * scale) - 1; Vector2 position = new Vector2((float)row1Pair.Key * FluidSystem.CELL_SPACING, (float)row2Pair.Key * FluidSystem.CELL_SPACING); _spriteBatch.Draw(_pixel, (position - debugOffset) * scale + _halfScreen, new Rectangle(0, 0, gridSize, gridSize), Color.DarkBlue, 0f, Vector2.Zero, 1f, SpriteEffects.None, 0f); } } // Particle pressures for (int i = 0; i < FluidSystem.MAX_PARTICLES; i++) { Particle particle = fluidSystem.liquid[i]; _spriteBatch.Draw(_pixel, (particle.position - debugOffset) * scale + _halfScreen, new Rectangle(0, 0, 16, 16), Color.Red * 0.5f, 0f, new Vector2(8, 8), Math.Abs(particle.pressure) / FluidSystem.MAX_PRESSURE, SpriteEffects.None, 0f); } // Particle near pressures for (int i = 0; i < FluidSystem.MAX_PARTICLES; i++) { Particle particle = fluidSystem.liquid[i]; _spriteBatch.Draw(_pixel, (particle.position - debugOffset) * scale + _halfScreen, new Rectangle(0, 0, 16, 16), Color.Orange * 0.5f, 0f, new Vector2(8, 8), Math.Abs(particle.pressureNear) / FluidSystem.MAX_PRESSURE_NEAR, SpriteEffects.None, 0f); } // Particle positions for (int i = 0; i < FluidSystem.MAX_PARTICLES; i++) { Particle particle = fluidSystem.liquid[i]; Color color = particle.active ? Color.White : Color.DarkGray; _spriteBatch.Draw(_pixel, (particle.position - debugOffset) * scale + _halfScreen, new Rectangle(0, 0, 4, 4), color, 0, new Vector2(2, 2), 1, SpriteEffects.None, 0); } // Simulation AABB Vector2[] vertices = new Vector2[4]; vertices[0] = fluidSystem.simulationAABB.LowerBound; vertices[1] = new Vector2(fluidSystem.simulationAABB.UpperBound.X, fluidSystem.simulationAABB.LowerBound.Y); vertices[2] = fluidSystem.simulationAABB.UpperBound; vertices[3] = new Vector2(fluidSystem.simulationAABB.LowerBound.X, fluidSystem.simulationAABB.UpperBound.Y); for (int i = 0; i < 4; i++) { Vector2 a = vertices[i]; Vector2 b = vertices[i == 3 ? 0 : i + 1]; Vector2 relative = b - a; float angle = (float)Math.Atan2(relative.Y, relative.X); Rectangle rect = new Rectangle(0, 0, (int)(relative.Length() * scale), 2); _spriteBatch.Draw(_pixel, (a - debugOffset) * scale + _halfScreen, rect, Color.Lime, angle, new Vector2(0, 1), 1f, SpriteEffects.None, 0); } _spriteBatch.End(); _graphicsDevice.SetRenderTarget(null); } // Begin drawing a source for post effects under the player's level _graphicsDevice.SetRenderTarget(_postSourceUnder); _graphicsDevice.Clear(Color.Black); // Draw background if (_backgroundRenderer.background != null) { _spriteBatch.Begin(SpriteSortMode.BackToFront, BlendState.AlphaBlend); _backgroundRenderer.drawFirstHalf(); _spriteBatch.End(); } // Begin ordered drawing _spriteBatch.Begin(SpriteSortMode.BackToFront, BlendState.AlphaBlend); _halfScreen = new Vector2(_graphicsDevice.Viewport.Width, _graphicsDevice.Viewport.Height) / 2; _viewMatrix = Matrix.CreateTranslation(new Vector3(-screenCenter, 0)) * Matrix.CreateScale(new Vector3(_scale, -_scale, 1f)); _projectionMatrix = Matrix.CreateOrthographic(_graphicsDevice.Viewport.Width, _graphicsDevice.Viewport.Height, 0, 1); _primitivesEffect.Parameters["view"].SetValue(_viewMatrix); _primitivesEffect.Parameters["projection"].SetValue(_projectionMatrix); // Primitive rendering for (int i = 0; i < primitiveRenderEntities.Count; i++) { int entityId = primitiveRenderEntities[i]; PrimitivesRenderComponent primitiveRenderComponent = (PrimitivesRenderComponent)_entityManager.getComponent(levelUid, entityId, ComponentType.PrimitivesRender); for (int j = 0; j < primitiveRenderComponent.primitiveRenderObjects.Count; j++) { PrimitiveRenderObject primitiveRenderObject = primitiveRenderComponent.primitiveRenderObjects[j]; PhysicsComponent physicsComponent = (PhysicsComponent)_entityManager.getComponent(levelUid, entityId, ComponentType.Physics); IComponent component; // Update world matrix if (physicsComponent != null) { primitiveRenderObject.worldMatrix = primitiveRenderObject.originMatrix * Matrix.CreateRotationZ(physicsComponent.body.Rotation) * Matrix.CreateTranslation(new Vector3(physicsComponent.body.Position, 0)); } else if (_entityManager.tryGetComponent(levelUid, entityId, ComponentType.FollowMetamer, out component)) { FollowMetamerComponent followMetamerComponent = component as FollowMetamerComponent; primitiveRenderObject.worldMatrix = primitiveRenderObject.originMatrix * Matrix.CreateRotationZ(followMetamerComponent.metamer.currentAngle + StasisMathHelper.halfPi) * Matrix.CreateTranslation(new Vector3(followMetamerComponent.metamer.position, 0)); } // Update vertices primitiveRenderObject.updateVertices(); addRenderablePrimitive(primitiveRenderObject); } } // Rope rendering for (int i = 0; i < ropeEntities.Count; i++) { int entityId = ropeEntities[i]; RopeComponent ropeComponent = _entityManager.getComponent(levelUid, entityId, ComponentType.Rope) as RopeComponent; RopeNode current = ropeComponent.ropeNodeHead; RopeNode head = current; RopeNode tail = head.tail; Vector2 position; float muIncrement = 1f / (float)ropeComponent.interpolationCount; while (current != null) { float mu = 0f; for (int j = 0; j < ropeComponent.interpolationCount; j++) { Texture2D texture = current.ropeNodeTextures[j].texture; Vector2 a; Vector2 b = current.body.GetWorldPoint(new Vector2(current.halfLength, 0)); Vector2 c = current.body.GetWorldPoint(new Vector2(-current.halfLength, 0)); Vector2 d; // Determine a's position if (current.previous == null) { a = b + (b - c); } else { a = current.previous.body.GetWorldPoint(new Vector2(current.halfLength, 0)); } // Determine d's position if (current.next == null) { d = c + (c - b); } else { d = current.next.body.GetWorldPoint(new Vector2(-current.halfLength, 0)); } StasisMathHelper.interpolate(ref a, ref b, ref c, ref d, mu, out position); _spriteBatch.Draw(texture, (position - screenCenter) * _scale + _halfScreen, texture.Bounds, Color.White, current.body.Rotation + current.ropeNodeTextures[j].angleOffset, current.ropeNodeTextures[j].center, 1f, SpriteEffects.None, 0.1f); mu += muIncrement; } current = current.next; } } // Character rendering for (int i = 0; i < characterRenderEntities.Count; i++) { PhysicsComponent physicsComponent = (PhysicsComponent)_entityManager.getComponent(levelUid, characterRenderEntities[i], ComponentType.Physics); CharacterRenderComponent characterRenderComponent = _entityManager.getComponent(levelUid, characterRenderEntities[i], ComponentType.CharacterRender) as CharacterRenderComponent; Vector2 offset; Texture2D texture = _animationManager.getTexture(characterRenderComponent.character, characterRenderComponent.animation, characterRenderComponent.currentFrame, out offset); _spriteBatch.Draw(texture, (physicsComponent.body.Position - screenCenter) * _scale + _halfScreen, texture.Bounds, Color.White, 0, offset, 1f, SpriteEffects.None, 0.05f); } /* * for (int i = 0; i < characterMovementEntities.Count; i++) * { * PhysicsComponent physicsComponent = (PhysicsComponent)_entityManager.getComponent(levelUid, characterMovementEntities[i], ComponentType.Physics); * CharacterMovementComponent characterMovementComponent = (CharacterMovementComponent)_entityManager.getComponent(levelUid, characterMovementEntities[i], ComponentType.CharacterMovement); * Vector2 movementUnitVector = characterMovementComponent.movementUnitVector; * Rectangle source = new Rectangle(0, 0, (int)(movementUnitVector.Length() * _scale), 2); * float angle = (float)Math.Atan2(movementUnitVector.Y, movementUnitVector.X); * * _spriteBatch.Draw(_pixel, (physicsComponent.body.Position - screenCenter) * _scale + _halfScreen, source, Color.Yellow, angle, new Vector2(0, 1), 1f, SpriteEffects.None, 0); * }*/ // Tree _primitivesEffect.Parameters["world"].SetValue(Matrix.Identity); for (int i = 0; i < treeEntities.Count; i++) { TreeComponent treeComponent = _entityManager.getComponent(levelUid, treeEntities[i], ComponentType.Tree) as TreeComponent; if (treeComponent.tree.active) { addRenderablePrimitive(treeComponent.tree); treeComponent.tree.rootMetamer.draw(this); } } drawRenderablePrimitives(); // Rope grab components (TEMPORARY) for (int i = 0; i < ropeGrabComponents.Count; i++) { foreach (KeyValuePair <Body, RevoluteJoint> pair in ropeGrabComponents[i].joints) { Vector2 pointA = pair.Value.BodyA.Position; Vector2 pointB = pair.Value.BodyB.Position; Vector2 relative = pointB - pointA; float angle = (float)Math.Atan2(relative.Y, relative.X); _spriteBatch.Draw(_pixel, (pointA - screenCenter) * _scale + _halfScreen, new Rectangle(0, 0, (int)(relative.Length() * _scale), 2), Color.Green, angle, new Vector2(0, 1), 1f, SpriteEffects.None, 0f); } } // Draw explosions (TEMPORARY) for (int i = 0; i < explosionEntities.Count; i++) { ExplosionComponent explosionComponent = (ExplosionComponent)_entityManager.getComponent(levelUid, explosionEntities[i], ComponentType.Explosion); _spriteBatch.Draw(_circle, (explosionComponent.position - screenCenter) * _scale + _halfScreen, _circle.Bounds, Color.Red, 0f, new Vector2(_circle.Width, _circle.Height) / 2f, ((explosionComponent.radius * _scale) / (_circle.Width / 2f)), SpriteEffects.None, 0f); } // Aim components for (int i = 0; i < aimEntities.Count; i++) { AimComponent aimComponent = (AimComponent)_entityManager.getComponent(levelUid, aimEntities[i], ComponentType.Aim); Vector2 worldPosition = (_entityManager.getComponent(levelUid, aimEntities[i], ComponentType.WorldPosition) as WorldPositionComponent).position; float length = aimComponent.length; _spriteBatch.Draw(_reticle, (worldPosition - screenCenter + new Vector2((float)Math.Cos(aimComponent.angle), (float)Math.Sin(aimComponent.angle)) * length) * _scale + _halfScreen, _reticle.Bounds, Color.Red, aimComponent.angle, new Vector2(_reticle.Width, _reticle.Height) / 2f, 1f, SpriteEffects.None, 0f); } _spriteBatch.End(); // Begin drawing source for post effects over the player's layer _graphicsDevice.SetRenderTarget(_postSourceOver); _graphicsDevice.Clear(Color.Transparent); _spriteBatch.Begin(SpriteSortMode.BackToFront, BlendState.AlphaBlend); // Draw background's second half if (_backgroundRenderer.background != null) { _backgroundRenderer.drawSecondHalf(); } // Draw tooltips for (int i = 0; i < tooltipComponents.Count; i++) { TooltipComponent tooltip = tooltipComponents[i]; if (tooltip.draw) { Vector2 tooltipPosition = (tooltip.position - screenCenter) * _scale + _halfScreen - new Vector2(0, 50f); _spriteBatch.DrawString(_tooltipFont, tooltip.message, tooltipPosition + new Vector2(2, 2), Color.Black, 0f, Vector2.Zero, 1f, SpriteEffects.None, 0.0001f); _spriteBatch.DrawString(_tooltipFont, tooltip.message, tooltipPosition, Color.White, 0f, Vector2.Zero, 1f, SpriteEffects.None, 0f); tooltip.draw = false; } } _spriteBatch.End(); _graphicsDevice.SetRenderTarget(null); _graphicsDevice.Clear(Color.Transparent); // Render fluid _graphicsDevice.SetRenderTarget(_fluidRenderTarget); _graphicsDevice.Clear(Color.Transparent); spriteBatch.Begin(); int limit = fluidSystem.numActiveParticles; for (int i = 0; i < limit; i++) { // Current particle Particle particle = fluidSystem.liquid[fluidSystem.activeParticles[i]]; Color color = new Color(1, particle.velocity.X < 0 ? -particle.velocity.X : particle.velocity.X, particle.velocity.Y < 0 ? -particle.velocity.Y : particle.velocity.Y); spriteBatch.Draw(_fluidParticleTexture, (particle.position - _cameraSystem.screenCenter) * scale + _halfScreen, _fluidParticleTexture.Bounds, color, 0, new Vector2(16, 16), 1, SpriteEffects.None, 0); } spriteBatch.End(); _graphicsDevice.SetRenderTarget(_renderedFluid); _graphicsDevice.Clear(Color.Transparent); // Draw post-processed render target to screen _graphicsDevice.Textures[1] = _postSourceUnder; _fluidEffect.Parameters["renderSize"].SetValue(new Vector2(_renderedFluid.Width, _renderedFluid.Height)); spriteBatch.Begin(SpriteSortMode.Immediate, BlendState.AlphaBlend, SamplerState.LinearClamp, null, null, _fluidEffect); spriteBatch.Draw(_fluidRenderTarget, Vector2.Zero, Color.DarkBlue); spriteBatch.End(); _graphicsDevice.SetRenderTarget(null); // Draw post source under and over _spriteBatch.Begin(); _spriteBatch.Draw(_postSourceUnder, _postSourceUnder.Bounds, Color.White); _spriteBatch.End(); // Draw fluid if (fluidSystem != null) { _spriteBatch.Begin(); _spriteBatch.Draw(_renderedFluid, _renderedFluid.Bounds, Color.White); _spriteBatch.End(); } _spriteBatch.Begin(SpriteSortMode.Immediate, BlendState.AlphaBlend); _spriteBatch.Draw(_postSourceOver, _postSourceOver.Bounds, Color.White); _spriteBatch.End(); // Particle debug if (LoderGame.debug) { _spriteBatch.Begin(); _spriteBatch.Draw(_debugFluid, Vector2.Zero, _debugFluid.Bounds, Color.White, 0f, Vector2.Zero, _enlargeDebugFuild ? 1f : 0.25f, SpriteEffects.None, 0f); _spriteBatch.End(); /* * _spriteBatch.Begin(); * int limit = fluidSystem.numActiveParticles; * for (int i = 0; i < limit; i++) * { * // Current particle * Particle particle = fluidSystem.liquid[fluidSystem.activeParticles[i]]; * spriteBatch.Draw(_pixel, (particle.position - _cameraSystem.screenCenter) * scale + _halfScreen, new Rectangle(0, 0, 2, 2), Color.White, 0, new Vector2(1, 1), 1, SpriteEffects.None, 0); * } * _spriteBatch.End(); */ } // AI Wander Behavior debug if (LoderGame.debug) { AIBehaviorSystem aiBehaviorSystem = _systemManager.getSystem(SystemType.AIBehavior) as AIBehaviorSystem; List <int> wanderBehaviorEntities = _entityManager.getEntitiesPosessing(levelUid, ComponentType.AIWanderBehavior); for (int i = 0; i < wanderBehaviorEntities.Count; i++) { AIWanderBehaviorComponent wanderComponent = _entityManager.getComponent(levelUid, wanderBehaviorEntities[i], ComponentType.AIWanderBehavior) as AIWanderBehaviorComponent; List <WaypointsComponent> waypointsComponents = _entityManager.getComponents <WaypointsComponent>(levelUid, ComponentType.Waypoints); if (waypointsComponents.Count > 0) { WaypointsComponent waypointsComponent = aiBehaviorSystem.getWaypointsComponent(wanderComponent.waypointsUid, waypointsComponents); Vector2 waypointPosition = waypointsComponent.waypoints[wanderComponent.currentWaypointIndex]; _spriteBatch.Begin(); _spriteBatch.Draw(_circle, (waypointPosition - screenCenter) * _scale + _halfScreen, _circle.Bounds, Color.Red, 0f, new Vector2(_circle.Width, _circle.Height) / 2f, 0.02f, SpriteEffects.None, 0f); _spriteBatch.End(); } } } }