鸿蒙用OLED板实现FlappyBird小游戏(下)

开发
文章由鸿蒙社区产出,想要了解更多内容请前往:51CTO和华为官方战略合作共建的鸿蒙技术社区https://harmonyos.51cto.com/#zz

想了解更多内容,请访问:

51CTO和华为官方合作共建的鸿蒙技术社区

https://harmonyos.51cto.com/#zz

年底这段时间相信大家都和我一样挺忙的,最近稍得空闲,赶紧来更新咱的FlappyBird。上次说到要加一个联机对战的功能,想想这个小鸟也不适合改成对战类,不过没关系,这也不妨碍咱们来研究一下开发板联网的方法。所以本文主要介绍我是如何让开发板具备连接wifi并开启socket server,然后开发基于HarmonyOS的手机遥控器,或者也可以说成是虚拟手柄的雏形吧。说起来,这可是鸿蒙OS手机和鸿蒙Hi3861开发板之间的故事哦。

咱们这个Harmony Hi3861 Wifi IoT开发板本来就是为Wifi智能家居量身定做,所以Wifi的支持一定少不了,在阅读了各种官方文档、代码,又拜读了连志安老师的几篇文章(链接),总算是有了眉目。

一般来说,wifi相关的接口都在“\vendor\hisi\hi3861\hi3861\third_party\lwip_sack\include\lwip\netifapi.h”头文件中,仔细阅读代码中的注释会很有帮助。这次没有把手机配网功能放进来,因为觉得每次运行还得手机一顿操作好麻烦,用的是直接STA模式连接指定AP的方式,以后可以改进成碰一碰组网的方式,留待后续研究。

话不多说,上图:

这是总体架构图,路由器做AP,手机和开发板分别连接到同一个Wifi。


这是开发板启动server的流程图:

在启动socket server后,就是接受客户端的连接请求,然后循环接收数据,根据指令执行动作。还有一点需要注意,那就是网络相关的操作函数放到单独的一个thread中执行,即后台连接网络,避免阻塞程序主线程。这里socket server侦听端口设置为8888。

很快我就发现,不知道开发板的IP地址啊。虽然我可以在路由器管理页面上查看到所有设备IP,但总是不方便,总不能去哪都得找路由器管理员吧。于是我又加入了一键显示IP地址的功能。具体就是调用netifapi_netif_get_addr函数(netifapi.h),函数的声明如下:

  1. /* 
  2.  
  3. * Func Name: netifapi_netif_get_addr 
  4.  
  5. */ 
  6.  
  7. /** 
  8.  
  9. * @ingroup Threadsafe_Network_Interfaces 
  10.  
  11.  
  12. * @brief 
  13.  
  14.  
  15. * This is a thread safe API, used to get IP_add configuration for a network interface 
  16.  
  17. * (including netmask and default gateway). 
  18.  
  19. * It is recommended to use this API instead of netif_get_addr() 
  20.  
  21.  
  22. * @param[in] netif Indicates the network interface to get. 
  23.  
  24. * @param[in] ipaddr Indicates the IP address. 
  25.  
  26. * @param[in] netmask Indicates the network mask. 
  27.  
  28. * @param[in] gw Indicates the default gateway IP address. 
  29.  
  30.  
  31. * @returns 
  32.  
  33. * 0 : On success \n 
  34.  
  35. * Negative value : On failure \n 
  36.  
  37.  
  38. * @par Related Topics 
  39.  
  40. * netif_get_addr() 
  41.  
  42.  
  43. * @note 
  44.  
  45. * - netmask and/or gw can be passed NULL, if these details about the netif are not needed 
  46.  
  47. */ 
  48.  
  49. err_t netifapi_netif_get_addr(struct netif *netif, 
  50.  
  51. ip4_addr_t *ipaddr, 
  52.  
  53. ip4_addr_t *netmask, 
  54.  
  55. ip4_addr_t *gw); 

 第一个参数netif,即之前连接wifi用到的netif结构体指针,其他三个分别是用来返回的ip地址、子网掩码、网关。

那么如何把返回的ip4_addr_t结构体转换为通用的数字加句点的字符串格式(例如192.168.1.1)呢?答案就是ip4addr_ntoa函数。

  1. char *ip = ip4addr_ntoa(ipAddr); 
  2.  
  3. printf("ip: %s\n", ip); 
  4.  
  5. free(ip)//用完记得释放 

 其实在\vendor\hisi\hi3861\hi3861\third_party\lwip_sack\include\lwip\ip4_addr.h头文件中定义好了一系列的转换函数,他们的定义如下,我们可以按需使用:

  1. u32_t ipaddr_addr(const char *cp); 
  2.  
  3. int ip4addr_aton(const char *cp, ip4_addr_t *addr); 
  4.  
  5. /** returns ptr to static buffer; not reentrant! */ 
  6.  
  7. char *ip4addr_ntoa(const ip4_addr_t *addr); 
  8.  
  9. char *ip4addr_ntoa_r(const ip4_addr_t *addr, char *buf, int buflen); 
  10.  
  11. int inet_pton4(const char *src, unsigned char *dst); 
  12.  
  13. const char *lwip_inet_ntop4(const unsigned char *src, char *dst, u32_t size); 

 手机控制器方面,我在DevEcoStudio中基于鸿蒙OS做了一版App,主要实现Tcp方式连接到指定IP,并发送指令。但由于手上没有真机,故无法调试,只能另外做了一个Android版本App代替调试,有些遗憾,希望也能借此机会拿到P40,完成这个梦想,也一睹鸿蒙OS的芳容。

这是在DevEcoStudio中的工程截图:


模拟器运行起来长这样:


就是模拟器没法联网,比较无奈。不过这不妨碍做一个Android版本用来测试,核心代码如下:

  1. public class MainActivity extends AppCompatActivity { 
  2.  
  3. @Override 
  4.  
  5. protected void onCreate(Bundle savedInstanceState) { 
  6.  
  7. super.onCreate(savedInstanceState); 
  8.  
  9. setContentView(R.layout.activity_main); 
  10.  
  11. //添加按钮事件回调 
  12.  
  13. this.findViewById(R.id.btn_go).setOnClickListener(new View.OnClickListener() { 
  14.  
  15. @Override 
  16.  
  17. public void onClick(View view) { 
  18.  
  19. new Thread(new Runnable() { 
  20.  
  21. @Override 
  22.  
  23. public void run() { 
  24.  
  25. EditText editIp = findViewById(R.id.edit_ip);//界面添加了一个IP地址输入框 
  26.  
  27. String ip = editIp.getText().toString(); 
  28.  
  29. sendCmd(ip);//向指定IP发送指令 
  30.  
  31.  
  32. }).start(); 
  33.  
  34.  
  35. }); 
  36.  
  37.  
  38. private Socket socket; 
  39.  
  40. private void sendCmd(String ipAddr){ 
  41.  
  42. int port = 8888;//开发板socket server监听端口号8888 
  43.  
  44. try { 
  45.  
  46. if(socket == null){ 
  47.  
  48. socket = new Socket(ipAddr, port);//创建socket客户端 
  49.  
  50. Log.i("JoyStick""Create socket!!"); 
  51.  
  52.  
  53. String cmdData = "A";//发送一个A 
  54.  
  55. byte data[] = cmdData.getBytes(); 
  56.  
  57. socket.getOutputStream().write(data); 
  58.  
  59. Log.i("JoyStick""Send success!!"); 
  60.  
  61. showMessage("Send success!", Toast.LENGTH_SHORT); 
  62.  
  63.  
  64. catch (Exception e) 
  65.  
  66.  
  67. e.printStackTrace(); 
  68.  
  69. Log.e("JoyStick", e.toString()); 
  70.  
  71. showMessage("Send Error!\n" + e.toString(), Toast.LENGTH_SHORT); 
  72.  
  73.  
  74.  

 APP在我的mate20上运行界面如下:


这里只是发送了一种指令“A",因为FlappyBird只用到了一个控制按钮,如果考虑通用性的话,可以制定一套协议,实现手柄所有按键的指令发送。

例如:左L,右R,上U,下D,按键A/B/P/Q等,留待以后完善。

好了,编译、烧板、运行。实际操作起来,手感还是不错的,上图:

这是按S2显示IP演示:

这是手机控制演示:


这是演示视频:

https://harmonyos.51cto.com/show/2767

代码奉上:

https://gitee.com/pleiades/harmonyos_flappy_bird

感谢大家的支持~

后续打算将一些套件没有的外设纳入进来,比如GPS模块,摄像头,蓝牙之类的,应该能碰撞出更多的创意火花,大家觉得如何呢?

©著作权归作者和HarmonyOS技术社区共同所有,如需转载,请注明出处,否则将追究法律责任

想了解更多内容,请访问:

51CTO和华为官方合作共建的鸿蒙技术社区

https://harmonyos.51cto.com/#zz

 

责任编辑:jianghua 来源: 鸿蒙社区
相关推荐

2020-12-02 11:55:40

OLED

2020-11-25 11:55:47

FlappyBird

2021-09-02 15:25:53

鸿蒙HarmonyOS应用

2023-08-07 15:18:29

游戏开发鸿蒙Arkts

2022-07-29 14:47:34

数独Sudoku鸿蒙

2020-11-30 06:20:13

javascript

2021-01-12 12:16:55

鸿蒙HarmonyOS游戏

2022-11-01 15:17:48

JS鸿蒙小游戏

2022-02-11 14:39:11

游戏JS鸿蒙

2022-02-11 14:02:09

游戏JS鸿蒙

2022-10-28 16:20:10

JS鸿蒙小游戏

2020-11-12 09:44:43

鸿蒙

2022-08-25 21:41:43

ArkUI鸿蒙

2022-03-24 07:57:58

Python水果忍者游戏

2020-11-03 12:26:55

Hi3861

2024-01-15 07:47:09

井字棋游戏编程练习Python

2022-03-29 07:40:23

H5游戏开发扫雷游戏

2022-02-17 20:18:27

JS鸿蒙操作系统

2022-10-31 15:22:37

JS鸿蒙小游戏

2023-01-03 15:16:27

点赞
收藏

51CTO技术栈公众号