Introducción al curso

1

¡Alto! Tenemos una nueva versión de este curso para ti

2

Bienvenidos al Curso de Fundamentos de JavaScript

3

Repositorio de este curso de fundamentos de JS

Primeros pasos en JavaScript

4

Variables

5

Variables: Strings

6

Variables: Números

7

Funciones

8

El alcance de las funciones

9

Objetos

10

Desestructurar objetos

11

Parámetros como referencia o como valor

12

Comparaciones en JavaScript

Estructuras de Control y Funciones

13

Condicionales

14

Funciones que retornan valores

15

Arrow functions

16

Estructuras repetitivas: for

17

Estructuras repetitivas: while

18

Estructuras repetitivas: do-while

19

Condicional múltiple: switch

Arrays

20

Introducción a arrays

21

Filtrar un array

22

Transformar un array

23

Reducir un array a un valor

Programación Orientada a Objetos en JavaScript

24

Cómo funcionan las clases en JavaScript

25

Modificando un prototipo

26

El contexto de las funciones: quién es this

27

La verdad oculta sobre las clases en JavaScript

28

Clases en JavaScript

Asincronismo

29

Funciones como parámetros

30

Cómo funciona el asincronismo en JavaScript

31

Cómo funciona el tiempo en JavaScript

32

¿Qué pasó con swapi.co?

33

Callbacks

34

Haciendo múltiples requests

35

Manejando el Orden y el Asincronismo en JavaScript

36

Manejo de errores con callbacks

37

Promesas

38

Promesas Encadenadas

39

Múltiples promesas en paralelo

40

Async-await: lo último en asincronismo

Juego de HTML

41

Comenzando el juego

42

Generando una secuencia de números

43

Iluminando la secuencia de colores

44

Obteniendo el input del usuario

45

Agregando la verificación del color elegido

46

Agregando los estados finales del juego

47

Conclusiones del curso

Complementos

48

Diferencias entre var, let y const

49

Memoización: ahorrando cómputo

50

¿Hace cuántos días naciste?

51

Funciones recursivas

52

Entiende los closures de JavaScript

53

Estructuras de datos inmutables

54

Cambiando de contexto al llamar a una función

55

¿Cuándo hace falta poner el punto y coma al final de la línea?

No tienes acceso a esta clase

¡Continúa aprendiendo! Únete y comienza a potenciar tu carrera

Agregando la verificación del color elegido

45/55
Recursos

Para agregar atributos al objeto principal en el que está nuestro código, basta con usar this, haciendo referencia al contexto de la clase, y agregar los atributos con un punto: this.atributo = valor

La verificación del color elegido la haremos creando y removiendo los eventos del click al pasar el juego a cada nuevo nivel.

Aportes 166

Preguntas 61

Ordenar por:

¿Quieres ver más aportes, preguntas y respuestas de la comunidad?

Soy el único que se está perdiendo?

código clase verificación del color elegido

const celeste = document.getElementById('celeste')
      const violeta = document.getElementById('violeta')
      const naranja = document.getElementById('naranja')
      const verde = document.getElementById('verde')
      const btnEmpezar = document.getElementById('btnEmpezar')
      const ULTIMO_NIVEL = 10
      
      class Juego {
        constructor() {
          this.inicializar()
          this.generarSecuencia()

          setTimeout(this.siguienteNivel(),500)
          
        }
        inicializar() {
            this.elegirColor= this.elegirColor.bind(this)
            this.siguienteNivel = this.siguienteNivel.bind(this)
            btnEmpezar.classList.add('hide')
          this.nivel= 1
          this.colores= {
            celeste,
            violeta,
            naranja,
            verde
          }
        }

        generarSecuencia(){
        this.secuencia= new Array(ULTIMO_NIVEL).fill(0).map(n=> Math.floor(Math.random()*4))
       }

       siguienteNivel(){
           this.subnivel = 0
           this.iluminarSecuencia()
           this.agregarEventosClick()
       }

       transformarNumeroAColor(numero)
       {

        switch(numero){

            case 0:
            return 'celeste'
            case 1:
            return 'violeta'
            case 2:
            return 'naranja'
            case 3:
            return 'verde'

        }

       }

       transformarColorANumero(color)
       {

        switch(color){

            case 'celeste':
            return 0
            case 'violeta':
            return 1
            case 'naranja':
            return 2
            case 'verde':
            return 3

        }

       }


       iluminarSecuencia(){

        for(let  i=0; i <  this.nivel; i++)
        {
            let color =this.transformarNumeroAColor(this.secuencia[i])
            
           setTimeout(() => {
            console.log(color)
            this.iluminarColor(color)
        },  1000 * i ) 
       
           
            }
       }
       
       iluminarColor(color){

        this.colores[color].classList.add('light')
        setTimeout(() => this.apagarColor(color),350)

       }

       apagarColor(color) {
           this.colores[color].classList.remove('light')
       }

       agregarEventosClick(){
           this.colores.celeste.addEventListener('click',this.elegirColor)
           this.colores.verde.addEventListener('click',this.elegirColor)
           this.colores.violeta.addEventListener('click',this.elegirColor)
           this.colores.naranja.addEventListener('click',this.elegirColor)
        }

        eliminarEventosClick(){
            this.colores.celeste.removeEventListener('click',this.elegirColor)
           this.colores.verde.removeEventListener('click',this.elegirColor)
           this.colores.violeta.removeEventListener('click',this.elegirColor)
           this.colores.naranja.removeEventListener('click',this.elegirColor)
      
        }

        elegirColor(ev){
           const nombreColor = ev.target.dataset.color
           const numeroColor = this.transformarColorANumero(nombreColor)
            
           this.iluminarColor(nombreColor)
           if(numeroColor === this.secuencia[this.subnivel]){

            this.subnivel++
            if(this.subnivel==this.nivel){
                this.nivel++
                this.eliminarEventosClick()
                if(this.nivel ==(ULTIMO_NIVEL + 1)){
                    //GANO
                }else{
                    setTimeout(this.siguienteNivel,1500)
                }
            }

           }else{
               //perdio
           }
        }
    
    }
      function empezarJuego() {
        window.juego = new Juego()
      
    }

se hacen algo complicadas las clases del proyecto porque damos demasidas cosas en una sola clase y no se aprecia muy bien la logica

En el 14:26 hace varias maromas para hacer lo del this pero con solo llamar a una arrow function no pasa eso

setTimeout(()=>this.siguienteNivel(),2000 )

Después de repetir 10 veces el vídeo logré entender muchísimo más.

Excelente! Espero algún día poder programar a este y mucho más nivel, se ve genial hasta ahora el juego. Soy nueva en esto y la verdad me causa intriga si podré hacer todo esto por mi cuenta 😃

Creo que la variable “subnivel” podría entenderse mejor como “número de aciertos”

Un pequeño cambio para no permitir que se haga click mientras se muestra la secuencia, primero quito la llamada a agregarEventosClick del método siguienteNivel.

    siguienteNivel() {
        this.subNivel = 0;
        this.iluminarSecuencia();
    }

Luego desde el método iluminarSecuencia envío el contador al método iluminarColor

    iluminarSecuencia() {
        for (let i=0; i<this.nivel; i++) {
            const color = this.transformarNumeroAColor(this.secuencia[i]);
            setTimeout(() => this.iluminarColor(color, i), 1000 * i);
        }
    }

Desde el método iluminarColor también envío ese contador al método apagarColor.

    iluminarColor(color, i) {
        this.colores[color].classList.add('light');
        setTimeout(() => this.apagarColor(color, i), 350);
    }

Finalmente en el método apagarColor valido si se esta apagando el último color de la secuencia para agregar los eventos de click con el método agregarEventosClick

    apagarColor(color, i) {
        this.colores[color].classList.remove('light');
        if ((i+1) === this.nivel) {
            this.agregarEventosClick();
        }
    }

Un pequeño detalle para la usabilidad del juego, la función ‘agregarEventosClick’ que se encuentra en la función ‘siguienteNivel’ debería de llamarse una vez se ilumine toda la secuencia completa y deje de iluminar el ultimó color, puesto que sino, podríamos hacer _click _ en un color mientras se esta iluminando la secuencia…

no se usan los parentesis en una funcion si esta dentro de un SETTIMEOUT() debido a que es un llamado a la referencia no una invocacion, minuto 11:45

Por que en algunas ocaciones cuando se usa el setTimeOut se usa una arrow function y en otras no?

Excelente.

A mi hijo de 2 años le encanta ver los colores del juego.

pucha, siento que solo copeo lo que hace sacha, soy el único ?
no se si estoy aprendiendo, siento que necesito practicar para poder asimilar tantos conceptos, tanta información. alguien sabe donde puedo obtener ejercicios de cada tema para practicar la lógica y todo ?

Es dificil comprender cuando invocas a la función y cuando solo hacer referencia a ella. Ejem: this.siguienteNivel vs this.siguienteNivel()
Como dicen, en algún momento todo hará click y entenderemos. Sigan practicando

Clase de hoy

const celeste = document.getElementById('celeste')
const violeta = document.getElementById('violeta')
const naranja = document.getElementById('naranja')
const verde = document.getElementById('verde')
const btnEmpezar=document.getElementById('btnEmpezar')
const ULTIMO_NIVEL = 10; 

class Juego{
    constructor(){
        this.inicializar()
        this.generarSecuencia()
        setTimeout(this.siguienteNivel, 500)
    } 
    inicializar(){  
        this.siguienteNivel = this.siguienteNivel.bind(this )   
        this.elegirColor = this.elegirColor.bind(this) 
        
        btnEmpezar.classList.add('hide')
        this.nivel = 1 
        this.colores = {
            celeste, 
            violeta,
            naranja,
            verde
        }    
    }  

    generarSecuencia(){
        this.secuencia = new Array(ULTIMO_NIVEL).fill(0).map(n => Math.floor(Math.random()*4))
    }

    siguienteNivel(){
        //inicializando el subnivel
        this.subnivel= 0
        this.iluminarSecuencia()
        this.agregarEventosClick()
    }

    transformarNumeroAColor(numero){
        switch (numero){
            case 0: 
                return 'celeste';
            case 1:
                return 'violeta';
            case 2:
                return 'naranja';
            case 3:
                return 'verde';
        }
    }

    transformarColorANumero(numero){
        switch (numero){
            case 'celeste': 
                return 0;
            case 'violeta':
                return 1;
            case 'naranja':
                return 2;
            case 'verde':
                return 3;
        }
    }

    iluminarSecuencia(){
        /*aplicamos i < this.nivel porque el numero del nivel 
		corresponde al numero de elementos que le usuario 
        modificara y tendra que seguir */
        
        for (let i = 0; i < this.nivel; i++){
            const color = this.transformarNumeroAColor(this.secuencia[i]) 
            // Ej: const color = "verde"

            setTimeout(() => this.iluminarColor(color), 1000*i)
			//colocar x * i nos permite acumular tiempo en función del for

        }
    }

    iluminarColor(color){
		//Colocando la clase que ilumina el color
        this.colores[color].classList.add('light')
        setTimeout(() => this.apagarColor(color), 350)
    }

    apagarColor(color){
		//Quitando la clase que ilumina el color
        this.colores[color].classList.remove('light')
    }

    agregarEventosClick(){
		//para obtener el input agregando un manejador de eventos (click)
        this.colores.celeste.addEventListener('click', this.elegirColor)
        this.colores.verde.addEventListener('click', this.elegirColor)
        this.colores.violeta.addEventListener('click', this.elegirColor)
        this.colores.naranja.addEventListener('click', this.elegirColor)
    }

    eliminarEventosClick(){
        //para remover el input agregado al manejador de eventos (click)
        this.colores.celeste.removeEventListener('click', this.elegirColor)
        this.colores.verde.removeEventListener('click', this.elegirColor)
        this.colores.violeta.removeEventListener('click', this.elegirColor)
        this.colores.naranja.removeEventListener('click', this.elegirColor)
    }
    
    //los metodos que se llaman en el event listener suelen tener en la funcion un parametro ev
    
    elegirColor(ev){ //le asignamos su target dataset // un evento (ev)
        const nombreColor = ev.target.dataset.color
        // daset almacena valores 

        const numeroColor = this.transformarColorANumero(nombreColor)
        this.iluminarColor(nombreColor)
        // algoritmo d la funcion del juego
        if (numeroColor === this.secuencia[this.subnivel]){
            this.subnivel++
            if (this.subnivel === this.nivel){
                this.nivel++
                this.eliminarEventosClick()
                if(this.nivel === (ULTIMO_NIVEL + 1)){
                    //gano
                } else {
                    setTimeout(this.siguienteNivel, 1500)
                }
            }
        } else {
            //perdio
        }
    }
}    
function empezarJuego(){    
    window.juego = new Juego()
}

Me eche toda la maña buscando un error y resulta que llame a subnivel en lugar de llamar a subNivel!

Está cabrón un error así jajaajajajja porque no entiendes porque la lógica no funciona si está bien pero al final fue error de dedo

excelente clase, tengo que verla otra vez ya que son demasiados pasos seguidos.

Perfecto!! 2da vez tomando el curso y todo va agarrando sentido!

Otra vez por acá jeje

ya está, podemos seguir el codigo.
Siembargo el poder establecer las observaciones, equivocaciones y solución de ellas solo serán posibles con mucha practica para acumular mucha experiencia. 😃

Otra solución para evitar el error del this es usando una arrow function que actue como la función parámetro.

setTimeout(() => this.siguienteNivel(),2000)

no se usan los parentesis en una funcion si esta dentro de un SETTIMEOUT() debido a que es un llamado a la referencia no una invocacion, minuto 11:45

otra solución para el error de setTimeout donde el this pasa a ser window es hacer el llamado con una arrow function:

setTimeout(() => this.nextLevel(), 2000); 

A mi me funcionó

En el método elegirColor() lo del bind() se evitaba invocando la el método dentro de una función del setTimeOut().

setTimeout(() => this.siguienteNivel(), 500);

La menera en la que lo explicó el profe era haciendo referencia al método.

setTimeout(this.siguienteNivel.bind(this), 500);

Aunque sé que puede que esto no funcione en todos los casos, así que mejor usen bind() :'d

Lo del dataset es algo nuevo para mi jaja

Me surgio este problema :
Juego.html:196 Uncaught TypeError: Cannot read property ‘classList’ of undefined
at Juego.iluminarColor (Juego.html:196)
at Juego.elegirColor (Juego.html:240)
revisando tengo el código igual, alguna solución?

me cuesta entender esto, creo que tratare de leer un poco mas sobre javascript para complementar al curso…😕

En el ultimo paso me daba un error por poner la funcion como el profesor como referencia “setTimeout( siguienteNivel, 500 ) )” entonces lo hice llamandolá “setTimeout( siguienteNivel(), 500))” y ya fue correcto. Aún no tengo claro la diferencia entre poner una función como referencia o llamarla.

Me di cuenta que puedes reemplazar el bind con arrow functions

  • bind
this.colors.celeste.addEventListener('click', this.chooseColor.bind(this))
  • arrow fucntion
this.colors.celeste.addEventListener('click', () => this.chooseColor)

Por qué Sacha pone en el constructor el timeout de esta manera:

setTimeout(this.siguienteNivel, 500)

y en el método iluminarSecuencia utiliza arrow functions?

setTimeout(() => this.iluminarColor(color), 1000 * i)

Gracias

Genial la clase. Aunque estoy en desacuerdo con el uso execiso del if y del switch.

agregar generarSecuencia en el else de Ultimo_Nivel para que en cada nivel el array sea distinto. Esto le da una mayor dificultad al juego!!

En el minuto 9:59 el profesor modifica el addEventListener() por removeAddEventListener(). Para poder modificar varios valores de una manera más optimizada lo pueden hacer haciendo lo siguiente:
*
hacer click en la parte que van a modificar, apretan alt y con esa tecla presionada van dando click en las demás lineas que van a modificar, así pueden tomar varias lineas al mismo tiempo y modificarlas también.

Comparto otra forma de hacer las funciones agregarEventosClick y eliminarEventosClick 😄

agregarEventosClick() {
        // Obtenemos los indices del objeto this.colores y le asignamos el evento
        Object.keys(this.colores).map((color) => {
            this.colores[color].addEventListener('click', this.elegirColor);
        });
    }
    
    eliminarEventosClick() {
        // Obtenemos los indices del objeto this.colores y le asignamos el evento
        Object.keys(this.colores).map((color) => {
            this.colores[color].removeEventListener('click', this.elegirColor);
        });
    }

Genial!! Es muy fácil perderse en el código debemos ser muy cuidadosos

Por acá dejo mi código


const btnEmpezar = document.getElementById('btnEmpezar')
const tituloNivel = document.getElementById('tituloNivel')
const celeste = document.getElementById('celeste')
const violeta = document.getElementById('violeta')
const naranja = document.getElementById('naranja')
const verde = document.getElementById('verde')
const ULTIMO_NIVEL = 10

class Juego {

    constructor() {
        this.inicializar()
        this.generarSecuencia()
        this.siguienteNivel()
    }

    inicializar() {
        btnEmpezar.classList.add('hide')
        this.nivel = 1
        this.elegirColor = this.elegirColor.bind(this)
        this.colores = [celeste, violeta, naranja, verde]
    }

    generarSecuencia() {
        this.secuencia = new Array(ULTIMO_NIVEL).fill(0).map(() => Math.floor(Math.random() * 4))
    }

    agregarEventoClick() {
        this.colores.forEach(color => color.addEventListener('click', this.elegirColor))
    }

    removerEventoClick() {
        this.colores.forEach(color => color.removeEventListener('click', this.elegirColor))
    }

    obtenerColordeNumero(numero) {
        let arrayColors = [celeste, violeta, naranja, verde]
        return arrayColors[numero]
    }

    elegirColor(evento) {
        this.parpadearColor(evento.target)
        let colorSeleccionado = evento.target.id
        let colorSecuencia = this.obtenerColordeNumero(this.secuencia[this.subnivel])

        if (colorSeleccionado === colorSecuencia.id) {
            this.subnivel++
            this.subirNivel()
        } else {
            tituloNivel.innerHTML = 'Perdiste!!!'
            this.removerEventoClick()
        }
    }

    subirNivel() {
        if (this.subnivel === this.nivel) {
            this.nivel++
            tituloNivel.innerHTML = `Nivel ${this.nivel}`
            this.evaluarGanador()
        }
    }

    evaluarGanador() {
        if (ULTIMO_NIVEL < this.nivel) {
            tituloNivel.innerHTML = 'Ganaste!!!'
            this.removerEventoClick()
        } else {
            this.siguienteNivel()
        }
    }

    parpadearColor(color) {
        color.classList.add('light')
        setTimeout(() => color.classList.remove('light'), 400)
    }

    iluminarSecuencia() {
        for (let index = 0; index < this.nivel; index++) {
            let color = this.obtenerColordeNumero(this.secuencia[index])
            setTimeout(() => this.parpadearColor(color), 600 * index)
        }
    }

    siguienteNivel() {
        this.subnivel = 0
        this.agregarEventoClick()
        setTimeout(() => this.iluminarSecuencia(), 1000)
    }
}

// Ejecucion App
function empezarJuego() {
    let juego = new Juego()
}

Excelente clase! Esto se está volviendo bastante complejo. 🙂

Bind se utilizar cuando estás declarando algún this dentro de cualquier función que javascript haya delegado al navegador.

Realmente me esta gustando mucho este juego saber que al principio ni imaginaba esto

ayuda!! me sale un error pero no logro identificar el problema

Acá el código

soy muy nuevo en la cuestión de programación

Yo coloque de la siguiente manera

setTimeout(() => this.siguienteNivel(), 1000)

Y me funcionó de lujo

Asi va quedando el código de JS, funcionando a la perfeccion.

const btnStart = document.getElementById('btnStart')
const skyblue = document.getElementById('skyblue')
const violet = document.getElementById('violet')
const orange = document.getElementById('orange')
const green = document.getElementById('green')
const lastLevel = 10;


class Game {
    constructor() {
        this.run = this.run.bind(this);
        this.run();
        this.generateSequence()
        setTimeout(this.nextLevel, 1000) 
    }
    run(){
        this.selectColor = this.selectColor.bind(this)
        this.nextLevel = this.nextLevel.bind(this)
        btnStart.classList.add('hide');
        this.level = 1;
        this.colors = {
            skyblue,
            violet,
            orange,
            green
        }
    }
    generateSequence(){
        this.sequence = new Array(lastLevel).fill(0).map(n => Math.floor(Math.random() * 4));
    }
    nextLevel(){
        this.subLevel = 0
        this.lightSequence()
        this.addEventClick()
    }
    transformNumberToColor(number){
        switch(number) {
            case 0: 
                return 'skyblue'
            case 1:
                return 'violet'
            case 2:
                return 'orange'
            case 3:
                return 'green'
        }
    }
    transformColorToNumber(color){
        switch(color) {
            case 'skyblue': 
                return 0
            case 'violet':
                return 1
            case 'orange':
                return 2
            case 'green':
                return 3
        }
    }
    lightSequence(){
        for (let i=0; i < this.level; i++){
            const color = this.transformNumberToColor(this.sequence[i])
            setTimeout(() => this.lightColor(color), 1000 * i)
        }
    }
    lightColor(color){
        this.colors[color].classList.add('light')
        setTimeout(() => this.turnoffColor(color), 350)
    }
    turnoffColor(color){
        this.colors[color].classList.remove('light');
    }
    addEventClick(){
        this.colors.skyblue.addEventListener('click', this.selectColor)
        this.colors.violet.addEventListener('click', this.selectColor)
        this.colors.orange.addEventListener('click', this.selectColor)
        this.colors.green.addEventListener('click', this.selectColor)
    }
    deleteEventClick() {
        this.colors.skyblue.removeEventListener('click', this.selectColor)
        this.colors.violet.removeEventListener('click', this.selectColor)
        this.colors.orange.removeEventListener('click', this.selectColor)
        this.colors.green.removeEventListener('click', this.selectColor)
    }

    selectColor(ev){
        const nameColor = ev.target.dataset.color;
        const numberColor = this.transformColorToNumber(nameColor)
        this.lightColor(nameColor)
        if(numberColor === this.sequence[this.subLevel]){
            this.subLevel ++
            if (this.subLevel === this.level) {
                this.level ++
                this.deleteEventClick();
                if(this.level === (lastLevel + 1)){
                    //Gano
                } else {
                    setTimeout(this.nextLevel, 1500)
                }
            }
        } else {
            //Perdio
        }
    }
}

function startGame(){

    window.game = new Game();
}

Presento un problema y es que el codigo me va bien hasta que se me presenta
un bug y es que el this me devuelve “undifined” la funcion de transformar color a numero,
quien entienda este bug, muy agradecido estaria, <chao mundo>

<code>elegirColor(ev){
                const nombreColor = ev.target.dataset.color;
                const numeroColor = this.transformarColoraNumero(nombreColor)
		//la funcion this.transformarColoraNumero me devuelve UNDIFENED ayudaaaaaa

                this.iluminarColor(nombreColor);

Al colocarle setTimeout a this.siguienteNivel() me genero error con el valor de this.

utilice un Arrow function y problema solucionado:

    setTimeout(() => {
      this.siguienteNivel();
    }, 500);

les comparto una forma de remover los events a los botones sin necesidad de repetirlo 4 veces, haciendo uso de la clase Object que me provee javascript

removeEventsClick() {
    const keyColors = Object.keys(this.colors)

    keyColors.forEach(color => {
      this.colors[color].removeEventsClick('click' , this.chooseColor)
    })  
  }

Es un código muy avanzado y sin pausas para aclarar algunas cosas esta clase, creo que el profe debió tomarlo con mas calma e ir haciendo mas lentamente el código para que pueda entenderse mejor y hacer ejercicios al final de cada clase, a los que empezamos recién nos complica bastante la lógica de este juego. Es un nivel Senior por ahí la dificultad

Me costo un poco entenderlo… pobre los nuevos nuevos en este mundo…

Excelente !

Código en JS

        /*DECLARACIÓN DE VARIABLES
=======================================*/

	
/*VARIABLE CONSTANTE CON ELEMENTOS OBTENIDOS POR ID
=====================================================*/          
const celeste = document.getElementById('celeste')
const violeta = document.getElementById('violeta')
const naranja = document.getElementById('naranja')
const verde = document.getElementById('verde')
const btnEmpezar=document.getElementById('btnEmpezar')
const ULTIMO_NIVEL = 10; 

 /* Usando la lbreria de sweetalert
 ==================================*/
            swal('Hola')

/*DECLARACIÓN DE CLASES PROTOTIPALES
==================================*/

class Juego{
    constructor(){
        this.inicializar = this.inicializar.bind(this)
        this.inicializar()
        this.generarSecuencia()
        setTimeout(this.siguienteNivel, 500)
    } 

    //Metodo que se ejecuta cuando empieza el juego
    inicializar(){  
        this.siguienteNivel = this.siguienteNivel.bind(this)   
        this.elegirColor = this.elegirColor.bind(this) 
        //.blid ahora el this esta atado al this de la clase prototipo juego
        
        //toggle es una forma de hacer un boton 
        this.toggleBtnEmpezar()
        this.nivel = 1 
        this.colores = {
            celeste, 
            violeta,
            naranja,
            verde
        }    
    } 
    
    toggleBtnEmpezar(){
        if(btnEmpezar.classList.contains('hide')){
            btnEmpezar.classList.remove('hide')
        } else {
            btnEmpezar.classList.add('hide')
        }
    }

    generarSecuencia(){
        this.secuencia = new Array(ULTIMO_NIVEL).fill(0).map(n => Math.floor(Math.random()*4))
        //Array Creamos un nuevo objeto Array con 10 casillas
		//fill rellenamos cada casilla con 0
        //Math random * 4 entrega un valor entre 0 y 3
        
        //map() solo funciona si el elemento del array tiene un valor asi sea 0
    }

    siguienteNivel(){
        //inicializando el subnivel
        this.subnivel= 0
        this.iluminarSecuencia()
        this.agregarEventosClick()
    }

    transformarNumeroAColor(numero){
        switch (numero){
            case 0: 
                return 'celeste';
				//Pedimos como parametro un numero aleatorio entre 0 y 4 que viene de this.secuencia()
            case 1:
                return 'violeta';
            case 2:
                return 'naranja';
            case 3:
                return 'verde';
        }
    }

    transformarColorANumero(numero){
        switch (numero){
            case 'celeste': 
                return 0;
				//Pedimos como parametro un numero aleatorio entre 0 y 4 que viene de this.secuencia()
            case 'violeta':
                return 1;
            case 'naranja':
                return 2;
            case 'verde':
                return 3;
        }
    }

    iluminarSecuencia(){
        /*aplicamos i < this.nivel porque el numero del nivel 
		corresponde al numero de elementos que le usuario 
        modificara y tendra que seguir */
        
        for (let i = 0; i < this.nivel; i++){
            const color = this.transformarNumeroAColor(this.secuencia[i]) 
            // Ej: const color = "verde"

            setTimeout(() => this.iluminarColor(color), 1000*i)
			//colocar x * i nos permite acumular tiempo en función del for

        }
    }

    iluminarColor(color){
		//Colocando la clase que ilumina el color
        this.colores[color].classList.add('light')
        setTimeout(() => this.apagarColor(color), 350)
    }

    apagarColor(color){
		//Quitando la clase que ilumina el color
        this.colores[color].classList.remove('light')
    }

    agregarEventosClick(){
		//para obtener el input agregando un manejador de eventos (click)
        this.colores.celeste.addEventListener('click', this.elegirColor)
        this.colores.verde.addEventListener('click', this.elegirColor)
        this.colores.violeta.addEventListener('click', this.elegirColor)
        this.colores.naranja.addEventListener('click', this.elegirColor)
    }

    eliminarEventosClick(){
        //para remover el input agregado al manejador de eventos (click)
        this.colores.celeste.removeEventListener('click', this.elegirColor)
        this.colores.verde.removeEventListener('click', this.elegirColor)
        this.colores.violeta.removeEventListener('click', this.elegirColor)
        this.colores.naranja.removeEventListener('click', this.elegirColor)
    }
    
    //los metodos que se llaman en el event listener suelen tener en la funcion un parametro ev
    
    elegirColor(ev){ //le asignamos su target dataset // un evento (ev)
        const nombreColor = ev.target.dataset.color
        // daset almacena valores 

        const numeroColor = this.transformarColorANumero(nombreColor)
        this.iluminarColor(nombreColor)
        // algoritmo d la funcion del juego
        if (numeroColor === this.secuencia[this.subnivel]){
            this.subnivel++
            if (this.subnivel === this.nivel){
                this.nivel++
                this.eliminarEventosClick()
                if(this.nivel === (ULTIMO_NIVEL + 1)){
                    this.ganoElJuego()
                } else {
                    setTimeout(this.siguienteNivel, 1500)
                }
            }
        } else {
            this.perdioElJuego()
        }
    }

    ganoElJuego(){
        swal('Platzi','Felicitaciones Ganaste', 'success')
        .then(this.inicializar)
    }

    perdioElJuego(){
        swal('Platzi','Lo lamentamos, Perdiste :(', 'error')
        .then (()=> {
            this.eliminarEventosClick()
            this.inicializar()
        })
    }
}    

/*DECLARACIÓN DE FUNCIONES
========================================================*/

function empezarJuego(){    
    window.juego = new Juego()
}

Que chingón está este curso. lo voy a tener que repetir para entender algunas cosas pero que bueno!!! Este juego me motiva mucho.

        class Juego {
            constructor() {
                this.inicializar()
                this.generarSecuencia()
                setTimeout(this.siguienteNivel, 500)
                
            }

            inicializar() {
                this.siguienteNivel = this.siguienteNivel.bind(this)
                this.elegirColor = this.elegirColor.bind(this)
                btnEmpezar.classList.add('hide')
                this.nivel = 1
                this.colores = {
                    celeste,
                    violeta,
                    naranja,
                    verde
                }
            }

            generarSecuencia() {
                this.secuencia = new Array(ULTIMO_NIVEL).fill(0).map(n => Math.floor(Math.random() * 4))
            }

            siguienteNivel() {
                this.subnivel = 0
                this.iluminarSecuencia()
                this.agregarEventosClick()
            }

            transformarNumeroAColor(numero) {
                switch (numero) {
                    case 0:
                        return 'celeste'
                    case 1:
                        return 'violeta'
                    case 2:
                        return 'naranja'
                    case 3:
                        return 'verde'
                }
            }

            transformarColorANumero(color) {
                switch (color) {
                    case 'celeste':
                        return 0
                    case 'violeta':
                        return 1
                    case 'naranja':
                        return 2
                    case 'verde':
                        return 3
                }
            }

            iluminarSecuencia() {
                for (let i = 0; i < this.nivel; i++) {
                    const color = this.transformarNumeroAColor(this.secuencia[i])
                    setTimeout(() => this.iluminarColor(color), 1000 * i)
                }
            }

            iluminarColor(color) {
                this.colores[color].classList.add('light')
                setTimeout(() => this.apagarColor(color), 350)
            }

            apagarColor(color) {
                this.colores[color].classList.remove('light')
            }

            agregarEventosClick() {
                this.colores.celeste.addEventListener('click', this.elegirColor)
                this.colores.violeta.addEventListener('click', this.elegirColor)
                this.colores.naranja.addEventListener('click', this.elegirColor)
                this.colores.verde.addEventListener('click', this.elegirColor)
            }

            eliminarEventosClick() {
                this.colores.celeste.removeEventListener('click', this.elegirColor)
                this.colores.violeta.removeEventListener('click', this.elegirColor)
                this.colores.naranja.removeEventListener('click', this.elegirColor)
                this.colores.verde.removeEventListener('click', this.elegirColor)
            }

            elegirColor(ev) {
                const nombreColor = ev.target.dataset.color
                const numeroColor = this.transformarColorANumero(nombreColor)
                this.iluminarColor(nombreColor)
                if (numeroColor === this.secuencia[this.subnivel]) {
                    this.subnivel++
                    if (this.subnivel === this.nivel) {
                        this.nivel++
                        this.eliminarEventosClick()
                        if (this.nivel === (ULTIMO_NIVEL + 1)) {
                            //gano el juego
                        } else {
                            setTimeout(this.siguienteNivel, 1500) 
                        }
                    }
                } else {
                    //perdio e juego
                }
            }

        }

Yo lo hice de una forma distinta.utilicé el mismo método de conversión de número a string…en el código la explicación:

const verde = document.getElementById('verde');
const celeste = document.getElementById('celeste');
const violeta = document.getElementById('violeta');
const naranja = document.getElementById('naranja');
const btnEmpezar = document.getElementById('btnEmpezar');

class Juego {
  constructor() {
    this.inicializar();
    this.generarSecuencia();
    setTimeout(() => {
      this.siguienteNivel();
      
    }, 500);
  }
  inicializar() {
    // Se esconde el boton
    btnEmpezar.classList.add('hide');
    // Se define el maximo de niveles
    this.nivelMaximo = 3;
    // Contador de nivel
    this.contadorDeNivel = 1;
    // Siempre se comenzara a revisar por el color que se encuentre en la posicion 0 del array
    this.arrayPosValidaIni = 0;
    // Se definen los colores en un objeto
    this.colores = {
      // celeste : celeste, como tiene los mismos nombres JS
      // lo interpreta automaticamente de que se trata del Scope Global
      // En caso de usar nombres distintos, colorCeleste : celest
      celeste,
      verde,
      violeta,
      naranja,
    };
    // Con esto nos evitamos de colocarlo por cada color.
    // Ya queda vinculado de esta forma al this del constructor
    this.elegirColor = this.elegirColor.bind(this);
  }

  // Generar de forma aleatoria la secuencia en un array
  generarSecuencia() {
    // Se crea el array segun el nivel, con el fill(se inicializa en 0)
    // con el map se modifica los valores del array
    // Y se obtiene un numero aleatorio entre el 0 y 3
    this.secuencia = new Array(this.contadorDeNivel).fill(0).map((n) => Math.floor(Math.random() * 4));
    console.log(this.secuencia);
  }

  //   Metodo que se encargara de activar
  //   la iluminacion de los colores
  siguienteNivel() {
    this.iluminarSecuencia();

    // Agregamos metodo que activa el evento Click sobre los colores
    this.agregarEventoClick();
  }

  obteneterColor(numero) {
    switch (numero) {
      case 0:
        return 'celeste';
      case 1:
        return 'verde';
      case 2:
        return 'violeta';
      case 3:
        return 'naranja';
    }
  }
  iluminarSecuencia() {
    // se arma un curso que se encargara de
    // de iluminar los colores segun el nivel
    // es decir, si el nivel 1, entonces solo se
    // recorrera una sola vez y solo encedera un color, si es nivel 2
    // seran 2 colores los que se encenderan.
    for (let index = 0; index < this.contadorDeNivel; index++) {
      // Se le pasa al metodo el valor del index(nivel)
      // para que vaya recuperando a que color corresponde
      // en la posicion del array de colores de secuencia
      const color = this.obteneterColor(this.secuencia[index]);
      // Ahora llamamos metodo que se encargara de setear la propieda
      // al color que corresponda
      setTimeout(() => {
        this.iluminarColor(color);
      }, 1000 * index);
    }
  }

  iluminarColor(color) {
    this.colores[color].classList.add('light');
    setTimeout(() => {
      this.apagarColor(color);
    }, 350);
  }
  apagarColor(color) {
    this.colores[color].classList.remove('light');
  }

  agregarEventoClick() {
    // Agregando el bind(this) es para no perder la referencia del this del constructor
    // var _this = this
    this.colores.celeste.addEventListener('click', this.elegirColor);
    this.colores.violeta.addEventListener('click', this.elegirColor);
    this.colores.naranja.addEventListener('click', this.elegirColor);
    this.colores.verde.addEventListener('click', this.elegirColor);
  }

  eliminarEventoClick() {
    // Agregando el bind(this) es para no perder la referencia del this del constructor
    // var _this = this
    this.colores.celeste.removeEventListener('click', this.elegirColor);
    this.colores.violeta.removeEventListener('click', this.elegirColor);
    this.colores.naranja.removeEventListener('click', this.elegirColor);
    this.colores.verde.removeEventListener('click', this.elegirColor);
  }

  perdioReiniciarJuego() {
    this.eliminarEventoClick();
    console.log ('Vuelva a iniciar');
  }
  elegirColor(ev) {
    //console.log(ev);
    //console.log(this);
    //console.log(this.secuencia[1]);

    // Aqui obtenemos el color eligio el usuario
    // el target.dataset.color lo que hace es traer el valor
    // que se encuentra en el data del xml, para este caso
    // existe div que tiene data-color="violeta", si fuese data-hola="hola"
    // entonces seria target.dataset.hola
    const nombreColorEvBtnClick = ev.target.dataset.color;
    console.log(`Color evento click ${nombreColorEvBtnClick}`);
    // En vez de crear otro metodo que traide de string el id, la logica
    // del juego es que siempre validaremos que el usuario acierte los colores
    // segun el orden presentado, por lo que ese orden ya lo tenemos asi que lo que
    // haremos es obtener el nombre de la secuencia y compararlo con el presionado
    // por el jugador y si es igual, aunmentar de nivel y resetear
    const colorNombreSecuencia = this.obteneterColor(this.secuencia[this.arrayPosValidaIni]);
    console.log(`Color segun nivel en el array ${colorNombreSecuencia}`);
    
      
    
    // Validamos si el color presionado es igual al primer color de la secuencia
    if (colorNombreSecuencia === nombreColorEvBtnClick) {
      console.log('Color OK');
     
      console.log ('contadorDeNivel ' + this.contadorDeNivel);
      console.log ('arrayPosValidaIni ' + this.arrayPosValidaIni);
      console.log ('nivelMaximo ' + this.nivelMaximo);
      
      if  (this.arrayPosValidaIni === (this.contadorDeNivel - 1)){
        // Gano el juego
        if (this.contadorDeNivel === this.nivelMaximo) {
          console.log ('Ganó el Juego');
          this.eliminarEventoClick();
        } else {
          this.contadorDeNivel += 1;
          this.arrayPosValidaIni = 0;
          this.generarSecuencia();
          this.siguienteNivel();
          console.log (`Siguiente nivel ${this.contadorDeNivel}`);
          
        }

      } else {
        // Se incrementa la posicion del array para conocer cual fue el color generado
        // aleatoriamente y contra que se validara si el usuario presiona el mismo color
        this.arrayPosValidaIni += 1;
      }
    } else {
      console.log('Color NOK');
      this.perdioReiniciarJuego();
    }
  }
}

function empezarJuego() {
  var juego = new Juego();
}
const celeste = document.getElementById('celeste')
const violeta = document.getElementById('violeta')
const naranja = document.getElementById('naranja')
const verde = document.getElementById('verde')
const btnEmpezar = document.getElementById('btnEmpezar')
const ULTIMO_NIVEL = 10

class Juego {
  constructor(){
    this.inicializar()
    this.generarSecuencia()
    setTimeout(this.siguienteNivel, 500)
  }
  inicializar(){
    this.siguienteNivel = this.siguienteNivel.bind(this)
    this.elegirColor = this.elegirColor.bind(this)
    btnEmpezar.classList.add('hide')
    this.nivel = 1
    this.colores = {
      celeste,
      violeta,
      naranja,
      verde
    }
  }
  generarSecuencia(){
    //Una forma de generar Arrays de numeros aleatorios entre 0 y 3
    this.secuencia = new Array(ULTIMO_NIVEL).fill(0).map(n => Math.floor(Math.random() *4))
  }
  siguienteNivel(){
    this.subnivel = 0
    this.iluminarSecuencia()
    this.agregarEventosClick()
  }

  transformarNumeroAColor(numero){
    switch (numero) {
      case 0:
        return 'celeste'
      case 1:
        return 'violeta'
      case 2:
        return 'naranja'
      case 3:
        return 'verde'
    }
  }

  transformarColorANumero(color){
    switch (color) {
      case 'celeste':
        return 0
      case 'violeta':
        return 1
      case 'naranja':
        return 2
      case 'verde':
        return 3
    }
  }
  iluminarSecuencia(){
    for (let i = 0; i < this.nivel; i++){
      const color = this.transformarNumeroAColor(this.secuencia[i])
      console.log(color)
      setTimeout(() => this.iluminarColor(color), 1000 * i)
    }
  }
  iluminarColor(color){
    this.colores[color].classList.add('light')
    setTimeout(() => this.apagarColor(color), 350)
  }
  apagarColor(color){
    this.colores[color].classList.remove('light')
  }
  agregarEventosClick(){
    this.colores.celeste.addEventListener('click', this.elegirColor)
    this.colores.verde.addEventListener('click', this.elegirColor)
    this.colores.violeta.addEventListener('click', this.elegirColor)
    this.colores.naranja.addEventListener('click', this.elegirColor)
  }

  eliminarEventosClick(){
    this.colores.celeste.removeEventListener('click', this.elegirColor)
    this.colores.verde.removeEventListener('click', this.elegirColor)
    this.colores.violeta.removeEventListener('click', this.elegirColor)
    this.colores.naranja.removeEventListener('click', this.elegirColor)
  }

  elegirColor(ev){
    const nombreColor = ev.target.dataset.color
    const numeroColor = this.transformarColorANumero(nombreColor)
    this.iluminarColor(nombreColor)
    if(numeroColor === this.secuencia[this.subnivel]){
      this.subnivel++
      if(this.subnivel === this.nivel){
        this.nivel++
        this.eliminarEventosClick()
        if(this.nivel === (ULTIMO_NIVEL + 1)){
          //Gana
        } else {
          setTimeout(this.siguienteNivel, 1500)
        }
      }
    } else {
      //perdio
    }
  }
}

function empezarJuego(){
  juego = new Juego()
}

Este proyecto es bellisimo :’)

Porqué el proyecto funciona incluso cuando elimino a parte donde se declara las constantes para obtener los elementos de dom?

// const btnCeleste = document.getElementById('btnCeleste')
// const btnVioleta = document.getElementById('btnVioleta')
// const btnNaranja = document.getElementById('btnNaranja')
// const btnVerde = document.getElementById('btnVerde')
const btnEmpezar = document.getElementById('btnEmpezar')
const ULTIMO_NIVEL = 10

aún comentando esa parte sigue reconociendo los eventos click sobre los botones de colores

me ayudan a arreglar esto ? me saltaron 10 errores al poner los condicionales, se me rompio todo el codigo 😕

btnEmpezar = document.getElementById('btnEmpezar')


const celeste = document.getElementById('celeste')
const violeta = document.getElementById('violeta')
const naranja = document.getElementById('naranja')
const verde = document.getElementById('verde')
const ULTIMO_NIVEL = 10





class Juego {
    constructor(){
        this.inicializar()
        this.generarSecuencia()
        this.siguienteNivel()
    }

    inicializar(){
        this.elegirColor = this.elegirColor.bind(this)
        btnEmpezar.classList.add('hide')
        this.nivel = 1
        this.colores = {
            //como propiedad javascript al guardar objetos con su mismo nombre "violeta: violeta," te permite poner solo 1 vez el nombre para ahorrar codigo

            celeste,
            violeta,
            naranja,
            verde
        }
    }
    generarSecuencia(){
        this.secuencia = new Array (ULTIMO_NIVEL).fill(0).map(n => Math.floor(Math.random() * 4))
    }
    siguienteNivel(){
        this.subnivel = 0
        this.iluminarSecuencia()
        this.agregarEventrosClick()
    }
    transformarNumeroAColor(numero){
        switch (numero) {
            case 0:
                return 'celeste'
            case 1: 
                return 'violeta'
            case 2:
                return 'naranja'
            case 3:
                return 'verde'
        }

    }

    transformarColorANumero(color){
        switch (color) {
            case 'celeste':
                return 0
            case 'violeta': 
                return 1
            case 'naranja':
                return 2
            case 'verde':
                return 3
        }
    iluminarSecuencia(){
        for (let i = 0; i < this.nivel; i++){
            const color = this.transformarNumeroAColor(this.secuencia[i])
           setTimeout(() =>  this.iluminarColor(color), 1000 * i)
           
        }
    }
    apagarColor(color){
        this.colores[color].classList.remove('light')
    }
    agregarEventrosClick(){
        this.colores.celeste.addEventListener('click', this.elegirColor)
        this.colores.violeta.addEventListener('click', this.elegirColor)
        this.colores.naranja.addEventListener('click', this.elegirColor)
        this.colores.verde.addEventListener('click', this.elegirColor)
    }
    eliminarEventrosClick(){
        this.colores.celeste.removeEventListener('click', this.elegirColor)
        this.colores.violeta.removeEventListener('click', this.elegirColor)
        this.colores.naranja.removeEventListener('click', this.elegirColor)
        this.colores.verde.removeEventListener('click', this.elegirColor)

    }
    elegirColor(ev){
        const nombreColor = ev.target.dataset.color
        const numeroColor = this.transformarColorANumero(nombreColor)
        
        this.iluminarColor(nombreColor)
        
        if(numeroColor === this.secuencia [this.subnivel]){
            this.subnivel ++
            if (this.subnivel === this.nivel){
                this.nivel++
                // this.eliminarEventosClick()
                if( this.nivel === (ULTIMO_NIVEL + 1)){
                    //gano!
                }
                else { 
                    this.siguienteNivel()

                }

            }
          
            }  else {
                //perdio
        }
    }
    }
    iluminarColor(color){
        this.colores[color].classList.add('light')
        setTimeout(() => this.apagarColor(color), 350)
    }
}
function empezarJuego () {
    window.juego = new Juego()
}

Muy buena clase!

quisiera saber si la unica forma de saber que alguna funcion cambis el this del objeto al this window por ejemplo es mediante testing probando con los break point?

Lo hice siguiendo lo que hizo el profesor, sin embargo cuando lo ejecuto al pasar al siguiente nivel e intento jugar, el programa siempre pasa a la condicion de perder, a alguien mas lo ocurrio lo mimo o que escribi mal del codigo?

<script>
      const celeste = document.getElementById('celeste');
      const violeta = document.getElementById('violeta');
      const naranja = document.getElementById('naranja');
      const verde = document.getElementById('verde');
      const btnEmpezar = document.getElementById('btnEmpezar');
      const ULTIMO_NIVEL = 1;

      class Juego {
        constructor() {
            this.inicializar = this.inicializar.bind(this);
            this.inicializar();
            this.generarSecuencia();
            setTimeout(this.siguienteNivel, 500);
        }    

        inicializar() {
            this.elegirColor = this.elegirColor.bind(this);
            this.siguienteNivel = this.siguienteNivel.bind(this);
            this.toggleBtnEmpezar();
            this.nivel = 1;
            this.colores = {
                celeste,
                violeta,
                naranja,
                verde,
            };
        }

        toggleBtnEmpezar() {
            if(btnEmpezar.classList.contains('hide')) {
                btnEmpezar.classList.remove('hide)');
            }else{
                btnEmpezar.classList.add('hide');   
            }
        }

        //genera la secuencia de colores a seguir 0=celeste 1=violeta 2=naranja 3=verde.
        generarSecuencia(){
            this.secuencia = new Array(ULTIMO_NIVEL)
            .fill(0)
            .map(n => Math.floor(Math.random ()  * 4));
            console.log(this.secuencia);
        }

        siguienteNivel(){
            this.subNivel = 0
            this.iluminarSecuencia(); 
            this.agregarEventosClick();

        }

        transformarNumeroAColor(numero) { //transforma los numeros de la secuencia de math.random asignando los colores

            switch (numero) {
                case 0: 
                    return 'celeste';
                case 1:
                    return 'violeta';
                case 2:
                    return 'naranja';
                case 3:
                    return 'verde';        
                    
            }   
        }

        transformarColorANumero(color) { //transforma los colores a numero

            switch (color) {
                case 'celeste': 
                    return 0;
                case 'violeta':
                    return 1;
                case 'naranja':
                    return 2;
                case 'verde':
                    return 3;        
                    
            }   
        }



        iluminarSecuencia() {
            for(let i = 0; i < this.nivel; i ++){
                const color = this.transformarNumeroAColor(this.secuencia[i])
                setTimeout(() => this.iluminarColor(color), 1000 * i);
            }
        }

        iluminarColor(color){
            this.colores[color].classList.add('light'); //utiliza el atributo light del css para resaltar color
            setTimeout(() => this.apagarColor(color), 350);
        }

        apagarColor(color) {
            this.colores[color].classList.remove('light')
        }

        agregarEventosClick() {
            this.colores.celeste.addEventListener('click', this.elegirColor);
            this.colores.verde.addEventListener('click', this.elegirColor);
            this.colores.violeta.addEventListener('click', this.elegirColor);
            this.colores.naranja.addEventListener('click', this.elegirColor);
        }

        eliminarEventosClick() {
            this.colores.celeste.removeEventListener('click', this.elegirColor);
            this.colores.verde.removeEventListener('click', this.elegirColor);
            this.colores.violeta.removeEventListener('click', this.elegirColor);
            this.colores.naranja.removeEventListener('click', this.elegirColor);
        }

        ganoElJuego(){
            swal('Platzi','Felicitaciones, ganaste el juego!', 'success')
              .then(this.inicializar());
        };

        perdioElJuego(){
            swal('Platzi','Lo lamentamos, perdiste :(', 'error')
              .then( ()=> {
                this.eliminarEventosClick();
                this.inicializar();
            });   
        };


        elegirColor(ev){
          const nombreColor = ev.target.dataset.color;
          const numeroColor = this.transformarColorANumero(nombreColor);

          this.iluminarColor(nombreColor);
          if (numeroColor === this.secuencia[this.subNivel]){
             this.subNivel++;                       
            if (this.subNivel === this.nivel){
                this.nivel++;
                this.eliminarEventosClick();
             
                if(this.nivel === (ULTIMO_NIVEL + 1)){
                    this.ganoElJuego();
                }else{   
                   setTimeout(this.siguienteNivel(), 1500);
                }   
            }else{
                this.perdioElJuego();  
            }
          }
        }
       

    }
      function empezarJuego() {
       window.juego = new Juego(); //inicio de juego desde el objeto global window
      }
    </script>

Tengo la siguiente duda y es que subnivel se está incrementando dentro del método elegirColor(), y en éste mismo método también se llama a siguienteNivel() sí es que el usuario ha elegido los colores correctamente.

Mi duda es que en siguienteNivel() se ejecuta de 1ro ésta instrucción: this.subnivel = 0, con lo que yo creía que siempre que entrará a siguienteNivel(), this.subnivel siempre volvería a tener el valor de 0.

nextLevel() {
        this.sublevel = 0
        this.illuminateSquence()
        this.addEventsClick()
    }

Pero realizando el console.log(this.subnivel) veo que está variable no se resetea sino que recuerda el valor y por eso la lógica del juego funciona.

chooseColor(ev) {
        const nameOfColor = ev.target.dataset.color
        const numberOfColor = this.transformColorToNumber(nameOfColor)
        this.illuminateColor(nameOfColor)

        if (numberOfColor === this.sequence[this.sublevel]) {
            this.sublevel++
            console.log(this.sublevel)
            if (this.sublevel === this.level) {
                this.level++
                this.removeEventsClick()
                if (this.level === (ULTIMO_NIVEL + 1)) {
                    //Ganó
                } else {
                    // setTimeout(this.nextLevel.bind(this), 2000)
                    setTimeout(() => this.nextLevel(), 1500)
                }
            }
        } else {
            //Perdió
        }
    }

Quisiera saber porque pasa ésto!

Hola a todos, tengo una duda, en la funcion elegirColor() al utilizar la funcion siguienteNivel() dentro del setTimeOut(), la llame dentro de una arrow function asi:

setTimeout(() => {this.siguienteNivel()}, 2000);

y tambien me funciono sin problemas, esto esta bien? o es recomendable hacerlo como en el video agregando el bind(this)?

Me falla en el momento de la iluminación… he revisado el codigo varias veces y creo k lo tengo idéntico…

<code>

<!DOCTYPE html>
<html>
<head>
<meta charset=“utf-8”>
<title>Leonardo Dice</title>
<style>
body {
margin: 0;
background: #dedede;
display: flex;
align-items: center;
height: 100vh;
}

  .gameboard {
    height: 100vh;
    width: 100vh;
    border-radius: 50%;
    overflow: hidden;
    margin: 0 auto;
    max-height: 60vh;
    max-width: 60vh;
  }

  .color {
    width: 50%;
    height: 50%;
    display: inline-block;
  }

  .left {
    float: left;
  }

  .right {
    float: left;
  }

  .celeste {
    background: #22a6b3;
  }

  .celeste.light {
    background: #7ed6df;
  }

  .violeta {
    background: #be2edd;
  }

  .violeta.light {
    background: #e056fd;
  }

  .naranja {
    background: #f0932b;
  }

  .naranja.light {
    background: #ffbe76;
  }

  .verde {
    background: #6ab04c;
  }

  .verde.light {
    background: #badc58;
  }

  .btn-start {
    width: 400px;
    height: 100px;
    background: #ecf0f1;
    color: #2c3e50;
    font-size: 2.5rem;
    position: absolute;
    top: calc(50% - 50px);
    left: calc(50% - 200px);
  }

  .hide {
    display: none;
  }
</style>

</head>
<body>
<div class=“gameboard”>
<div id=“celeste” class=“color celeste left” data-color=“celeste”></div>
<div id=“violeta” class=“color violeta right” data-color=“violeta”></div>
<div id=“naranja” class=“color naranja left” data-color=“naranja”></div>
<div id=“verde” class=“color verde right” data-color=“verde”></div>
<button id=“btnEmpezar” class=“btn-start” onclick=“empezarJuego()”>Empezar a jugar!</button>
</div>
<script>
const celeste = document.getElementById(‘celeste’)
const violeta = document.getElementById(‘violeta’)
const naranja = document.getElementById(‘naranja’)
const verde = document.getElementById(‘verde’)
const btnEmpezar = document.getElementById(‘btnEmpezar’)
const ULTIMO_NIVEL = 10

  class Juego {
    constructor() {
      this.inicializar()
      this.generarSecuencia()
      this.siguienteNivel()
    }

    inicializar() {
      this.siguienteNivel = this.siguienteNivel.bind(this)
      this.elegirColor = this.elegirColor.bind(this)
      btnEmpezar.classList.add('hide')
      this.nivel = 1
      this.colores = {
        celeste,
        violeta,
        naranja,
        verde
      }
    }

    generarSecuencia(){
      this.secuencia = new Array(ULTIMO_NIVEL).fill(0).map(n => Math.floor(Math.random() * 4))
    }

    siguienteNivel() {
      this.subnivel = 0
      this.iluminarSecuencia()
      this.agregarEventosClick()

    }

    transformarColorANumero(color) {
      switch (numero) {
        case 'celeste':
          return 0
        case 'violeta':
           return 1
        case 'naranja':
            return 2
        case 'verde':
            return 3
      }
    }

    iluminarSecuencia(){
      for (let i = 0; i < this.nivel; i++) {
        const color = this.transformarNumeroAcolor(this.secuencia[i])
        setTimeout(() => this.iluminarColor(color), 1000 * i)
      }
    }


    iluminarColor(color){
      this.colores[color].classList.add('light')
      setTimeout(() => this.apagarColor(color), 350)
    }

    apagarColor(color){
      this.colores[color].classList.remove('light')
    }

    agregarEventosClick() {
      this.colores.celeste.addEventListener('click', this.elegirColor)
      this.colores.verde.addEventListener('click', this.elegirColor)
      this.colores.violeta.addEventListener('click', this.elegirColor)
      this.colores.naranja.addEventListener('click', this.elegirColor)
    }

    eliminarEventosClick() {
      this.colores.celeste.removeEventListener('click', this.elegirColor)
      this.colores.verde.removeEventListener('click', this.elegirColor)
      this.colores.violeta.removeEventListener('click', this.elegirColor)
      this.colores.naranja.removeEventListener('click', this.elegirColor)
    }

//¿Dónde esta el error,alguien me puede ayudar? Por favor, lo hice idéntico al de sasha,pero esta off.

    elegirColor(ev) {
    const nombreColor = ev.target.dataset.color
    const nombreColor = this.transformarColorANumero(nombreColor)
    this.iluminarColor(nombreColor)
    if (nombreColor === this.secuencia[this.subnivel]) {
       this.subnivel++
       if (this.subnivel === this.nivel) {
         this.nivel++
        this.eliminarEventosClick()
        if (this.nivel === (ULTIMO_NIVEL + 1)) {
          //gano!
        }   else {
          setTimeout(this.siguienteNivel, 2000)
           }
          }
        } else {
          //perdio
        }
      }

//¿Dónde esta el error,alguien me puede ayudar? Por favor, lo hice idéntico al de sasha,pero esta off.

  function empezarJuego() {
    window.juego = new Juego()
  }
</script>

</body>
</html>

Así como está el código, este permite clickear los colores mientras se está mostrando la secuencia, a lo que yo entiendo esto sucede por los callbacks de los timeout de iluminar secuencia.
Me gustaría saber si esto es correcto.

Lo que yo hice el realizar lo que Diego Alejandro Correa Quecan propone pero me gustaría saber también si existen otras maneras de solucionar esto.

const btnEmpezar = document.getElementById('btnEmpezar')
const celeste = document.getElementById('celeste')
const violeta = document.getElementById('violeta')
const naranja = document.getElementById('naranja')
const verde = document.getElementById('verde')
const ULTIMO_NIVEL = 10



class Juego {
    constructor(){
        
        this.inicializar()
        this.generarSecuencia()
        setTimeout(this.siguienteNivel, 500)
    }
    
    
    inicializar(){
        this.siguienteNivel = this.siguienteNivel.bind(this)
        this.elegirColor = this.elegirColor.bind(this)
        btnEmpezar.classList.add('hide')
        this.nivel = 1
        this.colores = {
            celeste,
            violeta,
            naranja,
            verde
        }
    }

    generarSecuencia(){
        this.secuencia = new Array(ULTIMO_NIVEL).fill(0).map(n=> Math.floor(Math.random()*4))
    }

    siguienteNivel(){
        this.subnivel = 0
        this.iluminarSecuencia()
        this.agregarEventosClick()
    }

    transformarNumeroAColor(numero){
        switch(numero){
            case 0:
                return 'celeste'
            case 1:
                return 'violeta'
            case 2:
                return 'naranja'
            case 3:
                return 'verde'
        }
    }

    transformarColorANumero(color){
        switch(color){
            case 'celeste':
                return 0
            case 'violeta': 
                return 1
            case 'naranja':
                return 2
            case 'verde':
                return 3
        }
    }

    

    iluminarSecuencia(){
        for(let i = 0; i < this.nivel; i++){
            let color = this.transformarNumeroAColor(this.secuencia[i])
            setTimeout(()=>this.iluminarColor(color), 1000 * i)

        }
    }
    iluminarColor(color){
        this.colores[color].classList.add('light')
        setTimeout(()=>this.apagarColor(color), 350)
    }

    apagarColor(color){
        this.colores[color].classList.remove('light')
    }

    agregarEventosClick(){
        this.colores.celeste.addEventListener('click', this.elegirColor)
        this.colores.violeta.addEventListener('click', this.elegirColor)
        this.colores.naranja.addEventListener('click', this.elegirColor)
        this.colores.verde.addEventListener('click', this.elegirColor)
    }

    eliminarEventosClick(){
        this.colores.celeste.removeEventListener('click', this.elegirColor)
        this.colores.violeta.removeEventListener('click', this.elegirColor)
        this.colores.naranja.removeEventListener('click', this.elegirColor)
        this.colores.verde.removeEventListener('click', this.elegirColor)
    }

    elegirColor(ev){
        const nombreColor = ev.target.dataset.color
        const numeroColor = this.transformarColorANumero(nombreColor)
        this.iluminarColor(nombreColor)
        if (numeroColor === this.secuencia[this.subnivel]){
            this.subnivel++
            if (this.subnivel === this.nivel){
                this.nivel++
                this.eliminarEventosClick()
                if(this.nivel === (ULTIMO_NIVEL+1)){
                    //gano!
                } else {
                    setTimeout(this.siguienteNivel, 1500)
                }
            }
        } else{
            //perdio
        }
    }
}



function empezarJuego (){
    window.juego = new Juego()
}

¿Podrían ayudarme?

Actualmente estoy teniendo problemas con transformar Color a numero, les dejo mi codigo

const $btnEmpezar = document.querySelector('#btnEmpezar')
const $celeste = document.querySelector('#celeste')
const $violeta = document.querySelector('#violeta')
const $naranja = document.querySelector('#naranja')
const $verde = document.querySelector('#verde')
const $finaLVL = 10

class Juego{
    constructor(){
        this.comenzar()
        this.generarSecuencia()
        this.nextLevel()
     
    }
    
    comenzar(){
        $btnEmpezar.classList.add('hide')
        this.nivel = 1
        this.colores = {
            $celeste,
            $violeta,
            $naranja,
            $verde
        }
    }
    generarSecuencia(){
        this.secuencia = new Array ($finaLVL)
        .fill(0)
        .map( n => Math.floor(Math.random() * 4))
    }

    nextLevel(){
        this.subNivel = 0
        this.iluminarSecuencia()
        this.agregarEventosClick()
    }

    transforNumeroAColor(numero){
        switch (numero){
            case 0:
                return '$celeste'
            case 1:
                return '$violeta'
            case 2:
                return '$naranja'
            case 3: 
                return '$verde'            
        }
    }

    transforColorAnumero(color){
        switch (color){
            case 'celeste':
                return 0
            case 'violeta':
                return 1
            case 'naranja':
                return 2
            case 'verde': 
                return 3
        }
    }

    iluminarSecuencia(){
        for( let i = 0; i < this.nivel; i++){
            let color = this.transforNumeroAColor(this.secuencia[i])
            setTimeout(()=> this.iluminarColor(color),1000 * i)
        }
    }

    iluminarColor(color){
        this.colores[color].classList.add('light')
        setTimeout(()=> this.apagarColor(color),350)
    }

    apagarColor(color){
        this.colores[color].classList.remove('light')
    }

    agregarEventosClick(){
        this.colores.$celeste.addEventListener('click',this.elegirColor)
        this.colores.$violeta.addEventListener('click',this.elegirColor)
        this.colores.$naranja.addEventListener('click',this.elegirColor)
        this.colores.$verde.addEventListener('click',this.elegirColor)
    }

    eliminarEventosClick(){
        this.colores.$celeste.removeEventListener('click',this.elegirColor)
        this.colores.$violeta.removeEventListener('click',this.elegirColor)
        this.colores.$naranja.removeEventListener('click',this.elegirColor)
        this.colores.$verde.removeEventListener('click',this.elegirColor)
    }

    elegirColor(ev){
        const nombreColor = ev.target.dataset.color
	// AQUI EL ERROR
        const numeroColor = this.transforColorAnumero(nombreColor)
        this.iluminarColor(nombreColor)
        if (numeroColor === this.secuencia[this.nivel]){
            this.subNivel++
            if (this.subNivel === this.nivel){
                this.nivel++
                this.eliminarEventosClick()
                if (this.nivel === ($finaLVL + 1)){
                    // Gano
                }else{
                    this.nextLevel()
                }
            }
        }else{
            // Perdio
        }
    }   

}

function comenzarJuego(){
    window.juego =  new Juego()
}

También les dejo una captura de lo que me dice el navegador

PD: Se que estoy usando querySelector en ves de getElementById pero no influye en nada. (Al menos hasta ahora)

Gracias comunidad💚

Sería más fácil si tuvieramos los archivos para basarnos

Chicos tengo un problema y es que no me pasa al nivel 2, simplemente sale el primer nivel y luego del click y no hace mas nada!

<script>
  const celeste = document.getElementById("celeste")
  const violeta = document.getElementById("violeta")
  const naranja = document.getElementById("naranja")
  const verde = document.getElementById("verde")
  const btnEmpezar = document.getElementById("btnEmpezar")
  const ULTIMO_NIVEL = 10

  class Juego{
    constructor(){
      this.inicializar()
      this.generarSecuencia()
      this.siguienteNivel()
    }

    inicializar(){
      this.siguienteNivel = this.siguienteNivel.bind(this)
      this.elegirColor = this.elegirColor.bind(this)
      btnEmpezar.classList.add("hide") 
      this.nivel = 1
      this.colores = {
        celeste,
        violeta,
        naranja,
        verde
      }     
    }
    generarSecuencia(){
      this.secuencia = new Array(ULTIMO_NIVEL).fill(0).map(n => Math.floor(Math.random() * 4))
    }
    siguienteNivel(){
      this.iluminarSecuencia()
      this.agregarEventosClick()
      this.subNivel = 0

    }

    transformarNumeroAColor(numero){
      switch (numero){
        case 0:
          return "celeste"
        case 1:
          return "violeta"
        case 2:
          return "naranja"
        case 3: 
          return "verde"
      }
    }
    transformarColorANumero(color){
      switch (color){
        case celeste:
          return "0"
        case violeta:
          return "1"
        case naranja:
          return "2"
        case verde: 
          return "3"
      }
    }

    iluminarSecuencia(){
      for (let i = 0; i < this.nivel; i++){
        const color = this.transformarNumeroAColor(this.secuencia[i])
        setTimeout(() => this.iluminarColor(color), 1000 * i)
      }
    }
    iluminarColor(color){
      this.colores[color].classList.add("light")
      setTimeout(() => this.apagarColor(color), 350)
    }
    apagarColor(color){
      this.colores[color].classList.remove("light")
    }
    agregarEventosClick(){
      this.colores.celeste.addEventListener("click", this.elegirColor)
      this.colores.violeta.addEventListener("click", this.elegirColor)
      this.colores.naranja.addEventListener("click", this.elegirColor)
      this.colores.verde.addEventListener("click", this.elegirColor)
    }
    eliminarEventosClick(){
      this.colores.celeste.removeEventListener("click", this.elegirColor)
      this.colores.violeta.removeEventListener("click", this.elegirColor)
      this.colores.naranja.removeEventListener("click", this.elegirColor)
      this.colores.verde.removeEventListener("click", this.elegirColor)
    }
    elegirColor(ev){
      const nombreColor = ev.target.dataset.color
      const numeroColor = this.transformarNumeroAColor(nombreColor)
      this.iluminarColor(nombreColor)
      if(numeroColor === this.secuencia[this.subNivel]){
        this.subNivel++
        if(this.subNivel === this.nivel){
          this.nivel++
          this.eliminarEventosClick()
          if(this.nivel === (ULTIMO_NIVEL + 1)){
            //Ganò
          } else{
            setTimeout(this.siguienteNivel, 2000)
          }
        }
      }else{
        //Perdiò
      }

    }
  }

  function empezarJuego(){
    window.juego = new Juego()
  }
</script>

Me confundí mucho con los niveles y subniveles :c
Siento que son demasiados if :S

Alguien sabe por que el subnivel en la consola es siempre 0, según yo para que se pueda ejecutar la siguiente secuencia tiene que ser igual al nivel pero independientemente del nivel en el que estés la consola te lo muestra en 0

¿Ayuda? Me aparece como si no estuvieran definidas, llevo mas o menos una hora y no encuentro el error.


class Game{
    constructor() {
        this.initialize()
        this.generateSecuence()
        this.nextLevel()
    }

    //El primer paso del juego, aquí escondemos el botón, ponemos el nivel en el que vamos y anotamos los colores disponibles
    initialize(){
        this.chooseColor = this.chooseColor.bind(this);
        btnBegin.classList.add('hide');
        this.level = 1;
        this.colors = {blue, purple, orange, green};
    }

    //Aquí genero una secuencia del 1 al 10
    generateSecuence() {
        this.secuence = new Array(LAST_LEVEL).fill(0).map(n => Math.floor(Math.random() * 4))
    }

    //Para cada nivel nuevo, se va a iluminar la secuencia 
    nextLevel(){
        this.sublevel = 0
        this.iluminateSecuence()
        this.addEventClick()
    }

    transformNumberToColor(number){
        switch (number) {
            case 0:
                return 'blue'
            case 1:
                return 'purple'
            case 2:
                return 'orange'
            case 3: 
                return 'green'
        }
    }

    transformColorToNumber(color){
        switch (color) {
            case 'blue':
                return 0
            case 'purple':
                return 1
            case 'orange':
                return 2
            case 'green': 
                return 3
        }
    }

    //Se hace un ciclo en el cual se le asigna a cada numero un color
    iluminateSecuence() {
        for (let i = 0; i < this.level; i++) {
            let color = this.transformNumberToColor(this.secuence[i])
            setTimeout(() =>  this.iluminateColor(color), 1000 * i);
        }
    }

    //Aquí le agrego la iluminación a las colores, se utiliza 'light' por que es como lo indiqué en CSS
    iluminateColor(color){
        //Aquí el primer ERROR
        this.colors[color].classList.add('light');
        setTimeout(() => this.returnColor(color), 350);
    }

    //Aquí le quito la iluminación a la ruedita
    returnColor(color){
        this.colors[color].classList.remove('light');
    }

    //Aquí se agrega un listener para cuando el mouse clickea en alguna parte de la ruedita
    addEventClick(){
        this.colors.blue.addEventListener('click', this.chooseColor);
        this.colors.purple.addEventListener('click', this.chooseColor);
        this.colors.orange.addEventListener('click', this.chooseColor);
        this.colors.green.addEventListener('click', this.chooseColor);
    }

    eliminateEventClick(){
        this.colors.blue.removeEventListener('click', this.chooseColor);
        this.colors.purple.removeEventListener('click', this.chooseColor);
        this.colors.orange.removeEventListener('click', this.chooseColor);
        this.colors.green.removeEventListener('click', this.chooseColor);
    }

    chooseColor(ev){
        const nameColor = ev.target.dataset.color
        const numberColor = this.transformColorToNumber(nameColor);
        //Aquí el 2 ERROR
        this.iluminateColor(nameColor)
        if (numberColor === this.secuence[this.sublevel]){
            this.sublevel++; 
            if(this.sublevel === this.level){ //aquí el usuario pasa de nivel 
                this.level++;
                eliminateEventClick();
                if(this.level === (LAST_LEVEL + 1)){
                    //Aquí ya ganó el hdspm 
                } else{
                    this.nextLevel();
                }
            }
        } else {
            //perdió
        }
    }
}```

Cuando intenté hacerlo, hice todo igual pero por error puse el this.subnivel = 0 en inicializar() en lugar de en siguienteNivel(), y me andaba mal el juego, no daba ningun error en consola pero no tomaba valido el click que respetaba la secuencia (puse en el else de //perdiste un alert(‘perdiste’) que me saltaba en la 2da tanda, apretara lo que apretara). Luego cambie eso a siguienteNivel y anduvo perfecto. Alguien me podría explicar la lógica de porque si o si tiene que estar en siguienteNivel?

¿Alguien sabe cuál es la diferencia entre poner como referencia una función osea llamarla (ejemplo: setTimeout( siguienteNivel, 500 ) ) o invocar a una función (ejemplo: setTimeout( siguienteNivel(), 500)) ?

el subnivel es para perder apenas hagamos un click mal dentro de la secuencia y no esperar a terminar toda la secuencia para perder ?

Hola, disculpen, alguien puede ayudarme, es que sigo el código exacto sin embargo la consola me indica que “transformarNumeroaColor” no es una funcion. Les plasmo para saber donde puede estar el error (corresponde a la linea con el siguiente codigo): const color = this.transformarNumeroaColor(this.secuencia[i])

Gracias por ayudar

<!DOCTYPE html>
<html>
  <head>
    <meta charset="utf-8">
    <title>Simon Dice</title>
    <style>
      body {
        margin: 0;
        background: #dedede;
        display: flex;
        align-items: center;
        height: 100vh;
      }

      .gameboard {
        height: 100vh;
        width: 100vh;
        border-radius: 50%;
        overflow: hidden;
        margin: 0 auto;
        max-height: 60vh;
        max-width: 60vh;
      }

      .color {
        width: 50%;
        height: 50%;
        display: inline-block;
      }

      .left {
        float: left;
      }

      .right {
        float: left;
      }

      .celeste {
        background: #22a6b3;
      }

      .celeste.light {
        background: #7ed6df;
      }

      .violeta {
        background: #be2edd;
      }

      .violeta.light {
        background: #e056fd;
      }

      .naranja {
        background: #f0932b;
      }

      .naranja.light {
        background: #ffbe76;
      }

      .verde {
        background: #6ab04c;
      }

      .verde.light {
        background: #badc58;
      }

      .btn-start {
        width: 400px;
        height: 100px;
        background: #ecf0f1;
        color: #2c3e50;
        font-size: 2.5rem;
        position: absolute;
        top: calc(50% - 50px);
        left: calc(50% - 200px);
      }

      .hide {
        display: none;
      }
    </style>
  </head>
  <body>
    <div class="gameboard">
      <div id="celeste" class="color celeste left" data-color="celeste"></div>
      <div id="violeta" class="color violeta right" data-color="violeta"></div>
      <div id="naranja" class="color naranja left" data-color="naranja"></div>
      <div id="verde" class="color verde right" data-color="verde"></div>
      <button id="btnEmpezar" class="btn-start" onclick="empezarJuego()">Empezar a jugar!</button>
    </div>
    <script>
      const celeste = document.getElementById('celeste')
      const violeta = document.getElementById('violeta')
      const naranja = document.getElementById('naranja')
      const verde = document.getElementById('verde')
      const btnEmpezar = document.getElementById('btnEmpezar')
      const ULTIMO_NIVEL = 10


        class Juego {
        constructor() {
          setTimeout (() => {
            this.inicializar()
            this.generarSecuencia()
            this.siguienteNivel()
          }, 500)
          
        }

        inicializar() {
          this.siguienteNivel = this.siguienteNivel.bind(this)
          btnEmpezar.classList.add('hide')
          this.nivel = 1
          this.colores = {
              celeste,
              violeta,
              naranja,
              verde,
          }
        }

        generarSecuencia() {
            this.secuencia = new Array(10).fill(0).map(n => Math.floor(Math.random() * 4))
        }

        siguienteNivel() {
            this.subnivel = 0
            this.iluminarSecuencia()
            this.agregarEventosClick()
        }

        iluminarSecuencia() {
          for (let i = 0; i < this.nivel; i++) {
       const color = this.transformarNumeroaColor(this.secuencia[i])
            setTimeout(() => this.iluminarColor(color), 1000 * i)
          }
           
            
        }

        iluminarColor(color) {
          this.colores[color].classList.add('light')
          setTimeout(() => this.apagarColor(color), 350)
        }

        apagarColor(color) {
          this.colores[color].classList.remove("light")
        }
 
        agregarEventosClick() {
          this.colores.celeste.addEventListener("click", this.elegirColor)
          this.colores.verde.addEventListener("click", this.elegirColor)
          this.colores.violeta.addEventListener("click", this.elegirColor)
          this.colores.naranja.addEventListener("click", this.elegirColor)
        }

       eliminarEventosClick() {
        this.colores.celeste.removeEventListener("click", this.elegirColor)
          this.colores.verde.removeEventListener("click", this.elegirColor)
          this.colores.violeta.removeEventListener("click", this.elegirColor)
          this.colores.naranja.removeEventListener("click", this.elegirColor) 

       }

        elegirColor(ev) {
          console.log(ev)
          const nombreColor = ev.target.dataset.color
          const numeroColor = this.transformarColorANumeros(nombreColor)
          this.iluminarColor(nombreColor)
          if (numeroColor === this.secuencia[this.subnivel]){

            this.subnivel++
            if (this.subnivel === this.nivel)
            this.nivel++
            this.eliminarEventosClick()

            if (this.nivel === (ULTIMO_NIVEL + 1)) {

            } else {
              setTimeout(this.siguienteNivel, 1500)

            }
            
          }
        }

         transformarColorANumero(color) {
            switch (color) {
               case "celeste":
                    return 0
                case "violeta":
                    return 1
                case "naranja":
                    return 2
                case "verde":
                    return 3
            
            }

      }
          transformarNumeroAColor(numero) {
                switch (numero) {
                    case 0:
                        return'celeste'
                    case 1:
                        return'violeta'
                    case 2:
                        return'naranja'
                    case 3:
                        return'verde'
                }
      }
        
      }
      function empezarJuego() {
        var juego = new Juego()
      }

    </script>
  </body>
</html>

Excelente clase, me costó entender la parte de elegirColor() pero lo logré!!

Se va poniendo interesante

app.js:62 Uncaught TypeError: Cannot read property ‘classList’ of undefined
at Juego.iluminarColor (app.js:62)
at app.js:57

Si este es el curso de Fundamentos de Javascript, que será el curso Profesional de Javascript…😅 como diríamos en Perú… ya volé :'v creo que el curso fue de un nivel básico a un intermedio y luego saltó drásticamente al avanzado U_u …por ratos da dejar todo y estudiar por su cuenta poco a poco pero bueno creo que lo terminaré tratanto de entender lo que pueda y escribiendo tal cual lo pone Sacha y luego hacer los demás cursos, por cierto yo estoy haciendo la Escuela de desarrollo web, y no se por qué este curso no está en la ruta… osea es bueno, solo en la última parte he volado, igual complementaré con libros y los demás cursos de Platzi, quizás me lleve la sorpresa que luego de terminar este curso vuelva a la ruta de desarrollo web y los cursos expliquen todo lo desarrollado aquí y el curso de profesional de javascript que está en esa ruta sea de este nivel…(me faltan como 6 cursos para llegar a ese curso) supongo que en ese momento podré comprender todo esto e incluso hacerlo por mi cuenta

Excelente clase!

edita 'transformar numero, o crea un nuevo argumento ?

Al principio se menciona que dentro del target esta el dataset, y esta perfecto hacerlo de otra manera pero tambien se puede acceder al id desde el mismo target y los dos tienen los mismos valores

ev.target.id == ev.target.dataset.color
//true

Excelente explicación

Por qué el this.siguienteNivel que se pasó por setTimeout no fue como función? (casi al final de la clase)

const celeste = document.getElementById("celeste");
const violeta = document.getElementById("violeta");
const naranja = document.getElementById("naranja");
const verde = document.getElementById("verde");
const btnEmpezar = document.getElementById("btnEmpezar");
const ULTIMO_NIVEL = 10;
class Juego {
	constructor() {
		this.inicializar();
		this.generar_secuencia();
		setTimeout(this.siguiente_nivel, 500);
	}
	inicializar() {
		btnEmpezar.classList.add("hide");
		this.elegir_color = this.elegir_color.bind(this);
		this.siguiente_nivel = this.siguiente_nivel.bind(this);
		this.nivel = 1;
		this.colores = {
			celeste,
			violeta,
			naranja,
			verde
		};
	}

	generar_secuencia() {
		this.secuencia = new Array(ULTIMO_NIVEL)
			.fill(0)
			.map(n => Math.floor(Math.random() * 4));
	}

	siguiente_nivel() {
		this.subnivel = 0;
		this.iluminar_secuencia();
		this.agregar_evento_click();
	}

	transformar_numero_a_color(numero) {
		switch (numero) {
			case 0:
				return "celeste";
			case 1:
				return "violeta";
			case 2:
				return "naranja";
			case 3:
				return "verde";
		}
	}

	transformar_color_a_numero(color) {
		switch (color) {
			case "celeste":
				return 0;
			case "violeta":
				return 1;
			case "naranja":
				return 2;
			case "verde":
				return 3;
		}
	}

	iluminar_secuencia() {
		for (let i = 0; i < this.nivel; i++) {
			let color = this.transformar_numero_a_color(this.secuencia[i]);
			setTimeout(() => this.iluminar_color(color), 1000 * i);
		}
	}

	iluminar_color(color) {
		this.colores[color].classList.add("light");
		setTimeout(() => this.apagar_color(color), 500);
	}

	apagar_color(color) {
		this.colores[color].classList.remove("light");
	}

	agregar_evento_click() {
		this.colores.celeste.addEventListener("click", this.elegir_color);
		this.colores.verde.addEventListener("click", this.elegir_color);
		this.colores.violeta.addEventListener("click", this.elegir_color);
		this.colores.naranja.addEventListener("click", this.elegir_color);
	}

	eliminar_eventos_click() {
		this.colores.celeste.removeEventListener("click", this.elegir_color);
		this.colores.verde.removeEventListener("click", this.elegir_color);
		this.colores.violeta.removeEventListener("click", this.elegir_color);
		this.colores.naranja.removeEventListener("click", this.elegir_color);
	}

	elegir_color(ev) {
		const nombre_color = ev.target.dataset.color;
		const numero_color = this.transformar_color_a_numero(nombre_color);
		this.iluminar_color(nombre_color);
		if (numero_color === this.secuencia[this.subnivel]) {
			this.subnivel++;
			if (this.subnivel === this.nivel) {
				this.nivel++;
				this.eliminar_eventos_click();
				if (this.nivel === ULTIMO_NIVEL + 1) {
					//Gano
				} else {
					setTimeout(this.siguiente_nivel, 1500);
				}
			}
		} else {
			//perdio
		}
	}
}

function empezarJuego() {
	window.juego = new Juego();
}

Alguien me ayuda, no logro que funcione como debería

    <script>
      const celeste = document.getElementById('celeste')
      const violeta = document.getElementById('violeta')
      const naranja = document.getElementById('naranja')
      const verde = document.getElementById('verde')
      const btnEmpezar = document.getElementById('btnEmpezar')
      const ULTIMO_NIVEL = 10

      class Juego{
        constructor(){
          this.inicializar()
          this.generarSecuencia()
          setTimeout(this.siguienteNivel, 500)
        }
        inicializar(){
          this.siguienteNivel = this.siguienteNivel.bind(this)
          this.elegirColor = this.elegirColor.bind(this)
          btnEmpezar.classList.add('hide')
          this.nivel = 1
          this.colors = {
            celeste: celeste,
            violeta: violeta,
            naranja: naranja,
            verde: verde
          }
        }
        generarSecuencia(){
          this.secuencia = new Array(ULTIMO_NIVEL).fill(0).map(n => Math.floor(Math.random() * 4))
        }
        siguienteNivel(){
          this.subnivel = 0
          this.iluminarSecuencia()
          this.agregarEventoClick()
        }
        transfomarNumeroAColores(numero){
          switch (numero) {
            case 0: return 'celeste'
            case 1: return 'violeta'
            case 2: return 'naranja'
            case 3: return 'verde'
            }
          }
          transfomarColoresANumeros(color){
            switch(color){
              case 'celeste': return 0
              case 'violeta': return 1
              case 'naranja': return 2
              case 'verde': return 3
            }
          }
        iluminarSecuencia(){
          for(let i = 0; i < this.nivel; i++){
            const COLOR = this.transfomarNumeroAColores(this.secuencia[i])
            setTimeout(()=> this.iluminarColores(COLOR), 1000 * i)
          }
        }
        iluminarColores(colors){
          this.colors[colors].classList.add('light');
          setTimeout(() => this.apagarColores(colors), 350)
        }
        apagarColores(colors){
          this.colors[colors].classList.remove('light');
        }
        agregarEventoClick(){
          this.colors.celeste.addEventListener('click', this.elegirColor)
          this.colors.violeta.addEventListener('click', this.elegirColor)
          this.colors.naranja.addEventListener('click', this.elegirColor)
          this.colors.verde.addEventListener('click', this.elegirColor)
        }
        eliminarEventoClick(){
          this.colors.celeste.removeEventListener('click', this.elegirColor)
          this.colors.violeta.removeEventListener('click', this.elegirColor)
          this.colors.naranja.removeEventListener('click', this.elegirColor)
          this.colors.verde.removeEventListener('click', this.elegirColor)
        }

        elegirColor(ev){
          const nombreColor = ev.target.dataset.color
          const numeroColor = this.transfomarColoresANumeros(nombreColor)
          this.iluminarColores(nombreColor)
          if(numeroColor === this.secuencia[this.subnivel]){
            this.subnivel++
            if(this.subnivel === this.nivel){
              this.nivel++
             this.eliminarEventoClick()
              if(this.nivel === ULTIMO_NIVEL + 1){
                //Ganó
              }
            }else{
              setTimeout(this.siguienteNivel, 1500)
            }
          } else{
            // Perdio
          }
        }
      }

      function empezarJuego(){
        window.juego = new Juego()
      }
    </script>

Excelente

me sale error en esta parte pero no se que tengo mal si me pueden ayudar lo agradecería.
elegirColor(ev){
const nombreColor = ev.target.dataset.color
const numeroColor = transformarColorANumero(nombreColor);
this.iluminarColor(nombreColor)
if(numeroColor === this.secuencia[this.subnivel]){
this.subnivel++
if (this.subnivel === this.nivel){
this.nivel++
this.eliminarEventosClick()
if(this.nivel === (ULTIMO_NIVEL + 1 )){
// Gano
}else {
setTimeout(this.siguienteNivel, 2000)
}
}
} else{
//perdio
}
}

    console.log(e.target.dataset.color);

Ganó

Excelente clase, ya casi esta listo

Muy buen ritmo de las clases

Gracias

Buenas tardes una duda porque cuando solo llamo a la funcion setTimeout(() =>this.nextLevel,1500) no me funciona y cuando la invoco setTimeout(() =>this.nextLevel(),1500) si me funciona y al instructor si le funciona con solo llamar

Resumen Clase:
La realizar click en un botón tendremos una propiedad que se llama atrge y dentro de este tenemos uno que se llama dataset y se guarda un elemento que se agrego al crear el botn con el código de: data-color=”valor”, el data indica que es dataset color indica el nombre y el valor almacena el valor del dataset

I share my notes

 /*====================================== */ // Nuestro juego de memoria:Agregando la verificación del color elegido

 const celeste = document.getElementById('celeste')
 const violeta = document.getElementById('violeta')
 const naranja = document.getElementById('naranja')
 const verde   = document.getElementById('verde')

 /*====================================== */ // Cual va a ser nuestro ultimo nivel

const ULTIMO_NIVEL = 10

 /*====================================== */ // Boton empezar


 const btnEmpezar = document.getElementById('btnEmpezar')


 /*====================================== */ // 

class Juego {
    constructor() {
    this.inicializar()
    this.generarSecuencia()
    setTimeout(this.siguienteNivel(), 500)
    }

    inicializar() {  
        this.siguienteNivel = this.siguienteNivel.bind(this)
        this.elegirColor = this.elegirColor.bind(this)                                              
        btnEmpezar.classList.add('hide')
        this.nivel = 1
        this.colores = {
            celeste,
            violeta,
            naranja,
            verde
        }
    }
    
    generarSecuencia(){                                            
        this.secuencia = new Array(ULTIMO_NIVEL).fill(0).map(n => Math.floor(Math.random()*4))
    }

    siguienteNivel(){   
        this.subnivel = 0                                                       
        this.iluminarSecuencia()
        this.agregarEventosClick()
    }

    transformarNumeroAColor(numero){                               
      switch (numero){
        case 0:
          return 'celeste'
        case 1:
          return 'violeta'
        case 2:
          return 'naranja'
        case 3:
          return 'verde'
      }
    }

    transformarColorANumero(color){                                                            //Agregamos un nuevo metodo para cambiar de color a numero               
      switch (color){
        case 'celeste':
          return 0
        case 'violeta':
          return 1
        case 'naranja':
          return 2
        case 'verde':
          return 3
      }
    }

    iluminarSecuencia(){
      for (let i = 0; i < this.nivel; i++){                         
        const color = this.transformarNumeroAColor(this.secuencia[i]) 
        setTimeout(() => this.iluminarColor(color), 1000 * i );
      }
    }

    iluminarColor (color){                                        
      this.colores[color].classList.add('light')
      setTimeout(() => this.apagarColor(color),350)
    }

    apagarColor(color){
      this.colores[color].classList.remove('light')
    }

    agregarEventosClick(){
      this.colores.celeste.addEventListener('click', this.elegirColor)
      this.colores.verde.addEventListener('click', this.elegirColor)
      this.colores.violeta.addEventListener('click', this.elegirColor)
      this.colores.naranja.addEventListener('click', this.elegirColor)
    }

    eliminarEventosClick(){
      this.colores.celeste.removeEventListener('click', this.elegirColor)
      this.colores.verde.removeEventListener('click', this.elegirColor)
      this.colores.violeta.removeEventListener('click', this.elegirColor)
      this.colores.naranja.removeEventListener('click', this.elegirColor)
    }

    elegirColor(ev){                                                                        //Nuestra logica que pasa cuando el usuario haga alguna acción                                                              
      const nombreColor = ev.target.dataset.color
      const numeroColor = this.transformarColorANumero (nombreColor)
      this.iluminarColor(nombreColor)

      if (numeroColor === this.secuencia[this.subnivel]){
        this.subnivel++

        if (this.subnivel === this.nivel){
          this.nivel++
          this.eliminarEventosClick()

          if (this.nivel === (ULTIMO_NIVEL+1)){
            //Gano

          } else {
            setTimeout( this.siguienteNivel, 1500)
          }
        }
      }else {
        //perdio
      }
    }
}

 /*====================================== */ // 

function empezarJuego() {                                           
    window.juego = new Juego()
    alert('El juevo va comenzar')```

Ahora toca solucionar los siguientes planteamientos del proyecto:

-Detectar el color en el que hace click el usuario
-Compararlo con el color que tenemos en el array de generar secuencia
-Si no falla incrementar nivel y el array de secuencia
-Si termina correctamente la secuencia, siguienteNivel hasta el ultimo nivel donde se dira que gano.

Muy bien explicado