Open dustinanon opened 13 years ago
Screen Orientation is controlled in manifest file, originally we didn't check the CCDirector's setDeviceOrientation function.
I will merge the commit soon.
Thanks, Weikuan Zhou
2011/7/7 dustinanon < reply@reply.github.com>
If you first set the orientation to Landscape, then change to Portrait (or visa versa) and add sprites to a scene, then the sprite will be rotated and positioned correctly, but the dimensions will be wrong.
That is, what was once the width is now the height, and what was once the height is now the width. This makes wide objects look squished horizontally and make tall objects look squished vertically.
I'm trying to fix the problem now, but I don't know if it's been encountered before.
Reply to this email directly or view it on GitHub: https://github.com/ZhouWeikuan/cocos2d/issues/21
Ah, fantastic :D
Thanks for the fast response!
Any luck? I'm on a bit of a tight schedule, sadly, so if a fix can't be posted, then is there a known workaround?
Thanks again!
Oh, I thought you sent a commit yesterday, but not.. We didnt' have a fix for this yet.
Thanks, Weikuan Zhou
2011/7/8 dustinanon < reply@reply.github.com>
Any luck? I'm on a bit of a tight schedule, sadly, so if a fix can't be posted, then is there a known workaround?
Thanks again!
Reply to this email directly or view it on GitHub: https://github.com/ZhouWeikuan/cocos2d/issues/21#issuecomment-1529057
Ah, I see... is all of that controlled in CCDirector? I'm not quite sure what the problem is, because I can't find exactly where the coordinate translations and CCNode transformations take place when you change the orientation.
No, there is no transform about the coordinates. When I translated the code from obj-c, I removed them.. Originally, I assume the orientation is controlled only by manifest.
2011/7/8 dustinanon < reply@reply.github.com>
Ah, I see... is all of that controlled in CCDirector? I'm not quite sure what the problem is, because I can't find exactly where the coordinate translations and CCNode transformations take place when you change the orientation.
Reply to this email directly or view it on GitHub: https://github.com/ZhouWeikuan/cocos2d/issues/21#issuecomment-1530571
Alright man, I'm going crazy. If I try to apply OpenGL transforms then I get the following exception:
E/AndroidRuntime(11653): FATAL EXCEPTION: GLThread 29 E/AndroidRuntime(11653): java.util.ConcurrentModificationException E/AndroidRuntime(11653): at java.util.WeakHashMap$HashIterator.next(WeakHashMap.java:165) E/AndroidRuntime(11653): at org.cocos2d.opengl.GLResourceHelper$2.perform(GLResourceHelper.java:87) E/AndroidRuntime(11653): at org.cocos2d.opengl.GLResourceHelper.update(GLResourceHelper.java:122) E/AndroidRuntime(11653): at org.cocos2d.nodes.CCDirector.drawCCScene(CCDirector.java:702) E/AndroidRuntime(11653): at org.cocos2d.nodes.CCDirector.onDrawFrame(CCDirector.java:667) E/AndroidRuntime(11653): at org.cocos2d.opengl.GLSurfaceView$GLThread.guardedRun(GLSurfaceView.java:1245) E/AndroidRuntime(11653): at org.cocos2d.opengl.GLSurfaceView$GLThread.run(GLSurfaceView.java:1056)
I'm going a little bit crazy figuring out exactly the best way to do this stuff... are you at all familiar with the problem I'm having?
To replicate it, create and run a scene and add a few sprites. Then switch the orientation. You'll see that the dimensions displayed on the screen are something crazy (in my case, it was roughly 700x700) and that all the sprites will be distorted.
This is what I'm trying to correct. Do you have any advice on where to look?
Thanks for your help and patience!
What about create two activity and one for landscape, one for portrait?
2011/7/12 dustinanon < reply@reply.github.com>
Alright man, I'm going crazy. If I try to apply OpenGL transforms then I get the following exception:
E/AndroidRuntime(11653): FATAL EXCEPTION: GLThread 29 E/AndroidRuntime(11653): java.util.ConcurrentModificationException E/AndroidRuntime(11653): at java.util.WeakHashMap$HashIterator.next(WeakHashMap.java:165) E/AndroidRuntime(11653): at org.cocos2d.opengl.GLResourceHelper$2.perform(GLResourceHelper.java:87) E/AndroidRuntime(11653): at org.cocos2d.opengl.GLResourceHelper.update(GLResourceHelper.java:122) E/AndroidRuntime(11653): at org.cocos2d.nodes.CCDirector.drawCCScene(CCDirector.java:702) E/AndroidRuntime(11653): at org.cocos2d.nodes.CCDirector.onDrawFrame(CCDirector.java:667) E/AndroidRuntime(11653): at org.cocos2d.opengl.GLSurfaceView$GLThread.guardedRun(GLSurfaceView.java:1245) E/AndroidRuntime(11653): at org.cocos2d.opengl.GLSurfaceView$GLThread.run(GLSurfaceView.java:1056)
I'm going a little bit crazy figuring out exactly the best way to do this stuff... are you at all familiar with the problem I'm having?
To replicate it, create and run a scene and add a few sprites. Then switch the orientation. You'll see that the dimensions displayed on the screen are something crazy (in my case, it was roughly 700x700) and that all the sprites will be distorted.
This is what I'm trying to correct. Do you have any advice on where to look?
Thanks for your help and patience!
Reply to this email directly or view it on GitHub: https://github.com/ZhouWeikuan/cocos2d/issues/21#issuecomment-1551717
that's not quite an ideal solution because I can't use any page turn transitions... apparently something was stripped out of cocos2d-iphone during the port... my coworker can easily switch the page orientation, but I can't quite find what the difference in code is..
Okay, so if you try to set the screen size twice then you get the same error. I think that the problem lies in the fact that you need to do:
CCDirector.sharedDirector().setScreenSize(h, w) when switching, but opengl doesn't like you to just change like that... hmmm
okay, continuing forward, changing the screensize does appear to be necessary. I figured out that the issue is that whenever you change orientation in Android, the system destroys the Activity (going through the entire lifecycle) and recreates it.
This causes a race condition in the GLThread, particularly when iterating through the WeakHashMap reloadMap.
The best thing I have come up with so far is to add the following property to your activity node in AndroidManifest.xml :
android:configChanges="orientation"
which causes the Activity to not be destroyed when the orientation is switched. This allows me to switch orientation freely.
However, when I switch to Portrait orientation, cocos2d shows about 150 ~ 200 pixels of black space at the top of the screen and I can't figure out how to move the display region back up.
So... that's my progress so far -__-
Hello dustinanon,
I believe than an activity can be destroyed also in some other cases, not only during orientation change.
I found the following solution (almost a solution to be honest).
I followed http://developer.android.com/reference/android/opengl/GLSurfaceView.html and http://developer.android.com/guide/topics/resources/runtime-changes.html#RetainingAnObject and modified my activity as written in the code below.
It works fine (at least in AVD as I don't have android device yet) except you need to restart all actions. This probably can be solved by adding public method to CCActionManager to get/set private "targets" field and retain it also.
public class CocosTest extends Activity {
private CCGLSurfaceView mainView;
/** Called when the activity is first created. */
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
requestWindowFeature(Window.FEATURE_NO_TITLE);
getWindow().setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN,
WindowManager.LayoutParams.FLAG_FULLSCREEN);
getWindow().setFlags(WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON,
WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON);
// setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_LANDSCAPE);
mainView = new CCGLSurfaceView(this);
setContentView(mainView);
CCDirector.sharedDirector().attachInView(mainView);
//CCDirector.sharedDirector().setDeviceOrientation(CCDirector.kCCDeviceOrientationLandscapeLeft);
CCDirector.sharedDirector().setDisplayFPS(true);
CCDirector.sharedDirector().setAnimationInterval(1.0/60);
Object prevScene = getLastNonConfigurationInstance();
if((prevScene!=null)&&(prevScene instanceof CCScene))
CCDirector.sharedDirector().runWithScene((CCScene)prevScene);
else
CCDirector.sharedDirector().runWithScene(SpriteTestLayer.getScene());
}
@Override
public void onStart() {
super.onStart();
}
@Override
public void onPause() {
super.onPause();
CCDirector.sharedDirector().pause();
mainView.onPause();
}
@Override
public void onResume() {
super.onResume();
mainView.onResume();
CCDirector.sharedDirector().resume();
}
@Override
public void onDestroy() {
super.onDestroy();
CCDirector.sharedDirector().end();
}
@Override
public Object onRetainNonConfigurationInstance () {
return CCDirector.sharedDirector().getRunningScene();
}
/**
@Override
public void onConfigurationChanged(Configuration newConfig) {
super.onConfigurationChanged(newConfig);
}
*/
}
Best Regards, Petr Boklashov
If you first set the orientation to Landscape, then change to Portrait (or visa versa) and add sprites to a scene, then the sprite will be rotated and positioned correctly, but the dimensions will be wrong.
That is, what was once the width is now the height, and what was once the height is now the width. This makes wide objects look squished horizontally and make tall objects look squished vertically.
I'm trying to fix the problem now, but I don't know if it's been encountered before.