首页 > 编程语言 >如何用 JavaScript 编写游戏

如何用 JavaScript 编写游戏

时间:2022-09-06 08:12:10浏览次数:105  
标签: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,图像,编写
From: https://www.cnblogs.com/amboke/p/16660357.html

相关文章

  • 学习现代 JavaScript (ES6+) 的基础知识
    学习现代JavaScript(ES6+)的基础知识您应该在代码中开始使用的10个现代功能您可能已经知道JavaScript是一种功能丰富的编程语言,每次更新都会不断增强。有很多事......
  • 动画标签 HTML CSS JavaScript
    动画标签HTMLCSSJavaScript动画标签HTMLCSSJavaScript免费下载HTML:<linkrel="样式表"href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.1......
  • 以我的方式编写代码
    以我的方式编写代码在课堂录制的第2天,我了解到可以通过放置容器并使它们可见来规划我的网站。通过做一个****在html中并使它们在css中可见,您可以编写例如.main-......
  • 编写脚本实现登陆远程主机(使用expect和shell脚本两种形式)
    一、expect形式1.安装expectyuminstallexpect-y2.Expect脚本#!/usr/bin/expectsetip10.0.0.149setuseryangchenghuasetpasswordyangchenghuasettimeout10spa......
  • Javascript简介
    ​ /**作者:呆萌老师*☑csdn认证讲师*☑51cto高级讲师*☑腾讯课堂认证讲师*☑网易云课堂认证讲师*☑华为开发者学堂认证讲师*☑爱奇艺千人名师计划成员*在这里......
  • JavaScript: stringify
     constobj={name:'qwer',hobbies:['op','nm'],year:2022,fn:function(){},//functionignorereg:newRegExp(),//RegExp{......
  • Android.mk 文件编写
    Android.mk以下内容通常够用,如需添加其他变量,百度查看LOCAL_PATH:=$(callmy-dir)//源码所在目录,写法固定include$(CLEAR_VARS)//清除除外LOCAL_PATH变量以外的其......
  • 56 | JAVA_编写HTTPserver
    编写HTTPServer我们来看一下如何编写HTTPServer。一个HTTPServer本质上是一个TCP服务器,我们先用TCP编程的多线程实现的服务器端框架:publicclassServer{public......
  • 游戏场景
    1.尺寸与方向1.尺寸以Cube作为参照,Cube是长宽高都为1米的参照物。2.方向-世界坐标系X(红色):右边Y(绿色):上边Z(蓝色):前边世界坐标系可以理解为现实生活中的方向,东南......
  • JavaScript 特殊数字值 NaN
    NaN是唯一一个不和自身不相等的值,Array》prototype.indexOf使用了严格相等,因此不能通过该方法在数组中查找NaN:NaN===NaN//false[NaN].indexof(NaN);//false如......