Problema con widgets flutter

Miguel-ito

Buenas.

Estoy empezando con flutter y para hacerme con el estoy haciendo un 3 en raya, tengo un widget que hace de tablero y dentro de ese tablero creo 9 widgets token que son los que tienes que pulsar y se transforman en un circulo o en una X.

desde el widget tablero le paso al token el estado para poder saber que imagen tengo que poner pero el problema es que se me cambian todos los tokens en lugar del que pulso.

He intentado asignar keys pero no he obtenido mucho resultado. A ver si vosotros podeis echarme una manilla o al menos guiarme por donde tengo que tirar y ya investigo yo.

Tablero:

class Board extends StatefulWidget {
  @override
  _BoardState createState() => _BoardState();
}

class _BoardState extends State<Board> {

  List<int> _score = [0,0,0,0,0,0,0,0,0];
  int _player = 0;
  bool _started = false;
  bool _finished = false;

  bool checkWinner() {
    return true;
  }

  void startGame() {
    this._started = true;
    this._finished = false;
  }

  void finishGame() {
    this._finished = true;
  }

  void tokenPressed(int index) {
    if(this._player == 1) {
      setState(() {
        this._player = 2;
      });
    }
    else {
      setState(() {
        this._player = 1;
      });
    }
    this.doPlay(index);
  }

  void doPlay(int index) {

  }

  void showWinner(BuildContext context, int player) {
    showDialog<void>(
        context: context,
        builder: (BuildContext context) {
          return AlertDialog(
            content: Text(
                'Congratulations player $player, you have won this match.',
                style: TextStyle(
                  fontFamily: 'Dosis',
                  fontWeight: FontWeight.bold
                )
            ),
            actions: [
              FlatButton(
                child: Text(
                    'OK',
                    style: TextStyle(
                      fontFamily: 'Dosis',
                      fontWeight: FontWeight.bold
                    )
                ),
                onPressed: () {
                  Navigator.pop(context);
                },
              )
            ],
          );
        }
    );
  }

  @override
  Widget build(BuildContext context) {
    return Container(
      margin: EdgeInsets.fromLTRB(0, 50.0, 0, 0),
      padding: EdgeInsets.all(10.0),
      child: GridView.count(
        crossAxisCount: 3,
        children: List.generate(9, (index) => Token(
          index: index,
          player: this._player,
          started: this._started,
          finished: this._finished,
          onTokenPressed: this.tokenPressed,
          onStartGame: this.startGame,
        )),
      ),
    );
  }
}

Token:

class Token extends StatefulWidget {
  final int index;
  final int player;
  final bool started;
  final bool finished;
  final dynamic onTokenPressed;
  final dynamic onStartGame;

  Token({Key key, this.index, this.player, this.started, this.finished, this.onTokenPressed, this.onStartGame}) : super(key: key);

  @override
  _TokenState createState() => _TokenState();
}

class _TokenState extends State<Token> {

  Widget _image;

  @override
  Widget build(BuildContext context) {
    this._image = SizedBox( width: 96, height: 96, );
    if(this.widget.started) {
      if(this.widget.player == 1) {
        this._image = Image(image: AssetImage('assets/circle.png'), width: 96.0, height: 96.0);
      }
      if(this.widget.player == 2) {
        this._image = Image(image: AssetImage('assets/cross.png'), width: 96.0, height: 96.0);
      }
    }
    return GestureDetector(
      child: Stack(
        alignment: Alignment.center,
        children: <Widget>[
          Container(
            margin: EdgeInsets.all(5.0),
            decoration: BoxDecoration(
                color: Colors.white,
                border: Border.all(color: Colors.black),
                boxShadow: [
                  BoxShadow(
                      offset: Offset.fromDirection(0.25*pi, 2.5),
                      blurRadius: 2.5
                  )
                ],
                borderRadius: BorderRadius.all(Radius.circular(10.0))
            ),
          ),
          this._image,
        ],
      ),
      onTap: () {
        if(!this.widget.started) {
          this.widget.onStartGame();
        }
        this.widget.onTokenPressed(this.widget.index);
      },
    );
  }
}

Gracias de antemano.

JuAn4k4

Estas confundiendo el turno con quién pulsó en el tablero la casilla.
Tu token está pintando de quién es el turno, y no quién pulsó la casilla

Ahora edito y te doy más detalles.

Edit:

Básicamente, el "score" es el tablero, y es lo que tienen que pintar los 9 tokens (casillas). Cada uno tiene que pintar el índice correspondiente de este array.
Y además, cuando el jugador actual (el que tiene el turno) pulsa en una casilla, se tiene que guardar en el score quién la pulsó. (ademas de cambiar el turno).

Como regla general, esos if/else repitiendo código según el player, intenta simplificar el if/else a lo básico (url de la imagen, el número de quien es el turno, etc)

Importante: No pato. Gracias #3

2 respuestas
B

#2 Se te olvido poner no pato.
Ya lo pongo yo.

Pd: No pato.

1 respuesta
JuAn4k4

#3 Pensaba que era en off-topic only.

Me convertiré en un pato por ser #2?

1 respuesta
B

#4 Perdón por patocinar el hilo (No sé si esa palabra existe)

Pero te respondo, no es sólo Off Topic, pato está en todos los foros, controla todos los temas, deporte, videojuegos, criptomonedas, feda, off topic, estudios,hardware etc.
Pato es omnipresente y omnisapiente, por eso hay que recalcar el pato en cada hilo si eres el 2ª

1
Fyn4r

Mira, si fuese mod os banearia a todos los que jodeis hilos con pato parriba, pato pabajo

3 1 respuesta
cabron

#6

¿les mandabas patomar por culo?

8 1 respuesta
B

#7 Dios, como me he patoido de la risa jajaja.

Miguel-ito

#2 Muchas gracias. Tiene todo el sentido eso que dices, voy a darle una vuelta para arreglarlo.