首页 装机必备 正文

contextbg.dll 开源鸿蒙 OpenHarmony 31画布解析,教你如何完成飞机大战小游戏

开源鸿蒙 OpenHarmony 31画布解析,教你如何完成飞机大战小游戏

IT之家 2 月 10 日消息,华为技术有限公司的江英杰为大家揭晓了关于开源鸿蒙 OpenHarmony 3.1 Beta 版中的一个关键特性,也就是 ArkUI 开发框架中的 canvas 画布。

据介绍,canvas 是 ArkUI 开发框架里的画布组件,常用于自定义绘制图形。因为其轻量、灵活、高效等优点,被广泛应用于 UI 界面开发中。本期,我们将为大家介绍 ArkUI 开发框架中 canvas 组件的使用。

canvas 介绍

1.1 什么是 canvas?

IT之家了解到,在 Web 浏览器中,canvas 是一个可自定义 width、height 的矩形画布,画布左上角为坐标原点,以像素为单位,水平向右为 x 轴,垂直向下为 y 轴,画布内所有元素都基于原点进行定位。

如下图所示,我们可以通过 <canvas> 标签,创建了一个 width= 1500px,height=900px 的空白画布,我们还需要“画笔”才能绘制图形。canvas 采用轻量的逐像素渲染机制,以 JS 为“画笔”直接控制画布像素,从而实现图形绘制。

1.2 Canvas 的“画笔”

canvas 本身虽不具备绘制能力,但是提供了获取“画笔”的方法。开发者可通过 getContext ('2d') 方法获取 CanvasRenderingContext2D 对象完成 2D 图像绘制,或通过 getContext ('webgl') 方法获取 WebGLRenderingContext 对象完成 3D 图像绘制。

目前,ArkUI 开发框架中的 WebGL1.0 及 WebGL2.0 标准 3D 图形绘制能力正在完善中,所以本文将着重介绍 2D 图像的绘制。如下图所示,是 CanvasRenderingContext2D 对象提供的部分 2D 图像绘制方法,丰富的绘制方法让开发者能高效地绘制出矩形、文本、图片等。

除此之外,开发者还可以通过获取 OffscreenCanvasRenderingContext2D 对象进行离屏绘制,绘制方法同上。当绘制的图形比较复杂时,频繁地删除与重绘会消耗很多性能。

这时,开发者可以根据自身的需求灵活选取离屏渲染的方式,首先通过创建 OffscreenCanvas 对象作为一个缓冲区,然后将内容绘制在 OffscreenCanvas 上,最后再将 OffscreenCanvas 绘制到主画布上,以提高画布性能,确保绘图的质量。

canvas 基础绘制方法

通过上节对 canvas 组件的基本介绍,相信大家对 canvas 组件已经有了一定的认识,下面我们将为大家实际演示 canvas 组件在 ArkUI 开发框架中的使用方法。ArkUI 开发框架参考了 Web 浏览器中 canvas 的设计,并在“类 Web 开发范式”及“声明式开发范式”两种开发范式中进行提供,接下来我们将分别介绍这两种开发范式中 canvas 的绘制方法。

2.1 类 Web 开发范式中 canvas 的绘制方法

类 Web 开发范式,使用 HML 标签文件进行布局搭建、CSS 文件进行样式描述,并通过 JS 语言进行逻辑处理。目前,JS 语言的 canvas 绘图功能已经基本上完善,下面我们将通过两个示例,展示基于 JS 语言的 canvas 组件基础使用方法。

2.1.1 矩形填充

CanvasRenderingContext2D 对象提供了 fillRect (x, y, width, height) 方法,用于绘制一个填充的矩形。如下图所示,在画布内绘制了一个黑色的填充矩形,x 与 y 指定了在 canvas 画布上所绘制的矩形的左上角(相对于原点)的坐标,width 和 height 则设置了矩形的尺寸。

示例代码如下:

//创建一个width=1500px,height=900px的画布<!-- xxx.hml --><div>  <canvas ref="canvas" style="width: 1500px; height: 900px; "></canvas></div>

//xxx.jsexport default {  onShow() {    const el =this.$refs.canvas;//获取2D绘制对象    const ctx = el.getContext('2d');//设置填充为黑色    ctx.fillStyle = '#000000';//设置填充矩形的坐标及尺寸    ctx.fillRect(200, 200, 300, 300);  }}

2.1.2 缩放与阴影

CanvasRenderingContext2D 对象提供了 scale (x,y) 方法,参数 x 表示横轴方向上缩放倍数,y 表示纵轴方向上缩放的倍数,值得注意的是缩放过程中定位也会被缩放。如下图所示,是将上个示例中的填充矩形通过 scale (2,1.5) 缩放,并通过 shadowBlur 方法加上阴影后的效果。

示例代码如下:

//xxx.jsexport default {  onShow() {    const el =this.$refs.canvas;    const ctx = el.getContext('2d');//设置绘制阴影的模糊级别    ctx.shadowBlur = 80;    ctx.shadowColor = 'rgb(0,0,0)';    ctx.fillStyle = 'rgb(0,0,0)';    // x Scale to 200%,y Scale to 150%    ctx.scale(2, 1.5);    ctx.fillRect(200, 200, 300, 300);  }}

2.2 声明式开发范式中 canvas 的绘制方法

声明式开发范式,采用 TS 语言并进行声明式 UI 语法扩展,从组件、动效和状态管理三个维度提供了 UI 绘制能力,目前已经提供了 canvas 组件绘制能力,但功能仍在完善中。下面我们将通过两个示例展示声明式开发范式中 canvas 组件的基础使用方法。

2.2.1 图片叠加

如下图所示,是三张图片叠加的效果,顶层的图片覆盖了底层的图片。通过依次使用 drawImage (x,y, width, height) 方法设置图片坐标及尺寸,后面绘制的图片自动覆盖原来的图像,从而达到预期效果。

扩展的 TS 语言采用更接近自然语义的编程方式,让开发者可以直观地描述 UI 界面,示例代码如下:

@Entry@Componentstruct IndexCanvas1 {  private settings:RenderingContextSettings = new RenderingContextSettings(true);//获取绘图对象  private ctx: RenderingContext = new RenderingContext(this.settings);//列出所要用到的图片  private img:ImageBitmap = new ImageBitmap("common/bg.jpg");  build() {    Column() {      //创建canvas      Canvas(this.ctx)        .width(1500)        .height(900)        .border({color:"blue",width:1,})        .backgroundColor('#ffff00')         //开始绘制        .onReady(() => {          this.ctx.drawImage( this.img,400,200,540,300);          this.ctx.drawImage( this.img,500,300,540,300);          this.ctx.drawImage( this.img,600,400,540,300);        })    }    .width('100%')    .height('100%')  }}

2.2.2 点击创建线性渐变

如下图所示,是一个线性渐变效果。基于 canvas 扩展了一个 Button 组件,通过点击“Click”按钮,触发 onClick () 方法,并通过调用 createLinearGradient () 方法,绘制出了一个线性渐变色。

示例代码如下:

@Entry@Componentstruct GradientExample {  private settings: RenderingContextSettings = new RenderingContextSettings(true);  private context: RenderingContext = new RenderingContext(this.settings);  private gra: CanvasGradient = new CanvasGradient();  build() {    Column({ space: 5 })  {//创建一个画布      Canvas(this.context)        .width(1500)        .height(900)        .backgroundColor('#ffff00 ')      Column() {//设置按钮的样式        Button('Click').width(250).height(100).backgroundColor('#000000')          .onClick(() => {//创建一个线性渐变色            var grad = this.context.createLinearGradient(600, 200, 400, 750)            grad.addColorStop(0.0, 'red');            grad.addColorStop(0.5, 'white');            grad.addColorStop(1.0, 'green');            this.context.fillStyle = grad;            this.context.fillRect(400, 200, 550, 550);          })       }.alignItems(HorizontalAlign.center)     }   } }

飞机大战小游戏绘制实践

如下图所示,是一款”飞机大战”小游戏,通过控制战机的移动摧毁敌机。如何使用 ArkUI 开发框架提供的 canvas 组件轻松实现这个经典怀旧的小游戏?实现思路及关键代码如下:

1. 首先列出游戏所用到的图片

private imgList:Array<string> = ["xx.png","xx.png"…];

2. 将图片渲染到 canvas 画布上

let img:ImageBitmap = new ImageBitmap("图片路径(如common/images)/"+this.imgList[数组下标]);this.ctx.drawImage( img,150/* x坐标*/,  150/* y坐标*/, 600/*宽*/, 600/*高*/)

3. 绘制背景图片和战机向下移动的效果

this.ctx.drawImage(this.bg, 0, this.bgY);this.ctx.drawImage(this.bg, 0, this.bgY - 480);this.bgY++ == 480 && (this.bgY = 0);

4. 使用 Math.round 函数随机获取敌机图片并渲染到画布上,并且改变敌机 y 轴坐标,使它向下运动。

Efight = Math.round(Math.random()*7);//前七张为敌机图片。let img:ImageBitmap = new ImageBitmap("common/img"+this.imgList[Efight]);this.ctx.drawImage(img, 0, this.Eheight + 50);//渲染敌机

5. 在页面每隔 120s 出现一排子弹,之后减小或增大(x,y)轴的坐标达到子弹射出效果。

let i= 0;setInterval(()=>{  this.ctx.drawImage(this.bulImg1,image.x – 10 – (i *10) , image.x + (i *10))  this.ctx.drawImage(this.bulimg2, this. bulImg1,image.x – (i *10) , i image.x + (i *10))  this.ctx.drawImage(this.bulimg3, image.x + 10 + (i *10), image.x + (i *10))i ++;},120)

6. 使用 onTouch 方法获取战机移动位置,获取拖动的坐标后重新设置战机的图片坐标,使战机实现拖动效果。

.onTouch((event)=>{  var offsetX = event.localX ||event.touches[0].localX;  var offsetY = event.localY ||event.touches[0].localY;  var w = this.heroImg[0].width,      h = this.heroImg[0].height;  var nx = offsetX - w / 2,      ny = offsetY - h / 2;      nx < 20 - w / 2 ? nx = 20 - w / 2 : nx > (this.windowWidth - w / 2 - 20) ? nx =  (this.windowWidth - w / 2 - 20) : 0;  ny < 0 ? ny = 0 : ny > (this.windowHeight - h / 2) ? ny = (this.windowHeight –  h/2) : 0;     this.hero.x = nx;     this.hero.y = ny;     this.hero.count = 2;

注:本示例引用了部分开源资源,感兴趣的开发者可参考此开源资源,结合文中的实现思路补全代码。(https://github.com/ xs528 / game)

以上就是本期全部内容,期待广大开发者能通过 canvas 组件绘制出精美的图形,更多 canvas 组件的详细使用方法,请参考文档进行学习:

https://developer.harmonyos.com/cn/docs/documentation/doc-references/js-components-canvas-canvas-0000000000621808

只需五步,快速构建Python聊天室

在本文中,我们来谈一谈如何构建一个Python聊天室。

注意:你不需要安装任何额外的Python包。

作者 | Dark Soulz

译者 | 弯月,责编 | 郑丽媛

头图 | CSDN 下载自东方 IC

出品 | CSDN(ID:CSDNnews)

概念介绍

大致来说,Python聊天室使用了套接字编程和多线程的概念。聊天室分为两个部分:服务器端程序socketserver.py和客户端程序chat.py。它支持聊天室或同时与多个用户连接的聊天框。但是,在进入下一阶段之前,我们先来学习套接字编程和多线程。如果不明白这两个概念,初学者很难理解下面构建的项目。

套接字编程

一般来说,你可以将套接字视为双向通信通道中的端点,帮助服务器和一个或多个客户端组加入通信。它允许客户端通过服务器与其他客户端交互。

多线程

多线程是一个子进程,可以负责运行其他任何线程中的各个命令。当用户连接到服务器时,就会创建一个新的线程,并根据为每个客户端的规范构建的套接字对象,通过单独的线程实现服务器到客户端的通信。

聊天室的工作原理:我们的聊天室使用计算机的本地IP地址,在服务器端脚本和客户端脚本之间进行通信。每当客户端连接到聊天室时,它就在服务器端脚本中显示“已建立连接”,并允许客户端开始聊天。聊天室可以允许多个客户端一起使用,并与有限的本地IP一起使用。这反过来避免了为个人运行程序的复杂性。

项目要求

● 一台拥有I5核心处理器的优质PC,负责运行各种程序。

● 一个用来写注释的记事本。

● 一个IDE,通常是VS Code Editor、Atom或Sublime。

● 最重要的是,你必须在PC上安装Python才能执行任何Python程序。

● 专注。

如何构建Python聊天室?

首先,在桌面上创建一个名为Python chatbox或chatroom的文件夹,用于保存所有的文件。

然后,将你的文件拖到IDE中,并创建两个文件,即chat.py (客户端脚本/GUI部分)和socketserver.py(服务器端脚本)。

注意:无需安装任何Python软件包,因为Python安装包自带所有的库。

第三,仔细阅读各个文件中的代码,并把这些代码放到你的文件中。

第四,首先执行Python socketserver.py,然后执行Python chat.py

第五,测试你的聊天框是否可以正常工作,然后这个DIY项目就完成了。

代码

socketserver.py

##Python codes to do server-side part of chat room.import _threadimport socketimport threading"""AF_INET is the address domain of the socket. This is used when we have an Internet Domain with any two hosts The 2nd context of the code is the type of socket. """s=socket.socket(socket.AF_INET,socket.SOCK_STREAM) s.setsockopt(socket.SOL_SOCKET,socket.SO_REUSEADDR,1)# piece of code to allow IP address & Porthost="127.0.0.1"port=5000s.bind((host,port))s.listen(5)clients=#code to allow users to send messagesdef connectNewClient(c): while True: global clients msg = c.recv(2048) msg ='Online ('+str(clients.index(c)+1)+'): '+msg.decode('ascii') sendToAll(msg,c)def sendToAll(msg,con): for client in clients: client.send(msg.encode('ascii')) while True: c,ad=s.accept # Display message when user connects print('*Server Connected ') clients.append(c) c.send(('Online ('+str(clients.index(c)+1)+')').encode('ascii')) _thread.start_new_thread(connectNewClient,(c,))

chat.py(GUI部分)

#Gui Programming Partimport tkinterimport socketimport _threadimport sys# Code to create a new client socket and connect to the serveri = 3client = 0start = Truedef sendMessage : msg = txt.get client.send(msg.encode('ascii'))def recievingMessage (c): global i while True : msg=c.recv(2048).decode('ascii') if not msg : sys.exit(0) global start if (start) : start = False #tkinter codes starts window.title(msg) continue msglbl = tkinter.Label(window,text=msg) msglbl['font']=("Courier",10) msglbl['bg']='black' msglbl['fg']='#0aff43' msglbl['width']=50 msglbl.grid(columnspan=2,column=0,row=i,padx=5) i += 1#Socket Creationdef socketCreation : c = socket.socket(socket.AF_INET, socket.SOCK_STREAM) c.setsockopt(socket.SOL_SOCKET,socket.SO_REUSEADDR,1)#Local Host # import all functions /# everthing from chat.py file host = '127.0.0.1' port = 5000 c.connect((host,port)) global client client = c send['command'] = sendMessage _thread.start_new_thread(recievingMessage, (c,) )#Creating a windowwindow = tkinter.Tkwindow.title('Chatbox')window['bg']='#242424'window['padx']=10window['pady']=10#Adding Elements#Entrytxt = tkinter.Entry(window)txt['width']=50txt['relief']=tkinter.GROOVEtxt['bg']='#f5f6f7'txt['fg']='red'txt['font']=("Courier",12)txt.grid(column=0,row=1,padx=5,pady=15)#Buttonsend = tkinter.Button(window,text="Send")send['relief']=tkinter.GROOVEsend['bg']='red'send['fg']='white'send['activebackground']='#404040'send['padx']=3send['font']=("Courier",10)send.grid(column=1,row=1,padx=5,pady=15)_thread.start_new_thread(socketCreation, )window.mainloop

总结

上述给出了主要代码,本文的讲解可以帮助你理解代码的工作方式。最后,请严格执行文本的步骤,以防止运行程序时发生不必要的麻烦。感谢您的阅读!

原文:https://thecodezine.com/5-easy-way-to-build-a-python-chat-room/

本文为 CSDN 翻译,转载请注明来源出处。

Mate40 成麒麟绝唱,光刻机进厂即遭抵押,北斗指路能否解除“芯痛”?

点分享

相关问答

有没有做宜信普惠贷款,还没还的朋友,交流下- 汇财吧专业问...

[回答]样应该比较困难。据您所述,申请信用贷款是存在难度的,宜信普惠的信用贷款对申请人的信用要求比较严格,因为它是基于申请人信用的一种贷款,可以考虑...