当前位置: 首页 > 科技观察

跟着小白学鸿蒙——【番外】一起来学做FlappyBird

时间:2023-03-20 11:43:42 科技观察

想要了解更多开源,请访问:开源基础软件社区https://ost.51cto.com简介记得很久以前有一款流行的像素游戏,叫FlappyBird。让我们来看看如何使用OpenHarmony来学习做一个FlappyBird。本文引用的图片资源均来自Github。开发1.HAP应用的建立这里不再赘述Hap项目的建立过程。下面是基本的Hap页面文件:index.etsbuild(){Row(){Column(){Canvas(this.context).width('100%').height('100%').onClick((ev:ClickEvent)=>{console.info("click!!")//鼠标左键点击的响应this.doClick()}).onReady(()=>{//绘制基础this.context.imageSmoothingEnabled=falsethis.drawBlock()})}.width('100%')}.height('100%').backgroundImage($r("app.media.backgroundday")).backgroundImageSize(ImageSize.Cover)}build是基础页面的构造函数,用于构造界面的元素。其他页面的生命周期函数如下:declareclassCustomComponent{/***自定义弹窗内容构造函数。*@since7*/build():void;/***aboutToAppear方法*@since7*/aboutToAppear?():void;/***aboutToDisappear方法*@since7*/aboutToDisappear?():void;/***onPageShow方法*@since7*/onPageShow?():空白;/***onPageHide方法*@since7*/onPageHide?():void;/***onBackPress方法*@since7*/onBackPress?():void;}2.Canvas介绍canvas是画布组件,用于自定义绘制图形。具体API页面如下:https://developer.harmonyos.com/cn/docs/documentation/doc-references/ts-components-canvas-canvas-0000001333641081在页面显示之前,aboutToAppear()函数,这个函数是页面生命周期函数。canvas组件初始化后,调用onReady()函数,该函数内部实现了小游戏初始页面的绘制。(1)初始化页面数据drawBlock(){this.context.clearRect(0,0,this.context.width,this.context.height)this.context.drawImage(this.baseImg,this.baseX,this.baseY,500,300)switch(this.flappyState){案例0:this.context.drawImage(this.messageImg,this.startX,this.startY,300,500)this.drawBird()中断;案例1:this.drawBird()this.context.drawImage(this.pipegreenImg,this.pipeX,this.pipeY,50,150)中断;case2:this.context.drawImage(this.gameoverImg,this.startX,this.startY*3,300,90)break}}页面状态有三:0:等候开始界面1:游戏进入2:游戏绑定(2)绘制BirddrawBird(){switch(this.birdType){案例0:this.context.drawImage(this.middbirdImg,this.slotX,this.slotY,this.birdH,this.birdW)中断案例1:this.context.drawImage(this.upbirdImg,this.slotX,this.slotY,this.birdH,this.birdW)中断;案例2:this.context.drawImage(this.downbirdImg,this.slotX,this.slotY,this.birdH,this.birdW)中断;默认值:中断;}}小鸟飞行状态一共有三种:Wingsinmiddle:0Wingsup:1Wingsdown:23.简单的游戏逻辑主要的游戏逻辑是:等待开始,开始,结束流程图如下:graphLR等待开始-->点击[点击]点击[点击]-->gamestartgamestart-->点击-->|gamestart|小鸟飞,水管移动-->|小鸟撞到水管|游戏结束-->点击-->|游戏结束|等待开始小鸟飞了,水管动了-->|小鸟不碰水管|){switch(this.flappyState){case0:{//启动this.flappyState=1break}case1:{//上下飞行//this.flappyState=2this.slotY-=this.flyHeightconsole.log(this.slotY.toString())break}case2:{//从结束到开始this.flappyState=0this.slotY=this.slotStartYthis.pipeX=this.pipeStartXbreak}default:break}this.drawBlock()}4.完整逻辑@Entry@ComponentstructIndex{@Statemessage:string='HelloWorld'privatebaseImg:ImageBitmap=newImageBitmap("common/images/base.png")privatemessageImg:ImageBitmap=newImageBitmap("common/images/message.png")privatezeroImg:ImageBitmap=newImageBitmap("common/images/0.png")私人gameoverImg:ImageBitmap=newImageBitmap("common/images/gameover.png")私人upbirdImg:ImageBitmap=newImageBitmap("common/images/bluebirdupflap.png")bluebirdmidflap.png")privatedownbirdImg:ImageBitmap=newImageBitmap("common/images/bluebirddownflap.png")privatepipegreenImg:ImageBitmap=newImageBitmap("common/images/pipegreen.png")私有设置:RenderingContextSettings=newRenderingContextSettings(true);私有上下文:CanvasRenderingContext2D=newCanvasRenderingContext2D(this.settings);privateflappyState:number=0privatestartX=30;私人开始Y=100;私人slotStartY=410;私人插槽X=50;私人slotY=this.slotStartY;私有的ebaseX=0;私人基地Y=650;私人pipeStartX=330;privatepipeX=this.pipeStartX;私有管道Y=500;私人鸟H=60;私人鸟W=50;私有birdTimer:数字;私人鸟型:数量=0;私人计数=1;私人flyHeight=20;私人pipeMove=10;drawBird(){switch(this.birdType){案例0:this.context.drawImage(this.middbirdImg,this.slotX,this.slotY,this.birdH,this.birdW)打破案例1:this.context.drawImage(this.upbirdImg,this.slotX,this.slotY,this.birdH,this.birdW)中断;情况2:this.context.drawImage(this.downbirdImg,this.slotX,this.slotY,this.birdH,this.birdW)中断;默认值:中断;}}drawBlock(){this.context.clearRect(0,0,this.context.width,this.context.height)this.context.drawImage(this.baseImg,this.baseX,this.baseY,500,300)开关(this.flappyState){案例0:this.context.drawImage(this.messageImg,this.startX,this.startY,300,500)this.drawBird()中断;案例1:this.drawBird()this.context.drawImage(this.pipegreenImg,this.pipeX,this.pipeY,50,150)中断;case2:this.context.drawImage(this.gameoverImg,this.startX,this.startY*3,300,90)break}}doClick(){switch(this.flappyState){case0:{//开始this.flappyState=1break}case1:{//上下飞//this.flappyState=2this.slotY-=this.flyHeightconsole.log(this.slotY.toString())break}case2:{//由绑定到等待开始this.flappyState=0this.slotY=this.slotStartYthis.pipeX=this.pipeStartXbreak}default:break}this.drawBlock()}doFly():void{console.log("dofly------!!")this.birdType+=1if(this.birdType/5==0){this.message="dofly---555---!!"}}asyncsleep(ms:number){returnnewPromise((r)=>{setInterval(()=>{this.birdType+=1this.message=this.birdType.toString()if(this.birdType==3){this.birdType=0}console.log(this.message)if(this.flappyState==1){this.pipeX-=this.pipeMoveif(this.pipeX<0){this.pipeX=330}this.slotY+=this.flyHeight/5}if((((this.pipeX-this.slotX)<=this.birdW)&&((this.pipeY-this.slotY)<=this.birdH))||this.pipeY>=this.baseY){this.flappyState=2}this.drawBlock()},ms)})}aboutToDisappear(){}aboutToAppear(){this.sleep(200)}build(){行(){Column(){Canvas(this.context).width('100%').height('100%').onClick((ev:ClickEvent)=>{console.info("click!!")this.doClick()}).onReady(()=>{this.context.imageSmoothingEnabled=falsethis.drawBlock()})}.width('100%')}.height('100%').backgroundImage($r("app.media.backgroundday")).backgroundImageSize(ImageSize.Cover)}}遗留问题:水管只显示在下层:它们可以显示在上层;地不让游戏声音问题:目前ohos不支持音频播放资源音频,看以后版本是否支持DevEcoy用setInterval重绘画布会导致ide崩溃5.见附件https://gitee.com/wshikh/ohosflappybird源码总结本文主要介绍小游戏的开发和canvas功能的使用。了解更多开源知识,请访问:开源基础软件社区https://ost.51cto.com。