ICode9

精准搜索请尝试: 精确搜索
首页 > 编程语言> 文章详细

如何用 JavaScript 编写游戏

2022-09-06 08:34:38  阅读:483  来源: 互联网

标签:canvas 游戏 image JavaScript 画布 objects 图像 编写


如何用 JavaScript 编写游戏

今天的浏览器允许您创建具有完整图形的游戏。以下是使用 JavaScript 和 HTML5 编写简单赛车游戏的方法。

浏览器现在为 JavaScript 开发人员提供了许多用于创建有趣站点的选项。 Flash曾经被用来做这个——它很流行,无数的游戏、播放器、花哨的界面等等都是在它上面创造出来的。但是,它们不再在任何现代浏览器中运行。

Flash技术重量级,漏洞百出,因此开始放弃。特别是因为有 HTML5 形式的替代方案。

Canvas 是可以使用 JS 命令在其上进行绘制的画布。它可用于创建动画背景、各种构造函数,最重要的是,游戏。

在本文中,您将学习如何使用 JavaScript 和 HTML5 创建浏览器游戏。但首先,我们建议您熟悉 JS 中的面向对象编程(只需了解类、方法和对象是什么)。这是创建游戏的最佳方式,因为它允许您使用实体而不是抽象数据。但是,有一个缺点:任何版本的 Internet Explorer 都不支持 OOP。

游戏页面布局

首先,您需要创建一个显示画布的页面。这需要很少的 HTML:

 <!DOCTYPE html>  
 <html>  
 <head>  
 <title>JS游戏</title>  
 <link rel="stylesheet" href="style.css">  
 <meta charset="utf-8">  
 </head>  
 <body>  
 <div class="wrapper">  
 <canvas width="0" height="0" class="canvas" id="canvas">您的浏览器不支持 JavaScript è HTML5</canvas>  
 </div>  
 <script src="game.js"></script>  
 </body>  
 </html>

现在我们需要添加样式:

 正文,html  
 {  
 宽度:100%;  
 高度:100%;  
 填充:0px;  
 边距:0px;  
 溢出:隐藏;  
 }  
   
 .wrapper  
 {  
 宽度:100%;  
 高度:100%;  
 }  
   
 。帆布  
 {  
 宽度:100%;  
 高度:100%;  
 背景:#000;  
 }

请注意,在 HTML 中,canvas 元素的宽度和高度为零,而 CSS 指定为 100%。在这方面,画布的行为就像一个图像。它具有实际分辨率和可见分辨率。

使用样式更改可见分辨率。但是,图片的尺寸将保持不变:它只会被拉伸或压缩。这就是为什么稍后将通过脚本指定实际宽度和高度的原因。

游戏脚本

首先,让我们为游戏添加一个脚本蓝图:

 var canvas = document.getElementById("canvas"); // 从 DOM 中获取画布  
 var ctx = canvas.getContext("2d"); //获取上下文 - 通过它您可以使用画布  
   
 变量比例= 0.1; //机器秤  
   
 调整大小(); //页面加载时,设置画布大小  
   
 window.addEventListener("resize", Resize); //改变窗口大小会改变画布大小  
   
 window.addEventListener("keydown", function (e) { KeyDown(e); }); //接收来自键盘的击键  
   
 变量对象 = []; //游戏对象数组  
 var 道路 = []; //带背景的数组  
   
 var 播放器 = null; //玩家控制的对象 - 这里将是对象数组中对象的编号  
   
 函数开始()  
 {  
 计时器 = setInterval(更新,1000 / 60); //游戏状态每秒会更新60次——按照这个速度,正在发生的事情的更新会显得很流畅  
 }  
   
 函数停止()  
 {  
 清除间隔(定时器); //停止更新  
 }  
   
 function Update() //游戏更新  
 {  
 画();  
 }  
   
 function Draw() //处理图形  
 {  
 ctx.clearRect(0, 0, canvas.width, canvas.height); //从上一帧清除画布  
 }  
   
 功能 KeyDown(e)  
 {  
 开关(e.keyCode)  
 {  
 案例 37: //左  
 休息;  
   
 案例 39: //对  
 休息;  
   
 案例 38: //向上  
 休息;  
   
 案例 40: //向下  
 休息;  
   
 案例 27: //Esc  
 休息;  
 }  
 }  
   
 函数调整大小()  
 {  
 canvas.width = window.innerWidth;  
 canvas.height = window.innerHeight;  
 }

该脚本包含创建游戏所需的一切:数据(数组)、更新、绘制和控制功能。它只剩下用基本逻辑来补充它。也就是说,准确指定对象的行为方式以及它们在画布上的显示方式。

游戏逻辑

在 Update() 函数调用期间,游戏对象的状态将发生变化。之后,它们将使用 Draw() 函数在画布上绘制。所以我们实际上并没有在画布上移动对象,我们绘制它们一次,然后更改它们的坐标,擦除旧图像并使用新坐标显示对象。这一切发生得如此之快,以至于给人一种运动的错觉。

让我们看一个道路的例子。

此图像显示在画布上并逐渐向下移动。紧接着,又会显示出另一幅这样的画面,让人感觉像是一条没有尽头的路。

为此,让我们创建一个 Road 类:

 班道  
 {  
 构造函数(图像,y)  
 {  
 这个.x = 0;  
 这个.y = y;  
   
 this.image = new Image();  
          
 this.image.src = 图像;  
 }  
   
 更新(路)  
 {  
 this.y += 速度; //刷新时图片下移  
   
 if(this.y > window.innerHeight) //如果图像越过了画布边缘,改变位置  
 {  
 this.y = road.y - this.image.height + 速度; //新位置用第二个背景表示  
 }  
 }  
 }

将 Road 类的两个对象添加到背景数组中:

 var 道路 =  
 [  
 new Road("images/road.jpg", 0),  
 新路(“图片/路.jpg”,626)  
 ]; //背景数组

您现在可以更改 更新() 功能,使图像的位置随每一帧而变化。

 function Update() //游戏更新  
 {  
 道路[0].更新(道路[1]);  
 道路[1].更新(道路[0]);  
   
 画();  
 }

只需添加这些图像的输出:

 function Draw() //处理图形  
 {  
 ctx.clearRect(0, 0, canvas.width, canvas.height); //从上一帧清除画布  
   
 for(var i = 0; i < 道路长度; i++)  
 {  
 ctx.drawImage  
 (  
 road[i].image, //渲染图像  
 0, //图像中的初始X位置  
 0, //图像中的初始Y轴位置  
 road[i].image.width, //图像宽度  
 road[i].image.height, //图像高度  
 road[i].x, //画布上的X轴位置  
 road[i].y, //画布上的Y轴位置  
 canvas.width, //图像在画布上的宽度  
 canvas.width //由于背景的宽度和高度相同,所以宽度指定为高度  
 );  
 }  
 }

现在你可以看到它在游戏中是如何工作的:

现在是添加玩家和 NPC 的时候了。为此,您需要编写一个 Car 类。它将有一个 Move() 方法,玩家可以使用该方法控制他的汽车。 NPC 的移动将通过 Update() 完成,它只是更改 Y 坐标。

 类车  
 {  
 构造函数(图像,x,y)  
 {  
 这个.x = x;  
 这个.y = y;  
   
 this.image = new Image();  
   
 this.image.src = 图像;  
 }  
   
 更新()  
 {  
 this.y += 速度;  
 }  
   
 移动(v,d)  
 {  
 if(v == "x") //X轴移动  
 {  
 这个.x += d; //抵消  
   
 //  
 if(this.x + this.image.width * scale > canvas.width)  
 {  
 这个.x -= d;  
 }  
      
 如果(this.x < 0)  
 {  
 这个.x = 0;  
 }  
 }  
 else //Y轴移动  
 {  
 这个.y += d;  
   
 if(this.y + this.image.height * scale > canvas.height)  
 {  
 这个.y -= d;  
 }  
   
 如果(这个.y < 0)  
 {  
 这个.y = 0;  
 }  
 }  
          
 }  
 }

让我们创建第一个要检查的对象。

 变量对象 =  
 [  
 新车("images/car.png", 15, 10)  
 ]; //游戏对象数组  
 var 播放器 = 0; //玩家控制的物体数量

现在您需要向 Draw() 函数添加一个用于绘制汽车的命令。

 for(var i = 0; i < objects.length; i++)  
 {  
 ctx.drawImage  
 (  
 objects[i].image, //渲染图像  
 0, //图像中的初始X位置  
 0, //图像中的初始Y轴位置  
 objects[i].image.width, //图像宽度  
 objects[i].image.height, //图像高度  
 objects[i].x, //画布上的X轴位置  
 objects[i].y, //画布上的Y轴位置  
 objects[i].image.width * scale, //画布上图像的宽度乘以比例  
 objects[i].image.height * scale //图像在画布上的高度乘以比例  
 );  
 }

在按下键盘时调用的 KeyDown() 函数中,您需要添加对 Move() 方法的调用。

 功能 KeyDown(e)  
 {  
 开关(e.keyCode)  
 {  
 案例 37: //左  
 对象[玩家].Move("x", -speed);  
 休息;  
  
 案例 39: //对  
 objects[player].Move("x", speed);  
 休息;  
   
 案例 38: //向上  
 objects[player].Move("y", -speed);  
 休息;  
   
 案例 40: //向下  
 objects[player].Move("y", speed);  
 休息;  
   
 案例 27: //Esc  
 如果(计时器 == 空)  
 {  
 开始();  
 }  
 别的  
 {  
 停止();  
 }  
 休息;  
 }  
 }

现在您可以检查渲染和控制。

碰撞时什么都没有发生,但这将在以后修复。首先,您需要确保删除视图中丢失的对象。这是为了避免堵塞 RAM。

在 Car 类中,我们添加值为 false 的字段 dead,然后在 Update() 方法中对其进行更改:

 如果(this.y > canvas.height + 50)  
 {  
 this.dead = true;  
 }

现在您需要更改游戏的更新功能,替换与对象关联的代码:

 var hasDead = false;  
   
 for(var i = 0; i < objects.length; i++)  
 {  
 如果(我!=玩家)  
 {  
 对象[i].Update();  
   
 如果(对象[i].dead)  
 {  
 有死=真;  
 }  
 }  
 }  
   
 如果(已死亡)  
 {  
 对象.shift();  
 }

如果您不移除对象,当生成太多汽车时,游戏将开始降低计算机速度。

游戏对象碰撞

现在您可以开始实施碰撞。为此,为 Car 类编写一个方法 Collide(),它将检查汽车的坐标:

 碰撞(汽车)  
 {  
 变量命中=假;  
   
 if(this.y < car.y + car.image.height * scale && this.y + this.image.height * scale > car.y) //如果物体水平在同一条线上  
 {  
 if(this.x + this.image.width * scale > car.x && this.x < car.x + car.image.width * scale) //如果物体垂直在同一条线上  
 {  
 命中=真;  
 }  
 }  
   
 回击;  
 }

现在我们需要在 Update() 函数中添加碰撞检查:

 变量命中=假;  
   
 for(var i = 0; i < objects.length; i++)  
 {  
 如果(我!=玩家)  
 {  
 hit = objects[player].Collide(objects[i]);  
   
 如果(命中)  
 {  
 alert("你崩溃了!");  
 停止();  
 休息;  
 }  
 }  
 }

这是游戏中的内容

碰撞时可以添加任何逻辑:

• 打开动画;

• 添加效果;;

• 删除对象;

• 健康状况的改变,等等。

所有这些都由开发人员自行决定。

结论

这是一个非常简单的游戏,但足以了解 JS 如何处理图形以及一般如何创建游戏。您可以在 GitHub 存储库中找到图像和完整的游戏代码。

使用画布非常适合处理图形:它提供了强大的功能并且不会过多地加载浏览器。我们现在也有一个可用的 WebGL 库(示例和用法),它可以为您提供大量性能和 3D 工作(canvas 无法做到这一点)。

理解 WebGL 可能很困难——也许相反,许多人对尝试 Unity 引擎更感兴趣,它知道如何编译项目以在浏览器中运行它们。

版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明

本文链接:https://www.qanswer.top/18380/02530608

标签:canvas,游戏,image,JavaScript,画布,objects,图像,编写
来源: https://www.cnblogs.com/amboke/p/16660357.html

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有