in NearbyConnectionsCpp/app/src/main/cpp/NearbyNativeActivity.cpp [37:154]
void Engine::PlayGame() {
ndk_helper::JNIHelper::GetInstance()->RunOnUiThread([this]() {
LOGI("Playing match");
if (dialog_) delete dialog_;
// Start game
InitializeGame();
//
// Using jui_helper, a support library, to create and bind gameplay buttons.
//
dialog_ = new jui_helper::JUIDialog(app_->activity);
// Setting up labels
time_text_ = new jui_helper::JUITextView("Time Left: 0:00");
time_text_->AddRule(jui_helper::LAYOUT_PARAMETER_ALIGN_PARENT_TOP,
jui_helper::LAYOUT_PARAMETER_TRUE);
time_text_->AddRule(jui_helper::LAYOUT_PARAMETER_CENTER_IN_PARENT,
jui_helper::LAYOUT_PARAMETER_TRUE);
time_text_->SetAttribute("TextSize", jui_helper::ATTRIBUTE_UNIT_SP, 18.f);
time_text_->SetAttribute("Padding", 10, 10, 10, 10);
// Adding formula Text
math_formula_ = new jui_helper::JUITextView("10 + 5 = ?");
math_formula_->AddRule(jui_helper::LAYOUT_PARAMETER_BELOW, time_text_);
math_formula_->AddRule(jui_helper::LAYOUT_PARAMETER_CENTER_IN_PARENT,
jui_helper::LAYOUT_PARAMETER_TRUE);
math_formula_->SetAttribute("TextSize", jui_helper::ATTRIBUTE_UNIT_SP,
24.f);
math_formula_->SetAttribute("Padding", 10, 10, 10, 10);
// Adding Multiple Choice Buttons
jui_helper::JUIButton *button = CreateChoiceButton("A", NULL);
if (button) {
button->AddRule(jui_helper::LAYOUT_PARAMETER_ALIGN_PARENT_LEFT,
jui_helper::LAYOUT_PARAMETER_TRUE);
button->SetMargins(40, 0, 0, 0); // todo: make it adaptive
}
game_buttons_[0] = button;
for (int i = 1; i < CHOICES_PER_QUESTION; i++) {
std::string cap(1, 'A' + i);
button = CreateChoiceButton(cap.c_str(), game_buttons_[i - 1]);
game_buttons_[i] = button;
}
const int32_t labelWidth = 600;
const int32_t labelHeight = 300;
scores_text_ = new jui_helper::JUITextView("0:00");
scores_text_->AddRule(jui_helper::LAYOUT_PARAMETER_BELOW,
game_buttons_[CHOICES_PER_QUESTION - 1]);
scores_text_->AddRule(jui_helper::LAYOUT_PARAMETER_CENTER_IN_PARENT,
jui_helper::LAYOUT_PARAMETER_TRUE);
scores_text_->SetAttribute("TextSize", jui_helper::ATTRIBUTE_UNIT_SP, 18.f);
scores_text_->SetAttribute("MinimumWidth", labelWidth);
scores_text_->SetAttribute("MinimumHeight", labelHeight);
scores_text_->SetAttribute("Padding", 10, 10, 10, 10);
UpdateScoreBoardUI(false);
dialog_->AddView(math_formula_);
std::for_each(
game_buttons_, game_buttons_ + CHOICES_PER_QUESTION,
[this](jui_helper::JUIButton *button) { dialog_->AddView(button); });
PlayOneRound();
dialog_->AddView(time_text_);
dialog_->AddView(scores_text_);
dialog_->SetAttribute("Title", "Select an answer");
dialog_->SetCallback(
jui_helper::JUICALLBACK_DIALOG_DISMISSED,
[this](jui_helper::JUIDialog *dialog, const int32_t message) {
LOGI("Dialog dismissed");
LeaveGame();
dialog_ = nullptr;
});
dialog_->Show();
//
// Invoke time counter periodically
//
std::thread([this]() {
ndk_helper::JNIHelper &helper = *ndk_helper::JNIHelper::GetInstance();
helper.AttachCurrentThread();
while (playing_ && game_time_ <= GAME_DURATION) {
// Update game UI, UI update needs to be performed in UI thread
ndk_helper::JNIHelper::GetInstance()->RunOnUiThread([this]() {
char str[SCORE_STRING_LEN];
std::lock_guard<std::mutex> lock(mutex_);
snprintf(str, SCORE_STRING_LEN, "Time Left: %d",
GAME_DURATION - this->game_time_);
time_text_->SetAttribute("Text", const_cast<const char *>(str));
});
// maintain our private clock
std::this_thread::sleep_for(std::chrono::milliseconds(1000));
game_time_ += 1;
}
// finish game
playing_ = false;
ndk_helper::JNIHelper::GetInstance()->RunOnUiThread([this]() {
std::lock_guard<std::mutex> lock(mutex_);
for (int i = 0; i < CHOICES_PER_QUESTION; i++) {
game_buttons_[i]->SetAttribute("Enabled", false);
}
math_formula_->SetAttribute("Enabled", false);
});
BroadcastScore(score_counter_, true);
UpdateScoreBoardUI(true);
helper.DetachCurrentThread();
}).detach();
});
}