查看: 10574|回复: 62

[原创] 【Battle没你不行】无限火力—使用EW-win不要太爽

  [复制链接]
  • TA的每日心情
    擦汗
    2024-11-7 09:48
  • 签到天数: 1 天

    连续签到: 1 天

    [LV.1]初来乍到

    35

    主题

    83

    帖子

    0

    金牌会员

    Rank: 6Rank: 6

    积分
    1252
    最后登录
    2025-8-5
    发表于 2022-3-29 15:56:24 | 显示全部楼层 |阅读模式
    这个活动好:【Battle没你不行】无限火力—全民游戏 - 活动专区 - 恩智浦技术社区 (nxpic.org.cn)。无限火力—使用EW-win不要做游戏不要太爽

    1、UI页面
    二话不说先看效果,第一个模拟飞行

    gameUI.gif
    下载到板子上的演示:
    gameUI1.gif

    然后在根据范例模板快速修修改,生成独立的打砖块。

    1255054155.jpg
    2、这个都是使用embedded-wizard辅助开发的工具,使用了非常丝滑的插件,因为使用了独特的图形化插件,开发的速度是用小时计,而不是以前的需要花掉头发的代价。
    这个输出的代码,可以输入到MCUXpressoIDE 中去进一步加工,快速实现嵌入式开发。

    3、软件和硬件
    3.1 需要的软件embedded-wizard Simplify Your GUI Development - Embedded Wizard (embedded-wizard.de)
    MCUXpressoIDE
    3.2 使用的硬件LPCXpresso54628
    Getting Started with the LPCXpresso54628 Development Board | NXP Semiconductors
    该板由LPC54628目标器件和板载CMSIS-DAP/SEGGER®J-Link兼容的硬件调试器组成。板载硬件调试器与MCUXpresso IDE及Keil和IAR®等其他领先的工具链兼容。
    这个是一个强悍的ARM-M4内核的芯片,功能丰富。LPC546XX:基于Arm® Cortex®-M4内核的高效微控制器(MCU),带先进外设。
    显示屏是272x480彩色电容式触摸屏LCD10/100Mbps以太网(RJ45连接器)Winbond 128 Mb W25Q128JVFIM四通道SPI闪存Winbond 128 Mb W9812G6JB-6I SDRAM全尺寸SD/MMC卡插槽恩智浦MMA8652FCR1加速度传感器Knowles SPH0641LM4H数字麦克风立体声音频编解码器,带线路输入/输出

    Capture.PNG
    4、开发过程
    4.1 embedded-wizard开发,启动代码,
    11.PNG
    然后进入主控brick积木构件中,开发主要只是围绕application这个定制模块进行,很像android studio使用一个所见即所得的交互界面,但是代码更简单,都是用一个个更低层级的brick组成,从程序逻辑就是逐步按照对象编程,一只写代码到底层函数和变量赋值,确实需要的代码,用和brick模块关联的inline嵌入式代码就可以搞定。
    模块之间,通过slot机制,进行任务触发,直接形成程序链。这个自动假设模块,正确选择已经内置的各种仪表盘,然后选择动画机制,是effect效果模块,就可以非常简便形成模拟飞行的过程。
    增加对于touch响应的WipeTouchHandle,形成一个slot,对应实现全局变量的修改,在图像自动刷新的过程中,就实现了飞行姿态的控制和响应,

    1.   case Core::Direction.Left  : BankAngle = BankAngle - 5.0;
    2.   case Core::Direction.Right : BankAngle = BankAngle + 5.0;
    3.   case Core::Direction.Top    : AttackAngle = AttackAngle - 5.0;
    4.   case Core::Direction.Bottom  : AttackAngle = AttackAngle + 5.0;
    5.   default: ;
    6. }

    7. /* limit calculated values */
    8. if ( BankAngle < -45.0 )
    9.   BankAngle = -45.0;
    10. if ( BankAngle > 45.0 )
    11.   BankAngle = 45.0;
    12. if ( AttackAngle < -45.0 )
    13.   AttackAngle = -45.0;
    14. if ( AttackAngle > 45.0 )
    15.   AttackAngle = 45.0;

    16. /* restart autopilot... */
    17. AutoPilotTimer.Enabled = false;
    18. AutoPilotTimer.Enabled = true;
    复制代码
    13.PNG
    界面如下图,这个对于飞行控阔以,但是大部分不爱玩,那么下一个打砖块是消灭时间利器,可以尝试一下。
    ii.PNG
    4.2 直接下载到办卡
    embedded-wizard提供了独立的开发和下载工具,直接在GCC下可以编译,使用NXP的redlink下载二进制代码。当开发环境配置好以后就非常简单,第一步make
    30.PNG
    31.PNG
    33.PNG
    再一步  make install
    36.PNG
    完全不用再进入MCUxpresso IDE

    5、打砖块
    5.1 同上启动打砖块的开发界面,创建工程,一定选中开发平台,是NXP的,这个ew-win是一个跨平台开发工具,可以在windows上同样的代码开发。
    20.PNG
    然后选择到application的交互界面,
    21.PNG
    这个已经更换背景为无限火力的热图,不过有些太酷炫了,在打砖块的时候砖块不是很清晰,这个代码首先启动的init初始化,根据关卡设置砖块布置,然后开始启动计时和计分,代码逻辑部分异常简单,就是不断更新砖块,小球等的相对位置

    1. <blockquote>super( aState );
    复制代码
    24.PNG
    中间最关键的逻辑判断就是碰撞函数,根据碰撞情况改变状态和
    25.PNG
    1. var int32 noOfBricks = 0;

    2. /* first check for collisions with any bricks */
    3. noOfBricks = noOfBricks + BrickRow1.CheckCollision( aBall );
    4. noOfBricks = noOfBricks + BrickRow2.CheckCollision( aBall );
    5. noOfBricks = noOfBricks + BrickRow3.CheckCollision( aBall );
    6. noOfBricks = noOfBricks + BrickRow4.CheckCollision( aBall );
    7. noOfBricks = noOfBricks + BrickRow5.CheckCollision( aBall );

    8. /* check if level is completed */
    9. if ( noOfBricks == 0 )
    10. {
    11.   /* add 50 bonus points */
    12.   Data.Score = Data.Score + 50;

    13.   /* next level */
    14.   Data.Level = Data.Level + 1;
    15.   postsignal PrepareLevel;

    16.   /* increase speed ;-) */
    17.   if ( Data.Level < 25 )
    18.     speedFactor = speedFactor + 0.005;
    19. }

    20. /* hit left/right border */
    21. if ( ( aBall.Bounds.x1 <= 0 && aBall.SpeedX < 0.0 ) || ( aBall.Bounds.x2 >= Bounds.w && aBall.SpeedX > 0.0 ) )
    22.   aBall.SpeedX = -aBall.SpeedX;

    23. /* hit top border */
    24. if ( aBall.Bounds.y1 <= 0 && aBall.SpeedY < 0.0 )
    25.   aBall.SpeedY = -aBall.SpeedY;


    26. /* hit the paddle */
    27. if ( aBall.Bounds.y2 > Paddle.Bounds.y1 && aBall.Bounds.y2 < Paddle.Bounds.y2 && aBall.SpeedY > 0.0 )
    28. {

    29.   /* left corner corner of the paddle */
    30.   if ( aBall.Bounds.x1 < Paddle.Bounds.x1 && aBall.Bounds.x2 > Paddle.Bounds.x1 )
    31.   {
    32.     var int32 dx = aBall.Bounds.x2 - Paddle.Bounds.x1;
    33.     var int32 dy = aBall.Bounds.y2 - Paddle.Bounds.y1;
    34.     if ( math_pow(dx,2.0) + math_pow(dy,2.0) < math_pow(aBall.Bounds.w,2.0) && dy < Paddle.Bounds.h/2 )
    35.     {
    36.       aBall.SpeedY = -aBall.SpeedY;
    37.       aBall.SpeedX = aBall.SpeedX + (float)( aBall.Bounds.center.x - Paddle.Bounds.center.x ) / (float)(Paddle.Bounds.w);
    38.     }
    39.   }
    40.   /* right corner corner of the paddle */
    41.   if ( aBall.Bounds.x2 > Paddle.Bounds.x2 && aBall.Bounds.x1 < Paddle.Bounds.x2 )
    42.   {
    43.     var int32 dx = Paddle.Bounds.x2 - aBall.Bounds.x1;
    44.     var int32 dy = aBall.Bounds.y2 - Paddle.Bounds.y1;
    45.     if ( math_pow(dx,2.0) + math_pow(dy,2.0) < math_pow(aBall.Bounds.w,2.0) && dy < Paddle.Bounds.h/2 )
    46.     {
    47.       aBall.SpeedY = -aBall.SpeedY;
    48.       aBall.SpeedX = aBall.SpeedX + (float)( aBall.Bounds.center.x - Paddle.Bounds.center.x ) / (float)(Paddle.Bounds.w);
    49.     }
    50.   }
    51.   /* center of paddle */
    52.   else if ( aBall.Bounds.x1 > Paddle.Bounds.x1 && aBall.Bounds.x2 < Paddle.Bounds.x2 )  
    53.   {
    54.     aBall.SpeedY = -aBall.SpeedY;
    55.     aBall.SpeedX = aBall.SpeedX + (float)( aBall.Bounds.center.x - Paddle.Bounds.center.x ) / (float)(Paddle.Bounds.w);
    56.   }
    57. }

    58. /* ball is out :-( */
    59. if ( aBall.Bounds.y1 >= Bounds.y2 )
    60. {
    61.   ballMove = false;
    62.   
    63.   /* increase the ball lost counter */
    64.   Data.Lost = Data.Lost + 1;

    65.   /* decrease 100 points */
    66.   Data.Score = Data.Score - 100;
    67. }
    复制代码
    4.2 编译和模拟运行,这个过程就直接点击build,虽然是嵌入式开发,但是在windows也可以顺利跑所见即所得的模拟器
    gameUI3.gif

    5 导入MCUxpressoIDE
    5.1 正确配置开发环境后,同时生成一个generated文件夹,这个就是可直接导出的,启动MCUxpresso导入工程
    1.PNG
    这个就是可以直接编译的
    2.PNG
    然后下载
    4.PNG
    这样就在开发板上直接跑起来了。
    5.2 代码分析
    生成的主代码main.c只提供了一个框架,同时启动了freeRTOS,但是这个只是为了给其他任务提供交互接口,对于ew-win是有独立的屏幕刷新和时钟控制的。主要的代码在ewmain.c中,实现初始化,update更新等功能,整个代码其实都已经封装好了,对于UI界面以及完成,除非是非常熟悉搞事情,完全没有必要再深入这个循环中。
    而且仔细读代码之后,整个控制逻辑完全在embedded-wizard的图形化开发界面实现,代码简洁,可读性非常好。
    唯一的问题,就是核心的驱动是有segger提供的封装库中提供,限制代码范围的是免费版,如果希望解锁高级工程,那么就需要licence了。

    1. int EwInit( void )
    2. {
    3.   /* initalize system clocks */
    4.   EwBspClockInit();

    5.   /* set RTC, if current RTC time is before the minimum time */
    6.   if ( EwBspClockGetTime() < RTC_MINIMUM_TIME )
    7.     EwBspClockSetTime( RTC_DEFAULT_TIME );

    8.   /* initialize display */
    9.   EwPrint( "Initialize Display...                        " );
    10.   CHECK_HANDLE( EwBspDisplayInit( EwScreenSize.X, EwScreenSize.Y, &DisplayInfo ));

    11.   /* initialize touchscreen */
    12.   EwPrint( "Initialize Touch Driver...                   " );
    13.   CHECK_HANDLE( EwBspTouchInit( EwScreenSize.X, EwScreenSize.Y, &DisplayInfo ));

    14.   #if EW_MEMORY_POOL_SIZE > 0
    15.     /* initialize heap manager */
    16.     EwPrint( "Initialize Memory Manager...                 " );
    17.     EwInitHeap( 0 );
    18.     EwAddHeapMemoryPool( (void*)EW_MEMORY_POOL_ADDR, EW_MEMORY_POOL_SIZE );

    19.     #if EW_EXTRA_POOL_SIZE > 0
    20.       EwAddHeapMemoryPool( (void*)EW_EXTRA_POOL_ADDR, EW_EXTRA_POOL_SIZE );
    21.     #endif

    22.     EwPrint( "[OK]\n" );
    23.   #endif

    24.   /* initialize the Graphics Engine and Runtime Environment */
    25.   EwPrint( "Initialize Graphics Engine...                " );
    26.   CHECK_HANDLE( EwInitGraphicsEngine( 0 ));

    27.   /* create the applications root object ... */
    28.   EwPrint( "Create Embedded Wizard Root Object...        " );
    29.   RootObject = (CoreRoot)EwNewObjectIndirect( EwApplicationClass, 0 );
    30.   CHECK_HANDLE( RootObject );

    31.   EwLockObject( RootObject );
    32.   CoreRoot__Initialize( RootObject, EwScreenSize );

    33.   /* create Embedded Wizard viewport object to provide uniform access to the framebuffer */
    34.   EwPrint( "Create Embedded Wizard Viewport...           " );
    35.   Viewport = EwInitViewport( EwScreenSize, EwNewRect( 0, 0, DisplayInfo.BufferWidth, DisplayInfo.BufferHeight ),
    36.     0, 255, DisplayInfo.FrameBuffer, DisplayInfo.DoubleBuffer, 0, 0 );
    37.   CHECK_HANDLE( Viewport );

    38.   /* initialize your device driver(s) that provide data for your GUI */
    39.   DeviceDriver_Initialize();

    40.   return 1;
    41. }


    42. /*******************************************************************************
    43. * FUNCTION:
    44. *   EwDone
    45. *
    46. * DESCRIPTION:
    47. *   EwDone() is responsible to shutdown the application and to release all
    48. *   used resources.
    49. *
    50. * ARGUMENTS:
    51. *   None
    52. *
    53. * RETURN VALUE:
    54. *   None.
    55. *
    56. *******************************************************************************/
    57. void EwDone( void )
    58. {
    59.   /* deinitialize your device driver(s) */
    60.   DeviceDriver_Deinitialize();

    61.   /* destroy the applications root object and release unused resources and memory */
    62.   EwPrint( "Shutting down Application...                 " );
    63.   EwDoneViewport( Viewport );
    64.   EwUnlockObject( RootObject );
    65.   EwReclaimMemory();
    66.   EwPrint( "[OK]\n" );

    67.   /* deinitialize the Graphics Engine */
    68.   EwPrint( "Deinitialize Graphics Engine...              " );
    69.   EwDoneGraphicsEngine();
    70.   EwPrint( "[OK]\n" );

    71.   #if EW_MEMORY_POOL_SIZE > 0
    72.     /* deinitialize heap manager */
    73.     EwDoneHeap();
    74.   #endif

    75.   EwPrint( "Deinitialize Touch Driver...                 " );
    76.   EwBspTouchDone();
    77.   EwPrint( "[OK]\n" );

    78.   /* deinitialize display */
    79.   EwBspDisplayDone( &DisplayInfo );

    80.   Viewport   = 0;
    81.   RootObject = 0;
    82. }


    83. /*******************************************************************************
    84. * FUNCTION:
    85. *   EwProcess
    86. *
    87. * DESCRIPTION:
    88. *   EwProcess() implements one cycle of the main loop. This function has to be
    89. *   called in an (endless) loop and contains typically the following steps:
    90. *   1. Processing data from your device driver(s)
    91. *   2. Processing key events
    92. *   3. Processing cursor or touch screen events
    93. *   4. Processing timers
    94. *   5. Processing signals
    95. *   6. Updating the screen
    96. *   7. Triggering the garbage collection
    97. *   For more information concerning the integration of an Embedded Wizard
    98. *   generated GUI application into your main application, please see
    99. *   https://doc.embedded-wizard.de/main-loop
    100. *
    101. * ARGUMENTS:
    102. *   None.
    103. *
    104. * RETURN VALUE:
    105. *   1, if further processing is needed, 0 otherwise.
    106. *
    107. *******************************************************************************/
    108. int EwProcess( void )
    109. {
    110.   int          timers  = 0;
    111.   int          signals = 0;
    112.   int          events  = 0;
    113.   int          devices = 0;
    114.   XEnum        cmd     = CoreKeyCodeNoKey;
    115.   int          noOfTouch;
    116.   XTouchEvent* touchEvent;
    117.   int          touch;
    118.   int          finger;
    119.   XPoint       touchPos;

    120.   /* process data of your device driver(s) and update the GUI
    121.      application by setting properties or by triggering events */
    122.   devices = DeviceDriver_ProcessData();

    123.   /* receive keyboard inputs */
    124.   cmd = EwGetKeyCommand();

    125.   if ( cmd != CoreKeyCodeNoKey )
    126.   {
    127.     if ( cmd == CoreKeyCodePower )
    128.       return 0;

    129.     /* feed the application with a 'press' and 'release' event */
    130.     events |= CoreRoot__DriveKeyboardHitting( RootObject, cmd, 0, 1 );
    131.     events |= CoreRoot__DriveKeyboardHitting( RootObject, cmd, 0, 0 );
    132.   }

    133.   /* receive (multi-) touch inputs and provide it to the application */
    134.   noOfTouch = EwBspTouchGetEvents( &touchEvent );

    135.   if ( noOfTouch > 0 )
    136.   {
    137.     for ( touch = 0; touch < noOfTouch; touch++ )
    138.     {
    139.       /* get data out of the touch event */
    140.       finger     = touchEvent[ touch ].Finger;
    141.       touchPos.X = touchEvent[ touch ].XPos;
    142.       touchPos.Y = touchEvent[ touch ].YPos;

    143.       /* begin of touch cycle */
    144.       if ( touchEvent[ touch ].State == EW_BSP_TOUCH_DOWN )
    145.         events |= CoreRoot__DriveMultiTouchHitting(  RootObject, 1, finger, touchPos );

    146.       /* movement during touch cycle */
    147.       else if ( touchEvent[ touch ].State == EW_BSP_TOUCH_MOVE )
    148.         events |= CoreRoot__DriveMultiTouchMovement( RootObject, finger, touchPos );

    149.       /* end of touch cycle */
    150.       else if ( touchEvent[ touch ].State == EW_BSP_TOUCH_UP )
    151.         events |= CoreRoot__DriveMultiTouchHitting(  RootObject, 0, finger, touchPos );
    152.     }
    153.   }

    154.   /* process expired timers */
    155.   timers = EwProcessTimers();

    156.   /* process the pending signals */
    157.   signals = EwProcessSignals();

    158.   /* refresh the screen, if something has changed and draw its content */
    159.   if ( devices || timers || signals || events )
    160.   {
    161.     if ( CoreRoot__DoesNeedUpdate( RootObject ))
    162.       EwUpdate( Viewport, RootObject );

    163.     /* just for debugging purposes: check the memory structure */
    164.     EwVerifyHeap();

    165.     /* after each processed message start the garbage collection */
    166.     EwReclaimMemory();

    167.     /* print current memory statistic to console interface */
    168.     #ifdef EW_PRINT_MEMORY_USAGE
    169.       EwPrintProfilerStatistic( 0 );
    170.     #endif

    171.     /* evaluate memory pools and print report */
    172.     #ifdef EW_DUMP_HEAP
    173.       EwDumpHeap( 0 );
    174.     #endif
    175.   }
    176.   else
    177.   {
    178.     /* otherwise sleep/suspend the UI application until a certain event occurs or a timer expires... */
    179.     EwBspEventWait( EwNextTimerExpiration());
    180.   }

    181.   return 1;
    182. }


    183. /*******************************************************************************
    184. * FUNCTION:
    185. *   EwUpdate
    186. *
    187. * DESCRIPTION:
    188. *   The function EwUpdate performs the screen update of the dirty area.
    189. *
    190. * ARGUMENTS:
    191. *   aViewPort    - Viewport used for the screen update.
    192. *   aApplication - Root object used for the screen update.
    193. *
    194. * RETURN VALUE:
    195. *   None
    196. *
    197. *******************************************************************************/
    198. static void EwUpdate( XViewport* aViewport, CoreRoot aApplication )
    199. {
    200.   XBitmap*       bitmap;
    201.   GraphicsCanvas canvas     = EwNewObject( GraphicsCanvas, 0 );
    202.   XRect          updateRect = {{ 0, 0 }, { 0, 0 }};

    203.   if ( !canvas )
    204.     return;

    205.   if ( DisplayInfo.UpdateMode == EW_BSP_DISPLAY_UPDATE_NORMAL )
    206.   {
    207.     bitmap = EwBeginUpdate( aViewport );

    208.     /* redraw the dirty area of the screen */
    209.     if ( bitmap  )
    210.     {
    211.       GraphicsCanvas__AttachBitmap( canvas, (XHandle)bitmap );
    212.       updateRect = CoreRoot__UpdateGE20( aApplication, canvas );
    213.       GraphicsCanvas__DetachBitmap( canvas );
    214.       EwEndUpdate( aViewport, updateRect );
    215.     }
    216.   }
    217.   else
    218.   {
    219.     int regions = CoreRoot__BeginUpdate( aApplication );

    220.     while ( regions-- )
    221.     {
    222.       /* get rectangular area of the update region for scratch-pad buffer */
    223.       if ( DisplayInfo.UpdateMode == EW_BSP_DISPLAY_UPDATE_SCRATCHPAD )
    224.         updateRect = CoreRoot__GetUpdateRegion( aApplication, regions );

    225.       /* iterate through all update areas */
    226.       while ( EwBspDisplayGetUpdateArea( &updateRect ))
    227.       {
    228.         /* update the current subarea */
    229.         bitmap = EwBeginUpdateArea( aViewport, updateRect );
    230.         GraphicsCanvas__AttachBitmap( canvas, (XHandle)bitmap );
    231.         CoreRoot__UpdateCanvas( aApplication, canvas, updateRect.Point1 );
    232.         GraphicsCanvas__DetachBitmap( canvas );
    233.         EwEndUpdate( aViewport, updateRect );
    234.       }

    235.       if ( DisplayInfo.UpdateMode != EW_BSP_DISPLAY_UPDATE_SCRATCHPAD )
    236.         break;
    237.     }
    238.     CoreRoot__EndUpdate( aApplication );
    239.   }
    240. }
    复制代码



    gameUI.gif
    该会员没有填写今日想说内容.
    回复

    使用道具 举报

  • TA的每日心情
    开心
    6 天前
  • 签到天数: 1504 天

    连续签到: 1 天

    [LV.Master]伴坛终老

    97

    主题

    4692

    帖子

    12

    版主

    Rank: 7Rank: 7Rank: 7

    积分
    10093
    最后登录
    2025-8-8
    发表于 2022-3-29 18:01:55 | 显示全部楼层
    学习了
    也看到了差距
    该会员没有填写今日想说内容.
    回复 支持 反对

    使用道具 举报

  • TA的每日心情
    奋斗
    昨天 20:27
  • 签到天数: 2475 天

    连续签到: 7 天

    [LV.Master]伴坛终老

    17

    主题

    5410

    帖子

    5

    金牌会员

    Rank: 6Rank: 6

    积分
    11384
    最后登录
    2025-8-13
    发表于 2022-3-29 20:32:49 | 显示全部楼层
    动手做了一个,牛!
    该会员没有填写今日想说内容.
    回复 支持 反对

    使用道具 举报

  • TA的每日心情
    慵懒
    半小时前
  • 签到天数: 2396 天

    连续签到: 105 天

    [LV.Master]伴坛终老

    84

    主题

    2万

    帖子

    3

    版主

    Rank: 7Rank: 7Rank: 7

    积分
    22248
    最后登录
    2025-8-14
    发表于 2022-3-30 11:54:17 | 显示全部楼层
    厉害了,好好学习
    该会员没有填写今日想说内容.
    回复 支持 反对

    使用道具 举报

  • TA的每日心情
    开心
    昨天 10:35
  • 签到天数: 1714 天

    连续签到: 7 天

    [LV.Master]伴坛终老

    23

    主题

    1万

    帖子

    1

    金牌会员

    Rank: 6Rank: 6

    积分
    15892
    最后登录
    2025-8-13
    发表于 2022-3-30 14:20:42 | 显示全部楼层
    厉害了,好好学习
    跟着日天混,三天饱九顿!
    回复 支持 反对

    使用道具 举报

  • TA的每日心情
    开心
    2025-7-11 08:53
  • 签到天数: 301 天

    连续签到: 2 天

    [LV.8]以坛为家I

    3914

    主题

    7529

    帖子

    0

    管理员

    Rank: 9Rank: 9Rank: 9

    积分
    39830
    最后登录
    2025-8-14
    发表于 2022-3-31 09:29:02 | 显示全部楼层
    这个很有意思啊!
    qiandao qiandao
    回复 支持 反对

    使用道具 举报

  • TA的每日心情
    奋斗
    2023-1-26 09:36
  • 签到天数: 31 天

    连续签到: 1 天

    [LV.5]常住居民I

    0

    主题

    122

    帖子

    0

    中级会员

    Rank: 3Rank: 3

    积分
    480
    最后登录
    2023-3-7
    发表于 2022-3-31 09:44:56 | 显示全部楼层
    签到打卡
    QQ图片20220325111418.png
    微信图片_20220328154557.png
    哎...今天够累的,签到来了~
    回复

    使用道具 举报

  • TA的每日心情
    奋斗
    2022-6-14 16:43
  • 签到天数: 13 天

    连续签到: 1 天

    [LV.3]偶尔看看II

    0

    主题

    37

    帖子

    0

    注册会员

    Rank: 2

    积分
    124
    最后登录
    2022-12-21
    发表于 2022-3-31 09:46:57 | 显示全部楼层
    签到签到
    29.png
    哎...今天够累的,签到来了~
    回复

    使用道具 举报

  • TA的每日心情
    奋斗
    昨天 10:06
  • 签到天数: 1190 天

    连续签到: 3 天

    [LV.10]以坛为家III

    6

    主题

    7116

    帖子

    1

    金牌会员

    Rank: 6Rank: 6

    积分
    9278
    最后登录
    2025-8-13
    发表于 2022-3-31 13:45:33 | 显示全部楼层
    学习学习
    该会员没有填写今日想说内容.
    回复

    使用道具 举报

  • TA的每日心情
    擦汗
    2022-2-25 10:20
  • 签到天数: 32 天

    连续签到: 1 天

    [LV.5]常住居民I

    1

    主题

    290

    帖子

    0

    金牌会员

    Rank: 6Rank: 6

    积分
    1147
    最后登录
    2025-7-2
    发表于 2022-3-31 13:52:20 | 显示全部楼层
    打卡,正想看看界面UI相关的东西
    该会员没有填写今日想说内容.
    回复 支持 反对

    使用道具 举报

    您需要登录后才可以回帖 注册/登录

    本版积分规则

    关闭

    站长推荐上一条 /3 下一条

    Archiver|手机版|小黑屋|恩智浦技术社区

    GMT+8, 2025-8-14 09:51 , Processed in 0.111313 second(s), 29 queries , MemCache On.

    Powered by Discuz! X3.4

    Copyright © 2001-2024, Tencent Cloud.

    快速回复 返回顶部 返回列表