/// <summary> /// Update method /// </summary> /// <param name="gameTime"></param> protected override void Update(TimeSpan gameTime) { touchPanelState = WaveServices.Input.TouchPanelState; bestValue = float.MaxValue; if (touchPanelState.IsConnected && touchPanelState.Count > 0) { // Calculate the ray CalculateRay(); // Look for all entities in the game... for (int i = 0; i < EntityManager.Count; i++) { currentEntity = EntityManager.EntityGraph.ElementAt(i);; entityCollider = currentEntity.FindComponent <BoxCollider3D>(); // ... but only a collidable entities ( entities which have a boxCollider component) if (entityCollider != null) { // Intersect our calculated ray with the entity's boxCollider collisionResult = entityCollider.Intersects(ref ray); // If any collision if (collisionResult.HasValue) { // Check the distance. We want to have the closer to the screen entity, so we want to get the low collisionResult value if (collisionResult.Value < bestValue) { // Send to the scene the new entity picked name if (this.myScene != null) { this.myScene.ShowPickedEntity(currentEntity.Name); } bestValue = collisionResult.Value; } } } } } else { if (this.myScene != null) { this.myScene.ShowPickedEntity("None"); } } }
private void SelectPickedEntity() { // Creates Ray from Mouse 2d position this.nearPosition.X = this.mousePosition.X; this.nearPosition.Y = this.mousePosition.Y; this.nearPosition.Z = 0.0f; this.farPosition.X = this.mousePosition.X; this.farPosition.Y = this.mousePosition.Y; this.farPosition.Z = 1.0f; // Unproject Mouse Position this.nearPosition = this.camera.Unproject(ref this.nearPosition); this.farPosition = this.camera.Unproject(ref this.farPosition); // Update ray. Ray launched from nearPosition in rayDirection direction. this.rayDirection = this.farPosition - this.nearPosition; this.rayDirection.Normalize(); this.ray.Direction = this.rayDirection; this.ray.Position = this.nearPosition; foreach (Entity entity in this.Owner.Scene.EntityManager.EntityGraph) { // It takes Box Shaped Physic Entities this.entityBoxCollider = entity.FindComponent <BoxCollider3D>(); if (this.entityBoxCollider != null) { this.collisionResult = this.entityBoxCollider.Intersects(ref ray); if (this.collisionResult.HasValue) { if (this.collisionResult.Value < this.distance) { this.distance = this.collisionResult.Value; this.selectedEntity = entity; } } } } }
private void Ray(Camera3D activeCamera, TouchLocation touchLocation) { // Creates Ray from Touch 2D position _nearPosition.X = touchLocation.Position.X; _nearPosition.Y = touchLocation.Position.Y; _nearPosition.Z = 0.0f; _farPosition.X = touchLocation.Position.X; _farPosition.Y = touchLocation.Position.Y; _farPosition.Z = 1.0f; // Unproject Mouse Position _nearPosition = activeCamera.Unproject(ref _nearPosition); _farPosition = activeCamera.Unproject(ref _farPosition); // Update ray. Ray launched from nearPosition in rayDirection direction. _rayDirection = _farPosition - _nearPosition; _rayDirection.Normalize(); _ray.Direction = _rayDirection; _ray.Position = _nearPosition; foreach (Entity entity in this.Owner.Scene.EntityManager.FindAllByTag("touchable")) { _entityBoxCollider = entity.FindComponent <BoxCollider3D>(); if (_entityBoxCollider != null) { _materialComponent = entity.FindComponent <MaterialComponent>(); _collisionResult = _entityBoxCollider.Intersects(ref _ray); if (_collisionResult.HasValue) { PushpinTapped?.Invoke(this, new PushpinTappedEventArgs(entity.Name)); } } } }
/// <summary> /// Updates the specified game time. /// </summary> /// <param name="gameTime">The game time.</param> protected override void Update(TimeSpan gameTime) { float elapsed = (float)gameTime.TotalSeconds; Vector3 position = this.playerTransform.Position; this.ray.Position = position; // Initialization if (!initialized) { this.InitializeAttributes(); this.initialized = true; } // Check Collision var collidables = this.blockPositions.Where( b => b.ZPosition > this.playerTransform.Position.Z - 1 && b.ZPosition < this.playerTransform.Position.Z + 1); foreach (var blockPathPosition in collidables) { var collidableEntity = this.EntityManager.Find(blockPathPosition.Path); var blockCollider = collidableEntity.FindComponent <BoxCollider3D>().BoundingBox; var collisionType = this.CheckCollisionType(this.playerTransform.Position, 0.45f, blockCollider, collidableEntity.Tag); if (collisionType == CollisionType.KILLER) { position = this.initialPosition; this.state = PlayerState.GROUND; break; } else if (collisionType == CollisionType.GROUND) { this.currentVerticalVelocity = 0; position.Y = (int)Math.Round(position.Y); this.state = PlayerState.GROUND; } } // Check Ground var under = this.blockPositions.Where(b => b.ZPosition == (float)Math.Round(this.playerTransform.Position.Z)); BoxCollider3D nearestBoxCollider = null; float minDistance = float.MaxValue; foreach (var blockPathPosition in under) { var collidableEntity = this.EntityManager.Find(blockPathPosition.Path); var blockCollider = collidableEntity.FindComponent <BoxCollider3D>(); var groundDistance = blockCollider.BoundingBox.Intersects(ref this.ray); if (groundDistance.HasValue) { if (groundDistance.Value < minDistance) { minDistance = groundDistance.Value; nearestBoxCollider = blockCollider; } } } if (nearestBoxCollider != null) { if (minDistance <= 0.5f) { this.state = PlayerState.GROUND; } else { this.state = PlayerState.FALLING; } } else { this.state = PlayerState.FALLING; } // Check state switch (this.state) { case PlayerState.GROUND: // Check the game keys this.currentVerticalVelocity = 0; if (WaveServices.Input.KeyboardState.Up == ButtonState.Pressed || WaveServices.Input.KeyboardState.Space == ButtonState.Pressed || WaveServices.Input.TouchPanelState.Count > 0) { this.currentVerticalVelocity = this.JumpSpeed; this.state = PlayerState.JUMPING; break; } break; // playing is jumping, ascending!! case PlayerState.JUMPING: this.currentVerticalVelocity -= this.Gravity * elapsed; break; // player falls down, after a jump of running over an empty block (then should fall anyway) case PlayerState.FALLING: this.currentVerticalVelocity -= this.Gravity * elapsed; // Dead level if (position.Y <= -7.0f) { position = this.initialPosition; this.state = PlayerState.GROUND; } break; } // Move Forward and spin (speed relative) var horizontalstep = this.PlayerVelocity * elapsed; this.spinner.IncreaseX = this.PlayerVelocity; position.Z += horizontalstep; position.Y += this.currentVerticalVelocity * elapsed; this.playerTransform.Position = position; }
private AxisManipulationHelper CreateHandle(AxisManipulationHelperType amhType, AxisType axisType, Prefab prefab, Material idleMaterial, Material grabbedMaterial, Material focusedMaterial, Quaternion orientation, AxisManipulationHelper[] relatedHandlers) { // Entity name suffix var suffix = $"{amhType}_{axisType}"; // Handle root var handle = new Entity($"handle_{suffix}") .AddComponent(new Transform3D() { LocalScale = Vector3.One * this.HandleScale, }); this.rigRootEntity.AddChild(handle); if (prefab != null) { // Instantiate prefab var prefabInstance = prefab.Instantiate(); var prefabTransform = prefabInstance.FindComponent <Transform3D>(); prefabTransform.LocalOrientation = orientation; handle.AddChild(prefabInstance); } else { // Generate default look for the handle Vector3 position = Vector3.Zero; Vector3 size = Vector3.One; Component mesh = null; Component collider = null; switch (amhType) { case AxisManipulationHelperType.Center: var sphereDiameter = 1f; mesh = new SphereMesh() { Diameter = sphereDiameter, }; collider = new SphereCollider3D() { Margin = 0.0001f, Radius = sphereDiameter, }; break; case AxisManipulationHelperType.Axis: var axisLength = 4f; var axisThickness = 0.5f; size = new Vector3(axisLength, axisThickness, axisThickness); mesh = new CubeMesh(); collider = new BoxCollider3D() { Margin = 0.0001f, Size = size + Vector3.One, Offset = Vector3.UnitX, }; position = 0.5f * Vector3.UnitX * (axisLength + 2f); break; case AxisManipulationHelperType.Plane: var planeLength = 2f; var planeThickness = 0.25f; size = new Vector3(planeLength, planeThickness, planeLength); mesh = new CubeMesh(); collider = new BoxCollider3D() { Margin = 0.0001f, Size = size + Vector3.One, Offset = Vector3.UnitX + Vector3.UnitZ, }; position = 0.5f * Vector3.Normalize(Vector3.UnitX + Vector3.UnitZ) * (planeLength + 2f); break; } // Collider entity var handleCollider = new Entity($"collider_{suffix}") .AddComponent(new Transform3D() { LocalPosition = Vector3.Transform(position, orientation), LocalOrientation = orientation, }) .AddComponent(collider) .AddComponent(new StaticBody3D() { CollisionCategories = this.CollisionCategory, IsSensor = true, }) .AddComponent(new NearInteractionGrabbable()); // Visual entity var handleVisual = new Entity($"visuals_{suffix}") .AddComponent(new Transform3D() { LocalScale = size, }) .AddComponent(mesh) .AddComponent(new MeshRenderer()) .AddComponent(new MaterialComponent()); // Build hierarchy handle.AddChild(handleCollider); handleCollider.AddChild(handleVisual); } // Apply material var materialComponents = handle.FindComponentsInChildren <MaterialComponent>().ToArray(); this.ApplyMaterialToAllComponents(materialComponents, idleMaterial); // Register helper object var helperTargetEntity = handle.FindComponentInChildren <NearInteractionGrabbable>()?.Owner; if (helperTargetEntity == null) { throw new Exception($"The handle entity needs to have a {nameof(NearInteractionGrabbable)} component."); } var handleHelper = new AxisManipulationHelper() { Type = amhType, AxisType = axisType, BaseEntity = handle, MaterialComponents = materialComponents, IdleMaterial = idleMaterial, GrabbedMaterial = grabbedMaterial, FocusedMaterial = focusedMaterial, RelatedHandles = relatedHandlers, }; this.helpers.Add(helperTargetEntity, handleHelper); return(handleHelper); }
protected override void Update(TimeSpan gameTime) { touchPanelState = WaveServices.Input.TouchPanelState; if (touchPanelState.IsConnected && touchPanelState.Count > 0) { // Calculate the ray CalculateRay(); // Look for all entities in the game... Entity auxEntity = currentEntity = null; bestValue = float.MaxValue; for (int i = 0; i < EntityManager.Count; i++) { auxEntity = EntityManager.EntityGraph.ElementAt(i); entityCollider = auxEntity.FindComponent<BoxCollider3D>(); // ... but only a collidable entities ( entities which have a boxCollider component) if (entityCollider != null && ( auxEntity.Name.Contains("box") || auxEntity.Name.Contains("anchor") || auxEntity.Name.Contains("BigBall")) ) { // Intersect our calculated ray with the entity's boxCollider collisionResult = entityCollider.Intersects(ref ray); // If any collision if (collisionResult.HasValue && collisionResult.Value > 0.001f) { //Labels.Add("CollisionResult", collisionResult.ToString()); //Labels.Add("CollisionValue", collisionResult.Value.ToString()); // Check the distance. We want to have the closer to the screen entity, so we want to get the low collisionResult value if (collisionResult.Value < bestValue) { this.currentEntity = auxEntity; bestValue = collisionResult.Value; } } } } if (this.currentEntity != null) { Vector3 entityPosition = this.currentEntity.FindComponent<Transform3D>().Position; Vector3 impulse = entityPosition - this.Camera.Position; this.currentEntity.FindComponent<RigidBody3D>().ApplyLinearImpulse(impulse*FORCE); this.line.StartPoint = ray.Position; this.line.EndPoint = entityPosition; Labels.Add("Entity", this.currentEntity.Name); //Labels.Add("Impulse", impulse.ToString()); //Labels.Add("IsActive", this.currentEntity.FindComponent<RigidBody3D>().IsActive.ToString()); } else { Labels.Add("Entity", "None"); //Labels.Add("Impulse", "0,0,0"); } } //RenderManager.LineBatch3D.DrawLine(ref line); //RenderManager.LineBatch3D.DrawLine(ref line2); }
protected override void Update(TimeSpan gameTime) { touchPanelState = WaveServices.Input.TouchPanelState; bestValue = float.MaxValue; if (touchPanelState.IsConnected && touchPanelState.Count > 0) { // Calculate the ray CalculateRay(); // Look for all entities in the game... for (int i = 0; i < EntityManager.Count; i++) { currentEntity = EntityManager.EntityGraph.ElementAt(i); ; entityCollider = currentEntity.FindComponent<BoxCollider3D>(); // ... but only a collidable entities ( entities which have a boxCollider component) if (entityCollider != null) { // Intersect our calculated ray with the entity's boxCollider collisionResult = entityCollider.Intersects(ref ray); // If any collision if (collisionResult.HasValue) { // Check the distance. We want to have the closer to the screen entity, so we want to get the low collisionResult value if (collisionResult.Value < bestValue) { // Send to the scene the new entity picked name (WaveServices.ScreenContextManager.CurrentContext[0] as MyScene).ShowPickedEntity(currentEntity.Name); bestValue = collisionResult.Value; } } } } } else { (WaveServices.ScreenContextManager.CurrentContext[0] as MyScene).ShowPickedEntity("None"); } }
private void SelectPickedEntity() { // Creates Ray from Mouse 2d position this.nearPosition.X = this.mousePosition.X; this.nearPosition.Y = this.mousePosition.Y; this.nearPosition.Z = 0.0f; this.farPosition.X = this.mousePosition.X; this.farPosition.Y = this.mousePosition.Y; this.farPosition.Z = 1.0f; // Unproject Mouse Position this.nearPosition = this.camera.Unproject(ref this.nearPosition); this.farPosition = this.camera.Unproject(ref this.farPosition); // Update ray. Ray launched from nearPosition in rayDirection direction. this.rayDirection = this.farPosition - this.nearPosition; this.rayDirection.Normalize(); this.ray.Direction = this.rayDirection; this.ray.Position = this.nearPosition; foreach (Entity entity in this.Owner.Scene.EntityManager.EntityGraph) { // It takes Box Shaped Physic Entities this.entityBoxCollider = entity.FindComponent<BoxCollider3D>(); if (this.entityBoxCollider != null) { this.collisionResult = this.entityBoxCollider.Intersects(ref ray); if (this.collisionResult.HasValue) { if (this.collisionResult.Value < this.distance) { this.distance = this.collisionResult.Value; this.selectedEntity = entity; } } } } }
protected override void Update(TimeSpan gameTime) { touchPanelState = WaveServices.Input.TouchPanelState; if (touchPanelState.IsConnected && touchPanelState.Count > 0) { // Calculate the ray CalculateRay(); // Look for all entities in the game... Entity auxEntity = currentEntity = null; bestValue = float.MaxValue; for (int i = 0; i < EntityManager.Count; i++) { auxEntity = EntityManager.EntityGraph.ElementAt(i); entityCollider = auxEntity.FindComponent <BoxCollider3D>(); // ... but only a collidable entities ( entities which have a boxCollider component) if (entityCollider != null && (auxEntity.Name.Contains("box") || auxEntity.Name.Contains("anchor") || auxEntity.Name.Contains("BigBall"))) { // Intersect our calculated ray with the entity's boxCollider collisionResult = entityCollider.Intersects(ref ray); // If any collision if (collisionResult.HasValue && collisionResult.Value > 0.001f) { //Labels.Add("CollisionResult", collisionResult.ToString()); //Labels.Add("CollisionValue", collisionResult.Value.ToString()); // Check the distance. We want to have the closer to the screen entity, so we want to get the low collisionResult value if (collisionResult.Value < bestValue) { this.currentEntity = auxEntity; bestValue = collisionResult.Value; } } } } if (this.currentEntity != null) { Vector3 entityPosition = this.currentEntity.FindComponent <Transform3D>().Position; Vector3 impulse = entityPosition - this.Camera.Position; this.currentEntity.FindComponent <RigidBody3D>().ApplyLinearImpulse(impulse * FORCE); this.line.StartPoint = ray.Position; this.line.EndPoint = entityPosition; Labels.Add("Entity", this.currentEntity.Name); //Labels.Add("Impulse", impulse.ToString()); //Labels.Add("IsActive", this.currentEntity.FindComponent<RigidBody3D>().IsActive.ToString()); } else { Labels.Add("Entity", "None"); //Labels.Add("Impulse", "0,0,0"); } } //RenderManager.LineBatch3D.DrawLine(ref line); //RenderManager.LineBatch3D.DrawLine(ref line2); }
/// <summary> /// Allows this instance to execute custom logic during its /// <c>Update</c>. /// </summary> /// <param name="gameTime">The game time.</param> /// <remarks> /// This method will not be executed if it are not /// <c>Active</c>. /// </remarks> protected override void Update(TimeSpan gameTime) { if (!this.initialized) { this.modelFactoryService = ModelFactoryService.Instance; this.playScene = this.Owner.Scene as MyScene; this.player = this.EntityManager.Find(this.PlayerSource); this.playerTransform = this.player.FindComponent<Transform3D>(); this.playerCollider = this.player.FindComponent<BoxCollider3D>(); this.playerBehavior = this.player.FindComponent<PlayerBehavior>(); this.tempBoundingBox = new BoundingBox(); this.initialized = true; } // Game Tri-state machine switch (GameState) { // Initial level state case GameState.INIT: // Loads the level // it can be done in everywhere we want, in scene too, but then we need to call a Reset method or similar this.LevelModel = ImportService.Instance.ImportLevel(WaveContent.Assets.Levels.level1A_level); // Restart Camera, Player states and positions this.player.FindComponent<PlayerBehavior>().Restart(); // put player over the first ground block // FIRST BLOCK OF LEVEL SHOULD BE A GROUND, logically this.playerTransform.Position = new Vector3(0f, this.modelFactoryService.Scale.Y, 0.0f); // fills the intiial Buffer, we need to load some elements prior playing float currentZ = 0; for (int i = 0; i < BlockBufferSize; i++) { // Create Column this.CreateNextColumnEntity(currentZ); currentZ += this.modelFactoryService.Scale.Z; } GameState = GameState.PLAY; break; // Playing State of game: case GameState.PLAY: // new player position, using acceleration, falling, etc... where applicable //// this.UpdatePlayerPosition(elapsedGameTime); // Check if dead by level platform falling down if (this.playerTransform.Position.Y <= UnderDeadLevel) { this.GameState = Enums.GameState.DIE; break; } // Selects the current and next column, selects the columns to free too. // the current column and next column are used to check collisions, only with those two columns, others are ignored for (int i = 0; i < this.ColumnCollection.Count - 1; i++) { Entity column = this.ColumnCollection[i]; var columnTransform = column.FindComponent<Transform3D>(); // Remove passedby columns by distance if (columnTransform.Position.Z < this.playerTransform.Position.Z - PasseByBlocksToDiscardColumn * this.modelFactoryService.Scale.Z) { ////// removes column this.modelFactoryService.FreeColumn(column); this.ColumnCollection.RemoveAt(i); ////// Create new column at the end this.CreateNextColumnEntity(columnTransform.Position.Z + BlockBufferSize * this.modelFactoryService.Scale.Z); } // check if player is over this column and sets current and next column else if (this.playerTransform.Position.Z < columnTransform.Position.Z + this.modelFactoryService.Scale.Z && this.playerTransform.Position.Z >= columnTransform.Position.Z) { this.CurrentColumn = column; this.NextColumn = this.ColumnCollection[i + 1]; // update the ground level for current and next columns this.CheckGroundPosition(); break; } } // if there are a current column checks the collision in current and next column if (this.CurrentColumn != null && !this.CurrentColumn.IsDisposed && this.NextColumn!=null && !this.NextColumn.IsDisposed) { // creates the union of each column entities List<Entity> collidableCollection = this.CurrentColumn.ChildEntities.ToList(); collidableCollection.AddRange(this.NextColumn.ChildEntities.ToList()); // check if collides foreach (Entity block in collidableCollection) { var blockTransform = block.FindComponent<Transform3D>(); var blockCollider = block.FindComponent<BoxCollider3D>(); // updates the block boundingbox to check collision this.tempBoundingBox.Max = blockTransform.Position + blockCollider.Size / 2; this.tempBoundingBox.Min = blockTransform.Position - blockCollider.Size / 2; // we use intersects of boundboxes cause collider class has not a Intersects with boundingboxes if (this.tempBoundingBox.Intersects(this.playerBehavior.PlayerBoundingBox)) { BlockTypeEnum blockType = BlockTypeEnum.EMPTY; Enum.TryParse<BlockTypeEnum>(block.Tag, out blockType); // if player colliders with the block, we must to check the block effect: switch (blockType) { case BlockTypeEnum.EMPTY: break; // ground and box obstacles can walk over they, but if crash horizontally player dies case BlockTypeEnum.GROUND: case BlockTypeEnum.BOX: if (this.playerBehavior.Collides(blockTransform)) { this.GameState = Enums.GameState.DIE; } break; case BlockTypeEnum.PYRAMID: // pyramid collision dies player this.GameState = Enums.GameState.DIE; break; case BlockTypeEnum.SPEEDERBLOCK: // if collide with speeder then player accelerates this.playerBehavior.Accelerate((float)gameTime.TotalSeconds); break; default: break; } } } } break; // player die state case GameState.DIE: // free every column entity and remove containers from entitymanager foreach (Entity column in this.ColumnCollection) { this.modelFactoryService.FreeColumn(column); } // clears the collection and colums this.ColumnCollection.Clear(); this.CurrentColumn = null; this.NextColumn = null; // just init GameState = GameState.INIT; break; } }