简单的双鼠标光标 matter.js
Double mouse cursor with simple matter.js
我想用 matter.js 创建一个闲置游戏。我可以完美地捕获鼠标事件,然后在我单击中心的门户后开始注意到有一个双光标。即使在删除所有与捕获鼠标事件相关的代码之后,我仍然看到一个重复的光标。我把代码简化到最低限度,我仍然不知道这可能来自哪里。
提供的示例在 Chrome 中进行了最佳测试,Edge 出于某种原因忽略了我在 css 中的黑色背景指令。
// Install plugin
Matter.use('matter-attractors');// PLUGIN_NAME
Matter.use('matter-collision-events');// PLUGIN_NAME
// module aliases
var Engine = Matter.Engine,
Events = Matter.Events,
Runner = Matter.Runner,
Render = Matter.Render,
World = Matter.World,
Body = Matter.Body,
//Mouse = Matter.Mouse,
Common = Matter.Common,
Bodies = Matter.Bodies;
//MouseConstraint = Matter.MouseConstraint;
function UI() {
listenToResize();
// Create engine
this.engine = Engine.create();
// Create renderer
this.render = Render.create({
element: document.body,
engine: this.engine,
options: {
width: document.documentElement.clientWidth,
height: document.documentElement.clientHeight,
wireframes: false,
background: 'black',
showId: true
}
});
//Link engine and renderer
this.engine.render = this.render;
// Create runner
this.runner = Runner.create();
// Do the running
Runner.run(this.runner, this.engine);
Render.run(this.render);
// Create demo scene
this.world = this.engine.world;
this.world.gravity.scale = 0;
World.add(this.world, UI.createPortal(this));
}
function listenToResize() {
function captureSize() {
console.log("Resize captured!");
UI.height = window.innerHeight || document.documentElement.clientHeight;
UI.width = window.innerWidth || document.documentElement.clientWidth;
UI.centerX = UI.width >> 1;
UI.centerY = UI.height >> 1;
}
window.addEventListener("optimizedResize", captureSize);
captureSize();
}
UI.createPortal = function createPortalUI(ui) {
// create a body with an attractor
return Bodies.circle(ui.render.options.width / 2, ui.render.options.height / 2, 50, {
isStatic: true,
label: 'centerPortal',
id:'centerPortal',
render: {
sprite: {
texture: '//konijn.github.io/needle-eye/SVGMerchant/png/star-gate.png',
xScale: 0.1,
yScale: 0.1,
showId: true
}
},
// example of an attractor function that
// returns a force vector that applies to bodyB
//Todo recognize non attracted thingies
plugin: {
attractors: [// MatterAttractors.Attractors.gravity(bodyA, bodyB)
function(bodyA, bodyB) {
return {
x: (bodyA.position.x - bodyB.position.x) * 1e-6,
y: (bodyA.position.y - bodyB.position.y) * 1e-6,
};
}
]
}
});
};
UI.log = function(txt, x, y) {
let div = document.createElement("div");
let content = document.createTextNode(txt);
div.classList.add('message');
div.appendChild(content);
document.body.appendChild(div);
UI.animateLog();
}
UI.animateLog = function animateLog() {
if (UI.interval)
return;
UI.interval = window.setInterval(UI.animateLogItems, 100);
}
UI.animateLogItems = function animateLogItems() {
let list = document.getElementsByClassName('message');
for (e of list) {
//console.log(e);
if (e.offsetTop < 5) {
document.body.removeChild(e);
} else {
e.style.top = (e.offsetTop - 1) + 'px';
}
}
}
UI.remove = function(body){
World.remove(ui.world, body);
}
/*
Inspiration : Merchant RPG
http://brm.io/matter-js/docs/index.html
https://game-icons.net/
https://github.com/liabru/matter-js/issues/321
*/
/*jshint esversion: 6 */
var game = new Game(),
data = game.data,
ui = new UI();
function Game() {
this.updateInterval = setInterval(update, 1000);
this.data = {};
}
Game.prototype.onClick = function onClick(body){
console.log(body);
if(body.label=="centerPortal"){
//UI.createImp(ui);
//UI.log('You summoned an Imp');
}
if(body.label.startsWith('Imp,')){
UI.createLog(ui);
UI.remove(body);
}
};
function update() {
//console.log('Tick');
if (!data.gameStarted) {
message('Welcome to Portal Merchant');
message('You see a start portal');
message('You feel compelled to activate it');
}
}
function message(msg) {
}
function load() {
return scaffoldLoad(JSON.parse(localStorage.getItem('data') || "{}"));
}
function save() {
localStorage.setItem('data', JSON.stringify(scaffoldSave(data)));
}
function reset() {
localStorage.removeItem('data');
}
function help() {
console.log("Console commands:");
console.log("reset()");
}
function scaffoldLoad(data) {
return data;
}
function scaffoldSave(data) {
return data;
}
function step(timestamp) {
UI.last = UI.last || timestamp;
let progress = timestamp - UI.last;
}
/* Pretty colors and such */
body {
background-color: black;
/* Foreground is 'merino' */
color: rgb(225, 219, 208);
height: 100%
background: black;
}
html, body {
margin: 0;
height: 100%;
width: 100%;
}
canvas {
display: inline-block;
max-width: 100%;
max-height: 100%;
}
canvas:active {
cursor: pointer;
}
.message {
position:absolute;
background-color: black;
color: rgb(225, 219, 208);
z-index: 2;
bottom: 30px;
}
<meta name="description" content="Merchant">
<meta charset="utf-8">
<meta name="viewport" content="width=device-width">
<title>Merchant</title>
<link rel="stylesheet" type="text/css" href="merch.css" media="screen"/>
<!-- <script src="//cdnjs.cloudflare.com/ajax/libs/matter-js/0.12.0/matter.min.js"></script> -->
<script src="//cdnjs.cloudflare.com/ajax/libs/matter-js/0.12.0/matter.min.js"></script>
<script src="//cdn.rawgit.com/liabru/matter-attractors/master/build/matter-attractors.js"></script>
<script src="//cdn.jsdelivr.net/npm/matter-collision-events@0.1.7/build/matter-collision-events.min.js"></script>
Single click the portal in the center, you should see a double cursor, why??
原来是 canvas:active {}
,active
关键字使光标加倍。
我想用 matter.js 创建一个闲置游戏。我可以完美地捕获鼠标事件,然后在我单击中心的门户后开始注意到有一个双光标。即使在删除所有与捕获鼠标事件相关的代码之后,我仍然看到一个重复的光标。我把代码简化到最低限度,我仍然不知道这可能来自哪里。
提供的示例在 Chrome 中进行了最佳测试,Edge 出于某种原因忽略了我在 css 中的黑色背景指令。
// Install plugin
Matter.use('matter-attractors');// PLUGIN_NAME
Matter.use('matter-collision-events');// PLUGIN_NAME
// module aliases
var Engine = Matter.Engine,
Events = Matter.Events,
Runner = Matter.Runner,
Render = Matter.Render,
World = Matter.World,
Body = Matter.Body,
//Mouse = Matter.Mouse,
Common = Matter.Common,
Bodies = Matter.Bodies;
//MouseConstraint = Matter.MouseConstraint;
function UI() {
listenToResize();
// Create engine
this.engine = Engine.create();
// Create renderer
this.render = Render.create({
element: document.body,
engine: this.engine,
options: {
width: document.documentElement.clientWidth,
height: document.documentElement.clientHeight,
wireframes: false,
background: 'black',
showId: true
}
});
//Link engine and renderer
this.engine.render = this.render;
// Create runner
this.runner = Runner.create();
// Do the running
Runner.run(this.runner, this.engine);
Render.run(this.render);
// Create demo scene
this.world = this.engine.world;
this.world.gravity.scale = 0;
World.add(this.world, UI.createPortal(this));
}
function listenToResize() {
function captureSize() {
console.log("Resize captured!");
UI.height = window.innerHeight || document.documentElement.clientHeight;
UI.width = window.innerWidth || document.documentElement.clientWidth;
UI.centerX = UI.width >> 1;
UI.centerY = UI.height >> 1;
}
window.addEventListener("optimizedResize", captureSize);
captureSize();
}
UI.createPortal = function createPortalUI(ui) {
// create a body with an attractor
return Bodies.circle(ui.render.options.width / 2, ui.render.options.height / 2, 50, {
isStatic: true,
label: 'centerPortal',
id:'centerPortal',
render: {
sprite: {
texture: '//konijn.github.io/needle-eye/SVGMerchant/png/star-gate.png',
xScale: 0.1,
yScale: 0.1,
showId: true
}
},
// example of an attractor function that
// returns a force vector that applies to bodyB
//Todo recognize non attracted thingies
plugin: {
attractors: [// MatterAttractors.Attractors.gravity(bodyA, bodyB)
function(bodyA, bodyB) {
return {
x: (bodyA.position.x - bodyB.position.x) * 1e-6,
y: (bodyA.position.y - bodyB.position.y) * 1e-6,
};
}
]
}
});
};
UI.log = function(txt, x, y) {
let div = document.createElement("div");
let content = document.createTextNode(txt);
div.classList.add('message');
div.appendChild(content);
document.body.appendChild(div);
UI.animateLog();
}
UI.animateLog = function animateLog() {
if (UI.interval)
return;
UI.interval = window.setInterval(UI.animateLogItems, 100);
}
UI.animateLogItems = function animateLogItems() {
let list = document.getElementsByClassName('message');
for (e of list) {
//console.log(e);
if (e.offsetTop < 5) {
document.body.removeChild(e);
} else {
e.style.top = (e.offsetTop - 1) + 'px';
}
}
}
UI.remove = function(body){
World.remove(ui.world, body);
}
/*
Inspiration : Merchant RPG
http://brm.io/matter-js/docs/index.html
https://game-icons.net/
https://github.com/liabru/matter-js/issues/321
*/
/*jshint esversion: 6 */
var game = new Game(),
data = game.data,
ui = new UI();
function Game() {
this.updateInterval = setInterval(update, 1000);
this.data = {};
}
Game.prototype.onClick = function onClick(body){
console.log(body);
if(body.label=="centerPortal"){
//UI.createImp(ui);
//UI.log('You summoned an Imp');
}
if(body.label.startsWith('Imp,')){
UI.createLog(ui);
UI.remove(body);
}
};
function update() {
//console.log('Tick');
if (!data.gameStarted) {
message('Welcome to Portal Merchant');
message('You see a start portal');
message('You feel compelled to activate it');
}
}
function message(msg) {
}
function load() {
return scaffoldLoad(JSON.parse(localStorage.getItem('data') || "{}"));
}
function save() {
localStorage.setItem('data', JSON.stringify(scaffoldSave(data)));
}
function reset() {
localStorage.removeItem('data');
}
function help() {
console.log("Console commands:");
console.log("reset()");
}
function scaffoldLoad(data) {
return data;
}
function scaffoldSave(data) {
return data;
}
function step(timestamp) {
UI.last = UI.last || timestamp;
let progress = timestamp - UI.last;
}
/* Pretty colors and such */
body {
background-color: black;
/* Foreground is 'merino' */
color: rgb(225, 219, 208);
height: 100%
background: black;
}
html, body {
margin: 0;
height: 100%;
width: 100%;
}
canvas {
display: inline-block;
max-width: 100%;
max-height: 100%;
}
canvas:active {
cursor: pointer;
}
.message {
position:absolute;
background-color: black;
color: rgb(225, 219, 208);
z-index: 2;
bottom: 30px;
}
<meta name="description" content="Merchant">
<meta charset="utf-8">
<meta name="viewport" content="width=device-width">
<title>Merchant</title>
<link rel="stylesheet" type="text/css" href="merch.css" media="screen"/>
<!-- <script src="//cdnjs.cloudflare.com/ajax/libs/matter-js/0.12.0/matter.min.js"></script> -->
<script src="//cdnjs.cloudflare.com/ajax/libs/matter-js/0.12.0/matter.min.js"></script>
<script src="//cdn.rawgit.com/liabru/matter-attractors/master/build/matter-attractors.js"></script>
<script src="//cdn.jsdelivr.net/npm/matter-collision-events@0.1.7/build/matter-collision-events.min.js"></script>
Single click the portal in the center, you should see a double cursor, why??
原来是 canvas:active {}
,active
关键字使光标加倍。