当前位置: 首页 > news >正文

从零开始用AI开发游戏(二)代码实现

在这里插入图片描述
以下是基于递归分割算法的迷宫生成与玩家移动控制的完整实现代码,包含详细注释:

// 迷宫生成器(递归分割算法实现)
class MazeGenerator {
  constructor(width, height) {
    this.width = width;
    this.height = height;
    this.grid = this.initGrid();
    this.recursiveDivision(0, 0, width, height);
  }

  // 初始化二维网格(全部设为墙)
  initGrid() {
    const grid = [];
    for (let y = 0; y < this.height; y++) {
      grid[y] = [];
      for (let x = 0; x < this.width; x++) {
        grid[y][x] = 1; // 1表示墙,0表示路
      }
    }
    return grid;
  }

  // 递归分割核心算法
  recursiveDivision(x, y, width, height) {
    // 终止条件:区域小于阈值
    if (width < 3 || height < 3) return;

    // 随机选择横向/纵向分割
    const isHorizontal = Math.random() > 0.5;
    
    // 分割线坐标(确保在范围内)
    const wx = x + (isHorizontal ? 0 : Math.floor(Math.random() * (width - 2)) + 1);
    const wy = y + (isHorizontal ? Math.floor(Math.random() * (height - 2)) + 1 : 0);
    
    // 开口位置(随机留通路)
    const px = wx + (isHorizontal ? Math.floor(Math.random() * width) : 0);
    const py = wy + (isHorizontal ? 0 : Math.floor(Math.random() * height));

    // 绘制分割墙
    const dx = isHorizontal ? 1 : 0;
    const dy = isHorizontal ? 0 : 1;
    for (let i = 0; i < (isHorizontal ? width : height); i++) {
      if (wx + dx*i !== px || wy + dy*i !== py) { // 跳过开口位置
        this.grid[wy + dy*i][wx + dx*i] = 1;
      }
    }

    // 递归处理子区域
    if (isHorizontal) {
      this.recursiveDivision(x, y, width, wy - y);
      this.recursiveDivision(x, wy + 1, width, y + height - wy - 1);
    } else {
      this.recursiveDivision(x, y, wx - x, height);
      this.recursiveDivision(wx + 1, y, x + width - wx - 1, height);
    }
  }
}

// 玩家控制器
class Player {
  constructor(maze) {
    this.maze = maze; // 迷宫二维数组引用
    this.x = 1;       // 初始位置(确保在路径上)
    this.y = 1;
  }

  // 计算下一个位置
  calculateNextPosition(direction) {
    switch(direction) {
      case 'up':    return { x: this.x, y: this.y - 1 };
      case 'down':  return { x: this.x, y: this.y + 1 };
      case 'left':  return { x: this.x - 1, y: this.y };
      case 'right': return { x: this.x + 1, y: this.y };
      default:      return { x: this.x, y: this.y };
    }
  }

  // 碰撞检测
  isCollidingWithWall(pos) {
    // 边界检查
    if (pos.x < 0 || pos.x >= this.maze[0].length || 
        pos.y < 0 || pos.y >= this.maze.length) {
      return true;
    }
    // 墙体检查(grid[y][x] === 1)
    return this.maze[pos.y][pos.x] === 1;
  }

  // 移动控制
  move(direction) {
    const nextPos = this.calculateNextPosition(direction);
    if (!this.isCollidingWithWall(nextPos)) {
      this.x = nextPos.x;
      this.y = nextPos.y;
      return true; // 移动成功
    }
    return false; // 碰撞发生
  }
}

/****************** 使用示例 ******************/
// 生成迷宫(建议奇数值)
const mazeGen = new MazeGenerator(21, 21);
const maze = mazeGen.grid;

// 创建玩家实例
const player = new Player(maze);

// 测试移动
player.move('right');  // 成功移动到(2,1)
player.move('down');   // 成功移动到(2,2)
player.move('left');   // 如果(1,2)是墙则失败

关键实现细节说明:

  1. 迷宫生成算法
  • 递归分割通过不断划分区域创建迷宫结构
  • 随机选择横向/纵向分割(50%概率)
  • 分割时总会留出一个随机开口保证路径连通
  • 建议使用奇数值尺寸(保证墙/路的交替模式)
  1. 玩家移动控制
  • 基于网格的离散移动(每次移动1格)
  • 四方向移动控制(WASD对应方向)
  • 双重碰撞检测(边界检查+墙体检查)
  • 返回移动结果用于游戏逻辑反馈
  1. 扩展建议
// 可添加的扩展功能示例:
// 1. 终点检测
class Game {
  constructor() {
    this.exit = { x: maze[0].length-2, y: maze.length-2 };
  }
  
  checkWin() {
    return player.x === this.exit.x && player.y === this.exit.y;
  }
}

// 2. 动态生成可视化
function drawMaze(ctx, maze, cellSize) {
  for (let y = 0; y < maze.length; y++) {
    for (let x = 0; x < maze[y].length; x++) {
      ctx.fillStyle = maze[y][x] === 1 ? '#333' : '#fff';
      ctx.fillRect(x * cellSize, y * cellSize, cellSize, cellSize);
    }
  }
}

实际开发时需要结合渲染模块(Canvas/WebGL)将网格数据可视化,并添加玩家视角的3D投影逻辑(如之前提供的伪3D示例)。建议先验证迷宫生成效果,再逐步添加游戏功能模块。

相关文章:

  • SolarWinds Web Help Desk漏洞曝光:攻击者可访问存储密码
  • 动态IP vs 静态IP:终极对比一览表
  • 使用LiteFlow实现阻塞审批工作流
  • 前端面试:React hooks 调用是可以写在 if 语句里面吗?
  • JavaScript性能优化实战指南
  • 软件工程概述、软件过程模型、逆向工程(高软45)
  • HTML5拼图游戏开发经验分享
  • Pycharm(五)序列的操作
  • 网络VLAN技术详解:原理、类型与实战配置
  • Elasticsearch Java High Level Client [7.17] 使用
  • K8S学习之基础二十八:k8s中的configMap
  • Interview preparation.md
  • RabbitMQ从入门到实战-知识详情总结
  • 2024下半年真题 系统架构设计师 论文写作 答案解析
  • 基于全局分析SpringCloud各个组件所解决的问题?
  • 框架源码私享笔记(02)Mybatis核心框架原理 | 一条SQL透析核心组件功能特性
  • 证券交易系统的流程
  • T2.小牛架炮 - 美团机试真题题解
  • qt c++线程中的同步和异步
  • Linux入门 全面整理终端 Bash、Vim 基础命令速记
  • 多少Moreless:向世界展示现代中式家具的生活美学
  • 一个留美学生的思想转向——裘毓麐的《游美闻见录》及其他
  • 国际金价下跌,中概股多数上涨,穆迪下调美国主权信用评级
  • 全国林业院校校长论坛举行,聚焦林业教育的创新与突破
  • 广西壮族自治区政府主席蓝天立任上被查
  • 消息人士称俄方反对美国代表参加俄乌直接会谈