#flutter #dart
#flutter #dart
Вопрос:
Я кодирую игру в лабиринт. Игрок должен найти путь от верхнего левого квадрата до нижнего правого квадрата в сетке 6 x 6 (состоящей из плоских кнопок). Когда игрок нажимает на кнопку, она становится зеленой, если ход находится на пути, и красной, если это не так. Однако я хочу, чтобы квадрат, на который игрок нажимал последний раз, был фиолетовым. Например, если я ранее нажал на квадрат (0,0), я хочу, чтобы он оставался фиолетовым, пока не будет нажат другой квадрат. Затем я хочу, чтобы этот квадрат стал фиолетовым и (0,0) вернулся к исходному серому цвету. Однако я не могу найти способ изменить цвет кнопки, которую я в данный момент не нажимаю.
import 'dart:async';
import 'dart:io';
import 'package:flutter/cupertino.dart';
import 'package:flutter/foundation.dart';
import 'package:flutter/material.dart';
import 'package:flutter/services.dart';
import 'package:mazeeapp/HomePageClass.dart';
import 'dart:math';
import 'GameButtonamp;MazeClasses.dart';
import 'package:mazeeapp/main.dart';
import 'PathGenerator.dart';
import 'dart:convert';
import 'package:path_provider/path_provider.dart';
class GameButton extends StatefulWidget {
final int id;
int onPath = 0;
bool testOnPath() {
if (this.onPath == 1) {
return true;
} else {
return false;
}
}
bool testIfLegal(lastMove) {
return (((this.id - lastMove).abs() == 1) ^
((this.id - lastMove).abs() == 10));
}
bool moveCheck() {
if (this.testIfLegal(lastMove) amp; this.testOnPath()) {
return true;
} else {
return false;
}
}
GameButton(this.id, lastMove);
@override
_GameButtonState createState() => _GameButtonState();
}
class _GameButtonState extends State<GameButton> {
// this code going to be what happens on button press event
String buttonPress() {
displayImage=true;
//start timer only one time then return time elapsed once the maze has been completed.
bool shouldClockStart=true;
if(shouldClockStart) {
clock.start();
final shouldClockStart=false;
}
if(this.mounted) {
setState(() {
timeElapsed = clock.elapsed;
});
}
//if the person's previous move was correct this if statement will run and and utilize the moveCheck function
if (!lastMoveIncorrect) {
if (widget.moveCheck()) {
image="assets/greencheck.jpg";
lastMove = widget.id;
color = Colors.green;
//once square is correctly found it is taken off the path. ie the player cannot go backwards on the path
widget.onPath=0;
errors.add("correct");
Timer(Duration(milliseconds: 450), () {
if(this.mounted) {
setState(() {
color = Colors.purple;
displayImage = false;
});
}
});
//ending conditions: what app should do upon completion of maze. only triggers if player hits button 99 and it is a correct move
if ((widget.id == 99) amp; this.mounted) {
setState(() {
appComplete=true;
});
}
// end of ending conditions. next else statement is what happens if player's current move is incorrect but their lastmove was correct
} else {
image="assets/redx.jpg";
color = Colors.red;
lastMoveIncorrect = true;
//now that we know that player's most recent move was incorrect we need to determine whether move was not on path or invalid for documentation purposes in json file. this code does that
if(widget.testIfLegal(lastMove)) {
errors.add("incorrect");
}
else {
errors.add("invalid");
}
//end of classifying player's incorrect move
Timer(Duration(milliseconds:450), () {
if(this.mounted) {
setState(() {
color = Colors.purple;
displayImage = false;
});
}
});
setState(() => numberErrors );
}
}
// end of current if statement. Now if the player's previous move was incorrect the following statements will run-requiring the player to input the last correct move.
if (lastMoveIncorrect) {
if (widget.id == lastMove) {
color = Colors.green;
errors.add("Correct");
image="assets/greencheck.jpg";
lastMoveIncorrect = false;
Timer(Duration(milliseconds: 450), () {
if(this.mounted) {
setState(() {
color = Colors.purple;
displayImage = false;
});
}
});
} else {
setState(() => numberErrors );
image="assets/redx.jpg";
displayImage=true;
color = Colors.red;
if(widget.testIfLegal(lastMove)) {
errors.add("incorrect");
}
else {
errors.add("invalid");
}
Timer(Duration(milliseconds: 450), () {
if(this.mounted) {
setState(() {
color = Colors.purple;
displayImage = false;
});
}
});
}
}
// this line needed so flutter knows to dynamically rebuild entire grid of buttons on every press
controller.add(widget.id);
}
@override
Widget build(BuildContext context) {
return Container(
decoration: BoxDecoration(border: Border.all(color: Colors.black)),
child: FlatButton(
padding: EdgeInsets.all(10.0),
child: displayImage?Image.asset(image):null,
color: color,
materialTapTargetSize: MaterialTapTargetSize.shrinkWrap,
onPressed: () {
setState(() {
color=Colors.grey;
});
buttonPress();
}
),
);
}
}
class Maze extends StatefulWidget {
int numberErrors = 0;
List<GameButton> empty_grid = [
for (var i = 0; i < 100; i ) new GameButton(i, lastMove)
];
@override
_MazeState createState() => _MazeState();
}
class _MazeState extends State<Maze> {
@override
Widget build(BuildContext context) {}
}
Затем список из 100 игровых кнопок помещается в GridView и возвращается.
Комментарии:
1. Вы можете создать функцию в GameButton для изменения цвета, зачем просто нажимать?
2. @hoangquyy Я пробовал это, но я не могу понять, как создать функцию, которая может изменять цвет только одной кнопки за раз. Обратите внимание, что все мои кнопки являются экземплярами класса GameButton. Любой совет был бы оценен
3. Похоже, вы используете переменную color в качестве глобальной переменной, но не атрибута GameButton. Это было причиной, по которой вы не можете изменить цвет только одной кнопки. Почему бы вам не задать цвет имени атрибута в GameButton?
4. @hoangquyy хорошая идея, спасибо