// end of HandleMouseInput() private void HandleTouchInput() { //if (TouchInput.TouchCount == 0) { return; } // nothing to see here. //TouchContact touch = TouchInput.GetOldestTouch(); //Vector2 touchHit = TouchInput.GetAspectRatioAdjustedPosition( // touch.position, // camera, // true //); if (TouchInput.TouchCount == 0) { return; } // nothing to see here. TouchContact touch = TouchInput.GetOldestTouch(); Vector2 touchHit = ScreenWarp.ScreenToRT(touch.position); if (TouchGestureManager.Get().TapGesture.WasTapped()) { if (okButton.Box.Contains(touchHit)) { Accept(); } if (cancelButton.Box.Contains(touchHit)) { Cancel(); } if (textBox.Contains(touchHit)) { KeyboardInput.ShowOnScreenKeyboard(); } } } // end of HandleTouchInput()
/// <summary> /// Actually add a node to the scene. /// </summary> /// <param name="camera"></param> private void DoAddNode(Camera camera) { Debug.Assert(fromNode != null); if (inGame.UnderBudget) { if (fromNode != node) { Click(ModeChange.Add); if (node != null) { WayPoint.CreateNewEdge(fromNode, node); fromNode = node; } else { Vector3 pos = AddPosition(camera, fromNode); fromNode = WayPoint.CreateNewNode(fromNode, inGame.shared.curObjectColor, pos); //in touch mode, when we place a new node, have it highlighted, since there is no mouse over equivalent node = fromNode; } Changed(); } else if (TouchGestureManager.Get().DoubleTapGesture.WasRecognized) { //allow finish by double tapping selected node node = null; mode = Mode.None; fromNode = null; } } else { Click(ModeChange.NoBudget); } }
} // end of Update() private void UpdateTouch() { Camera camera = Boku.InGame.inGame.shared.camera; TouchEdit touchEdit = Boku.InGame.inGame.TouchEdit; TouchEdit.TouchHitInfo hitInfo = TouchEdit.HitInfo; // Don't update touchOver if the menus are active. This way the focus state will be preserved. if (!MenusActive && !SliderActive) { //handle color palette interactions if (touchOver.Over && touchOver.Path != null) { //set target color focusColorIndex = ColorPalette.GetIndexFromColor(touchOver.Path.Color); Boku.InGame.ColorPalette.Active = true; //check for touch on a new color Classification.Colors touchColor = Boku.InGame.ColorPalette.GetColorFromTouch(); if ((touchColor != Classification.Colors.None) && (touchOver.Path.Color != touchColor)) { touchOver.Path.Color = touchColor; focusColorIndex = ColorPalette.GetIndexFromColor(touchColor); Foley.PlayColorChange(); Boku.InGame.IsLevelDirty = true; } // For the duration of the color palette handling touch, all touch inputs are deferred. if (Boku.InGame.ColorPalette.HandlingTouch) { return; } } else { //no path selected, hide the palette Boku.InGame.ColorPalette.Active = false; } //clear selections if menu options change if (TouchInput.WasTouched && !Boku.InGame.inGame.TouchEdit.HasNonUITouch()) { touchOver.Clear(); } //adding/adjusting flags may change with update - but we don't want to allow a new path if we entered the update in //one of these modes bool allowNewPath = !touchOver.Adding && !touchOver.Adjusting; touchOver.Update(inGame, camera); // If the user presses the left button while not over anything // start adding a plain path. if (allowNewPath && !touchOver.Adding && !touchOver.Adjusting && TouchGestureManager.Get().TapGesture.WasRecognized&& Boku.InGame.inGame.touchEditUpdateObj.ToolBar.IsButtonActionToggledOn(ToolBar.TouchControls.BrushActionIDs.baNode) && Boku.InGame.inGame.TouchEdit.HasNonUITouch()) { Road.GenIndex = 0; touchOver.NewPath(hitInfo.TerrainPosition, focusColorIndex); } } //We stop adding in touch mode when the add node button is toggled off if (touchOver.Adding && !Boku.InGame.inGame.touchEditUpdateObj.ToolBar.IsButtonActionToggledOn(ToolBar.TouchControls.BrushActionIDs.baNode)) { touchOver.StopAdding(); } // Check to see if any of the menus need activating. if (TouchGestureManager.Get().TouchHoldGesture.WasRecognized&& Boku.InGame.inGame.TouchEdit.HasNonUITouch()) { // The menus may change depending on whether or not the full path is selected. SetUpMenus(); if (touchOver.Over) { if (touchOver.node != null) { nodeMenu.Activate(TouchInput.GetOldestTouch().position); } if (touchOver.edge != null) { edgeMenu.Activate(TouchInput.GetOldestTouch().position); } } else { groundMenu.Activate(TouchInput.GetOldestTouch().position); menuPosition = hitInfo.TerrainPosition; } } if (TouchGestureManager.Get().RotateGesture.IsValidated || TouchGestureManager.Get().PinchGesture.IsValidated || TouchGestureManager.Get().DoubleDragGesture.IsValidated) { //turn off menu if rotating, pinching or double dragging (i.e. terrain manipulation) groundMenu.Deactivate(); nodeMenu.Deactivate(); edgeMenu.Deactivate(); } groundMenu.Update(); nodeMenu.Update(); edgeMenu.Update(); // Change edge direction? if (touchOver.Over && touchOver.Path != null && touchOver.edge != null) { //direction change via double tap if (TouchGestureManager.Get().DoubleTapGesture.WasRecognized) { if (touchOver.ActOnPath) { touchOver.Path.IncDir(); } else { touchOver.edge.IncDir(); } } } // // Set up correct HelpOverlay // if (touchOver.Over) { if (touchOver.ActOnPath) { HelpOverlay.ReplaceTop("MouseEditPathsFocusPath"); } else if (touchOver.node != null) { HelpOverlay.ReplaceTop("MouseEditPathsFocusNode"); } else if (touchOver.edge != null) { HelpOverlay.ReplaceTop("MouseEditPathsFocusEdge"); } } }
//static private bool skipShow = false; public static void Update() { //if (BokuGame.bokuGame.IsActive) { #if NETFX_CORE Touch[] touchesThisFrame = AltGetTouchContacts(); #else //---------------------------------------------------------------------------------- // This is a stub until Unity support is added. Unity doesn't need its update called //---------------------------------------------------------------------------------- Input.Update(); //---------------------------------------------------------------------------------- // Please remove the above hack when Unity is integrated //---------------------------------------------------------------------------------- Touch[] touchesThisFrame = Input.touches; //From touchesThisFrame list in UnityTouchEmulation. #endif // Sort the array of Touch objects on the fingerId Array.Sort(touchesThisFrame, delegate(Touch touchZero, Touch touchOne) { return(touchZero.fingerId.CompareTo(touchOne.fingerId)); }); // Initially set it to nothing is touching the screen isTouched = false; wasMoved = false; wasTouched = false; if (touchesThisFrame.Length <= 0) { wasMultiTouch = false; } else if (touchesThisFrame.Length > 1) { //a single frame of multi touch means multi touch was detected, don't reset until no data wasMultiTouch = true; } // Assume we just released until proven false below wasReleased = true; // If there are a different number of touches than touch contacts, we either added // or deleted some contacts. int touchContactsLength = touchContacts.Count; int touchesThisFrameLength = touchesThisFrame.Length; if (touchContacts.Count != touchesThisFrame.Length) { //RemoveEndedTouchContacts(); // A touch was added, or multiple touches if (touchesThisFrame.Length > touchContacts.Count) { wasTouched = true; for (int i = 0; i < touchesThisFrame.Length; ++i) { Touch t = touchesThisFrame[i]; TouchContact contact = GetTouchContactByFingerId(t.fingerId); if (contact == null) { contact = new TouchContact(); contact.fingerId = t.fingerId; touchContacts.Add(contact); } } } else // A touch was deleted, or multiple touches { List <TouchContact> temp = new List <TouchContact>(); for (int i = 0; i < touchesThisFrame.Length; ++i) { Touch t = touchesThisFrame[i]; TouchContact contact = GetTouchContactByFingerId(t.fingerId); if (contact != null) { //search for existing touch with this id TouchContact existT = temp.Find(delegate(TouchContact p) { return(p.fingerId == contact.fingerId); }); if (existT == null) { temp.Add(contact); } } } touchContacts = temp; } } // Now that the number of TouchContact's is correct, lets sort them on the fingerId touchContacts.Sort(delegate(TouchContact contactZero, TouchContact contactOne) { return(contactZero.fingerId.CompareTo(contactOne.fingerId)); }); //string message = ""; if (touchContacts.Count != touchesThisFrame.Length) { /* * Debug.Assert((touchContacts.Count == touchesThisFrame.Length), message + * "old:\n" + oldTouchesThisFrameString + oldTouchContactsString + * "new:\n" + newTouchesThisFrameString + newTouchContactsString); */ #if !NETFX_CORE Input.ClearEvents(); #endif touchContacts.Clear(); wasReleased = false; return; } // Perform a deep copy of each touch object for (int i = 0; i < touchesThisFrame.Length; ++i) { Touch touch = touchesThisFrame[i]; TouchContact touchContact = touchContacts[i]; switch (touch.phase) { case TouchPhase.Began: //Console.WriteLine("New TouchContact"); touchContact.phase = TouchPhase.Began; touchContact.startPosition = touch.position; touchContact.previousPosition = touch.position; touchContact.startTime = Time.WallClockTotalSeconds; touchContact.elapsedTime = Time.WallClockFrameSeconds; break; case TouchPhase.Moved: case TouchPhase.Stationary: // JW - NOTE: Even when the Unity layer reports a touch as stationary once the // delta position is unchanged for one frame, that is not a very accurate measure. // We won't set TouchContact objects to be stationary until we've detected no // delta position change for STATIONARY_TIME seconds. if (touch.deltaPosition == Vector2.Zero) { if ((Time.WallClockTotalSeconds - touchContact.lastMoveTime) > STATIONARY_TIME) { touchContact.phase = TouchPhase.Stationary; } } else { touchContact.lastMoveTime = Time.WallClockTotalSeconds; touchContact.phase = TouchPhase.Moved; } touchContact.previousPosition = touchContact.position; touchContact.elapsedTime = Time.WallClockFrameSeconds; wasMoved = true; break; case TouchPhase.Ended: //Console.WriteLine("TouchContact has ended"); touchContact.previousPosition = touchContact.position; touchContact.phase = TouchPhase.Ended; touchContact.elapsedTime = Time.WallClockFrameSeconds; break; default: break; } if (touchContact.phase != TouchPhase.Ended) { isTouched = true; wasReleased = false; } touchContact.position = touch.position; touchContact.deltaPosition = touch.deltaPosition; touchContact.fingerId = touch.fingerId; //touchContact.tapCount = touch.tapCount; touchContact.deltaTime = touch.deltaTime; if (touchContact.elapsedTime > 0.0f) { touchContact.Velocity = (touchContact.position - touchContact.previousPosition) / touchContact.elapsedTime; } else { touchContact.Velocity = Vector2.Zero; } } // If we have no touch objects, then we are at least one frame after the last touch ended // so we are not released. if (touchContacts.Count == 0) { wasReleased = false; } } TouchGestureManager.Get().Update(); }
private void HandleTouchInput(Camera uicamera) { //TODO: this method is now extremely unwieldly - now that we have the basics down, refactor and consolidate the various checks if (GamePadInput.ActiveMode != GamePadInput.InputMode.Touch) { return; } // If the mouse took over from the touch, it should clear any // highlights the touch had going. Boku.InGame.inGame.MouseEdit.Clear(); Camera camera = Boku.InGame.inGame.shared.camera; TouchEdit touchEdit = Boku.InGame.inGame.TouchEdit; TouchEdit.TouchHitInfo hitInfo = null; //keep track of previous focus actor for comparisons this frame GameActor previousFocusActor = FocusActor; hitInfo = TouchEdit.HitInfo; //Check for color pallet hits if (Boku.InGame.ColorPalette.Active && (FocusActor != null) && !actorMenu.Active && !noActorMenu.Active) { Classification.Colors touchColor = Boku.InGame.ColorPalette.GetColorFromTouch(); if ((touchColor != Classification.Colors.None) && (FocusActor.ClassColor != touchColor)) { FocusActor.ClassColor = touchColor; focusColorIndex = ColorPalette.GetIndexFromColor(touchColor); Foley.PlayColorChange(); Boku.InGame.IsLevelDirty = true; } // For the duration of the color palette handling touch, all touch inputs are deferred. if (Boku.InGame.ColorPalette.HandlingTouch) { return; } } bool hasNonUITouch = touchEdit.HasNonUITouch(); bool hasValidTap = TouchGestureManager.Get().TapGesture.WasValidEditObjectTap; touchEdit.DoObject(camera); //check for tap to adjust hit actor if (hasValidTap || TouchGestureManager.Get().DoubleTapGesture.WasRecognized || TouchGestureManager.Get().TouchHoldGesture.WasRecognized || TouchGestureManager.Get().TouchHoldGesture.SlightHoldMade || (TouchGestureManager.Get().DragGesture.IsDragging&& TouchInput.InitialActorHit != null)) { if (hasNonUITouch && TouchGestureManager.Get().DragGesture.IsDragging&& TouchInput.InitialActorHit != null) { FocusActor = TouchInput.InitialActorHit; focusColorIndex = ColorPalette.GetIndexFromColor(FocusActor.Classification.Color); Boku.InGame.ColorPalette.Active = true; } else if (hasNonUITouch && hitInfo.HaveActor) { FocusActor = hitInfo.ActorHit; focusColorIndex = ColorPalette.GetIndexFromColor(FocusActor.Classification.Color); Boku.InGame.ColorPalette.Active = true; } else { FocusActor = null; Boku.InGame.ColorPalette.Active = false; } } //check for double tap on terrain to bring up add actor if (hasNonUITouch && TouchGestureManager.Get().DoubleTapGesture.WasRecognized&& FocusActor == null && !MenusActive && !SliderActive && inGame.editObjectUpdateObj.newItemSelectorShim.State != UIShim.States.Active) { // No actor in focus so activate AddItem menu. Vector2 position = new Vector2(hitInfo.TerrainPosition.X, hitInfo.TerrainPosition.Y); inGame.editObjectUpdateObj.ActivateNewItemSelector(position, true); } //handle dragging an actor if (TouchGestureManager.Get().DragGesture.IsDragging&& TouchInput.InitialActorHit != null && FocusActor != null) { //clear out menu if up actorMenu.Deactivate(); noActorMenu.Deactivate(); //select the focus actor when we start dragging if (selectedActor == null) { // Start draggin if over actor. selectedActor = FocusActor; actorOffset = selectedActor.Movement.Position - hitInfo.TerrainPosition; } Vector3 position = hitInfo.TerrainPosition + actorOffset; selectedActor.Movement.Position = Boku.InGame.SnapPosition(position); // Try and keep the bot directly under the mouse cursor while still being at the correct height. // A possible alternative would be to use the cursor's 2d position for the bot and just have the // bot float at the appropriate height over the cursor. This would allow more exact placement of // bots over terrain but it would mean a visual disconnect between where the cursor is and where // the bot is. There would also be a jump when the bot is first clicked on since the terrain // position of the cursor is most likely further back than the bot's current position. if (hitInfo.VerticalOffset == 0.0f) { Vector3 terrainToCameraDir = hitInfo.TerrainPosition - camera.From; terrainToCameraDir.Normalize(); position = hitInfo.TerrainPosition + terrainToCameraDir * (selectedActor.EditHeight / terrainToCameraDir.Z); selectedActor.Movement.Position = Boku.InGame.SnapPosition(position); } // If the actor is supposed to stay above water, try to enforce that. // This can have some strange visual effects since it forces the actor to // float above where the mouse cursor is but the alternative is to have // actor get dragged under water. if (selectedActor.StayAboveWater) { float waterAlt = Terrain.GetWaterBase(position); if (waterAlt != 0) { position.Z = waterAlt + selectedActor.EditHeight; selectedActor.Movement.Position = Boku.InGame.SnapPosition(position); } } Boku.InGame.IsLevelDirty = true; } else { selectedActor = null; //rules for context menus: // tap + hold -> always bring up menu (terrain or actor accordingly) // double tap -> bring up menu if over an actor (actor only) // single tap -> bring up menu if over an actor that was already selected (actor only) if (hasNonUITouch && (TouchGestureManager.Get().TouchHoldGesture.WasRecognized || (FocusActor != null && TouchGestureManager.Get().DoubleTapGesture.WasRecognized) || (FocusActor != null && hasValidTap && FocusActor == previousFocusActor))) { menuActor = FocusActor; menuCursorPosition = hitInfo.TerrainPosition; // We need to do this repeatedly since the Paste option will // change depending on what's in the cut/paste buffer. SetUpMenus(); if (FocusActor == null) { actorMenu.Deactivate(); noActorMenu.Activate(TouchInput.GetOldestTouch().position); } else { noActorMenu.Deactivate(); actorMenu.Activate(TouchInput.GetOldestTouch().position); // Turn off any thought balloons so they don't clutter the menu. ThoughtBalloonManager.RemoveThoughts(FocusActor); } } // Handle two finger actions. Only enabled when not dragging. if (hasNonUITouch && TouchInput.TouchCount == 2 && selectedActor == null) { PinchGestureRecognizer pinchGesture = TouchGestureManager.Get().GetActiveGesture(TouchGestureType.Pinch, TouchGestureType.Rotate) as PinchGestureRecognizer; if (pinchGesture != null && pinchGesture.IsPinching) { //Debug.WriteLine("Pinching... Scale: "+ pinchGesture.Scale ); DoScaleActor(pinchGesture.DeltaScale, FocusActor); } RotationGestureRecognizer rotationGesture = TouchGestureManager.Get().GetActiveGesture(TouchGestureType.Rotate, TouchGestureType.Pinch) as RotationGestureRecognizer; if (null != rotationGesture && rotationGesture.IsRotating) { DoRotateActor(rotationGesture.RotationDelta, FocusActor); } } } if (TouchGestureManager.Get().RotateGesture.IsValidated || TouchGestureManager.Get().PinchGesture.IsValidated || TouchGestureManager.Get().DoubleDragGesture.IsValidated) { //turn off menu if rotating, pinching or double dragging (i.e. terrain manipulation) actorMenu.Deactivate(); noActorMenu.Deactivate(); } noActorMenu.Update(); actorMenu.Update(); // Support for changing tree types via up/down arrow keys. if (FocusActor != null && FocusActor.Classification.name == "tree") { inGame.editObjectUpdateObj.MakeTreeChange(FocusActor); } // // Figure out help overlay mode. // if (inGame.editObjectUpdateObj.newItemSelectorShim.State == UIShim.States.Active) { // The pie menu is active. HelpOverlay.ReplaceTop("MouseEditAddItemMenu"); } else if (hitInfo != null && hitInfo.HaveActor) { // We have an actor in focus. if (FocusActor != null && FocusActor.Classification.name == "tree") { HelpOverlay.ReplaceTop("MouseEditEditObjectFocusTree"); } else { HelpOverlay.ReplaceTop("MouseEditEditObjectFocus"); } } }
/// <summary> /// Drag the current node/edge/path by mouse movement. Includes raise/lower /// as well as horizontal drag. /// </summary> /// <param name="camera"></param> private void DoDrag(Camera camera) { Vector2 pos = Vector2.Zero; Vector2 prevPos = Vector2.Zero; TouchContact touch = TouchInput.GetOldestTouch(); if (touch != null) { pos = touch.position; prevPos = touch.previousPosition; } Vector3 newPosition = Vector3.Zero; if (mode == Mode.Drag) { newPosition = TouchEdit.FindAtHeight(camera, TouchInput.GetAsPoint(TouchGestureManager.Get().DragGesture.DragPosition), height); } Vector3 delta = Vector3.Zero; if (mode == Mode.Raise) { float dheight = MouseInput.Position.Y - MouseInput.PrevPosition.Y; float kUpDownSpeed = -0.002f; dheight *= kUpDownSpeed; Vector3 dragPos = camera.ActualFrom; bool asRoad = false; if (node != null) { dragPos = node.RenderPosition(asRoad); } if (edge != null) { dragPos = (edge.Node0.RenderPosition(asRoad) + edge.Node1.RenderPosition(asRoad)) * 0.5f; } float dist = Vector3.Distance(dragPos, camera.ActualFrom); dheight *= dist; delta.Z = dheight; } if (newPosition != Vector3.Zero && Path != null) { if (actOnPath) { if (node != null) { Path.Translate(newPosition - node.Position); } else if (edge != null) { Path.Translate(newPosition - edge.HandlePosition); } } else if (node != null) { node.Translate(newPosition - node.Position); } else if (edge != null) { edge.Translate(newPosition - edge.HandlePosition); } skeletonTimer = kSkeletonTime; } if ((delta != Vector3.Zero) && (Path != null)) { if (actOnPath) { MovePath(Path, delta); } else if (node != null) { MoveNode(node, delta); } else if (edge != null) { MoveEdge(edge, delta); } skeletonTimer = kSkeletonTime; } }
} // end of BasePicker RestorePreviousChoice() public virtual void Update(PerspectiveUICamera camera) { if (active) { if (hidden) { // Note, even though we're hidden we may still be rendering our fade out. double elapsedTime = Time.WallClockTotalSeconds - startFadeTime; if (elapsedTime >= fadeTime) { Alpha = 0.0f; } else { Alpha = 1.0f - (float)(elapsedTime / fadeTime); } } else { // Not hidden, so respond to user input. int scroll = MouseInput.ScrollWheel - MouseInput.PrevScrollWheel; if (Actions.PickerRight.WasPressedOrRepeat || scroll > 0) { Actions.PickerRight.ClearAllWasPressedState(); DecrementFocus(); } if (Actions.PickerLeft.WasPressedOrRepeat || scroll < 0) { Actions.PickerLeft.ClearAllWasPressedState(); IncrementFocus(); } if (Actions.Select.WasPressed) { Actions.Select.ClearAllWasPressedState(); SelectCurrentChoice(); Foley.PlayPressA(); } if (Actions.Cancel.WasPressedOrRepeat) { Actions.Cancel.ClearAllWasPressedState(); RestorePreviousChoice(); Foley.PlayBack(); } bool handled = false; if (GamePadInput.ActiveMode == GamePadInput.InputMode.Touch) { handled = HandleTouchInput(camera); } else if (GamePadInput.ActiveMode == GamePadInput.InputMode.KeyboardMouse) { handled = HandleMouseInput(camera); } if (!handled) { // If the user clicked but didn't hit any of the picker elements, close the picker. // If alt is pressed, they must be in eyedropper mode. if ((MouseInput.Left.WasPressed && !KeyboardInput.AltIsPressed) || (TouchGestureManager.Get().TapGesture.WasRecognized)) { SelectCurrentChoice(); Foley.PlayPressA(); } else if (Actions.Sample.WasPressed || MouseEdit.TriggerSample() || TouchEdit.TriggerSample()) { Actions.Sample.ClearAllWasPressedState(); int t = OnSampleType(); if (t >= 0) { OnSetType(t); Point selection = grid.SelectionIndex; selection.X = t; grid.SelectionIndex = selection; Foley.PlayCut(); } else { Foley.PlayNoBudget(); } } } grid.Update(ref worldMatrix); } } // end if active } // end of BasePicker Update()
const float kZoomFactor = 1.1f; // Multiplicative factor applied per second. /// <summary> /// Reads user input to orbit and track the camera position. /// </summary> private void OrbitAndTrackCamera() { GamePadInput pad = GamePadInput.GetGamePad0(); float tics = Time.WallClockFrameSeconds; // Right stick to orbit around cursor. // Note in first person mode, the sense of rotation is reversed. float dRotation = (GamePadInput.InvertCamX() ? -pad.RightStick.X : pad.RightStick.X) * tics * kOrbitSpeed; float dPitch = GamePadInput.InvertCamY() ? -pad.RightStick.Y : pad.RightStick.Y; if (CameraInfo.FirstPersonActive) { parent.Camera.DesiredRotation -= dRotation * 2.0f; parent.Camera.FirstPersonDesiredPitchDelta = -dPitch * kOrbitSpeed; } else { parent.Camera.DesiredRotation += dRotation; parent.Camera.DesiredPitch -= dPitch * tics * kOrbitSpeed; } // If the user has programmed the right mouse button, // don't also use it for moving the camera. if (!InGame.inGame.ProgramUsesRightMouse) { parent.MouseEdit.DoCamera(parent.Camera); } if (GamePadInput.ActiveMode == GamePadInput.InputMode.Touch) { bool bAllowCameraMovement = true; bAllowCameraMovement = !TouchVirtualController.IsVirtualControllerActedOn(); SwipeGestureRecognizer swipeGesture = TouchGestureManager.Get().SwipeGesture; if (bAllowCameraMovement && swipeGesture.IdentifiedFinger) { #if NETFX_CORE float halfWidth = (float)BokuGame.bokuGame.Window.ClientBounds.Width * 0.5f; float height = (float)BokuGame.bokuGame.Window.ClientBounds.Height; #else float halfWidth = (float)XNAControl.Instance.ClientSize.Width * 0.5f; float height = (float)XNAControl.Instance.ClientSize.Height; #endif //center half of the screen width-wise float minX = halfWidth - (halfWidth * k_TouchExitAreaWidthPercent); float maxX = halfWidth + (halfWidth * k_TouchExitAreaWidthPercent); //bottom 20% height-wise float minY = height - (height * k_TouchExitAreaHeightPercent); Vector2 pos = swipeGesture.InitialPosition; bAllowCameraMovement = !(pos.X >= minX && pos.X <= maxX && pos.Y >= minY); } if (bAllowCameraMovement) { parent.TouchEdit.DoCamera(parent.Camera); parent.TouchEdit.AddPitchYawByDrag(parent.Camera); parent.TouchEdit.ProcessCameraRotation(parent.Camera); } } // Shoulder buttons track camera in/out. // Don't change zoom while in first person mode unless we got there via zooming in. if (!CameraInfo.FirstPersonActive || CameraInfo.FirstPersonViaZoom) { if (Actions.ZoomOut.IsPressed) { parent.Camera.DesiredDistance *= 1.0f + tics * kZoomFactor; } if (Actions.ZoomIn.IsPressed) { parent.Camera.DesiredDistance *= 1.0f - tics * kZoomFactor; } parent.MouseEdit.DoZoom(parent.Camera); parent.TouchEdit.DoZoom(parent.Camera); } } // end of RunSimUpdateObj OrbitAndTrackCamera()
} // end of MouseMenu Update() private void UpdateTouchInput() { for (int j = 0; j < TouchInput.TouchCount; j++) { TouchContact touch = TouchInput.GetTouchContactByIndex(j); Vector2 touchHit = touch.position; // HitTest mouse vs elements. Set selected state. curIndex = -1; for (int i = 0; i < itemList.Count; i++) { if (itemList[i].HitBox.Contains(touchHit)) { itemList[i].Selected = true; curIndex = i; } else { itemList[i].Selected = false; } } if (TouchInput.WasReleased) { // If released while over an item, then select that item. if (curIndex != -1) { if (onSelect != null) { Foley.PlayPressA(); onSelect(this); chosenIndex = curIndex; } itemList[CurIndex].Selected = false; if (CurIndex != -1) { CurIndex = -1; } Deactivate(); return; } // If released near origin, then we assume that the user wants to click on items seperately so do nothing. // If released elsewhere, treat this as a cancel, but only if its a tap release. float dist = (touchHit - position).Length(); if (dist > originRadius) { if (TouchGestureManager.Get().TapGesture.WasTapped()) { // Cancel. if (onCancel != null) { onCancel(this); } if (CurIndex != -1) { itemList[CurIndex].Selected = false; } CurIndex = -1; chosenIndex = -1; Deactivate(); } } } } }
} // end of c'tor /// <summary> /// Updates the toast system. /// </summary> /// <returns>True if the user has indicated that the modal display should be activated. (clicking on the toast or pressing Y)</returns> public static bool Update() { double secs = Time.WallClockTotalSeconds; alpha = 0.0f; if (curToast != null) { // Find where we are in fade-in, hold, fade-out cycle. double elapsedTime = Time.WallClockTotalSeconds - startShowTime; if (dirty) { RefreshTexture(); } if (elapsedTime < fadeInTime) { // Fading in. alpha = (float)(elapsedTime / fadeInTime); } else if (elapsedTime <= fadeInTime + holdTime) { alpha = 1.0f; } else { // Fading out. alpha = 1.0f - (float)((elapsedTime - fadeInTime - holdTime) / fadeOutTime); if (alpha < 0.0f) { alpha = 0.0f; curToast = null; } } } bool result = false; if (GamePadInput.ActiveMode == GamePadInput.InputMode.KeyboardMouse) { if (MouseInput.Left.WasPressed) { // Did this hit the toast? if (MouseInput.Position.X > curPosition.X && MouseInput.Position.X < curPosition.X + size.X && MouseInput.Position.Y > curPosition.Y && MouseInput.Position.Y < curPosition.Y + size.Y) { MouseInput.Left.ClearAllWasPressedState(); Clear(); // Turn off this toast result = true; } } // F1 pressed? if (KeyboardInput.WasPressed(Keys.F1)) { MouseInput.Left.ClearAllWasPressedState(); Clear(); // Turn off this toast result = true; } } else if (GamePadInput.ActiveMode == GamePadInput.InputMode.Touch) { TapGestureRecognizer tapGesture = TouchGestureManager.Get().TapGesture; if (tapGesture.WasRecognized) { // Did this hit the toast? if (tapGesture.Position.X > curPosition.X && tapGesture.Position.X < curPosition.X + size.X && tapGesture.Position.Y > curPosition.Y && tapGesture.Position.Y < curPosition.Y + size.Y) { Clear(); // Turn off this toast result = true; } } } else { // We can't steal input when in run mode since the user may // have mapped the Y button for game play. if (InGame.inGame.CurrentUpdateMode != InGame.UpdateMode.RunSim) { GamePadInput pad = GamePadInput.GetGamePad0(); if (pad.ButtonY.WasPressed) { pad.ButtonY.ClearAllWasPressedState(); Clear(); // Turn off this toast result = true; } } } return(result); } // end of ToastManager Update()
public override void Update() { // Did we switch modes? if (inputMode != GamePadInput.ActiveMode) { inputMode = GamePadInput.ActiveMode; shared.dirty = true; } if (AuthUI.IsModalActive) { return; } // Input focus and not pushing? if (parent.Active && CommandStack.Peek() == parent.commandMap && shared.pushOffset == 0.0f) { GamePadInput pad = GamePadInput.GetGamePad0(); if (Actions.Cancel.WasPressed) { Actions.Cancel.ClearAllWasPressedState(); parent.Deactivate(); Foley.PlayShuffle(); shared.dirty = true; } bool moveLeft = false; bool moveRight = false; // left if (Actions.ComboLeft.WasPressedOrRepeat) { moveLeft = true; } // right if (Actions.ComboRight.WasPressedOrRepeat) { moveRight = true; } //touch? if (GamePadInput.ActiveMode == GamePadInput.InputMode.Touch) { TouchContact touch = TouchInput.GetOldestTouch(); Vector2 touchHit = Vector2.Zero; SwipeGestureRecognizer swipeGesture = TouchGestureManager.Get().SwipeGesture; if (swipeGesture.WasSwiped() && swipeGesture.SwipeDirection == Boku.Programming.Directions.East) { moveLeft = true; } else if (swipeGesture.WasSwiped() && swipeGesture.SwipeDirection == Boku.Programming.Directions.West) { moveRight = true; } else if (touch != null) { touchHit = touch.position; if (shared.leftArrowBox.Touched(touch, touchHit)) { moveLeft = true; } if (shared.rightArrowBox.Touched(touch, touchHit)) { moveRight = true; } if (shared.backBox.Touched(touch, touchHit)) { Actions.Cancel.ClearAllWasPressedState(); parent.Deactivate(); Foley.PlayShuffle(); shared.dirty = true; } } } // Mouse hit? else if (GamePadInput.ActiveMode == GamePadInput.InputMode.KeyboardMouse) { Vector2 mouseHit = new Vector2(MouseInput.Position.X, MouseInput.Position.Y); if (shared.leftArrowBox.LeftPressed(mouseHit)) { moveLeft = true; } if (shared.rightArrowBox.LeftPressed(mouseHit)) { moveRight = true; } if (shared.backBox.LeftPressed(mouseHit)) { Actions.Cancel.ClearAllWasPressedState(); parent.Deactivate(); Foley.PlayShuffle(); shared.dirty = true; } } if (moveLeft) { --shared.curScreen; if (shared.curScreen < 0) { parent.Deactivate(); } Foley.PlayShuffle(); shared.dirty = true; shared.pushOffset = -BokuGame.ScreenSize.X; } if (moveRight) { ++shared.curScreen; if (shared.curScreen >= shared.screenList.Count) { parent.Deactivate(); } Foley.PlayShuffle(); shared.dirty = true; shared.pushOffset = BokuGame.ScreenSize.X; } } if (shared.dirty && shared.curScreen >= 0 && shared.curScreen < shared.screenList.Count) { shared.prevTexture = shared.curTexture; // Get the correct overlay image to use depending on input mode. string name = GamePadInput.ActiveMode == GamePadInput.InputMode.GamePad ? shared.screenList[shared.curScreen].name : shared.screenList[shared.curScreen].mouseName; shared.curTexture = BokuGame.Load <Texture2D>(BokuGame.Settings.MediaPath + @"Textures\HelpScreens\" + name); shared.dirty = false; // Create a twitch to do the push. TwitchManager.Set <float> set = delegate(float val, Object param) { shared.pushOffset = val; }; TwitchManager.CreateTwitch <float>(shared.pushOffset, 0.0f, set, 0.3f, TwitchCurve.Shape.EaseOut); } } // end of Update()
private void HandleTouchInput(Camera camera) { if (GamePadInput.ActiveMode != GamePadInput.InputMode.Touch) { return; } // Touch input // If the touch is over the menu, move the selection index to the item under the mouse. // On touch down, make the item (if any) under the touch the ClickedOnItem. // On tap, if the touch is still over the ClickedOnItem, activate it. If not, just clear ClickedOnItem. TouchContact touch = TouchInput.GetOldestTouch(); if (touch != null) { Vector2 hitUV = TouchInput.GetHitUV(touch.position, camera, ref invWorldMatrix, width, height, useRtCoords: useRtCoords); // See if we're over anything. If so, set that item to being selected but only if we've moved the mouse. // This prevents the menu from feeling 'broken' if the mouse is over it and the user tries to use // the gamepad or keyboard. int touchItem = -1; for (int i = 0; i < itemList.Count; i++) { if (itemList[i].UVBoundingBox != null && itemList[i].UVBoundingBox.Contains(hitUV)) { // Only update the current in-focus element when the mouse moves. if (true) // touch.position != touch.previousPosition) { CurIndex = i; } touchItem = i; } } //if ( TouchInput.TapGesture.WasTapped() ) if (TouchInput.IsTouched) { if (touchItem != -1) { touch.TouchedObject = itemList[touchItem]; } } if (TouchGestureManager.Get().TapGesture.WasTapped()) { // Make sure we're still over the ClickedOnItem. if (touchItem != -1 && touch.TouchedObject == itemList[touchItem]) { ToggleState(); } } Vector2 hit = touch.position; if (useRtCoords) { hit = ScreenWarp.ScreenToRT(hit); } if (changeBox.Touched(touch, hit)) { ToggleState(); } if (backBox.Touched(touch, hit)) { Deactivate(); Foley.PlayBack(); } // Allow Swipeto cycle through elements. // Allow scroll wheel to cycle through elements. SwipeGestureRecognizer swipeGesture = TouchGestureManager.Get().SwipeGesture; if (swipeGesture.WasSwiped()) { if (swipeGesture.SwipeDirection == Boku.Programming.Directions.South) { curIndex -= 6; if (curIndex < 0) { curIndex = itemList.Count - 1; } Foley.PlayShuffle(); } else if (swipeGesture.SwipeDirection == Boku.Programming.Directions.North) { curIndex += 6; if (curIndex > (itemList.Count - 1)) { curIndex = 0; } Foley.PlayShuffle(); } } // If we click outside of the list, close it treating it as if select was chosen. //if (TouchInput.TapGesture.WasTapped() && touch.touchedObject == null) if (TouchInput.WasTouched && touch.TouchedObject == null) { Deactivate(); } } }
private void HandleTouchInput() { if (GamePadInput.ActiveMode != GamePadInput.InputMode.Touch) { return; } if (scrollItems.Count == 0) { return; } if (TouchInput.TouchCount != 1) { return; } Vector2 touchHit = TouchInput.GetOldestTouch().position; Vector2 adjHitPos = touchHit; if (scrollBoxHit.Contains(adjHitPos) || startDragOffset != 0.0f) { if (TouchInput.WasTouched || (TouchInput.IsTouched && startDragOffset == 0.0f)) { startDragOffset = touchHit.Y; startScrollOffset = scrollOffset; } else if (TouchInput.IsTouched) { float dragDistance = touchHit.Y - startDragOffset; float desiredScrollOffset = (ScrollableHeight * (dragDistance / MaxBoxTravelDistance)) + startScrollOffset; ConstrainScrollBox(desiredScrollOffset); } else { startDragOffset = 0.0f; } } else { adjHitPos -= relativePosition; for (int i = 0; i < scrollItems.Count; i++) { if (scrollItems[i].IsInFocus(adjHitPos)) { if (TouchGestureManager.Get().TapGesture.WasRecognized) { Object obj; scrollItems[i].Click(adjHitPos, out obj, ClickType.WasReleased); if (indexFocusedItem != i) { indexFocusedItem = i; scrollItems[indexFocusedItem].ResetFocus(); } } } } } }
} // end of PreGameRacingWithDesc c'tor public override void Update() { if (Active) { if (showingDescription) { // Waiting for A to be pressed. if (Actions.Select.WasPressed) { Actions.Select.ClearAllWasPressedState(); showingDescription = false; startTime = Time.WallClockTotalSeconds; HelpOverlay.Pop(); // Don't let current pressed state leak into game. GamePadInput.IgnoreUntilReleased(Buttons.A); } if (GamePadInput.ActiveMode == GamePadInput.InputMode.KeyboardMouse) { // Check if user click on bottom text. if (MouseInput.Left.WasPressed && HelpOverlay.MouseHitBottomText(MouseInput.Position)) { showingDescription = false; startTime = Time.WallClockTotalSeconds; HelpOverlay.Pop(); MouseInput.Left.ClearAllWasPressedState(); } } if (GamePadInput.ActiveMode == GamePadInput.InputMode.Touch) { // Check if user click on bottom text. if (TouchGestureManager.Get().TapGesture.WasTapped() && HelpOverlay.MouseHitBottomText(TouchInput.GetAsPoint(TouchInput.GetOldestTouch().position)) ) { showingDescription = false; startTime = Time.WallClockTotalSeconds; HelpOverlay.Pop(); } } } else { int oldPhase = phase; phase = (int)Math.Ceiling(startTime + duration - Time.WallClockTotalSeconds); if (oldPhase != phase) { if ((phase < cueNames.Length) && (phase >= 0)) { BokuGame.Audio.GetCue(cueNames[phase]).Play(); } } if (Time.WallClockTotalSeconds > startTime + duration) { // We're done. Active = false; } // Check if user click on bottom text. if (GamePadInput.ActiveMode == GamePadInput.InputMode.Touch) { // Check if user click on bottom text. if (TouchGestureManager.Get().TapGesture.WasTapped() && HelpOverlay.MouseHitBottomText(TouchInput.GetAsPoint(TouchInput.GetOldestTouch().position)) ) { Active = false; } } else if (MouseInput.Left.WasPressed && HelpOverlay.MouseHitBottomText(MouseInput.Position)) { Active = false; MouseInput.Left.ClearAllWasPressedState(); } } } base.Update(); } // end of PreGameRacingWithDesc Update()
} // end of Update() private void HandleTouchInput() { if (GamePadInput.ActiveMode != GamePadInput.InputMode.Touch) { return; } if (TouchInput.TouchCount == 0) { return; } bool hitMenu = false; TouchContact touch = TouchInput.GetOldestTouch(); // If in focus element has help available, get it. UIGridElement focusElement = grid.SelectionElement; string helpID = focusElement.HelpID; string helpText = TweakScreenHelp.GetHelp(helpID); // Check for help tile. Matrix mat = Matrix.CreateTranslation(-helpSquare.Position.X, -helpSquare.Position.Y, 0); if (touch != null) { Vector2 hitHelpUV = Vector2.Zero; hitHelpUV = TouchInput.GetHitUV(touch.position, camera, ref mat, helpSquare.Size, helpSquare.Size, true); if (grid.SelectionElement.ShowHelpButton) { if (hitHelpUV.X >= 0 && hitHelpUV.X < 1 && hitHelpUV.Y >= 0 && hitHelpUV.Y < 1) { if (TouchInput.WasTouched) { touch.TouchedObject = helpSquare; } if (TouchInput.WasReleased && touch.TouchedObject == helpSquare) { if (helpText != null) { ShowHelp(helpText); } } hitMenu = true; } } // Check if mouse hitting current selection object. Or should this be done in the object? mat = Matrix.Invert(focusElement.WorldMatrix); Vector2 hitFocusUV = TouchInput.GetHitUV(touch.position, camera, ref mat, focusElement.Size.X, focusElement.Size.Y, true); bool focusElementHit = false; if (hitFocusUV.X >= 0 && hitFocusUV.X < 1 && hitFocusUV.Y >= 0 && hitFocusUV.Y < 1) { if (touch.phase == TouchPhase.Began) { touch.TouchedObject = focusElement; } focusElement.HandleTouchInput(touch, hitFocusUV); focusElementHit = true; hitMenu = true; } // If we didn't hit the focus object, see if we hit any of the others. // If so, bring them into focus. if (!focusElementHit && TouchGestureManager.Get().TapGesture.WasTapped()) { for (int i = 0; i < grid.ActualDimensions.Y; i++) { if (i == grid.SelectionIndex.Y) { continue; } UIGridElement e = grid.Get(0, i); mat = Matrix.Invert(e.WorldMatrix); Vector2 hitUV = TouchInput.GetHitUV(touch.position, camera, ref mat, e.Size.X, e.Size.Y, true); if (hitUV.X >= 0 && hitUV.X < 1 && hitUV.Y >= 0 && hitUV.Y < 1) { // We hit an element, so bring it into focus. grid.SelectionIndex = new Point(0, i); hitMenu = true; break; } } } if ((hitFocusUV.X >= 0) && (hitFocusUV.X < 1)) { hitMenu = true; } if (!hitMenu && TouchGestureManager.Get().TapGesture.WasTapped()) { Deactivate(); } // Handle free-form scrolling if (touch.TouchedObject != focusElement) { grid.HandleTouchInput(camera); } } // end of touch input }
public void Update(out bool cancelRing) { sliceActivated = false; cancelRing = false; Vector2 hitUV = Vector2.Zero; Matrix invWorld = Matrix.Invert(worldMatrix); // user clicked on me? GraphicsDevice device = BokuGame.bokuGame.GraphicsDevice; // Center on screen and just high enough to clear bottom help overlay text. Vector2 screenSize = new Vector2(device.Viewport.Width, device.Viewport.Height); int sliceIndex = -1; for (int i = 0; i < TouchInput.TouchCount; i++) { TouchContact touch = TouchInput.GetTouchContactByIndex(i); Vector2 touchPos = touch.position; touchPos = touch.position - ScreenOffset; hitUV = TouchInput.GetHitOrtho(touchPos, camera, ref invWorld, useRtCoords: false); if (gotTouchBegan) { if (touch.phase == TouchPhase.Moved || touch.phase == TouchPhase.Stationary) { if (WithinPieRing(hitUV)) { sliceIndex = GetSliceAtAngle(hitUV); SetFocus(sliceIndex); indexLastHoverItem = indexCurrentHoverItem; } } else if (TouchGestureManager.Get().TapGesture.WasTapped()) //cancel? { float len = hitUV.Length(); if (len > outerRadius) { cancelRing = true; sliceActivated = false; } } // is this a group slice? open its pie! if (!cancelRing && (touch.phase == TouchPhase.Ended)) { if (WithinPieRing(hitUV)) { sliceIndex = GetSliceAtAngle(hitUV); if (sliceIndex > -1) { PieDisk nextDisk = slices[sliceIndex].subDisk; if (nextDisk != null && nextDisk.SliceCount() > 0) { Object rootParent = Parent; while ((rootParent as PieMenu) == null) { rootParent = (rootParent as PieDisk).Parent; } (rootParent as PieMenu).activeDisk = nextDisk; (rootParent as PieMenu).focusedDiskNo++; nextDisk.Visible = true; nextDisk.ScreenPosition = touch.position; nextDisk.BuildSlices(); } else { indexPickedItem = sliceIndex; sliceActivated = true; } } else { Debug.Assert(false);// && "something unexpected failed here."); } } } else { sliceActivated = false; } } if (touch.phase == TouchPhase.Began) { gotTouchBegan = true; } else if (touch.phase == TouchPhase.Ended) { gotTouchBegan = false; } } if (TouchInput.TouchCount == 0) { indexCurrentHoverItem = -1; SetFocus(sliceIndex); } if ((sliceIndex == -1)) { indexCurrentHoverItem = -1; SetFocus(sliceIndex); indexLastHoverItem = -1; } }
} // end of DeleteAll() public void Update(Camera camera, ref Matrix parentMatrix) { // Check for input. if (active && itemList.Count > 1 && !IgnoreInput && CommandStack.Peek() == commandMap) { bool selectionChanged = false; bool moveUp = false; bool moveDown = false; { // Mouse input if (GamePadInput.ActiveMode == GamePadInput.InputMode.KeyboardMouse) { // If the mouse is over the menu, move the selection index to the item under the mouse. // On mouse down, make the item (if any) under the mouse the ClickedOnItem. // On mouse up, if the mouse is still over the ClickedOnItem, activate it. If not, just clear ClickedOnItem. Vector2 hitUV = MouseInput.GetHitUV(camera, ref invWorldMatrix, width, height, useRtCoords); // See if we're over anything. If so, set that item to being selected but only if we've moved the mouse. // This prevents the menu from feeling 'broken' if the mouse is over it and the user tries to use // the gamepad or keyboard. int mouseOverItem = -1; for (int i = 0; i < itemList.Count; i++) { if (itemList[i].UVBoundingBox != null && itemList[i].UVBoundingBox.Contains(hitUV)) { // Only update the current in-focus element when the mouse moves. if (MouseInput.Position != MouseInput.PrevPosition) { CurIndex = i; } mouseOverItem = i; } } if (MouseInput.Left.WasPressed && mouseOverItem != -1) { MouseInput.ClickedOnObject = itemList[mouseOverItem]; } if (MouseInput.Left.WasReleased && mouseOverItem != -1 && MouseInput.ClickedOnObject == itemList[mouseOverItem]) { // Normally this is already set except in the case where the app didn't have focus and a menu item is clicked. // In that case, the CurIndex value stays stuck at its previous position. In particular this was causing Kodu's // Main Menu to think RESUME was clicked even when it was one of the other menu items. CurIndex = mouseOverItem; if (onSelect != null) { onSelect(this); } Foley.PlayPressA(); return; } // Allow scroll wheel to cycle through elements. int wheel = MouseInput.ScrollWheel - MouseInput.PrevScrollWheel; if (wheel > 0) { moveUp = true; } else if (wheel < 0) { moveDown = true; } } // end if KeyboardMouse mode. if (GamePadInput.ActiveMode == GamePadInput.InputMode.Touch) { // Look for Tap gesture first. No need to care about touch response if we've got a tap. bool goodTapGesture = false; if (TouchGestureManager.Get().TapGesture.WasTapped()) { // Check if tap position hit any of the menu elements. Vector2 tapPosition = TouchGestureManager.Get().TapGesture.Position; Vector2 touchHitUV = TouchInput.GetHitUV(tapPosition, camera, ref invWorldMatrix, width, height, useRtCoords); for (int index = 0; index < itemList.Count; index++) { if (itemList[index].UVBoundingBox != null && itemList[index].UVBoundingBox.Contains(touchHitUV)) { CurIndex = index; if (onSelect != null) { onSelect(this); Foley.PlayPressA(); selectionChanged = true; goodTapGesture = true; } } } } // Look for touch events to change focus. Ignore this if we had a good tap gesture. if (!goodTapGesture) { for (int i = 0; i < TouchInput.TouchCount; i++) { TouchContact touch = TouchInput.GetTouchContactByIndex(i); // Touch input // If the user touched the menu, move the selection index to the item under the touch. // On touch down, make the item (if any) under the contact the touchedItem. // On touch up, if the touch is still over the touchedItem, activate it. If not, just clear touchedItem. Vector2 touchHitUV = TouchInput.GetHitUV(touch.position, camera, ref invWorldMatrix, width, height, useRtCoords); // See what UI element we are over, if anything. If it hits, set that item to being selected but only if the touch has moved. // This emulates how the mouse is being handled by allowing the input to change only if the touch has moved. If a user moves // the gamepad or keyboard but doesn't move their touch contact, then the selection won't flicker back and forth and feel 'broken' int touchOverIndex = -1; for (int index = 0; index < itemList.Count; index++) { if (itemList[index].UVBoundingBox != null && itemList[index].UVBoundingBox.Contains(touchHitUV)) { touchOverIndex = index; } } if (touch.phase == TouchPhase.Began || touch.phase == TouchPhase.Moved) { // Touch is down! if (touchOverIndex != -1) { touch.TouchedObject = itemList[touchOverIndex]; if (CurIndex != touchOverIndex) { selectionChanged = true; } CurIndex = touchOverIndex; } } else if (touch.phase == TouchPhase.Moved) { // Touch moved!!! Update Something!! if (CurIndex != touchOverIndex) { CurIndex = touchOverIndex; } } } } // end if not good tap gesture. if (selectionChanged) { if (onChange != null) { onChange(this); } dirty = true; //RecalcPositions(); // Ensure that the selected state of all items is correct. for (int i = 0; i < itemList.Count; i++) { itemList[i].Selected = i == CurIndex; } } } // end of touch mode processing. } if (GamePadInput.ActiveMode == GamePadInput.InputMode.GamePad || GamePadInput.ActiveMode == GamePadInput.InputMode.KeyboardMouse) { // Gamepad / Keyboard input. GamePadInput pad = GamePadInput.GetGamePad0(); if ((AcceptStartForCancel && Actions.Start.WasPressed) || Actions.Cancel.WasPressed) { Actions.Cancel.ClearAllWasPressedState(); if (onCancel != null) { onCancel(this); } Foley.PlayBack(); return; } if (Actions.Select.WasPressed) { Actions.Select.ClearAllWasPressedState(); if (onSelect != null) { onSelect(this); } Foley.PlayPressA(); return; } int prevIndex = CurIndex; // Handle input changes here. if (Actions.ComboDown.WasPressedOrRepeat || moveDown) { ++CurIndex; if (CurIndex >= itemList.Count) { CurIndex = 0; } selectionChanged = true; } if (Actions.ComboUp.WasPressedOrRepeat || moveUp) { --CurIndex; if (CurIndex < 0) { CurIndex = itemList.Count - 1; } selectionChanged = true; } if (selectionChanged) { if (onChange != null) { onChange(this); } dirty = true; //RecalcPositions(); } // Ensure that the selected state of all items is correct. for (int i = 0; i < itemList.Count; i++) { itemList[i].Selected = i == CurIndex; } } } RefreshTexture(); } // end of UIGridModularMenu Update()
} // end of RunSimUpdateObj c'tor /// <summary> /// RunSimUpdateObj Update() /// </summary> /// <param name="camera"></param> public override void Update() { base.Update(); parent.Camera.Update(); float secs = Time.WallClockFrameSeconds; ThoughtBalloonManager.Update(shared.camera); SaidStringManager.Update(); #if !NETFX_CORE MicrobitManager.Update(); #endif // Start with visible cursor. parent.cursor3D.Activate(); parent.cursor3D.Rep = Cursor3D.Visual.RunSim; parent.cursor3D.Hidden = false; // // Determine the correct camera mode. // // // The priorities used to determine the camera mode when the game is running are: // // 1) First person. This can be either via programming or because the user zoomed // into a bot the camera was following. // 2) Follow mode caused by bot(s) programmed with "follow" camera view. // 3) World tweak screen fixed camera or fixed offset camera. // 4) Follow mode caused by user controlled bot(s). // 5) Free camera. // // Start with a fake loop to break out of. while (true) { Terrain terrain = InGame.inGame.Terrain; // Just a shortcut. // // Always use edit mode when the game is paused except during victory on level with one of the fixed cameras // or when game is paused for a bot to speak (modal text display). // bool victoryActive = VictoryOverlay.ActiveGameOver || VictoryOverlay.ActiveWinner; bool speaking = InGame.inGame.shared.smallTextDisplay.Active || InGame.inGame.shared.scrollableTextDisplay.Active; if (Time.Paused && !((terrain.FixedCamera || terrain.FixedOffsetCamera) && victoryActive) && !speaking) { CameraInfo.Mode = CameraInfo.Modes.Edit; CameraInfo.CameraFocusGameActor = null; break; } // // 1) First person // if (CameraInfo.FirstPersonActive) { CameraInfo.Mode = CameraInfo.Modes.Actor; // We're following a single actor so update the FollowActor camera values. shared.camera.FollowCameraValid = false; // Turn off 3d cursor since we don't need it. parent.cursor3D.Deactivate(); if (parent.cursorClone != null) { parent.cursorClone.Deactivate(); parent.cursorClone = null; } break; } // // 2) Follow mode caused by bot(s) programmed with "follow" camera view. // if (CameraInfo.ProgrammedFollowList.Count > 0) { // Note that even though we looked at the count of bot programmed to // have the camera follow them, for this mode we want to keep all // deserving bots in camera. So, the rest of this section will use // the merged follow list instead of just the programmed follow list. SetUpCameraFollowMode(); break; } // // 3) World tweak fixed cameras. Note for fixed offset we have to let // the later modes do their stuff and then override the camera. // if (terrain.FixedCamera) { CameraInfo.Mode = CameraInfo.Modes.FixedTarget; CameraInfo.CameraFocusGameActor = null; // Turn off 3d cursor since we don't need it. parent.cursor3D.Deactivate(); if (parent.cursorClone != null) { parent.cursorClone.Deactivate(); parent.cursorClone = null; } break; } // // 4) Follow mode caused by user controlled bot(s). // if (CameraInfo.MergedFollowList.Count > 0) { SetUpCameraFollowMode(); break; } // // 5) Free! // // Not following an actor. CameraInfo.Mode = CameraInfo.Modes.Edit; CameraInfo.CameraFocusGameActor = null; // Turn on 3d cursor in case we previously disabled it. parent.cursor3D.Activate(); parent.CreateCursorClone(); parent.cursor3D.Hidden = false; // We have no camera restrictions, so keep track of what the user is doing. shared.camera.PlayValid = true; shared.camera.PlayCameraFrom = shared.camera.From; shared.camera.PlayCameraAt = shared.camera.At; shared.camera.FollowCameraValid = false; // Final break just to be sure the loop exits. break; } // // Now that we're done, we need to check again to see if // we should be in FixedOffsetMode. // if (!Time.Paused && InGame.inGame.Terrain.FixedOffsetCamera && !CameraInfo.FirstPersonActive) { CameraInfo.Mode = CameraInfo.Modes.FixedOffset; } // Zero out any offset while running. float t = Math.Min(Time.GameTimeFrameSeconds, 1.0f); shared.camera.HeightOffset = MyMath.Lerp(shared.camera.HeightOffset, 0.0f, t); // bool inputFocus = CommandStack.Peek() == commandMap; // Move the camera. switch (CameraInfo.Mode) { case CameraInfo.Modes.Edit: MoveCameraEditMode(inputFocus, false); break; case CameraInfo.Modes.Actor: MoveCameraActorMode(true, false); break; case CameraInfo.Modes.FixedTarget: MoveCameraFixedTargetMode(inputFocus); break; case CameraInfo.Modes.FixedOffset: MoveCameraFixedOffsetMode(inputFocus); break; case CameraInfo.Modes.MultiTarget: MoveCameraMultiTargetMode(inputFocus, false); break; } shared.camera.Update(); // Update terrain. parent.terrain.Update(shared.camera); // Update the list of objects using our local camera. for (int i = 0; i < updateList.Count; i++) { UpdateObject obj = (UpdateObject)updateList[i]; obj.Update(); } parent.UpdateObjects(); /// Pregame must update after parent.UpdateObjects, in case it /// decides to switchToMiniHub if (InGame.inGame.preGame != null) { InGame.inGame.preGame.Update(); } // Update the particle system. shared.particleSystemManager.Update(); DistortionManager.Update(); FirstPersonEffectMgr.Update(); // This must be done after all brains are updated. Scoreboard.Update(shared.camera); // Update the TextDisplays. Ignored if not active. shared.scrollableTextDisplay.Update(shared.camera); shared.smallTextDisplay.Update(shared.camera); VictoryOverlay.Update(); // Do the input processing after object update because there will be order of operation issue if we don't // // Check if we have input focus. Don't do any input // related update if we don't. if (inputFocus) { // Grab the current state of the gamepad. GamePadInput pad = GamePadInput.GetGamePad0(); // Switch to Mini-Hub? if (Actions.MiniHub.WasPressed) { Actions.MiniHub.ClearAllWasPressedState(); //parent.ResetSim(CurrentLevelFilename()); // Needed to make sure that deactivated objects are actually removed from // the list otherwise they may get saved along with the newly activated ones. //parent.Refresh(BokuGame.gameListManager.updateList, BokuGame.gameListManager.renderList); parent.SwitchToMiniHub(); return; } //handle swipe to return to edit for touch input if (GamePadInput.ActiveMode == GamePadInput.InputMode.Touch) { SwipeGestureRecognizer swipeGesture = TouchGestureManager.Get().SwipeGesture; if (swipeGesture.WasRecognized && swipeGesture.SwipeDirection == Directions.North) { #if NETFX_CORE float halfWidth = (float)BokuGame.bokuGame.Window.ClientBounds.Width * 0.5f; float height = (float)BokuGame.bokuGame.Window.ClientBounds.Height; #else float halfWidth = (float)XNAControl.Instance.ClientSize.Width * 0.5f; float height = (float)XNAControl.Instance.ClientSize.Height; #endif //center half of the screen width-wise float minX = halfWidth - (halfWidth * k_TouchExitAreaWidthPercent); float maxX = halfWidth + (halfWidth * k_TouchExitAreaWidthPercent); //bottom 20% height-wise float minY = height - (height * k_TouchExitAreaHeightPercent); Vector2 pos = swipeGesture.InitialPosition; if (pos.X >= minX && pos.X <= maxX && pos.Y >= minY) { // User did a swipe from the bottom of the screen, enter edit mode InGame.inGame.CurrentUpdateMode = UpdateMode.EditObject; InGame.inGame.CurrentUpdateMode = UpdateMode.TouchEdit; Foley.PlayPressStart(); return; } } // HACKHACK (****) Put in a tap recognizer since swipe seems to fail. { TapGestureRecognizer hackTapGesture = TouchGestureManager.Get().TapGesture; if (hackTapGesture.WasTapped()) { #if NETFX_CORE float halfWidth = (float)BokuGame.bokuGame.Window.ClientBounds.Width * 0.5f; float height = (float)BokuGame.bokuGame.Window.ClientBounds.Height; #else float halfWidth = (float)XNAControl.Instance.ClientSize.Width * 0.5f; float height = (float)XNAControl.Instance.ClientSize.Height; #endif //center area of the screen width-wise float minX = halfWidth - (halfWidth * 0.1f); float maxX = halfWidth + (halfWidth * 0.1f); //bottom 10% height-wise float minY = height - (height * 0.1f); Vector2 pos = hackTapGesture.Position; if (pos.X >= minX && pos.X <= maxX && pos.Y >= minY) { // User did a tap on the bottom of the screen, enter edit mode InGame.inGame.CurrentUpdateMode = UpdateMode.EditObject; InGame.inGame.CurrentUpdateMode = UpdateMode.TouchEdit; Foley.PlayPressStart(); return; } } } } bool gameOver = VictoryOverlay.GameOver; if (Time.Paused && !gameOver) { // We must be in user induced pause mode. if (Actions.Unpause.WasPressed) { Actions.Unpause.ClearAllWasPressedState(); Time.Paused = false; HelpOverlay.Pop(); } } else { if (gameOver) { // Game over man! Let the user restart if they want. if (Actions.Restart.WasPressed) { Actions.Restart.ClearAllWasPressedState(); InGame.inGame.ResetSim(preserveScores: false, removeCreatablesFromScene: true, keepPersistentScores: false); // Since we're going right back into RunSim mode we need to first inline. ApplyInlining(); } } // Open ToolMenu. if (Actions.ToolMenu.WasPressed) { Actions.ToolMenu.ClearAllWasPressedState(); parent.CurrentUpdateMode = UpdateMode.ToolMenu; Foley.PlayPressStart(); return; } // Pause? // We want to make pause hard to get into so it requires both triggers and both stickButtons to be pressed. if ((pad.LeftStickButton.IsPressed && pad.RightStickButton.IsPressed && pad.LeftTriggerButton.IsPressed && pad.RightTriggerButton.IsPressed) || Actions.Pause.WasPressed) { Actions.Pause.ClearAllWasPressedState(); if (!Time.Paused) { Time.Paused = true; HelpOverlay.Push("PauseGame"); GamePadInput.GetGamePad0().IgnoreLeftStickUntilZero(); GamePadInput.GetGamePad0().IgnoreRightStickUntilZero(); } } } } // Force the the HelpOverlay to be correct. if (!Time.Paused || VictoryOverlay.Active) { if (InGame.inGame.PreGame != null && InGame.inGame.PreGame.Active) { if (HelpOverlay.Depth() != 1 || HelpOverlay.Peek() != "RunSimulationPreGame") { HelpOverlay.Clear(); HelpOverlay.Push("RunSimulationPreGame"); } } else { if (HelpOverlay.Depth() != 1 || HelpOverlay.Peek() != "RunSimulation") { HelpOverlay.Clear(); HelpOverlay.Push("RunSimulation"); } } } else { // We're paused. if (HelpOverlay.Depth() != 2 || HelpOverlay.Peek(1) != "RunSimulation") { HelpOverlay.Clear(); HelpOverlay.Push("RunSimulation"); HelpOverlay.Push("PauseGame"); } } // When in run mode, allow the user to click on the "Press [esc] to edit" text as if it was a button. if (MouseInput.Left.WasPressed) { Point mousePos = MouseInput.Position; if (HelpOverlay.MouseHitBottomText(mousePos)) { // Switch to edit mode. InGame.inGame.CurrentUpdateMode = UpdateMode.EditObject; } } TapGestureRecognizer tapGesture = TouchGestureManager.Get().TapGesture; if (tapGesture.WasTapped()) { // JW - Until we have proper Touch help overlays, we are still using the mouse/keyboard // overlays. The mouse handling code for these depends on being able to 'absorb' pressed // info to hide it from later callers. Our touch stuff doesn't (and really shouldn't) // do this. So, we handle cases here based on what type of overlay is being displayed. if (HelpOverlay.Peek() == "RunSimulationPreGame") { // Tap during instructions: just begin game. InGame.inGame.PreGame.Active = false; } // Also test if running sim for tapping on "tap to edit" at bottom. if (HelpOverlay.Peek() == "RunSimulation") { Point pos = new Point((int)tapGesture.Position.X, (int)tapGesture.Position.Y); if (HelpOverlay.MouseHitBottomText(pos)) { // Switch to edit mode. InGame.inGame.CurrentUpdateMode = UpdateMode.EditObject; } } } } // end of RunSimUpdateObj Update()
/// <summary> /// /// </summary> /// <param name="reflex"></param> /// <param name="param"></param> /// <returns>Return true if the TouchGestureFilter passes. Ignoring the other filters.</returns> public override bool MatchAction(Reflex reflex, out object param) { // Based on gesture type, we check if the gesture has been recognized/performed this frame to see // if this filter may have something to do! bool result = IsPerformed; // ** UNUSED ** // Return as a parameter a vector that can be used for input to the movement system, so // that players can drive and turn bots using mouse buttons. // The touch filters don't have a use for this parameter at this time. param = null; // Did the gesture just begin this frame? Useful for 'once' filters and such. wasPerformed = WasPerformed; if (result) { // If we have a Once modifier, clear it on wasPerformed if (wasPerformed) { for (int i = 0; i < reflex.Modifiers.Count; i++) { OnceModifier om = reflex.Modifiers[i] as OnceModifier; if (om != null) { om.Reset(reflex); } } } // Set the touch position and touch actor based on TouchEdit data and // whether we've hit an actor or not. bool meFilter = reflex.Data.FilterExists("filter.me"); if (TouchEdit.HitInfo.ActorHit != null) { reflex.TouchPosition = TouchEdit.HitInfo.ActorPosition; reflex.TouchActor = TouchEdit.HitInfo.ActorHit; } else { reflex.TouchActor = null; if (!meFilter) { reflex.TouchPosition = TouchEdit.HitInfo.TerrainPosition; } else { reflex.TouchPosition = null; } } // Gesture-type specific behavior goes here. if (type == TouchGestureFilterType.Rotate) { deltaRotation = TouchGestureManager.Get().RotateGesture.RotationDelta; } else if (type == TouchGestureFilterType.Swipe) { direction = TouchGestureManager.Get().SwipeGesture.SwipeDirection; } else if (type == TouchGestureFilterType.Slide) { // Slide is unique in that it cares about what actor you began the slide on, not where // you are now. The touch position is your current touch position, however. // Here we override the TouchActor set above. reflex.TouchPosition = TouchEdit.HitInfo.TerrainPosition; reflex.TouchActor = TouchInput.InitialActorHit; } else if (type == TouchGestureFilterType.Tap) { tapPosition = TouchGestureManager.Get().TapGesture.Position; } else if (type == TouchGestureFilterType.Touching) { } } // Don't hold onto a ref to a dead bot. if (reflex.TouchActor != null && reflex.TouchActor.CurrentState == GameThing.State.Inactive) { reflex.TouchActor = null; reflex.TouchPosition = null; } return(result); }