Android 魔塔小遊戲--界面設計以及方向鍵設計(一)

本人自小玩魔塔遊戲長大的,當時學習機上的50層魔塔玩了不知道多少遍了,現在做了碼農一枚,非常希望可以製作一款自己的魔塔,於是花費了一點時間,斷斷續續的完成了一款運行於Android上的魔塔小遊戲。本人不是專門編寫Android程序的,所以肯定很多方面考慮的不完善,歡迎大家指教。

遊戲運行的效果就是這個樣子的了,當作這麼不專業的界面是我自己設計的,也並沒有美工不是,地圖都是自己製作的,詳情請參見https://blog.csdn.net/dongze2/article/details/90769387

實現了怪物掉血查看,快速上下樓,以及保存和加載遊戲

沒有實現的便是打鬥界面,由於在我看來這個不太實用,強行延長我打遊戲的時間,影響我打遊戲的心情,所以我就沒有加上

全部文章將會分爲以下幾部分

一、界面的製作以及方向鍵設計

二、地圖的加載

三、怪物的生成和運動

四、主人公移動的判斷

五、怪物查看和上下樓的實現

六、保存和加載的實現

 

界面是分爲左中右三段,中間的是遊戲界面,在我的設計裏,遊戲界面是運行時加載的,所以xml文件裏只有左和右兩部分。左面一個LinearLayout,內部豎直八等分,即所有height設置爲0,weight設置爲1。右面放一些必要的按鈕,下面放上方向鍵。代碼如下:

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:id="@+id/layout1"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    tools:context="com.lidongze.mota.MainActivity"
    android:orientation="horizontal">
    <LinearLayout
        android:layout_width="wrap_content"
        android:layout_height="match_parent"

        android:layout_marginLeft="10dp"
        android:layout_marginRight="10dp"
        android:orientation="vertical" >

        <LinearLayout
            android:layout_width="match_parent"
            android:layout_height="0dp"
            android:layout_weight="1"
            android:orientation="horizontal" >
            <TextView
                android:id="@+id/stair"
                android:layout_width="wrap_content"
                android:layout_height="match_parent"
                android:gravity="start|center_vertical"
                android:drawableLeft="@drawable/up_floor"
                android:drawableStart="@drawable/up_floor"
                android:drawablePadding="10dp"
                android:paddingStart="10dp"
                android:paddingLeft="10dp"
                android:paddingRight="10dp"
                android:textColor="#ffffffff"
                android:text="1"
                android:textSize="14sp" />
        </LinearLayout>

        <LinearLayout
            android:layout_width="match_parent"
            android:layout_height="0dp"
            android:layout_weight="1"
            android:orientation="horizontal" >

            <TextView
                android:id="@+id/life"
                android:layout_width="wrap_content"
                android:layout_height="match_parent"
                android:gravity="start|center_vertical"
                android:drawableLeft="@drawable/icon_6"
                android:drawableStart="@drawable/icon_6"
                android:drawablePadding="10dp"
                android:paddingStart="10dp"
                android:paddingLeft="10dp"
                android:paddingRight="10dp"
                android:textColor="#ffffffff"
                android:textSize="14sp" />
        </LinearLayout>

        <LinearLayout
            android:layout_width="match_parent"
            android:layout_height="0dp"
            android:layout_weight="1"
            android:orientation="horizontal" >

            <TextView
                android:id="@+id/attack_power"
                android:layout_width="wrap_content"
                android:layout_height="match_parent"
                android:gravity="start|center_vertical"
                android:drawableLeft="@drawable/icon_7"
                android:drawableStart="@drawable/icon_7"
                android:drawablePadding="10dp"
                android:paddingStart="10dp"
                android:paddingLeft="10dp"
                android:paddingRight="10dp"
                android:textColor="#ffffffff"
                android:textSize="14sp" />
        </LinearLayout>

        <LinearLayout
            android:layout_width="match_parent"
            android:layout_height="0dp"
            android:layout_weight="1"
            android:orientation="horizontal" >

            <TextView
                android:id="@+id/defensive_power"
                android:layout_width="wrap_content"
                android:layout_height="match_parent"
                android:gravity="start|center_vertical"
                android:drawableLeft="@drawable/icon_5"
                android:drawableStart="@drawable/icon_5"
                android:drawablePadding="10dp"
                android:paddingStart="10dp"
                android:paddingLeft="10dp"
                android:paddingRight="10dp"
                android:textColor="#ffffffff"
                android:textSize="14sp" />
        </LinearLayout>

        <LinearLayout
            android:layout_width="match_parent"
            android:layout_height="0dp"
            android:layout_weight="1"
            android:orientation="horizontal" >

            <TextView
                android:id="@+id/money"
                android:layout_width="wrap_content"
                android:layout_height="match_parent"
                android:gravity="start|center_vertical"
                android:drawableLeft="@drawable/icon_4"
                android:drawableStart="@drawable/icon_4"
                android:drawablePadding="10dp"
                android:paddingStart="10dp"
                android:paddingLeft="10dp"
                android:paddingRight="10dp"
                android:textColor="#ffffffff"
                android:textSize="14sp" />
        </LinearLayout>

        <LinearLayout
            android:layout_width="match_parent"
            android:layout_height="0dp"
            android:layout_weight="1"
            android:orientation="horizontal" >

            <TextView
                android:id="@+id/yellow_key"
                android:layout_width="wrap_content"
                android:layout_height="match_parent"
                android:gravity="start|center_vertical"
                android:drawableLeft="@drawable/icon_1"
                android:drawableStart="@drawable/icon_1"
                android:drawablePadding="10dp"
                android:paddingStart="10dp"
                android:paddingLeft="10dp"
                android:paddingRight="10dp"
                android:textColor="#ffffffff"
                android:textSize="14sp" />
        </LinearLayout>

        <LinearLayout
            android:layout_width="match_parent"
            android:layout_height="0dp"
            android:layout_weight="1"
            android:orientation="horizontal" >

            <TextView
                android:id="@+id/blue_key"
                android:layout_width="wrap_content"
                android:layout_height="match_parent"
                android:gravity="start|center_vertical"
                android:drawableLeft="@drawable/icon_2"
                android:drawableStart="@drawable/icon_2"
                android:drawablePadding="10dp"
                android:paddingStart="10dp"
                android:paddingLeft="10dp"
                android:paddingRight="10dp"
                android:textColor="#ffffffff"
                android:textSize="14sp" />
        </LinearLayout>

        <LinearLayout
            android:layout_width="match_parent"
            android:layout_height="0dp"
            android:layout_weight="1"
            android:orientation="horizontal" >

            <TextView
                android:id="@+id/red_key"
                android:layout_width="wrap_content"
                android:layout_height="match_parent"
                android:gravity="start|center_vertical"
                android:drawableLeft="@drawable/icon_3"
                android:drawableStart="@drawable/icon_3"
                android:drawablePadding="10dp"
                android:paddingStart="10dp"
                android:paddingLeft="10dp"
                android:paddingRight="10dp"
                android:textColor="#ffffffff"
                android:textSize="14sp" />
        </LinearLayout>
    </LinearLayout>
    <LinearLayout
        android:id="@+id/layout2"
        android:orientation="horizontal"
        android:layout_width="wrap_content"
        android:layout_height="match_parent" />
    <RelativeLayout
        android:layout_width="wrap_content"
        android:layout_height="match_parent"
        android:id="@+id/direction_layout">
        <LinearLayout
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:id="@+id/imageButton_layout"
            android:orientation="horizontal">

        <ImageButton android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:src="@drawable/s41_b"
            android:id="@+id/lookButton"/>
        <ImageButton android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:src="@drawable/up_down_label"
            android:layout_toRightOf="@id/lookButton"
            android:id="@+id/up_downButton"/>
        </LinearLayout>
        <LinearLayout
            android:layout_width="match_parent"
            android:layout_height="match_parent"
            android:layout_below="@id/imageButton_layout"
            android:orientation="vertical">
            <Button
                android:layout_width="match_parent"
                android:layout_height="wrap_content"
                android:id="@+id/save_button"
                android:text="保存遊戲"
                android:layout_below="@id/lookButton"/>
            <Button
                android:layout_width="match_parent"
                android:layout_height="wrap_content"
                android:id="@+id/load_button"
                android:text="加載遊戲"
                android:layout_below="@id/save_button"/>
            <LinearLayout
                android:layout_height="wrap_content"
                android:layout_width="match_parent"
                android:layout_weight="1">
            </LinearLayout>
            <com.lidongze.mota.DirectionButton
                android:id="@+id/direction"
                android:layout_width="match_parent"
                android:layout_height="match_parent"
                android:layout_weight="0"
                android:layout_gravity="center_horizontal"
                android:alpha="0.7"
                android:padding="20dp" />
            <LinearLayout
                android:layout_height="wrap_content"
                android:layout_width="match_parent"
                android:layout_weight="1">
            </LinearLayout>

        </LinearLayout>


    </RelativeLayout>

</LinearLayout>

其中那個醜陋的方向鍵是我自己畫的,原諒我不具有藝術細胞。我給方向鍵起名爲DirectionButton,繼承的是View類。當然,爲了區分上下左右四個方向被按下,這裏需要五張圖片。我給方向鍵在四個方向上分別給上光照效果,便生成了四張圖片

在不同的手機上,該按鈕大小肯定是不一樣的,在更新的時候,需要對它進行縮放

 

    private void init() {
        picture_width=direction.getWidth();
        picture_height=direction.getHeight();
        float scaleWidth = ((float) radius) / picture_width;
        float scaleHeight = ((float) radius) / picture_height;
        // 取得想要縮放的matrix參數
        Matrix matrix = new Matrix();
        matrix.postScale(scaleWidth, scaleHeight);
        // 得到新的圖片
        direction = Bitmap.createBitmap(direction, 0, 0, picture_width, picture_height, matrix,
                true);
        right_direction = Bitmap.createBitmap(right_direction, 0, 0, picture_width, picture_height, matrix,
                true);
        up_direction = Bitmap.createBitmap(up_direction, 0, 0, picture_width, picture_height, matrix,
                true);
        left_direction = Bitmap.createBitmap(left_direction, 0, 0, picture_width, picture_height, matrix,
                true);
        down_direction = Bitmap.createBitmap(down_direction, 0, 0, picture_width, picture_height, matrix,
                true);
        bitmap=direction;

    }

按鍵的時候,需要檢測其按下的是哪個方向,首先,圖片的中間以及兩個方向的邊界肯定是不予判斷的,這裏選取了絕對值50,然後調用接口函數,回調函數longCheck是用於檢測一個按鈕是否被長時間按下,如果長時間按下一個方向,主角便會變爲跑步,節約時間。setBitmap函數會判斷具體哪個按鍵被按下,從而更新圖片和調用接口函數

​
    @Override
    public boolean onTouchEvent(MotionEvent event) {


        final float x=event.getX();
        final float y=event.getY();
        switch (event.getAction()){
            case MotionEvent.ACTION_DOWN:
                //中間值不予判定
                if(Math.abs(x-y)<50||Math.abs(x+y-bound)<50) return true;
                //根據y和x大小,及y與x的和進行判定,四塊四個按鈕
                setBitmap(x,y);
                break;
            case MotionEvent.ACTION_MOVE:
                if(Math.abs(x-y)<50||Math.abs(x+y-bound)<50)
                {
                    if(directionlistener!=null)
                    {
                        directionlistener.cancel();
                    }
                    bitmap=direction;
                    removeCallbacks(longCheck);
                    isTouch=false;
                    i=0;
                }
                else
                {
                    if (!isTouch)
                    {
                        setBitmap(x,y);
                    }
                }

                break;
            case MotionEvent.ACTION_UP:
                if(directionlistener!=null)
                {
                    directionlistener.cancel();
                }
                removeCallbacks(longCheck);
                i=0;
                bitmap=direction;
                isTouch=false;
                 break;

        }
        invalidate();
        return true;
    }

​
  private void setBitmap(float x,float y)
    {
        //查看哪個方向被按下
        if(x>y)
    {
        if(x+y<bound)
        {
            flag=DirectionListener.DIRECTION_UP;
            if (directionlistener!=null)
            directionlistener.direction_go(false,flag);
            bitmap=up_direction;
        }else
        {
            flag=DirectionListener.DIRECTION_RIGHT;
            if (directionlistener!=null)
            directionlistener.direction_go(false,flag);
            bitmap=right_direction;
        }
    }else
    {
        if(x+y<bound)
        {
            flag=DirectionListener.DIRECTION_LEFT;
            if (directionlistener!=null)
            directionlistener.direction_go(false,flag);
            bitmap=left_direction;
        }else
        {
            flag=DirectionListener.DIRECTION_DOWN;
            if (directionlistener!=null)
            directionlistener.direction_go(false,flag);
            bitmap=down_direction;
        }
    }
        isTouch=true;
    //檢測長時間按下
        postDelayed(longCheck,250);}

長按方法的實現,線程反覆調用自己去持續檢測按鈕是否被按下,從而調用接口函數,一旦鬆開,線程也就不再調用自己了

class LongCheck implements Runnable
    {

        @Override
        public void run() {

            if(isTouch)
            {
                if(i==1) {
                    if (directionlistener!=null)
                    directionlistener.direction_go(DirectionListener.LONG_DIRECTION,flag);
                    return;
                }
                postDelayed(longCheck,250);
                i++;
            }
            else {
                i = 0;
                if (directionlistener != null)
                    directionlistener.cancel();
            }

        }
    }

當然,該類中具體的實現方法全都是調用接口,實現還需結合遊戲本身,接口如下所示,規定了上下左右,和兩個方法,direction_go不但傳遞方向,還傳遞長時間按下這個信息。

    interface DirectionListener
    {
        final static int DIRECTION_UP=0;
        final static int DIRECTION_LEFT=1;
        final static int DIRECTION_DOWN=2;
        final static int DIRECTION_RIGHT=3;
        final static boolean LONG_DIRECTION=true;
        void direction_go(boolean isLong,int direction);
        void cancel();
    }

制此,界面便設計完畢了。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章