Fractional x/y positions from touch events?

Using a config size of 320 x 480, the “content pixels” and “actual pixels on the device” will differ on an iPad. For example, you have to drag an object with your finger 4 actual pixels on the device before the position changes by 1 content pixel. This  creates an “unsmooth” effect since the dragged image jumps by 4 content pixels at a time. By printing event.x to the console, I have seen that the “moved” phase of the listener actually gets triggered although event.x remains the same (when dragging just a tiny amount). This means that the listener is triggered by the move although nothing has actually moved on the screen.

My question: can fractional x and y coordinates can be read in a touch listener?

I asked this question along time ago but the only suggestion I got was to change the config size, but that would mean having to re-create all graphics, which is not an option for me. Hopefully there is another solution that I am not aware of…

Nope.  Same answer, sorry.

You need to use a higher resolution setting in your config.lua file.

But that would mean that the whole content scaling stuff is kind of flawed since it automatically also means that objects cannot be dragged smoothly. In an older thread I found a developper who set the size to 1600 x 2560 and simply downscaled from there, only to get rid of the “jagged dragging”. The response from the Corona staff was that it might cause memory problems since devices with a lower resolution tended to have less memory. Also, the whole reasoning behind the “ultimate config.lua” discussion falls if a consequence of it is this. Third, in my case, the game is finished and I have a lot of images. Changing the resolution would mean recreating all those images, which would be a very time consuming task…

Wouldn’t all this be solved if the listener (which obviously is triggered by fractional moves) also allowed for fractional event.x values?

At Corona staff: is this something that you have considered adding as a feature?

You should be getting fractional content locations and your dragging should be smooth unless you’re setting things to whole numbers.

Rob

But the event.x property of the touch event only returns integers…

I tried a very simple example following the tutorial (https://coronalabs.com/blog/2011/09/24/tutorial-how-to-drag-objects/) while printing the value of event.x to the xcode console from an iPad. All I get are integers. Or is there another way of getting content location that can be used when dragging?

I made a demo reproducing your findings and I’m surprised.  Once Rob mentioned it I was sure we used to get fractional values.

However, I’m not seeing them either.

This demo can easily be tested at any multiple of 320 x 480 by adjusting the variable ‘scale’ in config.lua on line 9.

https://github.com/roaminggamer/RG_FreeStuff/raw/master/AskEd/2016/10/fractional_touch.zip

‘scale’ is actually an inverse-scale, so 0.5 means 640 x 960 while 2 means 160 x 240.

By changing this one line, the rest of the demo will adjust.  I tested these scales :

  • 0.5 - 640 x 960 
  • 1 - 320 x 480
  • 4 160 x 240
  • 8 - 60 x 40 - Noticeable stepping**  during drag.**
  • 16 -  Super Noticeable stepping during drag.

https://www.youtube.com/watch?v=tmoyS_Jdu0w&feature=youtu.be

If you’re going to file a bug or feature request, feel free to snag the demo and use it.  I think it clearly shows the issue your describing and is easy to use as a test for a fix/change.

PS - I didn’t print them to the screen (and should have), but the event <x,y> values are coming through as whole values.

At RoamingGamer: yes, that is exactly what I mean, thanks! Given Rob’s posting, I have submitted a bug report with your sample code.

At Rob: any chance we have misunderstood what you meant? Did you perhaps not mean then event.x property?

First of all, we’ve not made any changes that would affect the x and y returning from events. There is a distinct likelyhood that I’ve not paid attention to the values in a while and I could be wrong. 

So it’s not likely a bug other than me getting confused. You can position items with fractional x, y’s. Transitions and physics use fractional x, y’s. But I guess it’s possible that the event.x, y of a touch is coming in with whole content unit values.

Rob

In that case, given my initial problem statement, how could dragging ever be made smooth on a 4x scale??

I would consider it absolutely necessary to have event.x return fractions, otherwise the whole content scaling thing loses an important component. Sure, I could file a feature request but I would actually consider this a bug (or at least a design flaw).

Divergent Monkey

I agree with you in some ways and understand your plight, but consider:

  1. Scaling from 320x480 to modern resolutions is a pretty big jump.  Most designs should start at no lower than 640 x 960 (or even 750x1334)
  • I typically tell clients to choose the primary target device and to set that as their resolution in config.lua.  
  • I further advise folks to use iPhone 6 or 6+ as their base.
  • Note: I totally understand liking 320x480 because it makes hand-calculations easy (I stayed there for a long time.)
  1. Implementing floating point values in the touch event(s) may have a hidden cost/performance side-effect.  
  2. Changing the current system to accommodate floating point values might also have a huge negative impact on current and past projects (one never knows what assumptions developers have made, but changing fundamentals is bound to cause issues.)

I know you said you’d have a lot of work ahead of you if you were forced to implement this at a higher resolution.  Can you elaborate on that a bit?  I ask because while there may be no way to get floating-point values from touches, there may still be ways to help you move this forward.

@ roaminggamer

You could definitely be right about possible negative performance effects of having floats in touch events. Also, just changing the behavior of event.x would be unwise. Instead adding e.g. event.xFract as a new property would be better at least from a backward compatibility standpoint.

In my project I have three versions of all images: 1x, 2x and 4x using a content size of 320 x 480 in config.lua. I assume that if I change the the content size to 640 x 960, all I would have to do is to delete all the 1x images and rename the remaining to 1x and 2x. A doubling of the content size paired with a doubling of the image size. In my code, I would then have to double all the image sizes in my newImageRect images as well as reposition in case I have used pixels instead of values like “display.contentWidth * 0.5”. Am I correct this far?

However, in “Modernizing the config.lua”, the argument is to have 1200 x 800 and above you mention 750 x 1334. These resolutions are not an even factor of 320 x 480, which I assume means that I would need images 2.5 times the size if e.g. using 1200 x 800. That in turn would then mean that I have to redraw them.  Or am I getting it wrong?

If you already have @2x assets, just rename them with out the extension and your @4x to @2x and then you could use a 640x960 screen which would improve things.

Yes, but wouldn’t I also have to resize them in the code? For example:

myImage = display.newImageRect(“myimage.png”, 50, 50)

myimage.png = 50 x 50 px

myimage@2x.png = 100 x 100 px

myimage@4x.png = 200 x 200 px

at content size 320 x 480

If I do as you suggest:

myimage.png = 100 x 100 px

myimage@2x.png = 200 x 200 px

at content size 640 x 960

If the image is still set as

myImage = display.newImageRect(“myimage.png”, 50, 50)

then it will not reflect the true 1x imge size. Wouldn’t that have a negative effect on image quality?

To my great surprise, I just received an email from the Corona staff that said:

This issue is resolved on our latest build version 2016.2994 and above.

I downloaded the latest daily build and sure enough, event.x now returns fractional values! Judging from Robs initial response, I suspect this is the way it should work and that the integer-thing was a bug.

Spoke too soon…

Fractional values are indeed returned, but they are not updated with the movement of the finger. The list below shows the event.x as I slowly drag an object, with printouts made in the “moved” phase. As you can see, the values are identical although the “moved” phase is obviously triggered and the object does not move on the screen until the value below shifts. So yes, fractional values are returned but the problem remains since it is the same fractional value that i returned although the finger is moved…

Dec 02 11:40:31.417 Event x: 78.50666809082
Dec 02 11:40:31.431 Event x: 78.50666809082
Dec 02 11:40:31.439 Event x: 78.50666809082
Dec 02 11:40:31.495 Event x: 78.50666809082
Dec 02 11:40:32.125 Event x: 78.50666809082
Dec 02 11:40:34.173 Event x: 78.50666809082
Dec 02 11:40:36.513 Event x: 78.50666809082
Dec 02 11:40:36.547 Event x: 78.50666809082
Dec 02 11:40:36.614 Event x: 78.50666809082
Dec 02 11:40:37.322 Event x: 78.50666809082
Dec 02 11:40:37.324 Event x: 78.50666809082
Dec 02 11:40:38.099 Event x: 78.50666809082
Dec 02 11:40:38.101 Event x: 80.213333129883
Dec 02 11:40:39.157 Event x: 80.213333129883
Dec 02 11:40:39.158 Event x: 80.213333129883
Dec 02 11:40:39.167 Event x: 80.213333129883
Dec 02 11:40:39.843 Event x: 80.213333129883
Dec 02 11:40:40.303 Event x: 80.213333129883
Dec 02 11:40:40.833 Event x: 80.213333129883
Dec 02 11:40:40.846 Event x: 80.213333129883
Dec 02 11:40:41.272 Event x: 80.213333129883
Dec 02 11:40:41.274 Event x: 80.213333129883
Dec 02 11:40:41.451 Event x: 80.213333129883
Dec 02 11:40:41.800 Event x: 81.919998168945
Dec 02 11:40:41.803 Event x: 81.919998168945
Dec 02 11:40:42.408 Event x: 81.919998168945
Dec 02 11:40:42.858 Event x: 81.919998168945
Dec 02 11:40:43.353 Event x: 81.919998168945
Dec 02 11:40:44.331 Event x: 81.919998168945
Dec 02 11:40:44.838 Event x: 81.919998168945
Dec 02 11:40:48.427 Event x: 81.919998168945
Dec 02 11:40:48.720 Event x: 81.919998168945
Dec 02 11:40:50.463 Event x: 81.919998168945
Dec 02 11:40:50.553 Event x: 81.919998168945
Dec 02 11:40:50.722 Event x: 81.919998168945
Dec 02 11:40:51.183 Event x: 81.919998168945
 

The returning of integers was not a bug but it kind of turned into a less desirable feature. Back in the day when every device was 320xsomething the precision for finger positions didn’t matter that much and it’s easier to work with integers than floats.

Today we need the factional values.  I’ll let the Engineer know about your findings.

Rob

Also, can you post your touch handling code here or at least a sample that demonstrates this?

Thanks

Rob

if (event.phase == "began") then -- Store current position touchObjectL.markX = touchObjectL.x touchObjectL.markY = touchObjectL.y elseif (event.phase == "moved") then print(event.x) -- Set new position of touch object touchObjectL.x = (event.x - event.xStart + touchObjectL.markX) touchObjectL.y = (event.y - event.yStart + touchObjectL.markY) elseif (event.phase == "ended" or event.phase == "cancelled") then .... end

touchObjectL is the object that is moved. Hope this snippet helps, please let me know if you need a more complete example. However, all you need is basically just to print the event.x in a “moved” phase to see what I mean.

We had a couple of engineers look into this today and we are basically just passing what the operating system provides us. Perhaps the device isn’t granular enough.

Rob