это работает на моем локальном сайте (на моем компьютере).
однако, как вы можете видеть, я получаю ошибку о поврежденном состоянии текстурных изображений при загрузке на сервер.
поэтому я пытаюсь загрузить изображения текстуры ранее как
const loadImage = (url, onSuccess, onError) => {
const img = new Image();
img.onload = () => {
onSuccess(img.src);
};
img.onerror = onError();
img.src = url;
};
, как я вижу в https://github.com/liabru/matter-js/issues/497
таким образом
// stack 1
const loadImageEo = (url, onSuccess, onError) => {
const img = new Image();
img.onload = () => { onSuccess(img.src); };
img.onerror = onError();
img.src = "imagenes/Eoculista.png";
};
//stack 2
const loadImageMo = (url, onSuccess, onError) => {
const img = new Image();
img.onload = () => { onSuccess(img.src); };
img.onerror = onError();
img.src = "imagenes/Moculista.png";
};
// etc...
для каждых четырех разных стеков с различной текстурой каждый
после этого я загружаю текстуры изображений
loadImageEo(
"imagenes/Eoculista.png",
url => { console.log("Success"); }, () => { console.log("Error Loading "); } );
loadImageMo(
"imagenes/Moculista.png",
url => { console.log("Success"); }, () => { console.log("Error Loading "); } );
loadImageEEo(
"imagenes/EEoculista.png",
url => { console.log("Success"); }, () => { console.log("Error Loading "); } );
loadImageWo(
"imagenes/Woculista.png",
url => { console.log("Success"); }, () => { console.log("Error Loading "); } );
и, наконец, делаю стеки, чтобы добавить в мир
это это полный фрагмент, та же ошибка.
при попытке вставить его в функцию init () я получил ошибку из-за слишком большого количества соединений. так что это тоже не работает.
Я действительно буду признателен за любые идеи
// para encapsular
var visionCheck = {};
// lo metemos todo dentro de una funcion autoejecutable
visionCheck = (function (){
// variables universales ------------------------------
var nuevos = [];
var bodyNuevo;
// sonidos
var audioClick = new Audio('imagenes/click.wav');
//tamaño del canvas
var ancho = window.innerWidth;
var alto = window.innerHeight - 100;
// configuracion del canvas
var canvas = document.getElementById("papel");
var ctx = canvas.getContext("2d");
// pantalla completa
canvas.width = window.innerWidth;
// para que se vean las lineas de abajo fuera del canvas
canvas.height = window.innerHeight - 100;
// para dar atributos a los cuerpos
var signos =[];
// tamaño del canvas
//canvas.width = ancho;
//canvas.height = alto;
// estos son los modulos MATTER
var Engine = Matter.Engine, // actualizan objetos. con mayuscula
Render = Matter.Render, // modulo basico htm5 para renderizar
World = Matter.World, // similar a matter.composite pero tiene ademas gravity y bounds
Bodies = Matter.Bodies, // crear cuerpos. matterBody los manipula individualmente
Mouse = Matter.Mouse,
MouseConstraint = Matter.MouseConstraint;// permite dragging
var Common = Matter.Common;// conjunto de utilidades de matterjs
var Composites = Matter.Composites; // para hacer pilas
// create engine
var engine = Engine.create(); // crea un objeto de la clase Engine. con minuscula
var world = engine.world;
world.gravity.x = 0;
world.gravity.y = .8;
// tiene un parametro settings create([settings]) es en realidad un objeto
//con un par de valores: propiedad:valor,
// para anular los valores predeterminados de algunas propiedades relacionadas al motor
// por ejemplo el tiempo ( camara lenta)
var render = Render.create({
element: document.body, // especifica donde pintar en la pagina. se podria usar canvas
engine: engine, // especifica el motor
canvas: canvas,
options: {width: ancho,
height: alto,
background: '#ffffff',
wireframes: false,
showAngleIndicator: true} // acepta un objeto
//background = "imagenes/ lo que sea.jpg" ... imagen de fondo o un color
// wireframe = true renderiza en alambre
});
////ATENCION /////////////////////////////////////////////////////////
// si se cargan las imagenes como texturas directamente en el ordenador funcionara bien,
/*
este seria un ejemplo de como hacerlo
// variables de stack xx, yy, columns, rows, columnGap, rowGap, callback
var stack1 = Composites.stack(ancho/4, alto-520, 10, 2, 0, 19, function(x, y, column, row) {
return Bodies.rectangle(x, y, 90, 90,
{friction: 1, restitution: 1, density: 5.5,
render: {sprite :{ texture : "imagenes/Eoculista.png", xScale : .2, yScale: .2}}})
*/
// pero una vez lo subamos tendremos un error al ejecutarlo del tipo
// Uncaught DOMException: Failed to execute 'drawImage'on 'CanvasRenderingContext2D': The HTMLImageElement provided is in the 'broken' state.
// asi que hay que cargar las imagenes previamente, y despues convertirlas en textura para matter
/// VER https://github.com/liabru/matter-js/issues/497
// ESTE ES UN CARGADOR DE IMAGENES
const loadImageEo = (url, onSuccess, onError) => {
const img = new Image();
img.onload = () => { onSuccess(img.src); };
img.onerror = onError();
img.src = "imagenes/Eoculista.png";
};
const loadImageMo = (url, onSuccess, onError) => {
const img = new Image();
img.onload = () => { onSuccess(img.src); };
img.onerror = onError();
img.src = "imagenes/Moculista.png";
};
const loadImageEEo = (url, onSuccess, onError) => {
const img = new Image();
img.onload = () => { onSuccess(img.src); };
img.onerror = onError();
img.src = "imagenes/EEoculista.png";
};
const loadImageWo = (url, onSuccess, onError) => {
const img = new Image();
img.onload = () => { onSuccess(img.src); };
img.onerror = onError();
img.src = "imagenes/Woculista.png";
};
// Y AHORA CARGAMOS LAS IMAGENES
// para borrar un objeto Matter.Composite.remove(world, body)
//var ground = Bodies.rectangle(500, 470, 950, 20, { isStatic: true });
var ground = Bodies.rectangle(ancho/2, alto, ancho, 20, { isStatic: true });
// x e y son coordenadas del centro del objeto !!!!
var paredIzq = Bodies.rectangle(ancho*.25, alto*.66, 2, 500, { isStatic: true });
var paredDcha = Bodies.rectangle(ancho*.75, alto*.66, 2, 500, { isStatic: true });
// x e y son coordenadas del centro del objeto !!!!
// x , y ancho , alto
// add mouse control
var mouse = Mouse.create(render.canvas), // hay un canvas creado por defecto !!!!
mouseConstraint = MouseConstraint.create(engine, {
mouse: mouse,
constraint: { stiffness: 0.2, render: { visible: false }
}
});
// keep the mouse in sync with rendering
render.mouse = mouse;
World.add(world, mouseConstraint);
// parte publica
return {
init: function () {
ground.restitution = 0.1; // es un valor medio de los dos cuerpos que chocan
paredIzq.render.strokeStyle ="white"; // color de la linea de borde
paredDcha.render.strokeStyle ="white"; // color de la linea de borde
/*configurar los objetos
ballA.render.fillStyle = 'red';
ballA.render.lineWidth = 25;
ballB.render.opacity = 0.2;
ground.render.strokeStyle="white"; // color de la linea de borde
e.restitution=2;//capacidad de botar
m.restitution=0;
*/
// AQUI CARGAMOS LAS IMAGENES
loadImageEo(
"imagenes/Eoculista.png",
url => { console.log("Success"); }, () => { console.log("Error Loading "); } );
loadImageMo(
"imagenes/Moculista.png",
url => { console.log("Success"); }, () => { console.log("Error Loading "); } );
loadImageEEo(
"imagenes/EEoculista.png",
url => { console.log("Success"); }, () => { console.log("Error Loading "); } );
loadImageWo(
"imagenes/Woculista.png",
url => { console.log("Success"); }, () => { console.log("Error Loading "); } );
// DEFINIMOS LOS BLOQUES
var stack1 = Composites.stack(ancho/4, alto-520, 10, 2, 0, 19, function(x, y, column, row) {
return Bodies.rectangle(x, y, 90, 90,
{friction: 1, restitution: 1, density: 5.5,
render: {sprite :{ texture : "imagenes/Eoculista.png", xScale : .2, yScale: .2}}})
});
var stack2 = Composites.stack(ancho/4, alto-360, 13, 2, 0, 19, function(x, y, column, row) {
return Bodies.rectangle(x, y, 70, 70,
{friction: 1, restitution: 1, density: 5.5,
render: {sprite :{ texture : "imagenes/Moculista.png", xScale : .15, yScale: .15}}})
});
var stack3 = Composites.stack(ancho/4, alto-200, 18, 2, 0, 19, function(x, y, column, row) {
return Bodies.rectangle(x, y, 50, 50,
{friction: 1, restitution: 1, density: 5.5,
render: {sprite :{ texture : "imagenes/EEoculista.png", xScale : .1, yScale: .1}}})
});
var stack4 = Composites.stack(ancho/4, alto-100, 30, 2, 0, 19, function(x, y, column, row) {
return Bodies.rectangle(x, y, 30, 30,
{friction: 1, restitution: 1, density: 5.5,
render: {sprite :{ texture : "imagenes/Woculista.png", xScale : .05, yScale: .05}}})
});
// AÑADIMOS TODO AL MUNDO
World.add(engine.world, [ground,paredIzq, paredDcha, stack1,stack2,stack3,stack4 ]);
Engine.run(engine);
Render.run(render);//Continuously updates the render canvas on the requestAnimationFrame event.
// usamos doble click para crear objetos
// un solo click para pinchar y moverlos
// ya incorporado en mouseconstraint
canvas.addEventListener('dblclick', doubleClick, false);
/*// detectar colisiones
for (var i = 0; i < caja2.length; i++)
{
var collision = Matter.SAT.collides(bodyNuevo, caja2[i]);
if (collision.collided)
{
console.log("collision");
audioClick.play();
}
}
*/
//var collision = Matter.SAT.collides(bodyA, bodyB);
//if (collision.collided) { audioClick.play();}
}// fin de init. si hace falta otro metodo publico poner coma
}//fin de return ( parte publica)..................................................
// PARTE PRIVADA ( fuera del return)................................................
function draw () // se repetira al llamarse cada cierto intervalo
{ // POSIBILIDAD DE USAR REQUESTANIMATIONFRAME
//requestAnimationFrame(draw); // llamada recursiva al draw
}
//requestAnimationFrame(draw); // ejecucion del draw
//////////////////////////////////////////////////////////////////////////////////
/// FUNCIONES ////////////////////////////////////////////////////////
/////////////////////////////////////////////////////////////////////////////////
//para añadir objetos con mouseclick-------------------------------------------
// OJO : esta funcion controla los sucesivos que se van añadiendo
// asi que aqui tambien hay que añadir la textura
function addPalabra ()
{
let nuevaPalabra = Bodies.rectangle(mouse.position.x, mouse.position.y, 50, 50,
{render: {sprite :{ texture : "imagenes/Eoculista.png", xScale : .1, yScale: .1}}});
return nuevaPalabra;
};
function doubleClick()
{
World.add(engine.world, addPalabra());
audioClick.play();
bodyNuevo = addPalabra();
// para el tamaño Common.random(5, 15)
console.log("crea");
} //
})(); // fin de la funcion autoejecutable
body
{
height : 100%;
padding: 50px ;
margin: 20px;
/*background: #000000;*/
}
#links
{
/*aqui efectos del boton o lo que sea */
/*position:absolute;
top: 700px;
left: 950px;*/
font-family: 'Open Sans', sans-serif;
font-size: 17px;
text-align: center;
color: #000000;
line-height: 2;
letter-spacing: 1px;
float: right;
text-decoration: underline;
}
#instrucciones
{
font-family: 'Open Sans', sans-serif;
font-size: 15px;
}
.dialectica_minima
{
font-size:50px;
font-family:courier;
padding: 100px;
}
/* da estilo al back to works del final de los poemas*/
.margin-link
{
margin-top: 200px;
width: 50%
}
/* esto hace que la letra aparezca en un tamaño
razonable en pantallas mas pequeñas*/
@media (max-width:500px)
{
.dialectica_minima
{
font-size:24px;
}
.margin-link
{
width: 100%
}
}
<!DOCTYPE html>
<html lang="en" >
<head>
<meta charset="UTF-8">
<title> gradua la vista // vision check</title>
<meta name="viewport" content="width=device-width, user-scalable=no">
<canvas id="papel"></canvas>
<link rel="stylesheet" href="estilos/estiloFullScreen.css">
<!-- Bootstrap CSS redimensionamiento segun pantalla-->
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/4.0.0-beta.3/css/bootstrap.min.css" integrity="sha384-Zug+QiDoJOrZ5t4lssLdxGhVrurbmBWopoEl+M6BdEfwnCJZtKxi1KgxUyJq13dy" crossorigin="anonymous">
</head>
<!--llamar a init() con el nombre del namespace de cada poema.-->
<!--todas las variables globales protegidas.-->
<body onload="visionCheck.init();">
<!--llamadas a los archivos de sonido-->
<audio id = "click" src="imagenes/click.wav" ></audio>
<!--esto aparece por encima del canvas -->
<div id="container">
<!--declaracion del canvas. el tamaño en js-->
<canvas id="papel" > </canvas>
<!--este div se pone encima del canvas
dar id para colocar cosas donde queramos-->
<div id="overlay">
GRADUA LA VISTA// VISION CHECK <br>
doble click para insertar nuevos elementos // dbclick to insert new elements
</div> <!--fin de overlay-->
</div> <!--fin de container-->
<!--enlace abajo del todo-->
<div class="margin-link">
<a href="works.html" id = "links"> back to works</a>
</div>
<script src='https://cdnjs.cloudflare.com/ajax/libs/matter-js/0.11.0/matter.min.js'></script>
<!--ojo he tenido que cambiar el nombre del archivo para que sea diferente del nombre
de la funcion autoejecutable -->
<script src="scripts/visionCheckk.js"></script>
</body>
</html>
// GRADUA TU VISTA
// poema basico para la recitacion en el oculista
//www.activepoem.es
// pepe ballesteros. prototipolab
// sin encapsular
var ancho = 1000;//tamaño del canvas
var alto = 500;
// sonidos
var audioClick = new Audio('imagenes/click.wav');
// habilitar sonido cuando haya contacto
// audioClick.play() // sonido que sea
// detectar colisiones
//var collision = Matter.SAT.collides(bodyA, bodyB);
//if (collision.collided) { // do something }
// configuracion del canvas
var canvas = document.getElementById("papel");
var ctx = canvas.getContext("2d");
// para dar a tributos a los cuerpos
var signos =[];
// tamaño del canvas
canvas.width = ancho;
canvas.height = alto;
// estos son los modulos
var Engine = Matter.Engine, // actualizan objetos
Render = Matter.Render, // modulo basico htm5 para renderizar
World = Matter.World, // similar a matter.composite pero tiene ademas gravity y bounds
Bodies = Matter.Bodies, // crear cuerpos. matterBody los manipula individualmente
Mouse = Matter.Mouse,
MouseConstraint = Matter.MouseConstraint;// permite dragging
var Common = Matter.Common;// conjunto de utilidades de matterjs
var Composites = Matter.Composites; // para hacer pilas
// create engine
var engine = Engine.create();
var world = engine.world;
world.gravity.x=0;
world.gravity.y= .8;
// tiene un parametro settings create([settings]) es en realidad un objeto
//con un par de valores: propiedad:valor,
// para anular los valores predeterminados de algunas propiedades relacionadas al motor
// por ejemplo el tiempo ( camara lenta)
var render = Render.create({
element: document.body, // especifica donde pintar en la pagina. se podria usar canvas
engine: engine, // especifica el motor
canvas: canvas,
options: {width: ancho,
height: alto,
background: '#ffffff',
wireframes: false,
showAngleIndicator: true} // acepta un objeto
//background = "imagenes/ lo que sea.jpg" ... imagen de fondo o un color
// wireframe = true renderiza en alambre
}); // fin de render
// variables de stack xx, yy, columns, rows, columnGap, rowGap, callback
var stack1 = Composites.stack(50, 5, 10, 2, 0, 19, function(x, y, column, row) {
return Bodies.rectangle(x, y, 90, 90,
{friction: 1, restitution: 1, density: 5.5,
render: {sprite :{ texture : "imagenes/E.png", xScale : .2, yScale: .2}}})
});
var stack2 = Composites.stack(50, 200, 13, 2, 0, 19, function(x, y, column, row) {
return Bodies.rectangle(x, y, 70, 70,
{friction: 1, restitution: 1, density: 5.5,
render: {sprite :{ texture : "imagenes/M.png", xScale : .15, yScale: .15}}})
});
var stack3 = Composites.stack(50, 350, 18, 2, 0, 19, function(x, y, column, row) {
return Bodies.rectangle(x, y, 50, 50,
{friction: 1, restitution: 1, density: 5.5,
render: {sprite :{ texture : "imagenes/EE.png", xScale : .1, yScale: .1}}})
});
var stack4 = Composites.stack(50, 480, 30, 2, 0, 19, function(x, y, column, row) {
return Bodies.rectangle(x, y, 30, 30,
{friction: 1, restitution: 1, density: 5.5,
render: {sprite :{ texture : "imagenes/W.png", xScale : .05, yScale: .05}}})
});
console.log(getType(stack4)); // devuelve object
// para borrar un objeto Matter.Composite.remove(world, body)
var ground = Bodies.rectangle(500, 470, 950, 20, { isStatic: true });
var paredIzq = Bodies.rectangle(0, 500, 2, 500, { isStatic: true });
var paredDcha = Bodies.rectangle(1000, 500,2, 500, { isStatic: true });
// x e y son coordenadas del centro del objeto !!!!
// x , y ancho , alto
// add mouse control
var mouse = Mouse.create(render.canvas), // hay un canvas creado por defecto !!!!
mouseConstraint = MouseConstraint.create(engine, {
mouse: mouse,
constraint: { stiffness: 0.2, render: { visible: false }
}
});
// keep the mouse in sync with rendering
render.mouse = mouse;
World.add(world, mouseConstraint);
// parte publica
function init()
{
ground.restitution= 0.1; // es un valor medio de los dos cuerpos que chocan
paredIzq.render.strokeStyle="white"; // color de la linea de borde
paredDcha.render.strokeStyle="white"; // color de la linea de borde
/*
configurar los objetos
ballA.render.fillStyle = 'red';
ballA.render.lineWidth = 25;
ballB.render.opacity = 0.2;
ground.render.strokeStyle="white"; // color de la linea de borde
e.restitution=2;//capacidad de botar
m.restitution=0;
*/
World.add(engine.world, [ground,paredIzq, paredDcha, stack1,stack2,stack3,stack4 ]);
Engine.run(engine);
Render.run(render);//Continuously updates the render canvas on the requestAnimationFrame event.
// usamos doble click para crear objetos
// un solo click para pinchar y moverlos
// ya incorporado en mouseconstraint
canvas.addEventListener('dblclick', doubleClick, false);
draw();
}// fin de init.
function draw () // se repetira al llamarse cada cierto intervalo
{ // POSIBILIDAD DE USAR REQUESTANIMATIONFRAME
//requestAnimationFrame(draw); // llamada recursiva al draw
}
//requestAnimationFrame(draw); // ejecucion del draw
/////////////////////////////////////////////////////////////////////
/// FUNCIONES ////////////////////////////////////////////////////////
///////////////////////////////////////////////////////////////////////
//para añadir objetos con mouseclick-------------------------------------------
// OJO : esta funcion controla los sucesivos que se van añadiendo
// asi que aqui tambien hay que añadir la textura
function addPalabra ()
{
let nuevaPalabra = Bodies.rectangle(mouse.position.x, mouse.position.y, 50, 50,
{render: {sprite :{ texture : "imagenes/E.png", xScale : .1, yScale: .1}}});
return nuevaPalabra;
};
function doubleClick()
{
World.add(engine.world, addPalabra());
audioClick.play();
// para el tamaño Common.random(5, 15)
console.log("crea");
} //
//para chequear el tipo de un stack
function getType( inp ) {
var type = typeof inp, match;
var key;
if (type == 'object' && !inp) {
return 'null';
}
if (type == "object") {
if (!inp.constructor) {
return 'object';
}
var cons = inp.constructor.toString();
if (match = cons.match(/(\w+)\(/)) {
cons = match[1].toLowerCase();
}
var types = ["boolean", "number", "string", "array"];
for (key in types) {
if (cons == types[key]) {
type = types[key];
break;
}
}
}
return type;
};
body
{
height : 100%;
padding: 50px ;
margin: 20px;
/*background: #000000;*/
}
#links
{
/*aqui efectos del boton o lo que sea */
/*position:absolute;
top: 700px;
left: 950px;*/
font-family: 'Open Sans', sans-serif;
font-size: 17px;
text-align: center;
color: #000000;
line-height: 2;
letter-spacing: 1px;
float: right;
text-decoration: underline;
}
#instrucciones
{
font-family: 'Open Sans', sans-serif;
font-size: 15px;
}
.dialectica_minima
{
font-size:50px;
font-family:courier;
padding: 100px;
}
/* da estilo al back to works del final de los poemas*/
.margin-link
{
margin-top: 200px;
width: 50%
}
/* esto hace que la letra aparezca en un tamaño
razonable en pantallas mas pequeñas*/
@media (max-width:500px)
{
.dialectica_minima
{
font-size:24px;
}
.margin-link
{
width: 100%
}
}
<!DOCTYPE html>
<html lang="en" >
<head>
<meta charset="UTF-8">
<title> gradua la vista // vision check</title>
<!--etiqueta meta con view port
para que bootstrap las lea
redimensionamiento de la pagina
segun telefono tablet o pantalla-->
<meta name="viewport" content="width=device-width, user-scalable=no">
<canvas id="papel"></canvas>
<link rel="stylesheet" href="estilos/estiloPoemas.css">
<!-- Bootstrap CSS redimensionamiento segun pantalla-->
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/4.0.0-beta.3/css/bootstrap.min.css" integrity="sha384-Zug+QiDoJOrZ5t4lssLdxGhVrurbmBWopoEl+M6BdEfwnCJZtKxi1KgxUyJq13dy" crossorigin="anonymous">
</head>
<body onload="init();">
<!--llamadas a los archivos de sonido-->
<audio id = "click" src="imagenes/click.wav" ></audio>
<div class="back">
<a href="works.html" id = "links"> back to works</a>
</div>
<!--esto aparece abajo del todo -->
<div class = "textos"
<p class = "titulo" font face = "Courier, Arial, Verdana" size = "3"> GRADUA LA VISTA // VISION CHECK</p>
<p class = "instrucciones"font face = "Courier, Arial, Verdana" size = "1">
doble click dentro del poema para crear inestabilidad // double click inside the poem for instability </p>
<p class = "instrucciones"font face = "Courier, Arial, Verdana" size = "1"> pinchar y arrastrar un objeto para moverlo // click and drag to move objects
</p>
<p class = "instrucciones"font face = "Courier, Arial, Verdana" size = "1">
doble click para crear uno // double click for create objects</p>
</div>
<script src='https://cdnjs.cloudflare.com/ajax/libs/matter-js/0.11.0/matter.min.js'></script>
<script src="scripts/visionCheck.js"></script>
</body>
</html>