Home > Back-end >  Randomize shown Images in Flutter
Randomize shown Images in Flutter

Time:04-03

I want to randomize the shown Images, and check with a bool, that a used "card" doesnt get displayed anymore, until the whole deck got consumed.

Heres my "Card class" where i specified all my Cards in a List:

import 'dart:math';

import 'dart:ui';

List<String> cardlist = [
      'assets/images/card-1.png',
      'assets/images/card-2.png',
      'assets/images/card-3.png',
      'assets/images/card-4.png',
      'assets/images/card-5.png',
      'assets/images/card-6.png',
      'assets/images/card-7.png',
      'assets/images/card-8.png',
      'assets/images/card-9.png',
      'assets/images/card-10.png',
      'assets/images/card-11.png',
      'assets/images/card-12.png',
      'assets/images/card-13.png',
      'assets/images/card-14.png',
      'assets/images/card-15.png',
      'assets/images/card-16.png',
      'assets/images/card-17.png',
      'assets/images/card-18.png',
      'assets/images/card-19.png',
      'assets/images/card-20.png',
      'assets/images/card-21.png',
      'assets/images/card-22.png',
      'assets/images/card-23.png',
      'assets/images/card-24.png',
      'assets/images/card-25.png',
      'assets/images/card-26.png',
      'assets/images/card-27.png',
      'assets/images/card-28.png',
      'assets/images/card-29.png',
      'assets/images/card-30.png',
      'assets/images/card-31.png',
      'assets/images/card-32.png',
      'assets/images/card-33.png',
      'assets/images/card-34.png',
      'assets/images/card-35.png',
      'assets/images/card-36.png',
      'assets/images/card-37.png',
      'assets/images/card-38.png',
      'assets/images/card-39.png',
      'assets/images/card-40.png',
      'assets/images/card-41.png',
      'assets/images/card-42.png',
      'assets/images/card-43.png',
      'assets/images/card-44.png',
      'assets/images/card-45.png',
      'assets/images/card-46.png',
      'assets/images/card-47.png',
      'assets/images/card-48.png',
      'assets/images/card-49.png',
      'assets/images/card-50.png',
      'assets/images/card-51.png',
      'assets/images/card-52.png',
      'assets/images/card-53.png',
      'assets/images/card-54.png',
      'assets/images/card-55.png'

];

Random Randomizer = Random();
    int randomIndex = random.nextInt(cardlist.length);
    Image randomImage = cardlist[cardlist];

As actually only 1 Card can be shown on the Main.dart, and it get flipped when clicked. I would like to make it the way after having it "discard" that a new one gets displayed, heres the Code:

import 'package:flutter/material.dart';
import 'dart:math'; // wegen PI berechnung nötig

void main() {
  runApp(MyApp());
}

class MyApp extends StatelessWidget {
  // This widget is the root of your application.
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      debugShowCheckedModeBanner: false,
      home: HomePage(),
    );
  }
}

class HomePage extends StatefulWidget {
  @override
  _HomePageState createState() => _HomePageState();
}

class _HomePageState extends State<HomePage> {
  //declare the isBack bool
  bool isBack = true;
  double angle = 0;

  void _flip() {
    setState(() {
      angle = (angle   pi) % (2 * pi);
    });
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      backgroundColor: Color(0xFF292a3e),
      body: SafeArea(
        child: Center(
          child: Column(
            mainAxisAlignment: MainAxisAlignment.center,
            children: [
              GestureDetector(
                onTap: _flip,
                child: TweenAnimationBuilder(
                    tween: Tween<double>(begin: 0, end: angle),
                    duration: Duration(seconds: 1),
                    builder: (BuildContext context, double val, __) {
                      //isBack wert wird geswithced
                      if (val >= (pi / 2)) {
                        isBack = false;
                      } else {
                        isBack = true;
                      }
                      return (Transform(
                        //Karte wird vom Center geflipped
                        alignment: Alignment.center,
                        transform: Matrix4.identity()
                          ..setEntry(3, 2, 0.001)
                          ..rotateY(val),
                        child: Container(
                            width: 309,
                            height: 474,
                            child: isBack
                                ? Container(
                              decoration: BoxDecoration(
                                borderRadius: BorderRadius.circular(10.0),
                                image: DecorationImage(
                                  image: AssetImage("assets/images/back.png"),
                                ),
                              ),
                            ) //Rückseite hier displayed
                                : Transform(
                              alignment: Alignment.center,
                              transform: Matrix4.identity()
                                ..rotateY(
                                    pi), // horizontaler flip
                              child: Container(
                                decoration: BoxDecoration(
                                  borderRadius:
                                  BorderRadius.circular(10.0),
                                  image: DecorationImage(
                                    image: AssetImage("assets/images/card-1.png"),
                                  ),
                                ),
                                child: Center(
                                  child: Text(
                                    "Hello You",
                                    style: TextStyle(
                                      fontSize: 30.0,
                                    ),
                                  ),
                                ),
                              ),
                            )
                        ),
                      ));
                    }),
              )
            ],
          ),
        ),
      ),
    );
  }
}

CodePudding user response:

For starters, you can save a little screen real estate by declaring that list like so.

final cardList =
    List<String>.generate(55, (index) => 'assets/images/card-${index   1}.png');

If I understand your issue, you just want to generate a random image and make sure they don't get duplicated from the list before they're all used, is that correct?

If so, I would duplicate that list and work off of that, and remove all entries that get used.

List<String> availableImages = [...cardList]; // modifiable list

Then this function should return a random image that hasn't been used, and reset the list if they have all been used.

 AssetImage getRandomImage() {
    if (availableImages.length == 0) {
      availableImages = [...cardList]; // resetting if all images have been used
    }
    final random = Random();
    int randomIndex = random.nextInt(availableImages.length);
    final asset = availableImages[randomIndex];
    availableImages.remove(asset); // removing image so it doesn't get used again until all images have been used

    return AssetImage(asset);
  }

Then you can pass getRandomImage() into your DecorationImage instead of the hard coded value you have now.

That should at least get you going in the right direction.

Edit based on suggestion by @jamesdlin

Utilizing Darts shuffle method you could do something like this.

List<String> availableImages = [...cardList]..shuffle(); // shuffled copy of list

The getRandomImage could be implemented like so.

  int index = 0;

  AssetImage getRandomImage() {
    if (index == 54) {
      availableImages.shuffle();
      index = 0;
    } // re-shuffling and resetting index if all images have been used

    final asset = availableImages[index];

    index  ;

    return AssetImage(asset);
  }
  • Related