Touch event location and scaling

I’m scaling my app to fill the browser window using the usual method:

app.adjustSizeForWindow = function () { var margin = document.documentElement.clientWidth - document.body.clientWidth; if (document.documentElement.clientWidth < cc.originalCanvasSize.width) { cc.canvas.width = cc.originalCanvasSize.width; } else { cc.canvas.width = document.documentElement.clientWidth - margin; } if (document.documentElement.clientHeight < cc.originalCanvasSize.height) { cc.canvas.height = cc.originalCanvasSize.height; } else { cc.canvas.height = document.documentElement.clientHeight - margin; } var xScale = cc.canvas.width / cc.originalCanvasSize.width; var yScale = cc.canvas.height / cc.originalCanvasSize.height; if (xScale > yScale) { xScale = yScale; } cc.canvas.width = cc.originalCanvasSize.width * xScale; cc.canvas.height = cc.originalCanvasSize.height * xScale; var parentDiv = document.getElementById("Cocos2dGameContainer"); if (parentDiv) { parentDiv.style.width = cc.canvas.width + "px"; parentDiv.style.height = cc.canvas.height + "px"; } cc.renderContext.translate(0, cc.canvas.height); cc.renderContext.scale(xScale, xScale); cc.Director.getInstance().setContentScaleFactor(xScale); console.log( 'adjustSizeForWindow(), scaleFactor = ' + xScale ); };

when scaled up, touch event positions are in screen co-ordinates relative to the application rather than in application co-ordinates. I can handle this in my game by scaling the touch point positions by the contentScaleFactor of the application, but MenuItemSprites have stopped working as well - if the application is scaled by a factor of 2, then touches map to the bottom left quarter of the application window - so if my button is on the far right hand side of the screen, to activate it’s tap handler i have to tap half way across at the bottom of the screen.

I’ve just taken on this project and one of the first things i did was upgrade to the latest version of cocos2d-x - 2.1.4 - from what I can gather this was not happening before.

Any thoughts before I start hacking the cocos code?

i’ve fixed this for now by scaling the location of all mouse and touch events according to contentScaleFactor - in CCTouchDispatcher.js:

cc.TouchDispatcher.scaleLocation = function( location ){
var scale = cc.Director.getInstance().getContentScaleFactor();
location.x /= scale;
location.y /= scale;
};

and then replacing all instances (there are quite a few) of:

var location = cc.EGLView.getInstance().convertToLocationInView(tx, ty, pos);

in the mouse/touch event handlers with:

var location = cc.EGLView.getInstance().convertToLocationInView(tx, ty, pos);
cc.TouchDispatcher.scaleLocation( location );

this has made menu buttons work again and also fixed the issues in my game - haven’t seen any unpleasant side effects…

Thank you, matt Sayers.

Could you tell me how did you fill the browser window in your game?

Does it call app.adjustSizeForWindow function?

We call the function of “cc.EGLView.getInstance().setDesignResolutionSize(320,480,cc.RESOLUTION_POLICY.SHOW_ALL);” to fill the browser window in sample game “MoonWarriors”

The function “handleTouchesBegin” in CCEGLView.js includes touch location scaler, as well as cc.TouchDispatcher.scaleLocation:
@
touch.setTouchInfo(unusedIndex, (x - this.*viewPortRect.x) / this.*scaleX,
(y - this.*viewPortRect.y) / this.*scaleY);
@

hi - thanks for that - i’ve got the game scaling nicely to fit the screen on initial load as suggested using:
cc.EGLView.getInstance().setDesignResolutionSize([my_game_width],[my_game_height],cc.RESOLUTION_POLICY.SHOW_ALL);

now when I handle the orientation change if the user goes from landscape to portrait, how should I resize the application so that it is all visible still? calling the same method does not work.

fix for this:

the *adjustSize method in cc.EGLView was not getting the new browser window size - adding the following to the beginning of the method does this:
var ele = ? document.documentElement : cc.container.parentNode;
this.*screenSize = cc.size(ele.clientWidth, ele.clientHeight);

am also adding the same listener for “orientationChange” events as the existing one for “resize” events in the initialize method