文章详情

短信预约-IT技能 免费直播动态提醒

请输入下面的图形验证码

提交验证

短信预约提醒成功

跟着小白一起学鸿蒙—一起学做小蜜蜂

2024-11-30 16:04

关注

想了解更多关于开源的内容,请访问:

​51CTO 开源基础软件社区​

​https://ost.51cto.com​

简介

小时候我们有个熟悉的游戏叫小蜜蜂。本文中引用的图片资源均来自与Github。

开发

1、HAP应用建立

《#跟着小白一起学鸿蒙#[六]如何编写一个hap应用》里我们介绍了简单的Hap应用的开发以及基础控件的介绍,这里我们就不赘述Hap项目的建立过程,以下就是基础的Hap的page文件:index.ets。

build() {
Row() {
Column() {
Canvas(this.context)
.width('100%')
.height('100%')
.onClick((ev: ClickEvent) => {
console.info("click!!")
this.doClick()
})
.onReady(() =>{
this.context.imageSmoothingEnabled = false
this.drawall()
})
}
.width('100%')
}
.height('100%')
.backgroundColor("#000000")
}

build是基础页面的构造函数,用于界面的元素构造,其他的页面的生命周期函数如下:

declare class CustomComponent {

build(): void;


aboutToAppear?(): void;


aboutToDisappear?(): void;


onPageShow?(): void;


onPageHide?(): void;


onBackPress?(): void;
}

2、Canvas介绍

canvas是画布组件用于自定义绘制图形,具体的API页面如下:

https://developer.harmonyos.com/cn/docs/documentation/doc-references/ts-components-canvas-canvas-0000001333641081

页面显示前会调用aboutToAppear()函数,此函数为页面生命周期函数。

canvas组件初始化完毕后会调用onReady()函数,函数内部实现小游戏的初始页面的绘制。

(1)初始化页面数据
drawall() {
this.context.clearRect(0,0,this.context.width,this.context.height)
this.drawFj();
this.drawEn();
this.drawBullet();
this.drawScore();
}
(2)绘制飞机
drawFj() {
this.context.drawImage( this.fjImg, this.fjStartX, this.fjslotY,this.birdH,this.birdW)
}
(3)绘制害虫
drawEn() {
for (let line=0; line < this.enemylist.length; line++) {
for (let row=0; row < this.enemylist[line].length; row++) {
if (this.enemylist[line][row] == 1) {
if (line == 0) {
this.context.drawImage( this.en1Img, this.en1slotX+row*this.birdW,this.en1slotY-line*this.birdH,this.birdH,this.birdW);
} else if (line == 1) {
this.context.drawImage( this.en2Img, this.en1slotX+row*this.birdW,this.en1slotY-line*this.birdH,this.birdH,this.birdW);
} else if (line == 2) {
this.context.drawImage( this.en3Img, this.en1slotX+row*this.birdW,this.en1slotY-line*this.birdH,this.birdH,this.birdW);
}
}
}
}
}

不同行的害虫长相不同,分值不同。

3、游戏逻辑

简单的小游戏主体游戏逻辑为:点击鼠标移动飞机,飞机发射子弹,命中害虫,计算分数:

doClick() {
if (this.en1slotX <= 50) {
this.en1slotX += this.birdW
} else {
this.en1slotX -= this.birdW
}
console.log("doclick----")
this.moveFj();
}

4、完整逻辑

@Entry
@Component
struct Index {
@State message: string = 'Hello World'
private settings: RenderingContextSettings = new RenderingContextSettings(true);
private context: CanvasRenderingContext2D = new CanvasRenderingContext2D(this.settings);
private blockType: number = 0
private blockSize: number = 30
private en1Img:ImageBitmap = new ImageBitmap("common/images/mf1.png")
private en2Img:ImageBitmap = new ImageBitmap("common/images/mf2.png")
private en3Img:ImageBitmap = new ImageBitmap("common/images/mf3.png")
private fjImg:ImageBitmap = new ImageBitmap("common/images/fj.png")

private startX = 30;
private startY = 100;
private enStartY = 140;
private fjStartX = 50;
private fjStartY = 610;
private fjslotX = 50;
private fjslotY = this.fjStartY;
private en1slotX = 50;
private en1slotY = this.enStartY;
private en2slotX = 50;
private en2slotY = this.enStartY;
private bulletX = 65;
private bulletY = 550;
private birdH = 40;
private birdW = 40;
private score = 0;
private fjDirection = 1;

private enemylist = [
[1,1,1,1,1],
[1,1,1,1,1],
[1,1,1,1,1],
]

moveFj() {
this.fjStartX = this.fjStartX + this.fjDirection * this.birdW
if (this.fjStartX >= 210) {
this.fjDirection = -1
} else if (this.fjStartX <= 50) {
this.fjDirection = 1
}
}

drawFj() {
this.context.drawImage( this.fjImg, this.fjStartX, this.fjslotY,this.birdH,this.birdW)
}

drawEn() {
for (let line=0; line < this.enemylist.length; line++) {
for (let row=0; row < this.enemylist[line].length; row++) {
if (this.enemylist[line][row] == 1) {
if (line == 0) {
this.context.drawImage( this.en1Img, this.en1slotX+row*this.birdW,this.en1slotY-line*this.birdH,this.birdH,this.birdW);
} else if (line == 1) {
this.context.drawImage( this.en2Img, this.en1slotX+row*this.birdW,this.en1slotY-line*this.birdH,this.birdH,this.birdW);
} else if (line == 2) {
this.context.drawImage( this.en3Img, this.en1slotX+row*this.birdW,this.en1slotY-line*this.birdH,this.birdH,this.birdW);
}
}
}
}
}

drawBullet() {
let isfind = false
this.context.fillStyle = 'rgb(250,250,250)'
this.context.font = '80px sans-serif'
this.bulletX = this.fjStartX + 20
this.context.fillText(":", this.fjStartX+20, this.bulletY)
for (let line=0; line < this.enemylist.length; line++) {
if (Math.abs(this.bulletY - (this.en1slotY-line*this.birdH)) <= this.birdH) {
console.log("find line: "+line)
for (let row = 0; row < this.enemylist[line].length; row++) {
let matchsize = Math.abs(this.bulletX - (this.en1slotX+row*this.birdW))
// console.log("find szie: "+matchsize.toString()+" row:"+row.toString()+" line:"+line.toString()+" bulletX:"+this.bulletX.toString()+" bulletY:"+
// this.bulletY.toString()+" en1slotX"+this.en1slotX.toString()+" en1slotY"+this.en1slotY.toString())
if (matchsize <= this.birdW) {
if (this.enemylist[line][row] == 1) {
console.log("row:"+row.toString()+" line:"+line.toString()+" bulletX:"+this.bulletX.toString()+" bulletY:"+
this.bulletY.toString()+" en1slotX"+this.en1slotX.toString()+" en1slotY"+this.en1slotY.toString());
this.enemylist[line][row] = 0
isfind = true
switch (line) {
case 0:
this.score += 1;
break;
case 1:
this.score += 2;
break;
case 2:
this.score += 3;
break;
default:
break;
}
//console.log("score: "+this.score.toString())
break
}
}
}
if (isfind) {
break;
}
}
}
if (this.bulletY <= 100 || isfind == true) {
this.bulletY = 550
} else {
this.bulletY -= 50;
}
}

drawScore() {
this.context.fillStyle = 'rgb(250,250,250)'
this.context.font = '80px sans-serif'
this.context.fillText("Score:"+this.score.toString(), 20, 750)
// this.context.fillText(":", 65, 550)
}

drawall() {
this.context.clearRect(0,0,this.context.width,this.context.height)
this.drawFj();
this.drawEn();
this.drawBullet();
this.drawScore();
}

async sleep(ms: number) {
var that = this;
return new Promise((r) => {
setInterval(() => {
if (that.en1slotX <= 50) {
that.en1slotX += that.birdW
} else {
that.en1slotX -= that.birdW
}

console.log(that.en1slotX.toString())
that.drawall()

}, ms)
})
}

doClick() {
if (this.en1slotX <= 50) {
this.en1slotX += this.birdW
} else {
this.en1slotX -= this.birdW
}
console.log("doclick----")
this.moveFj();
}

aboutToAppear() {
this.sleep(1000)
}

build() {
Row() {
Column() {
Canvas(this.context)
.width('100%')
.height('100%')
.onClick((ev: ClickEvent) => {
console.info("click!!")
this.doClick()
})
.onReady(() =>{
this.context.imageSmoothingEnabled = false
this.drawall()
})
}
.width('100%')
}
.height('100%')
.backgroundColor("#000000")
}
}

遗留问题:

  1. 飞机的子弹可以多发
  2. 害虫可以攻击飞机
  3. 游戏声音问题:目前ohos不支持音频播放资源音频,看之后版本是否支持
  4. DevEco用setInterval重绘canvas会导致ide崩溃

5、获取源码

见附件:

https://ost.51cto.com/resource/2670。

总结

本文主要介绍了小游戏的开发,画布功能的使用。

想了解更多关于开源的内容,请访问:

​51CTO 开源基础软件社区​

​https://ost.51cto.com​

来源:51CTO 开源基础软件社区内容投诉

免责声明:

① 本站未注明“稿件来源”的信息均来自网络整理。其文字、图片和音视频稿件的所属权归原作者所有。本站收集整理出于非商业性的教育和科研之目的,并不意味着本站赞同其观点或证实其内容的真实性。仅作为临时的测试数据,供内部测试之用。本站并未授权任何人以任何方式主动获取本站任何信息。

② 本站未注明“稿件来源”的临时测试数据将在测试完成后最终做删除处理。有问题或投稿请发送至: 邮箱/279061341@qq.com QQ/279061341

软考中级精品资料免费领

  • 历年真题答案解析
  • 备考技巧名师总结
  • 高频考点精准押题
  • 2024年上半年信息系统项目管理师第二批次真题及答案解析(完整版)

    难度     813人已做
    查看
  • 【考后总结】2024年5月26日信息系统项目管理师第2批次考情分析

    难度     354人已做
    查看
  • 【考后总结】2024年5月25日信息系统项目管理师第1批次考情分析

    难度     318人已做
    查看
  • 2024年上半年软考高项第一、二批次真题考点汇总(完整版)

    难度     435人已做
    查看
  • 2024年上半年系统架构设计师考试综合知识真题

    难度     224人已做
    查看

相关文章

发现更多好内容

猜你喜欢

AI推送时光机
位置:首页-资讯-后端开发
咦!没有更多了?去看看其它编程学习网 内容吧
首页课程
资料下载
问答资讯