具体效果如下图:
GitHub地址:
https://github.com/weijifen/AndroidTetris
主要思路:
由于俄罗斯方块的主体部分是由一个个方格组成的,结合Android中有一个GridView网格视图,使用GridView不需要自己画view,可以把主要的精力放在游戏逻辑上面。
项目文件框架图:
游戏展示部分的界面:
<GridView
android:id="@+id/tetrisView"
android:background="@color/colorLine"
android:numColumns="10"
android:layout_width="240dp"
android:layout_height="360dp"
android:horizontalSpacing="0dp"
android:verticalSpacing="0dp">
GridView>
设置游戏界面为 10 × 15 10 \times 15 10×15的方格。方格间距设为0;
item_adapter.xml
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical" android:layout_width="24dp"
android:layout_height="24dp"
>
<ImageView
android:gravity="center"
android:id="@+id/adapter_image"
android:layout_width="23dp"
android:layout_height="23dp" />
LinearLayout>
为了严格限定使每个网格为正方形,设置Adapter尺寸为 24 × 24 24 \times 24 24×24,但是为了显示出网格之间细细的分割线,将ImageView尺寸设置为 23 × 23 23 \times 23 23×23,则分割线的线宽为1dp。分割线的颜色也可以自己设定。
以四个二进制数表示方块的形状。方块最大只能占据四行四列,用一个四行四列的矩阵就可以表示方块的形状,还可以进一步缩减为四个二进制数。
表示方法如下:
{0x8, 0x8, 0xc, 0x0}
表示为二进制为:
1 0 0 0
1 0 0 0
1 1 0 0
0 0 0 0
但是方格以左边为低位更方便,所以变为:
0 0 0 1
0 0 0 1
0 0 1 1
0 0 0 0
所以这是一个形状为反L的方块。
所有的方块表示为:
public static int[][] shape = new int[][]{
{0x8, 0x8, 0xc, 0},
{0xe, 0x8, 0, 0},
{0xc, 0x4, 0x4, 0},
{0x2, 0xe, 0x0, 0x0},
{0x4, 0x4, 0xc, 0x0},
{0x8, 0xe, 0x0, 0x0},
{0xc, 0x8, 0x8, 0x0},
{0xe, 0x2, 0x0, 0x0},
{0x8, 0xc, 0x4, 0x0},
{0x6, 0xc, 0x0, 0x0},
{0x4, 0xc, 0x8, 0x0},
{0xc, 0x6, 0x0, 0x0},
{0x4, 0xe, 0x0, 0x0},
{0x8, 0xc, 0x8, 0x0},
{0xe, 0x4, 0x0, 0x0},
{0x4, 0xc, 0x4, 0x0},
{0x4, 0x4, 0x4, 0x4},
{0x0, 0xf, 0x0, 0x0},
{0xc, 0xc, 0x0, 0x0}
};
这里使用五种仅仅颜色不同的方块来表现不同的方块颜色。
把不同颜色的id都放进StateFang的数组中,使用的时候利用0~4的下标就可以找到该颜色的方块图片。
public static int[] color = new int[] {
R.drawable.star_b, R.drawable.star_g, R.drawable.star_p, R.drawable.star_r, R.drawable.star_y
};
最后在BlockAdapter中显示
public class BlockAdapter extends CommonAdapter {
Context context;
List<Integer> mDatas;
public BlockAdapter( Context context, List mDatas, int mLayoutId )
{
super(context, mDatas, mLayoutId);
this.context = context;
this.mDatas = mDatas;
}
@Override
public void convert( ViewHolder helper, Object item )
{
ImageView imageView = helper.getView( R.id.adapter_image );
Integer integer = (Integer) item;
if ( integer > 0 )
{
imageView.setImageResource( StateFang.color[integer - 1] );
}else {
imageView.setBackgroundColor( Color.parseColor( "#29505B" ) );
}
}
}
这里也可以选择使用Glide等图片加载器加载图片。
感兴趣的朋友请继续阅读Android使用GridView实现俄罗斯方块(附源码)(二)