首页 > 其他分享 >【M5Stack物联网开发】第四章 用户界面

【M5Stack物联网开发】第四章 用户界面

时间:2024-05-13 15:42:16浏览次数:21  
标签:游戏 用户 M5 GAME M5Stack 设计 Display 第四章 用户界面

1 交互设计

交互设计(Interaction Design,简称IxD)是一种专注于创造有意义的关系,介于人与人、人与产品或服务之间的设计领域。这种设计形式主要关注于如何使产品、系统或服务与用户之间的交互更加有效、效率高、直观和愉悦。

交互设计的核心目标是提高用户体验和满意度,通过改善产品的可用性和可访问性来实现。它涉及到多个方面,包括:

  • 可用性:设计易于使用和理解的产品。
  • 功能性:确保产品功能满足用户的需求。
  • 情感化:设计能引发用户情感共鸣的产品。
  • 美学:产品的视觉和触觉设计。
  • 交互逻辑:用户与产品交互的流程和逻辑。

交互设计师常常需要考虑到用户的行为模式,并通过设计来引导和改善这些行为。常用的方法和工具包括用户研究、原型设计、用户测试和迭代设计等。交互设计不仅仅应用于数字产品,如网站和应用程序,也广泛应用于物理产品和服务的设计中。

1.1 UI设计

UI设计,即用户界面设计(User Interface Design),是交互设计的一个重要分支,专注于用户与产品界面之间的交互方式。UI设计的核心目标是通过创建直观、美观且功能性强的界面来提升用户体验。这涉及到视觉元素的设计,如布局、颜色、图标、按钮等,以及它们如何组织和工作以支持用户操作。

UI设计的主要组成部分包括:

  1. 布局:界面元素的组织和结构,决定了用户如何导航和使用产品。
  2. 视觉元素:
    • 颜色:使用合适的颜色方案可以影响用户的情绪和注意力,同时强化品牌认知。
    • 字体:选择易读且美观的字体来提升信息的可读性和界面的美观度。
    • 图标和按钮:设计直观的图标和按钮,使用户能快速理解并执行操作。
  3. 交互:设计元素的交互方式,如点击、滑动、拖拽等,这些都是用户与界面互动的方式。
  4. 动画和过渡:合理的动画和过渡效果可以提升用户体验,使界面感觉更加流畅和自然。

示例:

1. 移动应用的UI设计:

考虑一个常见的社交媒体应用,如Instagram。其UI设计包括:

  • 布局:清晰的导航栏位于屏幕底部,方便用户使用单手操作。
  • 颜色方案:使用温和的色调,以视觉上不过分刺激用户,同时保持品牌识别。
  • 图标设计:图标直观,如放大镜代表搜索,心形代表喜欢,这些都是用户容易理解和记忆的。
  • 动画:用户点赞时的心形图标会有弹跳效果,增加了互动的趣味性。

2. 网站UI设计:

以Amazon的在线购物网站为例。其UI设计特点包括:

  • 布局:清晰的分类导航,搜索栏位于页面顶部,方便用户快速找到所需商品。
  • 颜色和字体:使用品牌色和清晰的字体,确保用户能够轻松阅读和识别不同类别和功能。
  • 图标和按钮:购物车图标明显,结账按钮颜色鲜明,引导用户进行购买

1.2 UX设计

UX设计,即用户体验设计(User Experience Design),是交互设计中关注用户在使用产品或服务过程中的体验的一个领域。UX设计不仅仅涉及到界面的美观,更重要的是整体体验的流畅性、效率、易用性以及满足用户需求的程度。

UX设计的主要组成部分包括:

  1. 用户研究:了解目标用户的需求、行为和心理特点。
  2. 信息架构:组织和结构化信息,使用户能够容易地找到所需内容。
  3. 用户流程(User Flows):设计用户在应用中的行动路径,优化任务完成的效率。
  4. 交互设计:确保用户与产品的交互简单直观。
  5. 原型和线框图(Wireframing and Prototyping):创建初步设计模型,用于测试和改进设计。
  6. 可用性测试:通过用户测试来检验设计的有效性,确保用户能够顺利使用产品。

示例:

1. 网站的UX设计:

以一个在线图书馆网站为例。其UX设计特点可能包括:

  • 用户研究:调查用户最常查找的图书类型和使用设备,从而确定重点优化的功能。
  • 信息架构:将图书分类清晰地展示,如文学、科技、历史等,以及一个明显的搜索功能。
  • 用户流程:简化借书流程,用户可以在几步内完成借书,包括搜索、选择、借阅和确认。
  • 原型和线框图:设计初步的页面布局,通过迭代改进以提升用户体验。
  • 可用性测试:邀请真实用户测试网站,收集反馈并优化设计。

2. 移动应用的UX设计:

考虑一个健康追踪应用,如Fitbit。其UX设计特点包括:

  • 用户研究:了解用户在使用健康追踪应用时的主要需求,如记录运动、监测睡眠和饮食。
  • 信息架构:清晰地展示健康数据,如步数、心率、卡路里消耗等。
  • 用户流程:优化添加新的健康记录的流程,确保用户可以轻松输入和查看数据。
  • 交互设计:设计简单直观的交互元素,如滑动切换不同的健康指标。
  • 可用性测试:定期进行用户测试,确保新功能的可用性和解决用户反馈的问题。

2 M5Stack Core2中的交互技术

2.1 使用按钮

M5Stack Core2 v1.1 的虚拟按钮是通过其电容触控屏实现的,这为用户提供了更多的交互可能性。虚拟按钮位于屏幕的底部,从左侧开始分别为BtnA、BtnB和BtnC,三个按钮可以在软件中自定义其功能,包括点击(Press)、释放(Release)、长按(Hold)等操作,非常适合需要用户界面交互的应用。

M5Unified中的M5.BtnA、M5.BtnB、M5.BtnC三个模块分别对应按钮的各个操作。

#include <M5Unified.h>

void setup()
{
    auto cfg = M5.config();
    M5.begin(cfg);
}

void loop()
{
    // 只要按压(Press)即可,与点击(Click)不同
    // 点击(Click)是按压后快速释放(Release)
    if(M5.BtnA.isPressed())
        M5.Display.println("BtnA is Pressed");

    // 按压(Press)2000毫秒(2秒)后触发
    // 同样,不需要点击(Click)的释放(Release)操作
    if(M5.BtnB.pressedFor(2000))
        M5.Display.println("BtnB pressed for 2000 ms");

    // 点击(Click),包含两个动作
    // 按压(Press)与快速释放(Release)
    if(M5.BtnC.getState() == M5.BtnC.state_clicked)
        M5.Display.println("BtnC has clicked state");

    delay(100);
    // 更新所有硬件状态
    M5.update();
}

2.2 使用触摸屏

M5Stack Core2 具有一块集成的触摸屏。这块触摸屏是一个3.5英寸的彩色TFT LCD显示屏,分辨率为320x240像素。当前版本中,它支持最多2个触控点的多点触控,这对于开发交互式应用程序非常有用。

M5.Touch 是M5Unified API中用于处理触摸屏输入的一个模块。该模块提供了一系列函数,使开发者能够轻松地获取和处理来自Core2触摸屏的输入数据。

#include <M5Unified.h>

void setup()
{
    auto cfg = M5.config();
    M5.begin(cfg);

    M5.Display.println("Tounch anywhere");
}

void loop()
{
    // 获取产生了几个触控点,Core2最多支持两点触控
    auto count = M5.Touch.getCount();

    if (count != 0)
        M5.Display.printf("%d ", count);

    for (int i = 0; i < count; i++)
    {
        // 获取触控点信息的方式有两种
        // 简单的获取触控位置:getTouchPointRaw
        // 获取更丰富的交互信息,比如Press、Click、Drag等:getDetail
        // 参数是获取第几个触控点的信息,触控点的索引从0开始
        auto detail = M5.Touch.getDetail(i);
        auto rowXY = M5.Touch.getTouchPointRaw(i);

        // getDetail中的x、y与getTouchPointRaw中的x、y是同一个数据
        M5.Display.printf("T%d (%d,%d | %d) ", i, rowXY.x, rowXY.y, rowXY.size);
        M5.Display.printf("detail (%d,%d | %d, %d) ", detail.x, detail.y, detail.deltaX(), detail.deltaY());
        
        // 拖动(Drag)是由两个行为构成的:保持(Hold)与拖动(Drag)
        if (detail.isDragging())
            M5.Display.print("dragging ");

        // 点击(Click)也是有两个行为构成的:按压(Press)与快速释放(Release)
        if (detail.wasClicked())
            M5.Display.print("clicked ");
            
        M5.Display.printf("\n");
    }

    delay(100);
    // 更新所有硬件状态
    M5.update();
}

2.3 制作一个按钮(Button)

M5Unified API中的M5GFX模块已经包含了一个简单的按钮,本小节我们将从头自己做一个Button。

  • 绘制一个Button的外框
  • 在Button的正中间显示Button的文字(Label)
  • 检测用户是否点击了Button
#include <M5Unified.h>

// core2 screen 320x240
#define BtnX 100
#define BtnY 90
#define BtnW 120
#define BtnH 60

void setup()
{
    auto cfg = M5.config();
    M5.begin(cfg);

    // 在屏幕上填充一个矩形,表示按钮的边框
    M5.Display.fillRect(BtnX, BtnY, BtnW, BtnH, WHITE);

    // drawCenterString是在将文字的中文位置放置在(X,Y)
    // 然后在屏幕上绘制文字
    M5.Display.setTextColor(RED);
    M5.Display.drawCenterString("Click Me", BtnX + BtnW / 2, BtnY + BtnH / 2);
}

void loop()
{
    if (M5.Touch.getCount() == 1)
    {
        auto rawXY = M5.Touch.getTouchPointRaw(0);

        // 只有当触摸的位置,在按钮范围内
        // 且触控的交互行为是点击(Click)时
        // 才进行对应操作
        if (rawXY.x > BtnX && rawXY.x < BtnX + BtnW 
        && rawXY.y > BtnY && rawXY.y < BtnY + BtnH 
        && M5.Touch.getDetail(0).wasClicked())
            M5.Display.print("Clicked ");
    }

    delay(100);
    // 更新所有硬件状态
    M5.update();
}

 

3 游戏开发概论

3.1 游戏主循环

游戏主循环(Game Loop)是游戏运行中最核心的部分,它负责控制游戏的整体流程和时间管理。游戏主循环确保游戏的状态持续更新,并且使得游戏能够响应用户输入,同时还要渲染图形输出到屏幕上。这个循环在游戏启动后会不断重复执行,直到游戏关闭。

游戏主循环的主要组成部分包括:

  1. 处理输入(Input Handling):

    • 游戏需要检测并响应玩家的输入,如键盘、鼠标或游戏手柄的操作。这一步骤确保玩家的操作能够被游戏捕捉并作出相应的反应。
  2. 更新游戏状态(Updating Game State):

    • 游戏逻辑需要更新游戏世界的状态,包括角色的移动、得分变化、AI决策等。这一步骤是游戏动态变化的核心,涉及物理计算、碰撞检测、游戏规则的执行等。
  3. 渲染输出(Rendering):

    • 一旦游戏状态更新完成,游戏引擎需要将这些信息转化为图形输出,显示到屏幕上。这包括3D模型的渲染、场景的绘制、UI元素的显示等。
  4. 维护时间管理(Time Management):

    • 确保游戏的运行速度与真实时间同步。这通常通过控制每次循环的时间(即帧率)来实现,确保游戏播放流畅且不会因为硬件性能差异而有所不同。

3.2 游戏引擎

游戏引擎是一种为开发视频游戏提供核心功能的软件开发环境,它帮助开发者通过提供编写游戏所需的多种功能和工具来简化游戏开发过程。常见的游戏引擎包括Unity、Unreal Engine等,它们各有特色但都提供了上述的一些或全部功能,使得游戏开发更加高效和灵活。这些引擎不仅适用于开发电脑和游戏机游戏,也广泛应用于移动游戏和网页游戏的开发。

游戏主循环是游戏引擎中的中心枢纽,它与游戏引擎的其他部分紧密相连,共同支持游戏的运行和功能实现。下面详细介绍游戏主循环与游戏引擎其他部分的关系:

  1. 图形渲染引擎:

    • 游戏主循环的一个重要任务是调用图形渲染引擎来绘制游戏场景。在每个循环周期中,更新后的游戏状态需要被渲染引擎转化为视觉输出,这包括场景、角色、动画和UI元素的绘制。
  2. 物理引擎:

    • 在游戏主循环中,物理引擎负责计算和模拟物理互动,如碰撞检测、物体运动等。主循环确保这些物理计算与游戏状态的更新同步进行,以保持游戏世界的一致性和实时反应。
  3. 声音处理:

    • 游戏主循环也需要与声音系统协作,确保音效和背景音乐与游戏事件同步播放。例如,当发生特定事件(如爆炸或得分)时,相应的声音效果需要在正确的时刻被触发。
  4. 脚本系统:

    • 游戏逻辑和事件通常通过脚本来控制。游戏主循环会执行这些脚本,以更新游戏状态和响应玩家的行为。脚本系统使得开发者可以灵活地编写和修改游戏逻辑,而无需修改底层代码。
  5. 动画系统:

    • 动画系统负责处理角色和物体的动画。游戏主循环在每个周期更新动画状态,确保动画的流畅播放与游戏事件的同步。
  6. 人工智能(AI):

    • AI系统在游戏主循环中更新非玩家角色的行为。这包括路径寻找、策略决策等。主循环确保AI的决策过程与游戏状态实时更新相匹配。
  7. 网络功能:

    • 对于多玩家游戏,游戏主循环必须处理网络数据的发送和接收,确保所有玩家的游戏状态同步。这通常涉及处理延迟和网络抖动的策略。
  8. 用户界面(UI)系统:

    • UI系统与游戏主循环协作,更新和响应用户界面元素。例如,当玩家得分变化时,得分板需要立即更新。
  9. 资产管理:

    • 资产管理系统负责加载和管理游戏资源,如纹理、模型和声音文件。游戏主循环需要确保这些资源在需要时可用,而不会引起性能下降。

游戏主循环通过协调这些组件的活动,确保游戏的流畅运行和良好的玩家体验。它是游戏引擎中不同系统之间交互的桥梁,是整个游戏运行机制的核心。

4 小程序3:猜数字小游戏

4.1 功能分析

猜数字小游戏是一个简单有趣的游戏,通常是这样玩的:

  • 游戏开始时,玩家会在一定范围内(比如1到100)随机选择一个数字。
  • Core2尝试猜这个数字,每猜一次,玩家会给出提示,告诉Core2猜测的数字是太高了还是太低了。
  • 游戏继续进行,直到Core2猜中正确的数字。
  • 猜中后,可以选择重新开始游戏。

4.2 伪代码

我们将使用状态机,来完成猜数字游戏的主循环。游戏有三个主要状态:GAME_STARTGAME_LOOPGAME_OVER。以下是每个部分的功能和流程:

  • GAME_START:
    • 如果“开始游戏按钮”被点击,则会执行以下操作:
      • 生成一个0到100之间的随机数,表示Core2初次猜测的值。
      • 绘制游戏的主界面。
      • 将游戏状态切换到GAME_LOOP。
  • GAME_LOOP:
    • 按钮B:如果按钮B被按下,表示Core2猜对了数字,显示游戏结束屏幕,并切换到GAME_OVER状态。
    • 按钮A:如果按钮A被按下,表示Core2猜的数字太大了,减小数字,然后重新绘制游戏界面,并保持在GAME_LOOP状态。
    • 按钮C:如果按钮C被按下,表示Core2猜的数字太小了,增大数字,,然后重新绘制游戏界面,并保持在GAME_LOOP状态。
  • GAME_OVER:
    • 如果“重新开始游戏按钮”被点击,则会执行以下操作:
      • 生成一个0到100之间的随机数,表示Core2初次猜测的值。
      • 绘制游戏的主界面。
      • 将游戏状态切换到GAME_LOOP。

4.3 功能实现

#include <M5Unified.h>

// Core2 Screen 320x240

// 定义游戏标题在屏幕中的位置
#define TitleX 160
#define TitleY 60

// 定义“开始游戏”与“再次游戏”按钮在屏幕中的文字
#define StartButtonX 80
#define StartButtonY 130
#define StartButtonWidth 160
#define StartButtonHeight 60

// 定义游戏状态机
#define GAME_START 0
#define GAME_LOOP 1
#define GAME_OVER 2
int gameStatus = GAME_START;

// Core2当前猜测的数字
int currentNumber = 0;

// 在屏幕上绘制标题,这个函数有两个参数
// title:绘制在屏幕中上位置的标题文字
// button:绘制在屏幕中下方位置的按钮文字
void drawTitleScreen(String title, String button)
{
  M5.Display.clear(BLACK);

  // drawTitle
  M5.Display.setTextSize(2);
  M5.Display.setTextColor(WHITE);
  M5.Display.drawCenterString(title, TitleX, TitleY);

  // drawButton
  M5.Display.fillRect(StartButtonX, StartButtonY, StartButtonWidth, StartButtonHeight, WHITE);

  M5.Display.setTextSize(4);
  M5.Display.setTextColor(BLACK);
  M5.Display.drawCenterString(button, StartButtonX + StartButtonWidth / 2, StartButtonY + StartButtonHeight / 4);
}

// 检测当用户触摸屏幕时,位置是否在Button内
// 返回值true:触摸位置在Button内,相当于Button Click
// 返回值false:触摸位置不在Button内
bool infoButtonClicked()
{
  auto count = M5.Touch.getCount();
  if (!count)
  {
    return false;
  }

  auto detail = M5.Touch.getTouchPointRaw();
  if (detail.x > StartButtonX && detail.x < StartButtonX + StartButtonWidth && detail.y > StartButtonY && detail.y < StartButtonY + StartButtonHeight)
  {
    return true;
  }

  return false;
}

// 绘制猜数字界面
void drawLoopScreen()
{
  M5.Display.clear(BLACK);

  // drawNumber
  M5.Display.setTextSize(4);
  M5.Display.setTextColor(WHITE);
  M5.Display.drawCenterString("is it " + String(currentNumber) + "?", TitleX, TitleY);

  // drawButton
  M5.Display.setTextSize(2);
  // 320是Core2屏幕的宽度
  auto screenWidthIn1o3 = 320 / 3;
  M5.Display.drawCenterString("Lower", screenWidthIn1o3 / 2, 220);
  M5.Display.drawCenterString("Correct", screenWidthIn1o3 + screenWidthIn1o3 / 2, 220);
  M5.Display.drawCenterString("More", screenWidthIn1o3 * 2 + screenWidthIn1o3 / 2, 220);
}

void setup()
{
  auto cfg = M5.config();
  M5.begin(cfg);

  drawTitleScreen("Number Game", "START");
}

// 游戏主循环
void loop()
{
  delay(100);
  M5.update();

  switch (gameStatus)
  {
  case GAME_START:
    if (infoButtonClicked())
    {
      // random函数可以随机生成一个正整数
      // 该函数具有一个参数,生成的随机数小于该参数
      // random(101)就是随机生成0~100的随机数
      currentNumber = random(101);
      drawLoopScreen();
      gameStatus = GAME_LOOP;
    }
    break;
  case GAME_LOOP:
    if (M5.BtnB.isPressed())
    {
      drawTitleScreen("Game Over", "AGAIN");
      gameStatus = GAME_OVER;
    }
    else if (M5.BtnA.isPressed())
    {
      currentNumber = currentNumber - random(currentNumber);
      drawLoopScreen();
      gameStatus = GAME_LOOP;
    }
    else if (M5.BtnC.isPressed())
    {
      currentNumber = currentNumber + random(101 - currentNumber);
      drawLoopScreen();
      gameStatus = GAME_LOOP;
    }
    break;
  case GAME_OVER:
    if (infoButtonClicked())
    {
      currentNumber = random(101);
      drawLoopScreen();
      gameStatus = GAME_LOOP;
    }
    break;
  default:
    break;
  }
}

 

4.4 C++ 函数

 

4.5 练习

在进行猜数字时,可以看到,Core2在增加和减少时,会一下变得过多,比如第一次猜20,然后玩家按下More,于是第二次猜50,此时玩家按下Lower,第三次猜10。

实际上,第三次猜测的值应该在20-50之间才合理。请完成这个功能。

 

5 理论与术语总结

标签:游戏,用户,M5,GAME,M5Stack,设计,Display,第四章,用户界面
From: https://www.cnblogs.com/pangxingqing/p/18189358

相关文章

  • Windows 平台上有许多第三方文本编辑器,代码编辑器,它们提供了比系统自带记事本更丰富的
    Windows平台上有许多第三方文本编辑器,代码编辑器,它们提供了比系统自带记事本更丰富的功能和更友好的用户界面。以下是一些常见的第三方记事本软件文本编辑器,代码编辑器:Notepad++:Notepad++是一款免费开源的文本编辑器,支持多种编程语言的语法高亮显示和语法折叠,还具有查找......
  • 【M5Stack物联网开发】第一章 物联网
    第一章物联网介绍不知道对于下面这段描述,你是否熟悉: 小明是一名对科技充满热情的年轻人,每天的生活都离不开智能设备的协助。清晨,智能手环轻轻震动将他唤醒,这款手环不仅能追踪他的睡眠质量,还能根据他的生活习惯自动调整闹钟时间。小明从床上起来后,便对着智能音箱询问今天的天......
  • 第四章activity
    第四章activity1.生命周期方法onResume获取焦点onPause失去焦点packagecom.example.lifestyle;importandroidx.appcompat.app.AppCompatActivity;importandroid.os.Bundle;importandroid.util.Log;publicclassMainActivityextendsAppCompatActivity{@......
  • 第四章:Total Store Order and the x86 Memory Model
    chapter4:TSO于X86内存模型1、为什么需要TSO/x86处理器内核长期以来使用writebuffer来保存已提交的store指令,直到内存系统可以处理这些store请求。当store指令提交时,store请求进入writebuffer,而当需要写入的缓存行在内存系统中可以保证缓存一致性时,store请求就退出writebuffer......
  • ShellExperienceHost.exe 是 Windows 10 操作系统中的一个系统进程,它负责管理和运行一
    ShellExperienceHost.exe是Windows10操作系统中的一个系统进程,它负责管理和运行一些用户界面相关的功能和效果。具体来说,ShellExperienceHost主要有以下作用:启动菜单和任务栏:ShellExperienceHost负责启动、管理和渲染开始菜单、任务栏以及相关的用户界面元素。窗......
  • InfluxDB时序数据库图形用户界面可视化工具(influxdb-gui)
    说明之前开发了一款TDengine的GUI程序,出于兴趣,简单搞个InfluxDB的复制版,类似Navicat,目前基础操作功能已满足,后续看情况,可以继续扩展功能。介绍InfluxDB-GUI是一款功能全面、操作简便的influxdb时序数据库图形界面工具,V1.0.0目前支持influxdb版本列表如下:influxdb1.8.10版本......
  • 《无垠的太空(8).提亚玛特之怒》第四章:特蕾莎
    第四章:特蕾莎特蕾莎·杜阿尔特是高级领事杜阿尔特的独生女,从蹒跚学步起就住在拉科尼亚的帝国大厦,如今她快14岁了,伊利奇上校担任她的教师。近来,父亲要她一起参加帝国事务的报告会议,并在会后和他探讨。父亲把她当帝国的接班人培养,以便他出意外后由她接替高级领事的位置。 完整发......
  • 【13137】第四章 领导与战略计划
    目录1.单选题2.多选题3.名词解释题4.简答题5.论述题1.单选题......
  • 第四章 探究 FBV 视图
    第四章探究FBV视图​ 视图是Django的MTV的架构模式的V部分,主要负责处理用户请求和生成相应的响应内容,然后在页面或其他类型文档中显示。使用视图函数处理HTTP的请求,即在视图函数中定义函数,这种方法称为FBV。4.1设置响应方式​ 网站的运行原理是遵从HTTP协议,......
  • 第四章 总体设计
    第四章总体设计怎样实现目标系统【考核内容】总体设计的概念、设计步骤;模块化的概念、作用,模块化程度与软件开发工作量的关系;Miller法则,模块独立性的重要性,模块耦合及其分类,模块内聚及其分类,模块设计的几条启发式规则及与之相关的概念(深度、宽度、扇出、扇入、作用域);结构图的......