JavaScript

语言:

JaveScriptBabelCoffeeScript

确定

const Util = {};

Util.timeStamp = function() {

return window.performance.now();

};

Util.random = function(min, max) {

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

};

Util.randomArray = function(array) {

return array[Math.floor(Math.random() * array.length)];

};

Util.map = function(a, b, c, d, e) {

a = this.clamp(a, b, c);

return (a - b) / (c - b) * (e - d) + d;

};

Util.lerp = function(value1, value2, amount) {

return value1 + (value2 - value1) * amount;

};

Util.clamp = function(value, min, max) {

return Math.max(min, Math.min(max, value));

};

Util.threeAngle = function(p0, p1, p2) {

var b = Math.pow(p1.x - p0.x, 2) + Math.pow(p1.y - p0.y, 2),

a = Math.pow(p1.x - p2.x, 2) + Math.pow(p1.y - p2.y, 2),

c = Math.pow(p2.x - p0.x, 2) + Math.pow(p2.y - p0.y, 2);

return Math.acos((a + b - c) / Math.sqrt(4 * a * b));

}

Util.hsl = function(hue, saturation, lightness) {

return `hsl(${hue},${saturation}%,${lightness}%)`;

}

class Vector {

constructor(x, y) {

this.x = x || 0;

this.y = y || 0;

}

set(x, y) {

this.x = x;

this.y = y;

}

reset() {

this.x = 0;

this.y = 0;

}

fromAngle(angle) {

let x = Math.cos(angle),

y = Math.sin(angle);

return new Vector(x, y);

}

add(vector) {

this.x += vector.x;

this.y += vector.y;

}

sub(vector) {

this.x -= vector.x;

this.y -= vector.y;

}

mult(scalar) {

this.x *= scalar;

this.y *= scalar;

}

div(scalar) {

this.x /= scalar;

this.y /= scalar;

}

dot(vector) {

return vector.x * this.x + vector.y * this.y;

}

limit(limit_value) {

if (this.mag() > limit_value) this.setMag(limit_value);

}

mag() {

return Math.hypot(this.x, this.y);

}

setMag(new_mag) {

if (this.mag() > 0) {

this.normalize();

} else {

this.x = 1;

this.y = 0;

}

this.mult(new_mag);

}

normalize() {

let mag = this.mag();

if (mag > 0) {

this.x /= mag;

this.y /= mag;

}

}

normalizedMag() {

let copy = this.copy();

copy.normalize();

return copy.mag();

}

heading() {

return Math.atan2(this.y, this.x);

}

setHeading(angle) {

let mag = this.mag();

this.x = Math.cos(angle) * mag;

this.y = Math.sin(angle) * mag;

}

dist(vector) {

return new Vector(this.x - vector.x, this.y - vector.y).mag();

}

angle(vector) {

return Math.atan2(vector.y - this.y, vector.x - this.x);

}

copy() {

return new Vector(this.x, this.y);

}

}

class Tagada {

constructor() {

this.canvas = document.createElement("canvas");

this.ctx = this.canvas.getContext('2d');

document.body.appendChild(this.canvas);

this.W = 0;

this.H = 0;

this.ressources = {

images: [],

audio: [],

}

this.backgroundColor = "gray";

this.timeData = {

now: 0,

dt: 0,

last: Util.timeStamp(),

step: 1 / 60,

};

this.frame = 0;

window.addEventListener("resize", () => {

this.setSize();

this.resize();

});

this.mouse = new Vector(0, 0);

window.addEventListener("pointermove", (event) => {

this.pMove(event);

});

}

addImage(path) {

let image = new Image();

image.src = path;

this.ressources.images.push(image);

return image;

}

drawImageCover(image, x, y, sizeX, sizeY) {

if (sizeX <= 0 || sizeY <= 0) return false;

let scaleX,

scaleY,

ratio = image.width / image.height;

let sourceScaleX, sourceScaleY;

let cRation = sizeX / sizeY;

if (cRation > ratio) {

scaleX = sizeX;

scaleY = scaleX / ratio;

sourceScaleX = image.width;

sourceScaleY = sourceScaleX / cRation;

} else {

scaleY = sizeY;

scaleX = scaleY * ratio;

sourceScaleY = image.height;

sourceScaleX = sourceScaleY * cRation;

}

let offsetX = (sizeX - scaleX);

let offsetY = (sizeY - scaleY);

this.ctx.drawImage(

image, (image.width - sourceScaleX) / 2, (image.height - sourceScaleY) / 2, sourceScaleX, sourceScaleY,

x, y, scaleX + offsetX, scaleY + offsetY

);

}

run() {

Promise.all(

this.ressources.images.map(image => {

return new Promise(resolve => {

image.onload = () => {

resolve();

}

});

})

).then(v => {

this.setSize();

this.loop();

});

}

resize() {

}

pMove(event) {

this.mouse.x = event.clientX - this.canvas.offsetLeft;

this.mouse.y = event.clientY - this.canvas.offsetTop;

}

setSize() {

this.W = this.canvas.width = window.innerWidth;

this.H = this.canvas.height = window.innerHeight;

}

update(dt) {

}

render() {

}

loop() {

this.ctx.fillStyle = this.backgroundColor;

this.ctx.fillRect(0, 0, this.W, this.H);

this.timeData.now = Util.timeStamp();

this.timeData.dt = this.timeData.dt + Math.min(1, (this.timeData.now - this.timeData.last) / 1000);

while (this.timeData.dt > this.timeData.step) {

this.timeData.dt = this.timeData.dt - this.timeData.step;

this.update(this.timeData.step);

}

this.render();

this.timeData.last = this.timeData.now;

this.frame += 1;

requestAnimationFrame(() => {

this.loop()

});

}

}

let app = new Tagada();

let shapes = [];

let $ = app.ctx;

let minSize = 0;

class Particle {

constructor(container, x, y, size) {

this.container = container;

this.position = new Vector(x, y);

this.velocity = new Vector(0, 0);

this.acceleration = new Vector(0, 0);

this.size = size;

this.maxSpeed = Util.random(100, 1000);

this.start = new Date();

this.duration = Util.random(200, 2000);

this.spinOffset = Util.random(0.001, 0.4);

this.gravity = new Vector(0, 10);

this.colors = ["#fff83a", "#ffffff"];

}

draw() {

let time = new Date() - this.start;

if (time > this.duration) {

// delete particle

let id = this.container.indexOf(this);

this.container.splice(id, 1);

}

let sizeOffset = Util.map(time, 0, this.duration, 1, 0);

$.fillStyle = this.colors[Math.floor(Util.map(Math.sin(app.frame * this.spinOffset), -1, 1, 0, this.colors.length))];

$.beginPath();

$.ellipse(this.position.x, this.position.y, this.size * sizeOffset * Math.abs(Math.sin(app.frame * this.spinOffset)), this.size * sizeOffset, this.velocity.heading(), 0, Math.PI * 2);

$.fill();

}

addForce(force) {

this.acceleration.add(force);

}

update(dt) {

this.addForce(this.gravity);

this.velocity.add(this.acceleration);

this.velocity.limit(this.maxSpeed);

this.velocity.mult(0.98);

let v = this.velocity.copy();

v.mult(dt);

this.position.add(v);

this.acceleration.reset();

}

}

class Bubble {

constructor(container, x, y, size) {

this.container = container;

this.position = new Vector(x, y);

this.velocity = new Vector(0, 0);

this.acceleration = new Vector(0, 0);

this.size = size;

this.displayedSize = size;

this.maxSpeed = Util.random(100, 400);

this.beatSpeed = Util.random(0.01, 0.04);

this.offset = Util.random(0.1, 100);

this.colors = ["#ff93c9", "#12e524"];

this.color = Util.randomArray(this.colors);

}

draw() {

this.displayedSize = this.size * Util.map(Math.sin(app.frame * this.beatSpeed), -1, 1, 0.96, 1.04);

let dMouse = this.position.dist(app.mouse);

$.strokeStyle = Util.hsl(0, Util.map(dMouse - this.displayedSize, 0, 200, 80, 0),

Util.map(dMouse - this.displayedSize, 0, 200, 60, 0)

);

// draw ondulation

let resolution = Math.floor(Util.map(this.size, 0, minSize, 6, 10));

let ps = [];

let globalSpeed = Util.map(this.velocity.mag(), 0, this.maxSpeed, 0.01, 1);

let globalScale = Util.map(this.velocity.mag(), 0, this.maxSpeed, 0.1, 1.2);

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

let pSize = this.displayedSize + Math.sin(this.offset +

Math.cos(i * 0.46 + app.frame * 0.02) * Math.sin(-i * 2 + app.frame * 0.02)

) * this.size * globalScale;

let a = Util.map(i, 0, resolution, 0, Math.PI * 2),

x = this.position.x + Math.cos(a) * pSize,

y = this.position.y + Math.sin(a) * pSize;

//$.fillStyle = "blue";

//$.beginPath();

//$.arc(x, y, 2, 0, Math.PI * 2);

//$.fill();

ps.push({

x: x,

y: y

});

}

smooth(ps);

}

addForce(force) {

this.acceleration.add(force);

}

update(dt) {

this.divide();

this.bound();

this.velocity.add(this.acceleration);

this.velocity.limit(this.maxSpeed);

this.velocity.mult(0.98);

let v = this.velocity.copy();

v.mult(dt);

this.position.add(v);

this.acceleration.reset();

}

bound() {

let center = new Vector(app.W / 2, app.H / 2);

let dist = this.position.dist(center);

let smallestSide = Math.min(app.W, app.H) / 2;

if (dist > smallestSide) {

let force = new Vector(0, 0).fromAngle(this.position.angle(center));

force.setMag(Util.map(dist, 0, smallestSide, 0, 10));

this.addForce(force);

}

}

divide() {

let dist = this.position.dist(app.mouse);

if (dist > this.displayedSize) return;

// shake Screen

shake(Util.map(this.size, 0, minSize, 2, 8));

// delete bubble

let id = this.container.indexOf(this);

this.container.splice(id, 1);

// add Particles

let pCount = Util.map(this.size, 0, minSize, 10, 400);

for (let i = 0; i < pCount; i++) {

let angle = Util.map(i, 0, pCount, 0, Math.PI * 2),

pX = this.position.x + Math.cos(angle) * this.size,

pY = this.position.y + Math.sin(angle) * this.size;

let p = new Particle(particles, pX, pY,

Util.map(this.size, 0, minSize, 4, 10) * Util.random(0.2, 1.2));

p.velocity = new Vector().fromAngle(angle);

p.velocity.mult(Util.random(100, 800));

particles.push(p);

}

// add new bubles if size is sufficient

if (this.size < 20) return;

let divisions = Math.floor(Util.random(2, 6)),

childSize = this.size / divisions;

for (let i = 0; i < divisions; i++) {

let angle = Util.map(i, 0, divisions, 0, Math.PI * 2),

pX = this.position.x + Math.cos(angle) * this.size / 2,

pY = this.position.y + Math.sin(angle) * this.size / 2;

let bubbleChild = new Bubble(

this.container,

pX,

pY,

childSize * Util.random(0.8, 1.8)

);

bubbleChild.velocity = new Vector().fromAngle(angle);

bubbleChild.velocity.mult(Util.random(100, 400));

this.container.push(bubbleChild);

}

}

avoid(others) {

others.forEach(other => {

if (other !== this) {

let dist = this.position.dist(other.position),

max_dist = this.size + other.size;

if (max_dist - dist >= 0) {

let angle = other.position.angle(this.position);

let force = new Vector().fromAngle(angle);

force.setMag(Util.map(dist, 0, max_dist, 1, 0));

this.addForce(force);

}

}

});

}

}

function smooth(points) {

var xc = (points[0].x + points[1].x) / 2;

var yc = (points[0].y + points[1].y) / 2;

$.moveTo(xc, yc);

for (i = 1; i < points.length - 1; i++) {

var xc = (points[i].x + points[i + 1].x) / 2;

var yc = (points[i].y + points[i + 1].y) / 2;

$.quadraticCurveTo(points[i].x, points[i].y, xc, yc);

}

var xc = (points[points.length - 1].x + points[0].x) / 2;

var yc = (points[points.length - 1].y + points[0].y) / 2;

$.quadraticCurveTo(points[i].x, points[i].y, xc, yc);

var xc = (points[0].x + points[1].x) / 2;

var yc = (points[0].y + points[1].y) / 2;

$.quadraticCurveTo(points[0].x, points[0].y, xc, yc);

}

let bubbles = [],

particles = [];

// spring for the screen shake

function shake(intencity) {

let rForce = new Vector().fromAngle(Math.random() * Math.PI * 2);

rForce.setMag(intencity);

spring.velocity.add(rForce);

}

let spring = {

mass: 40,

k: 2,

damping: 0.94,

restPosition: new Vector(0, 0),

position: new Vector(0, 0),

velocity: new Vector(0, 0),

update: function() {

let force = this.position.copy();

force.sub(this.restPosition);

force.mult(-this.k);

force.div(this.mass);

this.velocity.add(force);

this.velocity.mult(this.damping);

this.velocity.limit(100);

this.position.add(this.velocity);

},

}

app.setSize();

populate();

function populate() {

minSize = Math.min(app.W, app.H) * 0.4;

particles = [];

bubbles = [];

bubbles.push(new Bubble(bubbles, app.W / 2, app.H / 2, minSize));

bubbles.push(new Bubble(bubbles, app.W / 2, app.H / 2, minSize));

}

app.resize = function() {

populate();

};

app.update = function(dt) {

spring.update();

bubbles.forEach(b => {

b.avoid(bubbles);

b.update(dt);

});

particles.forEach(p => p.update(dt));

};

app.render = function() {

$.save();

$.translate(spring.position.x, spring.position.y);

$.globalCompositeOperation = "xor";

bubbles.forEach(b => {

$.fillStyle = "#2551f3";

$.beginPath();

b.draw()

$.fill();

});

$.globalCompositeOperation = "destination-over";

bubbles.forEach(b => {

$.fillStyle = b.color;

$.beginPath();

b.draw()

$.fill();

});

$.globalCompositeOperation = "source-over";

for (let i = particles.length - 1; i > 0; i--) {

let p = particles[i];

p.draw();

}

$.restore();

};

app.backgroundColor = "#1a1a1a";

app.run();

bubbles html5游戏源码,html5 canvas弹性气泡爆破 | 撒花动画相关推荐

  1. 飞机大战HTML5游戏源码,基于Canvas制作的网页版飞机大战游戏+飞机大战手机端

    简介: 飞机大战HTML5游戏源码是一款基于Canvas制作的网页版飞机大战游戏,画质精美的飞机大战手机端游戏源码 网盘下载地址: http://kekewangLuo.net/W1S2LQcqAT2 ...

  2. 100行JS代码实现❤坦克大战js小游戏源码 HTML5坦克大战游戏代码(HTML+CSS+JavaScript )

    坦克大战js小游戏源码 HTML5坦克大战游戏代码(HTML+CSS+JavaScript ) HTML5坦克大战网页小游戏,完美还原小霸王学习机效果,以坦克战斗及保卫基地为主题,属于策略型类游戏. ...

  3. html5游戏源码素材哪家强?Top3都在这!

    今天小编为大家整理出了一些html5游戏源码素材网站~ 身为游戏制作爱好者,html5游戏开发未来前景不错,对于游戏开发者而言,开发语言都只是工具,需要有一些游戏开发的实例进行引导,学习更深层次的技术 ...

  4. 单机手机消消乐php游戏源码,html5做出叠房子消消乐小游戏代码

    html5做出叠房子消消乐小游戏代码 js代码 // The game configuration var qici = {}; qici.config = { projectName: 'Subar ...

  5. html扑克牌游戏源码,html5扑克牌消除小游戏源码

    特效描述:html5扑克牌 消除小游戏源码.html5扑克牌消除小游戏源码 代码结构 1. 引入CSS 2. 引入JS 3. HTML代码 $(function(){ //实现随机洗牌 neusoft ...

  6. html5直播源码,HTML5 直播疯狂点赞动画实现代码 附源码

    直播有一个很重要的互动:点赞. 为了烘托直播间的氛围,直播相对于普通视频或者文本内容,点赞通常有两个特殊需求: 点赞动作无限次,引导用户疯狂点赞 直播间的所有疯狂点赞,都需要在所有用户界面都动画展现出 ...

  7. html5黑板源码,HTML5/Canvas黑板涂鸦动画

    JavaScript 语言: JaveScriptBabelCoffeeScript 确定 class Pencil { constructor( x, y ) { this.position = { ...

  8. 类似蚂蚁森林html5游戏源码,js仿照 蚂蚁森林 效果

    如图js仿照 蚂蚁森林 效果 css ** 葫芦籽动画效果 */ /* animation */ .a-swing{-webkit-animation:1s ease;-moz-animation:1 ...

  9. html5表格源码,HTML5表格制作源代码.doc

    HTML5表格制作源代码.doc (4页) 本资源提供全文预览,点击全文预览即可全文预览,如果喜欢文档就下载吧,查找使用更方便哦! 3.9 积分 HTML5表格制作源代码 (姬岚洋)代码:th{fo ...

最新文章

  1. 即构科技张靖雨:以最优的用户体验为第一评估要素
  2. 95-10-025-启动-BrokerId相关
  3. sqlserver聚合索引(clustered index) / 非聚合索引(nonclustered index)的理解
  4. SpringBoot中快速实现邮箱发送
  5. 拯救Ubuntu环境变量搞蹦导致命令使用不了的办法
  6. 在linux中cd god,Linux基础/Linux基础和命令.md · kelekele/God-Of-BigData - Gitee.com
  7. VC开发工具与各运行库对应关系
  8. matlab 蔡旭晖,matlab基础与应用教程
  9. koreader下载_kindle koreader
  10. CSS中如何实现表格文字的换行
  11. 全国哀悼日,网页变黑白
  12. 超级详细的教程--如何写SCI
  13. ActivityScenario启动失败Activity never becomes requested state [RESUMED, STARTED, CREATED, DESTROYED]
  14. C#使用公共语言拓展(CLE)调用Python3(使用TensorFlow训练的模型)
  15. 以“人”为本,精准营销
  16. 触摸屏I2C驱动移植
  17. voa 1500单词
  18. ibatis批量插入数据-iterate标签详解及应用
  19. 用Excel 做 员工轮班表
  20. IDEA偏好设置汇总

热门文章

  1. 积木式移动互联网App Hybrid框架-modular
  2. 网站访问流程及原理分析
  3. 国学大师林语堂献宝:英文学习八要诀
  4. 关于100M以太网的争用期问题
  5. 带电粒子在匀强电场中的运动(忽略重力)
  6. 网易互娱2017实习生招聘在线笔试(三)
  7. 微信小程序 MinUI 组件库系列之 progress 进度条组件
  8. Lumiprobe Lumizol RNA 提取试剂解决方案
  9. 李彦宏登上《时代》封面:他正帮中国在21世纪赢得胜利
  10. 看网易的lofter,预测轻博客的未来