Skip to content

遊戲交互

以下展示幾個遊戲中常用的互動方式,完整的設備互動相關 API,可以查看API-設備

觸摸事件

遊戲中最常見的互動方式是點擊,拖曳,按住等等,這些互動都和觸控相關。小遊戲 API 提供了最基礎的觸控事件監聽介面:

如果要實現更其他觸摸相關的效果,需要自行實現,下文顯示實現點擊和滑動的範例程式碼:

js
const touchHandler = {
  startX: 0, // Record the starting X coordinate
  startY: 0, // Record the starting X coordinate
  startTime: 0, // Record the start time
  isMoving: false, // Track if the touch is moving
  longPressTimeout: null, // Timer for press and hold
  thresholdDistance: 10, // Threshold distance for movement
  thresholdTime: 300, // Threshold time for tap (milliseconds)
  longPressTime: 500, // Threshold time for press and hold (milliseconds)
  longPressTriggered: false, // Flag to indicate if press and hold was triggered
  onTouchStart: function(event) {
    this.startX = event.touches[0].clientX;
    this.startY = event.touches[0].clientY;
    this.startTime = Date.now(); // Record the start time
    this.isMoving = false; // Reset moving state

    // Set press and hold timer
    this.longPressTimeout = setTimeout(() => {
      this.handleLongPress(event);
    }, this.longPressTime);
  },
  onTouchMove: function(event) {
    this.isMoving = true;
  },
  onTouchEnd: function(event) {
    clearTimeout(this.longPressTimeout);

    const endX = event.changedTouches[0].clientX;
    const endY = event.changedTouches[0].clientY;
    const endTime = Date.now();
    const moveX = endX - this.startX;
    const moveY = endY - this.startY;
    const moveDistance = Math.sqrt(moveX * moveX + moveY * moveY);
    const timeDiff = endTime - this.startTime;

    if (
      timeDiff < this.thresholdTime &&
      moveDistance < this.thresholdDistance
    ) {
      // Handle tap event
      this.handleClick(event);
    } else if (
      this.isMoving &&
      !this.longPressTriggered &&
      moveDistance > this.thresholdDistance
    ) {
      // Handle swipe event
      this.handleSwipe(this.startX, this.startY, endX, endY);
    }

    this.isMoving = false;
    this.longPressTriggered = false;
  },
  onTouchCancel: function(event) {
    clearTimeout(this.longPressTimeout);
    this.isMoving = false;
    this.longPressTriggered = false;
  },
  handleClick: function(event) {
    console.log("Tap", event);
    // Handle tap event here
  },
  handleLongPress: function(event) {
    console.log("Press and hold", event);
    this.longPressTriggered = true;
    // Handle press and hold event here
  },
  handleSwipe: function(startX, startY, endX, endY) {
    const deltaX = endX - startX;
    const deltaY = endY - startY;

    if (Math.abs(deltaX) > Math.abs(deltaY)) {
      // Horizontal swipe
      if (deltaX > 0) {
        console.log("Swipe right");
        // Handle swipe right event here
      } else  {
        console.log("Swipe left");
        // Handle swipe left event here
      }
    } else  {
      // Vertical swipe
      if (deltaY > 0) {
        console.log("Swipe down");
        // Handle swipe down event here
      } else  {
        console.log("Swipe up");
        // Handle swipe up event here
      }
    }
  }
};

wx.onTouchStart(touchHandler.onTouchStart.bind(touchHandler));
wx.onTouchMove(touchHandler.onTouchMove.bind(touchHandler));
wx.onTouchEnd(touchHandler.onTouchEnd.bind(touchHandler));
wx.onTouchCancel(touchHandler.onTouchCancel.bind(touchHandler));

文字輸入

遊戲中有時會用到輸入文字的場景,例如登入帳號,聊天等場景。小遊戲 API 提供了以下介面用於拉起和監聽虛擬鍵盤。

示例代碼:

js
wx.onKeyboardConfirm(result => {
  console.warn("User input:", result.value);
...

wx.onTouchStart(result => {
  wx.showKeyboard({
    defaultValue: "",
    maxLength: 100,
    multiple: false,
    confirmHold: false,
    confirmType: "done",
    success: res => {
      console.warn("Keyboard shown successfully", res);
    },
    fail: err,
      console.warn("Failed to show keyboard", err);
    }
  });
});

設備感測器

在行動裝置上,有時候可以透過監聽裝置的感應器變化來做一些很特別的玩法:

  • wx.startDeviceMotionListening可監聽設備朝向,可用於實現全景地圖等功能。
  • wx.startAccelerometer可以監聽加速計的變化,通常用於測量施加在設備上的加速度,可以用於實現重力感應等功能。
  • wx.startGyroscope可以監聽陀螺儀的變化,通常用來偵測設備的旋轉速率,單位為弧度/秒,可以用來實現視角的控制等功能。
  • wx.startCompass可監聽設備朝向(平面),可用於實現指南針等功能。

示例代碼:

js
const deviceMotionData = { alpha: 0, beta: 0, gamma: 0 };
const accelerometerData = { x: 0, y: 0, z: 0 };
const gyroscopeData = { x: 0, y: 0, z: 0 };
const compassData = { direction: 0, accuracy: 0 };

// Start device motion listening
wx.startDeviceMotionListening({
  success: () => {
    wx.onDeviceMotionChange(res => {
      deviceMotionData = res;
    });
  },
  fail: err => {
    console.error("Failed to start device motion listening:", err);
  }
});

// Start accelerometer
wx.startAccelerometer
  success: () => {
    wx.onAccelerometerChange(res => {
      accelerometerData = res;
    });
  },
  fail: err => {
    console.error("Failed to start accelerometer:", err);
  }
});

// Start gyroscope
wx.startGyroscope
  success: () => {
    wx.onGyroscopeChange(res => {
      gyroscopeData = res;
    });
  },
  fail: err => {
    console.error("Failed to start gyroscope:", err);
  }
});

// Start compass
wx.startCompass
  success: () => {
    wx.onCompassChange(res => {
      compassData = res;
    });
  },
  fail: err => {
    console.error("Failed to start compass:", err);
  }
});