public override void Update() { Cube?.Transform.Rotate(new Vector3(MathUtil.DegreesToRadians(60) * Game.GetDeltaTime(), 0, 0)); DebugText.Print($"Screen {MainCamera.WorldToScreen(Entity.Transform.Position)}", new Int2(20, 20)); DebugText.Print($"ScreenToWorldRaySegment {MainCamera.ScreenToWorldRaySegment(Input.MousePosition)}", new Int2(20, 40)); if (Input.IsMouseButtonPressed(MouseButton.Left)) { _message = ""; var ray = MainCamera.ScreenToWorldRaySegment(Input.MousePosition); var hitResult = this.GetSimulation().Raycast(ray); if (hitResult.Succeeded) { _message = hitResult.Collider.Entity.Name; MainCamera.Entity.Transform.LookAt(hitResult.Collider.Entity.Transform); TargetAcquired.Broadcast(hitResult.Collider.Entity); } else { TargetAcquired.Broadcast(null); } DebugText.Print($"Clicked on {_message}", new Int2(20, 60)); } //DebugText.Print($"Main {SceneSystem.GetMainCamera() != null}", new Int2(20, 40)); }
private void Move(float maxRunSpeed) { if (!_isRunning) { RunSpeedEventKey.Broadcast(0); return; } UpdateMoveTowardsDestination(maxRunSpeed); }
/// <summary> /// Jump makes the character jump and also accounts for the player's reaction time, making jumping feel more natural by /// allowing jumps within some limit of the last time the character was on the ground /// </summary> private void Jump() { var dt = this.GetSimulation().FixedTimeStep; // Check if conditions allow the character to jump if (JumpReactionThreshold <= 0) { // No reaction threshold. The character can only jump if grounded if (!character.IsGrounded) { IsGroundedEventKey.Broadcast(false); return; } } else { // If there is still enough time left for jumping allow the character to jump even when not grounded if (jumpReactionRemaining > 0) { jumpReactionRemaining -= dt; } // If the character on the ground reset the jumping reaction time if (character.IsGrounded) { jumpReactionRemaining = JumpReactionThreshold; } // If there is no more reaction time left don't allow the character to jump if (jumpReactionRemaining <= 0) { IsGroundedEventKey.Broadcast(character.IsGrounded); return; } } // If the player didn't press a jump button we don't need to jump bool didJump; jumpEvent.TryReceive(out didJump); if (!didJump) { IsGroundedEventKey.Broadcast(true); return; } // Jump!! jumpReactionRemaining = 0; character.Jump(); // Broadcast that the character is jumping! IsGroundedEventKey.Broadcast(false); }
public override void Update() { if (!menuOpen && Input.HasMouse && Input.IsMouseButtonReleased(Stride.Input.MouseButton.Left)) { if (Raycaster.CheckForHits(Input.MousePosition, Camera, this.GetSimulation(), out var result)) { OnClickable.Broadcast(result); } else { OnClickable.Broadcast(Raycaster.ClickResult.Empty); } } }
public override async Task Execute() { var trigger = Entity.Get <PhysicsComponent>(); trigger.ProcessCollisions = true; // Start state machine while (Game.IsRunning) { var firstCollision = await trigger.NewCollision(); var oneContact = firstCollision.Contacts.First(); var shockNormal = oneContact.Normal; if (oneContact.ColliderA.Entity != Entity) { shockNormal *= -1; } var _2dnormal = shockNormal; _2dnormal.Z = 0.0f; var shock = new Shock { Entity = Entity, Normal = _2dnormal }; BrickHit.Broadcast(shock); } }
private void Move() { // Character speed moveDirectionEvent.TryReceive(out Vector3 moveDirection); if (character.IsGrounded) { character.SetVelocity(moveDirection * MaxRunSpeed); aerialVelocity = moveDirection * MaxRunSpeed; } else { character.SetVelocity( aerialVelocity ); // aerialVelocity *= 0.7f; } if (Input.IsKeyPressed(Keys.Space)) { var rb = this.Entity.Get <CharacterComponent>(); if (rb.IsGrounded) { rb.Jump(Vector3.UnitY * 10.0f); } } // Broadcast normalized speed RunSpeedEventKey.Broadcast(moveDirection.Length()); }
public override void Update() { if (Conduct == Current.ON) { DebugText.Print(Entity.Name + " has " + collisionNumber + "collisions", new Int2(900, 25 * (int)Entity.Name.Length)); } int temp = CountCollision(); if (collisionNumber != temp) { currentChange.Broadcast(); collisionNumber = temp; } }
public void ReceiveManyCheck() { var game = new EventSystemTest(); var frameCount = 0; game.AddTask(async() => { var evt = new EventKey(); var rcv = new EventReceiver(evt, EventReceiverOptions.Buffered); while (frameCount < 25) { evt.Broadcast(); if (frameCount == 20) { var manyEvents = rcv.TryReceiveAll(); Assert.Equal(21, manyEvents); game.Exit(); } await game.NextFrame(); frameCount++; } }); game.Run(); }
public void SameFrameReceiveAsync() { var test = new EventSystemTest(); var frameCounter = 0; test.AddTask(async() => { while (test.IsRunning) { frameCounter++; await test.NextFrame(); } }, 100); test.AddTask(async() => { var key = new EventKey(); var recv = new EventReceiver(key); key.Broadcast(); var currentFrame = frameCounter; await recv.ReceiveAsync(); Assert.Equal(currentFrame, frameCounter); test.Exit(); }); test.Run(); }
public override async Task Execute() { PhysicsComponent trigger = Entity.Get <PhysicsComponent>(); //trigger.ProcessCollisions = true; while (Game.IsRunning) { // Wait for the next collision event Collision firstCollision = await trigger.NewCollision(); // Filter collisions based on collision groups int filterAhitB = ((int)firstCollision.ColliderA.CanCollideWith) & ((int)firstCollision.ColliderB.CollisionGroup); int filterBhitA = ((int)firstCollision.ColliderB.CanCollideWith) & ((int)firstCollision.ColliderA.CollisionGroup); if (filterAhitB == 0 || filterBhitA == 0) { continue; } // Broadcast the collision start event if (TriggerCondition == CollisionEventType.StartOnly || TriggerCondition == CollisionEventType.StartAndEnd) { TriggerEvent.Broadcast(true); } if (TriggerCondition == CollisionEventType.StartOnly) { continue; } // Wait for the collision to end and broadcast that event Func <Task> collisionEndTask = async() => { Collision collision; do { collision = await trigger.CollisionEnded(); } while (collision != firstCollision); TriggerEvent.Broadcast(false); }; Script.AddTask(collisionEndTask); } }
/// <summary> /// Called on every frame update /// </summary> public override void Update() { bool didShoot; shootEvent.TryReceive(out didShoot); bool didReload; reloadEvent.TryReceive(out didReload); cooldownRemaining = (cooldownRemaining > 0) ? (cooldownRemaining - this.GetSimulation().FixedTimeStep) : 0f; if (cooldownRemaining > 0) { return; // Can't shoot yet } if ((remainingBullets == 0 && didShoot) || (remainingBullets < 9 && didReload)) { ReloadWeapon(); return; } if (!didShoot) { return; } remainingBullets--; UpdateBulletsLED(); cooldownRemaining = Cooldown; var raycastStart = Entity.Transform.WorldMatrix.TranslationVector; var forward = Entity.Transform.WorldMatrix.Forward; var raycastEnd = raycastStart + forward * MaxShootDistance; var result = this.GetSimulation().Raycast(raycastStart, raycastEnd); var weaponFired = new WeaponFiredResult { HitResult = result, DidFire = true, DidHit = false }; if (result.Succeeded && result.Collider != null) { weaponFired.DidHit = true; var rigidBody = result.Collider as RigidbodyComponent; if (rigidBody != null) { rigidBody.Activate(); rigidBody.ApplyImpulse(forward * ShootImpulse); rigidBody.ApplyTorqueImpulse(forward * ShootImpulse + new Vector3(0, 1, 0)); } } // Broadcast the fire event WeaponFired.Broadcast(weaponFired); }
public void SameFrameReceive() { var key = new EventKey(); var recv = new EventReceiver(key); key.Broadcast(); Assert.True(recv.TryReceive()); Assert.False(recv.TryReceive()); }
public override void Update() { var handsInput = new HandsInput(); handsInput.HandMovement[(int)HandSide.Left] = AsWorldVector(Input.GetLeftThumb(ControllerIndex)); handsInput.HandMovement[(int)HandSide.Right] = AsWorldVector(Input.GetRightThumb(ControllerIndex)); handsInput.HandGrab[(int)HandSide.Left] = Input.GetLeftTrigger(ControllerIndex); handsInput.HandGrab[(int)HandSide.Right] = Input.GetRightTrigger(ControllerIndex); HandsControlEventKey.Broadcast(handsInput); }
private void Move() { // Character speed Vector3 moveDirection = Vector3.Zero; moveDirectionEvent.TryReceive(out moveDirection); character.SetVelocity(moveDirection * MaxRunSpeed); // Broadcast normalized speed RunSpeedEventKey.Broadcast(moveDirection.Length()); }
public void EveryFrameClear() { var game = new EventSystemTest(); var frameCount = 0; var evt = new EventKey(); game.AddTask(async() => { while (frameCount < 25) { evt.Broadcast(); evt.Broadcast(); await game.NextFrame(); } }, 10); game.AddTask(async() => { var rcv = new EventReceiver(evt, EventReceiverOptions.Buffered); while (frameCount < 25) { if (frameCount == 20) { var manyEvents = rcv.TryReceiveAll(); Assert.Equal(2, manyEvents); game.Exit(); } rcv.Reset(); await game.NextFrame(); frameCount++; } }, -10); game.Run(); }
public override void Update() { if (Input.IsMouseButtonPressed(MouseButton.Left)) { EventOne.Broadcast(Input.MousePosition); } if (Input.IsMouseButtonPressed(MouseButton.Right)) { EventTwo.Broadcast(Input.MousePosition); } }
private void TreatShock(Shock shock) { foreach (var c in Callbacks) { c(shock); } SceneSystem.SceneInstance.RootScene.Entities.Remove(shock.Entity); SceneSystem.SceneInstance.RootScene.Entities.First(e => e.Name == "global script holder") .Components.Get <Level1>().SignalDeletedBrick(shock.Entity); ShockTreatedEK.Broadcast(); }
public override async Task Execute() { var trigger = Entity.Get <PhysicsComponent>(); trigger.ProcessCollisions = true; //start out state machine while (Game.IsRunning) { //wait for entities coming in var firstCollision = await trigger.NewCollision(); TriggerEvent.Broadcast(true); //now wait for entities exiting Collision collision; do { collision = await trigger.CollisionEnded(); } while (collision != firstCollision); TriggerEvent.Broadcast(false); } }
public void DelayedReceiverCreation() { var game = new EventSystemTest(); var frameCount = 0; game.AddTask(async() => { var evt = new EventKey(); EventReceiver rcv = null; while (frameCount < 25) { if (frameCount == 5) { evt.Broadcast(); } if (frameCount == 20) { rcv = new EventReceiver(evt); Assert.False(rcv.TryReceive()); evt.Broadcast(); } if (frameCount == 22) { Assert.NotNull(rcv); Assert.True(rcv.TryReceive()); game.Exit(); } await game.NextFrame(); frameCount++; } }); game.Run(); }
public void ReceiveFirstCheck() { var game = new EventSystemTest(); var frameCount = 0; var evt1 = new EventKey(); var evt2 = new EventKey(); game.AddTask(async() => { var rcv1 = new EventReceiver(evt1); var rcv2 = new EventReceiver(evt2); for (;;) { var rcv = await EventReceiver.ReceiveOne(rcv1, rcv2); if (rcv.Receiver == rcv1) { evt2.Broadcast(); //this is the point of this test.. see if t2 will get populated next loop await game.NextFrame(); } else if (rcv.Receiver == rcv2) { await game.NextFrame(); game.Exit(); } } }); game.AddTask(async() => { while (frameCount < 30 && game.IsRunning) { frameCount++; if (frameCount == 20) { evt1.Broadcast(); } await game.NextFrame(); } Assert.True(false, "t2 should be completed"); }); }
public override void Update(GameTime time) { if (ComponentDatas.Count == 0) { completed = false; } else { if (ComponentDatas.All(kvp => kvp.Key.Completed)) { if (!completed) { AllTasksCompleted.Broadcast(); } completed = true; } } }
private void Move(float speed) { // Character speed moveDirectionEvent.TryReceive(out Vector3 newMoveDirection); // Allow very simple inertia to the character to make animation transitions more fluid moveDirection = (moveDirection * 0.85f) + (newMoveDirection * 0.15f); character.SetVelocity(moveDirection * speed); // Broadcast speed as per cent of the max speed RunSpeedEventKey.Broadcast(moveDirection.Length()); // Character orientation if (moveDirection.Length() > 0.001) { yawOrientation = MathUtil.RadiansToDegrees((float)Math.Atan2(-moveDirection.Z, moveDirection.X) + MathUtil.PiOverTwo); } modelChildEntity.Transform.Rotation = Quaternion.RotationYawPitchRoll(MathUtil.DegreesToRadians(yawOrientation), 0, 0); }
private void ReloadWeapon() { IsReloading.Broadcast(true); Func <Task> reloadTask = async() => { // Countdown var secondsCountdown = cooldownRemaining = ReloadCooldown; while (secondsCountdown > 0f) { await Script.NextFrame(); secondsCountdown -= (float)Game.UpdateTime.Elapsed.TotalSeconds; } remainingBullets = 9; UpdateBulletsLED(); }; Script.AddTask(reloadTask); }
public override void Update() { // Condition 1 - the trigger can be a key press var isTriggered = Input.IsKeyPressed(Key); // Condition 2 - the trigger can be a time interval if (TimeInterval > 0) { timeIntervalCountdown -= (float)Game.UpdateTime.Elapsed.TotalSeconds; if (timeIntervalCountdown <= 0f) { timeIntervalCountdown = TimeInterval; isTriggered = true; } } if (!isTriggered) { return; } EventKey.Broadcast(EventName); }
private void MoveBall() { var dt = Game.DrawTime.Elapsed; var hLimit = 7; if (Entity.Transform.Position.X > hLimit || Entity.Transform.Position.X < -hLimit) { var right = Math.Sign(Entity.Transform.Position.X); Rebound(new Vector3(-right, 0.0f, 0.0f)); // set at free position Entity.Transform.Position = new Vector3(hLimit * right, Entity.Transform.Position.Y, Entity.Transform.Position.Z); } var verticalLimit = 5; var touchedBottom = Entity.Transform.Position.Y < -verticalLimit; if (Entity.Transform.Position.Y > verticalLimit || touchedBottom) { var top = Math.Sign(Entity.Transform.Position.Y); Rebound(new Vector3(0.0f, -top, 0.0f)); // set at free position Entity.Transform.Position = new Vector3(Entity.Transform.Position.X, verticalLimit * top, Entity.Transform.Position.Z); } if (touchedBottom) { // signal game lost. BallLostEK.Broadcast(); } var oldpos = Entity.Transform.Position; oldpos += ballSpeed * (float)dt.TotalSeconds; Entity.Transform.Position = oldpos; }
private void Attack() { var dt = (float)Game.UpdateTime.Elapsed.TotalSeconds; attackCooldown = (attackCooldown > 0) ? attackCooldown - dt : 0f; PunchCollision.Enabled = (attackCooldown > 0); if (attackEntity == null) { return; } var directionToCharacter = attackEntity.Transform.WorldMatrix.TranslationVector - modelChildEntity.Transform.WorldMatrix.TranslationVector; directionToCharacter.Y = 0; var currentDistance = directionToCharacter.Length(); if (currentDistance <= AttackDistance) { // Attack! HaltMovement(); attackEntity = null; attackCooldown = AttackCooldown; PunchCollision.Enabled = true; IsAttackingEventKey.Broadcast(true); } else { isRunning = true; directionToCharacter.Normalize(); moveDestination = attackEntity.Transform.WorldMatrix.TranslationVector; } }
public override void Update() { // Character movement: should be camera-aware { // Left stick: movement var moveDirection = Input.GetLeftThumbAny(DeadZone); // Keyboard: movement if (KeysLeft.Any(key => Input.IsKeyDown(key))) { moveDirection += -Vector2.UnitX; } if (KeysRight.Any(key => Input.IsKeyDown(key))) { moveDirection += +Vector2.UnitX; } if (KeysUp.Any(key => Input.IsKeyDown(key))) { moveDirection += +Vector2.UnitY; } if (KeysDown.Any(key => Input.IsKeyDown(key))) { moveDirection += -Vector2.UnitY; } // Broadcast the movement vector as a world-space Vector3 to allow characters to be controlled var worldSpeed = (Camera != null) ? Utils.LogicDirectionToWorldDirection(moveDirection, Camera, Vector3.UnitY) : new Vector3(moveDirection.X, 0, moveDirection.Y); // Adjust vector's magnitute - worldSpeed has been normalized var moveLength = moveDirection.Length(); var isDeadZoneLeft = moveLength < DeadZone; if (isDeadZoneLeft) { worldSpeed = Vector3.Zero; } else { if (moveLength > 1) { moveLength = 1; } else { moveLength = (moveLength - DeadZone) / (1f - DeadZone); } worldSpeed *= moveLength; } MoveDirectionEventKey.Broadcast(worldSpeed); } // Camera rotation: left-right rotates the camera horizontally while up-down controls its altitude { // Right stick: camera rotation var cameraDirection = Input.GetRightThumbAny(DeadZone); var isDeadZoneRight = cameraDirection.Length() < DeadZone; if (isDeadZoneRight) { cameraDirection = Vector2.Zero; } else { cameraDirection.Normalize(); } // Mouse-based camera rotation. Only enabled after you click the screen to lock your cursor, pressing escape cancels this if (Input.IsMouseButtonDown(MouseButton.Left)) { Input.LockMousePosition(true); Game.IsMouseVisible = false; } if (Input.IsKeyPressed(Keys.Escape)) { Input.UnlockMousePosition(); Game.IsMouseVisible = true; } if (Input.IsMousePositionLocked) { cameraDirection += new Vector2(Input.MouseDelta.X, -Input.MouseDelta.Y) * MouseSensitivity; } // Broadcast the camera direction directly, as a screen-space Vector2 CameraDirectionEventKey.Broadcast(cameraDirection); } // Jumping: don't bother with jump restrictions here, just pass the button states { // Controller: jumping var isJumpDown = Input.IsGamePadButtonDownAny(GamePadButton.A); var didJump = (!jumpButtonDown && isJumpDown); jumpButtonDown = isJumpDown; // Keyboard: jumping didJump |= (KeysJump.Any(key => Input.IsKeyPressed(key))); JumpEventKey.Broadcast(didJump); } }
public void DifferentSyntax() { var game = new EventSystemTest(); var frameCounter = 0; var broadcaster = new EventKey(); game.AddTask(async () => { var tests = 5; var recv = new EventReceiver(broadcaster); var threadId = Thread.CurrentThread.ManagedThreadId; while (tests-- > 0) { await recv; Assert.AreEqual(threadId, Thread.CurrentThread.ManagedThreadId); } }); game.AddTask(async () => { var tests = 5; var recv = new EventReceiver(broadcaster); var threadId = Thread.CurrentThread.ManagedThreadId; while (tests-- > 0) { await recv; Assert.AreEqual(threadId, Thread.CurrentThread.ManagedThreadId); } }); game.AddTask(async () => { var tests = 5; var recv = new EventReceiver(broadcaster); var threadId = Thread.CurrentThread.ManagedThreadId; while (tests-- > 0) { await recv; Assert.AreEqual(threadId, Thread.CurrentThread.ManagedThreadId); } }); Task.Run(async () => { while (!game.IsRunning) { await Task.Delay(100); } while (true) { frameCounter++; broadcaster.Broadcast(); if (frameCounter == 20) { game.Exit(); } await Task.Delay(50); } }); game.Run(); }
public void ReceiveManyCheck() { var game = new EventSystemTest(); var frameCount = 0; game.AddTask(async () => { var evt = new EventKey(); var rcv = new EventReceiver(evt, EventReceiverOptions.Buffered); while (frameCount < 25) { evt.Broadcast(); if (frameCount == 20) { var manyEvents = rcv.TryReceiveAll(); Assert.AreEqual(manyEvents, 21); game.Exit(); } await game.NextFrame(); frameCount++; } }); game.Run(); }
public void EveryFrameClear() { var game = new EventSystemTest(); var frameCount = 0; var evt = new EventKey(); game.AddTask(async () => { while (frameCount < 25) { evt.Broadcast(); evt.Broadcast(); await game.NextFrame(); } }, 10); game.AddTask(async () => { var rcv = new EventReceiver(evt, EventReceiverOptions.Buffered); while (frameCount < 25) { if (frameCount == 20) { var manyEvents = rcv.TryReceiveAll(); Assert.AreEqual(2, manyEvents); game.Exit(); } rcv.Reset(); await game.NextFrame(); frameCount++; } }, -10); game.Run(); }
public void DifferentSyntax() { var game = new EventSystemTest(); var frameCounter = 0; var broadcaster = new EventKey(); game.AddTask(async() => { var tests = 5; var recv = new EventReceiver(broadcaster); var threadId = Thread.CurrentThread.ManagedThreadId; while (tests-- > 0) { await recv; Assert.Equal(threadId, Thread.CurrentThread.ManagedThreadId); } }); game.AddTask(async() => { var tests = 5; var recv = new EventReceiver(broadcaster); var threadId = Thread.CurrentThread.ManagedThreadId; while (tests-- > 0) { await recv; Assert.Equal(threadId, Thread.CurrentThread.ManagedThreadId); } }); game.AddTask(async() => { var tests = 5; var recv = new EventReceiver(broadcaster); var threadId = Thread.CurrentThread.ManagedThreadId; while (tests-- > 0) { await recv; Assert.Equal(threadId, Thread.CurrentThread.ManagedThreadId); } }); Task.Run(async() => { while (!game.IsRunning) { await Task.Delay(100); } while (true) { frameCounter++; broadcaster.Broadcast(); if (frameCounter == 20) { game.Exit(); } await Task.Delay(50); } }); game.Run(); }
public void DifferentThreadBroadcast() { var game = new EventSystemTest(); var counter = 0; var broadcaster = new EventKey(); var readyCount = 0; game.AddTask(async () => { var recv = new EventReceiver(broadcaster, EventReceiverOptions.Buffered); Interlocked.Increment(ref readyCount); for (;;) { await recv.ReceiveAsync(); Interlocked.Increment(ref counter); } }); game.AddTask(async () => { var recv = new EventReceiver(broadcaster, EventReceiverOptions.Buffered); Interlocked.Increment(ref readyCount); for (;;) { await recv.ReceiveAsync(); Interlocked.Increment(ref counter); } }); game.AddTask(async () => { var recv = new EventReceiver(broadcaster, EventReceiverOptions.Buffered); Interlocked.Increment(ref readyCount); for (;;) { await recv.ReceiveAsync(); Interlocked.Increment(ref counter); } }); var t1W = new AutoResetEvent(false); var t2W = new AutoResetEvent(false); var waitHandles = new WaitHandle[] { t1W, t2W }; Exception threadException = null; new Thread(() => { try { while (!game.IsRunning && readyCount < 3) { Thread.Sleep(200); } var frameCounter = 0; while (true) { Thread.Sleep(50); frameCounter++; broadcaster.Broadcast(); if (frameCounter < 200) continue; t1W.Set(); return; } } catch (Exception e) { threadException = e; } }).Start(); new Thread(() => { try { while (!game.IsRunning && readyCount < 3) { Thread.Sleep(200); } var frameCounter = 0; while (true) { Thread.Sleep(50); frameCounter++; broadcaster.Broadcast(); if (frameCounter < 200) continue; t2W.Set(); return; } } catch (Exception e) { threadException = e; } }).Start(); new Thread(() => { try { //wait until both threads have broadcasted 200 times each if (!WaitHandle.WaitAll(waitHandles, TimeSpan.FromMinutes(2))) { throw new Exception("DifferentThreadBroadcast test timedout."); } Thread.Sleep(2000); game.Exit(); } catch (Exception e) { threadException = e; } }).Start(); game.Run(); Assert.IsNull(threadException); Assert.AreEqual(1200, counter); }
public void SameFrameReceiveAsync() { var test = new EventSystemTest(); var frameCounter = 0; test.AddTask(async () => { while (test.IsRunning) { frameCounter++; await test.NextFrame(); } }, 100); test.AddTask(async () => { var key = new EventKey(); var recv = new EventReceiver(key); key.Broadcast(); var currentFrame = frameCounter; await recv.ReceiveAsync(); Assert.AreEqual(currentFrame, frameCounter); test.Exit(); }); test.Run(); }
public override void Update() { // Character movement // The character movement can be controlled by a game controller or a keyboard // The character receives input in 3D world space, so that it can be controlled by an AI script as well // For this reason we map the 2D user input to a 3D movement using the current camera { // Game controller: left stick var moveDirection = Input.GetLeftThumbAny(DeadZone); var isDeadZoneLeft = moveDirection.Length() < DeadZone; if (isDeadZoneLeft) { moveDirection = Vector2.Zero; } else { moveDirection.Normalize(); } // Keyboard if (KeysLeft.Any(key => Input.IsKeyDown(key))) { moveDirection += -Vector2.UnitX; } if (KeysRight.Any(key => Input.IsKeyDown(key))) { moveDirection += +Vector2.UnitX; } if (KeysUp.Any(key => Input.IsKeyDown(key))) { moveDirection += +Vector2.UnitY; } if (KeysDown.Any(key => Input.IsKeyDown(key))) { moveDirection += -Vector2.UnitY; } // Broadcast the movement vector as a world-space Vector3 to allow characters to be controlled var worldSpeed = (Camera != null) ? Utils.LogicDirectionToWorldDirection(moveDirection, Camera, Vector3.UnitY) : new Vector3(moveDirection.X, 0, moveDirection.Y); // If we don't have the correct camera attached we can send the directions anyway, but they probably won't match MoveDirectionEventKey.Broadcast(worldSpeed); } // Camera rotation // Camera rotation is ALWAYS in camera space, so we don't need to account for View or Projection matrices { // Game controller: right stick var cameraDirection = Input.GetRightThumbAny(DeadZone); var isDeadZoneRight = cameraDirection.Length() < DeadZone; if (isDeadZoneRight) { cameraDirection = Vector2.Zero; } else { cameraDirection.Normalize(); } // Mouse-based camera rotation. // Only enabled after you click the screen to lock your cursor, pressing escape will cancel it. if (Input.IsMouseButtonDown(MouseButton.Left)) { Input.LockMousePosition(true); Game.IsMouseVisible = false; } if (Input.IsKeyPressed(Keys.Escape)) { Input.UnlockMousePosition(); Game.IsMouseVisible = true; } if (Input.IsMousePositionLocked) { cameraDirection += new Vector2(Input.MouseDelta.X, -Input.MouseDelta.Y) * MouseSensitivity; } // Broadcast the camera direction directly, as a screen-space Vector2 CameraDirectionEventKey.Broadcast(cameraDirection); } { // Controller: Right trigger // Mouse: Left button, Tap events var didShoot = Input.GetRightTriggerAny(0.2f) > 0.2f; // This will allow for continuous shooting if (Input.PointerEvents.Any(x => x.EventType == PointerEventType.Pressed)) { didShoot = true; } if (Input.HasMouse && Input.IsMouseButtonDown(MouseButton.Left)) // This will allow for continuous shooting { didShoot = true; } ShootEventKey.Broadcast(didShoot); } { // Reload weapon var isReloading = Input.IsGamePadButtonDownAny(GamePadButton.X); if (KeysReload.Any(key => Input.IsKeyDown(key))) { isReloading = true; } ReloadEventKey.Broadcast(isReloading); } }
public void DifferentThreadBroadcast() { var game = new EventSystemTest(); var counter = 0; var broadcaster = new EventKey(); var readyCount = 0; game.AddTask(async() => { var recv = new EventReceiver(broadcaster, EventReceiverOptions.Buffered); Interlocked.Increment(ref readyCount); for (;;) { await recv.ReceiveAsync(); Interlocked.Increment(ref counter); } }); game.AddTask(async() => { var recv = new EventReceiver(broadcaster, EventReceiverOptions.Buffered); Interlocked.Increment(ref readyCount); for (;;) { await recv.ReceiveAsync(); Interlocked.Increment(ref counter); } }); game.AddTask(async() => { var recv = new EventReceiver(broadcaster, EventReceiverOptions.Buffered); Interlocked.Increment(ref readyCount); for (;;) { await recv.ReceiveAsync(); Interlocked.Increment(ref counter); } }); var t1W = new AutoResetEvent(false); var t2W = new AutoResetEvent(false); var waitHandles = new WaitHandle[] { t1W, t2W }; Exception threadException = null; new Thread(() => { try { while (!game.IsRunning && readyCount < 3) { Thread.Sleep(200); } var frameCounter = 0; while (true) { Thread.Sleep(50); frameCounter++; broadcaster.Broadcast(); if (frameCounter < 200) { continue; } t1W.Set(); return; } } catch (Exception e) { threadException = e; } }).Start(); new Thread(() => { try { while (!game.IsRunning && readyCount < 3) { Thread.Sleep(200); } var frameCounter = 0; while (true) { Thread.Sleep(50); frameCounter++; broadcaster.Broadcast(); if (frameCounter < 200) { continue; } t2W.Set(); return; } } catch (Exception e) { threadException = e; } }).Start(); new Thread(() => { try { //wait until both threads have broadcasted 200 times each if (!WaitHandle.WaitAll(waitHandles, TimeSpan.FromMinutes(2))) { throw new Exception("DifferentThreadBroadcast test timedout."); } Thread.Sleep(2000); game.Exit(); } catch (Exception e) { threadException = e; } }).Start(); game.Run(); Assert.Null(threadException); Assert.Equal(1200, counter); }
public void ReceiveFirstCheck() { var game = new EventSystemTest(); var frameCount = 0; var evt1 = new EventKey(); var evt2 = new EventKey(); game.AddTask(async () => { var rcv1 = new EventReceiver(evt1); var rcv2 = new EventReceiver(evt2); for (;;) { var rcv = await EventReceiver.ReceiveOne(rcv1, rcv2); if (rcv.Receiver == rcv1) { evt2.Broadcast(); //this is the point of this test.. see if t2 will get populated next loop await game.NextFrame(); } else if (rcv.Receiver == rcv2) { await game.NextFrame(); game.Exit(); } } }); game.AddTask(async () => { while (frameCount < 30 && game.IsRunning) { frameCount++; if (frameCount == 20) { evt1.Broadcast(); } await game.NextFrame(); } Assert.Fail("t2 should be completed"); }); }
public void DelayedReceiverCreation() { var game = new EventSystemTest(); var frameCount = 0; game.AddTask(async () => { var evt = new EventKey(); EventReceiver rcv = null; while (frameCount < 25) { if (frameCount == 5) { evt.Broadcast(); } if (frameCount == 20) { rcv = new EventReceiver(evt); Assert.False(rcv.TryReceive()); evt.Broadcast(); } if (frameCount == 22) { Assert.NotNull(rcv); Assert.True(rcv.TryReceive()); game.Exit(); } await game.NextFrame(); frameCount++; } }); game.Run(); }