1.实现方式
*使用安卓开发实现
*使用开发工具:AndroidStudio
2.样例展示
1.游戏开始样例
2.游戏进行中
3.游戏暂停
4.游戏结束
3.代码展示
* 1.结构说明:控制显示的xml文件和逻辑控制的java代码组成
* 2.布局说明:主要是三部分布局:游戏部分,底部的button部分,以及右侧的状态显示部分和开始、暂停按钮部分
* 3.游戏窗口的线的绘制、游戏方格的绘制均由java代码实现
* 4.游戏方块的生成是创建相应的对象
* 5.不同方块的下落利用随机数实现
1.页面布局xml
xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical"
android:background="#67C6F1">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:padding="10dp"
android:orientation="horizontal">
<FrameLayout
android:id="@+id/layoutGame"
android:layout_width="wrap_content"
android:layout_height="wrap_content">
</FrameLayout>
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_gravity="bottom"
android:orientation="vertical">
<Button
android:id="@+id/btnStart"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_weight="1"
android:text="Start"/>
<Button
android:id="@+id/btnPause"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_weight="1"
android:text="Pause"/>
</LinearLayout>
</LinearLayout>
<LinearLayout
android:layout_width="match_parent"
android:layout_height="60dp"
android:orientation="horizontal">
<Button
android:id="@+id/btnLeft"
android:layout_width="0dp"
android:layout_height="match_parent"
android:layout_weight="1"
android:text="左"
android:textSize="25dp"/>
<Button
android:id="@+id/btnTop"
android:layout_width="0dp"
android:layout_height="match_parent"
android:layout_weight="1"
android:text="上"
android:textSize="25dp"/>
<Button
android:id="@+id/btnRight"
android:layout_width="0dp"
android:layout_height="match_parent"
android:layout_weight="1"
android:text="右"
android:textSize="25dp"/>
<Button
android:id="@+id/btnBottom"
android:layout_width="0dp"
android:layout_height="match_parent"
android:layout_weight="1"
android:text="下"
android:textSize="25dp"/>
</LinearLayout>
<LinearLayout
android:layout_width="match_parent"
android:layout_height="60dp"
android:orientation="horizontal">
<TextView
android:layout_width="0dp"
android:layout_height="match_parent"
android:layout_weight="1"
android:textStyle="bold"
android:text="power by android"
android:textSize="18dp"
android:gravity="center"
/>
</LinearLayout>
</LinearLayout>
2.后台逻辑
package com.example.i;
import android.annotation.SuppressLint;
import android.content.Context;
import android.graphics.Canvas;
import android.graphics.Paint;
import android.graphics.Point;
import android.os.Handler;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.util.DisplayMetrics;
import android.util.Log;
import android.view.View;
import android.view.Window;
import android.view.WindowManager;
import android.widget.FrameLayout;
import android.widget.Toast;
import java.util.Random;
public class MainActivity extends AppCompatActivity implements View.OnClickListener {
View view;
int xWidth,xHight;
Paint mapPaint;
Paint linepaint;
Paint boxPaint;
Paint startPaint;
boolean [][]maps;
Point[] boxs;
final int TYPE = 7;
int boxType;
int boxSize;
public Thread downThread;
public Handler handler=new Handler(){
public void handleMessage(android.os.Message msg){
view.invalidate();
};
};
public boolean isPause;
public boolean isOver;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
getSupportActionBar().hide();
setContentView(R.layout.activity_main);
intData();
newBoxs();
initView();
intLister();
}
public void intData(){
int width=getScreeWidth(this);
xWidth=width * 2/3;
xHight=2 * xWidth;
maps=new boolean[10][20];
boxSize=xWidth/maps.length;
}
public void newBoxs(){
Random random=new Random();
boxType=random.nextInt(7);
switch (boxType){
case 0:
boxs=new Point[]{new Point(4,0),new Point(5,0),new Point(4,1),new Point(5,1)};
break;
case 1:
boxs=new Point[]{new Point(4,1),new Point(5,0),new Point(3,1),new Point(5,1)};
break;
case 2:
boxs=new Point[]{new Point(4,1),new Point(3,0),new Point(3,1),new Point(5,1)};
break;
case 3:
boxs=new Point[]{new Point(3,0),new Point(4,0),new Point(5,0),new Point(6,0)};
break;
case 4:
boxs=new Point[]{new Point(4,1),new Point(5,0),new Point(5,1),new Point(6,1)};
break;
case 5:
boxs=new Point[]{new Point(4,0),new Point(5,0),new Point(5,1),new Point(5,2)};
break;
case 6:
boxs=new Point[]{new Point(5,0),new Point(6,0),new Point(4,1),new Point(5,1)};
break;
}
}
@SuppressLint("ResourceAsColor")
public void initView(){
mapPaint=new Paint();
mapPaint.setColor(0x50000000);
mapPaint.setAntiAlias(true);
linepaint =new Paint();
linepaint.setColor(R.color.paint1);
linepaint.setAntiAlias(true);
boxPaint=new Paint();
boxPaint.setColor(0xff000000);
boxPaint.setAntiAlias(true);
startPaint=new Paint();
startPaint.setColor(R.color.tools);
startPaint.setAntiAlias(true);
startPaint.setTextSize(100);
FrameLayout layoutGame=findViewById(R.id.layoutGame);
view = new View(this){
@Override
protected void onDraw(Canvas canvas) {
super.onDraw(canvas);
for(int x=0;x<maps.length;x++){
for(int y=0;y<maps[x].length;y++){
if(maps[x][y] == true)
canvas.drawRect(x*boxSize,y*boxSize,x*boxSize+boxSize,y*boxSize+boxSize,mapPaint);
}
}
for(int i=0;i<boxs.length;i++){
canvas.drawRect(
boxs[i].x*boxSize,
boxs[i].y*boxSize,
boxs[i].x*boxSize+boxSize,
boxs[i].y*boxSize+boxSize,boxPaint);
}
for(int x=0;x<maps.length;x++){
canvas.drawLine(x*boxSize,0,x*boxSize,view.getHeight(),linepaint);
}
for(int y=0;y<maps[0].length;y++){
canvas.drawLine(0,y*boxSize,view.getWidth(),y*boxSize,linepaint);
}
if(isOver){
canvas.drawText("游戏结束",view.getWidth()/2-startPaint.measureText("游戏结束")/2,view.getHeight()/2,startPaint);
}
if(isPause && !isOver){
canvas.drawText("暂停",view.getWidth()/2-startPaint.measureText("暂停")/2,view.getHeight()/2,startPaint);
}
}
};
view.setLayoutParams(new FrameLayout.LayoutParams(xWidth,xHight));
view.setBackgroundColor(R.color.gamabg11);
layoutGame.addView(view);
}
public void intLister(){
findViewById(R.id.btnLeft).setOnClickListener(this);
findViewById(R.id.btnRight).setOnClickListener(this);
findViewById(R.id.btnTop).setOnClickListener(this);
findViewById(R.id.btnRight).setOnClickListener(this);
findViewById(R.id.btnBottom).setOnClickListener(this);
findViewById(R.id.btnStart).setOnClickListener(this);
findViewById(R.id.btnPause).setOnClickListener(this);
}
public static int getScreeWidth(Context context){
WindowManager wm=(WindowManager) context.getSystemService(Context.WINDOW_SERVICE);
DisplayMetrics outMetrice = new DisplayMetrics();
wm.getDefaultDisplay().getMetrics(outMetrice);
return outMetrice.widthPixels;
}
@Override
public void onClick(View v) {
switch (v.getId()){
case R.id.btnLeft:
if (isPause)
return;
move(-1,0);
break;
case R.id.btnTop:
if (isPause)
return;
rotate();
break;
case R.id.btnRight:
if (isPause)
return;
move(1,0);
break;
case R.id.btnBottom:
if (isPause)
return;
while (true){
if(!moveBottom()){
break;
}
}
break;
case R.id.btnStart:
startGame();
break;
case R.id.btnPause:
setPause();
break;
}
view.invalidate();
}
public void setPause(){
if(isPause)
isPause=false;
else
isPause=true;
}
public void startGame(){
if(downThread==null){
downThread=new Thread(){
@Override
public void run() {
super.run();
while(true){
try{
sleep(500);
}catch (InterruptedException e){
e.printStackTrace();
}
if(isOver||isPause)
continue;
moveBottom();
handler.sendEmptyMessage(0);
}
}
};
downThread.start();
}
for(int x=0;x<maps.length;x++){
for(int y = 0;y<maps[0].length;y++){
maps[x][y]=false;
}
}
isOver=false;
isPause=false;
newBoxs();
}
public boolean moveBottom(){
if(move(0,1))
return true;
for(int i=0;i<boxs.length;i++)
maps[boxs[i].x][boxs[i].y] = true;
cleaneLine();
newBoxs();
isOver=checkOver();
return false;
}
public void cleaneLine(){
for(int y=maps[0].length-1;y>0;y--){
if(checkLine(y)) {
deleteLine(y);
y++;
}
}
}
public boolean checkLine(int y){
for(int x=0;x<maps.length;x++){
if(!maps[x][y])
return false;
}
return true;
}
public void deleteLine(int dy){
for(int y=maps[0].length-1;y>0; y--){
for(int x=0;x<maps.length;x++){
maps[x][y]=maps[x][y-1];
}
}
}
public boolean checkOver(){
for(int i=0;i<boxs.length;i++){
if(maps[boxs[i].x][boxs[i].y]){
return true;
}
}
return false;
}
public boolean move(int x,int y){
for(int i=0;i<boxs.length;i++) {
if(cheakBoundary(boxs[i].x +x, boxs[i].y +y)){
return false;
}
}
for(int i=0;i<boxs.length;i++) {
boxs[i].x += x;
boxs[i].y += y;
}
return true;
}
public boolean rotate(){
if(boxType==0){
return false;
}
for(int i=0;i<boxs.length;i++){
int checkX=-boxs[i].y+boxs[0].y+boxs[0].x;
int checkY=boxs[i].x-boxs[0].x+boxs[0].y;
if(cheakBoundary(checkX,checkY))
return false;
}
for(int i=0;i<boxs.length;i++){
int checkX=-boxs[i].y+boxs[0].y+boxs[0].x;
int checkY=boxs[i].x-boxs[0].x+boxs[0].y;
boxs[i].x=checkX;
boxs[i].y=checkY;
}
return true;
}
public boolean cheakBoundary(int x,int y){
return (x<0 ||y<0||x>=maps.length||y>=maps[0].length||maps[x][y] == true);
}
}
3.部分样式
4.功能说明:
* 1.底部的上下左右四个按钮实现游戏的方块的旋转和左右移动和快速下落。
* 2.右侧的“开始”按钮完成游戏的开始,“暂停”按钮实现游戏的暂停,并在游戏窗口显示暂停字样。