/// <summary> /// Handle a movement of the gaze point. /// </summary> /// <param name="sender"></param> /// <param name="e"></param> internal void OnGazeMove(object sender, GazeEventArgs e) { // add the gaze point to the history, keep a queue of 10 values gazeHistory.Enqueue(e.Point.X); if (gazeHistory.Count > 10) { gazeHistory.Dequeue(); } // calculate average gaze position var average = gazeHistory.Average(x => x); // move the paddle so its center aligns with the average location _pos.X = (int)average - _size.Width / 2; }
/// <summary> /// Calculate the current gaze point. /// </summary> /// <param name="sender"></param> /// <param name="e"></param> static void OnGazeMove(object sender, GazeEventArgs e) { // read the image from the sequence reader var frame = new RawImage(reader.GetNextImage()); var grayFrame = new RawImage(reader.GetCurrentFrameGray()); // only detect faces every 5 frames if (currentFace == default(Rect) || frameIndex % 5 == 0) { // detect face var faces = new List <System.Windows.Rect>(); var confidences = new List <double>(); faceDetector.DetectFacesHOG(faces, grayFrame, confidences); var face = faces.FirstOrDefault(); // remember where we saw the face if (face != default(Rect)) { currentFace = face; } } // detect landmarks var success = landmarkDetector.DetectLandmarksInVideo(grayFrame, faceModel); // calculate gaze angle gazeAnalyser.AddNextFrame(landmarkDetector, success, reader.GetFx(), reader.GetFy(), reader.GetCx(), reader.GetCy()); var gaze = gazeAnalyser.GetGazeAngle(); // convert gaze to a point coordinate e.Point.X = (int)(5000 * Math.Tan(-gaze.Item1) + form.Width / 2); e.Point.Y = form.Height / 2; // update frame counter frameIndex++; }
/// <summary> /// Calculate the current gaze point. /// </summary> /// <param name="sender"></param> /// <param name="e"></param> static void OnGazeMove(object sender, GazeEventArgs e) { // ****************** // ADD YOUR CODE HERE // ****************** }
/// <summary> /// Update the game board. /// </summary> /// <param name="sender"></param> /// <param name="e"></param> void tmr_Tick(object sender, EventArgs e) { // get the current gaze point var gea = new GazeEventArgs(); OnGazeMove?.Invoke(this, gea); // perform calibration for one second var interval = ((Timer)sender).Interval; if (_frameIndex < 1000 / interval) { gazeOffset.X -= (_dot._pos.X - this.Width / 2); } // after the calibration period, kill the circle and text and start the game else { if (!_circle.IsDead) { _circle.IsDead = true; _text.IsDead = true; Invalidate(_circle.GetRect()); Invalidate(_text.GetRect()); } } // apply offset to gaze point gea.Point.X += gazeOffset.X; // move the paddle Invalidate(_paddle.GetRect()); _paddle.OnGazeMove(this, gea); Invalidate(_paddle.GetRect()); // move the gaze dot Invalidate(_dot.GetRect()); _dot._pos.X = gea.Point.X; Invalidate(_dot.GetRect()); Point res; for (int iBall = 0; iBall < _NumBalls; iBall++) { // check if the ball is alive var ball = _balls[iBall]; if (!ball.IsDead) { // detect collisions with the wall res = DetectCollision(ball, ClientRectangle, fShouldBeInside: true); if (res.X == 0 && res.Y == 0) { // detect colissions with the paddle res = DetectCollision(ball, _paddle.GetRect(), fShouldBeInside: false); if (res.X == 0 && res.Y == 0) { // all blocks gone? if (_numBlocksAlive == 0) { // increment level _nLevels++; // build more blocks _nBlocksY++; // bring all balls back to life int nBallsToBringBackToLife = 0; for (int i = 0; i < _NumBalls; i++) { if (_balls[i].IsDead) { _balls[i].IsDead = false; _balls[i]._pos.X = 100 + 10 * i; _balls[i]._pos.Y = 100 + 10 * i; _NumBallsAlive++; Invalidate(_balls[i].GetRect()); if (++nBallsToBringBackToLife == 3) { break; } } } // recreate the blocks CreateBlocks(); } // some blocks remaining else { // detect collision with any block for (int i = 0; i < _nBlocksX; i++) { for (int j = 0; j < _nBlocksY; j++) { if (!_blocks[i, j].IsDead) { res = DetectCollision(ball, _blocks[i, j].GetRect(), fShouldBeInside: false); if (res.X != 0 || res.Y != 0) { // kill the block _blocks[i, j].IsDead = true; _numBlocksAlive--; _Score++; Invalidate(_blocks[i, j].GetRect()); } } } } } } // ball hit the paddle else { // bounce handled elsewhere } } // ball hit the wall else { // if the ball hit the bottom wall, it's dead if (res.Y == -1) { ball.IsDead = true; Invalidate(ball.GetRect()); _NumBallsAlive--; } } // update the ball position Invalidate(ball.GetRect()); ball._pos.X += ball._velocity.X; ball._pos.Y += ball._velocity.Y; Invalidate(ball.GetRect()); } } // stop the timer if all balls are dead if (_NumBallsAlive == 0) { this._timer.Enabled = false; } // update the frame counter _frameIndex++; // update game status this.Text = string.Format( "Score = {0} # Levels = {1} # of balls left = {2}", _Score, _nLevels, _NumBallsAlive); }