игровое поле шире экрана android studio

201
31 мая 2018, 07:00

Подскажите, как сделать игровое поле шире экрана устройства? Чтобы можно было сдвигать, например комнату, видеть и взаимодействовать с объектами (мебелью), находящимися вне экрана, но выдвигаемых с комнатой на экран. Перелистывание страниц не подходит, хочется чтобы картинка комнаты была целой.

Answer 1

Можете использовать HorizontalScrollView

<HorizontalScrollView 
xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="wrap_content"
android:layout_height="wrap_content">
<ImageView
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:contentDescription="@null"
    android:scaleType="center"
    android:src="@drawable/room" />
</HorizontalScrollView>

Answer 2

Попробуйте такой FrameLayout, куда поместите всё, что надо. В своё время успешно использовал его для игры с большим зумящимся полем. ScaleGestureDetector добавлял для того, чтобы поле корректно отлавливало onTouch, onClick и onLongClick

public class ZoomLayout extends FrameLayout implements ScaleGestureDetector.OnScaleGestureListener {
    private enum Mode {
        NONE,
        DRAG,
        ZOOM
    }
    public static boolean DRAGGING  =false;
    private static final float MIN_ZOOM = 1.0f;
    private static final float MAX_ZOOM = 4.0f;
    private Mode mode = Mode.NONE;
    private float scale = 1.0f;
    private float lastScaleFactor = 0f;
    // Where the finger first  touches the screen
    private float startX = 0f;
    private float startY = 0f;
    // How much to translate the canvas
    private float dx = 0f;
    private float dy = 0f;
    private float prevDx = 0f;
    private float prevDy = 0f;
    ScaleGestureDetector scaleDetector;
    public ZoomLayout(Context context) {
        super(context);
        init(context);
    }
    public ZoomLayout(Context context, AttributeSet attrs) {
        super(context, attrs);
        init(context);
    }
    public ZoomLayout(Context context, AttributeSet attrs, int defStyle) {
        super(context, attrs, defStyle);
        init(context);
    }
    @Override
    public boolean onInterceptTouchEvent(MotionEvent ev) {
        boolean upper = super.onInterceptTouchEvent(ev);
        DRAGGING = false;
        if (!upper) {
            switch (ev.getAction() & MotionEvent.ACTION_MASK) {
                case MotionEvent.ACTION_DOWN:
                    if (scale > MIN_ZOOM) {
                        mode = Mode.DRAG;
                        startX = ev.getX() - prevDx;
                        startY = ev.getY() - prevDy;
                    }
                    break;
                case MotionEvent.ACTION_MOVE:
                    DRAGGING = true;
                    if (mode == Mode.DRAG) {
                        dx = ev.getX() - startX;
                        dy = ev.getY() - startY;
                    }
                    break;
                case MotionEvent.ACTION_POINTER_DOWN:
                    mode = Mode.ZOOM;
                    break;
                case MotionEvent.ACTION_POINTER_UP:
                    mode = Mode.DRAG;
                    break;
                case MotionEvent.ACTION_UP:
                    mode = Mode.NONE;
                    prevDx = dx;
                    prevDy = dy;
                    break;
            }
            scaleDetector.onTouchEvent(ev);
            if ((mode == Mode.DRAG && scale >= MIN_ZOOM) || mode == Mode.ZOOM) {
               rescale();
            }
        }
        return upper;
    }
    private void init(Context context) {
        scaleDetector = new ScaleGestureDetector(context, this);
        this.setOnTouchListener(new View.OnTouchListener() {
            @Override
            public boolean onTouch(View view, MotionEvent motionEvent) {
                return true;
            }
        });
    }
    public void setScale(float scale) {
        this.scale = scale;
    }
    public void rescale() {
        for (int i = 0; i < getChildCount(); i++) {
            getParent().requestDisallowInterceptTouchEvent(true);
            float maxDx = (child(i).getWidth() - (child(i).getWidth() / scale)) / 2 * scale;
            float maxDy = (child(i).getHeight() - (child(i).getHeight() / scale)) / 2 * scale;
            dx = Math.min(Math.max(dx, -maxDx), maxDx);
            dy = Math.min(Math.max(dy, -maxDy), maxDy);
            applyScaleAndTranslation(i);
        }
    }
    @Override
    public boolean onScaleBegin(ScaleGestureDetector scaleDetector) {
        return true;
    }
    @Override
    public boolean onScale(ScaleGestureDetector scaleDetector) {
        float scaleFactor = scaleDetector.getScaleFactor();
        if (lastScaleFactor == 0 || (Math.signum(scaleFactor) == Math.signum(lastScaleFactor))) {
            scale *= scaleFactor;
            scale = Math.max(MIN_ZOOM, Math.min(scale, MAX_ZOOM));
            lastScaleFactor = scaleFactor;
        } else {
            lastScaleFactor = 0;
        }
        return true;
    }
    @Override
    public void onScaleEnd(ScaleGestureDetector scaleDetector) {
    }
    private void applyScaleAndTranslation(int i) {
        child(i).setScaleX(scale);
        child(i).setScaleY(scale);
        child(i).setTranslationX(dx);
        child(i).setTranslationY(dy);
    }
    private View child(int i) {
        return getChildAt(i);
    }
}
READ ALSO
Как скачать файл из интернета Java

Как скачать файл из интернета Java

Имеется ссылка вида https://

183
Повторный ввод логина и пароля при запуске приложения. Tomcat

Повторный ввод логина и пароля при запуске приложения. Tomcat

В моем тестовом приложении настроена аутентификация через фильтрыПри первом запуске программы, нужно вводить дважды логин и пароль, потому...

244
Получения всех ключей child&#39;ов. Firebase

Получения всех ключей child'ов. Firebase

В моем приложении используется Firebase databse и имеет следующую структуру:

204