Error "Uncaught TypeError: object is not a function"

Hola!!

Veréis, estoy desarrollando una especie de minijuego por mi cuenta para ir practicando esto del canvas y tal, es un buscaminas (no vi ninguno por la red open source así que decidí desarrollarlo por mi cuenta para ver qué tal voy) pero me encuentro con un pequeño error, tengo este código:
  var minas = new Array();
  function minas(numero){
    for(i=0; i<numero; i++){
      minas[i] = Math.floor(Math.random()*100) + 1;
      console.log('Mina en el siguiente área: ' + minas[i]);
    }
  }

Con esa función quiero generar un array con el número de "minas" que se indique en la función. El juego tiene 100 "áreas" (que son cuadrados de 50x50px) y cada área tiene su "id" por decirlo de alguna forma (el primer cuadrado es el área 1, el siguiente el área 2... en realidad esto aún no lo he conseguido lograr, pero paso por paso XD).
El problema es que al invocar la función minas(10) para generar 10 minas me da el siguiente error:
Uncaught TypeError: object is not a function

¿Cuál es el fallo? Gracias!!
Hmmmm, que interesante tu desarrollo :) (algo nuevo), suerte :).

En cuanto al problema, ¿te dice en que línea se genera el error? Lo que pasa es que el error dice que estas intentando usar un objeto como una función, pero no veo eso en el código que muestras, o sea, en ese trozo, no hay error. Según el error, estás haciendo algo así en algún lugar:

var obj = new Object();

obj(parametro); // obj es un objeto y no una función.

Editado: que manera de repetir la palabra error en el segundo párrafo XD.
Gracias por los ánimos!! Probablemente ponga alguna que otra duda aquí, como dije simplemente estoy practicando :)

Me vino una luz de inspiración revisando el código y lo he conseguido solucionar :D No llamo a ningún objeto, no entiendo por qué daba ese error.
El problema era que el array donde guardo las posiciones de las minas se llamas minas, que es también el nombre de la función para generarlas. Cambie el nombre de la función por mina (o por cualquier otro serviría) y ya funciona :)
Aaaaah, jajajaja, esas cosas suelen pasar.

No llamo a ningún objeto, no entiendo por qué daba ese error

El error esta bien, pues el script no sabía si usar la función o el objeto y, en este caso, usó el objeto y por ende object is not a function / el objeto no es una función.
Aaah perfecto, ahora sí lo entiendo, gracias!! [:)]
Ahora me toca pensar cómo hacer para saber qué cuadrado pulsó el jugador y comprobar si tiene una mina o no (esa función ya la he hecho, me queda lo de saber que área pulsó... le daré al coco un poco y si no puedo volveré por aquí... XD
Calcula el clic en base a la posición de la cuadrícula añadiendo un listener cuando el usuario haga clic en el canvas (o en un área dentro del mismo - creo que esta explicación esta algo compleja, pero es más una pista que otra cosa :P).
Sí, si la base creo que ya la tengo más o menos montada... tengo esto:
function juego(ev){
  ...código...
  var x = ev.clientX - canvas.offsetLeft;
  var y = ev.clientY - canvas.offsetTop;

  for(a=0; a<area.length; a++){
    ...aquí tengo que comprobar qué área pulsó y convertirla en la variable "areapulsada"...
  }

  check(areapulsada); // Esta función la tengo definida después y comprueba si "areapulsada" coincide con algun del array de minas, entonces da la partida por perdida
}

...código...

canvas.addEventListener('click', juego, false);

Pero me falta lo que puse entre el for... cree otro archivo que contiene un array con las áreas, es algo así:
var area = [
  {
    id: '1',
    x: '50',
    y: '50'
  },
  {
    id: '2',
    x: '100',
    y: '50'
  },
...así hasta llegar al 100...
id: ID del área
x: ancho del canvas en el que termina el área
y: alto del canvas en el que termina el área

No sé si es el método más apropiado pero fue el que se me ocurrió... ahora me quedaría hacer una condicional para comprobar el ancho y el alto para saber a qué área pertenece supongo...?

EDIT:
Según mi extremadamente poca lógica, no debería funcionar así?
	for(a=0; a<area.length; a++){
	  if(y<=area[a]['y'] && x<=area[a]['x']){
	    areapulsada = area[a]['id']
	  } else {
	    areapulsada = undefined;
	  }
	}
Recorremos todo el array, y cada vez vamos comparando que si la posición de "y" es igual o menor que el máximo "y" de esa área, y además la posición de "x" es igual o menor que el máximo "x" de esa area, areapulsada tenga como valor el ID del área que pulsó, no? El problema es que siempre le asigna el valor de 100 a areapulsada [:?]
Hmmm debería funcionar, no veo lo malo :P.

Hay una forma de automatizar el proceso (no tener que crear las áreas a mano).

Crea una grilla con cuadrados de igual tamaño y después utiliza la posición top|left del contenedor para averiguar dónde se hizo clic (necesitas obtener una columna y una fila, en lugar de un área). Imagina algo como esto:

  1 2
1 - -
2 - -

donde cada guión es un cuadrado. Ahora, el clic se podría calcular así:

var tamanoCuadrado = 10; // Supongamos que cada cuadrado medirá 10 pixeles.
var clicX = evento.left - left,
     clicY = evento.top - top,
     row   = Math.floor(clicX / tamanoCuadrado) + 1,
     col    = Math.floor(clicY / tamanoCuadrado) + 1;

Para graficar un poco... imagina que la grilla es de 20 x 20 pixeles; cada cuadrado será de 10 x 10 (habrían 4 cuadros); la posición top,left de la grilla será 0,0. Imagina que se hace clic en la posición 5,8 (top,left). Nosotros sabemos que eso significa que se clickeo en la columna 1, fila 1 (coordenada 1,1), pero en el computador no es tan simple. Esto, traducido con el código anterior, quedaría así:

var clicX = 5 - 0,
     clicY = 8 - 0,
     row  = Math.floor(5 / 10) + 1; // Math.floor(5 dividido en 10) = 0
     col   = Math.floor(8 / 10) + 1; // Math.floor(8 divido en 10) = 0 - sin floor da un número decimal, que no me sirve.

console.log("Coordenada clickeada: " + [row,col]); // Coordenada clickeada: 1,1.

El + 1 en row y col es para que te coordenadas comenzando en 1 y no desde 0. Si no te importa eso, entonces no le agregues 1. También te sirve para generar las minas al azar y asignarles una posición a cada una :).

Teóricamente, debería funcionar con cualquier grilla, siempre y cuando sea cuadrada XD.

En el fondo, intenta imaginar que es el juego de "hundir los barcos" (batalla naval).
¡Muchas gracias! Desde el principio busqué la forma de automatizar el proceso pero no lo conseguía... de todos modos, he conseguido arreglarlo!! (Me daba pena tener que borrar todo el esfuerzo de haber creado el archivo con las áreas XD). Al final dejé la parte del código así:
  for(a=0; a<area.length; a++){
    if(y <= area[a]['y'] && x <= area[a]['x']){
      areapulsada = area[a]['id'];
      check(areapulsada);
      console.log('Área pulsada: ' + areapulsada); // Info consola
      return false;
    }
  }

Tenía que hacer la comprobación dentro del for :rolleyes: Y si no añadía return false; a parte de la área que pulsó mostraba en la consola tooodas las siguientes áreas del archivo XD
Gracias por todo!! Me queda añadirle unos cuántos estilos para que no se vea tan simplón y añadir los números esos que aparecen cuando clickeas y no es una bomba... (mira qué bien, NUNCA supe para que eran hasta que miré la wikipedia para informarme XD). Tendrá también un sistema de puntuaciones (el primero será el que haya acabado el juego en menos tiempo, etc...)

EDIT: Al parecer hay algún error en mi código [:(] La primera fila funciona bien (áreas 1,2,3,4,5,6,7,8,9,10), pero la segunda/tercera/cuarta definen la misma área (1,2,3,4,5,6,7,8,9,10) en vez de seguir sumando... Además la línea 6 da igual donde clickees, siempre define el área 20 (cuando debería ser 51,52,53,54,55,56,57,58,59,60)... el resto de líneas funcionan bien (va de 1 en 1) pero claro al estar el resto de línea mal la última cuadrícula cuadra en 70 y no en 100

EDIT2: Le he cambiado los valores de X e Y para que los mire correctamente y dejé el código así: (cambié client por page)
  var x = ev.pageX - canvas.offsetLeft;
  var y = ev.pageY - canvas.offsetTop;

  for(a=0; a<area.length; a++){
    if(y <= area[a]['y'] && x <= area[a]['x']){
      areapulsada = area[a]['id'];
      check(areapulsada);
      console.log('Área pulsada: ' + areapulsada); // Info consola
      return false;
    }
  }
Y todas las casillas funcionan bien menos las de la línea 3 que siempre marca 20 (y es la correspondiente a que de 21,22,23,24,25,26,27,28,29,30)... no entiendo cuál puede ser el fallo si el resto funciona bien :confused:
Solucionado lo anterior, tenía definido mal el 'y' del área 20 y ya funciona perfectamente [:)]
Que bueno, me alegro que lo hayas solucionado (y por tu cuenta) :).

(Me daba pena tener que borrar todo el esfuerzo de haber creado el archivo con las áreas XD)

Claro! Es de suponer :). El script que te mostré lo tuve que hacer para un juego en AS3 y la base es similar :P, así que quise mostrarte una forma de automatizarlo (igualmente faltaba la parte de añadir las minas).

Bueno, suerte con tu juego (esperamos poder jugar pronto, jejejeje).
Muchas gracias!! [:)]
También desarrollas juegos en AS3? [:o] Qué genio, sabes de todo jajaja [;)]

Gracias de nuevo y yo también lo espero!! A ver si mejoro algo en diseño que nunca se me dió bien y creo algo medianamente aceptable a la vista...jajajaja
También desarrollas juegos en AS3? Qué genio, sabes de todo jajaja

Jejeje, sí. Fueron unos juegos educativos (nada complicado en cuanto a gráficos). También he hecho algo en 3D AS3 -> http://nicomv.com/WORDPRESS/demo/.

No es que sepa de todo, si no que, teniendo una base en programación, cualquier lenguaje es fácil (todos tienen una base similar). Después de tener la base, basta con leer la documentación y puedes programar en cualquiera :P.

Hay muy pocos programadores que hacen un diseño agradable a la vista, así que no te aflijas por eso (yo aprendí que es mejor trabajar con alguien XD), así que sigue adelante :).
La verdad es que hace poco me planteé o aprender AS3 o Canvas, y me acabé decidiendo por este último jajaja. Qué bueno lo del 3D, al principio no pillaba de qué iba la cosa pero luego ya me enteré XD Está genial!!

Gracias por los ánimos!! Pronto me tenéis dando la vara por aquí otra vez XD
Aaaaah... en realidad a mi no me gusta AS3, pero el cliente quería que el código fuente estuviera oculto de alguna forma, así que me pidió hacerlo en Flash... claro que después le hice ver que no sacaba nada con intentar proteger el código, puesto que todo se debe descargar al computador del cliente e igualmente queda expuesto XD.

En fin... yo hubiera preferido aprender a usar Canvas XD.
Sí, con eso no protege mucho la verdad jajajaja. Nunca es tarde para aprender!! No? :rolleyes:
Mi objetivo a largo plazo era aprender a manejar Canvas con node.js + socket.io y crear una especie de mundo virtual online, pero la cosa es más complicada de lo que parece... no doy hecho ni un buscaminas XD
A ver cómo hago para hacer lo de los numeritos esos que aparecen al clickar sobre una casilla...si no lo dejaré como un buscaminas "al azar" (Nueva edición del buscaminas XDDD)
Sí, con eso no protege mucho la verdad jajajaja.

Es verdad XD. Además del requisito del cliente, también tomé en cuenta el hecho de que AS3 tenía motores gráficos hechos y buenos (actualizados), mientras que en Javascript no había (en ese momento) mucho donde elegir (teniendo en cuenta también las licencias, que muchas veces dicen "uso exclusivo para estudiantes" o "solo se permite un uso no comercial").

Nunca es tarde para aprender!! No?

Claro que no :)! Si piensas dedicarte a programador, ya sea como profesión o hobby, te darás cuenta que siempre estás aprendiendo algo nuevo. Por ejemplo, ahora estoy aprendiendo a programar en ASP.NET (C# o C Sharp) para desarrollar un trabajo.

En algún momento leí sobre Node.js, pero en aquel entonces era un trabajo "recién salido del horno", así que no habían librerías ni nada hecho XD, sólo funcionaba como servidor (yo lo usé como tal, de hecho) y en cuanto a socket.io, no tengo ni idea XD.

¿Sabes inglés? Si sabes, este sitio tiene un excelente repertorio de tutoriales que te ayudarán a diseñar y desarrollar juegos. Lo primero que te dicen es "comienza por un juego sencillo", como lo estás haciendo tú :).
Pues la verdad tenía pensado dedicarme a algo de esto en un futuro :) Pero querer y poder... cosas diferentes jejeje aunque con trabajo y esfuerzo quién sabe!!. Suerte con eso!! :D

Con el uso de eso en conjunto de alguna que otra librería más Mozilla se hizo un juego online XD http://browserquest.mozilla.org/

S
é lo básico... XD pero esa página es de juegos en flash (AS3 supongo) no? Y yo estoy utilizando Canvas!! XD pero como bien dijiste la base es para casi todos la misma, al fin y al cabo, todas las páginas recomiendan empezar por un juego pequeño, no sólo es casualidad :)
XD pero esa página es de juegos en flash (AS3 supongo) no?

No, para nada. Bueno, hay ejemplos en AS3, pero son sólo ejemplos, los que se pueden "traducir" a otros lenguajes :P.

En general, son más que nada tutoriales que te explican el cómo se hacen ciertas cosas. Por ejemplo, hay tutoriales que te enseñan la base para detectar las colisiones entre los actores (en el juego space invaders, el contacto entre una bala y una nave o enemigo). También te enseñan a programar juegos orientado a objeto (Javascript se basa en prototipos, pero la lógica es muy similar), así te acostumbras a ordenar mejor tus ideas. La mayoría te ayudan a mejorar la lógica y terminarás aprendiendo algoritmos eficientes :P (cosa que no ocurre en el juego GTA IV sin parches, por ejemplo - esta muy mal optimizado, si es que tiene alguna optimización, en comparación con juegos como The Elder Scrolls: Morrowind, Oblivion o Skyrim o la serie Crysis).

En fin, hay muchos tutoriales para comenzar :P.
Le echaré un vistazo a menudo para ir mejorando entonces :)
Gracias!! Ya he terminado casi todo del buscaminas (incluídas las puntuaciones), sólo me queda hacer lo de los numeritos en cada casilla... según wikipedia el número ese que sale al pulsar sobre una casilla es la suma de todas las minas que hay en las casillas de alrededor de esa. Veamos qué sale al final... jejejeje

Saludos!! Y nunca he jugado a ninguno de esos juegos :p (Al GTA en la PS2 nada más XD)
el número ese que sale al pulsar sobre una casilla es la suma de todas las minas que hay en las casillas de alrededor de esa

Wuajajaja, con razón nunca he ganado en el busca minas; no sabía lo que significaba XD.

Y nunca he jugado a ninguno de esos juegos :p (Al GTA en la PS2 nada más XD)

Jajajaj, intenta jugarlos si puedes, para que veas las diferencias en los gráficos, la velocidad, el modo de juego, etc. Te puedes hacer buenas ideas en base a esas otras.
Pues ya somos dos porque hasta que necesité saberlo para recrearlo... ni idea tenía XD
Podrías orientarme un poco para hacerlo de una forma sencilla? (Sé que te molesto mucho y lo siento pero es lo que toca XD) En principio pensé en crear un array que contenga las áreas 'vecinas' de la que pulsó el usuario (que serían 5 áreas(rodeándola) a menos que sea un borde o esquina) y ver las áreas vecinas para añadirlas al array (y posteriormente mirar si contienen una mina o no, esto ya sería lo más fácil). Hice algo así:
	  if(pulsaday < 50){
	    if(comprobar == 1){
	      vecinas = [2, 11, 12];
	    }
	    if(comprobar == 10){
	      vecinas = [9, 19, 20];
	    }
		if(comprobar > 1 && comprobar < 10){
		  vecinas = []; // no sé como continuar aquí automatizando el proceso XD
		}
	  }
pulsaday es la posición y donde pulsó el usuario y pulsadax la posición x.
Eso sería un ejemplo para hacer la primera línea pero no sé cómo continuar como pone en el comentario XD

Intentaré probar los juegos cuando consiga un ordenador decente, sobretodo el GTA y Skyrim que son los que más conozco :)
Hmmmm complicado... XD. ¿No sabes de antemano dónde estarán las minas? O sea, antes de comenzar a comprobar, debes saber dónde quedarán las minas.

En base a lo que tú has hecho, yo crearía un array nuevo con todos los casilleros, guardando la posición de las minas, números y espacios vacíos y luego compararía ese array con la acción del usuario. Creo que sería lo más simple.
Sí, antes de eso ya tengo guardado en un array llamado minas la posición de cada mina, de hecho puedes ver el código online que tengo hasta ahora: doodleo.site88.net/html5/buscaminas

C
reo que será más simple dejar el juego en formato azar, eliges una casilla y si aciertas acertaste... jajajajaja
Como vas con tu juego? Perdona por no responder antes, pero estoy algo ocupado en un trabajo... no estoy atrasado, pero si me pongo a revisar otras cosas me voy a atrasar :P, así que disculpa.

La próxima semana debería poder verlo, si es que puedes/quieres esperar y no lo has resuelto.
Pues la verdad no conseguí hacer nada porque entre que ando de fiestas (me cuadraron dos patrones de sitios a los que voy seguidos XD) y que no tengo ni idea de cómo automatizar el proceso... la solución muuuy enredada sería declarar a cada casilla sus vecinas y luego comprobarlas pero como comprenderás no voy a hacer eso porque me tiraría la hostia de tiempo XD

Y aquí sigo, por más que lo intento no consigo aclararme en cómo hacerlo...