日B视频 亚洲,啪啪啪网站一区二区,91色情精品久久,日日噜狠狠色综合久,超碰人妻少妇97在线,999青青视频,亚洲一区二卡,让本一区二区视频,日韩网站推荐

0
  • 聊天消息
  • 系統(tǒng)消息
  • 評(píng)論與回復(fù)
登錄后你可以
  • 下載海量資料
  • 學(xué)習(xí)在線課程
  • 觀看技術(shù)視頻
  • 寫(xiě)文章/發(fā)帖/加入社區(qū)
會(huì)員中心
創(chuàng)作中心

完善資料讓更多小伙伴認(rèn)識(shí)你,還能領(lǐng)取20積分哦,立即完善>

3天內(nèi)不再提示

基于JAVA UI開(kāi)發(fā)的“推箱子”小游戲

OpenHarmony技術(shù)社區(qū) ? 來(lái)源:OpenHarmony技術(shù)社區(qū) ? 2023-01-05 09:32 ? 次閱讀
加入交流群
微信小助手二維碼

掃碼添加小助手

加入工程師交流群

本文我們將逐步分享基于 JAVA UI 開(kāi)發(fā)的“推箱子”小游戲這個(gè)項(xiàng)目的構(gòu)建流程。

實(shí)際上,筆者在進(jìn)行開(kāi)發(fā)的過(guò)程中,并不是寫(xiě)完一個(gè)界面的內(nèi)部邏輯,就開(kāi)始對(duì)界面進(jìn)行美化,而是先讓所有的東西可以正常地跑起來(lái),再談美化。

因此本系列文章前半部分會(huì)重點(diǎn)討論游戲以及界面之間的核心邏輯,后半部分則會(huì)分享美化界面的部分。

項(xiàng)目創(chuàng)建

打開(kāi) DevEco Studio,創(chuàng)建一個(gè)新項(xiàng)目,選擇 JAVA 作為開(kāi)發(fā)語(yǔ)言,將項(xiàng)目保存至合適的位置。

11a68738-8c76-11ed-bfe3-dac502259ad0.png

根據(jù)上期分享的開(kāi)發(fā)思路,先完成 UI 交互部分的框架。

11bbd4c6-8c76-11ed-bfe3-dac502259ad0.png

可以看到,這里需要新建三個(gè) Slice(原本自帶一個(gè) MainAbilitySlice):

11db0d46-8c76-11ed-bfe3-dac502259ad0.png

下面對(duì)四個(gè) UI 交互功能進(jìn)行講解。MainAbilitySlice:打開(kāi)應(yīng)用時(shí),首先顯示的界面,也就是用戶主界面。11e85aaa-8c76-11ed-bfe3-dac502259ad0.png

SelectSlice:關(guān)卡選擇界面,用戶可以在這個(gè)界面選擇將要跳轉(zhuǎn)的關(guān)卡。

11f29312-8c76-11ed-bfe3-dac502259ad0.png

InitSlice:加載界面。當(dāng)用戶選擇關(guān)卡之后,會(huì)進(jìn)入加載界面,仿照游戲加載資源。(實(shí)際上啥都沒(méi)干)

11f99c7a-8c76-11ed-bfe3-dac502259ad0.pngGameSlice:最后一個(gè)界面,也就是這個(gè)游戲的核心界面,所有的游戲邏輯都將在這個(gè)頁(yè)面中進(jìn)行,因此它將是本篇文章的核心講解部分。1201f4a6-8c76-11ed-bfe3-dac502259ad0.png

至此,我們可以簡(jiǎn)單地梳理一下四個(gè)界面以及他們包含的組件之間的關(guān)系:用戶進(jìn)入 MainAbilitySlice 之后,通過(guò)“開(kāi)始游戲”按鍵進(jìn)入 SelectSlice。

在 SelectSlice 中有三個(gè)按鍵,會(huì)對(duì)應(yīng)跳轉(zhuǎn)到三個(gè)不同的關(guān)卡,但是進(jìn)入關(guān)卡之前會(huì)先進(jìn)入 InitSlice,加載過(guò)后在進(jìn)入最后的 GameSlice,從而開(kāi)始游戲。以上就是開(kāi)發(fā)的時(shí)候要理清楚的頁(yè)面跳轉(zhuǎn)關(guān)系。

核心代碼分析

①M(fèi)ainAbilitySlice

里面有四個(gè)按鈕,那可以簡(jiǎn)單的給他們分個(gè)類,例如:開(kāi)始游戲的按鈕要實(shí)現(xiàn)的功能是頁(yè)面跳轉(zhuǎn),直接與其他界面關(guān)聯(lián),分為一類。

歷史記錄與關(guān)于游戲可以用彈出窗口來(lái)實(shí)現(xiàn),不需要額外界面,歸為一類;退出游戲按鈕直接結(jié)束應(yīng)用進(jìn)程,也是單獨(dú)一類。

明確之后,就可以給各個(gè)按鈕添加點(diǎn)擊事件了:

//開(kāi)始游戲按鈕
startBtn.setClickedListener(newComponent.ClickedListener(){
@Override
publicvoidonClick(Componentcomponent){
//頁(yè)面跳轉(zhuǎn)
present(newSelectSlice(),newIntent());
}
});
//歷史記錄按鈕
recordBtn.setClickedListener(newComponent.ClickedListener(){
@Override
publicvoidonClick(Componentcomponent){
//歷史記錄彈窗
}
});
//關(guān)于游戲按鈕
aboutBtn.setClickedListener(newComponent.ClickedListener(){
@Override
publicvoidonClick(Componentcomponent){
//關(guān)于游戲彈窗
}
});
//退出游戲按鈕
exitBtn.setClickedListener(newComponent.ClickedListener(){
@Override
publicvoidonClick(Componentcomponent){
//退出游戲提示
CommonDialogcommonDialog=newCommonDialog(getContext());
commonDialog.setTitleText("提示");
commonDialog.setContentText("是否退出游戲");
commonDialog.setButton(1,"確定",newIDialog.ClickedListener(){
@Override
publicvoidonClick(IDialogiDialog,inti){
terminateAbility();
}
});
commonDialog.setButton(2,"取消",newIDialog.ClickedListener(){
@Override
publicvoidonClick(IDialogiDialog,inti){
commonDialog.destroy();
}
});
commonDialog.show();
}
});
在開(kāi)發(fā)中,由于歷史記錄跟關(guān)于游戲這兩個(gè)功能并不是核心,因此,最開(kāi)始也只是做個(gè)殼子放在這,以便自己能專注于游戲主邏輯的開(kāi)發(fā),這也是我想分享的一種思路:先搭殼子再填東西。因此,閱讀本系列時(shí),如果碰到代碼中只有注釋,沒(méi)有實(shí)現(xiàn)內(nèi)容時(shí),那是因?yàn)楫?dāng)時(shí)做到這一步的時(shí)候,并不會(huì)去關(guān)注具體如何實(shí)現(xiàn),只會(huì)想個(gè)大概,先放著。到這里之后,實(shí)際上已經(jīng)完成了游戲的退出以及從 MainAbilitySlice 頁(yè)面到 SelectSlice 頁(yè)面的導(dǎo)航,便可進(jìn)行到我們的下一步。

②SelectSlice

這一個(gè)界面主要有三個(gè)按鈕,如何實(shí)現(xiàn)按下不同的按鈕,跳轉(zhuǎn)到同一個(gè)加載界面,但是加載完后又跳轉(zhuǎn)到不同的游戲界面?

這里使用 Intent 對(duì)跳轉(zhuǎn)時(shí)的數(shù)據(jù)進(jìn)行打包傳輸,具體實(shí)現(xiàn)如下:

firstBtn.setClickedListener(newComponent.ClickedListener(){
@Override
publicvoidonClick(Componentcomponent){
Intenti=newIntent();
i.setParam("關(guān)卡",1);
present(newInitSlice(),i);
}
});
secondBtn.setClickedListener(newComponent.ClickedListener(){
@Override
publicvoidonClick(Componentcomponent){
Intenti=newIntent();
i.setParam("關(guān)卡",2);
present(newInitSlice(),i);
}
});
thirdBtn.setClickedListener(newComponent.ClickedListener(){
@Override
publicvoidonClick(Componentcomponent){
Intenti=newIntent();
i.setParam("關(guān)卡",3);
present(newInitSlice(),i);
}
});
這里 Intent 的 key 都是“關(guān)卡”,但是有不同的 value,對(duì)應(yīng)不同的關(guān)卡。實(shí)際上,到這里 SelectSlice 已經(jīng)完成了它的功能了。接下來(lái)進(jìn)入 InitSlice。③InitSlice在加載界面中,我預(yù)想的是一個(gè)動(dòng)態(tài)的畫(huà)面,然后加上一個(gè)進(jìn)度條,因此我可能需要用到能夠播放 gif 的組件,以及進(jìn)度條組件。

那要怎么實(shí)現(xiàn)加載的時(shí)候進(jìn)度條跟進(jìn)?我的實(shí)現(xiàn)方式是使用兩個(gè)定時(shí)器(其實(shí)用一個(gè)也完全能搞定)

//onStart外定義
Timert1=newTimer();
Timert2=newTimer();
//onStart內(nèi)
TimerTasktask1=newTimerTask(){
@Override
publicvoidrun(){
//頁(yè)面跳轉(zhuǎn)
present(newGameSlice(),intent);
}
};
TimerTasktask2=newTimerTask(){
@Override
publicvoidrun(){
//進(jìn)度條更新
intvalue=progressBar.getProgress();
progressBar.setProgressValue(value+20);
}
};
t1.schedule(task1,5000);
t2.schedule(task2,0,1000);
關(guān)于如何播放 gif,本不應(yīng)該在此講解,因?yàn)榕c主線任務(wù)無(wú)關(guān),但是這里用到的第三方組件,后面游戲界面頻繁使用,因此在這進(jìn)行介紹。

這里用到了第三方組件 Glide,關(guān)于組件如何使用,可具體看這篇文章,只需幾行代碼即可完成 gif 的播放,十分方便。

https://ost.51cto.com/posts/8635
intimageResourceId=ResourceTable.Media_gifimg;
Glide.with(this)
.asGif()
.load(imageResourceId)
.into(draweeView);
至此,從 InitSlice 跳轉(zhuǎn)到 GameSlice 的邏輯也寫(xiě)好了,并且攜帶著從 SelectSlice 打包過(guò)來(lái)的數(shù)據(jù),接下來(lái)重點(diǎn)講解游戲界面的實(shí)現(xiàn)。④GameSlice制作一個(gè)可以玩的游戲界面最首要的任務(wù)就是繪制地圖,因此定義了一個(gè) JAVA 類 GameMap 用于地圖的繪制。在說(shuō)明如何實(shí)現(xiàn) GameMap 之前,我想先簡(jiǎn)單闡述一下推箱子游戲的實(shí)現(xiàn)邏輯:實(shí)際上每一次操作的都是圖片,邏輯判斷依賴的是圖片所綁定的屬性值(只涉及加減運(yùn)算)。舉個(gè)例子:我在程序中將路設(shè)置為 0,將墻體設(shè)置為 1,將寶可夢(mèng)設(shè)置為 2 和 3,將空球設(shè)置為 4,那收服之后的球應(yīng)該設(shè)置為:2+4=6、3+4=7,這樣就實(shí)現(xiàn)了你把空球推向?qū)毧蓧?mèng)時(shí),顯示的是已經(jīng)收復(fù)的球的狀態(tài)。而如果將人設(shè)置為 8,那 8+2=10、8+3=11 也必須是人,這樣才能實(shí)現(xiàn)你移動(dòng)到寶可夢(mèng)上面時(shí),是以原人物的方式呈現(xiàn)。這是在設(shè)置屬性值需要注意的,其他方面,例如怎么判斷墻體之類的,只需要 if 語(yǔ)句判斷即可。還有一點(diǎn),如果我們要實(shí)現(xiàn)回退功能,就需要用到棧的一些相關(guān)操作。

核心代碼如下:

//GameMap繼承于PositionLayout布局,方便對(duì)圖片進(jìn)行渲染
publicclassGameMapextendsPositionLayout{

privatefinalstaticintsize=110;

//用二維數(shù)組來(lái)存儲(chǔ)地圖
privateInteger[][]gameMap;
//定義x,y坐標(biāo)
privatePairmap_position;
//標(biāo)識(shí)是否繪制過(guò)地圖(畫(huà)過(guò)一次后,后面所有的操作都只能是進(jìn)行刷新,防止重復(fù)生成對(duì)象)
privateBooleanisDrew=Boolean.FALSE;
//定義移動(dòng)方式枚舉,方便外部調(diào)用進(jìn)行選擇
publicenumMOVE_WAY{
MOVE_UP,
MOVE_DOWN,
MOVE_LEFT,
MOVE_RIGHT
}

//設(shè)置每種物體的屬性值
privatefinalstaticintROAD=0;
privatefinalstaticintWALL=1;

privatefinalstaticintLABA=2;
privatefinalstaticintYIBU=3;
privatefinalstaticintBOBO=4;
privatefinalstaticintMINI=5;
privatefinalstaticintMIAO=6;

privatefinalstaticintBALL_EMPTY=7;
privatefinalstaticintBALL_FULL1=9;
privatefinalstaticintBALL_FULL2=10;
privatefinalstaticintBALL_FULL3=11;
privatefinalstaticintBALL_FULL4=12;
privatefinalstaticintBALL_FULL5=13;
privatefinalstaticintPEOPLE1=14;
privatefinalstaticintPEOPLE2=16;
privatefinalstaticintPEOPLE3=17;
privatefinalstaticintPEOPLE4=18;
privatefinalstaticintPEOPLE5=19;
privatefinalstaticintPEOPLE6=20;
//定義存儲(chǔ)地圖用的棧
privateStackstack;
//可使用此構(gòu)造函數(shù)繪制不同大小的地圖,這個(gè)是預(yù)留的接口,項(xiàng)目中使用的是直接在xml文件中加入這個(gè)組件(因?yàn)槔^承了PositionLayout所以可以在xml文件中使用),當(dāng)然也可以直接用構(gòu)造函數(shù)創(chuàng)建,留給讀者自己發(fā)揮。
publicGameMap(Contextcontext,Integer[][]map,intx,inty){
super(context);
gameMap=map;
map_position=newPair<>(x,y);
}
//外部設(shè)置地圖接口
publicvoidsetMap(Integer[][]map){
gameMap=map;
map_position=newPair<>(map.length,map[0].length);
stack=newStack<>();
}
//繪制地圖接口
publicvoiddrawMap(){
setHeight(size*map_position.s);
setWidth(size*map_position.f);
for(inti=0;ifor(intj=0;jnewDraweeView(getContext());
draweeView.setComponentSize(size,size);
draweeView.setContentPosition(size*j,size*i);
intindex=gameMap[i][j];
switch(index){
caseROAD:
Glide.with(getContext())
.load(ResourceTable.Media_road)
.diskCacheStrategy(DiskCacheStrategy.NONE)
.skipMemoryCache(true)
.into(draweeView);
break;
caseWALL:
Glide.with(getContext())
.load(ResourceTable.Media_wall)
.diskCacheStrategy(DiskCacheStrategy.NONE)
.skipMemoryCache(true)
.into(draweeView);
break;
caseLABA:
Glide.with(getContext())
.load(ResourceTable.Media_laba)
.diskCacheStrategy(DiskCacheStrategy.NONE)
.skipMemoryCache(true)
.into(draweeView);
break;
caseYIBU:
Glide.with(getContext())
.load(ResourceTable.Media_yibu)
.diskCacheStrategy(DiskCacheStrategy.NONE)
.skipMemoryCache(true)
.into(draweeView);
break;
caseBOBO:
Glide.with(getContext())
.load(ResourceTable.Media_bobo)
.diskCacheStrategy(DiskCacheStrategy.NONE)
.skipMemoryCache(true)
.into(draweeView);
break;
caseMINI:
Glide.with(getContext())
.load(ResourceTable.Media_mini)
.diskCacheStrategy(DiskCacheStrategy.NONE)
.skipMemoryCache(true)
.into(draweeView);
break;
caseMIAO:
Glide.with(getContext())
.load(ResourceTable.Media_miao)
.diskCacheStrategy(DiskCacheStrategy.NONE)
.skipMemoryCache(true)
.into(draweeView);
break;
caseBALL_EMPTY:
Glide.with(getContext())
.load(ResourceTable.Media_ballEmpty)
.diskCacheStrategy(DiskCacheStrategy.NONE)
.skipMemoryCache(true)
.into(draweeView);
break;
caseBALL_FULL1:
caseBALL_FULL2:
caseBALL_FULL3:
caseBALL_FULL4:
caseBALL_FULL5:
Glide.with(getContext())
.load(ResourceTable.Media_ballFull)
.diskCacheStrategy(DiskCacheStrategy.NONE)
.skipMemoryCache(true)
.into(draweeView);
break;
casePEOPLE1:
casePEOPLE2:
casePEOPLE3:
casePEOPLE4:
casePEOPLE5:
casePEOPLE6:
Glide.with(getContext())
.load(ResourceTable.Media_people)
.diskCacheStrategy(DiskCacheStrategy.NONE)
.skipMemoryCache(true)
.into(draweeView);
break;
}

this.addComponent(draweeView);
}
}
isDrew=Boolean.TRUE;
}
//外部刷新地圖接口
publicvoidflushMap(){
for(inti=0;ifor(intj=0;jintindex=gameMap[i][j];
switch(index){
caseROAD:
Glide.with(getContext())
.load(ResourceTable.Media_road)
.diskCacheStrategy(DiskCacheStrategy.NONE)
.skipMemoryCache(true)
.into(draweeView);
break;
caseWALL:
Glide.with(getContext())
.load(ResourceTable.Media_wall)
.diskCacheStrategy(DiskCacheStrategy.NONE)
.skipMemoryCache(true)
.into(draweeView);
break;
caseLABA:
Glide.with(getContext())
.load(ResourceTable.Media_laba)
.diskCacheStrategy(DiskCacheStrategy.NONE)
.skipMemoryCache(true)
.into(draweeView);
break;
caseYIBU:
Glide.with(getContext())
.load(ResourceTable.Media_yibu)
.diskCacheStrategy(DiskCacheStrategy.NONE)
.skipMemoryCache(true)
.into(draweeView);
break;
caseBOBO:
Glide.with(getContext())
.load(ResourceTable.Media_bobo)
.diskCacheStrategy(DiskCacheStrategy.NONE)
.skipMemoryCache(true)
.into(draweeView);
break;
caseMINI:
Glide.with(getContext())
.load(ResourceTable.Media_mini)
.diskCacheStrategy(DiskCacheStrategy.NONE)
.skipMemoryCache(true)
.into(draweeView);
break;
caseMIAO:
Glide.with(getContext())
.load(ResourceTable.Media_miao)
.diskCacheStrategy(DiskCacheStrategy.NONE)
.skipMemoryCache(true)
.into(draweeView);
break;
caseBALL_EMPTY:
Glide.with(getContext())
.load(ResourceTable.Media_ballEmpty)
.diskCacheStrategy(DiskCacheStrategy.NONE)
.skipMemoryCache(true)
.into(draweeView);
break;
caseBALL_FULL1:
caseBALL_FULL2:
caseBALL_FULL3:
caseBALL_FULL4:
caseBALL_FULL5:
Glide.with(getContext())
.load(ResourceTable.Media_ballFull)
.diskCacheStrategy(DiskCacheStrategy.NONE)
.skipMemoryCache(true)
.into(draweeView);
break;
casePEOPLE1:
casePEOPLE2:
casePEOPLE3:
casePEOPLE4:
casePEOPLE5:
casePEOPLE6:
Glide.with(getContext())
.load(ResourceTable.Media_people)
.diskCacheStrategy(DiskCacheStrategy.NONE)
.skipMemoryCache(true)
.into(draweeView);
break;
}

}
}
}
//獲取當(dāng)前操作的人物坐標(biāo)
publicPairgetMyPosition(){
for(inti=0;ifor(intj=0;jif(gameMap[i][j]==PEOPLE1||gameMap[i][j]==PEOPLE2||
gameMap[i][j]==PEOPLE3||gameMap[i][j]==PEOPLE4||
gameMap[i][j]==PEOPLE5||gameMap[i][j]==PEOPLE6)
{
returnnewPair<>(i,j);
}

}
}
returnnewPair<>(-1,-1);
}
//給地圖里任意一張圖設(shè)置對(duì)應(yīng)的值,移動(dòng)的時(shí)候需要此接口
protectedvoidsetValue(intx,inty,intvalue){
gameMap[x][y]+=value;
}
//判斷是否能夠移動(dòng)
protectedBooleanisMove(inti,intj){
if(gameMap[i][j]==ROAD||gameMap[i][j]==LABA||
gameMap[i][j]==YIBU||gameMap[i][j]==BOBO||
gameMap[i][j]==MINI||gameMap[i][j]==MIAO)
returnBoolean.TRUE;
returnBoolean.FALSE;
}
//判斷是不是球
protectedBooleanisBall(inti,intj){
if(gameMap[i][j]==BALL_EMPTY||gameMap[i][j]==BALL_FULL1||
gameMap[i][j]==BALL_FULL2||gameMap[i][j]==BALL_FULL3||
gameMap[i][j]==BALL_FULL4||gameMap[i][j]==BALL_FULL5)
{
returntrue;
}
returnBoolean.FALSE;
}
//外部接口,每一次移動(dòng)完判斷游戲是否結(jié)束
publicBooleanisWin(){
for(inti=0;ifor(intj=0;jif(gameMap[i][j]==LABA||gameMap[i][j]==YIBU||
gameMap[i][j]==BOBO||gameMap[i][j]==MINI||
gameMap[i][j]==MIAO)returnBoolean.FALSE;
}
}
returnBoolean.TRUE;
}
//外部移動(dòng)接口
publicvoidmove(@NotNullMOVE_WAYmove_way){
Pairposition=getMyPosition();
Integer[][]oldMap=newInteger[map_position.f][map_position.s];
for(inti=0;iif(map_position.s>=0)System.arraycopy(gameMap[i],0,oldMap[i],0,map_position.s);
}

stack.push(oldMap);
switch(move_way){
caseMOVE_UP:
if(this.isMove(position.f-1,position.s))
{
this.setValue(position.f,position.s,-PEOPLE1);
this.setValue(position.f-1,position.s,PEOPLE1);
}
if(this.isBall(position.f-1,position.s))
{
if(this.isMove(position.f-2,position.s))
{
this.setValue(position.f,position.s,-PEOPLE1);
this.setValue(position.f-1,position.s,BALL_EMPTY);
this.setValue(position.f-2,position.s,BALL_EMPTY);
}
}
break;
caseMOVE_DOWN:
if(this.isMove(position.f+1,position.s))
{
this.setValue(position.f,position.s,-PEOPLE1);
this.setValue(position.f+1,position.s,PEOPLE1);
}
if(this.isBall(position.f+1,position.s))
{
if(this.isMove(position.f+2,position.s))
{
this.setValue(position.f,position.s,-PEOPLE1);
this.setValue(position.f+1,position.s,BALL_EMPTY);
this.setValue(position.f+2,position.s,BALL_EMPTY);
}
}
break;
caseMOVE_LEFT:
if(this.isMove(position.f,position.s-1))
{
this.setValue(position.f,position.s,-PEOPLE1);
this.setValue(position.f,position.s-1,PEOPLE1);
}
if(this.isBall(position.f,position.s-1))
{
if(this.isMove(position.f,position.s-2))
{
this.setValue(position.f,position.s,-PEOPLE1);
this.setValue(position.f,position.s-1,BALL_EMPTY);
this.setValue(position.f,position.s-2,BALL_EMPTY);
}
}
break;
caseMOVE_RIGHT:
if(this.isMove(position.f,position.s+1))
{
this.setValue(position.f,position.s,-PEOPLE1);
this.setValue(position.f,position.s+1,PEOPLE1);
}
if(this.isBall(position.f,position.s+1))
{
if(this.isMove(position.f,position.s+2))
{
this.setValue(position.f,position.s,-PEOPLE1);
this.setValue(position.f,position.s+1,BALL_EMPTY);
this.setValue(position.f,position.s+2,BALL_EMPTY);
}
}
break;
}
flushMap();
}
//外部回退原先地圖接口
publicvoidback(){
if(stack.empty())return;
Integer[][]temp=stack.peek();
for(inti=0;iif(map_position.s>=0)System.arraycopy(temp[i],0,gameMap[i],0,map_position.s);
}
flushMap();
stack.pop();
}

publicBooleangetIsDrew(){
returnisDrew;
}

publicGameMap(Contextcontext){
super(context);
}

publicGameMap(Contextcontext,AttrSetattrSet){
super(context,attrSet);
}

publicGameMap(Contextcontext,AttrSetattrSet,StringstyleName){
super(context,attrSet,styleName);
}
}
至此,完成了地圖類的代碼,可以開(kāi)始繪制 GameSlice 了。在預(yù)覽圖中看到,核心部分有很多:一個(gè)退出界面按鈕,一個(gè)設(shè)置按鈕,一個(gè)倒計(jì)時(shí)器,還有一張地圖,一個(gè)后退地圖操作的按鈕,按照我自己的想法先進(jìn)行分類。

后退地圖操作的按鈕和地圖是剛需,優(yōu)先實(shí)現(xiàn),代碼如下:

//在外部定義變量
floatstart_x;
floatstart_y;

Integer[][]map;
Integer[][]map1={
{1,1,1,1,1,1,1,1,1},
{1,0,0,0,1,0,0,1,1},
{1,0,1,0,1,7,2,1,1},
{1,0,0,0,0,7,3,1,1},
{1,0,1,0,1,7,4,1,1},
{1,0,0,0,1,0,0,1,1},
{1,1,1,1,1,0,14,1,1},
{1,1,1,1,1,1,1,1,1},
{1,1,1,1,1,1,1,1,1}
};
Integer[][]map2={
{1,1,1,1,1,1,1,1,1},
{1,1,1,1,1,1,1,1,1},
{1,1,0,0,0,3,0,1,1},
{1,1,0,1,0,1,0,1,1},
{1,1,0,7,14,7,0,1,1},
{1,1,0,1,0,1,5,1,1},
{1,1,0,7,6,0,0,1,1},
{1,1,1,1,1,1,1,1,1},
{1,1,1,1,1,1,1,1,1}
};
Integer[][]map3={
{1,1,1,1,1,1,1,1,1},
{1,1,1,1,1,1,1,1,1},
{1,0,2,0,7,0,1,1,1},
{1,1,0,7,6,7,0,1,1},
{1,3,4,5,1,0,5,1,1},
{1,0,1,7,0,7,0,1,1},
{1,0,7,0,1,2,7,1,1},
{1,0,14,0,0,0,0,1,1},
{1,1,1,1,1,1,1,1,1}
};

//onStart方法內(nèi)

switch(intent.getIntParam("關(guān)卡",0))
{
case1:
map=map1;
break;
case2:
map=map2;
break;
case3:
map=map3;
break;
}
gameMap.setMap(map);
if(!gameMap.getIsDrew())gameMap.drawMap();
elsegameMap.flushMap();

//滑動(dòng)屏幕移動(dòng)角色
gameMap.setTouchEventListener(newComponent.TouchEventListener(){
@Override
publicbooleanonTouchEvent(Componentcomponent,TouchEventtouchEvent){
intaction=touchEvent.getAction();
switch(action){
caseTouchEvent.PRIMARY_POINT_DOWN:
MmiPointstartPoint=touchEvent.getPointerPosition(0);
start_x=startPoint.getX();
start_y=startPoint.getY();
break;
caseTouchEvent.PRIMARY_POINT_UP:
MmiPointendPoint=touchEvent.getPointerPosition(0);
if(endPoint.getX()>start_x&&Math.abs(endPoint.getY()-start_y)100){//right
gameMap.move(GameMap.MOVE_WAY.MOVE_RIGHT);
}
elseif(endPoint.getX()abs(endPoint.getY()-start_y)100){//left
gameMap.move(GameMap.MOVE_WAY.MOVE_LEFT);
}
elseif(endPoint.getY()abs(endPoint.getX()-start_x)100){//up
gameMap.move(GameMap.MOVE_WAY.MOVE_UP);
}
elseif(endPoint.getY()>start_y&&Math.abs(endPoint.getX()-start_x)100){//down
gameMap.move(GameMap.MOVE_WAY.MOVE_DOWN);
}
if(gameMap.isWin()){
//贏了之后該干嘛

}
break;
}
returntrue;
}

});
stackBtn.setClickedListener(newComponent.ClickedListener(){
@Override
publicvoidonClick(Componentcomponent){
gameMap.back();
}
});
游戲整體框架(不包括數(shù)據(jù)存儲(chǔ))大概就是這些,至此,已經(jīng)實(shí)現(xiàn)了這個(gè)游戲最基礎(chǔ)的功能了,從開(kāi)始界面到游戲界面,以及各種游戲操作,接下來(lái)的事情就是對(duì)這些零零散散的組件。

用一個(gè)漂亮的布局整合起來(lái),再根據(jù)自己的興趣添加一些其他功能,下篇將重點(diǎn)給出美化 UI 交互界面的代碼,敬請(qǐng)期待!

審核編輯 :李倩


聲明:本文內(nèi)容及配圖由入駐作者撰寫(xiě)或者入駐合作網(wǎng)站授權(quán)轉(zhuǎn)載。文章觀點(diǎn)僅代表作者本人,不代表電子發(fā)燒友網(wǎng)立場(chǎng)。文章及其配圖僅供工程師學(xué)習(xí)之用,如有內(nèi)容侵權(quán)或者其他違規(guī)問(wèn)題,請(qǐng)聯(lián)系本站處理。 舉報(bào)投訴
  • 應(yīng)用
    +關(guān)注

    關(guān)注

    2

    文章

    482

    瀏覽量

    34907
  • JAVA
    +關(guān)注

    關(guān)注

    20

    文章

    3012

    瀏覽量

    116873
  • 代碼
    +關(guān)注

    關(guān)注

    30

    文章

    4977

    瀏覽量

    74417
收藏 人收藏
加入交流群
微信小助手二維碼

掃碼添加小助手

加入工程師交流群

    評(píng)論

    相關(guān)推薦
    熱點(diǎn)推薦

    黑馬-Java+AI新版V16零基礎(chǔ)就業(yè)班百度云網(wǎng)盤(pán)下載+Java+AI全棧開(kāi)發(fā)工程師

    傳統(tǒng)開(kāi)發(fā)升級(jí),Java+AI 融合開(kāi)發(fā)精講——構(gòu)建下一代企業(yè)級(jí)智能應(yīng)用的技術(shù)棧重塑 在人工智能加速滲透至各行各業(yè)的當(dāng)下,Java 開(kāi)發(fā)者正面
    發(fā)表于 05-01 11:29

    [完結(jié)15章]Java轉(zhuǎn) AI高薪領(lǐng)域必備-從0到1打通生產(chǎn)級(jí)AI Agent開(kāi)發(fā)

    能力進(jìn)行深度融合,完成從“業(yè)務(wù)代碼實(shí)現(xiàn)者”向“AI系統(tǒng)工程架構(gòu)師”的硬核轉(zhuǎn)型。(搜星 課it。top) 一、 破除語(yǔ)言迷思:以Java生態(tài)構(gòu)建AI基礎(chǔ)設(shè)施 許多Java開(kāi)發(fā)者的轉(zhuǎn)型誤區(qū)在于認(rèn)為“做AI
    發(fā)表于 04-30 13:46

    TL-JAVA+AI大模型智能應(yīng)用開(kāi)發(fā)+Java+AI全棧開(kāi)發(fā)工程師

    各行各業(yè)提升競(jìng)爭(zhēng)力的重要途徑。特別是在教育領(lǐng)域,結(jié)合Java和人工智能(AI)技術(shù)的全棧開(kāi)發(fā)更是為這一轉(zhuǎn)型提供了強(qiáng)有力的支撐。本文將探討如何通過(guò)Java與AI的結(jié)合,驅(qū)動(dòng)教育行業(yè)的智能轉(zhuǎn)型。 一、數(shù)字化轉(zhuǎn)型的背景和意義 隨著互聯(lián)
    的頭像 發(fā)表于 04-28 16:43 ?78次閱讀

    Java 開(kāi)發(fā)者指南:全面對(duì)比傳統(tǒng) IDE AI 插件與 Cursor、Windsurf 等 AI 原生 IDE

    AI 正在以前所未有的速度重塑 Java 開(kāi)發(fā)工作流。本文將為您深度解析 AI 在 Java 開(kāi)發(fā)中的核心應(yīng)用場(chǎng)景,并全面對(duì)比傳統(tǒng) IDE(如 IntelliJ IDEA、VS Cod
    的頭像 發(fā)表于 03-26 14:36 ?663次閱讀
    <b class='flag-5'>Java</b> <b class='flag-5'>開(kāi)發(fā)</b>者指南:全面對(duì)比傳統(tǒng) IDE AI 插件與 Cursor、Windsurf 等 AI 原生 IDE

    LCD開(kāi)發(fā):從硬件適配到UI實(shí)現(xiàn)

    提升LCD開(kāi)發(fā)效率的關(guān)鍵,不在于更換更快的屏幕或更強(qiáng)的MCU,而在于優(yōu)化開(kāi)發(fā)鏈路本身。通過(guò)構(gòu)建從硬件接口驗(yàn)證、驅(qū)動(dòng)移植、圖形庫(kù)配置到UI組件開(kāi)發(fā)的完整流程,并引入標(biāo)準(zhǔn)化模板與自動(dòng)化工具
    的頭像 發(fā)表于 01-26 19:20 ?252次閱讀
    LCD<b class='flag-5'>開(kāi)發(fā)</b>:從硬件適配到<b class='flag-5'>UI</b>實(shí)現(xiàn)

    RUI Builder 圖形化UI設(shè)計(jì)工具

    RUI Builder 圖形化UI設(shè)計(jì)工具 該軟件為圖形化UI設(shè)計(jì)軟件,搭配瑞佑圖形處理器,輕松設(shè)計(jì)UI界面!主要特色功能: 在PC上直接設(shè)計(jì)界面,再生成UI渲染源碼(.c),程序中
    發(fā)表于 12-12 20:14

    花椒直播首次開(kāi)源流器組件 為鴻蒙開(kāi)發(fā)者提供高性能流解決方案

    器。該工具基于花椒直播自主通用多媒體框架HJMedia打造而來(lái),采用創(chuàng)新的通用多媒體框架設(shè)計(jì),以高度模塊化、可擴(kuò)展的插件化架構(gòu),極大提升了音視頻功能開(kāi)發(fā)效率與整體的資源利用率,為開(kāi)發(fā)者提供高性能、低耦合的流解決方案。 在直播、
    的頭像 發(fā)表于 09-04 09:52 ?837次閱讀
    花椒直播首次開(kāi)源<b class='flag-5'>推</b>流器組件 為鴻蒙<b class='flag-5'>開(kāi)發(fā)</b>者提供高性能<b class='flag-5'>推</b>流解決方案

    termux如何搭建python游戲

    termux如何搭建python游戲 Termux搭建Python游戲開(kāi)發(fā)環(huán)境的完整指南 一、Termux基礎(chǔ)環(huán)境準(zhǔn)備 Termux是一款無(wú)需root即可在安卓設(shè)備上運(yùn)行的Linux終端
    發(fā)表于 08-29 07:06

    Perforce JRebel 簡(jiǎn)介:即時(shí)加載代碼變更,加速Java應(yīng)用開(kāi)發(fā)

    Perforce JRebel 專為Java開(kāi)發(fā)提速而生!支持跳過(guò)構(gòu)建與重新部署,實(shí)時(shí)加載代碼變更,支持100+框架,無(wú)縫集成主流IDE與應(yīng)用服務(wù)器。
    的頭像 發(fā)表于 08-14 14:35 ?998次閱讀
    Perforce JRebel 簡(jiǎn)介:即時(shí)加載代碼變更,加速<b class='flag-5'>Java</b>應(yīng)用<b class='flag-5'>開(kāi)發(fā)</b>

    現(xiàn)在rtsp流還是只能向局域網(wǎng)流嗎?

    現(xiàn)在rtsp流還是只能向局域網(wǎng)流嗎
    發(fā)表于 08-08 06:07

    【VisionFive 2單板計(jì)算機(jī)試用體驗(yàn)】2、打造復(fù)古游戲機(jī)(Batocera鏡像+FBNeo虛擬機(jī), 多款游戲ROM分享)

    。 進(jìn)入All games,發(fā)現(xiàn)已經(jīng)內(nèi)置了一些開(kāi)源免費(fèi)的小游戲,但這些游戲已經(jīng)不具備可玩性了。如下圖: 這些游戲確實(shí)沒(méi)啥好玩的,所以讀者肯定想能不能安裝一些小時(shí)候游戲廳里常玩的經(jīng)典
    發(fā)表于 07-17 21:58

    UI開(kāi)發(fā)概述

    基于ArkTS的聲明式開(kāi)發(fā)范式的方舟開(kāi)發(fā)框架是一套開(kāi)發(fā)極簡(jiǎn)、高性能、支持跨設(shè)備的UI開(kāi)發(fā)框架,提供了構(gòu)建應(yīng)用
    發(fā)表于 06-24 06:36

    HarmonyOS NEXT意圖框架習(xí)慣推薦一場(chǎng)景說(shuō)明

    進(jìn)行續(xù)播。 ?常用復(fù)訪:涵蓋導(dǎo)航、打車以及小游戲等領(lǐng)域,推薦用戶經(jīng)常使用的應(yīng)用并展示卡片入口。 ?常用新:涵蓋咨詢及短視頻等領(lǐng)域,推薦用戶新的咨詢或者視頻。 接入意圖框架首先需要確定特性類別和具體
    發(fā)表于 06-18 15:06

    EtherCAT運(yùn)動(dòng)控制卡應(yīng)用開(kāi)發(fā)教程之Java

    運(yùn)動(dòng)控制卡的Java開(kāi)發(fā)及DLL調(diào)用
    的頭像 發(fā)表于 06-13 14:29 ?1035次閱讀
    EtherCAT運(yùn)動(dòng)控制卡應(yīng)用<b class='flag-5'>開(kāi)發(fā)</b>教程之<b class='flag-5'>Java</b>

    鴻蒙5開(kāi)發(fā)寶藏案例分享---一多開(kāi)發(fā)實(shí)例(游戲

    十年前藏的現(xiàn)金一樣驚喜?。┻@些藏在文檔深處的\"武功秘籍\",能幫我們輕松實(shí)現(xiàn)分布式游戲、跨端協(xié)同這些聽(tīng)起來(lái)很酷的功能??焐宪?,帶你解鎖鴻蒙開(kāi)發(fā)的正確姿勢(shì)! 一、分布式游戲手柄
    發(fā)表于 06-03 18:22
    云和县| 延庆县| 友谊县| 乌鲁木齐市| 沅陵县| 米林县| 建水县| 黎城县| 拜泉县| 泸水县| 合江县| 霞浦县| 平定县| 金秀| 高密市| 察哈| 全州县| 台北县| 浦城县| 黔江区| 新郑市| 丰都县| 黄大仙区| 德清县| 玉林市| 丁青县| 东乌珠穆沁旗| 海宁市| 平邑县| 合江县| 徐闻县| 墨玉县| 策勒县| 呼图壁县| 滦南县| 得荣县| 灯塔市| 石屏县| 嘉善县| 扎囊县| 南乐县|