01
2024
08
16:32:41

使用JS封装的一个小型游戏引擎及源码分享

复制代码

                                                                                                                           Game =             canvas =       self =                .context = canvas.getContext('2d');                       .sprites = [];                                             .gameName = gameName;                                               .startTime = 0;                                           .lastTime = 0;                                            .gameTime = 0;                                            .fps = 0;                                                .STARTING_FPS = 60;                                         .paused = ;                                           .startedPauseAt = 0     .PAUSE_TIMEOUT = 100;                                               .imageLoadingProgressCallback;                               .images = {};                                                 .imageUrls = [];                                              .imagesLoaded = 0;                                            .imagesFailedToLoad = 0;                                      .imagesIndex = 0;                                                         .soundOn =      .soundChannels = [];                                          .audio =  Audio();                                         .NUM_SOUND_CHANNELS = 10;                                                 .keyListeners = [];                                             window.onkeypress =  (ev) {                                 window.onkeydown =                  .HIGH_SCORES_SUFFIX = '_highscores';                          .highScores = [];                                                          ( i = 0; i < .NUM_SOUND_CHANNELS; i++          audio =                   ;                                                             Game.prototype =                         getImage :                                    imageLoadedCallback :                    .imagesLoaded++                         imageLoadErrorCallback :          .imagesFailedToLoad++                        loadImage :           self =           image =            image.src =                       image.addEventListener("load",                                                        image.addEventListener("error",                          .images[imageUrl] =                       loadImages :                     (.imagesIndex <                            .loadImage(.imageUrls[             .imagesIndex ++                         percentage = (.imagesLoaded + .imagesFailedToLoad) / .imageUrls.length * 100           (.imagesLoaded + .imagesFailedToLoad) / .imageUrls.length * 100                      queueImage :                                start:           self =            .startTime = + Date();                            console.log("游戏启动成功, 当前时间:",                                                                console.log(self,                                    self.animate.call(self, time);             animate:                     self =             (                                           setTimeout(              },                                  .tick(time);                                  .clearScreen();                                                 .startAnimate(time);                          .paintUnderSprites();                           .updateSprites(time);                         .paintSprites(time);                            .paintOverSprites();                          .endAnimate();                                                                            console.log(self,                                                                             togglePaused :                     now = + Date();                                  .paused = !.paused;                              (                           .startedPauseAt =         }                                                       .startTime = .startTime + now -              .lastTime =                           tick:                                         .gameTime = (+ Date()) -          console.log("设置游戏的时间:" +          .lastTime =        updateFrameRate:                     (.lastTime === 0             .fps =                                      .fps = 1000 / (time -              console.log("实时更新游戏当前的帧速率",                         pixelsPerFrame :                               velocity /                      clearScreen:                              .context.clearRect(0, 0, .context.canvas.width,          console.log("画布屏幕清空成功!"                        startAnimate:          console.log(time, "开始游戏动画………………"                   paintUnderSprites:          console.log("绘制精灵后面的内容!"                    updateSprites:          console.log("更新所有精灵的位置!"          ( i = 0; i < .sprites.length; i++              sprite =                            sprite.update(               paintSprites:          console.log("绘制所有可见的精灵对象"          ( i = 0; i < .sprites.length; i++              sprite =                                             sprite.paint(.context);                                          paintOverSprites:          console.log("绘制精灵前面的内容!"            endAnimate:          console.log("绘制动画结束!"                                  canPlayOggVorbis :                     "" != .audio.canPlayType('audio/ogg; codecs="vorbis"'                      canPlayMp3 :                     "" != .audio.canPlayType('audio/mpeg'                      getAvailableSoundChannel :                                ( i = 0; i < .NUM_SOUND_CHANNELS; i++             audio =                             (audio.played && audio.played.length > 0                                                                      }                                     (!                                                                playSound :                     track =              element =                        (track &&                           track.src = element.src === '' ?                                                     addKeyListener :                                 findKeyListener :           listener =                      ( i = 0; i < .keyListeners.length; i++                            keyAndListener =                  currentKey =                              (currentKey ===                 listener =                                   keyPressed :           listener =             key =                                       32                 key = 'space'                               65                 key = 'a'                               83                 key = 's'                               80                 key = 'p'                               87                 key = 'w'                                             37                 key = 'left arrow'                               39                 key = 'right arrow'                               38                 key = 'up arrow'                               40                 key = 'down arrow'                                       listener =                       listener();                                                 getHighScores :                     key = .gameName +              highScoresString =                        (highScoresString ==             localStorage[key] =                                          setHighScore :                     key = .gameName +              highScoresString =                                              (.highScores.length === 0             .highScores =                                  localStorage[key] = JSON.stringify(                     clearHighScores :                    localStorage[.name + .HIGH_SCORES_SUFFIX] =    }

复制代码

下面的是一个测试案例:

 

功能实现的比较简单,但是也就是对上面的这个引擎的基本使用吧。

 

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113<!DOCTYPE html><html lang="en"><head>    <meta charset="UTF-8">    <title>Game 1.0</title>    <!--引入需要的css文件, 注意这里的引入使用的是link方式来引入css文件-->    <link rel='stylesheet' type='text/css' href='css/Main.css'/></head><body><!--canvas画布--><canvas id="gameCanvas" width="580" height="600">    Canvas not supported in your browser!</canvas>  <!--canvas上方的悬浮div--><div id="loadingToast">    <span id="gameTitle">Engine Development</span>    <span id="loadingContents">        <p class="mainFunctions">            主要功能:        </p>          <ul class="Contents">            <li>1.资源加载的画面</li>            <li>2.游戏资源的管理</li>            <li>3.声音的播放</li>            <li>4.具有视差动画的滚动背景</li>            <li>5.生命数量的显示</li>            <li>6.高分榜的维护</li>            <li>7.按键的监听与处理</li>            <li>8.暂停功能与自动暂停机制实现</li>            <li>9.游戏结束的流程处理</li>        </ul>     </span>     <span id="loadButtonSpan">            <button autofocus="true" id="loadButton">载入引擎...</button><br/>            <span id="loadingMessage">Loading……</span>        </span>    <!--用于显示进度条-->    <div id="progressDiv">    </div> </div>  <!--左上角计时器--><div id="gameTimerDiv">    <span>000</span></div><!--右上角生命值--><div id="leftLives">    <span id="lifeValue">生命值:100</span></div> <!--中部的暂停--><div id="pausedToast">    <span>暂停</span><br/>    <span>点击此区域任意位置继续</span></div>   <!--中下位置的点击按钮--><div id="loseLifePanel">    <button id="loseLifeButton" onmouseover="this.style.backgroundColor='#00aced'"            onmouseleave="this.style.backgroundColor = ''">开杀    </button></div>   <!--游戏结束及高分榜--><div id="gameoverPan">    <div id="topPan">        <span id="scoreText">140</span>    </div>    <div id="middlePan">        <span>High Score!</span><br/>        <span class="Name">What's your name?</span><br/>         <input id='playerName' type='text' autofocus='true'><button id="addMyScoreButton">添加</button><button id="newGameButton">新游戏</button>    </div>    <div id="downPan">        <span>Previous High Scores</span>        <ul id="highScoreList">        </ul>    </div></div>  <!--游戏播放音乐需要使用的音频文件; preload 属性规定是否在页面加载后载入音频。--><audio id="pop" preload="auto">    <source src="sounds/pop.ogg" type="audio/ogg">    <source src="sounds/pop.mp3" type="audio/mp3"></audio><audio id="whoosh" preload="auto">    <source src="sounds/whoosh.ogg" type="audio/ogg">    <source src="sounds/whoosh.mp3" type="audio/mp3"></audio>   <!--引入需要的js文件--><script type="text/javascript" src="Engine/progressbar.js"></script><script type="text/javascript" src="Engine/requestNextAnimationFrame.js"></script><script type="text/javascript" src="Engine/GameEngine1.0.js"></script><script type="text/javascript" src="js/Main.js"></script></body></html>

  

 

实现的功能基本介绍:(目前是开发期间的9个版本及功能介绍)

/*
* V1.0: 引擎实现的基本模块思路
* 1.创建一个游戏引擎对象及精灵对象
* 2.将精灵对象添加到引擎中去,并实现播放动画效果以及需要用到的回调方法
* 3.启动引擎
* */

/*
* V2.0: 实现游戏循环模块
* 1.如果游戏暂停了,就跳过以下各步骤,并在100毫秒后再次执行游戏循环
* 2.更新帧速率
* 3.设置游戏时间
* 4.清除屏幕内容
* 5.在播放动画前,调用startAnimate的方法(可以进行碰撞检测)
* 6.绘制精灵背后的内容(绘制背景)
* 7.更新精灵
* 8.绘制精灵
* 9.绘制精灵前方的内容
* 10.动画播放完毕之后,调用endAnimate方法
* 11.请求浏览器播放下一帧动画
*
* */


/**
* V3.0: 实现在暂停状态与运行状态之间的切换togglePaused
*/

/**
* V4.0:实现基于时间的运动效果 :pixelPerFrame
* 计算公式:(pixels / second) * (second / frame) = pixeld / second【单位:每一秒移动的像素数】
*/

/**
* V5.0: 实现加载图像的功能:
* queueImage(imageUrl): 将图像放入到加载队列中去
* loadImages(): 开发者需要持续调用该方法,知道返回100位置(方法的返回值表示图像加载完成的百分比)
* getImage(imageUrl):返回图像对象, 只有咋loadImages()返回100之后,才可以调用该方法
*/

/**
* V6.0:实现同时播放多个声音的功能
* canPlay(): 用于查询浏览器是否能够播放某种特定格式的声音文件
* playSound():用于播放声音
*/


/**
* V7.0: 键盘事件的处理
* addKeyListener(): 用于向游戏注册按键监听器
*/


/**
* V8.0: 高分榜的维护:游戏的高分榜数组以json格式存档在本地
*/

/**
* V9.0: 实现了一个比较完整的游戏引擎,开始使用这个简单的游戏引擎去制作一个小游戏
* 需求分析:
* 1.资源加载的画面
* 2.游戏资源的管理
* 3.声音的播放
* 4.具有视差动画的滚动背景
* 5.生命数量的显示
* 6.高分榜的维护
* 7.按键的监听与处理
* 8.暂停功能与自动暂停机制实现
* 9.游戏结束的流程处理
*/

其他的文件已经全部上传到Github,感兴趣的朋友可以下载查看学习交流,如果觉得不错,欢迎给个star支持一下:

 

https://github.com/xiugangzhang/GameEngine

 

其他的几个小游戏也已经分享

中国象棋:https://github.com/xiugangzhang/ChineseChess

超级马里奥小游戏:https://github.com/xiugangzhang/SuperMarioGame

苏拉卡尔塔小游戏:https://github.com/xiugangzhang/SularaGame

 




推荐本站淘宝优惠价购买喜欢的宝贝:

image.png

本文链接:https://hqyman.cn/post/7336.html 非本站原创文章欢迎转载,原创文章需保留本站地址!

分享到:
打赏





休息一下~~


« 上一篇 下一篇 »

发表评论:

◎欢迎参与讨论,请在这里发表您的看法、交流您的观点。

请先 登录 再评论,若不是会员请先 注册

您的IP地址是: