我查看了与此问题有关的其他解决方案,但我没有找到适用于我的特定情况的解决方案。
概述:我正在创建一个基于回合制的多人游戏应用程序,两个用户随机匹配,然后开始游戏。
因为Parse查询返回可以播放的用户,所以我不希望包含已匹配的用户。但是,由于此错误,我无法排除匹配的用户:
java.lang.IllegalArgumentException: Cannot save a ParseUser that is not authenticated.
由于以下情况,这对我来说是个大问题:
假设用户A想要玩游戏,字段READY_TO_PLAY
设置为true,并且他被带到FindOpponentActivity
类。由于还没有其他人在寻找游戏,因此会出现告诉用户这一事件,然后他将被带回主要活动。
用户B也在寻找游戏。他点击查找随机对手按钮,同样被带到FindRandomOpponent
课程。可是等等!用户A也在寻找游戏!因此用户B与用户A匹配,此代码运行:
mCurrentUser.put(ParseConstants.KEY_READY_TO_PLAY,false);
mOpponent.put(ParseConstants.KEY_READY_TO_PLAY,false);
现在,此代码适用于不再出现在列表中的当前用户(用户B),但不适用于A.
因此,如果一分钟后,用户C出现,他与A匹配,D,E和F也匹配。你明白了。
如何解决这个问题?
public class FindingOpponentActivity extends Activity {
protected ParseRelation<ParseUser> mOpponentRelation;
protected ParseUser mCurrentUser;
protected MenuItem mDoneItem;
public static final String TAG = FindingOpponentActivity.class.getSimpleName();
protected List<ParseUser> mUsers;
protected ParseUser mOpponent;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
requestWindowFeature(Window.FEATURE_INDETERMINATE_PROGRESS);
setContentView(R.layout.activity_find_opponent);
// Show the Up button in the action bar
/*getListView().setChoiceMode(ListView.CHOICE_MODE_MULTIPLE); */
}
@Override
protected void onResume() {
super.onResume();
mCurrentUser = ParseUser.getCurrentUser();
mOpponentRelation = mCurrentUser.getRelation(ParseConstants.KEY_OPPONENT_NAME);
setProgressBarIndeterminateVisibility(true);
ParseQuery<ParseUser> query = ParseUser.getQuery();
query.whereEqualTo(ParseConstants.KEY_READY_TO_PLAY, true);
query.orderByAscending(ParseConstants.KEY_CREATED_AT);
query.setLimit(100);
query.findInBackground(new FindCallback<ParseUser>() {
@Override
public void done(List<ParseUser> users, ParseException e) {
setProgressBarIndeterminateVisibility(false);
if (e == null) {
//success!
int rand = (int) (Math.random() * 100);
mUsers = users;
mUsers.remove(ParseUser.getCurrentUser());
if (mUsers.size() == 0) {
Toast.makeText(FindingOpponentActivity.this,
R.string.no_player_available, Toast.LENGTH_LONG).show();
Intent intent = new Intent(FindingOpponentActivity.this, MainActivity.class);
startActivity(intent);
} else if (mUsers.size() == 1) {
mOpponentRelation.add(mUsers.get(0));
mOpponent = mUsers.get(0);
mCurrentUser.saveInBackground(new SaveCallback() {
@Override
public void done(ParseException e) {
if (e != null) {
Log.e(TAG, e.getMessage());
}
}
});
mCurrentUser.put(ParseConstants.KEY_READY_TO_PLAY, false);
mOpponent.put(ParseConstants.KEY_READY_TO_PLAY, false);
mCurrentUser.saveInBackground(new SaveCallback() {
@Override
public void done(ParseException e) {
if (e != null) {
Log.e(TAG, e.getMessage());
}
}
});
mOpponent.saveInBackground(new SaveCallback() {
@Override
public void done(ParseException e) {
if (e != null) {
Log.e(TAG, e.getMessage());
}
}
});
Intent intent = new Intent(FindingOpponentActivity.this, StartGameActivity.class);
startActivity(intent);