create a finger swipe

The mobile devices are smartphone with touch functionality. One of the limitations of the Touch Functionality is that there is little or no feedback. In the case of a keyboard, you can feel the keys being pressed, in case of a physical button, you can feel the contour and know if it is on or off. How do you create feedback on a touch device?

Being blessed with the 5 senses that we have, we can compensate for the lack of information on one if the other has some information related to that. So, though we cannot feel the swipe, if our eyes could see it, we are convinced enough that a swipe happened. For the ones that roamed with the dinosaurs, ok less dramatic, those that saw the ansca code for the Fruit Samurai, can almost identify the swipe. This wonderful code brought to us by the Miranda brothers had to be taken off, but before it was, there were several clones of that code, including the users that just put it up as is on the iTunes store.

Now spotting if that code has been used or not is very simple, there was a bug in that code that has persisted and the guys that copied this, were lesser developers (in my opinion, not because they copied it) because they could not spot the bug/error and none of them have fixed it. If you see the bomb blowing up and the screen shaking, it is definitely the Ansca Code. If you see the swipe, it is the dead giveaway that the app is made with Corona and the code *inspired* from this source.

The Bug

I am not sure how many have actually seen that when the swipe is displayed on screen, it is a combination of 5 points, and there are cases when this splits and you see a burst of lines instead of a swipe. Now if I see that in an app, it is the instant giveaway about it's origins. Recently I saw two apps, "Image Ninja" and "Cut the Birds". Image Ninja is a newer app as it uses Masks, the developer has a variety of masks, which demonstrates the inexperience, as they could have scaled the mask to achieve the size ans shape they wanted. That's besides the point, so what does that code look like?

-- Slash line properties (line that shows up when you move finger across the screen)
local maxPoints = 5
local lineThickness = 20
local lineFadeTime = 250
local endPoints = {}


-- Draws the slash line that appears when the user swipes his/her finger across the screen
function drawSlashLine(event)
 
 -- Play a slash sound
 if(endPoints ~= nil and endPoints[1] ~= nil) then
  local distance = math.sqrt(math.pow(event.x - endPoints[1].x, 2) + math.pow(event.y - endPoints[1].y, 2))
  if(distance > minDistanceForSlashSound and slashSoundEnabled == true) then 
   playRandomSlashSound();  
   slashSoundEnabled = false
   timer.performWithDelay(minTimeBetweenSlashes, function(event) slashSoundEnabled = true end)
  end
 end
 
 -- Insert a new point into the front of the array
 table.insert(endPoints, 1, {x = event.x, y = event.y, line= nil}) 

 -- Remove any excessed points
 if(#endPoints > maxPoints) then 
  table.remove(endPoints)
 end

 for i,v in ipairs(endPoints) do
  local line = display.newLine(v.x, v.y, event.x, event.y)
  line.width = lineThickness
  transition.to(line, {time = lineFadeTime, alpha = 0, width = 0, onComplete = function(event) line:removeSelf() end})  
 end

 if(event.phase == "ended") then  
  while(#endPoints > 0) do
   table.remove(endPoints)
  end
 end
end

Now if we take away the unnecessary distractions from the code above, the way the code works is

1. It adds to the table the current touch points
2. If there are more points than the maxPoints which is defined as 5, then the first point is removed
3. A line is drawn between the last point and the next point to have a continuous line.

The bug lies in the code here
 for i,v in ipairs(endPoints) do
  local line = display.newLine(v.x, v.y, event.x, event.y)
  line.width = lineThickness
  transition.to(line, {time = lineFadeTime, alpha = 0, width = 0, onComplete = function(event) line:removeSelf() end})  
 end

The problem being that the first time around, the values of v.x, v.y is the first point and the line splits up like a flare.

So I leave the fixing of this code to you as a learning exercise, I have narrowed it down for you, I had used something similar to this in my app Retroballz, which is a universal app for both the iPad and the iPhone/iPod devices. At first I tried this code and wasn't happy with the flares every now and then. So wrote my own and also addressed this issue.

There was one more issue in this code that could have been missed by many, if you do not lift your finger, and keep it touching the screen, you will find that you can keep chopping the fruits, the birds, the images, whatever by mere touch.

and while we are on the topic of bugs, another thing that can create issues in your apps is the shootObject function which is defined as

function shootObject(type)
 
 local object = type == "fruit" and getRandomFruit() or getBomb()
 
 fruitGroup:insert(object)
 
 object.x = display.contentWidth / 2
 object.y = display.contentHeight  + object.height * 2

 fruitProp.radius = object.height / 2
 physics.addBody(object, "dynamic", fruitProp)

 if(type == "fruit") then
  object:addEventListener("touch", function(event) chopFruit(object) end)
 else
  local bombTouchFunction
  bombTouchFunction = function(event) explodeBomb(object, bombTouchFunction); end
  object:addEventListener("touch", bombTouchFunction)
 end


The problem in this function lies in

    function shootObject(type)

The issue is that type is a keyword function, it is best that system keywords are left alone than using them as variables, prefix something, suffix it with something, but avoid keywords.

I hope that when you will henceforth see an *inspired* app, you can almost immediately identify how the developers have taken sample code and without understanding or working on it just compiled it.

Comments

Post a Comment

Popular Posts