• After 15+ years, we've made a big change: Android Forums is now Early Bird Club. Learn more here.

Bitmap Rendering Wrong Size - Game Engine

BlinkXIO

Lurker
Sep 4, 2019
3
1
I just put together the foundations for a simple game engine.

I was testing it with a mock background .png image. The image is 360px-640px 16:9. I tried loading it on a Nexus 5 and a Pixel 2 which are both 1080x1920. So the image should take up exactly 1/8th of the screen on both devises.

For some reason though not only is it larger than it should be but on each devise its being rendered at a different size. As you can see in the bellow image on the Pixel (right hand side) its taking up about 2/3rds of the screen and on the Nexus (left hand side) its taking up the whole screen.


image hosting

Anyone know why this might be happening?

Code:
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:dist="http://schemas.android.com/apk/distribution"
    package="com.example.magerush2">

    <dist:module dist:instant="true" />

    <application
        android:allowBackup="true"
        android:icon="@mipmap/ic_launcher"
        android:label="@string/app_name"
        android:roundIcon="@mipmap/ic_launcher_round"
        android:supportsRtl="true"
        android:theme="@style/AppTheme">
        <activity android:name=".GameActivity"
            android:screenOrientation="portrait"
            android:theme="@style/AppTheme.Fullscreen"></activity>

        <activity android:name=".MainActivity"
            android:screenOrientation="portrait"
            android:theme="@style/AppTheme.Fullscreen">
            <intent-filter>
                <action android:name="android.intent.action.MAIN"></action>

                <category android:name="android.intent.category.LAUNCHER" />

            </intent-filter>
        </activity>
    </application>

</manifest>

Java:
package com.example.magerush2;

import androidx.appcompat.app.AppCompatActivity;

import android.content.Intent;
import android.os.Bundle;
import android.view.View;
import android.widget.Button;
import android.widget.TextView;

public class MainActivity extends AppCompatActivity {

    public static final String EXTRA_SOUND = "com.example.magerush2.EXTRA_SOUND";
    public static final String EXTRA_CON = "com.example.magerush2.EXTRA_CON";


    Button Play;
    Button Continue;
    Button Sound;

    TextView txt;

    Boolean soundflip = true;
    Boolean continueflip = false;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        txt = (TextView) findViewById(R.id.textView);
        txt.setText("On");

        Play = (Button) findViewById(R.id.buttonplay);
        Play.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                opengame();

            }
        });

        Continue = (Button) findViewById(R.id.buttoncontinue);
        Continue.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                continueflip = true;
                System.out.println(continueflip);
                opengame();
            }
        });

        Sound = (Button) findViewById(R.id.buttonsound);
        Sound.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                soundflip = !soundflip;
                if (soundflip) txt.setText("On");
                if (!soundflip) txt.setText("Off");
            }
        });

    }



    public void opengame(){
        Intent intent = new Intent(this, GameActivity.class);

        String soundpass = "";
        String conpass = "";

        if (soundflip) soundpass = "1";
        if (!soundflip) soundpass = "0";
        if (continueflip) conpass = "1";
        if (!continueflip) conpass = "0";

        intent.putExtra(EXTRA_SOUND, soundpass);
        intent.putExtra(EXTRA_CON, conpass);

        startActivity(intent);
    }

}


Java:
package com.example.magerush2;

import androidx.appcompat.app.AppCompatActivity;

import android.app.Activity;
import android.content.Intent;
import android.os.Bundle;
import android.view.View;

public class GameActivity extends Activity {

    Boolean soundflip;
    Boolean continueflip;

    private TDView gameView;

    private View decorView;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_game);


        //Get veriables from main screen
        Intent intent = getIntent();
        String sound = intent.getStringExtra(MainActivity.EXTRA_SOUND);
        String con = intent.getStringExtra(MainActivity.EXTRA_CON);

        if (sound.equals("1")) soundflip = true;
        if (sound.equals("0")) soundflip = false;
        if (con.equals("1")) continueflip = true;
        if (con.equals("0")) continueflip = false;

        System.out.println("Sound is: " + soundflip);
        System.out.println("Continue is: " + continueflip);

        gameView = new TDView(this);
        setContentView(gameView);

        decorView = getWindow().getDecorView();

    }

    @Override
    public void onWindowFocusChanged(boolean hasFocus) {
        super.onWindowFocusChanged(hasFocus);

        if(hasFocus){
            decorView.setSystemUiVisibility(View.SYSTEM_UI_FLAG_IMMERSIVE_STICKY | View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN | View.SYSTEM_UI_FLAG_LAYOUT_HIDE_NAVIGATION | View.SYSTEM_UI_FLAG_FULLSCREEN | View.SYSTEM_UI_FLAG_HIDE_NAVIGATION);
        }




    }
    @Override
    protected void onPause() {
        super.onPause();
        gameView.pause();
    }

    @Override
    protected void onResume() {
        super.onResume();
        gameView.resume();
    }

}

Java:
package com.example.magerush2;

import android.content.Context;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.view.SurfaceHolder;
import android.view.SurfaceView;

public class TDView extends SurfaceView implements Runnable {

    volatile Boolean playing;

    Thread gameThread = null;

    Background background;

    public Paint paint;
    public Canvas canvas;
    public SurfaceHolder ourholder;

    public TDView(Context context) {
        super(context);

        ourholder = getHolder();
        paint = new Paint();

        background = new Background(context);
    }

    @Override
    public void run() {
        while (playing) {
            update();
            draw();
            control();
        }
    }


    public void update(){

    }
    public void draw(){

        if (ourholder.getSurface().isValid()){
            canvas = ourholder.lockCanvas();

            canvas.drawColor(Color.argb(255, 0, 0, 0));

            int x = 0;
            int y = 0;

            canvas.drawBitmap(background.getBitmap(), x, y, paint);

            ourholder.unlockCanvasAndPost(canvas);

        }

    }
    public void control(){

    }

    public void pause(){
        playing = false;

        try {
            gameThread.join();
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
    }
    public void resume(){
        playing = true;

        gameThread = new Thread(this);
        gameThread.start();
    }
}

Java:
package com.example.magerush2;

import android.content.Context;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;

public class Background {

    public Bitmap bitmap;

    public Background (Context context){
        bitmap = BitmapFactory.decodeResource(context.getResources(), R.drawable.maintest);
    }

    public Bitmap getBitmap(){
        return bitmap;
    }

}
 
I solved it.

So for some reason the "inScaled" option for BitmapFactory is set to true by default.

I just had to create and change the options with this code inside the Background class.

Java:
BitmapFactory.Options options = new BitmapFactory.Options();
options.inScaled = false;

Then add the option to the bitmap shown bellow

Code:
bitmap = BitmapFactory.decodeResource(context.getResources(), R.drawable.maintest, options);
 
  • Like
Reactions: codesplice
Upvote 0

BEST TECH IN 2023

We've been tracking upcoming products and ranking the best tech since 2007. Thanks for trusting our opinion: we get rewarded through affiliate links that earn us a commission and we invite you to learn more about us.

Smartphones