// ==UserScript==
// @name element miner
// @namespace Violentmonkey Scripts
// @match *
// @include *
// @require https://cdn.jsdelivr.net/npm/[email protected]/dist/jquery.min.js
// @grant none
// @version 1.0
// @author ec50n9
// @description 2022/4/11 20:00:18
// @license MIT
// ==/UserScript==
this.$ = this.jQuery = jQuery.noConflict(true);
// 道具
function Prop(crane, type = 'bomb') {
this.crane = crane;
this.countDown = 200;
this.size = 32;
this.deg = 0;
this.color = 'red';
this.zIndex = 0;
this.WAGGLE_DEG = 15;
this.SCORES = {
bomb: -100,
flower: 50,
diamond: 100
}
this.TYPES = {
bomb: '💣',
flower: '🌹',
diamond: '💎'
};
this.BOOM_TEXTS = {
bomb: '💥BOOM!!!',
flower: '❤️HEY!!!',
diamond: '💰HOOO!!!!'
}
this.type = (type in this.TYPES) ? type : 'bomb';
this.score = this.SCORES[this.type];
this.text = this.TYPES[this.type];
this.boomText = this.BOOM_TEXTS[this.type];
this.element = $(`<div>${this.TYPES[this.type]}</div>`).css({
'position': 'fixed',
'left': `${crane.captured.element.offset().left + crane.captured.element.width() / 2}px`,
'top': `${crane.captured.element.offset().top + crane.captured.element.height() / 2}px`,
'white-space': 'nowrap',
'color': this.color,
'font-size': `${this.size}px`,
'transform': `translate(-50%, -50%) rotate(${this.deg}deg)`,
'z-index': this.zIndex
});
}
Prop.prototype.appendTo = function (target) {
target.prepend(this.element);
}
// 抓手
function Crane(left = 0, top = 0) {
// 得分
this.score = 0;
this.porpList = [];
// 位置
this.position = {
left,
top
};
// 角度
this.deg = -180;
// 绳子
this.rope = {
width: 10,
length: 50,
step: 2,
DEFAULT_STEP: 2,
DEFAULT_LEN: 50,
MIN_LEN: 0,
MAX_LEN: 1000
};
// 钩子
this.hock = {
src: 'https://s3.bmp.ovh/imgs/2022/04/12/1c986b60d886b9dd.png',
src_default: 'https://s3.bmp.ovh/imgs/2022/04/12/1c986b60d886b9dd.png',
src_capture: 'https://s3.bmp.ovh/imgs/2022/04/12/fd3fdb4cf18eb9f2.png'
}
// 当前状态
this.cur_status = 0;
this.STATUS = {
static: 0,
elongating: 1,
reducing: 2,
inRecovery: 3
};
// 被捕获
this.captured = {
element: null,
dis_left: 0,
dis_top: 0
};
// 操作台
this.ele_console = $('<div></div>').css({
'position': 'fixed',
'left': `${this.position.left}px`,
'top': `${this.position.top}px`,
// 'transform': 'translate(-50%, -50%)',
'width': '10em',
'height': '10em',
'background-image': 'url(https://s3.bmp.ovh/imgs/2022/04/13/ebbf40101c3c1038.png)',
'background-size': '100% auto',
'overflow': 'visible',
'z-index': '997'
});
// 操作台图片
this.ele_console_img = $('<img src="https://s3.bmp.ovh/imgs/2022/04/13/3cf047c6fc4f1a33.png"/>').css({
position: 'absolute',
bottom: '0',
left: '20%',
width: '60%',
});
this.ele_console.append(this.ele_console_img);
// 抓手容器
this.ele_hock_container = $('<div></div>').css({
'margin-top': '90%',
'transform-origin': 'top center',
'transform': `rotate(${this.deg}deg)`,
'z-index': '999'
});
this.ele_console.append(this.ele_hock_container);
// 分数
this.ele_score = $(`<div>${this.score}</div>`).css({
'position': 'absolute',
'top': '-1.5em',
'font-size': '1em',
'color': 'green',
'white-space': 'nowrap'
});
this.ele_console.prepend(this.ele_score);
// 绳子
this.ele_rope = $('<div></div>').css({
'width': `${this.rope.width}px`,
'height': `${this.rope.length}px`,
'margin': '0 auto',
'background-image': 'url(https://s3.bmp.ovh/imgs/2022/04/13/65f0a51cebe9be16.png)',
'background-size': '100% auto',
'background-repeat': 'no-repeat repeat'
});
this.ele_hock_container.append(this.ele_rope);
// 抓手
this.ele_hock = $(`<div></div>`).css({
'width': '4em',
'height': '4em',
'margin': '0 auto',
'margin-top': '-4px'
});
this.ele_hock_img = $(`<img style="width:inherit; height:inherit; object-fit:contain;"
src="${this.hock.src}">`);
this.ele_hock.append(this.ele_hock_img);
this.ele_hock_container.append(this.ele_hock);
// 点击事件
let that = this;
this.ele_console.click(function () {
if (that.status == that.STATUS.elongating) {
that.catch();
} else {
that.elongate();
}
});
}
// 添加到
Crane.prototype.appendTo = function (target) {
target.append(this.ele_console);
}
// 增加角度
Crane.prototype.addDeg = function (increment) {
this.deg += increment;
if (this.deg == 360) {
this.deg = 0;
} else if (this.deg > 360) {
this.deg %= 360;
} else if (this.deg < 0) {
this.deg = 360 + this.deg % 360;
}
}
// 设置分数
Crane.prototype.updateScore = function (increment) {
let newScore = this.score + increment;
if (newScore < 0) {
this.score = 0;
} else {
this.score = newScore;
}
}
// 静态
Crane.prototype.static = function () {
this.status = this.STATUS.static;
}
// 伸长
Crane.prototype.elongate = function () {
this.status = this.STATUS.elongating;
}
// 恢复
Crane.prototype.recovery = function () {
this.status = this.STATUS.inRecovery;
// 移除元素
if (this.captured.element) {
this.updateScore(10);
this.captured.element.remove();
this.captured.element = null;
}
// 恢复绳子伸长的步长
this.rope.step = this.rope.DEFAULT_STEP;
}
// 捕捉
Crane.prototype.catch = function () {
this.status = this.STATUS.reducing;
let scrollLeft = $(document).scrollLeft();
let scrollTop = $(document).scrollTop();
let x = this.ele_hock.offset().left - scrollLeft + this.ele_hock.width() / 2,
y = this.ele_hock.offset().top - scrollTop + this.ele_hock.height() / 2;
let elements = document.elementsFromPoint(x, y);
if (elements.length > 3) {
this.captured.element = $(elements[3]);
let tagName = this.captured.element[0].tagName.toLowerCase();
// 忽略html元素
if (tagName == 'html' || tagName == 'body') {
this.captured.element = null;
return;
}
// 计算上和左的距离
this.captured.dis_left = this.ele_hock.offset().left - this.captured.element.offset().left + scrollLeft;
this.captured.dis_top = this.ele_hock.offset().top - this.captured.element.offset().top + scrollTop;
// 计算尺寸
let size = this.captured.element.width() + this.captured.element.height();
// this.rope.step = 1;
// 初始化元素
this.captured.element.css({
'position': 'fixed',
'left': `${this.captured.element.offset().left- $(document).scrollLeft()}px`,
'top': `${this.captured.element.offset().top- $(document).scrollTop()}px`,
'width': `${this.captured.element.width()}px`,
'height': `${this.captured.element.height()}px`,
'z-index': '995'
});
// 炸弹
if (tagName == 'img') {
let random = Math.random();
let porp;
if (random > .7) {
porp = new Prop(this, 'bomb');
} else if (random > .5) {
porp = new Prop(this, 'flower');
} else if (random > .3) {
porp = new Prop(this, 'diamond');
} else {
porp = new Prop(this, 'bomb');
}
if (porp) {
porp.appendTo(this.captured.element.parent());
}
this.porpList.push(porp);
}
}
}
// 更新
Crane.prototype.update = function () {
// 爪子
if (this.status == this.STATUS.elongating) {
// 伸长
if (this.rope.length < this.rope.MAX_LEN) {
this.rope.length += this.rope.step;
} else {
this.catch();
}
} else if (this.status == this.STATUS.reducing) {
// 收缩
if (this.rope.length > this.rope.MIN_LEN) {
this.rope.length -= this.rope.step;
} else {
this.recovery();
}
} else if (this.status == this.STATUS.inRecovery) {
// 恢复
if (this.rope.length > this.rope.DEFAULT_LEN) {
this.rope.length -= 1;
} else if (this.rope.length < this.rope.DEFAULT_LEN) {
this.rope.length += 1;
} else {
this.static();
}
} else {
this.addDeg(.5);
}
// 抓手状态
if (this.captured.element) {
// 抓着东西
this.hock.src = this.hock.src_capture;
} else {
// 没有东西
this.hock.src = this.hock.src_default;
}
// 道具
for (let i in this.porpList) {
let porp = this.porpList[i];
if (porp.countDown > 0) {
porp.countDown -= 1;
} else if (porp.countDown > -64) {
porp.size += 1;
porp.countDown -= 1;
} else if (porp.countDown == -64) {
porp.deg = porp.WAGGLE_DEG;
porp.text = porp.boomText;
porp.zIndex = 999;
porp.countDown -= 1;
porp.crane.updateScore(porp.score);
} else if (porp.countDown > -96) {
if (porp.countDown % 8 == 0) {
porp.deg = -porp.deg;
}
porp.countDown -= 1;
} else {
porp.element.remove();
this.porpList.splice(i, 1);
}
}
}
// 绘制
Crane.prototype.draw = function () {
// 分数
this.ele_score.text('分数:' + this.score);
// 旋转角度和长度
this.ele_hock_container.css('transform', `rotate(${this.deg}deg)`);
this.ele_rope.css({
'width': `${this.rope.width}px`,
'height': `${this.rope.length}px`
});
// 钩子图片
this.ele_hock_img.attr('src', this.hock.src);
// 拖动元素
if (this.captured.element) {
this.captured.element.css({
'left': `${this.ele_hock.offset().left - this.captured.dis_left}px`,
'top': `${this.ele_hock.offset().top - this.captured.dis_top}px`
});
}
// 道具
for (let porp of this.porpList) {
porp.element.text(porp.text).css({
'transform': `translate(-50%, -50%) rotate(${porp.deg}deg)`,
'color': porp.color,
'font-size': `${porp.size}px`,
'z-index': porp.zIndex
});
}
}
// 休眠
async function sleep(delay) { return new Promise((resolve) => setTimeout(resolve, delay)); }
// 游戏循环
async function game_loop(cranes) {
while (true) {
for (let crane of cranes) {
crane.update();
crane.draw();
}
await sleep(10);
}
}
$(function () {
console.log('开始矿工之旅!!!');
let crane = new Crane(400, 100);
crane.appendTo($('body'));
let cranes = [crane];
game_loop(cranes);
});