Table of contents
- Should my game allow for orientation changes?
- When you don't adjust for orientation changes
- What is the UI in a C++ game
- Renderer
My app on the Google play store
MINI GAME VERSION NOW LIVE!!!!
- The app
My app's GitHub code
Resources:
Should my game allow for orientation changes?
- The honest answer is probably not. If we look an any large mobile game(100 million+ downloads), we can notice that most of them are either locked into landscape or portrait mode. But lets be honest here... the games we build probably aren't going to get a 100 million downloads. So our games should adjust for orientation changes. It helps with user experience and its a fun little challenge
When you don't adjust for orientation changes
- Below is the UI for my little Dino Run clone game
- Portrait mode:
- Landscape mode with only one square adjusted to show the problems:
- As you can see if the squares are not adjusted for the orientation change, they will become distorted.
What code to call for orientation changes
- The GitHub code I used to create my game
- In order for us to show C++ code to our user we need to implement GLSurfaceView and then implement a Renderer and then implement a JNI class and finally we can call C++ code.
- A bit of a long process but that is just how we have to do it
What is the UI in a C++ game
- The UI is represented entirely in a Vector that OpenGL uses to create triangles and will be updated during an orientation change:
class TransformShader {
private:
std::vector<GLfloat> m_squareVertices = {
-0.800f, -0.0375f, -0.650f, -0.0375f, -0.650f, 0.0375f,
-0.800f, -0.0375f, -0.650f, 0.0375f, -0.800f, 0.0375f,
0.85f, -0.0375f, 1.0f, -0.0375f, 1.0f, 0.0375f,
0.85f, -0.0375f, 1.0f, 0.0375f, 0.85f, 0.0375f
};
GLuint simpleTriangleProgram;
GLuint vPosition;
bool showCoin = false;
}
- The vector should actually be created and updated dynamically. The static definition that I have above will lead to problems(problems I have delt with). The static definition above is a legacy that I inherited from following THIS tutorial. We will talk more about fixing its issues in the next section of this blog post
Renderer
- My game's own Renderer
During an orientation change the Renderer is going to call onSurfacechange(). When that function is called we need to remove any old vectors and create ones adjusted for the screen's aspect ratio
-
So when the orientation changes we need to do two things:
- 1)
Clear existing Vectors
:IF YOU DO NOT CLEAR OUT THE EXISTING VECTORS THE VERTICIES WILL STACK ONTOP OF EACHOTHER MAKING THE APSECT RATION APPEAR TO NOT CHANGE AND LEAD TO PERFORMANCE ISSUES
(the issue I talked about earlier) - 2)
Add new ones adjusted for aspect ratio
- 1)
Here is my actual C++ code to deal with the orientation changes:
bool TransformShader::setupGraphics(int w, int h) {
simpleTriangleProgram = createProgram(m_glVertexShader, m_glFragmentShader);
if (!simpleTriangleProgram) {
LOGE("Could not create program");
return false;
}
float aspectRatio = (float)w / (float)h;
LOGI("setupGraphicsTestingRatio", "aspectRatio--> %f",aspectRatio);
if(w>h){//determine if portrait or landscape
float scaleFactor = 0.5f; // reduction
// width of the first square
float squareWidth = (-0.650f - (-0.800f)) / aspectRatio * scaleFactor;
// Shift the first square to the left boundary (-1.0)y
float leftBoundary = -1.0f;
float newLeftX = leftBoundary;
float newRightX = leftBoundary + squareWidth;
// Move the square 20% to the right
float shiftAmount = 0.4f;
newLeftX += shiftAmount;
newRightX += shiftAmount;
std::vector<GLfloat> newOneToEdit = {
// First square shifted 20% to the right
newLeftX, (-0.0375f), // Bottom-left vertex
newRightX, (-0.0375f), // Bottom-right vertex
newRightX, (0.0375f), // Top-right vertex
newLeftX, (-0.0375f), // Bottom-left vertex (repeated for the second triangle)
newRightX, (0.0375f), // Top-right vertex
newLeftX, (0.0375f), // Top-left vertex
// Second square not shifted
(0.85f/aspectRatio) * scaleFactor, (-0.0375f), (1.0f/aspectRatio) * scaleFactor, (-0.0375f), (1.0f/aspectRatio) * scaleFactor, ( 0.0375f),
(0.85f/aspectRatio) * scaleFactor, (-0.0375f), (1.0f/aspectRatio) * scaleFactor, (0.0375f), ( 0.85f/aspectRatio) * scaleFactor, (0.0375f)
};
m_squareVertices.clear();
m_squareVertices.insert(m_squareVertices.end(), newOneToEdit.begin(), newOneToEdit.end());
}else{
// vertical display
std::vector<GLfloat> newOneToEdit = {
-0.800f, (-0.0375f) , -0.650f, (-0.0375f), -0.650f, (0.0375f) ,
-0.800f, (-0.0375f) , -0.650f, (0.0375f) , -0.800f, (0.0375f) ,
0.85f, (-0.0375f) , 1.0f, (-0.0375f), 1.0f, ( 0.0375f) ,
0.85f, (-0.0375f) , 1.0f, (0.0375f), 0.85f, (0.0375f)
};
m_squareVertices.clear();
m_squareVertices.insert(m_squareVertices.end(), newOneToEdit.begin(), newOneToEdit.end());
}
vPosition = glGetAttribLocation(simpleTriangleProgram, "vPosition");
glViewport(0, 0, w, h);
// Set up orthographic projection matrix
glUseProgram(simpleTriangleProgram);
LOGI("setupGraphicsTesting", "-----------------------END-----------------------------");
return true;
}
- The code its self is really not that important(its yucky but it works). What we should focus on is that to determine if we are in landscape mode. I checked if the
w
(width) is greater thanh
(height). If that is true then we have to adjust with the aspect ration (width/height) and apply landscape specific adjustments for the layout
Conclusion
- Thank you for taking the time out of your day to read this blog post of mine. If you have any questions or concerns please comment below or reach out to me on Twitter.
Top comments (1)
I have hidden bot comments
Some comments may only be visible to logged-in visitors. Sign in to view all comments. Some comments have been hidden by the post's author - find out more