You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

基于数量或难度选择批量生成Canvas游戏障碍物数组

Canvas躲避游戏:自动生成对应难度的障碍物数组

1. 定义难度配置映射

先把不同难度对应的障碍物数量(以及可选的速度、尺寸参数)统一配置,方便后续维护:

// 难度配置:包含数量、速度范围、尺寸范围
const DIFFICULTY_SETTINGS = {
  easy: {
    count: 6,
    minSpeed: 2,
    maxSpeed: 3,
    minWidth: 30,
    maxWidth: 40
  },
  medium: {
    count: 12,
    minSpeed: 3,
    maxSpeed: 4,
    minWidth: 30,
    maxWidth: 45
  },
  hard: {
    count: 24,
    minSpeed: 4,
    maxSpeed: 6,
    minWidth: 35,
    maxWidth: 50
  }
};

2. 编写障碍物生成函数

这个函数支持两种调用方式:传入难度字符串(如'hard'),或传入自定义配置对象,自动生成对应数量的障碍物数组:

function generateObstacles(difficultyOrConfig) {
  // 确定最终使用的配置
  let config;
  if (typeof difficultyOrConfig === 'string') {
    // 传入难度字符串,匹配预设配置,默认用简单难度
    config = DIFFICULTY_SETTINGS[difficultyOrConfig] || DIFFICULTY_SETTINGS.easy;
  } else if (typeof difficultyOrConfig === 'object' && difficultyOrConfig.count) {
    // 传入自定义配置,合并默认值
    config = { ...DIFFICULTY_SETTINGS.easy, ...difficultyOrConfig };
  } else {
    // 默认使用简单难度
    config = DIFFICULTY_SETTINGS.easy;
  }

  const obstacles = [];
  const { width: canvasWidth, height: canvasHeight } = canvas; // 假设canvas是全局元素

  for (let i = 0; i < config.count; i++) {
    obstacles.push({
      // 初始位置:右侧画布外,按数量分散避免扎堆
      x: canvasWidth + Math.random() * 300 + (i * (canvasWidth / config.count)),
      // y轴随机,避开画布底部(假设障碍物高度50)
      y: Math.random() * (canvasHeight - 50),
      // 随机尺寸
      width: config.minWidth + Math.random() * (config.maxWidth - config.minWidth),
      height: 50,
      // 随机速度
      speed: config.minSpeed + Math.random() * (config.maxSpeed - config.minSpeed)
    });
  }

  return obstacles;
}

3. 调用示例

根据需求生成对应障碍物数组,替换原来的手动添加逻辑:

// 生成困难难度障碍物(24个)
let obstacles = generateObstacles('hard');

// 或者生成自定义数量的障碍物
obstacles = generateObstacles({ count: 10, minSpeed: 2.5, maxSpeed: 4 });

// 切换难度时直接重新生成即可
function switchDifficulty(newDifficulty) {
  obstacles = generateObstacles(newDifficulty);
  // 可选:重置得分、最高分(如果需要)
  score = 0;
}

4. 原有绘制逻辑适配

原来的循环绘制代码可以直接复用,遍历生成好的数组即可:

function updateAndDrawObstacles() {
  const { width: canvasWidth, height: canvasHeight } = canvas;
  obstacles.forEach(obstacle => {
    // 绘制障碍物
    ctx.fillStyle = '#ff4444';
    ctx.fillRect(obstacle.x, obstacle.y, obstacle.width, obstacle.height);

    // 更新位置(向左移动)
    obstacle.x -= obstacle.speed;

    // 障碍物移出左侧画布时重置位置,同时增加得分
    if (obstacle.x + obstacle.width < 0) {
      obstacle.x = canvasWidth + Math.random() * 200;
      obstacle.y = Math.random() * (canvasHeight - 50);
      score++;
      // 更新最高分逻辑
      if (score > highScore) {
        highScore = score;
        localStorage.setItem('dodgeGameHighScore', highScore); // 持久化存储最高分
      }
    }
  });
}

内容的提问来源于stack exchange,提问作者Chobbit

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.03 18:52:34