百度360必应搜狗淘宝本站头条
当前位置:网站首页 > 编程字典 > 正文

七爪源码:如何用 JavaScript 编写游戏

toyiye 2024-07-06 23:32 15 浏览 0 评论


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

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

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

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


游戏页面布局

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

<!DOCTYPE html>
<html>
    <head>
        <title>JS Game</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">Your browser does not support JavaScript и HTML5 </canvas>
        </div>
        <script src="game.js"></script>
    </body>
</html>

现在我们需要添加样式:

body, html
{
    width: 100%;
    height: 100%;
    padding: 0px;
    margin: 0px;
    overflow: hidden;
}
 
.wrapper
{
    width: 100%;
    height: 100%;
}
 
.canvas
{
    width: 100%;
    height: 100%;
    background: #000;
}

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

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


游戏脚本

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

var canvas = document.getElementById("canvas"); //Retrieving a canvas from the DOM
var ctx = canvas.getContext("2d"); //Obtaining a context - through it you can work with the canvas
 
var scale = 0.1; //Machine scale
 
Resize(); //When the page loads, the canvas size is set
 
window.addEventListener("resize", Resize); //Changing the size of the window will change the size of the canvas
 
window.addEventListener("keydown", function (e) { KeyDown(e); }); //Receiving keystrokes from the keyboard
 
var objects = []; //An array of game objects
var roads = []; //An array with backgrounds
 
var player = null; //The object controlled by the player - here will be the number of the object in the objects array
 
function Start()
{
    timer = setInterval(Update, 1000 / 60); //The game state will update 60 times per second - at this rate, the update of what is happening will seem very smooth
}
 
function Stop()
{
    clearInterval(timer); //Stopping the update
}
 
function Update() //Game update
{
    Draw();
}
 
function Draw() //Working with graphics
{
    ctx.clearRect(0, 0, canvas.width, canvas.height); //Clearing the canvas from the previous frame
}
 
function KeyDown(e)
{
    switch(e.keyCode)
    {
        case 37: //Left
            break;
 
        case 39: //Right
            break;
 
        case 38: //Up
            break;
 
        case 40: //Down
            break;
 
        case 27: //Esc
            break;
    }
}
 
function Resize()
{
    canvas.width = window.innerWidth;
    canvas.height = window.innerHeight;
}

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


游戏逻辑

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

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

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

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

class Road
{
    constructor(image, y)
    {
        this.x = 0;
        this.y = y;
 
        this.image = new Image();
        
        this.image.src = image;
    }
 
    Update(road) 
    {
        this.y += speed; //The image shifts down when you refresh
 
        if(this.y > window.innerHeight) //If the image has gone over the edge of the canvas, change the position
        {
            this.y = road.y - this.image.height + speed; //The new position is indicated with the second background
        }
    }
}

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

var roads = 
[
    new Road("images/road.jpg", 0),
    new Road("images/road.jpg", 626)
]; //background array

您现在可以更改 Update() 函数,以便图像的位置随每一帧而变化。

function Update() //Game Update
{
    roads[0].Update(roads[1]);
    roads[1].Update(roads[0]);
 
    Draw();
}

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

function Draw() //Working with graphics
{
    ctx.clearRect(0, 0, canvas.width, canvas.height); //Clearing the canvas from the previous frame
 
    for(var i = 0; i < roads.length; i++)
    {
        ctx.drawImage
        (
            roads[i].image, //Render image
            0, //Initial X position in the image
            0, //Initial Y-axis position in the image
            roads[i].image.width, //Image width
            roads[i].image.height, //Image height
            roads[i].x, //X-axis position on the canvas
            roads[i].y, //Y-axis position on the canvas
            canvas.width, //The width of the image on the canvas
            canvas.width //Since the width and height of the background are the same, the width is specified as the height
        );
    }
}

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

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

class Car
{
    constructor(image, x, y)
    {
        this.x = x;
        this.y = y;
 
        this.image = new Image();
 
        this.image.src = image;
    }
 
    Update()
    {
        this.y += speed;
    }
 
    Move(v, d) 
    {
        if(v == "x") //X-axis movement
        {
            this.x += d; //Offset
 
            //
            if(this.x + this.image.width * scale > canvas.width)
            {
                this.x -= d; 
            }
    
            if(this.x < 0)
            {
                this.x = 0;
            }
        }
        else //Y-axis movement
        {
            this.y += d;
 
            if(this.y + this.image.height * scale > canvas.height)
            {
                this.y -= d;
            }
 
            if(this.y < 0)
            {
                this.y = 0;
            }
        }
        
    }
}

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

var objects = 
[
    new Car("images/car.png", 15, 10)
]; //An array of game objects
var player = 0; //the number of the object controlled by the player

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

for(var i = 0; i < objects.length; i++)
{
    ctx.drawImage
    (
        objects[i].image, //Render image
        0, //Initial X position in the image
        0, //Initial Y-axis position in the image
        objects[i].image.width, //Image width
        objects[i].image.height, //Image height
        objects[i].x, //X-axis position on the canvas
        objects[i].y, //Y-axis position on the canvas
        objects[i].image.width * scale, //The width of the image on the canvas multiplied by the scale
        objects[i].image.height * scale //The height of the image on the canvas multiplied by the scale
    );
}

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

function KeyDown(e)
{
    switch(e.keyCode)
    {
        case 37: //Left
            objects[player].Move("x", -speed);
            break;

        case 39: //Right
            objects[player].Move("x", speed);
            break;
 
        case 38: //Up
            objects[player].Move("y", -speed);
            break;
 
        case 40: //Down
            objects[player].Move("y", speed);
            break;
 
        case 27: //Esc
            if(timer == null)
            {
                Start();
            }
            else
            {
                Stop();
            }
            break;
    }
}

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

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

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

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

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

var hasDead = false;
 
for(var i = 0; i < objects.length; i++)
{
    if(i != player)
    {
        objects[i].Update();
 
        if(objects[i].dead)
        {
            hasDead = true;
        }
    }
}
 
if(hasDead)
{
    objects.shift();
}

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


游戏物体碰撞

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

Collide(car)
{
    var hit = false;
 
    if(this.y < car.y + car.image.height * scale && this.y + this.image.height * scale > car.y) //If the objects are on the same line horizontally
    {
        if(this.x + this.image.width * scale > car.x && this.x < car.x + car.image.width * scale) //If the objects are on the same line vertically
        {
            hit = true;
        }
    }
 
    return hit;
}

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

var hit = false;
 
for(var i = 0; i < objects.length; i++)
{
    if(i != player)
    {
        hit = objects[player].Collide(objects[i]);
 
        if(hit)
        {
            alert("You crashed!");
            Stop();
            break;
        }
    }
}

这是游戏中的内容

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

? 打开动画;

? 添加效果;;

? 删除对象;

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

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


结论

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

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

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


关注七爪网,获取更多APP/小程序/网站源码资源!

相关推荐

为何越来越多的编程语言使用JSON(为什么编程)

JSON是JavascriptObjectNotation的缩写,意思是Javascript对象表示法,是一种易于人类阅读和对编程友好的文本数据传递方法,是JavaScript语言规范定义的一个子...

何时在数据库中使用 JSON(数据库用json格式存储)

在本文中,您将了解何时应考虑将JSON数据类型添加到表中以及何时应避免使用它们。每天?分享?最新?软件?开发?,Devops,敏捷?,测试?以及?项目?管理?最新?,最热门?的?文章?,每天?花?...

MySQL 从零开始:05 数据类型(mysql数据类型有哪些,并举例)

前面的讲解中已经接触到了表的创建,表的创建是对字段的声明,比如:上述语句声明了字段的名称、类型、所占空间、默认值和是否可以为空等信息。其中的int、varchar、char和decimal都...

JSON对象花样进阶(json格式对象)

一、引言在现代Web开发中,JSON(JavaScriptObjectNotation)已经成为数据交换的标准格式。无论是从前端向后端发送数据,还是从后端接收数据,JSON都是不可或缺的一部分。...

深入理解 JSON 和 Form-data(json和formdata提交区别)

在讨论现代网络开发与API设计的语境下,理解客户端和服务器间如何有效且可靠地交换数据变得尤为关键。这里,特别值得关注的是两种主流数据格式:...

JSON 语法(json 语法 priority)

JSON语法是JavaScript语法的子集。JSON语法规则JSON语法是JavaScript对象表示法语法的子集。数据在名称/值对中数据由逗号分隔花括号保存对象方括号保存数组JS...

JSON语法详解(json的语法规则)

JSON语法规则JSON语法是JavaScript对象表示法语法的子集。数据在名称/值对中数据由逗号分隔大括号保存对象中括号保存数组注意:json的key是字符串,且必须是双引号,不能是单引号...

MySQL JSON数据类型操作(mysql的json)

概述mysql自5.7.8版本开始,就支持了json结构的数据存储和查询,这表明了mysql也在不断的学习和增加nosql数据库的有点。但mysql毕竟是关系型数据库,在处理json这种非结构化的数据...

JSON的数据模式(json数据格式示例)

像XML模式一样,JSON数据格式也有Schema,这是一个基于JSON格式的规范。JSON模式也以JSON格式编写。它用于验证JSON数据。JSON模式示例以下代码显示了基本的JSON模式。{"...

前端学习——JSON格式详解(后端json格式)

JSON(JavaScriptObjectNotation)是一种轻量级的数据交换格式。易于人阅读和编写。同时也易于机器解析和生成。它基于JavaScriptProgrammingLa...

什么是 JSON:详解 JSON 及其优势(什么叫json)

现在程序员还有谁不知道JSON吗?无论对于前端还是后端,JSON都是一种常见的数据格式。那么JSON到底是什么呢?JSON的定义...

PostgreSQL JSON 类型:处理结构化数据

PostgreSQL提供JSON类型,以存储结构化数据。JSON是一种开放的数据格式,可用于存储各种类型的值。什么是JSON类型?JSON类型表示JSON(JavaScriptO...

JavaScript:JSON、三种包装类(javascript 包)

JOSN:我们希望可以将一个对象在不同的语言中进行传递,以达到通信的目的,最佳方式就是将一个对象转换为字符串的形式JSON(JavaScriptObjectNotation)-JS的对象表示法...

Python数据分析 只要1分钟 教你玩转JSON 全程干货

Json简介:Json,全名JavaScriptObjectNotation,JSON(JavaScriptObjectNotation(记号、标记))是一种轻量级的数据交换格式。它基于J...

比较一下JSON与XML两种数据格式?(json和xml哪个好)

JSON(JavaScriptObjectNotation)和XML(eXtensibleMarkupLanguage)是在日常开发中比较常用的两种数据格式,它们主要的作用就是用来进行数据的传...

取消回复欢迎 发表评论:

请填写验证码