【移動應(yīng)用開發(fā)技術(shù)】Android實現(xiàn)俄羅斯方塊的方法_第1頁
【移動應(yīng)用開發(fā)技術(shù)】Android實現(xiàn)俄羅斯方塊的方法_第2頁
【移動應(yīng)用開發(fā)技術(shù)】Android實現(xiàn)俄羅斯方塊的方法_第3頁
【移動應(yīng)用開發(fā)技術(shù)】Android實現(xiàn)俄羅斯方塊的方法_第4頁
【移動應(yīng)用開發(fā)技術(shù)】Android實現(xiàn)俄羅斯方塊的方法_第5頁
已閱讀5頁,還剩32頁未讀, 繼續(xù)免費閱讀

下載本文檔

版權(quán)說明:本文檔由用戶提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權(quán),請進(jìn)行舉報或認(rèn)領(lǐng)

文檔簡介

【移動應(yīng)用開發(fā)技術(shù)】Android實現(xiàn)俄羅斯方塊的方法

這篇文章主要介紹了Android實現(xiàn)俄羅斯方塊的方法,具有一定借鑒價值,感興趣的朋友可以參考下,希望大家閱讀完這篇文章之后大有收獲,下面讓在下帶著大家一起了解一下。具體內(nèi)容如下思路:首先要畫出游戲背景墻;其次,要有方塊,以及方塊單元;方塊的不同形狀,顏色隨機產(chǎn)生;游戲的控制面板??赡軙霈F(xiàn)的問題或者難點:邊界問題:①處于邊界的時候,方塊不可以再左右移動;②下降的時候,到達(dá)邊界即底部,則不可繼續(xù)下落,此時應(yīng)該產(chǎn)生一個新的方塊;與其它方塊接觸問題:①下落的時候,如果碰到其它的方塊則停止下落;②左右移動的時候,移動的過程中,如果接觸到其他方快,則不可再繼續(xù)左右移動;方塊的消除:①調(diào)用方塊消除方法的時間:當(dāng)方塊下落到底部的時候,判斷是否有需要消除的行;②消除某一行之后,應(yīng)該把這一行上面的全部方塊下移一行;方塊的旋轉(zhuǎn):在當(dāng)前項目中,我采用的是順時針旋轉(zhuǎn)。①當(dāng)旋轉(zhuǎn)的時候,如果出現(xiàn)方塊部分超出了邊界,應(yīng)該對方塊進(jìn)行平移,使其回到邊界以內(nèi)。(曾在網(wǎng)上看到有人做過,判斷旋轉(zhuǎn)之后是否會超出邊界,如果會超出,則不進(jìn)行旋轉(zhuǎn),我覺得不好,方塊只要沒有下落到底部,我覺得都可以進(jìn)行旋轉(zhuǎn),除了沒有空間讓其旋轉(zhuǎn)外);②如果空間不足以旋轉(zhuǎn),也不可以旋轉(zhuǎn)??臻g不足以旋轉(zhuǎn)的意思是:比如橫向方向只有兩個的空間,而方塊旋轉(zhuǎn)后會占用三個空間,此時也不可進(jìn)行旋轉(zhuǎn);③當(dāng)無法繼續(xù)下落或者下落到了底部也不可再進(jìn)行旋轉(zhuǎn)控制面板:①游戲開始、暫停、繼續(xù)、結(jié)束,這些狀態(tài)應(yīng)該怎么去控制,以及游戲與控制臺的事件關(guān)聯(lián)。未發(fā)現(xiàn)的問題:因為本人能力,只做到這么多,如果有人發(fā)現(xiàn)問題,可以留言交流,歡迎挑問題。游戲的運行界面如下所示,基本的功能以及操作很簡單。下面直接看項目代碼項目文件結(jié)構(gòu)下面分別介紹每個類的功能TetrisViewAW.java游戲的主界面,背景墻以及方塊都在此TetrisViewAW.Java里面,就是一個自定義的View,(默認(rèn)大家對于自定義View是熟悉的),在改類里面,有一個游戲主線程,用于控制游戲的開始,暫停,繼續(xù),停止,以及方塊下落的速率。代碼我加了很多注釋,看不懂的可以留言。還有一點需要注意,當(dāng)停止游戲時,要釋放線程,養(yǎng)成好習(xí)慣/**

*

俄羅斯方塊Game主界面

*

*

@sign

Created

by

wang.ao

on

2017年1月12日

*/

@SuppressLint("DrawAllocation")

public

class

TetrisViewAW

extends

View

{

/**

網(wǎng)格開始坐標(biāo)值,橫縱坐標(biāo)的開始值都是此值

*/

public

static

final

int

beginPoint

=

10;

/**

俄羅斯方塊的最大坐標(biāo)

*/

private

static

int

max_x,

max_y;

/**

行數(shù)和列數(shù)

*/

private

static

int

num_x

=

0,

num_y

=

0;

/**

背景墻畫筆

*/

private

static

Paint

paintWall

=

null;

/**

俄羅斯方塊的單元塊畫筆

*/

private

static

Paint

paintBlock

=

null;

private

static

final

int

BOUND_WIDTH_OF_WALL

=

2;

/**

當(dāng)前正在下落的方塊

*/

private

List<BlockUnit>

blockUnits

=

new

ArrayList<BlockUnit>();

/**

下一個要顯示的方塊

*/

private

List<BlockUnit>

blockUnitBufs

=

new

ArrayList<BlockUnit>();

/**

下一個要顯示的方塊

*/

private

List<BlockUnit>

routeBlockUnitBufs

=

new

ArrayList<BlockUnit>();

/**

全部的方塊allBlockUnits

*/

private

List<BlockUnit>

allBlockUnits

=

new

ArrayList<BlockUnit>();

/**

調(diào)用此對象的Activity對象

*/

private

TetrisActivityAW

father

=

null;

private

int[]

map

=

new

int[100];

//

保存每行網(wǎng)格中包含俄羅斯方塊單元的個數(shù)

/**

游戲的主線程

*/

private

Thread

mainThread

=

null;

//

游戲的幾種狀態(tài)

/**

標(biāo)識游戲是開始還是停止

*/

private

boolean

gameStatus

=

false;

/**

標(biāo)識游戲是暫停還是運行

*/

private

boolean

runningStatus

=

false;

/**

俄羅斯方塊顏色數(shù)組

*/

private

static

final

int

color[]

=

{

Color.parseColor("#FF6600"),

Color.BLUE,

Color.RED,

Color.GREEN,

Color.GRAY

};

/**

方塊的中心方塊單元的坐標(biāo),

*/

private

int

xx,

yy;

/**

方塊,用戶隨機獲取各種形狀的方塊

*/

private

TetrisBlock

tetrisBlock;

/**

分?jǐn)?shù)

*/

private

int

score

=

0;

/**

當(dāng)前方塊的類型

*/

private

int

blockType

=

0;

public

TetrisViewAW(Context

context)

{

this(context,

null);

}

public

TetrisViewAW(Context

context,

AttributeSet

attrs)

{

super(context,

attrs);

if

(paintWall

==

null)

{//

初始化化背景墻畫筆

paintWall

=

new

Paint();

paintWall.setColor(Color.LTGRAY);

paintWall.setStyle(Paint.Style.STROKE);

paintWall.setStrokeWidth(BOUND_WIDTH_OF_WALL

+

1);

}

if

(paintBlock

==

null)

{//

初始化化背景墻畫筆

paintBlock

=

new

Paint();

paintBlock.setColor(Color.parseColor("#FF6600"));

}

tetrisBlock

=

new

TetrisBlock();

routeBlockUnitBufs

=

tetrisBlock.getUnits(beginPoint,

beginPoint);

Arrays.fill(map,

0);

//

每行網(wǎng)格中包含俄羅斯方塊單元的個數(shù)全部初始化為0

//

繪制方塊

}

/**

*

設(shè)置當(dāng)前游戲頁面的父類activity

*

*

@param

tetrisActivityAW

*/

public

void

setFather(TetrisActivityAW

tetrisActivityAW)

{

father

=

tetrisActivityAW;

}

@Override

protected

void

onDraw(Canvas

canvas)

{

super.onDraw(canvas);

max_x

=

getWidth();

max_y

=

getHeight();

RectF

rel;

//

繪制網(wǎng)格

num_x

=

0;

num_y

=

0;

for

(int

i

=

beginPoint;

i

<

max_x

-

BlockUnit.UNIT_SIZE;

i

+=

BlockUnit.UNIT_SIZE)

{

for

(int

j

=

beginPoint;

j

<

max_y

-

BlockUnit.UNIT_SIZE;

j

+=

BlockUnit.UNIT_SIZE)

{

rel

=

new

RectF(i,

j,

i

+

BlockUnit.UNIT_SIZE,

j

+

BlockUnit.UNIT_SIZE);

canvas.drawRoundRect(rel,

8,

8,

paintWall);

num_y++;

}

num_x++;

}

//

隨機產(chǎn)生一個俄羅斯方塊

int

len

=

blockUnits.size();

//

繪制方塊

//

Toast.makeText(context,

""

+

len,

Toast.LENGTH_SHORT).show();

for

(int

i

=

0;

i

<

len;

i++)

{

int

x

=

blockUnits.get(i).x;

int

y

=

blockUnits.get(i).y;

//

設(shè)置當(dāng)前方塊的顏色

paintBlock.setColor(color[blockUnits.get(i).color]);

rel

=

new

RectF(x

+

BOUND_WIDTH_OF_WALL,

y

+

BOUND_WIDTH_OF_WALL,

x

+

BlockUnit.UNIT_SIZE

-

BOUND_WIDTH_OF_WALL,

y

+

BlockUnit.UNIT_SIZE

-

BOUND_WIDTH_OF_WALL);

canvas.drawRoundRect(rel,

8,

8,

paintBlock);

}

//

隨機產(chǎn)生一個俄羅斯方塊

len

=

allBlockUnits.size();

//

繪制方塊

//

Toast.makeText(context,

""

+

len,

Toast.LENGTH_SHORT).show();

for

(int

i

=

0;

i

<

len;

i++)

{

int

x

=

allBlockUnits.get(i).x;

int

y

=

allBlockUnits.get(i).y;

paintBlock.setColor(color[allBlockUnits.get(i).color]);

rel

=

new

RectF(x

+

BOUND_WIDTH_OF_WALL,

y

+

BOUND_WIDTH_OF_WALL,

x

+

BlockUnit.UNIT_SIZE

-

BOUND_WIDTH_OF_WALL,

y

+

BlockUnit.UNIT_SIZE

-

BOUND_WIDTH_OF_WALL);

canvas.drawRoundRect(rel,

8,

8,

paintBlock);

}

}

/**

*

開始游戲

*/

public

void

startGame()

{

gameStatus

=

true;

runningStatus

=

true;

if

(mainThread

==

null

||

!mainThread.isAlive())

{

getNewBlock();

mainThread

=

new

Thread(new

MainThread());

mainThread.start();

}

}

/**

*

暫停游戲

*/

public

void

pauseGame()

{

runningStatus

=

false;

}

/**

*

繼續(xù)游戲

*/

public

void

continueGame()

{

runningStatus

=

true;

}

/**

*

停止游戲

*/

public

void

stopGame()

{

//

停止游戲,釋放游戲主線程

runningStatus

=

false;

gameStatus

=

false;

mainTerrupt();

blockUnits.clear();

allBlockUnits.clear();

score

=

0;

invalidate();

}

/**

*

向左滑動

*/

public

void

toLeft()

{

if

(BlockUnit.toLeft(blockUnits,

max_x,

allBlockUnits))

{

xx

=

xx

-

BlockUnit.UNIT_SIZE;

}

invalidate();

}

/**

*

向右滑動

*/

public

void

toRight()

{

if

(BlockUnit.toRight(blockUnits,

max_x,

allBlockUnits))

{

xx

=

xx

+

BlockUnit.UNIT_SIZE;

}

invalidate();

}

/**

*

按順時針旋轉(zhuǎn)

*/

public

void

route()

{

if

(blockType

==

3)

{//

如果當(dāng)前正在下落的方塊為正方形,則不進(jìn)行旋轉(zhuǎn)

return;

}

if

(routeBlockUnitBufs.size()

!=

blockUnits.size())

{

routeBlockUnitBufs

=

tetrisBlock.getUnits(xx,

yy);

}

for

(int

i

=

0;

i

<

blockUnits.size();

i++)

{

routeBlockUnitBufs.get(i).x

=

blockUnits.get(i).x;

routeBlockUnitBufs.get(i).y

=

blockUnits.get(i).y;

}

for

(BlockUnit

blockUnit

:

routeBlockUnitBufs)

{

int

tx

=

blockUnit.x;

int

ty

=

blockUnit.y;

blockUnit.x

=

-(ty

-

yy)

+

xx;

blockUnit.y

=

tx

-

xx

+

yy;

}

routeTran(routeBlockUnitBufs);

if

(!BlockUnit.canRoute(routeBlockUnitBufs,

allBlockUnits))

{

//

Toast.makeText(father,

"不可旋轉(zhuǎn)",

Toast.LENGTH_SHORT).show();

return;

}

for

(BlockUnit

blockUnit

:

blockUnits)

{

int

tx

=

blockUnit.x;

int

ty

=

blockUnit.y;

blockUnit.x

=

-(ty

-

yy)

+

xx;

blockUnit.y

=

tx

-

xx

+

yy;

}

routeTran(blockUnits);

invalidate();

}

/**

*

如果方塊處于邊緣,則翻轉(zhuǎn)過后,會出現(xiàn)方塊部分處于邊緣之外的情況,

因此,通過遞歸判斷是否有超出邊緣的部分,

*

如果有,則進(jìn)行左右平移,把處于邊緣外的方塊移動到邊緣內(nèi)

*/

public

void

routeTran(List<BlockUnit>

blockUnitsBuf)

{

boolean

needLeftTran

=

false;

boolean

needRightTran

=

false;

for

(BlockUnit

u

:

blockUnitsBuf)

{

if

(u.x

<

beginPoint)

{

needLeftTran

=

true;

}

if

(u.x

>

max_x

-

BlockUnit.UNIT_SIZE)

{

needRightTran

=

true;

}

}

if

(needLeftTran

||

needRightTran)

{

for

(BlockUnit

u

:

blockUnitsBuf)

{

if

(needLeftTran)

{

u.x

=

u.x

+

BlockUnit.UNIT_SIZE;

}

else

if

(needRightTran)

{

u.x

=

u.x

-

BlockUnit.UNIT_SIZE;

}

}

routeTran(blockUnitsBuf);

}

else

{

return;

}

}

/**

*

獲取一個新的方塊

*/

private

void

getNewBlock()

{

//

新的方塊的坐標(biāo),x坐標(biāo)位于x軸的中間,y

位于起始位置

this.xx

=

beginPoint

+

(num_x

/

2)

*

BlockUnit.UNIT_SIZE;

this.yy

=

beginPoint;

if

(blockUnitBufs.size()

==

0)

{

//

當(dāng)游戲第一次開始的時候,先初始化一個方塊

blockUnitBufs

=

tetrisBlock.getUnits(xx,

yy);

}

blockUnits

=

blockUnitBufs;

blockType

=

tetrisBlock.blockType;

blockUnitBufs

=

tetrisBlock.getUnits(xx,

yy);

if

(father

!=

null)

{//

顯示出下一個要出現(xiàn)的方塊

father.setNextBlockView(blockUnitBufs,

(num_x

/

2)

*

BlockUnit.UNIT_SIZE);

}

}

/**

*

游戲的主線程

*

*

@sign

Created

by

wang.ao

on

2017年1月16日

*/

private

class

MainThread

implements

Runnable

{

@Override

public

void

run()

{

while

(gameStatus)

{

while

(runningStatus)

{

if

(BlockUnit.canMoveToDown(blockUnits,

max_y,

allBlockUnits))

{

//

判斷是否可以繼續(xù)下落,如果可以下落,則下落

BlockUnit.toDown(blockUnits,

max_y,

allBlockUnits);

yy

=

yy

+

BlockUnit.UNIT_SIZE;

}

else

{

/**

*

當(dāng)不可以繼續(xù)下落的時候,把當(dāng)前的方塊添加到allBlockUnits中,

*

并且判斷是否有需要消除的方塊,然后再產(chǎn)生一個新的方塊

*/

for

(BlockUnit

blockUnit

:

blockUnits)

{

blockUnit.y

=

blockUnit.y

+

BlockUnit.UNIT_SIZE;

allBlockUnits.add(blockUnit);

}

for

(BlockUnit

u

:

blockUnits)

{

//

更新map,即更新每行網(wǎng)格中靜止俄羅斯方塊單元的個數(shù)

int

index

=

(int)

((u.y

-

beginPoint)

/

50);

//

計算所在行數(shù)

map[index]++;

}

//

每行最大個數(shù)

int

end

=

(int)

((max_y

-

50

-

beginPoint)

/

BlockUnit.UNIT_SIZE);

int

full

=

(int)

((max_x

-

50

-

beginPoint)

/

BlockUnit.UNIT_SIZE)

+

1;

try

{

Thread.sleep(GameConfig.SPEED);

}

catch

(InterruptedException

e)

{

e.printStackTrace();

}

for

(int

i

=

0;

i

<=

end;

i++)

{

/***

*

消除需要消除的方塊(觸發(fā)條件,某一行中被塞滿了方塊,沒有空白)

*

注意順序,先消除某一行,再移動這一行上邊的方塊

*/

if

(map[i]

>=

full)

{

BlockUnit.remove(allBlockUnits,

i);

score

+=

100;

map[i]

=

0;

for

(int

j

=

i;

j

>

0;

j--)

map[j]

=

map[j

-

1];

map[0]

=

0;

for

(BlockUnit

blockUnit

:

allBlockUnits)

{

if

(blockUnit.y

<

(i

*

BlockUnit.UNIT_SIZE

+

beginPoint))

{

blockUnit.y

=

blockUnit.y

+

BlockUnit.UNIT_SIZE;

}

}

}

}

father.runOnUiThread(new

Runnable()

{

@Override

public

void

run()

{

/**

*

刷新分?jǐn)?shù)

*/

father.score.setText(""

+

score);

invalidate();

}

});

try

{

Thread.sleep(GameConfig.SPEED

*

3);

}

catch

(InterruptedException

e)

{

e.printStackTrace();

}

father.runOnUiThread(new

Runnable()

{

@Override

public

void

run()

{

getNewBlock();

score

+=

10;

father.score.setText(""

+

score);

}

});

}

father.runOnUiThread(new

Runnable()

{

@Override

public

void

run()

{

invalidate();

}

});

try

{

Thread.sleep(GameConfig.SPEED);

}

catch

(InterruptedException

e)

{

e.printStackTrace();

}

}

}

}

}

}BlockUnit.java方塊的單元塊,大家都玩過俄羅斯方塊,每一個方塊由四個單元塊組成。單元快應(yīng)該有以下屬性:①大?。簡卧獕K的大小決定了主界面的容量(容納單元塊的數(shù)量);②顏色:每個單元塊都有一個顏色,美化游戲界面(可無);③坐標(biāo):包括X軸坐標(biāo)、Y軸坐標(biāo),在繪制方塊的時候,以單元塊的坐標(biāo)為起點繪制,即:單元塊的坐標(biāo)值應(yīng)該為單元塊在界面上的左上角的坐標(biāo)。此類的主要功能有:方塊的下落,左右移動,判斷是否可以旋轉(zhuǎn)等功能都在此類中,算是核心類。/**

*

俄羅斯方塊的單元快

*

*

@sign

Created

by

wang.ao

on

2017年1月13日

*/

public

class

BlockUnit

{

public

static

final

int

UNIT_SIZE

=

50;

public

static

final

int

BEGIN

=

10;

public

int

color;

//

單元塊

的坐標(biāo)

public

int

x,

y;

public

BlockUnit()

{

}

public

BlockUnit(int

x,

int

y,

int

color)

{

/*

*

@param

單元塊橫縱坐標(biāo)

構(gòu)造函數(shù)

*/

this.x

=

x;

this.y

=

y;

this.color

=

color;

}

/**

*

判斷方塊是否可以向左移動,1是否在邊緣,2是否會與其他方塊重合

*

@param

blockUnits

當(dāng)前正在下落的方塊

*

@param

max_x

游戲主界面X軸的最大值

,下同

*

@param

allBlockUnits

所有的方塊

*

@return

能移動true;不能移動false

*/

public

static

boolean

canMoveToLeft(List<BlockUnit>

blockUnits,

int

max_x,

List<BlockUnit>

allBlockUnits)

{

for

(BlockUnit

blockUnit

:

blockUnits)

{

int

x

=

blockUnit.x;

if

(x

-

UNIT_SIZE

<

BEGIN)

{

return

false;

}

int

y

=

blockUnit.y;

if

(isSameUnit(x

-

UNIT_SIZE,

y,

allBlockUnits))

{

return

false;

}

}

return

true;

}

/**

*

判斷方塊是否可以向右移動,1是否在邊緣,2是否會與其他方塊重合

*

@param

blockUnits

當(dāng)前正在下落的方塊

*

@param

max_x

游戲主界面X軸的最大值

,下同

*

@param

allBlockUnits

所有的方塊

*

@return

能移動true;不能移動false

*/

public

static

boolean

canMoveToRight(List<BlockUnit>

blockUnits,

int

max_x,

List<BlockUnit>

allBlockUnits)

{

for

(BlockUnit

blockUnit

:

blockUnits)

{

int

x

=

blockUnit.x;

if

(x

+

UNIT_SIZE

>

max_x

-

UNIT_SIZE)

{

return

false;

}

int

y

=

blockUnit.y;

if

(isSameUnit(x

+

UNIT_SIZE,

y,

allBlockUnits))

{

return

false;

}

}

return

true;

}

/**

*

判斷方塊是否可以向下移動,1是否在邊緣,2是否會與其他方塊重合

*

@param

blockUnits

當(dāng)前正在下落的方塊

*

@param

max_x

游戲主界面X軸的最大值

,下同

*

@param

allBlockUnits

所有的方塊

*

@return

能移動true;不能移動false

*/

public

static

boolean

canMoveToDown(List<BlockUnit>

blockUnits,

int

max_y,

List<BlockUnit>

allBlockUnits)

{

for

(BlockUnit

blockUnit

:

blockUnits)

{

int

x

=

blockUnit.x;

int

y

=

blockUnit.y

+

UNIT_SIZE

*

2;

if

(y

>

max_y

-

UNIT_SIZE)

{

return

false;

}

if

(isSameUnit(x,

y,

allBlockUnits))

{

return

false;

}

}

return

true;

}

public

static

boolean

canRoute(List<BlockUnit>

blockUnits,

List<BlockUnit>

allBlockUnits){

for

(BlockUnit

blockUnit:

blockUnits)

{

if(isSameUnit(blockUnit.x,

blockUnit.y,

allBlockUnits)){

return

false;

}

}

return

true;

}

/**

*

把當(dāng)前方塊向左移動一格

*

@param

blockUnits

*

@param

max_x

*

@param

allBlockUnits

*

@return

是否成功移動一格,是:true,否:false

*/

public

static

boolean

toLeft(List<BlockUnit>

blockUnits,

int

max_x,

List<BlockUnit>

allBlockUnits)

{

if

(canMoveToLeft(blockUnits,

max_x,

allBlockUnits))

{

for

(BlockUnit

blockUnit

:

blockUnits)

{

blockUnit.x

=

blockUnit.x

-

UNIT_SIZE;

}

return

true;

}

return

false;

}

/**

*

把當(dāng)前方塊向右移動一格

*

@param

blockUnits

*

@param

max_x

*

@param

allBlockUnits

*

@return

是否成功移動一格,是:true,否:false

*/

public

static

boolean

toRight(List<BlockUnit>

blockUnits,

int

max_x,

List<BlockUnit>

allBlockUnits)

{

if

(canMoveToRight(blockUnits,

max_x,

allBlockUnits))

{

for

(BlockUnit

blockUnit

:

blockUnits)

{

blockUnit.x

=

blockUnit.x

+

UNIT_SIZE;

}

return

true;

}

return

false;

}

/**

*

把當(dāng)前方塊下落一格

*

@param

blockUnits

*

@param

allBlockUnits

*

@return

是否成功移動一格,是:true,否:false

*/

public

static

void

toDown(List<BlockUnit>

blockUnits,

int

max_Y,

List<BlockUnit>

allBlockUnits)

{

for

(BlockUnit

blockUnit

:

blockUnits)

{

blockUnit.y

=

blockUnit.y

+

BlockUnit.UNIT_SIZE;

}

}

/**

*

判斷

方塊單元是否和所有方塊有重合

*

@param

x

*

@param

y

*

@param

allBlockUnits

*

@return

*/

public

static

boolean

isSameUnit(int

x,

int

y,

List<BlockUnit>

allBlockUnits)

{

for

(BlockUnit

blockUnit

:

allBlockUnits)

{

if

(Math.abs(x

-

blockUnit.x)

<

UNIT_SIZE

&&

Math.abs(y

-

blockUnit.y)

<

UNIT_SIZE)

{

return

true;

}

}

return

false;

}

/**

*

刪除在第j行上的方塊單元

*

@param

allBlockUnits

*

@param

j

需刪除行標(biāo)

*/

public

static

void

remove(List<BlockUnit>

allBlockUnits,

int

j)

{

for

(int

i

=

allBlockUnits.size()

-

1;

i

>=

0;

i--)

{

/*

*

①逆向遍歷

②根據(jù)y坐標(biāo)計算單元所在行,若為j行則從units中刪除

*/

if

((int)

((allBlockUnits.get(i).y

-

BEGIN)

/

50)

==

j)

allBlockUnits.remove(i);

}

}

}TetrisBlock.java用于產(chǎn)生不同形狀的方塊,共有其中類型。/**

*

方塊

*

*

@sign

Created

by

wang.ao

on

2017年1月13日

*/

public

class

TetrisBlock

{

private

static

final

int

TYPE_SUM

=

7;

public

int

blockType,

blockDirection;

//

方塊種類,方塊朝向

private

int

color;

//

方塊顏色

private

int

x,

y;

//

方塊坐標(biāo)

public

TetrisBlock()

{

}

public

TetrisBlock(int

x,

int

y)

{

this.x

=

x;

this.y

=

y;

}

public

List<BlockUnit>

getUnits(int

x,

int

y)

{

this.x

=

x;

this.y

=

y;

return

returnUnit();

}

/**

*

隨機產(chǎn)生一種方塊

*

@return

*/

public

List<BlockUnit>

returnUnit()

{

List<BlockUnit>

units

=

new

ArrayList<BlockUnit>();

//

方塊組成部分

blockType

=

(int)

(Math.random()

*

TYPE_SUM)

+

1;

//

隨機生成一個種類

blockDirection

=

1;

//

默認(rèn)初始方向

color

=

(int)

(Math.random()

*

4)

+

1;

//

隨機生成一個顏色

units.clear();

switch

(blockType)

{

case

1://

橫線

for

(int

i

=

0;

i

<

4;

i++)

{

units.add(new

BlockUnit(x

+

(-2

+

i)

*

BlockUnit.UNIT_SIZE,

y,

color));

}

break;

case

2:

units.add(new

BlockUnit(x

+

(-1

+

1)

*

BlockUnit.UNIT_SIZE,

y

-

BlockUnit.UNIT_SIZE,

color));

for

(int

i

=

0;

i

<

3;

i++)

{

units.add(new

BlockUnit(x

+

(-1

+

i)

*

BlockUnit.UNIT_SIZE,

y,

color));

}

break;

case

3:

for

(int

i

=

0;

i

<

2;

i++)

{

units.add(new

BlockUnit(x

+

(i

-

1)

*

BlockUnit.UNIT_SIZE,

y

-

BlockUnit.UNIT_SIZE,

color));

units.add(new

BlockUnit(x

+

(i

-

1)

*

BlockUnit.UNIT_SIZE,

y,

color));

}

break;

case

4:

units.add(new

BlockUnit(x

+

(-1

+

0)

*

BlockUnit.UNIT_SIZE,

y

-

BlockUnit.UNIT_SIZE,

color));

for

(int

i

=

0;

i

<

3;

i++)

{

units.add(new

BlockUnit(x

+

(-1

+

i)

*

BlockUnit.UNIT_SIZE,

y,

color));

}

break;

case

5:

units.add(new

BlockUnit(x

+

(-1

+

2)

*

BlockUnit.UNIT_SIZE,

y

-

BlockUnit.UNIT_SIZE,

color));

for

(int

i

=

0;

i

<

3;

i++)

{

units.add(new

BlockUnit(x

+

(-1

+

i)

*

BlockUnit.UNIT_SIZE,

y,

color));

}

break;

case

6:

for

(int

i

=

0;

i

<

2;

i++)

{

units.add(new

BlockUnit(x

+

(-1

+

i)

*

BlockUnit.UNIT_SIZE,

y

-

BlockUnit.UNIT_SIZE,

color));

units.add(new

BlockUnit(x

+

i

*

BlockUnit.UNIT_SIZE,

y,

color));

}

break;

case

7:

for

(int

i

=

0;

i

<

2;

i++)

{

units.add(new

BlockUnit(x

+

i

*

BlockUnit.UNIT_SIZE,

y

-

BlockUnit.UNIT_SIZE,

color));

units.add(new

BlockUnit(x

+

(-1

+

i)

*

BlockUnit.UNIT_SIZE,

y,

color));

}

break;

}

return

units;

}NextBlockView.java其實就是游戲主界面的一個縮減版,用于顯示下一個要出現(xiàn)的方塊的,玩家可以明確的知道下一個方塊的形狀和顏色。/**

*

下一個要展示的方塊

*

*

@sign

Created

by

wang.ao

on

2017年1月13日

*/

@SuppressLint("DrawAllocation")

public

class

NextBlockView

extends

View

{

/**

網(wǎng)格開始坐標(biāo)值,橫縱坐標(biāo)的開始值都是此值

*/

public

static

final

int

beginPoint

=

10;

/**

俄羅斯方塊的最大坐標(biāo)

*/

private

static

int

max_x,

max_y;

private

List<BlockUnit>

blockUnits

=

new

ArrayList<BlockUnit>();

/**

背景墻畫筆

*/

private

static

Paint

paintWall

=

null;

private

static

final

int

BOUND_WIDTH_OF_WALL

=

2;

private

static

Paint

paintBlock

=

null;

private

int

div_x

=

0;

//

俄羅斯方塊顏色數(shù)組

private

static

final

int

color[]

={

Color.parseColor("#FF6600"),

Color.BLUE,

Color.RED,

Color.GREEN,

Color.GRAY

};

public

NextBlockView(Context

context)

{

this(context,

null);

}

public

NextBlockView(Context

context,

AttributeSet

attrs)

{

super(context,

attrs);

if

(paintWall

==

null)

{//

初始化化背景墻畫筆

paintWall

=

new

Paint();

paintWall.setColor(Color.LTGRAY);

paintWall.setStyle(Paint.Style.STROKE);

paintWall.setStrokeWidth(BOUND_WIDTH_OF_WALL

+

1);

}

if

(paintBlock

==

null)

{//

初始化化背景墻畫筆

paintBlock

=

new

Paint();

paintBlock.setColor(Color.parseColor("#FF6600"));

}

}

public

void

setBlockUnits(List<BlockUnit>

blockUnits,

int

div_x)

{

this.blockUnits

=

blockUnits;

this.div_x

=

div_x;

invalidate();

}

@Override

protected

void

onDraw(Canvas

canvas)

{

super.onDraw(canvas);

max_x

=

getWidth();

max_y

=

getHeight();

RectF

rel;

//

繪制網(wǎng)格

int

len

=

blockUnits.size();

//

繪制方塊

//

Toast.makeText(context,

""

+

len,

Toast.LENGTH_SHORT).show();

for

(int

i

=

0;

i

<

len;

i++)

{

paintBlock.setColor(color[blockUnits.get(i).color]);

int

x

=

blockUnits.get(i).x

-

div_x

+

BlockUnit.UNIT_SIZE

*

2;

int

y

=

blockUnits.get(i).y

+

BlockUnit.UNIT_SIZE

*

2;

rel

=

new

RectF(x

+

BOUND_WIDTH_OF_WALL,

y

+

BOUND_WIDTH_OF_WALL,

x

+

BlockUnit.UNIT_SIZE

-

BOUND_WIDTH_OF_WALL,

y

+

BlockUnit.UNIT_SIZE

-

BOUND_WIDTH_OF_WALL);

canvas.drawRoundRect(rel,

8,

8,

paintBlock);

rel

=

new

RectF(x,

y,

x

+

BlockUnit.UNIT_SIZE,

y

+

BlockUnit.UNIT_SIZE);

canvas.drawRoundRect(rel,

8,

8,

paintWall);

}

}

}GameConfig.java用于配置方塊的下落速度public

class

GameConfig

{

/**方塊下落的速度*/

public

static

final

int

SPEED

=

300;

}TetrisActivityAW.java主界面,包括游戲主界面和控制臺,很簡單,直接貼代碼。public

class

TetrisActivityAW

extends

Activity

{

private

NextBlockView

nextBlockView;

private

TetrisViewAW

tetrisViewAW;

private

TextView

gameStatusTip;

public

TextView

score;

@Override

protected

void

onCreate(Bundle

savedInstanceState)

{

super.onCreate(savedInstanceState);

setContentView(R.layout.activity_tetris_activity_aw);

nextBlockView

=

(NextBlockView)

findViewById(R.id.nextBlockView1);

tetrisViewAW

=

(TetrisViewAW)

findViewById(R.id.tetrisViewAW1);

tetrisViewAW.setFather(this);

gameStatusTip

=

(TextView)

findViewById(R.id.game_staus_tip);

score

=

(TextView)

findViewById(R.id.score);

}

public

void

setNextBlockView(List<BlockUnit>

blockUnits,

int

div_x)

{

nextBlockView.setBlockUnits(blockUnits,

div_x);

}

/**

*

開始游戲

*

*

@param

view

*/

public

void

startGame(View

view)

{

tetrisViewAW.startGame();

gameStatusTip.setText("游戲運行中");

}

/**

*

暫停游戲

*/

public

void

pauseGame(View

view)

{

tetrisViewAW.pauseGame();

gameStatusTip.setText("游戲已暫停");

}

/**

*

繼續(xù)游戲

*/

public

void

continueGame(View

view)

{

tetrisViewAW.continueGame();

gameStatusTip.setText("游戲運行中");

}

/**

*

停止游戲

*/

public

void

stopGame(View

view)

{

tetrisViewAW.stopGame();

score.setText(""+0);

gameStatusTip.setText("游戲已停止");

}

/**

*

向左滑動

*/

public

void

toLeft(View

view)

{

tetrisViewAW.toLeft();

}

/**

*

向右滑動

*/

public

void

toRight(View

view)

{

tetrisViewAW.toRight();

}

/**

*

向右滑動

*/

public

void

toRoute(View

view)

{

tetrisViewAW.route();

}

}TetrisActivityAWactivity的xml文件<RelativeLayout

xmlns:android="/apk/res/android"

xmlns:tools="/tools"

android:layout_width="match_parent"

android:layout_height="match_parent"

tools:context="${relativePackage}.${activityClass}"

>

<com.awang.media.minetetris.TetrisViewAW

android:id="@+id/tetrisViewAW1"

android:layout_width="match_parent"

android:layout_height="match_parent"

android:layout_marginBottom="200dp"

android:layout_marginRight="120dp"

/>

<com.awang.media.minetetris.NextBlockView

android:id="@+id/nextBlockView1"

android:layout_width="120dp"

android:layout_height="120dp"

android:layout_alignParentRight="true"

/>

<LinearLayout

android:layout_width="110dp"

android:layout_height="wrap_content"

android:layout_alignParentRight="true"

android:layout_below="@+id/nextBlockView1"

android:layout_marginTop="20dp"

android:orientation="vertical"

>

<LinearLayout

android:layout_width="match_parent"

android:layout_height="wrap_content"

android:orientation="horizontal"

>

<TextView

android:layout_width="wrap_content"

android:layout_height="wrap_content"

android:text="分?jǐn)?shù)"

/>

<TextView

android:id="@+id/score"

android:layout_width="wrap_content"

android:layout_height="wrap_content"

android:layout_marginLeft="10dp"

android:text="1"

/>

</LinearLayout>

<LinearLayout

android:layout_width="match_parent"

android:layout_height="wrap_content"

android:layout_marginTop="20dp"

android:orientation="horizontal"

>

<TextView

android:layout_width="wrap_content"

android:layout_height="wrap_content"

android:text="等級"

/>

<TextView

android:layout_width="wrap_content"

android:layout_height="wrap_content"

android:layout_mar

溫馨提示

  • 1. 本站所有資源如無特殊說明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請下載最新的WinRAR軟件解壓。
  • 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請聯(lián)系上傳者。文件的所有權(quán)益歸上傳用戶所有。
  • 3. 本站RAR壓縮包中若帶圖紙,網(wǎng)頁內(nèi)容里面會有圖紙預(yù)覽,若沒有圖紙預(yù)覽就沒有圖紙。
  • 4. 未經(jīng)權(quán)益所有人同意不得將文件中的內(nèi)容挪作商業(yè)或盈利用途。
  • 5. 人人文庫網(wǎng)僅提供信息存儲空間,僅對用戶上傳內(nèi)容的表現(xiàn)方式做保護(hù)處理,對用戶上傳分享的文檔內(nèi)容本身不做任何修改或編輯,并不能對任何下載內(nèi)容負(fù)責(zé)。
  • 6. 下載文件中如有侵權(quán)或不適當(dāng)內(nèi)容,請與我們聯(lián)系,我們立即糾正。
  • 7. 本站不保證下載資源的準(zhǔn)確性、安全性和完整性, 同時也不承擔(dān)用戶因使用這些下載資源對自己和他人造成任何形式的傷害或損失。

評論

0/150

提交評論