Skip to content
Toggle navigation
P
Projects
G
Groups
S
Snippets
Help
Rafa Castillo Passols
/
peponator
This project
Loading...
Sign in
Toggle navigation
Go to a project
Project
Repository
Issues
0
Merge Requests
0
Pipelines
Wiki
Snippets
Settings
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Commit
aaf9d98d
authored
May 04, 2025
by
Diego Pérez Peña
Browse files
Options
_('Browse Files')
Download
Email Patches
Plain Diff
Agregada escritura y lectura del archivo de récords
parent
e7c7e494
Hide whitespace changes
Inline
Side-by-side
Showing
7 changed files
with
232 additions
and
100 deletions
lib/modelo/peponator_record.dart
lib/paginas/pantalla_juego.dart
lib/paginas/pantalla_records.dart
lib/peponator_app.dart
macos/Flutter/GeneratedPluginRegistrant.swift
pubspec.lock
pubspec.yaml
lib/modelo/peponator_record.dart
View file @
aaf9d98d
...
...
@@ -4,4 +4,23 @@ class PeponatorRecord {
final
DateTime
fecha
;
PeponatorRecord
({
required
this
.
jugador
,
required
this
.
puntuacion
,
required
this
.
fecha
});
factory
PeponatorRecord
.
desdeJson
(
Map
<
String
,
dynamic
>
json
)
{
return
PeponatorRecord
(
jugador:
json
[
'jugador'
],
puntuacion:
json
[
'puntuacion'
],
fecha:
DateTime
.
parse
(
json
[
'fecha'
])
);
}
String
aJson
(){
var
json
=
'''
{
"jugador": "
$jugador
",
"puntuacion":
$puntuacion
,
"fecha": "
$fecha
"
}
'''
;
return
json
;
}
}
\ No newline at end of file
lib/paginas/pantalla_juego.dart
View file @
aaf9d98d
import
'dart:async'
;
import
'dart:convert'
;
import
'dart:io'
;
import
'package:flutter/material.dart'
;
import
'package:peponator/modelo/peponator_record.dart'
;
import
'package:peponator/modelo/pista.dart'
;
import
'package:peponator/paginas/paginas.dart'
;
import
'package:peponator/widgets/pantalla_pausa.dart'
;
...
...
@@ -55,9 +60,14 @@ class _PantallaJuegoState extends State<PantallaJuego>
late
int
posicion
;
late
String
jugador
;
late
final
File
recordsFile
;
List
<
PeponatorRecord
>?
records
;
@override
void
initState
()
{
super
.
initState
();
_loadRecords
();
// TODO: Cargar el máximo de intentos
maxIntentos
=
21
;
...
...
@@ -640,7 +650,6 @@ class _PantallaJuegoState extends State<PantallaJuego>
);
}
// TODO: Agregar una pantalla de registro de récords
Widget
_buildPantallaFinal
(
Orientation
orientation
){
final
fullWidth
=
(
orientation
==
Orientation
.
portrait
)?
MediaQuery
.
of
(
context
).
size
.
width
-
MediaQuery
.
of
(
context
).
padding
.
horizontal
:
400.0
;
...
...
@@ -660,7 +669,7 @@ class _PantallaJuegoState extends State<PantallaJuego>
Column
(
children:
[
Text
(
'¡Nuevo récord!'
,
puntuacion
.
toString
()
,
textAlign:
TextAlign
.
center
,
style:
Theme
.
of
(
context
).
textTheme
.
headlineMedium
,
),
...
...
@@ -708,27 +717,60 @@ class _PantallaJuegoState extends State<PantallaJuego>
mainAxisAlignment:
MainAxisAlignment
.
spaceAround
,
children:
[
Expanded
(
child:
Padding
(
padding:
const
EdgeInsets
.
symmetric
(
horizontal:
8.0
),
child:
TextButton
(
style:
TextButton
.
styleFrom
(
backgroundColor:
Colors
.
green
,
disabledBackgroundColor:
Colors
.
white12
,
foregroundColor:
Color
.
fromARGB
(
255
,
237
,
237
,
237
)
backgroundColor:
Color
.
fromARGB
(
255
,
0
,
86
,
3
),
foregroundColor:
Colors
.
white
,
disabledBackgroundColor:
Colors
.
black26
,
disabledForegroundColor:
Color
.
fromARGB
(
255
,
40
,
40
,
40
),
),
onPressed:
(
jugador
.
isNotEmpty
)?
()
{}
:
null
,
onPressed:
(
jugador
.
isNotEmpty
)?
()
{
final
newRecord
=
PeponatorRecord
(
jugador:
jugador
,
puntuacion:
puntuacion
,
fecha:
DateTime
.
now
()
);
records
!.
insert
(
posicion
,
newRecord
);
while
(
records
!.
length
>
PantallaRecords
.
maxRecords
){
records
!.
removeLast
();
}
_writeRecords
();
setState
(()
{
posicion
=
PantallaRecords
.
maxRecords
;
});
}
:
null
,
child:
Text
(
'Guardar récord'
,
textScaler:
TextScaler
.
linear
(
1.1
),
)
)
),
)
),
Expanded
(
child:
Padding
(
padding:
const
EdgeInsets
.
symmetric
(
horizontal:
8.0
),
child:
TextButton
(
onPressed:
()
{},
child:
Text
(
'Salir sin guardar'
,
textScaler:
TextScaler
.
linear
(
1.1
),
)
)
style:
TextButton
.
styleFrom
(
backgroundColor:
Color
.
fromARGB
(
255
,
150
,
10
,
0
),
foregroundColor:
Colors
.
white
,
disabledBackgroundColor:
Colors
.
black26
,
disabledForegroundColor:
Color
.
fromARGB
(
255
,
40
,
40
,
40
),
),
onPressed:
()
{
setState
(()
{
posicion
=
PantallaRecords
.
maxRecords
;
});
},
child:
Text
(
'Salir sin guardar'
,
textScaler:
TextScaler
.
linear
(
1.1
),
)
),
)
)
],
)
...
...
@@ -756,7 +798,7 @@ class _PantallaJuegoState extends State<PantallaJuego>
),
const
SizedBox
(
height:
16.0
),
Text
(
victoria
?
'
¿Quieres jugar otra vez?
'
:
'Más suerte la próxima vez...'
,
victoria
?
'
Puntuación:
$puntuacion
'
:
'Más suerte la próxima vez...'
,
textAlign:
TextAlign
.
center
,
style:
Theme
.
of
(
context
).
textTheme
.
titleLarge
,
),
...
...
@@ -917,7 +959,7 @@ class _PantallaJuegoState extends State<PantallaJuego>
void
_escribirRespuesta
()
async
{
await
Future
.
delayed
(
Duration
(
milliseconds:
600
));
setState
(()
{
// TODO: Construir respuesta de Peponator
con cierto retardo
// TODO: Construir respuesta de Peponator
mensajes
.
add
(
PeponatorMensaje
(
message:
"¡Hola! Estoy pensando en un número del
$limiteInferior
al
$limiteSuperior
. ¿Te crees capaz de adivinarlo?"
));
if
(
numeroEscogido
!
<
numeroAdivinar
){
limiteInferior
=
numeroEscogido
!
+
1
;
...
...
@@ -929,10 +971,16 @@ class _PantallaJuegoState extends State<PantallaJuego>
}
if
(
numeroEscogido
!
==
numeroAdivinar
){
victoria
=
true
;
// TODO: Calcular puntuación
puntuacion
=
2000
;
// TODO: Calcular posición en la tabla de récords
posicion
=
0
;
puntuacion
=
1500
;
if
(
records
!=
null
){
posicion
=
records
!.
length
;
while
(
posicion
>
0
&&
records
![
posicion
-
1
].
puntuacion
<
puntuacion
){
posicion
--;
}
}
}
numeroEscogido
=
null
;
intentos
++;
...
...
@@ -947,6 +995,40 @@ class _PantallaJuegoState extends State<PantallaJuego>
_scrollDown
();
});
}
Future
<
void
>
_loadRecords
()
async
{
recordsFile
=
await
PantallaRecords
.
localFile
();
final
lista
=
<
PeponatorRecord
>[];
try
{
final
productosString
=
await
recordsFile
.
readAsString
();
print
(
productosString
);
final
List
<
dynamic
>
recordsJson
=
jsonDecode
(
productosString
);
for
(
var
prodJson
in
recordsJson
)
{
lista
.
add
(
PeponatorRecord
.
desdeJson
(
prodJson
));
}
}
on
FileSystemException
catch
(
e
)
{
lista
.
clear
();
}
finally
{
records
=
lista
;
}
}
Future
<
void
>
_writeRecords
()
async
{
final
sb
=
StringBuffer
(
'[
\n
'
);
for
(
int
i
=
0
;
i
<
records
!.
length
;
i
++)
{
sb
.
write
(
records
![
i
].
aJson
());
if
(
i
<
records
!.
length
-
1
)
{
sb
.
write
(
',
\n
'
);
}
else
{
sb
.
write
(
'
\n
'
);
}
}
sb
.
write
(
']'
);
await
recordsFile
.
writeAsString
(
sb
.
toString
());
}
}
enum
OpcionesFinPartida
{
...
...
lib/paginas/pantalla_records.dart
View file @
aaf9d98d
import
'dart:convert'
;
import
'dart:io'
;
import
'package:flutter/material.dart'
;
import
'package:path_provider/path_provider.dart'
;
import
'package:peponator/modelo/modelo.dart'
;
class
PantallaRecords
extends
State
less
Widget
{
class
PantallaRecords
extends
State
ful
Widget
{
static
const
int
maxRecords
=
20
;
const
PantallaRecords
({
super
.
key
});
@override
Widget
build
(
BuildContext
context
)
{
// TODO: Cargar los récords (esto se haría con un archivo de texto en la carpeta privada de la aplicación)
State
<
PantallaRecords
>
createState
()
=>
_PantallaRecordsState
();
static
Future
<
String
>
_localPath
()
async
{
final
Directory
directory
=
await
getApplicationDocumentsDirectory
();
return
directory
.
path
;
}
static
Future
<
File
>
localFile
()
async
{
final
path
=
await
_localPath
();
return
File
(
'
$path
/records.json'
);
}
}
class
_PantallaRecordsState
extends
State
<
PantallaRecords
>
{
@override
Widget
build
(
BuildContext
context
)
{
return
OrientationBuilder
(
builder:
(
context
,
orientation
)
{
return
Scaffold
(
body:
SafeArea
(
child:
LayoutBuilder
(
builder:
(
context
,
constraints
)
{
if
(
orientation
==
Orientation
.
portrait
){
return
Column
(
crossAxisAlignment:
CrossAxisAlignment
.
stretch
,
children:
[
_buildTitle
(
context
,
orientation
),
_buildRecordsView
(
context
,
orientation
)
],
);
}
else
{
return
Row
(
children:
[
SizedBox
(
height:
constraints
.
maxHeight
,
width:
constraints
.
maxWidth
/
4
,
child:
_buildTitle
(
context
,
orientation
),
),
SizedBox
(
height:
constraints
.
maxHeight
,
width:
constraints
.
maxWidth
*
3
/
4
,
child:
_buildRecordsView
(
context
,
orientation
),
)
],
);
}
}
)
child:
FutureBuilder
(
future:
_loadRecords
(),
builder:
(
context
,
AsyncSnapshot
<
List
<
PeponatorRecord
>>
snapshot
)
{
if
(
snapshot
.
connectionState
==
ConnectionState
.
done
){
return
LayoutBuilder
(
builder:
(
context
,
constraints
)
{
if
(
orientation
==
Orientation
.
portrait
){
return
Column
(
crossAxisAlignment:
CrossAxisAlignment
.
stretch
,
children:
[
_buildTitle
(
context
,
orientation
),
_buildRecordsView
(
context
,
orientation
,
snapshot
.
requireData
)
],
);
}
else
{
return
Row
(
children:
[
SizedBox
(
height:
constraints
.
maxHeight
,
width:
constraints
.
maxWidth
/
4
,
child:
_buildTitle
(
context
,
orientation
),
),
SizedBox
(
height:
constraints
.
maxHeight
,
width:
constraints
.
maxWidth
*
3
/
4
,
child:
_buildRecordsView
(
context
,
orientation
,
snapshot
.
requireData
),
)
],
);
}
}
);
}
else
{
return
const
Center
(
child:
CircularProgressIndicator
(),);
}
}
)
),
floatingActionButton:
_buildFAB
(
context
,
orientation
),
);
...
...
@@ -80,9 +107,7 @@ class PantallaRecords extends StatelessWidget {
);
}
Widget
_buildRecordsView
(
BuildContext
context
,
Orientation
orientation
){
final
records
=
_loadMockData
();
Widget
_buildRecordsView
(
BuildContext
context
,
Orientation
orientation
,
List
<
PeponatorRecord
>
records
){
if
(
records
.
isNotEmpty
)
{
final
vistaRecords
=
ListView
.
builder
(
shrinkWrap:
true
,
...
...
@@ -213,8 +238,8 @@ class PantallaRecords extends StatelessWidget {
)),
content:
Text
(
(
orientation
==
Orientation
.
portrait
)?
'Esta acción no se puede deshacer. ¿Seguro que quieres borrar todos los récords?'
:
'Esta acción no se puede deshacer.
\n
¿Seguro que quieres borrar todos los récords?'
'Esta acción no se puede deshacer. ¿Seguro que quieres borrar todos los récords?'
:
'Esta acción no se puede deshacer.
\n
¿Seguro que quieres borrar todos los récords?'
,
textAlign:
TextAlign
.
center
,
style:
Theme
.
of
(
context
).
textTheme
.
titleMedium
,
...
...
@@ -223,7 +248,7 @@ class PantallaRecords extends StatelessWidget {
actions:
[
TextButton
(
onPressed:
()
{
// TODO: Borrar récords
_deleteRecords
();
Navigator
.
pop
(
context
);
},
style:
TextButton
.
styleFrom
(
...
...
@@ -276,50 +301,27 @@ class PantallaRecords extends StatelessWidget {
);
}
List
<
PeponatorRecord
>
_loadMockData
()
{
final
records
=
<
PeponatorRecord
>[];
Future
<
List
<
PeponatorRecord
>>
_loadRecords
()
async
{
final
file
=
await
PantallaRecords
.
localFile
();
final
lista
=
<
PeponatorRecord
>[];
records
.
add
(
PeponatorRecord
(
jugador:
"AAA"
,
puntuacion:
12211350
,
fecha:
DateTime
.
now
()
));
records
.
add
(
PeponatorRecord
(
jugador:
"BBB"
,
puntuacion:
25
,
fecha:
DateTime
.
now
()
));
records
.
add
(
PeponatorRecord
(
jugador:
"CCC"
,
puntuacion:
13
,
fecha:
DateTime
.
now
()
));
records
.
add
(
PeponatorRecord
(
jugador:
"DDD"
,
puntuacion:
7
,
fecha:
DateTime
.
now
()
));
records
.
add
(
PeponatorRecord
(
jugador:
"EEE"
,
puntuacion:
6
,
fecha:
DateTime
.
now
()
));
records
.
add
(
PeponatorRecord
(
jugador:
"FFF"
,
puntuacion:
5
,
fecha:
DateTime
.
now
()
));
records
.
add
(
PeponatorRecord
(
jugador:
"GGG"
,
puntuacion:
4
,
fecha:
DateTime
.
now
()
));
records
.
add
(
PeponatorRecord
(
jugador:
"HHH"
,
puntuacion:
3
,
fecha:
DateTime
.
now
()
));
try
{
final
productosString
=
await
file
.
readAsString
();
print
(
productosString
);
final
List
<
dynamic
>
recordsJson
=
jsonDecode
(
productosString
);
for
(
var
prodJson
in
recordsJson
)
{
lista
.
add
(
PeponatorRecord
.
desdeJson
(
prodJson
));
}
}
on
FileSystemException
catch
(
e
)
{
lista
.
clear
();
}
return
lista
;
}
return
records
;
Future
<
void
>
_deleteRecords
()
async
{
final
file
=
await
PantallaRecords
.
localFile
();
await
file
.
delete
();
setState
(()
{});
}
}
\ No newline at end of file
lib/peponator_app.dart
View file @
aaf9d98d
...
...
@@ -17,7 +17,7 @@ class PeponatorApp extends StatelessWidget {
),
darkTheme:
ThemeData
.
dark
(),
themeMode:
ThemeMode
.
system
,
home:
Pantalla
Juego
(
fromHome:
true
)
home:
Pantalla
Records
(
)
);
}
}
macos/Flutter/GeneratedPluginRegistrant.swift
View file @
aaf9d98d
...
...
@@ -5,8 +5,10 @@
import
FlutterMacOS
import
Foundation
import
path_provider_foundation
import
shared_preferences_foundation
func
RegisterGeneratedPlugins
(
registry
:
FlutterPluginRegistry
)
{
PathProviderPlugin
.
register
(
with
:
registry
.
registrar
(
forPlugin
:
"PathProviderPlugin"
))
SharedPreferencesPlugin
.
register
(
with
:
registry
.
registrar
(
forPlugin
:
"SharedPreferencesPlugin"
))
}
pubspec.lock
View file @
aaf9d98d
...
...
@@ -160,6 +160,30 @@ packages:
url: "https://pub.dev"
source: hosted
version: "1.9.1"
path_provider:
dependency: "direct main"
description:
name: path_provider
sha256: "50c5dd5b6e1aaf6fb3a78b33f6aa3afca52bf903a8a5298f53101fdaee55bbcd"
url: "https://pub.dev"
source: hosted
version: "2.1.5"
path_provider_android:
dependency: transitive
description:
name: path_provider_android
sha256: d0d310befe2c8ab9e7f393288ccbb11b60c019c6b5afc21973eeee4dda2b35e9
url: "https://pub.dev"
source: hosted
version: "2.2.17"
path_provider_foundation:
dependency: transitive
description:
name: path_provider_foundation
sha256: "4843174df4d288f5e29185bd6e72a6fbdf5a4a4602717eed565497429f179942"
url: "https://pub.dev"
source: hosted
version: "2.4.1"
path_provider_linux:
dependency: transitive
description:
...
...
pubspec.yaml
View file @
aaf9d98d
...
...
@@ -35,6 +35,7 @@ dependencies:
# Use with the CupertinoIcons class for iOS style icons.
cupertino_icons
:
^1.0.8
shared_preferences
:
^2.5.3
path_provider
:
^2.1.5
dev_dependencies
:
flutter_test
:
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment