craftyjs / Crafty

JavaScript Game Engine
http://craftyjs.com
MIT License
3.38k stars 560 forks source link

Mobile devices #23

Closed louisstow closed 9 years ago

louisstow commented 13 years ago

Haven't been able to test Crafty on mobile devices but some components to accept mobile inputs would be handy.

ponychicken commented 13 years ago

Tried my game in progress on an iphone. It's seriously slow, but everything seems to work. Setting up touchzones is 20 lines or less.

louisstow commented 13 years ago

Damn. Is there a way to profile? And do you know which areas lagged?

ponychicken commented 13 years ago

Profile: not sure. I'm downloading the ios simulator now, maybe it can shed some light.

ponychicken commented 13 years ago

This is nice: http://stevesouders.com/mobileperf/mobileperfbkm.php

louisstow commented 13 years ago

Don't know how possible it will be in pure JS. It's pretty slow on my android.

BossRighteous commented 12 years ago

I have a cross device click/touch solution that's pretty easily implemented elsewhere. I'll make it a component, I just need to see how the current custom click events bubble up in Crafty. An example can be found at http://www.fjhorton.com/spinner.html This works on Desktop, iOs, and Andriod. The only thing it doesn't include is multi-touch support. But that's also implemented somewhat easily. An important note is that the move events fire much too fast to deal with directly. The way I handled it was to simply note the last known mouse position and deal with the resulting visual updates in an enterFrame style interval. This is also required because a touchend event doesn't fire a position coord. but this is pretty useful information.

One of the biggest issues with Android devices I have noticed in my own adventures is the slow speed of DOM manipulations. Transitioning to xTransform CSS translations should speed things up fairly nice. Another speed issue is how the page re-paints and reflows on a css property change. I took a look at the timer loop and I can optimize it a bit I think. Imagine 20 items, each with a x and y update. Currently, each item processes the left and top properties separately (rightly so.) The issue is this triggers a reflow and repaint of the screen. So 20x2 means that in one update loop the stage is re-adjusted 40 times. The simple solution is to remove the stage child from the DOM parent right before looping through the redraws, and when the redraw routine completes, simply add the stage back to the parent. That ensures that only one reflow/paint is performed per tick. This would create an issue only where the stage is a non [0] child of its parent. Properly denoting the first-child requirement shouldn't cause many further problems.

Another optimization that I feel is helpful, and certainly in a mobile environment, would be a deltaTime based tick structure. Right now, the ticks are based purely on the frame-rate (Assuming the browser doesn't support xRequestAnimationFrame). Lets assume the frame-rate of 50fps for an example. 20ms timeout delays are the current standard with this FPS. Time-consuming DOM manipulations can take over 20ms, even when the engines math functions are handled much more quickly. As it stands currently, the ticks occur every 20ms when there is an ideal 0ms processing overhead. However, 15ms of calculation would still trigger a 20ms delay before the next tick. The total time between currentFrameStart and nextFrameStart is at least 35ms now. An obvious problem with the current loop arises in timing based games on low end devices. "this.x +=2" style movements will be directly tied to the frame refresh. On a low-end device only capable of 10fps, the object will have only moved 1/5 of the intended distance over the course of a second.

deltaTime loops can observe the total processing time of a tick, and adjust the updateDelay accordingly. When the calculation/update takes 3ms, the 20ms goal is adjusted to 17ms. When the calculation/update takes 30ms, the delay is set to 4ms (html5 minimum), running as fast as possible. In this situation, deltaTime represents the percentage of 1 second the update took to exectute: (currentTime -previousTime) /1000 In this case we have the ability to bind movements to a units/second speed. obj.x += (50Crafty.deltaTime); in an ideal 20ms tick rate we can maintain an increment of (50.02 = 1px/tick) in a terrible case of 500ms per update, we maintain an increment of (50*.5 = 25px/tick). So while the actual FPS has dropped to 2, the apparent velocity has remained intact. This also handles cases of sudden system load.

Any concerns or thoughts on these issues?

This is a big issue post I know, so let me know if I should make new issue tickets (or feel free to do so yourself.) Unofficially, I am planning to look at: the DOM CSS transform issues, the color and image Component issues touch inputs for mobile optimizing the re-flow/re-paint by detaching the container retooling the timer loop to account for deltaTime refining the Tween component to deal with deltaTime and include basic easing

Let me know how to take the next step on this stuff, I'm new to github and shared repositories.

louisstow commented 12 years ago

Wow you've certainly done your home work.

I agree with every point you made and would love it if you would like to add some fixes for these. I will add you as a repo contributor.

Would you mind taking a look at the dev branch because I have changed the DOM drawing some what. Mainly checking if the value has changed before changing the css style and removing setters.

On Thu, Aug 11, 2011 at 4:56 PM, BossRighteous < reply@reply.github.com>wrote:

I have a cross device click/touch solution that's pretty easily implemented elsewhere. I'll make it a component, I just need to see how the current custom click events bubble up in Crafty. An example can be found at http://www.fjhorton.com/spinner.html This works on Desktop, iOs, and Andriod. The only thing it doesn't include is multi-touch support. But that's also implemented somewhat easily. An important note is that the move events fire much too fast to deal with directly. The way I handled it was to simply note the last known mouse position and deal with the resulting visual updates in an enterFrame style interval. This is also required because a touchend event doesn't fire a position coord. but this is pretty useful information.

One of the biggest issues with Android devices I have noticed in my own adventures is the slow speed of DOM manipulations. Transitioning to xTransform CSS translations should speed things up fairly nice. Another speed issue is how the page re-paints and reflows on a css property change. I took a look at the timer loop and I can optimize it a bit I think. Imagine 20 items, each with a x and y update. Currently, each item processes the left and top properties separately (rightly so.) The issue is this triggers a reflow and repaint of the screen. So 20x2 means that in one update loop the stage is re-adjusted 40 times. The simple solution is to remove the stage child from the DOM parent right before looping through the redraws, and when the redraw routine completes, simply add the stage back to the parent. This will create an issue only where the stage is a +1 child of its parent. Properly denoting the first-child requirement shouldn't cause many further problems.

Another optimization that I feel is helpful, and certainly in a mobile environment, would be a deltaTime based tick structure. Right now, the ticks are based purely on the frame-rate (Assuming the browser doesn't support xRequestAnimationFrame). Lets assume the frame-rate of 50fps for an example. 20ms timeout delays are the current standard with this FPS. Time-consuming DOM manipulations can take over 20ms, even when the engines math functions are handled much more quickly. As it stands currently, when the ticks occur every 20ms when there is 0ms processing overhead. 15ms of calculation would still trigger a 20ms delay before the next tick. The total time between currentFrameStart and nextFrameStart is at least 35ms now. An obvious problem with the current loop arises in timing based games on low end devices. "this.x +=2" style movements will be directly tied to the frame refresh. On a low-end device only capable of 10fps, the object will have only moved 1/5 of the intended speed over the course of a second.

deltaTime loops can observe the total processing time of a tick, and adjust the updateDelay accordingly. When the calculation/update takes 3ms, the 20ms goal is adjusted to 17ms. When the calculation/update takes 30ms, the delay is set to 4ms (html5 minimum), running as fast as possible. In this situation, deltaTime represents the percentage of 1 second (1.0000) between the previous tick and the current tick. In this case we have the ability to bind movements to a units/second speed. obj.x += (50Crafty.deltaTime); in an ideal 20ms tick rate we can maintain an increment of (50.02 = 1px/tick) in a terrible case of 500ms per update, we maintain an increment of (50*.5 = 25px/tick). So while the actual FPS has dropped to 2, the apparent veloctieshave remained intact. This also handles cases of sudden system load.

Any concerns or thoughts on these issues?

This is a big issue post I know, so let me know if I should make new issue tickets (or feel free to do so yourself.) Unofficially, I am planning to look at: the DOM CSS transform issues, the color and image Component issues touch inputs for mobile optimizing the re-flow/re-paint by detaching the container retooling the timer loop to account for deltaTime refining the Tween component to deal with deltaTime and include basic easing

Let me know how to take the next step on this stuff, I'm new to github and shared repositories.

Reply to this email directly or view it on GitHub: https://github.com/louisstow/Crafty/issues/23#issuecomment-1779711

ahilles107 commented 12 years ago

@BossRighteous - any progress with this?

BossRighteous commented 12 years ago

Very sorry, I am literally 10 days from graduating college and working full time all the while. I would really love to help if it is still needed after the 25th or so, but I can't commit any time to the project until then. I'll check back in then and see what changes I can still help with. I had started before but gotten a little thrown off by the dev branching. I am new to shared repos and wasn't quite sure if I was doing it all correctly. Then work and school got overwhelming.

I am certainly wanting to help as much as I can after this all clears up though.

sorenbs commented 12 years ago

Congrats with graduating :-) When you get time again feel free to split this into separate tickets and commit patches for them. If you need help with the git stuff, just let us know. Either here or in the forum.

sdrib commented 12 years ago

As suggested in the google group topic. https://groups.google.com/d/topic/craftyjs/VmlJIc4ulK8/discussion Considering mobile, PhoneGap support would be awesome!

I have been toying around with Crafty+PhoneGap, there's some issues but a lot of things work nicely.

ahilles107 commented 12 years ago

@BossRighteous - any progress with this?

BossRighteous commented 12 years ago

Yikes! Sorry to leave you all hanging! It's been a wild ride on my part the past few months. I just landed a great promotion 2 weeks ago, so things are finally settling quite nicely.

Anyway, I am grabbing the latest build and going to work feverishly to get some of these things added by Monday. I'm headed out of town with my laptop and no internet, so productivity should be top notch. ;)

I've been doing a lot of paper planning on parent/child enabled display-list alternatives in the past few months. The ideas may not all fit with Crafty's goals, but I intend to write something up and share it in the not too distant future. I finally have time to work on things and not just think about them, so I should be free for updates from here out. I may not have been actively contributing code, but I have been actively planning.

All the best to everyone!

sorenbs commented 12 years ago

Sounds amazing. Feel free to ask if you need anything.

austinh commented 11 years ago

Any update on the DOM performance or delta based ticks?

I'd be willing to help with the delta based ticks if nothing has been started yet, as I have often found that I end up implementing this in my own games anyways.

DOM Performance is beyond me though.

sorenbs commented 11 years ago

I think delta based ticks is being worked on in the layers branch https://github.com/craftyjs/Crafty/tree/layers Would be nice to get some extra eyes on that. Reach out to Matt Petrowick in the forum.

thehack commented 11 years ago

I tested Crafty.audio.play() in Android's browser. It doesn't work (Android 2.2). I have learned that this is because although the browser has support for the HTML5 audio element, it doesn't support playing ANY file formats on it!

The work-around for HTML5 audio is to dynamically set up the sound as a video element and play it, which ironically works.

starwed commented 9 years ago

This is old enough I'm going to close it. I'm sure we still have some issues on mobile, but both mobile browsers and our support for touch events/etc have improved drastically in the last couple years! And we can even use WebGL in recent Android/iOS builds, which should help performance.