C sharp - Manejo de cursores

 
Vista:
sin imagen de perfil
Val: 168
Bronce
Ha mantenido su posición en C sharp (en relación al último mes)
Gráfica de C sharp

Manejo de cursores

Publicado por Meta (138 intervenciones) el 20/08/2024 23:12:36
Teniendo este ejemplo que se muestra abajo, me funciona una parte del programa, pero no todo.

LCD-Volumen-01

Como puedes ver, el programa se ejecuta y si te fijas bien, hay un > en > Vol: ■■■■■■-- 6.

Si pulsas izquierda o derecha con la flecha del teclado, se mueve la barra y el número del 0 al 8, en este ejemplo se muestra el 6.

Lo que no me funciona es, que debo pulsar la tecla Enter, y el símbolo >, se muestra en > ATRÁS.

Si está el símbolo > en ATRÁS, puedes mover las flechas izquierdas y derecha y el > se muestra en ATRÁS o en INICIO.

Si estás en > ATRÁS, pulsas Enter, muestras un mensaje: ¡Mensaje ATRÁS!, si seleccionas con el > en INICIO y pulsas Enter, muestra el mensaje ¡Mensaje INICIO!, pulsas Enter y vuelves a la pantalla principal.

Estando en > ATRÁS INICIO, pulsas una de las flechas arriba o abajo, vuelve en > Vol: ■■■■■■-- 6 en e cual puedes regular otra vez el volumen.

El código que he hecho hasta el momento es este.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
using System;
 
namespace LCD_Volumen_Consola_01
{
    internal class Program
    {
        static void Main(string[] args)
        {
 
            Console.CursorVisible = false;
 
            // Variables.
            string[] TEXTO =
            {
                "   ** VOLUMEN **    ", // Posición 0.
                " Vol: ",               // 1
                "■",                    // 2
                "-",                    // 3
                "  ATRÁS",              // 4
                "INICIO",               // 5
                ">",                    // 6
                " "                     // 7
            };
 
            int volumen = 6;
            const int VOLMEN_MAX = 8;
 
            #region Volumen.
            void Volumen()
            {
                ConsoleKey teclaVolumen;
 
                // Limpiar pantalla.
                Console.Clear();
 
                Console.SetCursorPosition(0, 3);
                Console.Write(TEXTO[4]);           //   ATRÁS
 
                // Este es temporal solo para ver las coordenadas de posicionar el >.
                //Console.SetCursorPosition(11, 3);
                //Console.Write(TEXTO[6]);           //   >
 
                Console.SetCursorPosition(13, 3);
                Console.Write(TEXTO[5]);           //   INICIO
 
                Console.SetCursorPosition(0, 1);
                Console.Write(TEXTO[6]);           //   >
 
                do
                {
                    Console.SetCursorPosition(0, 0);
                    Console.Write(TEXTO[0]);           //    ** VOLUMEN **
 
                    Console.SetCursorPosition(1, 1);
                    Console.Write(TEXTO[1]);           //   Vol:
 
 
                    for (int i = 0; i < volumen; i++)
                    {
                        Console.Write(TEXTO[2]);       // ■ ASCII 254.
                    }
 
                    for (int j = 0; j < (VOLMEN_MAX - volumen); j++)
                    {
                        Console.Write(TEXTO[3]);       // -
                    }
 
                    // Mostrar el volumen en número.
                    Console.SetCursorPosition(16, 1);
                    Console.Write(volumen);
 
                    // Almacena el teclado pulsado en la variable teclaBrillo.
                    teclaVolumen = Console.ReadKey(true).Key;
 
                    // ¿Se pulsó el flecha derecha?
                    if (teclaVolumen == ConsoleKey.RightArrow)
                    {
                        // Sí. ¿Volumen es menor que VOLUMEN_MAX?
                        if (volumen < VOLMEN_MAX)
                        {
                            // Sí, incrementa 1.
                            volumen++;
                        }
                    }
 
                    // ¿Se pulsó flecha izquierda?
                    if (teclaVolumen == ConsoleKey.LeftArrow)
                    {
                        // Sí. ¿Volumen es mayor que cero?
                        if (volumen > 0)
                        {
                            // Sí, decremmenta 1.
                            volumen--;
                        }
                    }
 
                            //Console.SetCursorPosition(0, 1);
                            //Console.Write(TEXTO[7]);          //
                            //Console.SetCursorPosition(0, 3);
                            //Console.Write(TEXTO[4]);          // ATRÁS
                            //Console.SetCursorPosition(0, 3);
                            //Console.Write(TEXTO[6]);          // >
 
                            //Console.SetCursorPosition(0, 1);
                            //Console.Write(TEXTO[7]);          //
                            //Console.SetCursorPosition(11, 3);
                            //Console.Write(TEXTO[5]);          // INICIO
                            //Console.SetCursorPosition(11, 3);
                            //Console.Write(TEXTO[6]);          // >
 
 
                } while (teclaVolumen != ConsoleKey.Enter);
            }
            #endregion
 
 
            // Inicio.
            Volumen();
        }
    }
}

¿Alguna idea?

Se que entender es lioso.

Gracias.
Valora esta pregunta
Me gusta: Está pregunta es útil y esta claraNo me gusta: Está pregunta no esta clara o no es útil
0
Responder
Imágen de perfil de Pere

Manejo de cursores

Publicado por Pere (4 intervenciones) el 22/08/2024 14:54:42
Hola, uno de mis retos es ‘dibujar’ en la consola y hacer menús interactivos (me recuerda a Amstrad, Commodore…). Me ha parecido interesante y he intentado resolver tu duda, pero tampoco te voy a engañar, y he usado un poco de IA para organizar mejor el código:

Tenemos tres secciones:
[indent]1. Vol: ------- 0
2. ATRÁS
3. INICIO[/indent]

Cuando ejecutamos el programa nos movemos con las flechas arriba/abajo por las secciones.
Para acceder/salir de ellas pulsamos ‘Enter’. (He pensado que esta mejora puede ser útil, porqué me pareció entender que no la tenías).

Notarás que presionar ‘Enter’ en la sección del volumen no tiene sentido, pero te lo he dejado así porqué me ha parecido entender que el símbolo ‘>’ debe pasar por allí debido a que tu mensaje inicial contenía: “ > Vol: xxxxxx-- 6”. Así que así lo he dejado por tus posibles planes futuros.

Una vez seleccionamos ‘ATRÁS’ podemos manejar el volumen con las teclas izq/dcha.

Presionamos ‘Entrer’ para salir y nos movemos con las flechas otra vez para ir a ‘INICIO’.

Presionamos ‘Enter’ para entrar y podemos manipular el volumen con arriba/abajo.

Así pues, resolvemos un primer problema que era la navegación por el programa o menú.

En un siguiente paso que era organizativo, es donde al principio me he liado un poco y luego he empezado a reestructurarlo (sí, debería haber hecho un esquema antes).

Notarás que tu método Volumen() contiene todo lo que debe hacer, más el ‘do/while’ principal. Creo que ese ha sido el principal problema, porqué si dividimos el código en partes más pequeñas, conseguimos una estructura ordenada y modular por defecto. Yo también uso mucho el do/while en consola, pero en este caso (y la IA me dio la idea) lo moví al método principal para tener un método Main más limpio.

Por tanto, DibujarMenu() y ActualizarVolumen() son dos métodos que te ayudarán a comprender mejor como funciona el flujo del programa y puedes ampliarlos, editarlos, testearlos… sin afectar al resto.

Finalmente he mantenido la misma nomenclatura, pero creo que debería cambiarse, ya que no sé si tiene mucho sentido que el programa empiece con un método llamado Volumen(), en todo caso, imagino que forma parte de un proyecto mayor o de una prueba. Cambiar los nombres no será complicado.
Y poca cosa más.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
using System;
 
namespace LCD_Volumen_Consola_02
{
    internal class Program
    {
        static void Main(string[] args)
        {
            Console.CursorVisible = false;
 
            // Variables.
            string[] TEXTO =
            {
                "   ** VOLUMEN **    ", // Posición 0.
                " Vol: ",               // 1
                "■",                    // 2
                "-",                    // 3
                " ATRÁS",               // 4
                " INICIO",              // 5
                ">",                    // 6
                " "                     // 7
            };
 
            int volumen = 6;
            const int VOLUMEN_MAX = 8;
            int menuPos = 0; // 0 = Volumen, 1 = ATRÁS, 2 = INICIO
            bool subMenuActivo = false;
 
            void DibujarMenu()
            {
                Console.Clear();
 
                Console.SetCursorPosition(0, 0);
                Console.Write(TEXTO[0]); // ** VOLUMEN **
 
                Console.SetCursorPosition(1, 1);
                Console.Write(TEXTO[1]); // Vol:
 
                for (int i = 0; i < volumen; i++)
                {
                    Console.Write(TEXTO[2]); // ■
                }
 
                for (int j = 0; j < (VOLUMEN_MAX - volumen); j++)
                {
                    Console.Write(TEXTO[3]); // -
                }
 
                Console.SetCursorPosition(16, 1);
                Console.Write(volumen); // Mostrar volumen numérico
 
                Console.SetCursorPosition(0, 3);
                Console.Write(TEXTO[4]); // ATRÁS
 
                Console.SetCursorPosition(13, 3);
                Console.Write(TEXTO[5]); // INICIO
 
                if (!subMenuActivo)
                {
                    if (menuPos == 0)
                    {
                        Console.SetCursorPosition(0, 1);
                    }
                    else if (menuPos == 1)
                    {
                        Console.SetCursorPosition(0, 3);
                    }
                    else if (menuPos == 2)
                    {
                        Console.SetCursorPosition(12, 3);
                    }
                    Console.Write(TEXTO[6]); // >
                }
            }
 
            void ActualizarVolumen()
            {
                Console.SetCursorPosition(1, 1);
                Console.Write(TEXTO[1]); // Vol:
 
                for (int i = 0; i < volumen; i++)
                {
                    Console.Write(TEXTO[2]); // ■
                }
 
                for (int j = 0; j < (VOLUMEN_MAX - volumen); j++)
                {
                    Console.Write(TEXTO[3]); // -
                }
 
                Console.SetCursorPosition(16, 1);
                Console.Write(volumen); // Mostrar volumen numérico
            }
 
            void Volumen()
            {
                ConsoleKey tecla;
                DibujarMenu();
 
                do
                {
                    tecla = Console.ReadKey(true).Key;
 
                    if (subMenuActivo)
                    {
                        if (menuPos == 1)
                        {
                            // ATRÁS
                            if (tecla == ConsoleKey.RightArrow && volumen < VOLUMEN_MAX)
                            {
                                volumen++;
                            }
                            else if (tecla == ConsoleKey.LeftArrow && volumen > 0)
                            {
                                volumen--;
                            }
                            ActualizarVolumen();
                        }
                        else if (menuPos == 2)
                        {
                            // INICIO
                            if (tecla == ConsoleKey.UpArrow && volumen < VOLUMEN_MAX)
                            {
                                volumen++;
                            }
                            else if (tecla == ConsoleKey.DownArrow && volumen > 0)
                            {
                                volumen--;
                            }
                            ActualizarVolumen();
                        }
 
                        if (tecla == ConsoleKey.Enter)
                        {
                            subMenuActivo = false;
                            DibujarMenu();
                        }
                    }
                    else
                    {
                        if (tecla == ConsoleKey.DownArrow && menuPos < 2)
                        {
                            menuPos++;
                        }
                        else if (tecla == ConsoleKey.UpArrow && menuPos > 0)
                        {
                            menuPos--;
                        }
                        else if (tecla == ConsoleKey.Enter)
                        {
                            subMenuActivo = true;
                        }
 
                        DibujarMenu();
                    }
 
                } while (tecla != ConsoleKey.Escape);
            }
 
            // Inicio.
            Volumen();
        }
    }
}


Notas: La estructura del código que te paso, junto al método Main() es un proyecto de consola .NET 5.0
1
2
3
4
5
6
7
8
<Project Sdk="Microsoft.NET.Sdk">
 
  <PropertyGroup>
    <OutputType>Exe</OutputType>
    <TargetFramework>net5.0</TargetFramework>
  </PropertyGroup>
 
</Project>

Es mejor usar .NET 8.0 para proyectos futuros:
1
2
3
4
5
6
7
8
9
10
<Project Sdk="Microsoft.NET.Sdk">
 
  <PropertyGroup>
    <OutputType>Exe</OutputType>
    <TargetFramework>net8.0</TargetFramework>
    <ImplicitUsings>enable</ImplicitUsings>
    <Nullable>enable</Nullable>
  </PropertyGroup>
 
</Project>
Valora esta respuesta
Me gusta: Está respuesta es útil y esta claraNo me gusta: Está respuesta no esta clara o no es útil
0
Comentar
sin imagen de perfil
Val: 168
Bronce
Ha mantenido su posición en C sharp (en relación al último mes)
Gráfica de C sharp

Manejo de cursores

Publicado por Meta (138 intervenciones) el 22/08/2024 23:28:56
Hola:

A mi me recuerda mucho el Spectrum en su época, que buenos recuerdos.

He probado tu código. No se mueve bien el > por la ventana, a parte de esto, parpadea la pantalla mucho ya que el motivo, seguro, que refresca varias veces cada vez que pulso una tecla flecha.

Hice un código nuevo. por ahora funciona medio bien.

Cuando indico el > juego en:

> Vol: ■■■■■■-- 6

Si pulso Enter, no debe ocurrir exactamente nada, solo indica que puedes usar las flechas izquierda y derecha para mover el volumen. Pulsar Enter aquí es como si no lo pulsara, no debe ocurrir nada y se me cierra la ventana si lo hago.

Todo lo demás me funciona.

Dejo el código nuevo.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
using System;
 
namespace LCD_Volumen_Consola_02
{
    internal class Program
    {
        static void Main(string[] args)
        {
 
            #region Configuración ventana.
            // Título de la ventana.
            Console.Title = "Opciones";
 
            const byte ANCHO_X = 20, ALTO_Y = 5;
 
            // Tamaño de la ventana, x, y o, ancho y alto.
            Console.SetWindowSize(ANCHO_X, ALTO_Y);
 
            // Quitar scroll laterales. Derecho y abajo.
            Console.SetBufferSize(ANCHO_X, ALTO_Y);
 
            // Color de fondo.
            Console.BackgroundColor = ConsoleColor.Yellow;
 
            // Color de las letras.
            Console.ForegroundColor = ConsoleColor.Black;
 
            // Limpiar pantalla y dejarlo todo en color de fondo.
            Console.Clear();
 
            // Visible el cursor. // No! Así lo haces invisible.
            Console.CursorVisible = false;
            #endregion
 
            int volumen = 6;
 
            Volumen();
 
            void Volumen()
            {
                // Variables.
                string[] TEXTO =
                {
                "   ** VOLUMEN **    ", // Posición 0.
                " Vol: ",               // 1
                "■",                    // 2
                "-",                    // 3
                "  ATRÁS",              // 4
                "INICIO",               // 5
                ">",                    // 6
                " "                     // 7
            };
 
                const int VOLMEN_MAX = 8;
                int opcion = 0; // 0 = Volumen, 1 = ATRÁS y 2 = INICIO.
 
                ConsoleKey teclaVolumen;
 
                // Limpiar pantalla.
                Console.Clear();
 
                // Mostrar menú.
                MostrarMenu();
 
                do
                {
                    // ¿Están en la opción Volumen o 0?
                    if (opcion == 0)
                    {
                        // Sí. Mostrar volumen.
                        MostrarVolumen();
                    }
 
                    // Captura tecla y lo guarda en la variable teclaVolumen.
                    teclaVolumen = Console.ReadKey(true).Key;
 
                    // ¿Están en la opción Volumen o 0?
                    if (opcion == 0)
                    {
                        // Sí. Controlar el volumen.
                        if ((teclaVolumen == ConsoleKey.RightArrow) && (volumen < VOLMEN_MAX))
                        {
                            volumen++;
                        }
                        else if ((teclaVolumen == ConsoleKey.LeftArrow) && (volumen > 0))
                        {
                            volumen--;
                        }
                        else if ((teclaVolumen == ConsoleKey.UpArrow) || (teclaVolumen == ConsoleKey.DownArrow))
                        {
                            opcion = 1;
                        }
                    }
                    else // No. Mientras.
                    {
                        // Navegar entre ATRÁS e INICIO.
                        if ((teclaVolumen == ConsoleKey.LeftArrow) && (opcion == 2))
                        {
                            opcion = 1; // 1 = ATRÁS.
                        }
                        else if ((teclaVolumen == ConsoleKey.RightArrow) && (opcion == 1))
                        {
                            opcion = 2; // 2 = INICIO.
                        }
                        else if ((teclaVolumen == ConsoleKey.UpArrow) || (teclaVolumen == ConsoleKey.DownArrow))
                        {
                            opcion = 0; // 0 = Volumen.
                        }
                    }
 
                    // Mostrar menú.
                    MostrarMenu();
 
                } while (teclaVolumen != ConsoleKey.Enter);
 
                // Acción al pulsar Enter.
                if (opcion == 1)
                {
                    // Limpiar pantalla.
                    Console.Clear();
 
                    // Mostrar mensaje.
                    Console.WriteLine("¡Mensaje ATRÁS!");
 
                    // Lee tecla hasta que detecte que haz pulsado Enter.
                    while (Console.ReadKey(true).Key != ConsoleKey.Enter) { };
 
                    MostrarVolumen();
                    MostrarMenu();
                }
                else if (opcion == 2)
                {
                    // Limpiar pantalla.
                    Console.Clear();
 
                    // Mostrar mensaje.
 
                    Console.WriteLine("¡Mensaje INICIO!");
 
                    // Lee tecla hasta que detecte que haz pulsado Enter.
                    while (Console.ReadKey(true).Key != ConsoleKey.Enter) { };
 
                    MostrarVolumen();
                    MostrarMenu();
                }
 
                void MostrarVolumen()
                {
                    Console.SetCursorPosition(0, 0);
                    Console.Write(TEXTO[0]);           //    ** VOLUMEN **
 
                    Console.SetCursorPosition(1, 1);
                    Console.Write(TEXTO[1]);           //   Vol:
 
                    for (int i = 0; i < volumen; i++)
                    {
                        Console.Write(TEXTO[2]);       // ■
                    }
 
                    for (int j = 0; j < (VOLMEN_MAX - volumen); j++)
                    {
                        Console.Write(TEXTO[3]);       // -
                    }
 
                    // Mostrar el volumen en número.
                    Console.SetCursorPosition(16, 1);
                    Console.Write(volumen);
                }
 
                void MostrarMenu()
                {
                    Console.SetCursorPosition(0, 3);
                    Console.Write(TEXTO[4]);           //   ATRÁS
 
                    Console.SetCursorPosition(13, 3);
                    Console.Write(TEXTO[5]);           //   INICIO
 
                    Console.SetCursorPosition(0, 1);
                    Console.Write(TEXTO[7]);           //
                    Console.SetCursorPosition(0, 3);
                    Console.Write(TEXTO[7]);           //
                    Console.SetCursorPosition(11, 3);
                    Console.Write(TEXTO[7]);           //
 
                    // ¿Es 0 = Volumen?
                    if (opcion == 0)
                    {
                        // Sí. Indica esta posición del cursor.
                        Console.SetCursorPosition(0, 1);
                    }
 
                    // No. Entonces, ¿ 1 = ATRÁS?
                    else if (opcion == 1)
                    {
                        // Sí. Indica esta posición del cursor.
                        Console.SetCursorPosition(0, 3);
                    }
 
                    // No. Entonces, ¿2 = INICIO?
                    else if (opcion == 2)
                    {
                        // Sí. Indica esta posición del cursor.
                        Console.SetCursorPosition(11, 3);
                    }
 
                    // Muestra el caracter >.
                    Console.Write(TEXTO[6]);           //   >
                }
 
                // Pulse cualquier tecla para salir.
                Console.ReadKey();
            }
        }
    }
}

Este código funciona mucho mejor, menos la parte que dije arriba, todavía no he averiguado anular el Enter cuando me selecciona el volumen.

Y si, es un tema muy interesante todo esto.

Muchas gracias por el apoyo, solo me falta resolver este problema, con o sin IA.
Valora esta respuesta
Me gusta: Está respuesta es útil y esta claraNo me gusta: Está respuesta no esta clara o no es útil
0
Comentar