Comparing touches with targets

Now that we have a list of touches that can be examined at will, we need to add logic to compare those touches with the desired target locations.

Getting ready

Save touches.lua if needed, and open the file game.lua from the project folder. Take a look through the scene:willEnterScene(event) function; this is where the list of game targets will be created, that we will use in the main loop.

Getting on with it

Start at the top of game.lua.

Loading the touches module

Load the function that will carry a for loop over all active touch points:

local level = require "level"

local touches = require "touches"

local storyboard = require "storyboard"

Matching touches to targets

Find the scene:clock(event) function which is in charge of updating the game each time its main loop runs; it is currently empty.

  1. The first thing it does is start an empty list, which will hold targets that have a touch nearby, and the distance to the nearest touch for those targets, as well as a count of active touches that aren't the closest to any target:
    function scene:clock( event )
      local orbits = {}
      local orphans = 0
    end
  2. For each touch currently on the screen, it considers each target and finds the nearest one to that touch:
    function scene:clock( event )
      local orbits = {}
      local orphans = 0
      for id, location in touches() do
        local nearest, proximity
        for _, target in pairs(self.Targets) do
          local distance = math.pythagorean(location.x - target.x, location.y - target.y)
          if not nearest or distance < proximity then
            nearest, proximity = target, distance
          end
        end
      end
    end
  3. If the touch is the closest touch to some target, and within a specified range, it records the distance:
          if not nearest or distance < proximity then
            nearest, proximity = target, distance
          end
        end
        if proximity <= self.TARGET_RADIUS and ( not orbits[nearest] or proximity < orbits[nearest]) then
          orbits[nearest] = proximity
        end
      end
  4. Otherwise, it marks the touch as orphaned, or off-target. This count is stored as a negative number to make it easy to subtract from the user's score later.
        if proximity <= self.TARGET_RADIUS and ( not orbits[nearest] or proximity < orbits[nearest]) then
          orbits[nearest] = proximity
        else
          orphans = orphans - 1
        end

Adjusting the player's score

In the same function, we'll adjust the player's score. Because accuracy in this game is something that has to be sustained, the total accuracy of touches at any given moment is used to speed up or slow down the rate at which the score increases. If the score stops increasing completely, the level is over.

  1. First, reckon the penalty from any inaccurate touches:
          orphans = orphans - 1
        end
      end
      local pressure = orphans * self.TARGET_RADIUS * -0.5
    end
  2. Next, consider each touch that was on-target, and adjust the score increase upward accordingly.
      local pressure = orphans * self.TARGET_RADIUS * -0.5
      for target, proximity in pairs(orbits) do
        pressure = pressure + (self.TARGET_RADIUS - proximity)
      end
    end
  3. Apply this rate change to the degree of score increase, adjusted for the actual amount of time that has passed.
        pressure = pressure + (self.TARGET_RADIUS - proximity)
      end
      self.Velocity = math.min(self.Velocity + pressure * event.delta, self.TERMINAL_VELOCITY)
    end
  4. If the rate has bottomed out, the level is over.
      self.Velocity = math.min(self.Velocity + pressure * event.elapsed, self.TERMINAL_VELOCITY)
      if self.Velocity <= 0 then
        self:dispatchEvent{name = 'Level'; action = 'failed'}
      end
    end
  5. Otherwise, adjust the score by the rate of change multiplied by the amount of time passed.
      if self.Velocity <= 0 then
        self:dispatchEvent{name = 'Level'; action = 'failed'}
      else
        self.ScoreCurrent = self.ScoreCurrent + self.Velocity * event.delta
      end
    end

What did we do?

We set up the main game loop to award points for each touch that lies close enough to a target point (keep in mind that the target points are in motion). Because this will happen in every frame, we need to adjust the value being gained according to the amount of game time that has actually passed.

..................Content has been hidden....................

You can't read the all page of ebook, please click here login for view all page.
Reset
3.16.81.94