Phaser 3中创建动态纹理TileSprite实现老虎机卷轴结果展示
在Phaser 3中动态生成老虎机结果纹理('results')
由于无法加载包含全部图标的大TileSprite,可以通过动态生成纹理的方式,根据赔付引擎的输出结果,将指定图标拼接成每个卷轴专属的结果纹理,替换原有的'symbols'纹理。以下是两种可行的实现方案:
方案一:使用RenderTexture(Phaser原生推荐方式)
RenderTexture是Phaser专门用来动态绘制纹理的工具,适合直接在游戏内部生成需要的纹理。
步骤说明
- 提前加载单个图标资源:不要把所有图标拼成大图集,而是单独加载每个老虎机图标(比如'7'、'bar'、'cherry'等),确保可以按需调用。
- 编写纹理生成函数:根据赔付结果,将对应图标纵向绘制到RenderTexture中,生成每个卷轴专属的结果纹理。
- 在spin_end中替换纹理:调用生成函数,把TileSprite的纹理切换为动态生成的结果纹理。
代码示例
纹理生成函数
function createReelResultTexture(reelId, results) { // 替换成你实际的图标尺寸(宽x高) const iconWidth = 100; const iconHeight = 150; // 结果纹理尺寸:宽度和图标一致,高度为图标高度×显示的图标数量(通常是3个) const textureWidth = iconWidth; const textureHeight = iconHeight * results.length; // 创建RenderTexture,每个卷轴用唯一key避免冲突 const resultTexture = self.make.renderTexture({ width: textureWidth, height: textureHeight, key: `results_${reelId}` }); // 纵向绘制每个结果图标 results.forEach((symbolKey, index) => { // 从缓存中取出图标,绘制到对应位置 resultTexture.draw(symbolKey, 0, index * iconHeight); }); return `results_${reelId}`; }
修改后的spin_end函数
function spin_end(obj){ // 从赔付引擎获取当前卷轴的结果数组(比如['7', 'bar', 'cherry']) const reelResult = reelResults[obj.id]; // 生成当前卷轴的结果纹理 const resultTextureKey = createReelResultTexture(obj.id, reelResult); // 定位到停止起始位置 obj.y = get_stop('start', obj.id); // 切换为动态生成的结果纹理 obj.setTexture(resultTextureKey); self.tweens.add({ targets: obj, y: get_stop('end', obj.id), duration: 800, ease: 'Back.easeOut', onComplete(){ if(obj.id === 4){ calculate(); is_spinning = false; // 可选:销毁不再需要的纹理,节省内存 self.textures.destroy(`results_${obj.id}`); } } }); setTimeout(()=>{ play_sound('Slot Machine Stop '+Number(obj.id+1), self); }, 400); }
方案二:使用Canvas手动生成纹理
如果需要更底层的绘制控制,可以用原生Canvas生成纹理,再导入到Phaser中。
代码示例
Canvas纹理生成函数
function createReelResultTextureFromCanvas(reelId, results) { const iconWidth = 100; const iconHeight = 150; const textureWidth = iconWidth; const textureHeight = iconHeight * results.length; const canvas = document.createElement('canvas'); canvas.width = textureWidth; canvas.height = textureHeight; const ctx = canvas.getContext('2d'); // 逐个绘制结果图标 results.forEach((symbolKey, index) => { // 获取Phaser中图标纹理的原生Image对象 const symbolImage = self.textures.get(symbolKey).getSourceImage(); ctx.drawImage(symbolImage, 0, index * iconHeight, iconWidth, iconHeight); }); // 将Canvas添加为Phaser纹理 self.textures.addCanvas(`results_${reelId}`, canvas); return `results_${reelId}`; }
使用方式
直接在spin_end函数中替换createReelResultTexture为createReelResultTextureFromCanvas即可,其他逻辑和方案一一致。
关键注意事项
- 图标资源预加载:确保所有单个图标在游戏preload阶段加载完成,比如
this.load.image('7', 'assets/symbols/7.png')。 - 纹理唯一性:每个卷轴生成独立的纹理(用
results_${reelId}作为key),避免多个卷轴共用纹理导致显示混乱。 - 内存优化:在动画完成后,销毁不再需要的结果纹理,防止内存占用过高。
- 尺寸匹配:生成的结果纹理宽度必须和原TileSprite宽度一致,高度为图标高度×显示行数,确保滚动位置对齐正确。
内容的提问来源于stack exchange,提问作者Diego
相关产品推荐
相关产品推荐

