文档章节

HTML5 snake

我们取个名字叫珍惜
 我们取个名字叫珍惜
发布于 2016/11/10 20:40
字数 575
阅读 5
收藏 0

!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">

<html xmlns="http://www.w3.org/1999/xhtml">

<head>

<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />

<title>无标题文档</title>

<style type="text/css">

html,

body {

    height: 100%;

}

body {

    background: radial-gradient(#222, #000);

}

canvas {

    display: block;

}

</style>

</head>

 

<body>

<canvas id="c"></canvas>

</body>

<script type="text/javascript">

 

/* click to the atrract the snake bugs */

 

var a = document.getElementById('c'),

    c = a.getContext('2d');

 

var chains = [],

    chainCount = 30,

    entityCount = 10,

    w = a.width,

    h = a.height,

    cx = w / 2,

    cy = h / 2,

    mx = cx,

    my = cy,

    md = 0,

    tick = 0,

    maxa = 2,

    maxv = 1,

    avoidTick = 20,

    avoidThresh = 50,

    TWO_PI = Math.PI * 2;

 

function rand(min, max) {

    return Math.random() * (max - min) + min;

}

 

function Impulse() {

    this.x = cx;

    this.y = cy;

    this.ax = 0;

    this.ay = 0;

    this.vx = 0;

    this.vy = 0;

    this.r = 1;

}

 

Impulse.prototype.step = function() {

    this.x += this.vx;

    this.y += this.vy;

    if (this.x + this.r >= w || this.x <= this.r) {

        this.vx = 0;

        this.ax = 0;

    }

    if (this.y + this.r >= h || this.y <= this.r) {

        this.vy = 0;

        this.ay = 0;

    }

    if (this.x + this.r >= w) {

        this.x = w - this.r;

    }

    if (this.x <= this.r) {

        this.x = this.r;

    }

    if (this.y + this.r >= h) {

        this.y = h - this.r;

    }

    if (this.y <= this.r) {

        this.y = this.r;

    }

 

    if (md) {

        this.vx += (mx - this.x) * 0.03;

        this.vy += (my - this.y) * 0.03;

    }

 

    this.ax += rand(-0.4, 0.4);

    this.ay += rand(-0.4, 0.4);

    this.vx += this.ax;

    this.vy += this.ay;

    this.ax *= Math.abs(this.ax) > maxa ? 0.75 : 1;

    this.ay *= Math.abs(this.ay) > maxa ? 0.75 : 1;

    this.vx *= Math.abs(this.vx) > maxv ? 0.75 : 1;

    this.vy *= Math.abs(this.vy) > maxv ? 0.75 : 1;

};

 

function Chain() {

    this.branches = [];

    this.impulse = new Impulse();

    this.branches.push(new Branch({

        chain: this,

        attractor: this.impulse

    }));

}

 

Chain.prototype.step = function() {

    this.impulse.step();

    this.branches.forEach(function(branch, i) {

        branch.step();

    });

 

    this.branches.forEach(function(branch, i) {

        branch.draw();

    });

};

 

function Branch(opt) {

    this.entities = [];

    this.chain = opt.chain;

    this.avoiding = 0;

    var entity;

    for (var i = 0; i < entityCount; i++) {

        entity = new Entity({

            branch: this,

            i: i,

            x: cx,

            y: cy,

            radius: 1 + (entityCount - i) / entityCount * 5,

            damp: 0.2,

            attractor: i === 0 ? opt.attractor : this.entities[i - 1]

        });

        this.entities.push(entity);

    }

}

 

Branch.prototype.step = function() {

    var i = chains.length;

    while (i--) {

        var impulse = this.chain.impulse,

            oImpulse = chains[i].impulse,

            dx = oImpulse.x - impulse.x,

            dy = oImpulse.y - impulse.y,

            dist = Math.sqrt(dx * dx + dy * dy);

        if (!md && impulse !== oImpulse && dist < avoidThresh) {

            impulse.ax = 0;

            impulse.ay = 0;

            impulse.vx -= dx * 0.2;

            impulse.vy -= dy * 0.2;

            this.avoiding = avoidTick;

        }

    }

 

    this.entities.forEach(function(entity, i) {

        entity.step();

    });

 

    if (this.avoiding > 0) {

        this.avoiding--;

    }

};

 

Branch.prototype.draw = function() {

    var self = this;

    c.beginPath();

    c.moveTo(this.entities[0].x, this.entities[0].y);

    this.entities.forEach(function(entity, i) {

        if (i > 0) {

            c.lineTo(entity.x, entity.y);

        }

    });

    c.strokeStyle = 'hsla(' + (md ? 120 : (self.avoiding ? 0 : 200)) + ', 70%, 60%, 0.3)';

    c.stroke();

 

    this.entities.forEach(function(entity, i) {

        c.save();

        c.translate(entity.x, entity.y);

        c.beginPath();

        c.rotate(entity.rot);

        if (entity.i === 0) {

            c.fillStyle = (md ? '#6c6' : (self.avoiding ? '#c66' : '#6bf'));

        } else {

            c.fillStyle = 'hsla(' + (md ? 120 : (self.avoiding ? 0 : 200)) + ', 70%, ' + Math.min(50, (5 + ((entity.av / maxv) * 20))) + '%, ' + (((entityCount - i) / entityCount)) + ')';

        }

        c.fillRect(-entity.radius, -entity.radius, entity.radius * 2, entity.radius * 2);

        c.restore();

    });

 

};

 

function Entity(opt) {

    this.branch = opt.branch;

    this.i = opt.i;

    this.x = opt.x;

    this.y = opt.y;

    this.vx = 0;

    this.vy = 0;

    this.radius = opt.radius;

    this.attractor = opt.attractor;

    this.damp = opt.damp;

}

 

Entity.prototype.step = function() {

    this.vx = (this.attractor.x - this.x) * this.damp;

    this.vy = (this.attractor.y - this.y) * this.damp;

    this.x += this.vx;

    this.y += this.vy;

    this.av = (Math.abs(this.vx) + Math.abs(this.vy)) / 2;

 

    var dx = this.attractor.x - this.x,

        dy = this.attractor.y - this.y;

    this.rot = Math.atan2(dy, dx);

};

 

function loop() {

    requestAnimationFrame(loop);

 

    c.globalCompositeOperation = 'destination-out';

    c.fillStyle = 'rgba(0, 0, 0, 1)';

    c.fillRect(0, 0, a.width, a.height);

    c.globalCompositeOperation = 'lighter';

 

    chains.forEach(function(chain, i) {

        chain.step();

    });

 

    tick++;

}

 

function resize() {

    a.width = window.innerWidth;

    a.height = window.innerHeight;

    w = a.width;

    h = a.height;

    cx = w / 2;

    cy = h / 2;

}

 

window.addEventListener('resize', resize);

 

window.addEventListener('mousedown', function() {

    md = 1;

});

 

window.addEventListener('mouseup', function() {

    md = 0;

});

 

window.addEventListener('mousemove', function(e) {

    mx = e.clientX;

    my = e.clientY;

});

 

resize();

 

for (var i = 0; i < chainCount; i++) {

    chains.push(new Chain());

}

 

loop();

reset();

 

 

 

</script>

 

 

</html>

 

© 著作权归作者所有

上一篇: HTML5 重力球
下一篇: HTML5 面试总结
我们取个名字叫珍惜
粉丝 4
博文 48
码字总数 19405
作品 0
嘉兴
程序员
私信 提问
再来 10 个新鲜的 HTML5 教程

HTML5 火吗?看看 oschina 三天两头的 xx 个 xxx 就知道了。本文为你推荐最新的 10 个 HTML5 相关的教程,或许能启发你项目中的思路。 1. HTML5 canvas – Creating own Paint program Canva...

红薯
2011/11/15
3.9K
4
30 个必须看的 HTML 5 教程

HTML5 和 CSS3 拓展了Web 设计的可能性。有很多大量的设计师和开发者在web设计中开始学习并使用HTML 5。 这次我们推荐的30个有用的HTML 5 教程,相信会帮助开发者提升技能。列表如下: Maki...

小卒过河
2011/07/29
15.9K
7
史无前例的 HTML5 资源参考指南

尽管 HTML5 规范在 2014 年之前不会有正式版本,很多设计师已经开始试水高级浏览器已经支持的部分 HTML5 功能。HTML5 为 Web 设计和应用开发打开了一扇全新的门,原生支持了以前只可能使用 ...

李长春
2012/03/02
641
1
再来 35 个响应式 HTML5 和 CSS3 模版

免费响应式模版 FlexApp Demo || Download zGallering – Free Responsive Html5 Theme Demo || Download Responsive HTML5/CSS3 template Demo || Download VividPhoto HTML5 and CSS3 Tem......

oschina
2013/07/09
6.1K
7
好程序员HTML5大前端常用开发工具大集合

HTML5作为当前最为流行的编程语言,广为适用。语言的使用人数急剧增长,更多地开发人员使用这种语言来创建各种内容并放到互联网上。随着每一个新版本的发布,HTML通过更好的功能和技术渐渐占...

好程序员IT
06/12
68
0

没有更多内容

加载失败,请刷新页面

加载更多

OpenStack 简介和几种安装方式总结

OpenStack :是一个由NASA和Rackspace合作研发并发起的,以Apache许可证授权的自由软件和开放源代码项目。项目目标是提供实施简单、可大规模扩展、丰富、标准统一的云计算管理平台。OpenSta...

小海bug
昨天
5
0
DDD(五)

1、引言 之前学习了解了DDD中实体这一概念,那么接下来需要了解的就是值对象、唯一标识。值对象,值就是数字1、2、3,字符串“1”,“2”,“3”,值时对象的特征,对象是一个事物的具体描述...

MrYuZixian
昨天
6
0
数据库中间件MyCat

什么是MyCat? 查看官网的介绍是这样说的 一个彻底开源的,面向企业应用开发的大数据库集群 支持事务、ACID、可以替代MySQL的加强版数据库 一个可以视为MySQL集群的企业级数据库,用来替代昂贵...

沉浮_
昨天
4
0
解决Mac下VSCode打开zsh乱码

1.乱码问题 iTerm2终端使用Zsh,并且配置Zsh主题,该主题主题需要安装字体来支持箭头效果,在iTerm2中设置这个字体,但是VSCode里这个箭头还是显示乱码。 iTerm2展示如下: VSCode展示如下: 2...

HelloDeveloper
昨天
7
0
常用物流快递单号查询接口种类及对接方法

目前快递查询接口有两种方式可以对接,一是和顺丰、圆通、中通、天天、韵达、德邦这些快递公司一一对接接口,二是和快递鸟这样第三方集成接口一次性对接多家常用快递。第一种耗费时间长,但是...

程序的小猿
昨天
8
0

没有更多内容

加载失败,请刷新页面

加载更多

返回顶部
顶部