2 * Copyright 2013 Samsung Electronics Co., Ltd
4 * Licensed under the Flora License, Version 1.1 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
8 * http://floralicense.org/license/
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
17 /*global $: false, tizen: false, navigator: false, app: true*/
21 R: 2000.0, // // gravity constant * m * M
41 resistance: 0.98, // air
42 friction: 0.90, // bounce
51 animationInterval: 40,
54 * Draw earth background position
55 * @param {int} x current x earth position
56 * @param {int} y current y earth position
58 earthUpdateBackgroundPosition: function earthUpdateBackgroundPosition(x, y) {
69 cX = (this.gameWidth - this.backgroundWidth) / 2;
70 cY = (this.gameHeight - this.backgroundHeight) / 2;
75 bdX = tX - this.backgroundLeft;
76 bdY = tY - this.backgroundTop;
80 this.backgroundLeft += bdX * br;
81 this.backgroundTop += bdY * br;
83 $('.background').css('background-position', (this.backgroundLeft - 330) + 'px ' + (this.backgroundTop - 330) + 'px');
88 * @param {int} x current x earth position
89 * @param {int} y current y earth position
91 earthUpdateSunPosition: function earthUpdateSunPosition(x, y) {
102 cX = (this.gameWidth - this.sunWidth) / 2;
103 cY = (this.gameHeight - this.sunHeight) / 2;
108 bdX = tX - this.sunX;
109 bdY = tY - this.sunY;
113 this.sunX += bdX * br;
114 this.sunY += bdY * br;
116 $('#sun').css('left', this.sunX + 'px');
117 $('#sun').css('top', this.sunY + 'px');
122 * Deceleration - used when the earth leaves the Sun's gravitation
124 deceleration: function deceleration() {
131 * Draw the next animation frame for the 'earth' tab
133 earthEvents: function earthEvents() {
136 var event, borderTolerance,
145 borderTolerance = 30; // when Earth reach a border, then Earth is "moving"
147 x = -event.accelerationIncludingGravity.x;
148 y = -event.accelerationIncludingGravity.y;
150 // calculate X and Y distances between the Sun and Earth
151 dXl = (this.sunX + this.sunWidth / 2 - (this.ballX + (this.ballWidth / 2))); // x distance
152 dYl = (this.sunY + this.sunHeight / 2 - (this.ballY + (this.ballHeight / 2))); // y distance
154 if (Math.abs(dXl) < 1) {
155 dXl = dXl < 0 ? -1 : 1; // round to 1 * sign
157 if (Math.abs(dYl) < 1) {
158 dYl = dYl < 0 ? -1 : 1; // round to 1 * sign
162 d2 = Math.pow(dXl, 2) + Math.pow(dYl, 2);
166 // acceleration is proportional to 1/d2 [a=GM/r^2]
167 // X component is also proportional to dXl / d
168 ddx = (this.R * dXl) / (d2 * d);
169 ddy = (this.R * dYl) / (d2 * d);
171 // apply acceleration to speed
175 ratio = Math.sqrt(Math.pow(this.dX, 2) + Math.pow(this.dY, 2)) / 25; // max speed
176 if (ratio > 1) { // speed limit achieved
181 // apply speed to Earth position
182 this.ballX += this.dX;
183 this.ballY += this.dY;
185 // What do it when the earth leaves gravitation of the Sun?;
186 if (this.ballX > (this.gameWidth + borderTolerance)) {
187 this.ballX = -borderTolerance; this.deceleration();
189 if (this.ballY > (this.gameHeight + borderTolerance)) {
190 this.ballY = -borderTolerance; this.deceleration();
192 if (this.ballX < -borderTolerance) {
193 this.ballX = this.gameWidth + borderTolerance; this.deceleration();
195 if (this.ballY < -borderTolerance) {
196 this.ballY = this.gameHeight + borderTolerance; this.deceleration();
199 // update Earth position
200 $('.ball').css('left', this.ballX + 'px');
201 $('.ball').css('top', this.ballY + 'px');
203 // relative depth Sun / Earth
205 $('.ball').css('z-index', 100);
207 $('.ball').css('z-index', 20);
210 this.earthUpdateBackgroundPosition(x, y);
211 this.earthUpdateSunPosition(x, y);
215 * Checks if the ball already was on the edge in the previous step
217 * If so, this is not a 'real' bounce - the ball is just laying on the edge
218 * Uses globals: ballX, ballY, ballWidth, ballHeight, gameWidth, gameHeight
222 shouldVibrateIfHitsEdge: function shouldVibrateIfHitsEdge() {
229 if (this.ballX <= 0) {
231 } else if ((this.ballX + this.ballWidth) >= this.gameWidth) {
234 if (this.ballY <= 0) {
236 } else if ((this.ballY + this.ballHeight) >= this.gameHeight) {
244 * Draw the next animation frame for the 'ball' tab
246 ballEvents: function ballEvents() {
259 shouldVibrate = null,
260 isHittingEdge = null;
264 x = -event.accelerationIncludingGravity.x;
265 y = -event.accelerationIncludingGravity.y;
278 this.dX *= this.resistance;
279 this.dY *= this.resistance;
281 shouldVibrate = this.shouldVibrateIfHitsEdge();
283 this.ballX += this.dX;
284 this.ballY += this.dY;
286 if (this.ballX < 0) {
288 this.dX = Math.abs(this.dX) * this.friction - this.frictionC;
289 this.dY *= this.sideFriction;
291 } else if ((this.ballX + this.ballWidth) > this.gameWidth) {
292 this.ballX = this.gameWidth - this.ballWidth;
293 this.dX = -Math.abs(this.dX) * this.friction + this.frictionC;
294 this.dY *= this.sideFriction;
296 if (this.ballX < 0) {
301 if (this.ballY < 0) {
303 this.dY = Math.abs(this.dY) * this.friction - this.frictionC;
304 this.dX *= this.sideFriction;
306 } else if ((this.ballY + this.ballHeight) > this.gameHeight) {
307 this.ballY = this.gameHeight - this.ballHeight;
308 this.dY = -Math.abs(this.dY) * this.friction + this.frictionC;
309 this.dX *= this.sideFriction;
311 if (this.ballY < 0) {
317 x: (stickLeft || stickRight) && Math.abs(this.dX) > 1,
318 y: (stickTop || stickBottom) && Math.abs(this.dY) > 1
321 // if on the edge and the hitting speed is high enough
322 if ((shouldVibrate.x && isHittingEdge.x) || (shouldVibrate.y && isHittingEdge.y)) {
323 if (typeof navigator.webkitVibrate === 'function') {
324 navigator.webkitVibrate(100);
326 navigator.vibrate(100);
330 $('.ball').css('left', this.ballX + 'px');
331 $('.ball').css('top', this.ballY + 'px');
333 rX = this.ballX - rX;
334 rY = this.ballY - rY;
339 * Draw the next animation frame
341 fun: function fun() {
344 switch (this.current) {
355 console.warn("Incorrect current mode");
360 // animation - go to next step;
361 if (this.timeout !== null) {
362 clearTimeout(this.timeout);
364 this.timeout = setTimeout(this.fun.bind(this), this.animationInterval);
368 * Switch to the 'ball' tab
370 startBall: function startBall() {
373 $('.ui-content').removeClass('background1 background2 background3').addClass('background1');
374 $(':jqmData(role="controlbar")').find('.ui-btn').removeClass('ui-btn-hover-s ui-btn-down-s');
375 this.gameHeight = $('.background').outerHeight();
378 this.resistance = 0.98;
379 this.friction = 0.90;
380 this.sideFriction = 0.95;
381 this.frictionC = 0.002;
383 this.current = 'ball';
386 $('.ball').attr('src', './images/ball1.png');
387 $('.ball').css('width', '86px');
388 $('.ball').css('height', '86px');
390 $('.background').css('background-position', '0px -90px');
392 this.ballWidth = parseInt($('.ball').css('width'), 10);
393 this.ballHeight = parseInt($('.ball').css('height'), 10);
397 * Switch to the 'sky' tab
399 startSky: function startSky() {
401 $('.ui-content').removeClass('background1 background2 background3').addClass('background2');
402 $(':jqmData(role="controlbar")').find('.ui-btn').removeClass('ui-btn-hover-s ui-btn-down-s');
403 this.gameHeight = $('.background').outerHeight();
406 this.resistance = 0.90;
407 this.friction = 0.98;
408 this.sideFriction = 0.95;
409 this.frictionC = 0.002;
411 this.current = 'baloon';
414 $('.ball').attr('src', './images/balloon.png');
415 $('.ball').css('width', '100px');
416 $('.ball').css('height', '100px');
418 $('.background').css('background-position', '0px -80px');
420 this.ballWidth = parseInt($('.ball').css('width'), 10);
421 this.ballHeight = parseInt($('.ball').css('height'), 10);
425 * Switch to the 'space' tab
427 startSpace: function startSpace() {
429 var backgroundPosition, arrayPos;
431 $('.ui-content').removeClass('background1 background2 background3').addClass('background3');
432 $(':jqmData(role="controlbar")').find('.ui-btn').removeClass('ui-btn-hover-s ui-btn-down-s');
434 this.gameHeight = $('.background').outerHeight();
436 this.friction = 0.60; // bounce
437 this.sideFriction = 0.95;
438 this.frictionC = 0.0;
440 this.current = 'earth';
442 $('.ball').attr('src', './images/earth.png');
443 $('#main').append('<img id="sun" class="sun" src="./images/sun.png" style="display: none;"></img>');
445 this.sunX = (this.gameWidth - parseInt($('#sun').css('width'), 10)) / 2;
446 this.sunY = (this.gameHeight - parseInt($('#sun').css('height'), 10)) / 2;
447 $('.ball').css('width', '50px');
448 $('.ball').css('height', '50px');
450 $('.background').css('background-position', '0px 0px');
452 this.ballWidth = parseInt($('.ball').css('width'), 10);
453 this.ballHeight = parseInt($('.ball').css('height'), 10);
454 this.sunWidth = parseInt($('#sun').css('width'), 10);
455 this.sunHeight = parseInt($('#sun').css('height'), 10);
457 backgroundPosition = $('.background').css('background-position');
459 arrayPos = backgroundPosition.split(' ');
460 this.backgroundTop = parseInt(arrayPos[0], 10);
461 this.backgroundLeft = parseInt(arrayPos[1], 10);
462 this.backgroundWidth = parseInt($('.background').css('width'), 10);
463 this.backgroundHeight = parseInt($('.background').css('height'), 10);
466 saveSensorData: function saveSensorData(event) {
472 $(document).ready(function () {
475 contentHeight = screen.availHeight - $('div[data-role="header"]').outerHeight() - $('div[data-role="footer"]').outerHeight();
477 $('div[data-role="content"]').css('height', contentHeight - 33);
478 app.gameWidth = screen.availWidth;
479 app.ballWidth = parseInt($('.ball').css('width'), 10);
480 app.ballHeight = parseInt($('.ball').css('height'), 10);
482 window.addEventListener('devicemotion', app.saveSensorData.bind(app), false);
486 $(window).on('tizenhwkey', function (e) {
487 if (e.originalEvent.keyName === "back") {
488 tizen.application.getCurrentApplication().exit();
492 $('#btnBall').bind('click', function (event) {
493 preventSecClick(this);
497 $('#btnSky').bind('click', function (event) {
498 preventSecClick(this);
502 $('#btnSpace').bind('click', function (event) {
503 preventSecClick(this);
507 function preventSecClick(current) {
509 $("#footerControls li a.ui-disabled").removeClass('ui-disabled');
510 $(current).addClass("ui-disabled").blur();
513 $('#mainPage').on('pageshow', function () {
517 document.addEventListener('webkitvisibilitychange', function (event) {
518 if (document.webkitVisibilityState === 'visible') {
523 // Preload backgrounds;
524 img = $('<img>').hide();
525 img.attr('src', 'images/background1.png');
528 $(window).resize(function () {
530 app.gameWidth = screen.availWidth;
531 app.gameHeight = $('.background').outerHeight();