惯性聚合 高效追踪和阅读你感兴趣的博客、新闻、科技资讯
阅读原文 在惯性聚合中打开

推荐订阅源

GbyAI
GbyAI
奇客Solidot–传递最新科技情报
奇客Solidot–传递最新科技情报
Blog — PlanetScale
Blog — PlanetScale
PCI Perspectives
PCI Perspectives
K
Kaspersky official blog
T
Tenable Blog
Help Net Security
Help Net Security
Vercel News
Vercel News
Threat Intelligence Blog | Flashpoint
Threat Intelligence Blog | Flashpoint
F
Fortinet All Blogs
罗磊的独立博客
P
Palo Alto Networks Blog
爱范儿
爱范儿
Google DeepMind News
Google DeepMind News
T
Threat Research - Cisco Blogs
Security Archives - TechRepublic
Security Archives - TechRepublic
Cyber Security Advisories - MS-ISAC
Cyber Security Advisories - MS-ISAC
人人都是产品经理
人人都是产品经理
L
LangChain Blog
Recent Announcements
Recent Announcements
有赞技术团队
有赞技术团队
博客园_首页
D
Darknet – Hacking Tools, Hacker News & Cyber Security
H
Help Net Security
S
Secure Thoughts
freeCodeCamp Programming Tutorials: Python, JavaScript, Git & More
Project Zero
Project Zero
Exploit-DB.com RSS Feed
Exploit-DB.com RSS Feed
V
V2EX
Last Week in AI
Last Week in AI
H
Heimdal Security Blog
U
Unit 42
Y
Y Combinator Blog
The GitHub Blog
The GitHub Blog
SecWiki News
SecWiki News
量子位
博客园 - 【当耐特】
Martin Fowler
Martin Fowler
NISL@THU
NISL@THU
S
Securelist
P
Proofpoint News Feed
宝玉的分享
宝玉的分享
T
Tailwind CSS Blog
云风的 BLOG
云风的 BLOG
I
Intezer
CTFtime.org: upcoming CTF events
CTFtime.org: upcoming CTF events
博客园 - Franky
Cisco Talos Blog
Cisco Talos Blog
小众软件
小众软件
C
CXSECURITY Database RSS Feed - CXSecurity.com

元视角

.NET 生态下的 Agent 框架选型:从 ReAct 到原生推理 - 元视角 从「能用」到「好用」:LLM 流式响应实现方式的探索之路 - 元视角 当我用 2000 条聊天记录,让 AI 为我画一幅自画像 - 元视角 基于 Supabase 的 AI 应用开发探索 - 元视角 微博 × MCP:社交媒体新玩法解锁 - 元视角 四点钟海棠花未眠 - 元视角 Semantic Kernel × MCP:智能体的上下文增强探索 - 元视角 基于 K-Means 聚类分析实现人脸照片的快速分类 - 元视角 容器技术驱动下的代码沙箱实践与思考 - 元视角 温故而知新:后端通用查询方案的再思考 - 元视角 浅议 CancellationToken 在前后端协同取消场景中的应用 - 元视角 Semantic Kernel 视角下的 Text2SQL 实践与思考 - 元视角 关于 ChatGPT 的流式传输,你需要知道的一切 - 元视角 RAG 的是与非、Rewrite 和 Rerank - 元视角 使用 EFCore 和 PostgreSQL 实现向量存储及检索 - 元视角 基于 LLaMA 和 LangChain 实践本地 AI 知识库 - 元视角 使用 llama.cpp 在本地部署 AI 大模型的一次尝试 - 元视角 如何为 Git 配置多个 SSH Key - 元视角 C# 使用 LibUsbDotNet 实现 USB 设备检测 - 元视角 基于 C# 实现样式与数据分离的打印方案 - 元视角 基于 SVG 的图形交互方案实践 - 元视角 前端视频播放技术概览 - 元视角 温故而知新,再话 Python 动态导入 - 元视角 后 GPT 时代,NLP 不存在了? - 元视角 视频是不能 P 的系列:使用 Milvus 实现海量人脸快速检索 - 元视角 GDI+下字体大小自适应方案初探 - 元视角 小爱音箱集成 ChatGPT 的不完全教程 - 元视角 程序员视角下的三体世界随想 - 元视角 关于 Docker 容器配置信息的渐进式思考 - 元视角 在 Docker 容器内集成 Crontab 定时任务 - 元视角 为你的服务器集成 LDAP 认证 - 元视角 似花还似非花 - 元视角 视频是不能 P 的系列:使用 Dlib 实现人脸识别 - 元视角 浅议分布式链路追踪与日志的整合 - 元视角 关于 Git 大文件上传这件小事 - 元视角 .NET 进程内队列 Channel 的入门与应用 - 元视角 使用 Fody 实现 .NET 的静态编织 - 元视角 .NET Core + ELK 搭建可视化日志分析平台(下) - 元视角 聊一聊前端图片懒加载背后的故事 - 元视角 支持外部链接跳转的 Vue Router 扩展实现 - 元视角 视频是不能 P 的系列:OpenCV 和 Dlib 实现表情包 - 元视角 不得不说的 ASP.NET Core 集成测试 - 元视角 再议 DDD 视角下的 EFCore 与 领域事件 - 元视角 Vue.js 前端项目容器化部署实践极简教程 - 元视角 再见,人间四月天 - 元视角 Python 图像风格化迁移助力画家梦想 - 元视角 利用 ASP.NET Core 中的标头传播实现分布式链路追踪 - 元视角 利用 gRPC 实现文件的上传与下载 - 元视角 七种武器:延迟队列的原理和实现总结 - 元视角 gRPC 流式传输极简入门指南 - 元视角 Envoy 集成 Jaeger 实现分布式链路追踪 - 元视角 浅议非典型 Web 应用场景下的身份认证 - 元视角 gRPC 借助 Any 类型实现接口的泛化调用 - 元视角 分布式丛林探险系列之 Redis 集群模式 - 元视角 分布式丛林探险系列之 Redis 主从复制模式 - 元视角 通过 Python 预测 2021 年双十一交易额 - 元视角 gRPC 搭配 Swagger 实现微服务文档化 - 元视角 SSL/TLS 加密传输与数字证书的前世今生 - 元视角 使用 Python 自动识别防疫健康码 - 元视角 你不可不知的容器编排进阶技巧 - 元视角 ASP.NET Core 搭载 Envoy 实现 gRPC 服务代理 - 元视角 再话 AOP,从简化缓存操作说起 - 元视角 ASP.NET Core 搭载 Envoy 实现微服务身份认证(JWT) - 元视角 ASP.NET Core 搭载 Envoy 实现微服务的监控预警 - 元视角 ASP.NET Core 搭载 Envoy 实现微服务的反向代理 - 元视角 ASP.NET Core gRPC 打通前端世界的尝试 - 元视角 EFCore 实体命名约定库:EFCore.NamingConventions - 元视角 ASP.NET Core gRPC 集成 Polly 实现优雅重试 - 元视角 ASP.NET Core gRPC 健康检查的探索与实现 - 元视角 ASP.NET Core gRPC 拦截器的使用技巧分享 - 元视角 SnowNLP 使用自定义语料进行模型训练 - 元视角 使用 HttpMessageHandler 实现 HttpClient 请求管道自定义 - 元视角 ABP vNext 的实体与服务扩展技巧分享 - 元视角 ABP vNext 对接 Ant Design Vue 实现分页查询 - 元视角 源代码探案系列之 .NET Core 跨域中间件 CORS - 元视角 源代码探案系列之 .NET Core 限流中间件 AspNetCoreRateLimit - 元视角 源代码探案系列之 .NET Core 并发限制中间件 ConcurrencyLimiter - 元视角 通过 EmbededFileProvider 实现 Blazor 的静态文件访问 - 元视角 低代码,想说爱你不容易 - 元视角 记一次失败的 ThoughtWorks 面试经历 - 元视角 从 C# 1.0 到 C# 9.0,历代 C# 语言特性一览 - 元视角 通过 Python 分析 2020 年全年微博热搜数据 - 元视角 基于 Python 和 Selenium 实现 CSDN 一键三连自动化 - 元视角 使用多线程为你的 Python 爬虫提速的 N 种姿势,你会几种? - 元视角 实现网页长截图的常见思路总结 - 元视角 温故而知新,由 ADO.NET 与 Dapper 所联想到的 - 元视角 视频是不能 P 的系列:OpenCV 人脸检测 - 元视角 作为技术宅的我,是这样追鬼滅の刃的 - 元视角 使用 Python 抽取《半泽直树》原著小说人物关系 - 元视角 厉害了!打工人用 Python 分析西安市职位信息 - 元视角 使用 dotTrace 对 .NET 应用进行性能分析与优化 - 元视角 一道 HashSet 面试题引发的蝴蝶效应 - 元视角 基于选项模式实现.NET Core 的配置热更新 - 元视角 Dapper.Contrib 在 Oracle 环境下引发 ORA-00928 异常问题的解决 - 元视角 .NET Core 中对象池(Object Pool)的使用 - 元视角 利用 MySQL 的 Binlog 实现数据同步与订阅(下):EventBus 篇 - 元视角 利用 MySQL 的 Binlog 实现数据同步与订阅(中):RabbitMQ 篇 - 元视角 利用 MySQL 的 Binlog 实现数据同步与订阅(上):基础篇 - 元视角 记一次从已损坏的 Git 仓库中找回代码的经历 - 元视角 .NET Core 原生 DI 扩展之属性注入实现 - 元视角
HTML5 游戏开发技术基础整理 - 元视角
飞鸿踏雪 · 2015-03-09 · via 元视角

随着 HTML5 标准最终敲定,HTML5 将有望成为游戏开发领域的的热门平台。HTML5 游戏能够运行于包括 iPhone 系列和 iPad 系列在内的计算机、智能手机以及平板电脑上,是目前跨平台应用开发的最佳实施方案。本文系根据 《HML5 Canvas 游戏开发实战》 一书中的内容整理而成,是了解和学习 HTML5 游戏开发的基础内容,希望能够帮助到那些和博主一样致力于游戏开发的朋友们!

JavaScript 中的面向对象编程

对于游戏开发来说,面向对象编程(OOP)是一种重要而且必要的方法,所以在了解 HTML5 游戏开发前,首先应该了解 JavaScript 中的面向对象编程。JavaScript 是一种基于对象的语言,可它并不是一种真正的面向对象的编程语言,因为在 JavaScript 的语法中不存在类(Class)的概念。下面我们将分析和解决在 JavaScript 中实现封装、继承等面向对象的问题。

在 JavaScript 中函数(function)就是就是一个类(class)

//声明一个函数
function MyClass(){}
//实例化一个对象
var cls1 = new MyClass();

使用 this 关键字就可以为类增加属性

//声明一个类并定义其构造函数
function MyClass(name,age)
{
    this.name = name;
    this.age  = age;
};
//实例化一个对象
var cls1 = new MyClass("张三",20)
//输出cls1的两个属性值
alert("name=" + cls1.name + "&" + cls1.age)

使用 prototype 属性可以为类添加方法

//声明一个类并定义其构造函数
function MyClass(name,age)
{
    this.name = name;
    this.age  = age;
};
//为MyClass增加方法
MyClass.prototype=
{
    toString:function()
    {
        alert("name=" + this.name + "&" + this.age)
    },
    getName:function()
    {
        alert("name=" + this.name)
    },
    getAge:function()
    {
        alert("age=" + this.age)
    }
};

使用 apply 方法实现属性和方法的继承

//定义一个父类People
function People()
{
    this.type="人"
};
//为父类定义一个方法
People.prototype=
{
    getType:function()
    {
        alert("type=" + this.type)
    }
};

//定义一个子类Student
function Student(name,age,sex)
{
   //继承父类的属性type
   People.apply(this,arguments);
   this.name = name;
   this.age = age;
   this.sex = sex;
};

//声明一个Student实例
var stu = new Student("张三",20,"男")
//输出type
alert(stu.type)

//下面我们来了解下如何继承父类的方法,继承父类方法主要通过循环使用父对象的prototype进行复制来实现,如
//重新定义子类Student
function Student(name,age,sex)
{
    //继承父类的属性type
   People.apply(this,arguments);
   //继承父类的方法,略显抽象
   var prop;
   for(prop in People.prototype)
   {
        var proto = this.constructor.prototype;
        if(!proto[prop])
        {
            proto[prop] = People.prototype[prop];
        }
        proto[prop]["super"] = People.prototype;
   }
   //属性定义
   this.name = name;
   this.age = age;
   this.sex = sex;
};

//实例化Student对象
var stu = new Student("张三",20,"男");
stu.getType();

静态类的实现

function staticClass()
{
    staticClass.name = "张三";
    staticClass.toString=function
    {
        alert("name=" + staticClass.name )
    };
};

alert(staticClass.name);
staticClass.toString();

Canvas 绘图基础

HTML5 提供了图像、视频、音频、表单、位置、本地数据库、离线存储、websocket 等各种全新的特性,对于 HTML 游戏开发而言,我们主要关注图像、音频、本地数据库以及 websocket 等,首先我们来了解下 Canavs 绘图的基础内容。

Canvas 是 HTML5 为我们提供的一张画布,可以让我们在 HTML 上直接绘制图形,因此 Canvas 可以作为 HTML5 游戏开发的基本元素,即 HTML5 游戏引擎的底层都是以 Canvas 元素来驱动的。Canvas 本身没有绘图的能力,需要借助于 JavaScript 来实现绘图的功能。使用 Canvas 元素只需要在网页中添加 canvas 标记即可,如

<canvas id="myCanavs" width="800" height="480"></canvas>

接下来我们通过 JavaScript 来获取这个 Canvas 并通过相关 API 实现绘图环境的初始化

//获取Canvas元素
var canvas = document.getElementById('myCanvas');
//检查canvas合法性
if(canvas && canvas.getContext)
{
    //获取当前上下文
    var ctx = canvas.getContext('2d')    
}

因为目前 Canvas 只支持 2D 绘图,因此,这里的参数暂时只能为 2d。因为 Cnavas 绘图的 API 都封装在 ctx 这个实例中,因此下面的所有操作都是基于 ctx 来实现的:

使用 Canvas 绘制线

//设置线宽
ctx.lineWidth = 10;
//设置画笔颜色
ctx.strokeStyle = "red";
//创建一个路径
ctx.beginPath();
//路径起点
ctx.moveTo(10,10);
//路径终点
ctx.lineTo(150,50);
//绘制路径
ctx.stroke();

使用 Cnavas 绘制矩形

//设置线宽
ctx.lineWidth=5;
//设置画笔颜色
ctx.strokeStyle-"red"
//创建路径
ctx.beginPath();
//绘制矩形
ctx.strokeRect(10,10,70,40);

或者

//定义矩形
ctx.rect(10,10,70,40);
//绘制矩形
ctx.stroke();

如果需要对矩形进行填充

//创建路径
ctx.beginPath()
//绘制矩形
ctx.fillRect(10,10,70,40)

使用 Canvas 绘制圆

//创建路径
ctx.beginPath();
//定义圆
ctx.arc(100,100,50,0,360*Math.PI/180,true);
//绘制圆
ctx.stroke();

同样地,可以使用 fill 进行填充绘制

//创建路径
ctx.beginPath();
//定义圆
ctx.arc(100,100,50,0,360*Math.PI/180,true);
//绘制圆
ctx.fill();

使用 Canvas 绘制圆角矩形

绘制圆角矩形需要 arcTo 函数配合 lineTo 来完成

//创建路径
ctx.beginPath();
ctx.moveTo(40,20);
ctx.lineTo(100,20);
ctx.arcTo(100,20,120,40,20);
ctx.lineTo(120,70);
ctx.arcTo(120,90,100,90,20);
ctx.lineTo(40,90);
ctx.arcTo(20,90,100,70,20);
ctx.lineTo(20,40);
ctx.arcTo(20,20,40,20,20);
//绘制圆角矩形
ctx.stroke();

使用 Canvas 绘制复杂图形

在 HTML5 中可以通过 quadraticCurveTo 函数绘制二次贝塞尔曲线,通过 bezierCurveTo 函数绘制三次贝塞尔曲线,具体代码请参考 API 文档。

使用 Canvas 绘制文字

//设置字体
ctx.font="30px Arial";
//绘制文字
ctx.strokeText("Hello HTML5",100,50);

使用 Canvas 绘制图片

绘制图片使用 drawImage 函数,其函数原型如下:

其中 image 可以是 HTML 中的标签或者是 JavaScript 中的 Image 对象。如

//定义一个img标签
<img id="img_source" src="source.jpg" width="240" height="240"/>

接下来通过 getElementById 来取得图像数据,并将其绘制出来

var img=document.getElementById("img_source");
ctx.draw(img,200,200);

如果直接使用 JavaScript 代码

var img=new Image();
img.src="source.jpg";
ctx.draw(img,200,200)

图形的平移操作

使用 translate 函数实现在水平和垂直方向上的平移

图形的旋转操作

使用 rotate 函数实现旋转,需要注意的是传入的参数是弧度

图形的伸缩操作

使用 scale 函数实现伸缩,当参数为负值时表示在该方向上翻转

图形高级特效

这里主要介绍线性渐变、径向渐变、颜色反转、灰度。

  • 线性渐变
//创建一个线性渐变容器
var grd=ctx.createLinearGradient(0,0,200,0);
//添加颜色
grd.addColorStop(0.2,"#00ff00");
grd.addColorStop(0.8,"#ff0000");
//应用渐变
ctx.fillStyle=grd;
  • 径向渐变
//创建一个径向渐变容器
var grd=ctx.createRadialGradient(100,100,10,100,100,50);
//添加颜色
grd.addColorStop(0,"#00ff00");
grd.addColorStop(,"#ff0000");
//应用渐变
ctx.fillStyle=grd;
  • 颜色反转 遍历每个像素并对 RGB 值进行取反
  • 灰度 灰度计算公式:gary = red * 0.3 + green * 0.59 + blue * 0.11

基础的内容就是这些了,以后如果碰到需要 HTML5 的地方可以回过头来看看。