【HTML5游戲開發教程】零基礎入門合成大西瓜游戲實戰 | JS物理引擎+Canvas動畫+完整源碼詳解

《從咖啡杯到財務自由:一個程序員的合成之旅——當代碼遇上物理引擎的匠心之作》

🌟 這是小游戲開發系列的第四篇送福利文章,感謝一路以來支持和關注這個項目的每一位朋友!

💡 文章力求嚴謹,但難免有疏漏之處,歡迎各位朋友指出,讓我們一起在交流中進步。

💌 如果您有任何想法、建議或疑問,都歡迎在評論區留言或通過私信與我交流。您的每一個反饋都是項目進步的動力!

這款游戲不僅融合了流行的合成玩法,更加入了大量程序員文化元素,讓我們在休閑娛樂的同時,感受到濃濃的技術氛圍。

合成大西瓜Pro版 - 純程序猿元素風
合成大西瓜Pro版

文章目錄

  • 《從咖啡杯到財務自由:一個程序員的合成之旅——當代碼遇上物理引擎的匠心之作》
    • 游戲介紹:從咖啡杯到財務自由
    • 演示視頻:
    • 部分截圖:
    • 技術棧:輕量而強大
    • 模塊詳解:游戲架構拆解
      • 1. 核心游戲模塊 (Game.js)
      • 2. 物品渲染模塊 (ItemRenderer.js)
      • 3. 音頻管理模塊 (AudioManager.js)
      • 4. IDE風格控制臺 (ConsoleManager.js)
      • 5. 彩蛋系統:游戲點睛之筆
      • 主要彩蛋類型:
    • 開發難點與解決方案
      • 1. 物理碰撞的穩定性
      • 2. 游戲性能優化
      • 項目代碼:
    • 寫在最后

游戲介紹:從咖啡杯到財務自由

“程序員版合成大西瓜"是一款基于物理引擎的休閑合成游戲,專為程序員群體量身定制。游戲的主要目標是通過合成相同物品,一步步從最基礎的程序員日常用品(咖啡杯)開始,最終合成象征成功的"財務自由”。

游戲流程十分直觀:

  1. 玩家點擊屏幕頂部,投放物品(初始為咖啡杯)
  2. 物品會根據物理規則自由下落并互相碰撞
  3. 當兩個相同物品碰撞并滿足特定條件時,會合成為更高級的物品
  4. 隨著得分增加,玩家的"程序員等級"會提升,解鎖更多游戲內容
  5. 當物品堆積過高達到警戒線時,游戲結束

我們設計了一條充滿程序員文化的合成路徑:

咖啡杯(?) → 鍵盤(??) → 筆記本(💻) → 顯示器(🖥?) → 主機(🖥?) → 服務器(🖧) → 財務自由(💰)

每一級合成都會帶來翻倍的分數回報:從咖啡杯的2分,到財務自由的128分。當玩家成功合成三個"財務自由"時,將觸發游戲通關彩蛋,獲得專屬的程序員成就證書!

演示視頻:

合成大西瓜Pro版-程序員風

部分截圖:

本游戲有非常非常多的彩蛋,每種彩蛋觸發時機不同,需要玩家自行探索~~~

首頁:
在這里插入圖片描述

財富自由彩蛋:
在這里插入圖片描述

終極彩蛋:

在這里插入圖片描述

技術棧:輕量而強大

為了確保游戲運行流暢且易于擴展,我們精心選擇了以下技術棧:

  • 前端基礎:HTML5、CSS3、JavaScript (ES6+)
  • 構建工具:Vite(提供極速的開發體驗)
  • 物理引擎:Matter.js(處理游戲物體的物理行為和碰撞)
  • 包管理:npm

值得一提的是,我們沒有使用任何重量級前端框架(如React、Vue),而是選擇了純原生JavaScript實現。這不僅減輕了項目體積,提升了加載速度,還降低了學習門檻,讓更多對游戲開發感興趣的朋友能夠輕松理解代碼結構。

模塊詳解:游戲架構拆解

1. 核心游戲模塊 (Game.js)

這是整個游戲的中樞神經系統,負責協調各個模塊的工作,管理游戲狀態和物理世界。

核心功能

  • 物理世界的創建與管理
  • 游戲主循環的實現
  • 物品合成邏輯的控制
  • 分數計算與等級提升
  • 游戲狀態(開始、暫停、結束)管理

引擎初始化代碼

constructor() {// Matter.js 模塊初始化this.engine = Matter.Engine.create({enableSleeping: true,constraintIterations: 3,positionIterations: 8,velocityIterations: 6,timing: {timeScale: 1.1,timestamp: 0}})// 創建運行器,固定幀率this.runner = Matter.Runner.create({isFixed: true,delta: 1000 / 60  // 固定60幀})// 設置渲染器this.render = Matter.Render.create({element: document.getElementById('app'),engine: this.engine,options: {width: GAME_CONFIG.width,height: GAME_CONFIG.height,wireframes: false,background: 'transparent',pixelRatio: window.devicePixelRatio || 1,fps: 60}})// 設置重力this.engine.gravity.y = PHYSICS_CONFIG.gravity
}

這段代碼展示了如何初始化物理引擎。我們精心調整了物理參數,以確保游戲體驗的流暢性。特別是positionIterationsvelocityIterations參數的提高,使物理模擬更加精確,減少了物體穿透的可能性。

開發難點
物品合成判定是最大的挑戰之一。為了實現自然流暢的合成體驗,我們采用了復合判定條件:結合物品間的距離、接觸時間以及相對速度三個關鍵因素。這種方法解決了合成觸發不穩定的問題,提升了游戲的可玩性。

// 碰撞檢測與合并邏輯
Matter.Events.on(this.engine, 'collisionStart', (event) => {if (this.isPaused || this.gameOver) returnevent.pairs.forEach((pair) => {const { bodyA, bodyB } = pair// 檢查兩個物體是否相同類型且不在活動合并列表中if (bodyA.itemType && bodyB.itemType && bodyA.itemType.name === bodyB.itemType.name) {const pairId = [bodyA.id, bodyB.id].sort().join('-')// 避免重復添加if (!activeMergingPairs.has(pairId) && !collisionPairs.has(pairId)) {// 記錄碰撞信息collisionPairs.set(pairId, {bodyA, bodyB,time: Date.now(),contactPoint: {x: (bodyA.position.x + bodyB.position.x) / 2,y: (bodyA.position.y + bodyB.position.y) / 2},initialVelocityA: { ...bodyA.velocity },initialVelocityB: { ...bodyB.velocity },contactFrames: 0})}}})
})

合并條件判定代碼:

// 合并條件判定
const distCondition = dist < GAME_CONFIG.mergeThreshold * 1.5 * totalRadius;
const timeCondition = now - time > GAME_CONFIG.mergeWindow * 0.7;
const velocityCondition = totalVelocity < 0.8 && contactFrames > 15;if (distCondition && (timeCondition || velocityCondition)) {this.handleMerge(bodyA, bodyB);collisionPairs.delete(pairId);activeMergingPairs.delete(pairId);
}

這是游戲核心機制的一部分,通過綜合考慮多種條件,使合成過程更加智能和自然。當兩個物體足夠接近且滿足時間或速度條件時,會觸發合并處理。

2. 物品渲染模塊 (ItemRenderer.js)

負責游戲中各種物品的視覺呈現,確保每個物品都有鮮明的辨識度和程序員文化氣息。

核心功能

  • 使用Canvas API繪制各類程序員物品
  • 實現物品合成的視覺特效
  • 處理不同大小物品的適配渲染

程序化繪制代碼示例

// 渲染咖啡杯
static renderCoffee(ctx, x, y, size) {const scale = size / 100;// 繪制杯子主體ctx.beginPath();ctx.fillStyle = '#75432A';ctx.moveTo(x - 30 * scale, y - 15 * scale);ctx.bezierCurveTo(x - 32 * scale, y + 25 * scale,x - 28 * scale, y + 35 * scale,x - 20 * scale, y + 35 * scale);ctx.lineTo(x + 20 * scale, y + 35 * scale);ctx.bezierCurveTo(x + 28 * scale, y + 35 * scale,x + 32 * scale, y + 25 * scale,x + 30 * scale, y - 15 * scale);ctx.closePath();ctx.fill();// 繪制咖啡液體ctx.beginPath();ctx.fillStyle = '#4A2C1A';ctx.ellipse(x, y - 15 * scale, 30 * scale, 10 * scale, 0, 0, Math.PI * 2);ctx.fill();// 繪制杯把ctx.beginPath();ctx.strokeStyle = '#75432A';ctx.lineWidth = 5 * scale;ctx.arc(x + 35 * scale, y + 10 * scale, 10 * scale, Math.PI * 1.2, Math.PI * 1.8);ctx.stroke();
}

這段代碼展示了如何使用Canvas API繪制咖啡杯物品。我們使用貝塞爾曲線和基本形狀組合創建了具有立體感的圖形,而不是使用圖片資源。

合并動畫效果代碼

static renderMergeAnimation(ctx, x, y, size, progress) {// 創建閃光效果const radius = size * (1 + progress * 0.5);const opacity = 1 - progress;// 繪制外部光環ctx.beginPath();ctx.arc(x, y, radius, 0, Math.PI * 2);ctx.fillStyle = `rgba(255, 255, 255, ${opacity * 0.7})`;ctx.fill();// 繪制內部光芒const gradient = ctx.createRadialGradient(x, y, 0, x, y, radius);gradient.addColorStop(0, `rgba(255, 215, 0, ${opacity})`);gradient.addColorStop(0.7, `rgba(255, 140, 0, ${opacity * 0.5})`);gradient.addColorStop(1, `rgba(255, 69, 0, 0)`);ctx.beginPath();ctx.arc(x, y, radius * 0.8, 0, Math.PI * 2);ctx.fillStyle = gradient;ctx.fill();// 添加粒子效果const particles = 8;for (let i = 0; i < particles; i++) {const angle = (i / particles) * Math.PI * 2;const dist = radius * 0.6 * progress;const px = x + Math.cos(angle) * dist;const py = y + Math.sin(angle) * dist;const particleSize = (1 - progress) * size * 0.2;ctx.beginPath();ctx.arc(px, py, particleSize, 0, Math.PI * 2);ctx.fillStyle = `rgba(255, 215, 0, ${opacity * 0.8})`;ctx.fill();}
}

這段代碼實現了物品合成時的視覺特效。通過創建光環、漸變和粒子效果,使合成過程更加生動直觀。效果隨progress參數(0到1)動態變化,形成平滑的動畫效果。

開發難點
我們選擇了程序化生成圖形,而非使用圖片資源。這種方式雖然增加了編碼復雜度,但顯著減少了資源加載時間,提升了游戲啟動速度,同時也為未來可能的物品自定義提供了基礎。

3. 音頻管理模塊 (AudioManager.js)

負責游戲中所有音效和背景音樂的控制,為游戲增添聽覺體驗。

核心功能

  • 音頻資源的預加載
  • 游戲事件觸發的音效播放
  • 背景音樂的循環播放與控制

音頻加載與錯誤處理代碼

export class AudioManager {constructor() {this.sounds = {};this.bgm = null;this.isMuted = false;this.loadFailed = false;}loadAudio() {try {// 加載背景音樂this.bgm = new Audio('/src/assets/audio/bgm.mp3');this.bgm.loop = true;this.bgm.volume = 0.5;// 預加載音效const soundFiles = {drop: '/src/assets/audio/drop.mp3',merge: '/src/assets/audio/merge.mp3',levelup: '/src/assets/audio/levelup.mp3'};// 使用Promise.all并行加載所有音效const loadPromises = Object.entries(soundFiles).map(([key, path]) => {return new Promise((resolve, reject) => {const audio = new Audio(path);audio.addEventListener('canplaythrough', () => {this.sounds[key] = audio;resolve();}, { once: true });// 添加錯誤處理audio.addEventListener('error', (e) => {console.warn(`音頻 ${key} 加載失敗:`, e);// 即使加載失敗也允許繼續this.loadFailed = true;resolve();}, { once: true });// 開始加載audio.load();});});// 等待所有音效加載完成return Promise.all(loadPromises).then(() => console.log('所有音頻加載完成')).catch(err => {console.error('音頻加載過程出錯:', err);this.loadFailed = true;});} catch (error) {console.error('音頻初始化失敗:', error);this.loadFailed = true;return Promise.resolve(); // 返回已解決的Promise以免中斷游戲}}// 播放音效的安全方法playSound(name) {if (this.isMuted || this.loadFailed) return;try {const sound = this.sounds[name];if (!sound) return;// 克隆節點以允許重疊播放const soundClone = sound.cloneNode();soundClone.volume = name === 'levelup' ? 0.8 : 0.6;// 播放后自動清理soundClone.addEventListener('ended', () => {soundClone.remove();}, { once: true });soundClone.play().catch(e => {console.warn(`播放音效 ${name} 失敗:`, e);});} catch (error) {console.warn('播放音效錯誤:', error);}}
}

這段代碼展示了如何實現健壯的音頻加載和播放系統。我們使用Promise并行加載所有音效,并添加了全面的錯誤處理機制,確保即使音頻加載失敗也不會影響游戲主體功能。

開發難點
瀏覽器音頻API的兼容性問題是一大挑戰。我們實現了完善的錯誤捕獲機制,確保即使音頻加載失敗,也不會影響游戲主體功能的運行。另一個挑戰是解決自動播放限制,我們通過用戶交互觸發首次播放來解決這個問題。

// 在main.js中處理自動播放限制
function startMusicOnInteraction() {if (!musicStarted) {try {game.audioManager.playBGM()musicStarted = true} catch (error) {console.warn('播放背景音樂失敗:', error)}// 移除所有事件監聽器document.removeEventListener('click', startMusicOnInteraction)document.removeEventListener('keydown', startMusicOnInteraction)document.removeEventListener('touchstart', startMusicOnInteraction)}
}// 添加用戶交互事件監聽器
document.addEventListener('click', startMusicOnInteraction)
document.addEventListener('keydown', startMusicOnInteraction)
document.addEventListener('touchstart', startMusicOnInteraction)

4. IDE風格控制臺 (ConsoleManager.js)

這是游戲中最具特色的元素之一,模擬IDE控制臺,實時顯示游戲事件和調試信息。

核心功能

  • 不同類型消息的格式化顯示
  • 控制臺滾動和歷史記錄管理
  • 程序員幽默元素的隨機插入

控制臺實現代碼

export class ConsoleManager {constructor() {this.consoleElement = document.querySelector('.console-output');this.messageHistory = [];this.maxMessages = 100;// 初始化控制臺this.clear();this.log('程序員合成大西瓜 v1.0.0 初始化中...', 'info');this.log('物理引擎加載完成', 'success');this.log('準備就緒,開始游戲吧!', 'success');}// 添加日志消息log(message, type = 'log') {// 創建新的日志元素const logElement = document.createElement('div');logElement.className = `log ${type}`;// 根據類型添加前綴let prefix = '';switch(type) {case 'error': prefix = '[ERROR] '; break;case 'warning': prefix = '[WARN] '; break;case 'info': prefix = '[INFO] '; break;case 'success': prefix = '[SUCCESS] '; break;default: prefix = '[LOG] ';}// 添加當前時間const time = new Date().toLocaleTimeString();logElement.textContent = `${prefix}${time} - ${message}`;// 添加到控制臺并保存到歷史記錄this.consoleElement.appendChild(logElement);this.messageHistory.push({type,message,time});// 限制歷史記錄長度if (this.messageHistory.length > this.maxMessages) {this.messageHistory.shift();// 也從DOM中移除最早的消息if (this.consoleElement.children.length > this.maxMessages) {this.consoleElement.removeChild(this.consoleElement.children[0]);}}// 自動滾動到最新消息this.consoleElement.scrollTop = this.consoleElement.scrollHeight;// 添加入場動畫logElement.style.opacity = '0';setTimeout(() => {logElement.style.opacity = '1';}, 10);// 隨機添加程序員幽默元素this.maybeAddProgrammerHumor();return logElement;}// 隨機添加程序員幽默maybeAddProgrammerHumor() {// 每20條消息有約10%概率出現幽默元素if (this.messageHistory.length % 20 === 0 && Math.random() < 0.1) {const jokes = ['又在努力調試了一整天,才發現是少了一個分號...','嘗試了99種方法都不行?那就嘗試第100種吧!','git commit -m "我也不知道為什么這能運行,但它就是運行了"','當代碼運行時,別動它;當代碼不運行時,也別動它。','Error 404: 咖啡不足','世界上最遙遠的距離不是生與死,而是你我之間的1px偏差'];const randomJoke = jokes[Math.floor(Math.random() * jokes.length)];this.log(randomJoke, 'info');}}// 清空控制臺clear() {this.consoleElement.innerHTML = '';this.log('控制臺已清空', 'info');}
}

這段代碼展示了如何實現一個交互式的模擬IDE控制臺。它不僅能顯示不同類型的消息,還會自動管理消息歷史記錄、控制滾動,甚至隨機穿插程序員幽默元素,增強游戲的文化氛圍。

開發難點
平衡信息量和游戲體驗是最大的挑戰。我們精心設計了信息過濾機制,確保玩家既能獲得必要的游戲反饋,又不會被過多的技術細節所干擾。

5. 彩蛋系統:游戲點睛之筆

作為一款面向程序員的游戲,彩蛋系統是我們投入心血最多的部分。我們設計了多種彩蛋,在不同條件下觸發,為玩家帶來意外的驚喜。

游戲通關彩蛋代碼

// 觸發游戲通關彩蛋
triggerGameBeatEasterEgg() {console.log("恭喜通關!你已經合成了三個財務自由!");// 暫停游戲this.isPaused = true;// 播放勝利音效序列this.audioManager.playVictoryFanfare();// 計算游戲統計數據const stats = this.calculateGameStats();// 創建通關UIconst eggContainer = document.createElement('div');eggContainer.className = 'game-beat-egg';eggContainer.innerHTML = `<div class="endgame-content"><div class="endgame-title-container"><div class="endgame-banner"></div><h1 class="endgame-title">恭喜通關!</h1></div><div class="endgame-certificate"><div class="certificate-header">程序員成就證書</div><div class="certificate-body"><div class="achievement">? 成功實現財務自由</div><div class="achievement">? 編程技能達到專家級別</div><div class="achievement">? 解鎖自由職業者生涯</div><div class="stats-grid"><div class="stat-item"><div class="stat-label">游戲時長</div><div class="stat-value">${stats.playTime} 分鐘</div></div><div class="stat-item"><div class="stat-label">總得分</div><div class="stat-value">${this.score}</div></div><div class="stat-item"><div class="stat-label">合成次數</div><div class="stat-value">${stats.totalMerges}</div></div><div class="stat-item"><div class="stat-label">程序員等級</div><div class="stat-value">Lv.${stats.highestLevel}</div></div><div class="stat-item"><div class="stat-label">消耗咖啡</div><div class="stat-value">${stats.coffeeConsumed} 杯</div></div><div class="stat-item"><div class="stat-label">編寫代碼</div><div class="stat-value">${stats.linesOfCode} 行</div></div></div></div><div class="certificate-footer"><div class="certificate-date">${new Date().toLocaleDateString()}</div><div class="certificate-seal"></div></div></div><div class="endgame-message"><p>成功通關!你已經成為了擁有財務自由的程序員精英!</p><p class="joke">通往成功的唯一捷徑,就是把if/else改成switch,這會加速程序運行(笑)</p></div><button class="continue-button">繼續游戲</button></div>`;// 添加特效元素for (let i = 0; i < 20; i++) {const particle = document.createElement('div');particle.className = 'endgame-particle';particle.style.left = `${Math.random() * 100}%`;particle.style.top = `${Math.random() * 100}%`;particle.style.animationDelay = `${Math.random() * 5}s`;eggContainer.appendChild(particle);}// 添加流星for (let i = 0; i < 3; i++) {const star = document.createElement('div');star.className = 'shooting-star';star.style.top = `${10 + Math.random() * 30}%`;star.style.left = `${Math.random() * 20}%`;star.style.animationDelay = `${i * 3}s`;eggContainer.appendChild(star);}// 添加到文檔document.body.appendChild(eggContainer);// 添加按鈕事件const continueButton = eggContainer.querySelector('.continue-button');continueButton.addEventListener('click', () => {eggContainer.classList.add('fade-out');setTimeout(() => {eggContainer.remove();this.isPaused = false;}, 1000);});// 保存通關記錄this.saveGameCompletionStats();
}// 計算游戲統計數據
calculateGameStats() {return {playTime: Math.floor((Date.now() - this.gameStartTime) / 60000), // 游戲時長(分鐘)totalMerges: this._mergeCount || 0,  // 總合成次數highestLevel: this.currentLevel,  // 最高等級financialFreedoms: this.financialFreedomCount, // 財務自由數量difficultyLevel: this.difficultyLevel + 1, // 難度級別// 隨機生成一些有趣的統計數據coffeeConsumed: Math.floor(Math.random() * 15) + 5, // 5-20杯咖啡linesOfCode: (Math.floor(Math.random() * 2000) + 1000) * this.score, // 基于分數的代碼行數bugsFixed: Math.floor(Math.random() * 99) + 1, // 1-100個bugsleepLost: Math.floor(Math.random() * 12) + 4 // 4-16小時};
}

這段代碼實現了游戲的通關彩蛋,當玩家成功合成三個"財務自由"物品時觸發。彩蛋不僅顯示游戲成績,還生成了一張精美的"程序員成就證書",并添加了流星和粒子特效,為玩家帶來視覺盛宴。

主要彩蛋類型:

  1. 財務自由彩蛋:首次合成"財務自由"物品時觸發,模擬終端界面展示玩家的虛擬財富狀況。

  2. 游戲通關彩蛋:成功合成三個"財務自由"物品時觸發,展示精美的程序員成就證書,記錄游戲統計數據和幽默的成就描述。

  3. 等級彩蛋:在達到特定程序員等級時觸發,解鎖特殊能力或游戲機制。

特殊彩蛋觸發代碼

// 特殊彩蛋方法
triggerSpecialEasterEgg(type, message) {this.consoleManager.log(message, 'warning')if (type === 'mid_game') {// 在游戲中間觸發的彩蛋const warningElement = document.createElement('div')warningElement.className = 'special-easter-egg mid-game'warningElement.innerHTML = `<div class="terminal-window"><div class="terminal-header"><span class="terminal-title">Terminal</span><span class="terminal-controls">×</span></div><div class="terminal-content"><div class="command-line">$ rm -rf node_modules</div><div class="command-output">Deleting... This might take a while</div><div class="command-prompt">_</div></div></div>`document.body.appendChild(warningElement)// 3秒后刪除彩蛋元素setTimeout(() => {warningElement.classList.add('fade-out')setTimeout(() => warningElement.remove(), 1000)}, 3000)}else if (type === 'high_level') {// 高等級特殊彩蛋const confetti = document.createElement('div')confetti.className = 'confetti-container'// 創建50個隨機彩色紙屑for (let i = 0; i < 50; i++) {const color = ['#ff0000', '#00ff00', '#0000ff', '#ffff00', '#ff00ff'][Math.floor(Math.random() * 5)]const piece = document.createElement('div')piece.className = 'confetti-piece'piece.style.backgroundColor = colorpiece.style.left = Math.random() * 100 + '%'piece.style.animationDelay = Math.random() * 3 + 's'piece.style.animationDuration = Math.random() * 2 + 2 + 's'confetti.appendChild(piece)}document.body.appendChild(confetti)// 5秒后刪除紙屑setTimeout(() => {confetti.remove()}, 5000)}
}

這段代碼展示了如何實現特殊彩蛋,當玩家達到特定等級時觸發。這些彩蛋包括模擬終端窗口執行命令和彩色紙屑慶祝效果,為游戲增添了更多驚喜和樂趣。

開發難點與解決方案

1. 物理碰撞的穩定性

問題:使用Matter.js實現物理碰撞時,有時會出現物體穿透或合成判定不準確的問題。

解決方案

  • 優化碰撞參數,增加迭代次數提高精度
  • 設計復合判定條件,綜合考慮距離、時間和速度
  • 添加額外的安全檢查,防止邊緣情況導致的錯誤

代碼實現

// 物理引擎參數優化
this.engine = Matter.Engine.create({enableSleeping: true,constraintIterations: 3,  // 增加約束迭代次數positionIterations: 8,    // 增加位置迭代次數velocityIterations: 6     // 增加速度迭代次數
})

2. 游戲性能優化

問題:當屏幕上物體數量增多時,物理計算會導致性能下降。

解決方案

  • 實現物體睡眠機制,減少靜止物體的計算量
  • 優化渲染循環,分離物理更新和視覺渲染
  • 使用固定時間步長更新物理世界,保證穩定性

代碼實現

gameLoop() {if (this.gameOver) returnconst loop = (currentTime) => {if (!this.isPaused) {try {// 計算時間步長const deltaTime = currentTime - this.lastTimethis.lastTime = currentTimethis.accumulator += deltaTime// 固定時間步長更新物理while (this.accumulator >= this.fixedDeltaTime) {Matter.Engine.update(this.engine, this.fixedDeltaTime)this.accumulator -= this.fixedDeltaTime}this.checkLevelUp()this.checkDifficulty()this.checkWarningLine()this.updateGameState()this.checkCanDrop()} catch (error) {console.error('游戲循環錯誤:', error)// 嘗試恢復游戲狀態this.canDropItem = truethis.lastDroppedItem = null}}requestAnimationFrame(loop.bind(this))}requestAnimationFrame(loop.bind(this))
}

這段代碼實現了一個高效的游戲循環,使用固定時間步長更新物理世界,確保物理模擬的精確性和一致性,同時避免了過度渲染導致的性能問題。

項目代碼:

👉 項目源碼點擊這里獲取👈

寫在最后

🎉 到這里,“程序員版合成大西瓜"游戲的開發分享就到這里啦!希望這些內容能幫助到你的日常開發工作,也歡迎你下載游戲體驗,看看能否成功合成三個"財務自由”,解鎖終極彩蛋!

如果覺得有幫助的話,別忘了點個贊 👍 收藏 ? 關注 🔖 哦!

💡 開發路上,我們都是學習者。如果你有任何問題或更好的想法,歡迎在評論區留言交流!

🤝 一起進步,共同成長~


🎯 我是果凍~,一個熱愛技術、樂于分享的開發者
📚 更多精彩內容,請關注我的博客
🌟 我們下期再見!

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/diannao/75871.shtml
繁體地址,請注明出處:http://hk.pswp.cn/diannao/75871.shtml
英文地址,請注明出處:http://en.pswp.cn/diannao/75871.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

鴻蒙OS 5.0 服務能力框架深入剖析

鴻蒙OS 5.0 服務能力框架中關鍵類的作用分析 1\. 鴻蒙OS 5.0 服務能力框架導論 鴻蒙OS 5.0&#xff0c;亦稱鴻蒙智聯 5 1&#xff0c;標志著華為在分布式操作系統領域邁出的重要一步。與早期版本采用兼容安卓的AOSP層、Linux內核以及LiteOS內核不同&#xff0c;鴻蒙OS 5.0 專注…

RTMP推流+EasyDSS云服務+邊緣AI分析的無人機監控系統設計

在現代科技不斷發展的背景下&#xff0c;無人機技術已經廣泛應用于各個領域&#xff0c;從航拍攝影到工業巡檢&#xff0c;從農業監測到應急救援&#xff0c;無人機以其高效的工作能力&#xff0c;為人們的生活和工作帶來了諸多便利與創新&#xff0c;而其視頻傳輸與分析系統更…

HCIP(VLAN綜合實驗)

實驗拓補圖 實驗分析 一、實驗目的 掌握VLAN的創建和配置方法理解VLAN在局域網中的作用學習如何通過VLAN實現網絡隔離和通信 二、實驗環境 交換機&#xff08;SW1、SW2、SW3&#xff09;個人電腦&#xff08;PC1、PC2、PC3、PC4、PC5、PC6&#xff09;路由器&#xff08;R1…

Linux系統編程 | 線程的基本概念

&#x1f493;個人主頁&#xff1a;mooridy &#x1f493;專欄地址&#xff1a;Linux 關注我&#x1f339;&#xff0c;和我一起學習更多計算機的知識! &#x1f51d;&#x1f51d;&#x1f51d; 什么是線程 程序中的一個執行路線就叫做線程 一個進程至少要有一個執行線程,單…

小林coding-12道Spring面試題

1.說一下你對 Spring 的理解?spring的核心思想說說你的理解&#xff1f; 2.Spring IoC和AOP 介紹一下?Spring的aop介紹一下?IOC和AOP是通過什么機制來實現的?怎么理解SpringIoc&#xff1f;依賴倒置&#xff0c;依賴注入&#xff0c;控制反轉分別是什么&#xff1f;依賴注…

第十二章——位運算

按位的與& 若x的第i位和y的第i位都是1&#xff0c;那么&#xff08;x&y&#xff09;1&#xff0c;否則&#xff08;x&y&#xff09; 0 應用&#xff1a;希望讓某一位或某些位為0 。取一個數中的一段。 按位的或| 若x的第i位1或y的第i位1&#xff0c;那么&…

計算機等級考試數據庫三級(筆記3)

插入 修改 現要創建一個具有如下功能的觸發器&#xff1a;每當在銷售表中插入一條銷售記錄時&#xff0c;修改商品表中對應商品的銷售總量&#xff0c;假設一次只插入一條銷售記錄。請補全下列代碼。CREATE TRIGGER tri insert on xx FOR xx AS xx 商品表 xx 銷售總量xx (SELEC…

【Leetcode 每日一題】2716. 最小化字符串長度

問題背景 給你一個下標從 0 0 0 開始的字符串 s s s&#xff0c;重復執行下述操作 任意 次&#xff1a; 在字符串中選出一個下標 i i i&#xff0c;并使 c c c 為字符串下標 i i i 處的字符。并在 i i i 左側&#xff08;如果有&#xff09;和 右側&#xff08;如果有&…

Flutter中實現拍照識題的功能

文章目錄 **1. 功能拆解****2. 具體實現步驟****(1) 拍照或選擇圖片****(2) 圖片預處理&#xff08;可選&#xff09;****(3) 文字識別&#xff08;OCR&#xff09;****(4) 數學公式識別 → LaTeX****方案1&#xff1a;Mathpix API&#xff08;高精度&#xff0c;付費&#xff…

【Mysql:內置函數】

日期函數&#xff1a; 查看當前日期&#xff1a; select current_date();查看當前時間&#xff1a; select current_time(); 查看當前時間戳&#xff1a; select current_timestamp(); 計算兩個日期的差值&#xff1a; select datediff(date1,date2); 當前的日期時間&a…

71. 我的第一個Linux驅動實驗

一、字符設備驅動框架 字符設備驅動的編寫主要就是驅動對應的open、close、read。。。其實就是 file_operations結構體的成員變量的實現。 其中關于 C 庫以及如何通過系統調用“陷入” 到內核空間這個我們不用去管&#xff0c;我們重點關注的是應用程序和具體的驅動&#xff0…

jdk21使用Vosk實現語音文字轉換,免費的語音識別

1.下載vosk的model vosk官網&#xff1a;https://alphacephei.com/vosk/models 我這里使用較小的vosk-model-small-cn-0.22 2.添加相關pom文件 <!-- 獲取音頻信息 --><dependency><groupId>org</groupId><artifactId>jaudiotagger</artifac…

如何一鍵安裝所有Python項目的依賴!

在開發項目時&#xff0c;常常需要在多個環境中安裝各種依賴。對開發者來說&#xff0c;每次手動一個個安裝這些依賴是不是很麻煩&#xff1f;&#x1f605; 其實有個超簡單的辦法&#xff01;只需要一個腳本&#xff0c;就能快速解決問題&#xff01;&#x1f4a1; 這就是我們…

Blender配置渲染設置并輸出動畫

在Blender中&#xff0c;渲染設置和渲染動畫的選項位于不同的面板中。以下是具體步驟&#xff1a; 渲染設置 渲染設置用于配置輸出格式、分辨率、幀率等參數。 打開右側的 屬性面板&#xff08;按 N 鍵可切換顯示&#xff09;。 點擊 “輸出屬性” 選項卡&#xff08;圖標是…

C++修煉:string類的使用

Hello大家好&#xff01;很高興我們又見面啦&#xff01;給生活添點passion&#xff0c;開始今天的編程之路&#xff01; 我的博客&#xff1a;<但凡. 我的專欄&#xff1a;《編程之路》、《數據結構與算法之美》、《題海拾貝》、《C修煉之路》 歡迎點贊&#xff0c;關注&am…

【go微服務】如何快速掌握grpc開發

?? 歡迎大家來到景天科技苑?? &#x1f388;&#x1f388; 養成好習慣&#xff0c;先贊后看哦~&#x1f388;&#x1f388; &#x1f3c6; 作者簡介&#xff1a;景天科技苑 &#x1f3c6;《頭銜》&#xff1a;大廠架構師&#xff0c;華為云開發者社區專家博主&#xff0c;…

【區塊鏈 + 文化版權】基于 FISCO BCOS 的方言大數據語料庫 | FISCO BCOS 應用案例

蘇州喵自在區塊鏈科技有限公司打造的基于FISCO BCOS 的粵語大數據語料庫&#xff0c; 旨在利用區塊鏈技術保護和發展粵語文化遺產。該項目利用區塊鏈的不可篡改性、分布式存儲、智能合約和激勵機制等特性&#xff0c; 為保護非物質文化遺產&#xff0c; 加強粵語研究與教育和開…

大模型在支氣管擴張預測及治療方案制定中的應用研究

目錄 一、引言 1.1 研究背景與意義 1.2 研究目的與方法 1.3 國內外研究現狀 二、大模型技術概述 2.1 大模型的基本原理與架構 2.2 適用于支氣管擴張預測的大模型類型及特點 2.3 大模型在醫療領域的應用現狀與優勢 三、支氣管擴張的相關醫學知識 3.1 支氣管擴張的病因…

亞馬遜云科技提供完全托管的DeepSeek-R1模型

近日&#xff0c;亞馬遜云科技宣布在Amazon Bedrock上線完全托管的DeepSeek-R1模型。DeepSeek是首個登陸Amazon Bedrock的國產大模型&#xff0c;自今年1月底推出以來&#xff0c;已有數千客戶使用Amazon Bedrock的自定義模型導入功能部署了DeepSeek-R1模型。 DeepSeek在過去幾…

二叉樹、排序算法與結構圖

二叉樹、排序算法與數據庫 二叉樹 二叉樹的性質 節點數與深度的關系&#xff1a;深度為 k k k的二叉樹&#xff0c;最多有 2 k ? 1 2^k - 1 2k?1個節點。例如&#xff0c;深度為 3 3 3的二叉樹&#xff0c;最多有 2 3 ? 1 7 2^3 - 1 7 23?17個節點。葉子節點與度為2節…