本篇文章教大家如何在鴻蒙上實現“數字華容道”小游戲。

①打開引用首先為數字華容道的初始界面,點擊開始游戲即會切換到數字華容道的游戲界面。

②進入數字華容道的游戲界面顯示 3*3 的方陣,方陣中分布有隨意打亂的 1 至 8 的數字和一個空白方格,方陣下方顯示一個“重新開始”的按鈕和一個“返回”按鈕。
點擊“重新開始”按鈕即會重新生成隨意打亂的 1 至 8 的數字和一個空白方格的方陣,點擊“返回”按鈕即會切換到數字華容道的初始界面,最下方有四個指示不同方向箭頭的按鈕,點擊任一按鈕或向上、下、左、右任一方向滑動,空白方格周圍對應位置的方格便會隨之向對應的方向移動一格。
③經過若干次滑動或點擊后,當所有的數字按順序排列后,則會彈出游戲成功的界面,再滑動或點擊也不會有任何變化。
創建項目
DevEco Studio 下載安裝成功后,打開 DevEco Studio,點擊左上角的 File,點擊 New,再選擇 New Project,選擇 Phone 選項,選擇默認的模板,然后選擇保存路徑。
將文件命名為 MyPhoneApplication(文件名不能出現中文或者特殊字符,否則將無法成功創建項目文件),最后點擊 Finish。
實現初始界面布局
首先,我們要先實現數字華容道的初始界面,點擊開始游戲即會切換到另一頁面。

①先在 entry>src>main>config.json 文件中最下方"launchType": “standard"的后面添加以下代碼。
并且將上方的“label”:“MyPhoneApplication”修改成"label”: “數字華容道”,這樣就實現去掉應用上方的標題欄和將應用名稱改為數字華容道了。
config.json 最下面部分代碼:
"orientation":"unspecified", "name":"com.example.myphoneapplication.MainAbility", "icon":"$media:icon", "description":"$string:mainability_description", "label":"數字華容道", "type":"page", "launchType":"standard", "metaData":{ "customizeData":[ { "name":"hwc-theme", "value":"androidhwext:style/Theme.Emui.Light.NoTitleBar", "extra":"" } ] }②先將我們事先準備好的圖片復制粘貼到 entry>src>main>resources>base>media 文件夾中,并且命名為 game,點擊 OK。

在 entry>src>main>resources>base>layout>ability_main.xml 中添加布局。 先將事先存在的 Text 組件刪去,添加 Image 圖片組件,引入我們剛才復制粘貼的圖片,再添加一個 Button 按鈕組件,加入唯一標識符 id 并配置好其他相應的屬性。
③在 entry>src>main>java>com.example.myphoneapplication>slice 中右鍵選擇 New>Java Class 增加一個空白的類以用來后面編寫數字。 華容道的游戲界面,并且命名為 SecondAbilitySlice 在這里插入圖片描述。
將
entry>src>main>java>com.example.myphoneapplication>slice>SecondAbilitySlice
中的代碼修改成如下:
packagecom.example.myphoneapplication.slice;
importcom.example.myphoneapplication.ResourceTable;
importohos.aafwk.ability.AbilitySlice;
importohos.aafwk.content.Intent;
publicclassSecondAbilitySliceextendsAbilitySlice{
publicvoidonStart(Intentintent){
super.onStart(intent);
}
@Override
publicvoidonActive(){
super.onActive();
}
@Override
publicvoidonForeground(Intentintent){
super.onForeground(intent);
}
}
④在下面代碼中的 onStart 函數中添加一個按鈕指向我們(2)中添加的按鈕。
entry>src>main>java>com.example.myphoneapplication>slice>MainAbilitySlice按鈕添加一個響應點擊事件的函數,用 parsent 函數跳轉到 SecondAbilitySlice。
packagecom.example.myphoneapplication.slice;
importcom.example.myphoneapplication.ResourceTable;
importohos.aafwk.content.Intent;
importohos.agp.components.Button;
importohos.agp.components.Component;
publicclassMainAbilitySliceextendsohos.aafwk.ability.AbilitySlice{
@Override
publicvoidonStart(Intentintent){
super.onStart(intent);
super.setUIContent(ResourceTable.Layout_ability_main);
Buttonbutton=(Button)findComponentById(ResourceTable.Id_button_game);
button.setClickedListener(newComponent.ClickedListener(){
@Override
publicvoidonClick(Componentcomponent){
present(newSecondAbilitySlice(),newIntent());
}
});
}
@Override
publicvoidonActive(){
super.onActive();
}
@Override
publicvoidonForeground(Intentintent){
super.onForeground(intent);
}
}
實現數字的隨機打亂
然后我們要在數字華容道的游戲界面生成隨意打亂的 1 至 15 的數字和一個空白方格的方陣。
在這里編寫代碼:
entry>src>main>java>com.example.myphoneapplication>slice>SecondAbilitySlice先定義個一個位置布局 layout 和一個二維數組 grids,創建函數 initializeinitialize() 分別對其初始化,在 onStart 函數中調用函數 initializeinitialize()。
privatefloatstarX,starY,distanceX,distanceY;
privateDirectionalLayoutlayout;
privateint[][]grids;
publicvoidonStart(Intentintent){
super.onStart(intent);
initialize();
}
publicvoidinitialize(){
layout=newDirectionalLayout(this);
grids=newint[][]{{1,2,3,4},{5,6,7,8,},{9,10,11,12},{13,14,15,0}};
}
然后定義函數 drawGrids(int[][] grids) 用于繪制 4*4 方陣和其二維數組對應的數字。
publicvoiddrawGrids(int[][]grids){
layout.setLayoutConfig((newComponentContainer.LayoutConfig(ComponentContainer.LayoutConfig.MATCH_PARENT,ComponentContainer.LayoutConfig.MATCH_PARENT)));
Component.DrawTasktask=newComponent.DrawTask(){
publicvoidonDraw(Componentcomponent,Canvascanvas){
PaintmPaint=newPaint();
mPaint.setColor(Color.GRAY);
RectFloatrect=newRectFloat(2,230,1078,1306);
canvas.drawRect(rect,mPaint);
for(introw=0;row4;?row++){
????????????????????for(int?column?=?0;?column?4;?column++){
????????????????????????mPaint.setColor(Color.CYAN);
????????????????????????RectFloat?rectFloat=new?RectFloat(22+column*262,250+row*262,272+column*262,500+row*262);
????????????????????????canvas.drawRect(rectFloat,mPaint);
????????????????????????mPaint.setColor(Color.YELLOW);
????????????????????????mPaint.setTextSize(125);
????????????????????????if(grids[row][column]!=0){
????????????????????????????if(grids[row][column]<10){
????????????????????????????????canvas.drawText(mPaint,?String.valueOf(grids[row][column]),105+column*262,425+row*262);
????????????????????????????}
????????????????????????????else{
????????????????????????????????canvas.drawText(mPaint,?String.valueOf(grids[row][column]),65+column*262,425+row*262);
????????????????????????????}
????????????????????????}
????????????????????}
????????????????}
????????????}
????????};
????????layout.addDrawTask(task);
????????setUIContent(layout);
????}
再定義函數 changeGrids(int[][] grids,int direction),每次接收一個方向,2 表示上移,-1 表示左移,1 表示右移,-2 表示下移,找出空白方格所在位置對應的二維數組下標,對應的方格和空白方格對應的二維數組的數值對調。
publicvoidchangeGrids(int[][]grids,intdirection){ introw_0=3; intcolumn_0=3; inttemp; for(introw=0;row4;?row++)?{ ????????????for?(int?column?=?0;?column?4;?column++)?{ ????????????????if(grids[row][column]?==?0){ ????????????????????row_0?=?row; ????????????????????column_0?=?column; ????????????????} ????????????} ????????} ????????if(direction?==?-1?&&?(column_0?+?1)?<=?3){ ????????????temp?=?grids[row_0][column_0?+?1]; ????????????grids[row_0][column_0?+?1]?=?grids[row_0][column_0]; ????????????grids[row_0][column_0]?=?temp; ????????}else?if?(direction?==?1?&&?(column_0?-?1)?>=0){ temp=grids[row_0][column_0-1]; grids[row_0][column_0-1]=grids[row_0][column_0]; grids[row_0][column_0]=temp; }elseif(direction==2&&(row_0+1)<=?3)?{ ????????????temp?=?grids[row_0?+?1][column_0]; ????????????grids[row_0?+?1][column_0]?=?grids[row_0][column_0]; ????????????grids[row_0][column_0]?=?temp; ????????}?else?if?(direction?==?-2?&&?(row_0?-?1)?>=0){ temp=grids[row_0-1][column_0]; grids[row_0-1][column_0]=grids[row_0][column_0]; grids[row_0][column_0]=temp; } }
定義函數 createGrids(int[][] grids) 用于隨機生成一個表示方向的數字,循環調用函數 changeGrids(grids,direction) 用于隨機打亂二維數組對應的數字。
publicvoidcreateGrids(int[][]grids){
int[]array={-1,-2,1,2};
for(inti=0;i100;?i++){
????????????int?random?=?(int)Math.floor(Math.random()*4);
????????????int?direction?=?array[random];
????????????changeGrids(grids,direction);
????????}
????}
最后在initialize()函數中調用createGrids(grids)函數和drawGrids(grids)函數
public?void?initialize(){
????????layout?=?new?DirectionalLayout(this);
????????grids?=?new?int[][]{{1,?2,?3,?4},?{5,?6,?7,?8,},?{9,?10,?11,?12},?{13,?14,?15,?0}};
????????createGrids(grids);
????????drawGrids(grids);
????}
實現滑動或點擊調換數字
添加“重新開始”和“返回”按鈕,在每個方塊下面添加不同方向箭頭的按鈕,點擊方塊并向上、下、左、右任一方向滑動,空白方格周圍對應位置的方格便會隨之向對應的方向移動一格。

在這里編寫代碼:
entry>src>main>java>com.example.myphoneapplication>slice>SecondAbilitySlice
先定義一個函數 drawButton() 用于繪制所有的按鈕,四個指示不同方向箭頭的按鈕分別添加四個響應點擊事件的函數。
分別調用對應的 changeGrids(grids,direction) 函數實現空白方格周圍對應位置的方格便會隨之向對應的方向移動一格,并調用 drawGrids(grids) 函數用于繪制新的方陣。
publicvoiddrawButton(){
Buttonbutton=newButton(this);
button.setText("重新開始");
button.setTextSize(100);
button.setTextAlignment(TextAlignment.CENTER);
button.setTextColor(Color.WHITE);
button.setMarginTop(1400);
button.setMarginLeft(80);
button.setPadding(20,20,20,20);
ShapeElementbackground=newShapeElement();
background.setRgbColor(newRgbColor(174,158,143));
background.setCornerRadius(100);
button.setBackground(background);
layout.addComponent(button);
Buttonbutton0=newButton(this);
button0.setText("返回");
button0.setTextSize(100);
button0.setTextAlignment(TextAlignment.CENTER);
button0.setTextColor(Color.WHITE);
button0.setMarginTop(-170);
button0.setMarginLeft(680);
button0.setPadding(20,20,20,20);
button0.setBackground(background);
layout.addComponent(button0);
ShapeElementbackground0=newShapeElement();
background0.setRgbColor(newRgbColor(174,158,143));
background0.setCornerRadius(100);
Buttonbutton1=newButton(this);
button1.setText("↑");
button1.setTextAlignment(TextAlignment.CENTER);
button1.setTextColor(Color.WHITE);
button1.setTextSize(100);
button1.setMarginLeft(500);
button1.setMarginTop(70);
button1.setPadding(10,0,10,0);
button1.setBackground(background0);
button1.setClickedListener(newComponent.ClickedListener(){
@Override
publicvoidonClick(Componentcomponent){
changeGrids(grids,2);
}
});
layout.addComponent(button1);
Buttonbutton2=newButton(this);
button2.setText("←");
button2.setTextAlignment(TextAlignment.CENTER);
button2.setTextColor(Color.WHITE);
button2.setTextSize(100);
button2.setMarginTop(10);
button2.setMarginLeft(400);
button2.setPadding(10,0,10,0);
button2.setBackground(background0);
button2.setClickedListener(newComponent.ClickedListener(){
@Override
publicvoidonClick(Componentcomponent){
changeGrids(grids,-1);
}
});
layout.addComponent(button2);
Buttonbutton3=newButton(this);
button3.setText("→");
button3.setTextAlignment(TextAlignment.CENTER);
button3.setTextColor(Color.WHITE);
button3.setTextSize(100);
button3.setMarginLeft(600);
button3.setMarginTop(-130);
button3.setPadding(10,0,10,0);
button3.setBackground(background0);
button3.setClickedListener(newComponent.ClickedListener(){
@Override
publicvoidonClick(Componentcomponent){
changeGrids(grids,1);
}
});
layout.addComponent(button3);
Buttonbutton4=newButton(this);
button4.setText("↓");
button4.setTextAlignment(TextAlignment.CENTER);
button4.setTextColor(Color.WHITE);
button4.setTextSize(100);
button4.setMarginLeft(500);
button4.setMarginTop(10);
button4.setPadding(10,0,10,0);
button4.setBackground(background0);
button4.setClickedListener(newComponent.ClickedListener(){
@Override
publicvoidonClick(Componentcomponent){
changeGrids(grids,-2);
}
});
layout.addComponent(button4);
drawGrids(grids);
}
然后添加一個函數 slideGrids() 為布局 layout 添加一個滑動事件,并獲取滑動開始與結束的坐標,并計算出大致的滑動方向。
分別調用對應的 changeGrids(grids,direction) 函數實現空白方格周圍對應位置的方格便會隨之向對應的方向移動一格,并調用 drawGrids(grids) 函數用于繪制新的方陣,并在開頭添加相應的變量。
privatefloatstarX,starY,distanceX,distanceY;
publicvoidslideGrids(){
layout.setTouchEventListener(newComponent.TouchEventListener(){
@Override
publicbooleanonTouchEvent(Componentcomponent,TouchEventtouchEvent){
MmiPointpoint=touchEvent.getPointerScreenPosition(0);
switch(touchEvent.getAction()){
caseTouchEvent.PRIMARY_POINT_DOWN:
starX=point.getX();
starY=point.getY();
break;
caseTouchEvent.PRIMARY_POINT_UP:
distanceX=point.getX()-starX;
distanceY=point.getY()-starY;
break;
}
if(gameover()==false){
if(Math.abs(distanceX)>Math.abs(distanceY)){
if(distanceX>200){
changeGrids(grids,1);
}elseif(distanceX-200)?{
????????????????????????????changeGrids(grids,-1);
????????????????????????}
????????????????????}?else?if?(Math.abs(distanceX)?200){
changeGrids(grids,-2);
}elseif(distanceY-200)?{
????????????????????????????changeGrids(grids,2);
????????????????????????}
????????????????????}
????????????????}
????????????????drawGrids(grids);
????????????????return?false;
????????????}
????????});
????}
最后在 initialize() 函數中調用 slideGrids() 函數和 drawButton() 函數。
publicvoidinitialize(){
layout=newDirectionalLayout(this);
grids=newint[][]{{1,2,3,4},{5,6,7,8,},{9,10,11,12},{13,14,15,0}};
createGrids(grids);
slideGrids();
drawButton();
drawGrids(grids);
}
實現游戲成功界面
點擊“重新開始”按鈕即會重新生成隨意打亂的 1 至 15 的數字和一個空白方格的方陣,點擊“返回”按鈕即會切換到數字華容道的初始界面。 經過若干次滑動或點擊后,當所有的數字按順序排列后,則會彈出游戲成功的界面,再滑動或點擊也不會有任何變化。 
在這里編寫代碼:
entry>src>main>java>com.example.myphoneapplication>slice>SecondAbilitySlice首先定義一個函數 drawText() 用于繪制游戲成功字樣。
publicvoiddrawText(){
Texttext=newText(this);
text.setText("游戲成功");
text.setTextSize(100);
text.setTextColor(Color.BLUE);
text.setTextAlignment(TextAlignment.CENTER);
text.setMarginsTopAndBottom(-2000,0);
text.setMarginsLeftAndRight(350,0);
layout.addComponent(text);
setUIContent(layout);
}
然后定義一個函數 gameover() 用于判斷二維數組的數字是否按順序排列,當二維數組的數字按順序排列時返回 true,否則返回 false。
publicbooleangameover(){
int[][]gameoverGrids={{1,2,3,4},{5,6,7,8,},{9,10,11,12},{13,14,15,0}};
for(introw=0;row4;?row++)?{
????????????for?(int?column?=?0;?column?4;?column++)?{
????????????????if?(grids[row][column]?!=?gameoverGrids[row][column])?{
????????????????????return?false;
????????????????}
????????????}
????????}
????????return?true;
????}
再在 drawButton() 函數中重新開始按鈕中添加一個響應點擊事件的函數,用于調用函數 initialize() 實現重新生成隨意打亂的 1 至 15 的數字和一個空白方格的方陣,返回按鈕中添加一個響應點擊事件的函數。 用 parsen 函數返回數字華容道的初始界面,四個指示不同方向箭頭的按鈕的響應點擊事件的函數中增加一個判斷。 當函數 gameover() 返回為 false 時才調用各自的 changeGrids(grids,direction) 函數。
最后增加一個判斷,當函數 gameover() 返回為 true 時調用函數 drawText()。
publicvoiddrawButton(){//部分代碼沒有貼出,可自行下載源代碼查看
button.setClickedListener(newComponent.ClickedListener(){
@Override
publicvoidonClick(Componentcomponent){
initialize();
}
});
button0.setClickedListener(newComponent.ClickedListener(){
@Override
publicvoidonClick(Componentcomponent){
present(newSecondAbilitySlice(),newIntent());
}
});
button1.setClickedListener(newComponent.ClickedListener(){
@Override
publicvoidonClick(Componentcomponent){
if(gameover()==false){
changeGrids(grids,2);
}
}
});
button2.setClickedListener(newComponent.ClickedListener(){
@Override
publicvoidonClick(Componentcomponent){
if(gameover()==false){
changeGrids(grids,-1);
}
}
});
button3.setClickedListener(newComponent.ClickedListener(){
@Override
publicvoidonClick(Componentcomponent){
if(gameover()==false){
changeGrids(grids,1);
}
}
});
button4.setClickedListener(newComponent.ClickedListener(){
@Override
publicvoidonClick(Componentcomponent){
if(gameover()==false){
changeGrids(grids,-2);
}
}
});
if(gameover()){
drawText();
}
}
在函數 slideGrids() 函數中增加一個判斷,當函數 gameover() 返回為 false 時才調用 changeGrids(grids,direction) 函數,最后增加一個判斷,當函數 gameover() 返回為 true 時調用函數 drawText()。
publicvoidslideGrids(){//部分代碼沒有貼出,可自行下載源代碼查看
if(gameover()==false){
//{...}
}
if(gameover()){
drawText();
}
}
審核編輯:湯梓紅
-
游戲
+關注
關注
2文章
793瀏覽量
27539 -
函數
+關注
關注
3文章
4419瀏覽量
67772 -
鴻蒙
+關注
關注
60文章
2999瀏覽量
46114
原文標題:鴻蒙上實現“數字華容道”小游戲
文章出處:【微信號:gh_834c4b3d87fe,微信公眾號:OpenHarmony技術社區】歡迎添加關注!文章轉載請注明出處。
發布評論請先 登錄
鴻蒙上實現“數字華容道”小游戲
評論