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);
}