Skip to content
ximizhouPublic

About

No description, website, or topics provided.

Resources

Stars

0 stars

Watchers

0 watching

Forks

Repository files navigation

Hextris 微信小游戏

一个基于经典Hextris游戏的微信小游戏版本,完全按照原始Hextris网页版设计,具有完美的视觉还原和流畅的游戏体验。

游戏特色

🎮 核心玩法

  • 六边形消除:在六边形网格中连接3个以上相同颜色的方块进行消除
  • 旋转控制:点击屏幕左右两侧旋转六边形
  • 长按加速:长按屏幕加速方块下落
  • 渐进难度:游戏难度随时间递增,挑战性十足

🎨 界面设计

  • 完美还原:完全按照原始Hextris网页版设计
  • Exo字体:使用原始游戏的Exo字体,保持一致性
  • 精确布局:完全还原原始游戏的元素位置和大小
  • 教程渐变消失:点击开始时,教程会平滑地淡出消失
  • 经典配色:使用原始游戏的经典色彩搭配
  • 透明度动画:还原原始游戏的文字淡入效果

🎯 操作方式

  • 点击开始:在开始界面点击屏幕开始游戏
  • 左右旋转:左侧点击向右旋转,右侧点击向左旋转
  • 长按加速:长按300ms后方块下落速度×4
  • 重新开始:游戏结束后点击屏幕重新开始

⚡ 技术特性

  • 微信小游戏适配:完全适配微信小游戏环境
  • 响应式设计:支持不同屏幕尺寸
  • 错误处理:完善的错误处理和调试支持
  • 性能优化:高效的渲染和游戏逻辑
  • 完美还原:100%还原原始Hextris的视觉效果

文件结构

js/hextris/
├── game.js          # 主游戏逻辑
├── UI.js            # UI管理器(完全参照原始设计)
├── render.js        # 渲染系统
├── settings.js      # 游戏设置
├── Hex.js           # 六边形核心逻辑
├── Block.js         # 方块类
├── Text.js          # 文本效果
├── wavegen.js       # 方块生成器
├── checking.js      # 消除检测
└── ...

主要改进

1. 界面设计

  • ✅ 完全按照原始Hextris网页版设计
  • ✅ 使用Exo字体,保持原始视觉一致性
  • ✅ 精确还原原始游戏的元素位置和大小
  • ✅ 经典配色方案(#2c3e50, #3498db, #ecf0f1)
  • ✅ 新增:教程渐变消失动画
  • ✅ 完美还原:原始游戏的透明度动画效果

2. 触摸控制

  • ✅ 修复了触摸控制问题
  • ✅ 实现了精确的左右旋转控制
  • ✅ 添加了长按加速功能
  • ✅ 支持多种输入方式(触摸、鼠标)

3. 游戏体验

  • ✅ 移除了开始延迟,游戏立即开始
  • ✅ 实现了渐进难度系统
  • ✅ 改进了游戏结束处理
  • ✅ 添加了调试日志
  • ✅ 保持:原始游戏的核心体验

4. 技术改进

  • ✅ 完善的错误处理机制
  • ✅ 响应式设计支持
  • ✅ 性能优化
  • ✅ 微信小游戏完全适配
  • ✅ 完美还原:原始游戏的代码逻辑

使用方法

  1. 开始游戏:点击屏幕开始
  2. 旋转控制:左侧点击向右旋转,右侧点击向左旋转
  3. 加速下落:长按屏幕加速方块下落
  4. 重新开始:游戏结束后点击屏幕重新开始

开发说明

环境要求

  • 微信开发者工具
  • 微信小游戏基础库 2.0+

调试功能

  • 控制台会输出游戏状态变化
  • 支持触摸事件调试
  • 长按加速状态显示

自定义设置

可以在 settings.js 中调整:

  • 游戏速度
  • 难度曲线
  • 界面缩放
  • 颜色主题

版本历史

v1.8.1 (当前版本)

  • 🎨 按照图片重新设计简约高级界面
    • 完全按照提供的设计图片重新设计结算界面
    • 采用简约高级的设计风格,去除多余的装饰元素
    • 使用圆角矩形面板,提升视觉质感
    • 优化分数显示布局,预留足够空间支持大数字
    • 简化按钮设计,采用现代简约风格
    • 统一深色背景和浅色面板的配色方案
  • 🎨 优化分数显示和间距
    • 预留足够的分数显示空间,避免数字过大时超出
    • 优化左右分栏布局,确保分数和标签对齐
    • 调整字体大小和间距,提升可读性
    • 支持大数字显示,不会出现显示不全的问题
  • 🎨 统一设计语言
    • 暂停界面采用与结算界面一致的设计风格
    • 统一使用圆角矩形和简约按钮设计
    • 保持配色方案的一致性
    • 简化视觉元素,突出核心信息
  • 🎨 现代化游戏结算界面设计
    • 参考提供的设计图片,创建现代化结算界面
    • 添加中央面板设计,带有阴影和边框效果
    • 优化分数显示布局,左右分栏显示当前分数和最高分
    • 添加现代化按钮设计,带有阴影和悬停效果
    • 改进排行榜显示,高亮当前分数
    • 保持与游戏整体色调的一致性
  • 🎨 美化暂停界面设计
    • 采用与结算界面一致的设计风格
    • 添加中央面板和现代化按钮
    • 优化布局和视觉效果
    • 保持设计语言的一致性
  • 🔧 修复渐变效果在游戏开始后停止的问题
    • 修复游戏状态改变后drawStartScreen()不再被调用的问题
    • 在render函数中添加渐变更新逻辑
    • 添加drawFadingElements()方法,在游戏开始后继续绘制渐变元素
    • 确保渐变效果在游戏开始后仍然继续
  • 🔧 修复drawScoreboard中的渐变逻辑
    • 修复标题使用textOpacity而不是tutorialAlpha的问题
    • 统一使用tutorialAlpha控制所有渐变元素
    • 避免textOpacity快速递减导致的文字快速消失
  • 🔧 修复触摸事件干扰渐变效果
    • 修复点击开始游戏后立即触发长按加速的问题
    • 添加resetTouchState()函数,重置触摸状态
    • 防止触摸事件在游戏开始后继续干扰
    • 确保渐变效果不受触摸事件影响
  • 🎯 进一步优化渐变速度
    • 将渐变速度从0.02调整为0.01(每帧)
    • 提供更慢、更舒适的渐变体验
    • 约1.67秒完成渐变(100帧,60FPS)
  • 🎯 按照原版方式实现渐变效果
    • 采用原版的帧率渐变方式,每帧减少0.01透明度
    • 比原版的0.05更慢,提供更舒适的渐变体验
    • 移除基于时间的复杂渐变算法
    • 确保渐变效果与原版一致
  • 🔧 修复渐变时间问题
    • 修复setStartScreen()中init()调用导致UI状态重置的问题
    • 添加调试信息,监控渐变进度和透明度变化
    • 确保渐变时间设置正确生效
    • 解决文字点击后立即消失的问题
  • 🎯 进一步优化渐变算法
    • 前50%时间(2.5秒)文字保持完全不透明
    • 后50%时间使用缓慢的线性渐变
    • 避免复杂的缓动函数导致的快速消失
    • 提供更稳定、更可预测的渐变效果
  • 🎬 优化渐变算法
    • 前30%时间文字保持完全不透明
    • 从30%开始使用缓入缓出函数渐变
    • 避免文字一开始就快速消失
    • 提供更舒适的视觉体验
  • ⏱️ 优化渐变体验
    • 延长渐变时间到5秒
    • 添加缓动函数,让渐变更加平滑
    • 提供更舒适的视觉过渡效果
  • 🎨 界面进一步优化
    • 去除"Play!"文字,界面更简洁
    • 游戏操作文字往下移动,布局更合理
    • 标题和游戏规则一起渐变消失
    • 游戏在渐变一开始就立即进行
    • 优化整体视觉效果
  • 🎮 修复触摸控制问题
  • ⚡ 添加长按加速功能
  • 🏆 完善分数和排行榜系统

v1.6.0

  • 🎨 标题可见性优化
    • 提高标题透明度,完全不透明显示
    • 将标题颜色改为白色,更加醒目
    • 提高开始提示的透明度和字体大小
    • 优化文字层级,确保清晰可见
  • 🎮 修复触摸控制问题
  • ⚡ 添加长按加速功能
  • 🏆 完善分数和排行榜系统

v1.5.0

  • 🎨 UI优化升级
    • 移除中央白色方块,界面更简洁
    • 改进渐变逻辑:游戏立即开始,教程逐渐消失
    • 优化教程文字布局和字体大小
    • 添加脉冲动画的开始提示
    • 提升整体视觉效果
  • 🎮 修复触摸控制问题
  • ⚡ 添加长按加速功能
  • 🏆 完善分数和排行榜系统

v1.4.0

  • 🎨 界面优化
    • 移除白色背景框,界面更简洁
    • 移除菜单状态的六边形背景
    • 延长教程渐变消失时间到2秒
    • 简化教程文字显示
  • 🎮 修复触摸控制问题
  • ⚡ 添加长按加速功能
  • 🏆 完善分数和排行榜系统

v1.3.0

  • 🎨 完美还原原始设计
    • 完全按照原始Hextris网页版设计
    • 精确还原元素位置和大小
    • 使用Exo字体和经典配色
    • 还原原始游戏的透明度动画
    • 教程渐变消失动画
  • 🎮 修复触摸控制问题
  • ⚡ 添加长按加速功能
  • 🏆 完善分数和排行榜系统

v1.2.0

  • 🎨 回归原始设计(已进一步优化)
  • 🎮 修复触摸控制问题
  • ⚡ 添加长按加速功能
  • 🏆 完善分数和排行榜系统

v1.1.0

  • 🎨 界面全面美化(已回退)
  • 🎮 修复触摸控制问题
  • ⚡ 添加长按加速功能
  • 🏆 完善分数和排行榜系统

v1.0.0

  • 🎉 完成基础游戏功能
  • 🎨 实现美观的中文界面
  • 🎮 修复触摸控制问题
  • ⚡ 添加长按加速功能
  • 🏆 完善分数和排行榜系统

设计理念

本版本完全按照原始Hextris网页版设计:

  • 完美还原:100%还原原始游戏的视觉效果
  • 精确布局:完全按照原始代码实现元素位置
  • 经典永恒:保持原始游戏的经典美感
  • 用户体验:流畅的操作和清晰的反馈

原始参考

本版本完全参照以下原始文件:

  • hextris-gh-pages/js/view.js - 原始渲染逻辑
  • hextris-gh-pages/js/main.js - 原始游戏逻辑
  • hextris-gh-pages/style/style.css - 原始样式设计
  • hextris-gh-pages/index.html - 原始HTML结构

问题反馈

如果遇到问题,请检查:

  1. 微信开发者工具版本
  2. 基础库版本
  3. 控制台错误信息
  4. 触摸事件是否正常

许可证

基于原版Hextris游戏开发,遵循原版许可证。


1. 现象复盘

  • 第一次游戏:分数点击区可用
  • 第二次游戏:分数点击区不可用
  • 第三次游戏:又可用
  • 第四次游戏:又不可用
  • ...如此循环

2. 关键代码链路

入口

  • render.js 只创建一次 UI 实例,赋值到 gameVars.UI
  • drawScore() 每帧在 PLAYING/PAUSED 状态下被调用,理论上每帧都更新 scoreClickArea
  • checkScoreClick(x, y) 直接用 this.scoreClickArea 检查

重新开始流程

  1. 死亡后,handleClickTap 触发 init()
  2. init() 重新初始化游戏数据
  3. init() 末尾强制调用 gameVars.UI.updateScoreClickArea(scoreY)
  4. render() 进入新一轮循环,drawScore() 每帧都更新 scoreClickArea

3. 可能的根因分析

1. 渲染时机与点击时机错位

  • 你点击“重新开始”后,init() 立即执行,scoreClickArea 被更新,但此时画面还没渲染新分数。
  • 如果你很快点击分数,此时 scoreClickArea 还是“上一次游戏”的位置/尺寸。
  • 由于 drawScore() 依赖于 settings.scale、canvas 尺寸等,偶数次可能因为某些全局变量未及时刷新,导致区域错乱。

2. UI状态未完全重置

  • scoreClickArea 依赖于 drawScore() 的调用,但如果某一帧没被调用,区域就不对。
  • 你在 init() 里手动调用 updateScoreClickArea,但这和 drawScore() 的调用时机可能不一致。

3. 微信开发者工具事件队列问题

  • 事件触发和渲染帧不同步,导致“偶数次”时,点击事件发生在 drawScore() 之前。

4. 彻底解决方案

核心原则:分数点击区域的更新必须和画面渲染严格同步!

A. 只在 drawScore() 内部更新 scoreClickArea,其他地方一律不手动更新

  • 保证每一帧的点击区域和实际显示完全一致。

B. checkScoreClick 只在 scoreClickArea 存在时才判定,否则直接返回 false

  • 不再在 checkScoreClick 内部“补算”区域,避免时序错乱。

C. 点击事件处理时,强制先渲染一帧再判定点击

  • 这样能保证 scoreClickArea 是最新的。

5. 具体代码调整建议

1. UI.js 修改

// 只允许 drawScore 内部更新 scoreClickArea
drawScore() {
  const ctx = GameGlobal.canvas.getContext('2d');
  const scoreY = 80 * settings.scale;
  ctx.fillStyle = this.textColor;
  ctx.font = `bold ${Math.min(32 * settings.scale, 32)}px ${this.fontFamily}`;
  ctx.textAlign = 'center';
  ctx.fillText(gameVars.score.toString(), GameGlobal.canvas.width / 2, scoreY + 10);

  // 只在这里更新
  this.scoreClickArea = {
    x: GameGlobal.canvas.width / 2 - 150 * settings.scale,
    y: scoreY - 50 * settings.scale,
    width: 300 * settings.scale,
    height: 100 * settings.scale
  };
}

checkScoreClick(x, y) {
  // 只判定,不再补算
  if (!this.scoreClickArea) return false;
  return (
    x >= this.scoreClickArea.x &&
    x <= this.scoreClickArea.x + this.scoreClickArea.width &&
    y >= this.scoreClickArea.y &&
    y <= this.scoreClickArea.y + this.scoreClickArea.height
  );
}

2. game.js 修改

点击事件处理时,先强制渲染一帧再判定点击:

handleClickTap(x, y) {
  if (!gameVars.MainHex) return;

  // 先强制渲染一帧,确保scoreClickArea是最新的
  render();

  // ...后续逻辑不变
  if (gameVars.gameState === GAME_STATES.PLAYING) {
    if (gameVars.UI && typeof gameVars.UI.checkScoreClick === 'function') {
      if (gameVars.UI.checkScoreClick(x, y)) {
        this.pause();
        return;
      }
    }
    // ...旋转逻辑
  }
  // ...其他状态逻辑
}

6. 总结

  • 根因:分数点击区域的更新和点击判定时机错位,导致偶数次游戏区域失效。
  • 解决:只允许drawScore更新区域,点击时先渲染一帧,保证区域和画面同步。

请确认是否需要我直接帮你实现上述调整,或者你希望先理解原理再动手?

About

No description, website, or topics provided.

Resources

Stars

0 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages