0

I am working on a pong clone and I am currently using hard code pixel values for assigning the UI elements like paddles and the ball.

package com.nblsoft.ballpractise;

import android.content.Context;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.graphics.Rect;
import android.view.MotionEvent;
import android.view.View;



public class BallDraw extends View {

    //Default System Variables

    int screenHeight = getResources().getDisplayMetrics().heightPixels;
    int screenWidth = getResources().getDisplayMetrics().widthPixels;

    private int xMin = 0;          // This view's bounds
    private int xMax;
    private int yMin = 0;
    private int yMax;


    //Game Variables

    public int ball_pos_x = 0;
    public int ball_pos_y = 800;
    public int ball_vel_x = 5;
    public int ball_vel_y = 5;
    public int pad_1_pos = 10;
    public int pad_2_pos = 10;
    public int randi=1;
    //Pads Implemented as Array of points
    //public int[] pad_1 = {100,200,220,240};
    //public int[] pad_2 = {100,200,1250,1270};

    Rect pad_1 = new Rect(400 + pad_1_pos,220,500 + pad_1_pos,240);
    Rect pad_2 = new Rect(400 + pad_2_pos,1250,500 + pad_1_pos,1270);

    Rect pad_1_touch = new Rect(0, 0, 1080, 200);
    Rect pad_2_touch = new Rect(0, 1300, 1080, 1500);


    //calculations for screen sizes



    private Paint paint;


    public BallDraw(Context context) {
        super(context);
        paint = new Paint();

        // To enable touch mode
        this.setFocusableInTouchMode(true);
    }


    @Override
    public boolean onTouchEvent(MotionEvent event) {

        int x = (int) event.getX();
        int y = (int) event.getY();

        switch (event.getAction()) {
            case MotionEvent.ACTION_DOWN:
            //case MotionEvent.ACTION_MOVE:

                if(pad_1_touch.contains(x,y)){
                    //pad_1[0]+=10;
                    //pad_1[1]+=10;

                    pad_1.offset(pad_1_pos,0);

                }
                else if(pad_2_touch.contains(x,y)){
                    //pad_2[0]+=10;
                    //pad_2[1]+=10;

                    pad_2.offset(pad_2_pos,0);
                }

        }
        return true; //Event Handled

    }

    @Override
    protected void onDraw(Canvas canvas) {

        paint.setColor(Color.WHITE);

        //Touch Regions (Un-comment to see touch Regions)
        //canvas.drawRect(pad_1_touch,paint);
        //canvas.drawRect(pad_2_touch,paint);

        //Draw Border
        canvas.drawRect(0,800,1080,803,paint);

        //Paddles Draw code
        canvas.drawRect(pad_1,paint);
        canvas.drawRect(pad_2,paint);
        //canvas.drawRect(pad_1[0],pad_1[2], pad_1[1], pad_1[3], paint);
        //canvas.drawRect(pad_2[0],pad_2[2],pad_2[1],pad_2[3],paint);

        //Ball code
        canvas.drawRect(ball_pos_x,ball_pos_y,ball_pos_x + 13, ball_pos_y+13,paint);

        // Update the position of the ball, including collision detection and reaction.
        update();

        // Delay
        try {
            Thread.sleep(30);
        } catch (InterruptedException e) { }

        invalidate();
    }

    @Override
    public void onSizeChanged(int w, int h, int oldW, int oldH) {
        // Set the movement bounds for the ball
        xMax = w-1;
        yMax = h-1;
    }

    private void update(){

        ball_pos_y += ball_vel_y;
        ball_pos_x += ball_vel_x;

        if(pad_1.contains(ball_pos_x,ball_pos_y)){
            ball_vel_y = -ball_vel_y;

        }
        else if(pad_2.contains(ball_pos_x,ball_pos_y)){
            ball_vel_y = -ball_vel_y;

        }
        else if(ball_pos_x >= xMax){
            ball_vel_x = -ball_vel_x;
        }
        else if(ball_pos_y >= yMax){
            ball_init();
        }
        else if(ball_pos_x <= 0){
            ball_vel_x = -ball_vel_x;
        }
        else if(ball_pos_y <= 0){
            ball_init();
        }

    }

    private void ball_init(){
        if (randi == 1){
            randi = -1;
        }
        else{
            randi= 1;
        }

        ball_pos_x=0;
        ball_pos_y=800;
        ball_vel_x=5;
        ball_vel_y=5 * randi;

    }

It works fine with my debug nexus but the screen size is way off for other devices.I am looking for something that the interface remains constant across devices of different sizes. I tried this method so I could get the usable screen area in dips but the calculations are way off. The dpheight and dpwidth are returned as 509 and 316 on my 1920*1080 device. How should I achieve this?

EDIT: Ok I've Figured it out. If I calculate the dips using configuration.screenHeightDp, and then change that dp to pixels, I will get the height of the screen app is running on.

//set screen constrains in dip
    Configuration configuration = this.getResources().getConfiguration();
    int dpHeight = configuration.screenHeightDp; //The current height of the available screen space, in dp units, corresponding to screen height resource qualifier.
    int dpWidth = configuration.screenWidthDp; //The current width of the available screen space, in dp units, corresponding to screen width resource qualifier.
    //conversion methods
 private int dptopixel(int DESIRED_DP_VALUE){

        final float scale = getResources().getDisplayMetrics().density;    
        return (int)((DESIRED_DP_VALUE) * scale + 0.5f);
    }

    private int pixeltodp(int DESIRED_PIXEL_VALUE){

        final float scale = getResources().getDisplayMetrics().density;    
        return (int) ((DESIRED_PIXEL_VALUE) - 0.5f / scale);
    }
Community
  • 1
  • 1
nabeel
  • 425
  • 1
  • 9
  • 22
  • Those aren't off, they look reasonable to me. – Gabe Sechan Feb 21 '16 at 21:33
  • so do I need to Reconvert dpWidth and dpHeight to pixel when I pass them to Rect()? Because now, when I pass dpWidth and dpHeight to the Rect the display is way off. – nabeel Feb 22 '16 at 07:33
  • To what rect? How is the rect used? You probably do, but without your code there's no way to know. Of course if you need pixel dimensions at one point, you probably don't actually need the screen size in dps and you're overcomplicating yourself. – Gabe Sechan Feb 22 '16 at 07:50
  • ok I've editied my question to include my code. Basically I am passing pixel values for my paddles, ball etc. The paddles are a Rect object. The ball is a Rect object. The touch area is also a Rect. This works for my Nexus 5, but on other devices like a galaxy S2 or tab 3.7, The Interface is way off. it gets drawn out side the screen. – nabeel Feb 22 '16 at 09:19

0 Answers0