diff --git a/.gitignore b/.gitignore
new file mode 100644
index 0000000..aa724b7
--- /dev/null
+++ b/.gitignore
@@ -0,0 +1,15 @@
+*.iml
+.gradle
+/local.properties
+/.idea/caches
+/.idea/libraries
+/.idea/modules.xml
+/.idea/workspace.xml
+/.idea/navEditor.xml
+/.idea/assetWizardSettings.xml
+.DS_Store
+/build
+/captures
+.externalNativeBuild
+.cxx
+local.properties
diff --git a/.idea/.gitignore b/.idea/.gitignore
new file mode 100644
index 0000000..26d3352
--- /dev/null
+++ b/.idea/.gitignore
@@ -0,0 +1,3 @@
+# Default ignored files
+/shelf/
+/workspace.xml
diff --git a/.idea/.name b/.idea/.name
new file mode 100644
index 0000000..e83db66
--- /dev/null
+++ b/.idea/.name
@@ -0,0 +1 @@
+IrisClient
\ No newline at end of file
diff --git a/.idea/compiler.xml b/.idea/compiler.xml
new file mode 100644
index 0000000..fb7f4a8
--- /dev/null
+++ b/.idea/compiler.xml
@@ -0,0 +1,6 @@
+
+
+
+
+
+
\ No newline at end of file
diff --git a/.idea/dictionaries/student.xml b/.idea/dictionaries/student.xml
new file mode 100644
index 0000000..ecdd4ed
--- /dev/null
+++ b/.idea/dictionaries/student.xml
@@ -0,0 +1,3 @@
+
+
+
\ No newline at end of file
diff --git a/.idea/gradle.xml b/.idea/gradle.xml
new file mode 100644
index 0000000..52f5f62
--- /dev/null
+++ b/.idea/gradle.xml
@@ -0,0 +1,21 @@
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/.idea/inspectionProfiles/Project_Default.xml b/.idea/inspectionProfiles/Project_Default.xml
new file mode 100644
index 0000000..691ca64
--- /dev/null
+++ b/.idea/inspectionProfiles/Project_Default.xml
@@ -0,0 +1,5 @@
+
+
+
+
+
\ No newline at end of file
diff --git a/.idea/misc.xml b/.idea/misc.xml
new file mode 100644
index 0000000..c1f24a5
--- /dev/null
+++ b/.idea/misc.xml
@@ -0,0 +1,54 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/.idea/vcs.xml b/.idea/vcs.xml
new file mode 100644
index 0000000..35eb1dd
--- /dev/null
+++ b/.idea/vcs.xml
@@ -0,0 +1,6 @@
+
+
+
+
+
+
\ No newline at end of file
diff --git a/app/.gitignore b/app/.gitignore
new file mode 100644
index 0000000..42afabf
--- /dev/null
+++ b/app/.gitignore
@@ -0,0 +1 @@
+/build
\ No newline at end of file
diff --git a/app/build.gradle b/app/build.gradle
new file mode 100644
index 0000000..9b6aef0
--- /dev/null
+++ b/app/build.gradle
@@ -0,0 +1,71 @@
+plugins {
+ id 'com.android.application'
+}
+
+android {
+ compileSdk 30
+
+ defaultConfig {
+ applicationId "org.ntlab.irisclient"
+ minSdk 28
+ targetSdk 30
+ versionCode 1
+ versionName "1.0"
+
+ testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"
+ }
+
+ buildTypes {
+ release {
+ minifyEnabled false
+ proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro'
+ }
+ }
+ compileOptions {
+ sourceCompatibility JavaVersion.VERSION_1_8
+ targetCompatibility JavaVersion.VERSION_1_8
+ }
+ buildFeatures {
+ viewBinding true
+ }
+}
+
+dependencies {
+
+ implementation 'androidx.compose.ui:ui-graphics:1.0.0-rc01'
+ androidTestImplementation 'androidx.test.espresso:espresso-core:3.4.0'
+
+
+ // 各 2021/11/23 時点の最新版
+ // Retrofit
+ implementation "com.squareup.retrofit2:retrofit:2.9.0"
+ implementation "com.squareup.retrofit2:converter-moshi:2.9.0"
+
+ implementation 'com.squareup.retrofit2:converter-jackson:2.5.0'
+ implementation 'com.squareup.retrofit2:converter-scalars:2.1.0'
+
+
+ // Moshi
+ implementation "com.squareup.moshi:moshi:1.12.0"
+ implementation "com.squareup.moshi:moshi-kotlin:1.12.0"
+
+ implementation 'androidx.appcompat:appcompat:1.3.1'
+ implementation 'com.google.android.material:material:1.4.0'
+ implementation 'androidx.constraintlayout:constraintlayout:2.1.1'
+ implementation 'androidx.navigation:navigation-fragment:2.3.5'
+ implementation 'androidx.navigation:navigation-ui:2.3.5'
+ implementation 'androidx.lifecycle:lifecycle-livedata-ktx:2.3.1'
+ implementation 'androidx.lifecycle:lifecycle-viewmodel-ktx:2.3.1'
+ implementation 'androidx.annotation:annotation:1.2.0'
+ implementation 'androidx.lifecycle:lifecycle-extensions:2.2.0'
+ implementation 'androidx.swiperefreshlayout:swiperefreshlayout:1.1.0'
+ implementation 'androidx.legacy:legacy-support-v4:1.0.0'
+ testImplementation 'junit:junit:4.+'
+ androidTestImplementation 'androidx.test.ext:junit:1.1.3'
+ androidTestImplementation 'androidx.test.espresso:espresso-core:3.4.0'
+ implementation 'com.github.bumptech.glide:glide:4.10.0'
+ annotationProcessor 'com.github.bumptech.glide:compiler:4.10.0'
+ implementation 'com.google.android.material:material:1.1.0-alpha08'
+ implementation 'androidx.viewpager2:viewpager2:1.0.0-beta02'
+
+}
\ No newline at end of file
diff --git a/app/proguard-rules.pro b/app/proguard-rules.pro
new file mode 100644
index 0000000..481bb43
--- /dev/null
+++ b/app/proguard-rules.pro
@@ -0,0 +1,21 @@
+# Add project specific ProGuard rules here.
+# You can control the set of applied configuration files using the
+# proguardFiles setting in build.gradle.
+#
+# For more details, see
+# http://developer.android.com/guide/developing/tools/proguard.html
+
+# If your project uses WebView with JS, uncomment the following
+# and specify the fully qualified class name to the JavaScript interface
+# class:
+#-keepclassmembers class fqcn.of.javascript.interface.for.webview {
+# public *;
+#}
+
+# Uncomment this to preserve the line number information for
+# debugging stack traces.
+#-keepattributes SourceFile,LineNumberTable
+
+# If you keep the line number information, uncomment this to
+# hide the original source file name.
+#-renamesourcefileattribute SourceFile
\ No newline at end of file
diff --git a/app/src/androidTest/java/org/ntlab/irisclient/ExampleInstrumentedTest.java b/app/src/androidTest/java/org/ntlab/irisclient/ExampleInstrumentedTest.java
new file mode 100644
index 0000000..6d6fbae
--- /dev/null
+++ b/app/src/androidTest/java/org/ntlab/irisclient/ExampleInstrumentedTest.java
@@ -0,0 +1,26 @@
+package org.ntlab.irisclient;
+
+import android.content.Context;
+
+import androidx.test.platform.app.InstrumentationRegistry;
+import androidx.test.ext.junit.runners.AndroidJUnit4;
+
+import org.junit.Test;
+import org.junit.runner.RunWith;
+
+import static org.junit.Assert.*;
+
+/**
+ * Instrumented test, which will execute on an Android device.
+ *
+ * @see Testing documentation
+ */
+@RunWith(AndroidJUnit4.class)
+public class ExampleInstrumentedTest {
+ @Test
+ public void useAppContext() {
+ // Context of the app under test.
+ Context appContext = InstrumentationRegistry.getInstrumentation().getTargetContext();
+ assertEquals("org.ntlab.irisclient", appContext.getPackageName());
+ }
+}
\ No newline at end of file
diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml
new file mode 100644
index 0000000..dc21aea
--- /dev/null
+++ b/app/src/main/AndroidManifest.xml
@@ -0,0 +1,70 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/app/src/main/java/org/ntlab/irisclient/CreateRoomActivity.java b/app/src/main/java/org/ntlab/irisclient/CreateRoomActivity.java
new file mode 100644
index 0000000..4e4ffac
--- /dev/null
+++ b/app/src/main/java/org/ntlab/irisclient/CreateRoomActivity.java
@@ -0,0 +1,103 @@
+package org.ntlab.irisclient;
+
+import androidx.annotation.NonNull;
+import androidx.annotation.Nullable;
+import androidx.appcompat.app.ActionBar;
+import androidx.appcompat.app.AppCompatActivity;
+
+import android.content.DialogInterface;
+import android.content.Intent;
+import android.os.Bundle;
+import android.view.LayoutInflater;
+import android.view.View;
+import android.view.ViewGroup;
+import android.widget.Button;
+import android.widget.ImageButton;
+import android.app.AlertDialog;
+import android.widget.EditText;
+
+import org.ntlab.irisclient.entities.RoomJson;
+import org.ntlab.irisclient.resources.RoomsRest;
+
+import retrofit2.Call;
+import retrofit2.Callback;
+import retrofit2.Response;
+import retrofit2.Retrofit;
+import retrofit2.converter.jackson.JacksonConverterFactory;
+
+public class CreateRoomActivity extends AppCompatActivity {
+
+ @Override
+ protected void onCreate(Bundle savedInstanceState) {
+ super.onCreate(savedInstanceState);
+ setContentView(R.layout.activity_create_room);
+
+ //----------------------------------------------------------------------------------------------------------------------------------
+ //サーバーとの通信の初期化
+ Retrofit retrofit = new Retrofit.Builder()
+ .baseUrl("http://nitta-lab-www.is.konan-u.ac.jp/iris/")
+ .addConverterFactory(JacksonConverterFactory.create())
+ .build();
+ final RoomsRest roomRest = retrofit.create(RoomsRest.class);
+
+
+ //----------------------------------------------------------------------------------------------------------------------------------
+ //アクションバーの非表示
+ ActionBar actionBar = getSupportActionBar();
+ if (actionBar != null) {
+ actionBar.hide();
+ }
+//------------------------------------------------------------------------------------------------------------------------------------------
+ //バックボタンを押した場合、前の画面に遷移
+
+ ImageButton imageButton = (ImageButton) findViewById(R.id.backButton); // view経由でimageButtonを探す
+ imageButton.setOnClickListener(new View.OnClickListener() {
+ public void onClick(View v) {
+ Intent i = new Intent(v.getContext(), MainActivity.class);
+ startActivity(i);
+ }
+ });
+
+//-------------------------------------------------------------------------------------------------------------------------------------------
+
+ //ボタンをクリックすると、部屋を作る次の画面に遷移
+ Button nextButton = findViewById(R.id.CreateRoomButton);
+ nextButton.setOnClickListener(new View.OnClickListener() {
+ public void onClick(View v) {
+ EditText text = (EditText) findViewById(R.id.nicknameEditText);
+ String nickname = text.getText().toString();
+
+ //ニックネームが入力されていない場合エラーメッセージを表示する
+ if (text.getText().toString().isEmpty()) {
+ text.setError("ニックネームを入力されていません");
+
+ //ニックネームが入力されていれば次の画面へ
+ } else {
+ //サーバーとの通信のために呼び出す
+ Call call = roomRest.makeRooms(nickname);
+ call.enqueue(new Callback() {
+ //onResponseで成功
+ public void onResponse(Call call, Response response) {
+ if (response.isSuccessful()) {
+ //ridとnicknameをIrisへ
+ String rid = response.body().getRid();
+ ((Iris) getApplication()).setRid(rid);
+ ((Iris) getApplication()).setNickname(nickname);
+ //次の画面へ遷移
+ Intent intent = new Intent(CreateRoomActivity.this,OwnerRoomActivity.class);
+ intent.putExtra("nickname", nickname);
+ startActivity(intent);
+ }
+ }
+ //onFailureで失敗
+ public void onFailure(Call call, Throwable t) {
+ }
+ });
+
+ }
+ }
+ });
+
+ }
+}
+
diff --git a/app/src/main/java/org/ntlab/irisclient/DrawingActivity.java b/app/src/main/java/org/ntlab/irisclient/DrawingActivity.java
new file mode 100644
index 0000000..5b71427
--- /dev/null
+++ b/app/src/main/java/org/ntlab/irisclient/DrawingActivity.java
@@ -0,0 +1,219 @@
+package org.ntlab.irisclient;
+
+import androidx.appcompat.app.AppCompatActivity;
+import androidx.lifecycle.Observer;
+import androidx.lifecycle.ViewModelProvider;
+
+import android.content.Intent;
+import android.graphics.Bitmap;
+import android.graphics.Color;
+import android.os.Bundle;
+import android.view.View;
+import android.view.WindowManager;
+import android.widget.CompoundButton;
+import android.widget.ImageButton;
+import android.widget.SeekBar;
+import android.widget.TextView;
+import android.widget.ToggleButton;
+
+import org.ntlab.irisclient.models.Member;
+import org.ntlab.irisclient.viewmodels.DrawingStateViewModel;
+
+import java.util.List;
+
+public class DrawingActivity extends AppCompatActivity implements View.OnClickListener {
+
+ private DrawingCanvas drawingCanvas;
+ private DrawingStateViewModel drawingStateViewModel;
+
+ private List keywordList;
+ private Integer drawingNum;
+ private Integer drawingNow = 0;
+ private Integer nowTime;
+ private Integer alphaNow=255; //今のペンの透明度
+ private ToggleButton okToggleButton;
+
+ @Override
+ protected void onCreate(Bundle savedInstanceState) {
+ super.onCreate(savedInstanceState);
+ setContentView(R.layout.activity_drawing);
+
+ //getWindow().addFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN);//ステータスバー非表示
+
+ //Irisから必要な情報を取得
+ Iris iris = (Iris) this.getApplication();
+ Boolean bMaster = iris.isMaster();
+ List memberList = iris.getMemberList();
+
+ drawingStateViewModel= new ViewModelProvider(this).get(DrawingStateViewModel.class);
+
+ findViewById(R.id.clearButton).setOnClickListener(this);//画面クリアボタン
+ findViewById(R.id.blackPenButton).setOnClickListener(this);
+ findViewById(R.id.eraserButton).setOnClickListener(this);
+
+ //完了ボタン
+ okToggleButton = (ToggleButton) findViewById(R.id.toggleButton);
+ okToggleButton.setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener() {
+ public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) {
+ if (isChecked) {
+ okToggleButton.setTextOn("完了");
+ drawingCanvas.setEnabled(true);
+ drawingCanvas.setClickable(true);
+ drawingCanvas.setColor(Color.BLACK);
+
+ } else {
+ okToggleButton.setTextOff("描き直す");
+ drawingCanvas.setEnabled(false);
+ drawingCanvas.setClickable(false);
+ drawingCanvas.setColor(Color.TRANSPARENT);
+
+ //putDrawing
+ drawingCanvas.setDrawingCacheEnabled(true);//キャッシュを取得する設定にする
+ drawingCanvas.buildDrawingCache();
+ Bitmap bitmap = Bitmap.createBitmap(drawingCanvas.getDrawingCache());
+ drawingCanvas.destroyDrawingCache();//既存のキャッシュをクリアする
+ drawingStateViewModel.putDrawing(bitmap);
+ }
+ }
+ });
+
+ TextView textPenSize =(TextView)findViewById(R.id.penSizeText);
+ TextView textAlpha =(TextView)findViewById(R.id.alphaText);
+ textPenSize.setText("サイズ: 10%");
+ textAlpha.setText("透明度: 255%");
+
+ //筆の大きさを変えるシークバー
+ SeekBar seekbar = findViewById(R.id.seekBar);
+ seekbar.setOnSeekBarChangeListener(new SeekBar.OnSeekBarChangeListener() {
+ @Override
+ public void onProgressChanged(SeekBar seekBar, int i, boolean b) {//変更中
+ drawingCanvas.setPenWidth(i);
+ textPenSize.setText("サイズ: "+ i + "%");
+ }
+
+ @Override
+ public void onStartTrackingTouch(SeekBar seekBar) {//変更開始時
+ }
+
+ @Override
+ public void onStopTrackingTouch(SeekBar seekBar) {//変更終了時
+ }
+ });
+
+ //筆の透明度を変えるシークバー
+ SeekBar seekbar2 = findViewById(R.id.seekBar2);
+ seekbar2.setOnSeekBarChangeListener(new SeekBar.OnSeekBarChangeListener() {
+ @Override
+ public void onProgressChanged(SeekBar seekBar, int i, boolean b) {//変更中
+ drawingCanvas.setAlpha(i);
+ textAlpha.setText("透明度: "+ i + "%");
+ alphaNow = i;
+ }
+
+ @Override
+ public void onStartTrackingTouch(SeekBar seekBar) {//変更開始時
+ }
+
+ @Override
+ public void onStopTrackingTouch(SeekBar seekBar) {//変更終了時
+ }
+ });
+
+
+ TextView textKeyword =(TextView)findViewById(R.id.keywordText);//keywordのTextView
+ TextView textMemberNum = (TextView)findViewById(R.id.drawingNowText);//残りのイラスト枚数のTextView
+ TextView timerText = (TextView)findViewById(R.id.timerText);//TimerのTextView
+
+
+ drawingCanvas = (DrawingCanvas) findViewById(R.id.drawingCanvas);
+
+ //残りのイラスト枚数の表示
+ //drawingNum = 16 / 2; // 一人あたりが描く枚数(テスト部屋用,部屋作成からスタートする場合はこの行をコメントアウトして ↓ ふたつのコメントを解除)
+ drawingNum = 16 / memberList.size(); // 一人あたりが描く枚数
+ if (16 % memberList.size() != 0) drawingNum++; // 余りが出た場合プラス1枚
+
+ //getKeywords
+ drawingStateViewModel.getKeywords().observe(this, new Observer>(){
+ @Override
+ public void onChanged(List keywords) {
+ keywordList = keywords;
+ }
+ });
+
+ //getDno
+ drawingStateViewModel.getDno().observe(this, new Observer() {
+ @Override
+ public void onChanged(Integer dno) {
+ String keyword = keywordList.get(dno);
+ textKeyword.setText(keyword);
+ drawingNow++;
+ textMemberNum.setText(""+drawingNow+"/"+drawingNum);
+ drawingCanvas.clearCanvas();
+
+ okToggleButton.setChecked(true);
+ }
+ });
+
+ //getState
+ drawingStateViewModel.getState().observe(this, new Observer() {
+ @Override
+ public void onChanged(Integer state) {
+ Class nextActivity = GameMemberActivity.class;
+ if(bMaster) nextActivity = GameMasterActivity.class;//自分がMasterならMaster用のGame画面へ遷移
+
+ //stateが変わったらゲーム画面へ遷移
+ if(state == 3) {
+ Intent intent = new Intent(DrawingActivity.this, nextActivity);
+ startActivity(intent);
+ }
+ }
+ });
+
+ //getTimer
+ drawingStateViewModel.getTimer().observe(this, new Observer(){
+ @Override
+ public void onChanged(Integer time) {
+ nowTime = time;
+ timerText.setText(nowTime+"");
+ if(nowTime == 0){//タイマーが0秒になったら強制put
+ //putDrawing
+ drawingCanvas.setDrawingCacheEnabled(true);//キャッシュを取得する設定にする
+ drawingCanvas.buildDrawingCache();
+ Bitmap bitmap = Bitmap.createBitmap(drawingCanvas.getDrawingCache());
+ drawingCanvas.destroyDrawingCache();//既存のキャッシュをクリアする
+ drawingStateViewModel.putDrawing(bitmap);
+ }
+ }
+ });
+
+ //タイマースタート呼び出し
+ drawingStateViewModel.start(500,(Iris)getApplication());
+ }
+
+ @Override
+ public void onClick(View v){
+ if(okToggleButton.isChecked()) {//完了ボタンが押されていないときだけボタンが使える
+ if (v.getId() == R.id.clearButton) {//clearButtonが押されたときの処理
+ drawingCanvas.clearCanvas();
+ } else if (v.getId() == R.id.eraserButton) {//eraserButtonが押されたときの処理
+ drawingCanvas.setColor(Color.WHITE);
+ v.setBackgroundColor(Color.rgb(173,216,230));
+ findViewById(R.id.blackPenButton).setBackgroundColor(Color.rgb(211,211,211));
+ findViewById(R.id.blackPenButton).setScaleX(0.9f);
+ findViewById(R.id.blackPenButton).setScaleY(0.9f);
+ findViewById(R.id.eraserButton).setScaleX(1.0f);
+ findViewById(R.id.eraserButton).setScaleY(1.0f);
+ } else if (v.getId() == R.id.blackPenButton) {
+ drawingCanvas.setColor(Color.BLACK);
+ drawingCanvas.setAlpha(alphaNow);
+ v.setBackgroundColor(Color.rgb(173,216,230));
+ findViewById(R.id.eraserButton).setBackgroundColor(Color.rgb(211,211,211));
+ findViewById(R.id.eraserButton).setScaleX(0.9f);
+ findViewById(R.id.eraserButton).setScaleY(0.9f);
+ findViewById(R.id.blackPenButton).setScaleX(1.0f);
+ findViewById(R.id.blackPenButton).setScaleY(1.0f);
+ }
+ }
+ }
+
+}
\ No newline at end of file
diff --git a/app/src/main/java/org/ntlab/irisclient/DrawingCanvas.java b/app/src/main/java/org/ntlab/irisclient/DrawingCanvas.java
new file mode 100644
index 0000000..38b6aa1
--- /dev/null
+++ b/app/src/main/java/org/ntlab/irisclient/DrawingCanvas.java
@@ -0,0 +1,122 @@
+package org.ntlab.irisclient;
+
+import static android.graphics.Color.BLACK;
+import static android.graphics.Color.WHITE;
+
+import android.content.Context;
+import android.graphics.Bitmap;
+import android.graphics.Canvas;
+import android.graphics.Color;
+import android.graphics.Paint;
+import android.graphics.Path;
+import android.graphics.PorterDuff;
+import android.graphics.PorterDuffXfermode;
+import android.util.AttributeSet;
+import android.view.MotionEvent;
+import android.view.View;
+
+import androidx.annotation.Nullable;
+
+import java.util.ArrayList;
+
+public class DrawingCanvas extends View {
+
+ private Canvas canvas;
+ private Bitmap bitmap;
+
+ private Path path;
+ private Paint paint;
+
+ private int curw;
+ private int curh;
+ private int curoldw;
+ private int curoldh;
+
+ public DrawingCanvas(Context context, @Nullable AttributeSet attrs) {
+ super(context, attrs);
+
+ //1)コンストラクタ(≒必需品)
+ path = new Path();//線を引いたり、図形を描いたり、要するにグラフィック
+ paint = new Paint();//筆の種類
+ paint.setColor(Color.BLACK);//色の指定
+ paint.setStyle(Paint.Style.STROKE);//線をひく
+ paint.setStrokeWidth(20);//幅
+ }
+
+ //2)onDraw(描画の準備/プロペラが回りだした状態)
+ @Override
+ protected void onDraw(Canvas canvas) {
+ super.onDraw(canvas);
+ canvas.drawBitmap(bitmap, 0, 0, null);
+ canvas.drawPath(path,paint);
+ }
+ @Override
+ protected void onSizeChanged(
+ int w, int h,
+ int oldw, int oldh) {
+ super.onSizeChanged(w, h, oldw, oldh);
+ curw = w;
+ curh = h;
+ curoldw = oldw;
+ curoldh = oldh;
+ bitmap = Bitmap.createBitmap(
+ w, h, Bitmap.Config.ARGB_8888);
+ canvas = new Canvas(bitmap);
+ }
+
+ //3)実際の操縦 (条件分岐:押したとき、動かしたとき、放した時)
+ @Override
+ public boolean onTouchEvent(MotionEvent event) {
+ //(3-1)座標を取得(x座標、y座標)
+ float x = event.getX();
+ float y = event.getY();
+
+ //(3-2)タッチの処理
+ switch (event.getAction()){
+ case MotionEvent.ACTION_DOWN://タッチした瞬間
+ path.reset();
+ path.moveTo(x,y);
+ invalidate();
+ break;
+ case MotionEvent.ACTION_MOVE://動かしている間
+ path.lineTo(x,y);
+ invalidate();
+ break;
+ case MotionEvent.ACTION_UP://手を離す
+ path.lineTo(x, y);
+ canvas.drawPath(path, paint);
+ path.reset();
+ invalidate();
+ break;
+ }
+
+ //return super.onTouchEvent(event);
+ return true;
+ }
+
+
+ //4)クリア処理
+ public void clearCanvas(){
+ onSizeChanged(curw, curh, curoldw, curoldh);
+ path.reset();
+ invalidate();
+ }
+
+ //筆の色を変更
+ public void setColor(int color){
+ paint.setColor(color);
+ }
+
+ //筆の透明度を変更
+ public void setAlpha(int alpha){
+ if(paint.getColor()!=WHITE){
+ paint.setAlpha(alpha);
+ }
+ }
+
+ //筆の幅を変更
+ public void setPenWidth(int size){
+ paint.setStrokeWidth(size);
+ }
+
+}
diff --git a/app/src/main/java/org/ntlab/irisclient/DrawingCardFragment.java b/app/src/main/java/org/ntlab/irisclient/DrawingCardFragment.java
new file mode 100644
index 0000000..4f7c4d7
--- /dev/null
+++ b/app/src/main/java/org/ntlab/irisclient/DrawingCardFragment.java
@@ -0,0 +1,710 @@
+package org.ntlab.irisclient;
+import static android.os.Looper.getMainLooper;
+import static android.view.View.INVISIBLE;
+
+import android.app.AlertDialog;
+import android.app.Dialog;
+import android.content.Context;
+import android.content.Intent;
+import android.content.res.ColorStateList;
+import android.content.res.Resources;
+import android.graphics.Bitmap;
+import android.graphics.BitmapFactory;
+import android.graphics.drawable.Drawable;
+import android.os.Bundle;
+import android.util.DisplayMetrics;
+import android.view.LayoutInflater;
+import android.view.View;
+import android.view.ViewGroup;
+import android.view.animation.Animation;
+import android.view.animation.AnimationSet;
+import android.view.animation.RotateAnimation;
+import android.view.animation.ScaleAnimation;
+import android.widget.ImageButton;
+import android.widget.ImageView;
+import android.widget.LinearLayout;
+
+import androidx.core.os.HandlerCompat;
+import androidx.fragment.app.Fragment;
+import androidx.lifecycle.ViewModelProvider;
+
+import org.ntlab.irisclient.models.Drawing;
+import org.ntlab.irisclient.resources.GameRest;
+import org.ntlab.irisclient.viewmodels.GameViewModel;
+
+import java.io.IOException;
+import java.io.InputStream;
+import java.net.HttpURLConnection;
+import java.net.URL;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+import java.util.concurrent.Executors;
+
+
+public class DrawingCardFragment extends Fragment {
+
+ private ImageButton[] imageButtons;
+ private ImageView[] backColors;
+ private Resources resources;
+ private GameViewModel gameViewModel;
+ private Boolean isMaster;
+ private String myTeam;
+ private String nowTurn;
+ private String rid;
+ private Integer turnState = 1; // 0がヒント入力中
+ private Integer OpenRedCard = 0;
+ private Integer OpenBlueCard = 0;
+ // ロングタップで表示させるために必要。非同期で値が格納され、順番通りに保存されないからHashMapにしている
+ private Map bmImages = new HashMap<>();
+
+ // 下はテストが動くようになったら削除する
+ private Map drawingList; //
+ private List map; //cno順にdnoを管理(要するに絵の並び)
+ private List colorList; //cno順にr,g,b,dを管理:カードごとの色
+ private List nowOpenList;
+ private List nowQList;
+
+
+ // コンストラクタ
+ public static DrawingCardFragment newInstance(String str){
+ // インスタンス生成
+ DrawingCardFragment fragment = new DrawingCardFragment();
+ return fragment;
+ }
+
+ @Override
+ public View onCreateView(LayoutInflater inflater, ViewGroup container,
+ Bundle savedInstanceState) {
+ super.onCreateView(inflater, container, savedInstanceState);
+
+ Iris iris = (Iris) this.getActivity().getApplication();
+ rid = iris.getRid();
+ gameViewModel = new ViewModelProvider(this).get(GameViewModel.class);
+ gameViewModel.start(500, iris);
+ gameViewModel.setRid(rid);
+ System.out.println(gameViewModel.getImageLiveData());
+
+ resources = getResources();
+ View view = inflater.inflate(R.layout.fragment_card_drawing, container, false);
+ // 現在のopenListを記録
+ nowOpenList = new ArrayList(){
+ {
+ add(false);
+ add(false);
+ add(false);
+ add(false);
+ add(false);
+ add(false);
+ add(false);
+ add(false);
+ add(false);
+ add(false);
+ add(false);
+ add(false);
+ add(false);
+ add(false);
+ add(false);
+ add(false);
+ }
+ };
+
+ // 現在のQListを記録
+ nowQList = new ArrayList(){
+ {
+ add(false);
+ add(false);
+ add(false);
+ add(false);
+ add(false);
+ add(false);
+ add(false);
+ add(false);
+ add(false);
+ add(false);
+ add(false);
+ add(false);
+ add(false);
+ add(false);
+ add(false);
+ add(false);
+ }
+ };
+
+ // ImageButton16個の型を使いまわしやすいように配列で使用
+ imageButtons = new ImageButton[] {
+ (ImageButton) view.findViewById(R.id.imageButton0),
+ (ImageButton) view.findViewById(R.id.imageButton1),
+ (ImageButton) view.findViewById(R.id.imageButton2),
+ (ImageButton) view.findViewById(R.id.imageButton3),
+ (ImageButton) view.findViewById(R.id.imageButton4),
+ (ImageButton) view.findViewById(R.id.imageButton5),
+ (ImageButton) view.findViewById(R.id.imageButton6),
+ (ImageButton) view.findViewById(R.id.imageButton7),
+ (ImageButton) view.findViewById(R.id.imageButton8),
+ (ImageButton) view.findViewById(R.id.imageButton9),
+ (ImageButton) view.findViewById(R.id.imageButton10),
+ (ImageButton) view.findViewById(R.id.imageButton11),
+ (ImageButton) view.findViewById(R.id.imageButton12),
+ (ImageButton) view.findViewById(R.id.imageButton13),
+ (ImageButton) view.findViewById(R.id.imageButton14),
+ (ImageButton) view.findViewById(R.id.imageButton15)
+ };
+
+ backColors = new ImageView[]{
+ (ImageView) view.findViewById(R.id.backColour0),
+ (ImageView) view.findViewById(R.id.backColour1),
+ (ImageView) view.findViewById(R.id.backColour2),
+ (ImageView) view.findViewById(R.id.backColour3),
+ (ImageView) view.findViewById(R.id.backColour4),
+ (ImageView) view.findViewById(R.id.backColour5),
+ (ImageView) view.findViewById(R.id.backColour6),
+ (ImageView) view.findViewById(R.id.backColour7),
+ (ImageView) view.findViewById(R.id.backColour8),
+ (ImageView) view.findViewById(R.id.backColour9),
+ (ImageView) view.findViewById(R.id.backColour10),
+ (ImageView) view.findViewById(R.id.backColour11),
+ (ImageView) view.findViewById(R.id.backColour12),
+ (ImageView) view.findViewById(R.id.backColour13),
+ (ImageView) view.findViewById(R.id.backColour14),
+ (ImageView) view.findViewById(R.id.backColour15)
+ };
+
+ gameViewModel.getImageLiveData().observe(
+ getViewLifecycleOwner(),
+ gameJsonObserver -> {
+ System.out.println("kota: getImageLiveDataが取得:" + gameJsonObserver);
+ System.out.println("kota: getImageLiveDataが取得:" + gameJsonObserver.getDrawingList());
+ System.out.println("kota: getImageLiveDataが取得:" + gameJsonObserver.getColorList());
+ System.out.println("kota: getImageLiveDataが取得:" + gameJsonObserver.getMap());
+ setupWithViewModel();
+ }
+ );
+
+ // Openされた画像ををObserveして、Viewに反映
+ gameViewModel.getOpenLiveData().observe (
+ getViewLifecycleOwner(),
+ openListObserver -> {
+ System.out.println("kota: オープンされた。オープンの配列:" + openListObserver);
+ setOpen(openListObserver);
+ }
+ );
+
+ // 疑われた画像ををObserveして、Viewに反映
+ gameViewModel.getQLiveData().observe (
+ getViewLifecycleOwner(),
+ QObserver -> {
+ System.out.println("kota: 疑われた。 疑われた配列: " + QObserver);
+ setQ(QObserver);
+ }
+ );
+
+
+ gameViewModel.getEndStateLiveData().observe (
+ getViewLifecycleOwner(),
+ endStateObserver -> {
+ System.out.println("kota:getEndState" + endStateObserver);
+ if(endStateObserver == 0) {
+
+ System.out.println("kota: 黒めくってゲームが終了!!:" + endStateObserver);
+ finishGameAlertMake(myTeam, nowTurn);
+ } else {
+ finishFullOpenGameAlertMake(myTeam, nowTurn);
+ }
+ }
+ );
+
+ gameViewModel.getTurnsLiveData().observe (
+ getViewLifecycleOwner(),
+ turnsObserver -> {
+ System.out.println("kota: ターンが変更。今のターン:" + turnsObserver);
+ nowTurn = turnsObserver;
+ }
+ );
+
+ gameViewModel.getTurnStateLiveData().observe (
+ getViewLifecycleOwner(),
+ turnStateObserver -> {
+ System.out.println("kota: turnStateが変更。0ならヒント入力中。1ならめくれるよ。:" + turnStateObserver);
+ turnState = turnStateObserver;
+ }
+ );
+
+ System.out.println("コンストラクタでのログ確認");
+ System.out.println("kota: isMasterかどうか:" + isMaster);
+ System.out.println("kota: getrid:" + iris.getRid());
+ System.out.println("kota: getteame:" + iris.getTeam());
+ System.out.println("kota: nowTurn:" + nowTurn);
+ System.out.println("kota: getMemberList:" + iris.getMemberList());
+ System.out.println("kota: getNickName:" + iris.getNickname());
+ System.out.println("kota: getImageLiveData:" + gameViewModel.getImageLiveData().getValue());
+
+ return view;
+ }
+
+ public void onClick(View v) {
+ for(int i=0; i< imageButtons.length; i++) {
+ if(v.getId() == imageButtons[i].getId()) {
+ System.out.println( "kota: タップされたボタンの配列番号:" + i);
+ System.out.println( "kota: nowTurn:" + nowTurn);
+ System.out.println( "kota: myTeam:" + myTeam);
+ System.out.println( "kota: isMaster:" + isMaster);
+ System.out.println( "kota: turnState:" + turnState);
+
+ // カードめくれなくする処理
+ if(nowTurn.equals(myTeam) && isMaster == false && turnState == 1) {
+ System.out.println( "kota: めくれる処理が呼ばれた:");
+ confirmAlertMake(i);
+ }
+ }
+ }
+ }
+
+ public boolean onLongTap(View v) {
+
+ for(int i=0; i< imageButtons.length; i++) {
+
+ if(v.getId() == imageButtons[i].getId()) {
+ System.out.println( "kota: ロングタップされたボタンの配列番号:" + i);
+ // 自分のターンのとき、疑い機能のあるアラート表示
+ // 相手のターンのとき、画像だけ確認できるアラート表示
+ if(nowTurn.equals(myTeam)) {
+ doubtAlertMake(i);
+ } else {
+ lookImageAlertMake(i);
+ }
+ }
+
+ // めくられた画像を長押でも確認できるようにする
+ if(v.getId() == backColors[i].getId()) {
+ System.out.println( "kota: タップされたボタンの配列番号:" + i);
+ lookImageAlertMake(i);
+ }
+ }
+
+
+ return false;
+ }
+
+ private void setupWithViewModel() {
+ System.out.println("kota: setupWithViewModel呼ばれた");
+ Iris iris = (Iris) this.getActivity().getApplication();
+ myTeam = iris.getTeam();
+ rid = iris.getRid();
+ isMaster = iris.isMaster();
+ System.out.println("kota: isMasterですかどうか:" + isMaster);
+ System.out.println(iris.getRid());
+ System.out.println(iris.getTeam());
+ System.out.println(iris.getMemberList());
+ System.out.println(iris.getNickname());
+
+ drawingList = gameViewModel.getGame().getDrawingList();
+ map = gameViewModel.getGame().getMap();
+ colorList = gameViewModel.getGame().getColorList();
+
+ Context context = getContext();
+
+ for (Integer i: map) {
+
+ // タップとロングタップのセット
+ imageButtons[i].setOnClickListener(this::onClick);
+ imageButtons[i].setOnLongClickListener(this::onLongTap);
+ backColors[i].setOnLongClickListener(this::onLongTap);
+
+ // 画像のセット
+ String urlSt = drawingList.get(map.get(i)).getDrawing();
+ System.out.println(i+urlSt);
+ setImage(i, urlSt, context);
+
+ // 初回だけセットする外枠の、メンバーとマスターで表示分け
+ // メンバー:全て肌色、マスター:赤・青・黒・グレーの表示
+ if(isMaster == true) {
+ if (colorList.get(i).contains("r")) {
+ backColors[i].setBackground(resources.getDrawable(R.drawable.red_image));
+ } else if (colorList.get(i).contains("b")) {
+ backColors[i].setBackground(resources.getDrawable(R.drawable.blue_image));
+ } else if (colorList.get(i).contains("g")) {
+ backColors[i].setBackground(resources.getDrawable(R.drawable.gray_image));
+ } else if (colorList.get(i).contains("d")) {
+ backColors[i].setBackground(resources.getDrawable(R.drawable.black_image));
+ }
+ } else {
+ backColors[i].setBackground(resources.getDrawable(R.drawable.skin_image));
+ }
+
+ }
+
+ }
+
+ /**
+ * URLから画像を取得
+ * Androidのルール的にメインスレッドで書くとクラッシュする
+ * 非同期で書かなければならない
+ **/
+ private void setImage(int cno, String urlSt, Context context) {
+
+ System.out.println("kota: setImage呼ばれた");
+
+ // Singleの別スレッドを立ち上げる
+ Executors.newSingleThreadExecutor().execute(() -> {
+ try {
+ // TODO: Drawingのsetが使われるまで、無理やり指定。
+ URL url = new URL(urlSt);
+ System.out.println("kota: 表示させるURL文字列 " + url);
+ // String urlString = "http://nitta-lab-www.is.konan-u.ac.jp/irisdata/image/" + rid + "-" + cno + ".png";
+ //URL url = new URL(urlString);
+ HttpURLConnection urlCon = (HttpURLConnection) url.openConnection();
+
+ // タイムアウト設定
+ urlCon.setReadTimeout(10000);
+ urlCon.setConnectTimeout(20000);
+
+ // リクエストメソッド
+ urlCon.setRequestMethod("GET");
+
+ // リダイレクトを自動で許可しない設定
+ urlCon.setInstanceFollowRedirects(false);
+
+ InputStream is = urlCon.getInputStream();
+ Bitmap originalBMP = BitmapFactory.decodeStream(is);
+ Bitmap resizedMiniBMP = resize(originalBMP, (int) convertDp2Px(105, context),(int) convertDp2Px(60, context));
+ Bitmap resizedBigBMP = resize(originalBMP, (int) convertDp2Px(420, context),(int) convertDp2Px(240, context));
+ bmImages.put(cno, resizedBigBMP);
+
+ HandlerCompat.createAsync(getMainLooper()).post(() ->
+ // Mainスレッドに返す
+ imageButtons[cno].setImageBitmap(resizedMiniBMP)
+ );
+
+ } catch (IOException e) {
+ e.printStackTrace();
+ }
+ });
+ }
+
+ /**
+ * dpとpxを変換
+ * BitMapでImageを描画するためにどうしても必要だった
+ **/
+ private static float convertDp2Px(float dp, Context context) {
+ DisplayMetrics metrics = context.getResources().getDisplayMetrics();
+ return dp * metrics.density;
+ }
+
+ /**
+ * 表示させる画像のサイズ調整
+ **/
+ private static Bitmap resize(Bitmap image, int maxWidth, int maxHeight) {
+ if (maxHeight > 0 && maxWidth > 0) {
+
+ int width = image.getWidth();
+ int height = image.getHeight();
+ float ratioBitmap = (float) width / (float) height;
+ float ratioMax = (float) maxWidth / (float) maxHeight;
+
+ int finalWidth = maxWidth;
+ int finalHeight = maxHeight;
+ if (ratioMax > 1) {
+ finalWidth = (int) ((float)maxHeight * ratioBitmap);
+ } else {
+ finalHeight = (int) ((float)maxWidth / ratioBitmap);
+ }
+ image = Bitmap.createScaledBitmap(image, finalWidth, finalHeight, true);
+ return image;
+ } else {
+ return image;
+ }
+ }
+
+ /**
+ * 開けられたImageをViewに反映させる
+ * Observeして変更加わった度に呼ばれる
+ **/
+ private void setOpen(List openList) {
+ OpenRedCard = 0;
+ OpenBlueCard = 0;
+
+ for(int i=0; i< openList.size(); i++) {
+ if (openList.get(i) == true && nowOpenList.get(i) == false) {
+ // オープンだったときの描画
+ if (colorList.get(i).contains("r")) {
+ backColors[i].setBackground(resources.getDrawable(R.drawable.red_image));
+ imageButtons[i].setVisibility(INVISIBLE);
+ OpenRedCard += 1;
+// if( !colorList.get(i).equals(myTeam) ){
+// gameViewModel.addTurns();
+// }
+ } else if (colorList.get(i).contains("b")) {
+ backColors[i].setBackground(resources.getDrawable(R.drawable.blue_image));
+ imageButtons[i].setVisibility(INVISIBLE);
+ OpenBlueCard += 1;
+// if( !colorList.get(i).equals(myTeam) ){
+// gameViewModel.addTurns();
+// }
+ } else if (colorList.get(i).contains("g")) {
+ backColors[i].setBackground(resources.getDrawable(R.drawable.gray_image));
+ imageButtons[i].setVisibility(INVISIBLE);
+// gameViewModel.addTurns();
+ } else if (colorList.get(i).contains("d")) {
+ backColors[i].setBackground(resources.getDrawable(R.drawable.black_image));
+ imageButtons[i].setVisibility(INVISIBLE);
+ gameViewModel.sendEndState();
+ finishGameAlertMake(myTeam, nowTurn);
+ }
+ setAnime(i);
+ nowOpenList.set(i, true);
+ } else if( openList.get(i) == true && colorList.get(i).contains("r") ){
+ OpenRedCard += 1;
+ } else if( openList.get(i) == true && colorList.get(i).contains("b") ){
+ OpenBlueCard += 1;
+ }
+ }
+
+ if( OpenRedCard == 6 ){
+ gameViewModel.sendEndState();
+ finishFullOpenGameAlertMake(myTeam, "r");
+ }else if( OpenBlueCard == 5 ){
+ gameViewModel.sendEndState();
+ finishFullOpenGameAlertMake(myTeam, "b");
+ }
+
+ }
+
+ //-----------------------------------------------------------------------------
+ // アラート関係の関数
+ /**
+ * 本当に裏返してよいか確認させるアラート
+ */
+ private void confirmAlertMake(int cno){
+ String strTitle = "注意";
+ String strMessage = "本当にカードをめくってよろしいですか?";
+
+ AlertDialog.Builder builder;
+ builder = new AlertDialog.Builder(getContext());
+ builder.setMessage(strMessage);
+ builder.setTitle(strTitle);
+ builder.setPositiveButton("ok", (dialog, id) -> setOpenRealTime(cno, true));
+ builder.setNegativeButton("キャンセル", (dialog, id) -> setOpenRealTime(cno, false));
+ builder.create();
+ builder.show();
+ }
+
+ /**
+ * アラートから呼ばれる、裏返す通信処理
+ **/
+ private void setOpenRealTime(int cno, boolean isOK) {
+ if(isOK == true) {
+
+ nowQList.set(cno, false);//疑い関係
+ gameViewModel.sendOpenList(cno);
+
+ if( colorList.get(cno).contains("d") ){
+ //Game終了
+ gameViewModel.sendEndState();
+ } else if ( !colorList.get(cno).contains(myTeam)){
+ gameViewModel.addTurns();
+ }
+
+ //赤のカードが何枚めくれているか(6枚めくれていたら勝利)
+ if( colorList.get(cno).equals("r") ){
+ OpenRedCard = 0;
+ nowOpenList.set(cno, true);
+ for( int i = 0; i < 16; i++ ){
+ if( colorList.get(i).equals("r") && nowOpenList.get(i).equals(true) ){
+ OpenRedCard += 1;
+ }
+ }
+ nowOpenList.set(cno, false);
+ if( OpenRedCard == 6 ){
+ gameViewModel.sendEndState();
+ finishFullOpenGameAlertMake(myTeam, "r");
+ }
+ }
+ //青のカードが何枚めくれているか(5枚めくれていたら勝利)
+ if( colorList.get(cno).equals("b") ){
+ OpenBlueCard = 0;
+ nowOpenList.set(cno, true);
+ for( int i = 0; i < 16; i++ ){
+ if( colorList.get(i).equals("b") && nowOpenList.get(i).equals(true) ){
+ OpenBlueCard += 1;
+ }
+ }
+
+ nowOpenList.set(cno, false);
+ if( OpenBlueCard == 5 ){
+ gameViewModel.sendEndState();
+ finishFullOpenGameAlertMake(myTeam, "b");
+ }
+ }
+
+ }
+ }
+
+ /**
+ * 自分のターンのときに、
+ * 疑うか疑わないかのアラートを表示させるコード
+ */
+ private void doubtAlertMake(int cno){
+ String strTitle = "疑いますか?";
+
+ AlertDialog.Builder builder;
+ builder = new AlertDialog.Builder(getContext());
+ builder.setTitle(strTitle);
+
+ ImageView iv = new ImageView(getContext());
+ iv.setImageBitmap(bmImages.get(cno));
+
+ iv.setAdjustViewBounds(true);
+ builder.setView(iv);
+
+ builder.setNegativeButton("疑わない", (dialog, id) -> setDoubt(cno, false));
+ builder.setPositiveButton("疑う", (dialog, id) -> setDoubt(cno, true));
+ builder.setNeutralButton("閉じる", (dialog, id) -> setNone(cno, true));
+ builder.create();
+ builder.show();
+ }
+
+ /**
+ * アラートから呼ばれる、疑いをかける処理
+ **/
+ private void setDoubt(int cno, boolean isOK) {
+ // 疑う処理
+ if( nowQList.get(cno) == false && isOK == true ){
+ gameViewModel.sendQ(cno);
+ } else if( nowQList.get(cno) == true && isOK == false ){
+ gameViewModel.sendQ(cno);
+ }
+ }
+
+ //疑われたら枠の色をチームの色に変更(諜報員のみ)
+ private void setQ(List QList) {
+ for(int i = 0; i < QList.size(); i++) {
+ if ( QList.get(i) == true && nowQList.get(i) == false && isMaster.equals(false) ) {
+ if( nowTurn.equals("r") ){
+ backColors[i].setBackground(resources.getDrawable(R.drawable.red_image));
+ } else {
+ backColors[i].setBackground(resources.getDrawable(R.drawable.blue_image));
+ }
+ nowQList.set(i, true);
+ } else if ( QList.get(i) == false && nowQList.get(i) == true && isMaster.equals(false)){
+ backColors[i].setBackground(resources.getDrawable(R.drawable.skin_image));
+ nowQList.set(i, false);
+ }
+ }
+ }
+
+
+ /**
+ * 相手のターンのときに、
+ * 画像だけ確認できるアラートを表示させるコード
+ */
+ private void lookImageAlertMake(int cno){
+ String strTitle = "";
+
+ AlertDialog.Builder builder;
+ builder = new AlertDialog.Builder(getContext());
+ builder.setTitle(strTitle);
+
+ ImageView iv = new ImageView(getContext());
+ iv.setImageBitmap(bmImages.get(cno));
+ iv.setAdjustViewBounds(true);
+
+ builder.setView(iv);
+
+ builder.setPositiveButton("完了", (dialog, id) -> setNone(cno, true));
+ builder.create();
+ builder.show();
+ }
+
+ /**
+ * アラートからOKを呼ばれたときにする処理
+ * まだ空
+ **/
+ private void setNone(int cno, boolean isOK) {
+ }
+
+ private void setAnime(int cno){
+ ScaleAnimation scaleAnimation = new ScaleAnimation(1.0f, 0.0f, 1.0f, 0.0f,
+ Animation.RELATIVE_TO_SELF, 0.5f, Animation.RELATIVE_TO_SELF, 0.5f);
+ // animation時間 msec
+ scaleAnimation.setDuration(2000);
+
+ RotateAnimation rotate = new RotateAnimation(0.0f, 120.0f,
+ Animation.RELATIVE_TO_PARENT, 0.0f, Animation.RELATIVE_TO_PARENT, 0.5f);
+ // animation時間 msec
+ rotate.setDuration(2000);
+
+ AnimationSet animationSet = new AnimationSet( true );
+
+ // animationSetにそれぞれ追加する
+ animationSet.addAnimation( scaleAnimation );
+ animationSet.addAnimation( rotate );
+
+ imageButtons[cno].startAnimation(animationSet);
+ }
+
+ /**
+ * 黒いカードがひかれて、ゲームが終わったときに呼ばれるアラート
+ */
+ private void finishGameAlertMake(String myTeam, String nowTurn) {
+ String strTitle;
+ String strMessage;
+ System.out.println("ゲームが終わった時のmyTeam:" + myTeam);
+ System.out.println("ゲームが終わった時のmyTurn:" + nowTurn);
+
+ if (myTeam.equals(nowTurn)) {
+ strTitle = "Your Lose...";
+ strMessage = "お疲れ様でした。\n残念ながら、あなたチームは負けました...";
+ } else {
+ strTitle = "Your Win!!";
+ strMessage = "お疲れ様でした。\nおめでとうございます、あなたチームの勝利です!";
+ }
+
+ AlertDialog.Builder builder;
+ builder = new AlertDialog.Builder(getContext());
+ builder.setTitle(strTitle);
+ builder.setMessage(strMessage);
+ builder.setPositiveButton("完了", (dialog, id) -> setFinish());
+ builder.create();
+ builder.show();
+ }
+
+ /**
+ * 赤顔のカードがすべてひかれて、ゲームが終わったときに呼ばれるアラート
+ */
+ private void finishFullOpenGameAlertMake(String myTeam, String nowTurn) {
+ String strTitle;
+ String strMessage;
+ System.out.println("ゲームが終わった時のmyTeam:" + myTeam);
+ System.out.println("ゲームが終わった時のmyTurn:" + nowTurn);
+
+ if ( !myTeam.equals(nowTurn)) {
+ strTitle = "Your Lose...";
+ strMessage = "お疲れ様でした。\n残念ながら、あなたチームは負けました...";
+ } else {
+ strTitle = "Your Win!!";
+ strMessage = "お疲れ様でした。\nおめでとうございます、あなたチームの勝利です!";
+ }
+
+ AlertDialog.Builder builder;
+ builder = new AlertDialog.Builder(getContext());
+ builder.setTitle(strTitle);
+ builder.setMessage(strMessage);
+ builder.setPositiveButton("完了", (dialog, id) -> setFinish());
+ builder.create();
+ builder.show();
+ }
+
+ // TODO: 未完成の関数
+ /**
+ * ゲームが終了したときに呼ばれる関数
+ * 画面をトップに戻る動作でも書く?
+ **/
+ private void setFinish() {
+ Intent intent = new Intent(this.getActivity().getApplication(), MainActivity.class);
+ startActivity(intent);
+ }
+
+}
\ No newline at end of file
diff --git a/app/src/main/java/org/ntlab/irisclient/EnterRoomActivity.java b/app/src/main/java/org/ntlab/irisclient/EnterRoomActivity.java
new file mode 100644
index 0000000..5d62adb
--- /dev/null
+++ b/app/src/main/java/org/ntlab/irisclient/EnterRoomActivity.java
@@ -0,0 +1,96 @@
+package org.ntlab.irisclient;
+
+import androidx.appcompat.app.ActionBar;
+import androidx.appcompat.app.AppCompatActivity;
+import retrofit2.Call;
+import retrofit2.Callback;
+import retrofit2.Response;
+import retrofit2.Retrofit;
+import retrofit2.converter.jackson.JacksonConverterFactory;
+
+import android.content.Intent;
+import android.os.Bundle;
+import android.view.View;
+import android.widget.Button;
+import android.widget.EditText;
+import android.widget.ImageButton;
+
+import com.google.android.material.snackbar.Snackbar;
+
+import org.ntlab.irisclient.entities.MemberJson;
+import org.ntlab.irisclient.entities.RoomJson;
+import org.ntlab.irisclient.resources.RoomsRest;
+
+import java.util.List;
+
+
+public class EnterRoomActivity extends AppCompatActivity {
+
+ @Override
+ protected void onCreate(Bundle savedInstanceState) {
+ super.onCreate(savedInstanceState);
+ setContentView(R.layout.activity_enter_room);
+ ActionBar actionBar = getSupportActionBar();
+ if(actionBar != null) {
+ actionBar.hide();
+ }
+
+ Retrofit retrofit = new Retrofit.Builder()
+ .baseUrl("http://nitta-lab-www.is.konan-u.ac.jp/iris/")
+ .addConverterFactory(JacksonConverterFactory.create())
+ .build();
+ final RoomsRest roomsRest = retrofit.create(RoomsRest.class);
+
+ ImageButton imageButton = (ImageButton) findViewById(R.id.backButton); // view経由でimageButtonを探す
+ imageButton.setOnClickListener(new View.OnClickListener() {
+ public void onClick(View v) {
+ Intent i = new Intent(v.getContext(), MainActivity.class);
+ startActivity(i);
+ }
+ });
+
+ Button nextButton = findViewById(R.id.EntryRoomButton);
+ nextButton.setOnClickListener(new View.OnClickListener() {
+ public void onClick(View v) {
+ EditText nicknameForm = findViewById(R.id.nicknameEditText);
+ EditText roomIdForm = findViewById(R.id.roomIdEditText);
+
+ String name = nicknameForm.getText().toString();
+ String rid = roomIdForm.getText().toString();
+
+ //ニックネームまたは部屋番号が入力されていない場合エラーメッセージを表示する
+ if (name.isEmpty() || rid.isEmpty()) {
+ nicknameForm.setError("ニックネームを入力されていません");
+ roomIdForm.setError("部屋番号を入力されていません");
+ } else {
+ Call call = roomsRest.postMembers(rid,name);
+ call.enqueue(new Callback() {
+ @Override
+ public void onResponse(Call call, Response response) {
+ if(response.isSuccessful()){
+
+ String responseRid = response.body().getRid();
+ ((Iris) getApplication()).setRid(responseRid);
+ ((Iris) getApplication()).setNickname(name);
+
+ Intent intent = new Intent(EnterRoomActivity.this,MemberRoomActivity.class);
+ intent.putExtra("nickname", name);
+ startActivity(intent);
+ }else {
+ Snackbar.make(v, "部屋に同名のプレイヤーがいるか,満席です", Snackbar.LENGTH_LONG).show();
+ }
+
+ }
+
+ @Override
+ public void onFailure(Call call, Throwable t){
+
+ }
+ });
+ }
+ }
+ });
+
+ }
+
+}
\ No newline at end of file
diff --git a/app/src/main/java/org/ntlab/irisclient/GameMasterActivity.java b/app/src/main/java/org/ntlab/irisclient/GameMasterActivity.java
new file mode 100644
index 0000000..4749565
--- /dev/null
+++ b/app/src/main/java/org/ntlab/irisclient/GameMasterActivity.java
@@ -0,0 +1,226 @@
+package org.ntlab.irisclient;
+
+import androidx.appcompat.app.AppCompatActivity;
+import androidx.fragment.app.FragmentTransaction;
+import androidx.lifecycle.LiveData;
+import androidx.lifecycle.Observer;
+import androidx.lifecycle.ViewModelProvider;
+
+import android.os.Bundle;
+import android.view.View;
+import android.widget.Button;
+import android.widget.EditText;
+import android.widget.ImageButton;
+
+import org.ntlab.irisclient.entities.TurnJson;
+import org.ntlab.irisclient.viewmodels.GameViewModel;
+
+
+public class GameMasterActivity extends AppCompatActivity{
+
+ private GameViewModel gameViewModel;
+
+ //操作可能かどうかを記録。これがfalseの時は何のボタンを押すこともできない。
+ //時間があればオフラインの動作はできるようにしたい。
+ private boolean isActive = false;
+ private String myTeam;
+
+ //赤チームの「ヒント入力」からスタート
+ private String currentTeam = "r";
+ private int turnState = 0;//0:ヒント入力,1:カード選択
+
+
+ @Override
+ protected void onCreate(Bundle savedInstanceState) {
+ super.onCreate(savedInstanceState);
+ setContentView(R.layout.activity_game_master);
+
+ // Fragmentを作成します
+ DrawingCardFragment fragment = new DrawingCardFragment();
+ GamePlayerListFragment RedPlayerList = new GamePlayerListFragment("r");
+ GamePlayerListFragment BluePlayerList = new GamePlayerListFragment("b");
+ // Fragmentの追加や削除といった変更を行う際は、Transactionを利用します
+ FragmentTransaction transaction = getSupportFragmentManager().beginTransaction();
+ // 新しく追加を行うのでaddを使用します
+ // 他にも、よく使う操作で、replace removeといったメソッドがあります
+ // メソッドの1つ目の引数は対象のViewGroupのID、2つ目の引数は追加するfragment
+ transaction.add(R.id.container, fragment);
+ transaction.add(R.id.RedPlayerListContainer, RedPlayerList);
+ transaction.add(R.id.BluePlayerListContainer,BluePlayerList);
+
+ // 最後にcommitを使用することで変更を反映します
+ transaction.commit();
+
+ //Irisから必要な情報を取得
+ Iris iris = (Iris) this.getApplication();
+ String rid = iris.getRid();
+ String nickName = iris.getNickname();
+ myTeam = iris.getTeam();
+
+ //viewModelに必用な情報をセット
+ gameViewModel= new ViewModelProvider(this).get(GameViewModel.class);
+ gameViewModel.setRid(rid);
+
+ //ボタンの情報を入力
+ buttonProcesses();
+
+ //自分が赤チームマスターの場合はヒントが入力可能
+ if(myTeam == null) {
+ System.out.println(("GameMasterActivity: Gakuto: myteamがnullです"));
+ }else{
+ isActive = CheckActivity();
+ }
+
+ //タイマースタート呼び出し
+ gameViewModel.start(500,iris);
+
+ //ヒントの変更を監視
+ gameViewModel.getHintLiveData().observe(this, new Observer() {
+ @Override
+ public void onChanged(String new_Hint) {
+ System.out.println("Gakuto:MasterActivity ヒントが更新されました");
+ EditText Hint = findViewById(R.id.GameHint);
+ if(new_Hint != null){
+ Hint.setText(new_Hint);
+ }else{
+ Hint.getEditableText().clear();
+ }
+ }
+ });
+
+ gameViewModel.getMaxLiveData().observe(this, new Observer() {
+ @Override
+ public void onChanged(Integer new_HintMax) {
+ System.out.println("Gakuto:MasterActivity ヒントマックスが更新されました");
+ EditText HintMax = findViewById(R.id.GameHintMax);
+ if(new_HintMax != 0){
+ HintMax.setText(new_HintMax.toString());
+ }else{
+ HintMax.getEditableText().clear();
+ }
+ }
+ });
+
+ //どちらのターンかを監視
+ gameViewModel.getTurnsLiveData().observe(this, new Observer() {
+ @Override
+ public void onChanged(String new_currentTeam) {
+
+ //チームの情報を更新
+ currentTeam = new_currentTeam;
+
+ //操作できるかを判断する。
+ isActive = CheckActivity();
+ }
+ });
+
+ //「ヒント入力」か「カード選択」かを監視
+ gameViewModel.getTurnStateLiveData().observe(this, new Observer() {
+ @Override
+ public void onChanged(Integer new_turnState) {
+
+ //チームの情報を更新
+ turnState = new_turnState;
+
+ //操作できるかを判断する。
+ isActive = CheckActivity();
+ }
+ });
+
+ //マスターなので推測終了ボタンを入力不可に設定
+ // ImageButton を無効にする
+ Button FinishGuessButton = (Button) findViewById(R.id.finishGuessButton);
+ FinishGuessButton.setEnabled(false);
+ //FinishGuessButton.setColorFilter(0xaaCCCCCC);
+ }
+
+ private void buttonProcesses(){
+ Button SendHintButton = (Button) findViewById(R.id.SendHint);
+
+ SendHintButton.setOnClickListener(new View.OnClickListener() {
+ @Override
+ public void onClick(View view) {
+
+ if(!isActive){
+ return;
+ }//アクティブのときだけボタンを押せる
+
+ EditText Hint = findViewById(R.id.GameHint);
+ EditText HintMax = findViewById(R.id.GameHintMax);
+
+ String hint = null;
+ Integer hintMax = null;
+
+
+ //テキストを適した変数に変更
+ if(Hint.getText().toString().length() != 0){
+ System.out.println("Gakuto:MasterActivity ヒント" + Hint.getText().toString());
+ hint = Hint.getText().toString();
+ }
+ if(HintMax.getText().toString().length() != 0){
+ System.out.println("Gakuto:MasterActivity ヒントマックス" + HintMax.getText().toString());
+ hintMax = Integer.parseInt(HintMax.getText().toString());
+ //マックス0は受け付けない
+ if(hintMax < 0){
+ hintMax = 1;
+ }
+ }
+
+
+ //ニックネームまたは部屋番号が入力されていない場合エラーメッセージを表示する
+ if (hint == null) {
+ System.out.println("Gakuto:MasterActivity ヒントが入力されていません");
+ } else if (hintMax == null) {
+ System.out.println("Gakuto:MasterActivity 数字が入力されていません");
+ } else {
+ System.out.println("Gakuto:MasterActivity ヒントを送信" + hint + " " + hintMax);
+ gameViewModel.sendHint(hint,hintMax);
+
+ }
+
+ }
+ });
+
+
+
+ }
+
+ //操作可能かどうかを調べる関数。masterとかturnをオブザーブしておいて、変更があれば反映する。
+ private boolean CheckActivity(){
+
+ boolean isActive = false;
+
+ //非アクティブであればヒントの入力を禁止する
+ EditText Hint = findViewById(R.id.GameHint);
+ EditText HintMax = findViewById(R.id.GameHintMax);
+ Button SendHintButton = (Button) findViewById(R.id.SendHint);
+ Button FinishGuessButton = (Button) findViewById(R.id.finishGuessButton);
+
+ //自分のチームのターンで、かつ「ヒント入力」時間の場合は行動可能
+ if(currentTeam.equals(myTeam) && turnState == 0){
+ isActive = true;
+ Hint.setEnabled(true);
+ HintMax.setEnabled(true);
+ SendHintButton.setEnabled(true);
+ } else {
+ Hint.setEnabled(false);
+ Hint.setTextColor(0xff000000);
+ HintMax.setEnabled(false);
+ HintMax.setTextColor(0xff000000);
+ SendHintButton.setEnabled(false);
+ FinishGuessButton.setEnabled(false);
+ }
+
+ //デバッグ用
+ Iris iris = (Iris) this.getApplication();
+ if(isActive == true){
+ System.out.println("Gakuto:MasterActivity" + iris.getNickname() + "は操作可能");
+ }else{
+ System.out.println("Gakuto:MasterActivity" + iris.getNickname() + "は操作不可");
+ }
+
+ return isActive;
+ }
+
+
+}
\ No newline at end of file
diff --git a/app/src/main/java/org/ntlab/irisclient/GameMemberActivity.java b/app/src/main/java/org/ntlab/irisclient/GameMemberActivity.java
new file mode 100644
index 0000000..c208038
--- /dev/null
+++ b/app/src/main/java/org/ntlab/irisclient/GameMemberActivity.java
@@ -0,0 +1,187 @@
+package org.ntlab.irisclient;
+
+import androidx.appcompat.app.AppCompatActivity;
+import androidx.fragment.app.FragmentManager;
+import androidx.fragment.app.FragmentTransaction;
+import androidx.lifecycle.Observer;
+import androidx.lifecycle.ViewModelProvider;
+
+import android.content.Intent;
+import android.os.Bundle;
+import android.view.View;
+import android.widget.Button;
+import android.widget.EditText;
+
+import org.ntlab.irisclient.entities.TurnJson;
+import org.ntlab.irisclient.models.Game;
+import org.ntlab.irisclient.viewmodels.DrawingStateViewModel;
+import org.ntlab.irisclient.viewmodels.GameViewModel;
+
+public class GameMemberActivity extends AppCompatActivity {
+
+ private GameViewModel gameViewModel;
+
+ //操作可能かどうかを記録。これがfalseの時は何のボタンを押すこともできない。
+ //時間があればオフラインの動作はできるようにしたい。
+ private boolean isActive = false;
+ private String myTeam;
+
+ //赤チームの「ヒント入力」からスタート
+ private String currentTeam = "r";
+ private int turnState = 0;//0:ヒント入力,1:カード選択
+
+ @Override
+ protected void onCreate(Bundle savedInstanceState) {
+ super.onCreate(savedInstanceState);
+ setContentView(R.layout.activity_member_game);
+
+ // Fragmentを作成します
+ DrawingCardFragment fragment = new DrawingCardFragment();
+ GamePlayerListFragment RedPlayerList = new GamePlayerListFragment("r");
+ GamePlayerListFragment BluePlayerList = new GamePlayerListFragment("b");
+ // Fragmentの追加や削除といった変更を行う際は、Transactionを利用します
+ FragmentTransaction transaction = getSupportFragmentManager().beginTransaction();
+ // 新しく追加を行うのでaddを使用します
+ // 他にも、よく使う操作で、replace removeといったメソッドがあります
+ // メソッドの1つ目の引数は対象のViewGroupのID、2つ目の引数は追加するfragment
+ transaction.add(R.id.container, fragment);
+ transaction.add(R.id.redPlayerListContainer, RedPlayerList);
+ transaction.add(R.id.bluePlayerListContainer,BluePlayerList);
+
+ // 最後にcommitを使用することで変更を反映します
+ transaction.commit();
+
+ //Irisから必要な情報を取得
+ Iris iris = (Iris) this.getApplication();
+ String rid = iris.getRid();
+ String nickName = iris.getNickname();
+ myTeam = iris.getTeam();
+
+ //viewModelに必用な情報をセット
+ gameViewModel= new ViewModelProvider(this).get(GameViewModel.class);
+ gameViewModel.setRid(rid);
+
+ //ボタンの情報を入力
+ buttonProcesses();
+
+ //自分が赤チームマスターの場合はヒントが入力可能
+ if(myTeam == null) {
+ System.out.println(("myteamがnullです"));
+ }else if(myTeam.equals("r")){
+ isActive = true;
+ }
+
+ //タイマースタート呼び出し
+ gameViewModel.start(500,iris);
+
+ //ヒントの変更を監視
+ gameViewModel.getHintLiveData().observe(this, new Observer() {
+ @Override
+ public void onChanged(String new_Hint) {
+ System.out.println("Gakuto:MasterActivity ヒントが更新されました");
+ EditText Hint = findViewById(R.id.GameHint);
+ if(new_Hint != null){
+ Hint.setText(new_Hint);
+ }else{
+ Hint.getEditableText().clear();
+ }
+ }
+ });
+
+ gameViewModel.getMaxLiveData().observe(this, new Observer() {
+ @Override
+ public void onChanged(Integer new_HintMax) {
+ System.out.println("Gakuto:MasterActivity マックスが更新されました" + new_HintMax);
+ EditText HintMax = findViewById(R.id.GameHintMax);
+ if(new_HintMax != 0){
+ HintMax.setText(new_HintMax.toString());
+ }else{
+ HintMax.getEditableText().clear();
+ }
+ }
+ });
+
+ //どちらのターンかを監視
+ gameViewModel.getTurnsLiveData().observe(this, new Observer() {
+ @Override
+ public void onChanged(String new_currentTeam) {
+
+ //チームの情報を更新
+ currentTeam = new_currentTeam;
+
+ //操作できるかを判断する。
+ isActive = CheckActivity();
+ }
+ });
+
+ //「ヒント入力」か「カード選択」かを監視
+ gameViewModel.getTurnStateLiveData().observe(this, new Observer() {
+ @Override
+ public void onChanged(Integer new_turnState) {
+
+ //チームの情報を更新
+ turnState = new_turnState;
+
+ //操作できるかを判断する。
+ isActive = CheckActivity();
+ }
+ });
+
+ //触れないボタンを設定
+ }
+
+ public void buttonProcesses() {
+
+ Button FinishGuessButton = (Button) findViewById(R.id.finishGuessButton);
+
+ //推測終了を押した時に、ターン終了を通知
+ FinishGuessButton.setOnClickListener(new View.OnClickListener() {
+ @Override
+ public void onClick(View view) {
+
+ if ( !isActive ) {
+ return;
+ }//アクティブのときだけボタンを押せる
+
+
+ //次のターンに行くようにする
+ gameViewModel.addTurns();
+ }
+ });
+ }
+
+ //操作可能かどうかを調べる関数。masterとかturnをオブザーブしておいて、変更があれば反映する。
+ private boolean CheckActivity(){
+
+ boolean isActive = false;
+
+ //非アクティブであれば推測終了の入力を禁止する
+ EditText Hint = findViewById(R.id.GameHint);
+ EditText HintMax = findViewById(R.id.GameHintMax);
+ Button SendHintButton = (Button) findViewById(R.id.SendHint);
+ Button FinishGuessButton = (Button) findViewById(R.id.finishGuessButton);
+
+ //自分のチームのターンで、かつ「ヒント入力」時間の場合は行動可能
+ if(currentTeam.equals(myTeam) && turnState == 1){
+ isActive = true;
+ FinishGuessButton.setEnabled(true);
+ } else {
+ Hint.setEnabled(false);
+ Hint.setTextColor(0xff000000);
+ HintMax.setEnabled(false);
+ HintMax.setTextColor(0xff000000);
+ SendHintButton.setEnabled(false);
+ FinishGuessButton.setEnabled(false);
+ }
+
+ //デバッグ用
+ Iris iris = (Iris) this.getApplication();
+ if(isActive == true){
+ System.out.println("Gakuto:MemberActivity" + iris.getNickname() + "は操作可能");
+ }else{
+ System.out.println("Gakuto:MemberActivity" + iris.getNickname() + "は操作不可");
+ }
+
+ return isActive;
+ }
+}
diff --git a/app/src/main/java/org/ntlab/irisclient/GamePlayerListFragment.java b/app/src/main/java/org/ntlab/irisclient/GamePlayerListFragment.java
new file mode 100644
index 0000000..90157cc
--- /dev/null
+++ b/app/src/main/java/org/ntlab/irisclient/GamePlayerListFragment.java
@@ -0,0 +1,73 @@
+package org.ntlab.irisclient;
+
+import androidx.appcompat.app.AppCompatActivity;
+import androidx.fragment.app.Fragment;
+
+import android.content.res.Resources;
+import android.os.Bundle;
+import android.view.LayoutInflater;
+import android.view.View;
+import android.view.ViewGroup;
+import android.widget.BaseAdapter;
+import android.widget.ListView;
+import android.widget.TextView;
+import android.view.Gravity;
+import org.ntlab.irisclient.models.Member;
+
+import org.ntlab.irisclient.models.Member;
+
+import java.util.ArrayList;
+import java.util.List;
+
+public class GamePlayerListFragment extends Fragment {
+
+ private String myTeam;
+
+ public GamePlayerListFragment(String team)
+ {
+ myTeam = team;
+ }
+
+ @Override
+ public View onCreateView(LayoutInflater inflater, ViewGroup container,Bundle savedInstanceState) {
+ super.onCreateView(inflater, container, savedInstanceState);
+
+ View view = inflater.inflate(R.layout.fragment_game_player_list, container, false);
+
+ //irisからプレイヤーの一覧を取得
+ Iris iris = (Iris)this.getActivity().getApplication();
+
+ List players = iris.getMemberList();
+ List myTeamPlayers = new ArrayList<>();
+
+ //プレイヤーのリストから名前(string)だけを抽出
+ ArrayList viewPlayers = new ArrayList<>();
+
+ //自分と同じチームのだけと抽出。スパイマスターはトップにくるようにしています。
+ players.forEach(m -> {
+
+ if(m.getBelongs().equals(myTeam)){
+ if(m.getMaster() == true){
+ viewPlayers.add(0,m.getNickname());
+ myTeamPlayers.add(0,m);
+ }else{
+ viewPlayers.add(m.getNickname());
+ myTeamPlayers.add(m);
+ }
+
+ }
+ });
+
+ System.out.println("Gakuto:GamePLayerList" + players.get(0).getNickname() + players.get(1).getNickname() );
+
+ ListView playersList = (ListView) view.findViewById(R.id.PlayersList);
+
+ //BaseAdapter adapter = new MemberListAdapter(this.getActivity().getApplicationContext(), R.layout.member_list_layout, viewPlayers, players);
+ // BaseAdapter adapter = new MemberListAdapter(this.getActivity().getApplicationContext(), R.layout.fragment_game_player_list, viewPlayers, players);
+ BaseAdapter adapter = new MemberListAdapter(this.getActivity().getApplicationContext(), R.layout.member_list_layout, viewPlayers, myTeamPlayers);
+ playersList.setAdapter(adapter);
+
+ return view;
+ }
+
+}
\ No newline at end of file
diff --git a/app/src/main/java/org/ntlab/irisclient/Iris.java b/app/src/main/java/org/ntlab/irisclient/Iris.java
new file mode 100644
index 0000000..3a257aa
--- /dev/null
+++ b/app/src/main/java/org/ntlab/irisclient/Iris.java
@@ -0,0 +1,50 @@
+package org.ntlab.irisclient;
+
+import android.app.Application;
+import org.ntlab.irisclient.entities.RoomJson;
+import org.ntlab.irisclient.models.Member;
+
+import java.util.ArrayList;
+import java.util.List;
+
+
+public class Iris extends Application {
+ private String rid;
+ private String nickname;
+ private String team; //Memberクラスにおけるbelongs (r:赤チーム b:青チーム n:無所属)
+ private boolean bMaster;
+ private List memberList = new ArrayList<>();
+
+ //----------------------------------------------------------
+ // getter
+ public String getRid() {
+ return this.rid;
+ }
+
+ public String getNickname() {
+ return this.nickname;
+ }
+
+ public String getTeam() { return this.team; }
+
+ public boolean isMaster() { return this.bMaster; }
+
+ public List getMemberList() { return this.memberList; }
+
+ //----------------------------------------------------------
+ // setter
+ public void setRid(String rid) {
+ this.rid = rid;
+ }
+
+ public void setNickname(String nickname) {
+ this.nickname = nickname;
+ }
+
+ public void setTeam(String team) { this.team = team; }
+
+ public void setMaster(boolean master) { bMaster = master; }
+
+ public void setMemberList(List memberList) { this.memberList = memberList; }
+
+}
diff --git a/app/src/main/java/org/ntlab/irisclient/MainActivity.java b/app/src/main/java/org/ntlab/irisclient/MainActivity.java
new file mode 100644
index 0000000..0bb3ca4
--- /dev/null
+++ b/app/src/main/java/org/ntlab/irisclient/MainActivity.java
@@ -0,0 +1,41 @@
+package org.ntlab.irisclient;
+
+import androidx.appcompat.app.ActionBar;
+import androidx.appcompat.app.AppCompatActivity;
+
+import android.content.Intent;
+import android.os.Bundle;
+import android.view.View;
+import android.widget.Button;
+
+public class MainActivity extends AppCompatActivity {
+
+ @Override
+ protected void onCreate(Bundle savedInstanceState) {
+ super.onCreate(savedInstanceState);
+ setContentView(R.layout.activity_main);
+
+ ActionBar actionBar = getSupportActionBar();
+ if(actionBar != null) {
+ actionBar.hide();
+ }
+
+ Button createButton =(Button)findViewById(R.id.create_room);
+ createButton.setOnClickListener(new View.OnClickListener() {
+ public void onClick(View v){
+ Intent intent = new Intent(MainActivity.this,CreateRoomActivity.class);
+ startActivity(intent);
+ }
+ });
+
+ Button entryButton =(Button)findViewById(R.id.entry_room);
+ entryButton.setOnClickListener(new View.OnClickListener() {
+ public void onClick(View v){
+ Intent intent = new Intent(MainActivity.this,EnterRoomActivity.class);
+ startActivity(intent);
+ }
+ });
+
+
+ }
+}
\ No newline at end of file
diff --git a/app/src/main/java/org/ntlab/irisclient/MemberListAdapter.java b/app/src/main/java/org/ntlab/irisclient/MemberListAdapter.java
new file mode 100644
index 0000000..dcb547c
--- /dev/null
+++ b/app/src/main/java/org/ntlab/irisclient/MemberListAdapter.java
@@ -0,0 +1,132 @@
+package org.ntlab.irisclient;
+
+import android.content.Context;
+import android.graphics.Color;
+import android.view.LayoutInflater;
+import android.view.View;
+import android.view.ViewGroup;
+import android.widget.ArrayAdapter;
+import android.widget.ImageView;
+import android.widget.TextView;
+
+import org.ntlab.irisclient.models.Member;
+
+import java.util.ArrayList;
+import java.util.List;
+
+public class MemberListAdapter extends ArrayAdapter {
+
+ static class ViewHolder {
+ TextView textView;
+ ImageView imageView;
+ }
+ private LayoutInflater inflater;
+ private final int itemLayoutId;
+ private final List memberList;
+ private final List allList;
+ private List redTeam = new ArrayList<>();
+ private List blueTeam = new ArrayList<>();
+ private List grayTeam = new ArrayList<>();
+ private List masterTeam = new ArrayList<>();
+ private List spyTeam = new ArrayList<>();
+
+ final int redColor = Color.rgb(255, 70,70);
+ final int blueColor = Color.rgb(70, 70, 255);
+ final int grayColor = Color.rgb(172, 172, 172);
+
+ public MemberListAdapter(Context context, int itemLayoutId,
+ List members, List mm) {
+ super(context, 0);
+ this.inflater = (LayoutInflater) context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
+ this.itemLayoutId = itemLayoutId;
+ this.memberList = members;
+ this.allList = mm;
+
+ }
+
+ @Override
+ public View getView(int position, View convertView, ViewGroup parent) {
+ ViewHolder holder;
+
+ if (convertView == null) {
+ // activity_member_room.xml に member_list_layout.xml を inflate して convertView とする
+ convertView = inflater.inflate(itemLayoutId, parent, false);
+
+ // ViewHolder を生成
+ holder = new ViewHolder();
+ holder.textView = convertView.findViewById(R.id.textView);
+ holder.imageView = convertView.findViewById(R.id.star);
+
+ convertView.setTag(holder);
+
+ // 背景色を変える
+ convertView.setBackgroundColor(grayColor);
+
+ redTeam.clear();
+ blueTeam.clear();
+ grayTeam.clear();
+ masterTeam.clear();
+ spyTeam.clear();
+ for(int i = 0 ; i < allList.size();i++){
+ if(allList.get(i).getBelongs().equals("r")) {
+ redTeam.add(i);
+ }else if(allList.get(i).getBelongs().equals("b")) {
+ blueTeam.add(i);
+ }else{
+ grayTeam.add(i);
+ }
+ }
+
+ if (redTeam.contains(position)) {
+ convertView.setBackgroundColor(redColor);
+ }else if(blueTeam.contains(position)){
+ convertView.setBackgroundColor(blueColor);
+ } else{
+ convertView.setBackgroundColor(grayColor);
+ }
+
+
+ holder.imageView.setVisibility(View.GONE);
+ for(int i = 0 ; i < allList.size();i++){
+ if(allList.get(i).getMaster()) {
+ masterTeam.add(i);
+ }else{
+ spyTeam.add(i);
+ }
+ }
+
+ if (masterTeam.contains(position)) {
+ holder.imageView.setVisibility(View.VISIBLE);
+ }else{
+ holder.imageView.setVisibility(View.GONE);
+ }
+
+ }
+ else {
+ holder = (ViewHolder) convertView.getTag();
+ }
+
+ // 現在の position にあるファイル名リストを holder の textView にセット
+ holder.textView.setText(memberList.get(position));
+
+ return convertView;
+
+ }
+
+ @Override
+ public int getCount() {
+ // texts 配列の要素数
+ return memberList.size();
+ }
+
+ @Override
+ public String getItem(int position) {
+ return null;
+ }
+
+ @Override
+ public long getItemId(int position) {
+ return 0;
+ }
+
+}
diff --git a/app/src/main/java/org/ntlab/irisclient/MemberRoomActivity.java b/app/src/main/java/org/ntlab/irisclient/MemberRoomActivity.java
new file mode 100644
index 0000000..725f9ca
--- /dev/null
+++ b/app/src/main/java/org/ntlab/irisclient/MemberRoomActivity.java
@@ -0,0 +1,333 @@
+package org.ntlab.irisclient;
+
+import androidx.appcompat.app.AlertDialog;
+import androidx.appcompat.app.AppCompatActivity;
+import androidx.lifecycle.Observer;
+import androidx.lifecycle.ViewModelProvider;
+import androidx.recyclerview.widget.RecyclerView;
+import retrofit2.Call;
+import retrofit2.Retrofit;
+
+import android.content.ClipData;
+import android.content.ClipDescription;
+import android.content.ClipboardManager;
+import android.content.DialogInterface;
+import android.content.Intent;
+import android.os.Bundle;
+import android.view.View;
+import android.view.ViewGroup;
+import android.widget.ArrayAdapter;
+import android.widget.BaseAdapter;
+import android.widget.Button;
+import android.widget.ImageButton;
+import android.widget.LinearLayout;
+import android.widget.ListView;
+import android.widget.TextView;
+
+import com.google.android.material.snackbar.Snackbar;
+
+import org.ntlab.irisclient.entities.RoomJson;
+import org.ntlab.irisclient.models.Member;
+import org.ntlab.irisclient.models.Settings;
+import org.ntlab.irisclient.resources.RoomsRest;
+import org.ntlab.irisclient.viewmodels.RoomViewModel;
+
+import java.util.ArrayList;
+import java.util.List;
+
+
+public class MemberRoomActivity extends AppCompatActivity {
+
+ //フィールド
+ ArrayList viewMembers = new ArrayList<>();
+ ArrayList oldMembers = new ArrayList<>();
+ List allMembers = new ArrayList<>();
+ String roomId = "null";
+ String myName = "null";
+
+
+
+
+ @Override
+ protected void onCreate(Bundle savedInstanceState) {
+ super.onCreate(savedInstanceState);
+ setContentView(R.layout.activity_member_room);
+
+ roomId = ((Iris) getApplication()).getRid();
+ String nickname = ((Iris) getApplication()).getNickname();
+
+ //--------------------------------------------------------------------------
+ //自分の名前
+ Intent intentMain = getIntent();
+ myName = intentMain.getStringExtra("nickname");
+
+ //--------------------------------------------------------------------------
+ //メンバー表示
+ Member mn = new Member(myName);
+ mn.setBelongs("g");
+ mn.setMaster(false);
+
+ viewMembers.add(mn.getNickname());
+
+ //--------------------------------------------------------------------------
+ //RoomViewModelへのアクセス
+ RoomViewModel roomViewModel = new ViewModelProvider(this).get(RoomViewModel.class);
+
+ roomViewModel.setRid(roomId);
+
+ ListView membersList = (ListView) findViewById(R.id.MembersList);
+
+ BaseAdapter adapter = new MemberListAdapter(this.getApplicationContext(), R.layout.member_list_layout, viewMembers, allMembers);
+ membersList.setAdapter(adapter);
+
+ TextView drawTimer = (TextView) findViewById(R.id.drawTimer);
+ TextView dTimersec = (TextView) findViewById(R.id.dTimersec);
+ TextView gameTimer = (TextView) findViewById(R.id.gameTimer);
+ TextView gTimersec = (TextView) findViewById(R.id.gTimersec);
+
+ //LiveData(List)への購読
+ roomViewModel.getMembersLiveData().observe(this, new Observer>() {
+ //private List members;
+ @Override
+ public void onChanged(List irisMembers) {
+
+ viewMembers.clear();
+ irisMembers.forEach(m -> viewMembers.add(m.getNickname()));
+ allMembers = irisMembers;
+
+ Member myInfo = allMembers.get(myNameIndex(allMembers,myName));
+ ((Iris) getApplication()).setMaster(myInfo.isMaster());
+ ((Iris) getApplication()).setTeam(myInfo.getBelongs());
+
+ BaseAdapter adapter = new MemberListAdapter(getApplicationContext(), R.layout.member_list_layout, viewMembers, allMembers);
+ membersList.setAdapter(adapter);
+
+ }
+
+ });
+
+ roomViewModel.getStateLiveData().observe(this, new Observer() {
+ @Override
+ public void onChanged(Integer state) {
+ if(state >= 1){
+ Intent intent = new Intent(MemberRoomActivity.this,DrawingActivity.class);
+ startActivity(intent);
+ }
+
+ if(state == -1){
+ roomDeleted(roomViewModel);
+ }
+ }
+ });
+
+ roomViewModel.getSettingsLiveData().observe(this, new Observer() {
+ @Override
+ public void onChanged(Settings settings) {
+ if(settings.isDrawingTimer()) {
+ drawTimer.setText("お絵描きタイマー:ON");
+ dTimersec.setVisibility(View.VISIBLE);
+ dTimersec.setText(Integer.toString(settings.getDrawingTimerTimes())+"秒");
+
+ }else {
+ drawTimer.setText("お絵描きタイマー:OFF");
+ dTimersec.setVisibility(View.GONE);
+ }
+
+ if(settings.isGameTimer()) {
+ gameTimer.setText("ゲームタイマー:ON");
+ gTimersec.setVisibility(View.VISIBLE);
+ gTimersec.setText(Integer.toString(settings.getGameTimerTimes())+"秒");
+
+ }else {
+ gameTimer.setText("ゲームタイマー:OFF");
+ gTimersec.setVisibility(View.GONE);
+ }
+ }
+ });
+
+
+ //--------------------------------------------------------------------------
+ //各ボタン処理
+ Button redMasterButton = (Button) findViewById(R.id.beRedMaster);
+ Button redSpyButton = (Button) findViewById(R.id.beRedSpy);
+ Button blueMasterButton = (Button) findViewById(R.id.beBlueMaster);
+ Button blueSpyButton = (Button) findViewById(R.id.beBlueSpy);
+ ImageButton copyButton = (ImageButton) findViewById(R.id.copyButton);
+
+ //MemberRoom専用ボタン
+ ImageButton homeButton = (ImageButton) findViewById(R.id.homeButton);
+
+ //チームと役職の変更
+ //赤チーム・スパイマスター
+ redMasterButton.setOnClickListener(new View.OnClickListener() {
+ @Override
+ public void onClick(View v) {
+ roomViewModel.changeBelongsAndMaster(roomId, myName,"r",true);
+ }
+ });
+
+ //赤チーム・諜報員
+ redSpyButton.setOnClickListener(new View.OnClickListener() {
+ @Override
+ public void onClick(View v) {
+ roomViewModel.changeBelongsAndMaster(roomId, myName,"r",false);
+ }
+ });
+
+ //青チーム・スパイマスター
+ blueMasterButton.setOnClickListener(new View.OnClickListener() {
+ @Override
+ public void onClick(View v) {
+ roomViewModel.changeBelongsAndMaster(roomId, myName,"b",true);
+ }
+ });
+
+ //青チーム・諜報員
+ blueSpyButton.setOnClickListener(new View.OnClickListener() {
+ @Override
+ public void onClick(View v) {
+ roomViewModel.changeBelongsAndMaster(roomId, myName,"b",false);
+ }
+ });
+
+ //roomIDをクリップボードにコピー、他アプリに共有
+ copyButton.setOnClickListener(new View.OnClickListener() {
+ @Override
+ public void onClick(View v) {
+ CopyClipBoard();
+ CreateCommonIntent();
+ Snackbar.make(v, "コピーしました", Snackbar.LENGTH_LONG).show();
+ }
+ });
+
+ //部屋の退出、最初の画面(ホーム)に戻る
+ homeButton.setOnClickListener(new View.OnClickListener() {
+ @Override
+ public void onClick(View v) {
+
+ homeButton(roomViewModel);
+ }
+ });
+
+ //---------------------------------------------------------------
+ //部屋ID情報
+ TextView RoomIdText = findViewById(R.id.roomID);
+ RoomIdText.setText(roomId);
+
+
+ roomViewModel.start(500,(Iris)getApplication());
+
+ }
+
+ //---------------------------------------------------------------
+ //roomIDのテキストをコピーする処理
+ public void CopyClipBoard() {
+ String copyText = roomId; // 生成されたroomIDを取得
+
+ boolean result = SetClipData(copyText);
+ if(result) {
+
+ } else {
+
+ }
+ }
+
+ private boolean SetClipData(String copyText) {
+ try {
+ //クリップボードに格納するItemを作成
+ ClipData.Item item = new ClipData.Item(copyText);
+
+ //MIMETYPEの作成
+ String[] mimeType = new String[1];
+ mimeType[0] = ClipDescription.MIMETYPE_TEXT_URILIST;
+
+ //クリップボードに格納するClipDataオブジェクトの作成
+ ClipData cd = new ClipData(new ClipDescription("text_data", mimeType), item);
+
+ //クリップボードにデータを格納
+ ClipboardManager cm = (ClipboardManager) getSystemService(CLIPBOARD_SERVICE);
+ cm.setPrimaryClip(cd);
+ return true;
+ }
+ catch(Exception e) {
+ return false;
+ }
+ }
+
+ private void CreateCommonIntent() {
+ //システムのクリップボードを取得
+ ClipboardManager cm = (ClipboardManager) getSystemService(CLIPBOARD_SERVICE);
+
+ //クリップボードからClipDataを取得
+ ClipData cd = cm.getPrimaryClip();
+
+ if(cd != null) { // クリップボードにコピーがある場合
+ ClipData.Item item = cd.getItemAt(0);
+ Intent sendIntent =new Intent();
+ sendIntent.setAction(Intent.ACTION_SEND);
+ sendIntent.setType("text/plain");
+ sendIntent.putExtra(sendIntent.EXTRA_TEXT, item.getText()); // 他アプリのテキストをセット
+ startActivity(sendIntent); // 共有メニューを開く
+ }
+ }
+ //---------------------------------------------------------------
+
+ //---------------------------------------------------------------
+ //ホームボタンを押したときの処理
+ private void homeButton(RoomViewModel roomViewModel){
+ String strTitle = "ホーム画面に戻ってよろしいですか?";
+ String strMessage = "退出することになりますよ";
+
+ AlertDialog.Builder builder;
+ builder = new AlertDialog.Builder(this);
+ builder.setMessage(strMessage);
+ builder.setTitle(strTitle);
+ builder.setPositiveButton("OK", new DialogInterface.OnClickListener() {
+ @Override
+ public void onClick(DialogInterface dialog, int which) {
+ roomViewModel.deleteMember(roomId , myName);
+ Intent intent = new Intent(MemberRoomActivity.this,MainActivity.class);
+ startActivity(intent);
+ }
+ });
+ builder.setNegativeButton("キャンセル", new DialogInterface.OnClickListener() {
+ @Override
+ public void onClick(DialogInterface dialog, int which) {
+
+ }
+ });
+ builder.create();
+ builder.show();
+ }
+
+ //---------------------------------------------------------------
+ //オーナーが部屋を退出し、強制的に部屋が削除される処理
+ private void roomDeleted(RoomViewModel roomViewModel){
+ String strTitle = "オーナーが退出しました";
+ String strMessage = "強制的に部屋を削除します";
+
+ AlertDialog.Builder builder;
+ builder = new AlertDialog.Builder(this);
+ builder.setMessage(strMessage);
+ builder.setTitle(strTitle);
+
+ builder.setNegativeButton("OK", new DialogInterface.OnClickListener() {
+ @Override
+ public void onClick(DialogInterface dialog, int which) {
+ System.out.println("ホームへ戻される");
+ }
+ });
+ builder.create();
+ builder.show();
+ }
+
+ private int myNameIndex(List list, String name){
+ for(int i = 0; i < list.size(); i++){
+ if(list.get(i).getNickname().equals(name)) {
+ return i;
+ }
+ }
+ return 0;
+ }
+
+}
\ No newline at end of file
diff --git a/app/src/main/java/org/ntlab/irisclient/OwnerRoomActivity.java b/app/src/main/java/org/ntlab/irisclient/OwnerRoomActivity.java
new file mode 100644
index 0000000..54cc0b2
--- /dev/null
+++ b/app/src/main/java/org/ntlab/irisclient/OwnerRoomActivity.java
@@ -0,0 +1,449 @@
+package org.ntlab.irisclient;
+
+import android.annotation.SuppressLint;
+import android.content.DialogInterface;
+import android.content.ClipData;
+import android.content.ClipDescription;
+import android.content.ClipboardManager;
+import android.content.Intent;
+import android.os.Bundle;
+import android.view.View;
+import android.widget.BaseAdapter;
+import android.widget.Button;
+import android.widget.CompoundButton;
+import android.widget.ImageButton;
+import android.widget.ListView;
+import android.widget.Switch;
+import android.widget.TextView;
+
+import com.google.android.material.snackbar.Snackbar;
+
+import androidx.appcompat.app.AlertDialog;
+import androidx.appcompat.app.AppCompatActivity;
+import androidx.lifecycle.Observer;
+import androidx.lifecycle.ViewModelProvider;
+
+import org.ntlab.irisclient.models.Member;
+import org.ntlab.irisclient.viewmodels.RoomViewModel;
+
+import java.util.ArrayList;
+import java.util.List;
+
+
+public class OwnerRoomActivity extends AppCompatActivity {
+
+ //フィールド
+ ArrayList viewMembers = new ArrayList<>();
+ ArrayList oldMembers = new ArrayList<>();
+ List allMembers = new ArrayList<>();
+ List Mteam = new ArrayList<>();
+ List Steam = new ArrayList<>();
+ List Rteam = new ArrayList<>();
+ List Bteam = new ArrayList<>();
+ String roomId = "null";
+ String myName = "null";
+
+ boolean drawingTimer = true;
+ int drawingTimes = 40;
+ boolean gameTimer = true;
+ int gameTimes = 90;
+ int gameFirstTimes = 10;
+
+ private void homeButton(RoomViewModel roomViewModel){
+ String strTitle = "ホーム画面に戻ってもよろしいですか?";
+ String strMessage = "退出すると部屋は削除されます";
+
+ AlertDialog.Builder builder;
+ builder = new AlertDialog.Builder(this);
+ builder.setMessage(strMessage);
+ builder.setTitle(strTitle);
+ builder.setPositiveButton("ok", new DialogInterface.OnClickListener() {
+ @Override
+ public void onClick(DialogInterface dialog, int which) {
+ roomViewModel.ownerLeaving(roomId , myName);
+
+ Intent i = new Intent(OwnerRoomActivity.this, MainActivity.class);
+ startActivity(i);
+ }
+ });
+ builder.setNegativeButton("cancel", new DialogInterface.OnClickListener() {
+ @Override
+ public void onClick(DialogInterface dialog, int which) {
+
+ }
+ });
+ builder.create();
+ builder.show();
+ }
+
+ @Override
+ protected void onCreate(Bundle savedInstanceState) {
+ super.onCreate(savedInstanceState);
+ setContentView(R.layout.activity_owner_room);
+
+ myName = ((Iris) getApplication()).getNickname();
+ roomId = ((Iris) getApplication()).getRid();
+
+
+ //--------------------------------------------------------------------------
+ //メンバー表示
+ Member mn = new Member(myName);
+ mn.setBelongs("g");
+ mn.setMaster(false);
+
+ viewMembers.add(mn.getNickname());
+
+ //RoomViewModelへのアクセス
+ RoomViewModel roomViewModel = new ViewModelProvider(this).get(RoomViewModel.class);
+
+ roomViewModel.setRid(roomId);
+
+ ListView membersList = (ListView) findViewById(R.id.MembersList);
+
+ BaseAdapter adapter = new MemberListAdapter(this.getApplicationContext(), R.layout.member_list_layout, viewMembers, allMembers);
+ membersList.setAdapter(adapter);
+
+ //LiveData(List)への購読
+ roomViewModel.getMembersLiveData().observe(this, new Observer>() {
+ private List members;
+ @Override
+ public void onChanged(List irisMembers) {
+
+ viewMembers.clear();
+ irisMembers.forEach(m -> viewMembers.add(m.getNickname()));
+ allMembers = irisMembers;
+
+ Member myInfo = allMembers.get(myNameIndex(allMembers,myName));
+ ((Iris) getApplication()).setMaster(myInfo.isMaster());
+ ((Iris) getApplication()).setTeam(myInfo.getBelongs());
+
+
+ BaseAdapter adapter = new MemberListAdapter(getApplicationContext(), R.layout.member_list_layout, viewMembers, allMembers);
+ membersList.setAdapter(adapter);
+
+ }
+ });
+
+
+
+ //各ボタン処理
+ ArrayList members = new ArrayList<>();
+ Button redMasterButton = (Button) findViewById(R.id.beRedMaster);
+ Button redSpyButton = (Button) findViewById(R.id.beRedSpy);
+ Button blueMasterButton = (Button) findViewById(R.id.beBlueMaster);
+ Button blueSpyButton = (Button) findViewById(R.id.beBlueSpy);
+ ImageButton copyButton = (ImageButton) findViewById(R.id.copyButton);
+ ImageButton homeButton = (ImageButton) findViewById(R.id.homeButton);
+ @SuppressLint("UseSwitchCompatOrMaterialCode")
+ Switch dTimer = findViewById(R.id.dTimer);
+ @SuppressLint("UseSwitchCompatOrMaterialCode")
+ Switch gTimer = findViewById(R.id.gTimer);
+ @SuppressLint("UseSwitchCompatOrMaterialCode")
+ Switch d20Times = findViewById(R.id.d20Times);
+ @SuppressLint("UseSwitchCompatOrMaterialCode")
+ Switch d40Times = findViewById(R.id.d40Times);
+ @SuppressLint("UseSwitchCompatOrMaterialCode")
+ Switch d60Times = findViewById(R.id.d60Times);
+ @SuppressLint("UseSwitchCompatOrMaterialCode")
+ Switch g60Times = findViewById(R.id.g60Times);
+ @SuppressLint("UseSwitchCompatOrMaterialCode")
+ Switch g90Times = findViewById(R.id.g90Times);
+ @SuppressLint("UseSwitchCompatOrMaterialCode")
+ Switch g120Times = findViewById(R.id.g120Times);
+
+
+ //OwnerRoom専用ボタン
+ Button randomButton = (Button) findViewById(R.id.random);
+ Button startButton = (Button) findViewById(R.id.start);
+
+
+
+ //チームと役職の変更
+ //赤チーム・スパイマスター
+ redMasterButton.setOnClickListener(new View.OnClickListener() {
+ @Override
+ public void onClick(View v) {
+ roomViewModel.changeBelongsAndMaster(roomId, myName,"r",true);
+ }
+ });
+
+ //赤チーム・諜報員
+ redSpyButton.setOnClickListener(new View.OnClickListener() {
+ @Override
+ public void onClick(View v) {
+ roomViewModel.changeBelongsAndMaster(roomId, myName,"r",false);
+ }
+ });
+
+ //青チーム・スパイマスター
+ blueMasterButton.setOnClickListener(new View.OnClickListener() {
+ @Override
+ public void onClick(View v) {
+ roomViewModel.changeBelongsAndMaster(roomId, myName,"b",true);
+ }
+ });
+
+ //青チーム・諜報員
+ blueSpyButton.setOnClickListener(new View.OnClickListener() {
+ @Override
+ public void onClick(View v) {
+ roomViewModel.changeBelongsAndMaster(roomId, myName,"b",false);
+ }
+ });
+
+ //コピーボタン
+ copyButton.setOnClickListener(new View.OnClickListener() {
+ @Override
+ public void onClick(View v) {
+ Snackbar.make(v, "コピーしました", Snackbar.LENGTH_LONG).show();
+ CopyClipBoard();
+ CreateCommonIntent();
+ }
+ });
+
+
+ //設定ボタン
+ //お絵描きタイマー
+ dTimer.setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener() {
+ @Override
+ public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) {
+ drawingTimer = isChecked;
+ if(drawingTimer == false){
+ d20Times.setVisibility(View.GONE);
+ d40Times.setVisibility(View.GONE);
+ d60Times.setVisibility(View.GONE);
+ }else {
+ d20Times.setVisibility(View.VISIBLE);
+ d40Times.setVisibility(View.VISIBLE);
+ d60Times.setVisibility(View.VISIBLE);
+ }
+
+ roomViewModel.changeSettings(roomId, drawingTimer, drawingTimes, gameTimer, gameTimes, gameFirstTimes);
+ }
+ });
+
+ //d20タイマー
+ d20Times.setOnClickListener(new View.OnClickListener() {
+ @Override
+ public void onClick(View v) {
+ d40Times.setChecked(false);
+ d60Times.setChecked(false);
+ drawingTimes = 20;
+ roomViewModel.changeSettings(roomId, drawingTimer, drawingTimes, gameTimer, gameTimes, gameFirstTimes);
+ }
+ });
+
+ //d40タイマー
+ d40Times.setOnClickListener(new View.OnClickListener() {
+ @Override
+ public void onClick(View v) {
+ d20Times.setChecked(false);
+ d60Times.setChecked(false);
+ drawingTimes = 40;
+ roomViewModel.changeSettings(roomId, drawingTimer, drawingTimes, gameTimer, gameTimes, gameFirstTimes);
+ }
+ });
+
+ //d60タイマー
+ d60Times.setOnClickListener(new View.OnClickListener() {
+ @Override
+ public void onClick(View v) {
+ d20Times.setChecked(false);
+ d40Times.setChecked(false);
+ drawingTimes = 60;
+ roomViewModel.changeSettings(roomId, drawingTimer, drawingTimes, gameTimer, gameTimes, gameFirstTimes);
+ }
+ });
+
+ //ゲームタイマー
+ gTimer.setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener() {
+ @Override
+ public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) {
+ gameTimer = isChecked;
+ if(gameTimer == false){
+ g60Times.setVisibility(View.GONE);
+ g90Times.setVisibility(View.GONE);
+ g120Times.setVisibility(View.GONE);
+ }else {
+ g60Times.setVisibility(View.VISIBLE);
+ g90Times.setVisibility(View.VISIBLE);
+ g120Times.setVisibility(View.VISIBLE);
+ }
+ roomViewModel.changeSettings(roomId, drawingTimer, drawingTimes, gameTimer, gameTimes, gameFirstTimes);
+ }
+ });
+
+ //g60タイマー
+ g60Times.setOnClickListener(new View.OnClickListener() {
+ @Override
+ public void onClick(View v) {
+ g90Times.setChecked(false);
+ g120Times.setChecked(false);
+ gameTimes = 60;
+ roomViewModel.changeSettings(roomId, drawingTimer, drawingTimes, gameTimer, gameTimes, gameFirstTimes);
+ }
+ });
+
+ //g90タイマー
+ g90Times.setOnClickListener(new View.OnClickListener() {
+ @Override
+ public void onClick(View v) {
+ g60Times.setChecked(false);
+ g120Times.setChecked(false);
+ gameTimes = 90;
+ roomViewModel.changeSettings(roomId, drawingTimer, drawingTimes, gameTimer, gameTimes, gameFirstTimes);
+ }
+ });
+
+ //g120タイマー
+ g120Times.setOnClickListener(new View.OnClickListener() {
+ @Override
+ public void onClick(View v) {
+ g60Times.setChecked(false);
+ g90Times.setChecked(false);
+ gameTimes = 120;
+ roomViewModel.changeSettings(roomId, drawingTimer, drawingTimes, gameTimer, gameTimes, gameFirstTimes);
+ }
+ });
+
+ //ランダムボタン
+ randomButton.setOnClickListener(new View.OnClickListener() {
+ @Override
+ public void onClick(View v) {
+ roomViewModel.randomTeam(roomId,myName);
+ }
+ });
+
+ //スタートボタン
+ startButton.setOnClickListener(new View.OnClickListener() {
+ @Override
+ public void onClick(View v) {
+ if(ConditionStart()){
+ roomViewModel.startDrawing(roomId, myName);
+
+ Intent intent = new Intent(OwnerRoomActivity.this,DrawingActivity.class);
+ startActivity(intent);
+ }else{
+ Snackbar.make(v, "スタート条件を満たしていません", Snackbar.LENGTH_LONG).show();
+ }
+
+ }
+ });
+
+ //ホームボタン
+ homeButton.setOnClickListener(new View.OnClickListener() {
+ public void onClick(View v) {
+ homeButton(roomViewModel);
+ }
+ });
+
+ //部屋ID情報
+ TextView RoomIdText = findViewById(R.id.roomID);
+ RoomIdText.setText(roomId);
+
+
+
+ roomViewModel.start(500,(Iris)getApplication());
+ }
+
+ public void CopyClipBoard() {
+ String copyText = roomId; // 作成したレース結果を取得
+
+ // クリップボードへの格納成功時は成功メッセージをトーストで表示
+ boolean result = SetClipData(copyText);
+ if(result) {
+
+ } else {
+
+ }
+ }
+
+ private boolean SetClipData(String copyText) {
+ try {
+ //クリップボードに格納するItemを作成
+ ClipData.Item item = new ClipData.Item(copyText);
+
+ //MIMETYPEの作成
+ String[] mimeType = new String[1];
+ mimeType[0] = ClipDescription.MIMETYPE_TEXT_URILIST;
+
+ //クリップボードに格納するClipDataオブジェクトの作成
+ ClipData cd = new ClipData(new ClipDescription("text_data", mimeType), item);
+
+ //クリップボードにデータを格納
+ ClipboardManager cm = (ClipboardManager) getSystemService(CLIPBOARD_SERVICE);
+ cm.setPrimaryClip(cd);
+ return true;
+ } catch (Exception e) {
+ return false;
+ }
+ }
+
+ private void CreateCommonIntent() {
+ //システムのクリップボードを取得
+ ClipboardManager cm = (ClipboardManager) getSystemService(CLIPBOARD_SERVICE);
+
+ //クリップボードからClipDataを取得
+ ClipData cd = cm.getPrimaryClip();
+
+ if(cd != null) {
+ // クリップボードにコピーがある場合
+ ClipData.Item item = cd.getItemAt(0);
+ Intent sendIntent =new Intent();
+ sendIntent.setAction(Intent.ACTION_SEND);
+ sendIntent.setType("text/plain");
+ sendIntent.putExtra(sendIntent.EXTRA_TEXT, item.getText()); // メモ帳のテキスト欄、メールアプリの本文にテキストをセット
+ startActivity(sendIntent); // 共有メニューを開く
+ }
+ }
+
+ //スタートを押したときの人数・チーム・役職状況
+ public boolean ConditionStart() {
+ Mteam.clear();
+ Steam.clear();
+ Rteam.clear();
+ Bteam.clear();
+
+ for(int i=0; i< allMembers.size(); i++){
+
+ if(allMembers.get(i).getMaster()){
+ Mteam.add(i);
+ }else{
+ Steam.add(i);
+ }
+
+ if(allMembers.get(i).getBelongs().equals("r")){
+ Rteam.add(i);
+ }else if(allMembers.get(i).getBelongs().equals("b")) {
+ Bteam.add(i);
+ } else {
+ return false;
+ }
+
+ }
+
+ if(Mteam.size() != 2){
+ return false;
+ }
+
+ if(Rteam.size() < 2){
+ return false;
+ }
+
+ if(Bteam.size() < 2){
+ return false;
+ }
+
+ return true;
+ }
+
+ private int myNameIndex(List list, String name){
+ for(int i = 0; i < list.size(); i++){
+ if(list.get(i).getNickname().equals(name)) {
+ return i;
+ }
+ }
+ return 0;
+ }
+
+}
\ No newline at end of file
diff --git a/app/src/main/java/org/ntlab/irisclient/TestDrawingActivity.java b/app/src/main/java/org/ntlab/irisclient/TestDrawingActivity.java
new file mode 100644
index 0000000..f73e19d
--- /dev/null
+++ b/app/src/main/java/org/ntlab/irisclient/TestDrawingActivity.java
@@ -0,0 +1,109 @@
+package org.ntlab.irisclient;
+
+import android.content.Intent;
+import android.os.Bundle;
+import android.view.View;
+import android.widget.Button;
+
+import androidx.appcompat.app.ActionBar;
+import androidx.appcompat.app.AppCompatActivity;
+
+import org.ntlab.irisclient.models.Member;
+import org.ntlab.irisclient.resources.GameRest;
+import org.ntlab.irisclient.resources.RoomsRest;
+
+import java.util.List;
+
+import retrofit2.Call;
+import retrofit2.Callback;
+import retrofit2.Response;
+import retrofit2.Retrofit;
+import retrofit2.converter.jackson.JacksonConverterFactory;
+
+public class TestDrawingActivity extends AppCompatActivity {
+
+ @Override
+ protected void onCreate(Bundle savedInstanceState) {
+ super.onCreate(savedInstanceState);
+ setContentView(R.layout.test_activity_draw);
+
+ //サーバーとの通信を初期化
+ Retrofit retrofit = new Retrofit.Builder()
+ .baseUrl("http://nitta-lab-www.is.konan-u.ac.jp/iris/")
+ .addConverterFactory(JacksonConverterFactory.create())
+ .build();
+ final RoomsRest roomsRest = retrofit.create(RoomsRest.class);
+
+ //上の表示を削除
+ ActionBar actionBar = getSupportActionBar();
+ if (actionBar != null) {
+ actionBar.hide();
+ }
+
+ //ownerとして参加
+ Button ownerButton = findViewById(R.id.ownerdraw);
+ ownerButton.setOnClickListener(new View.OnClickListener() {
+ public void onClick(View v) {
+ ((Iris) getApplication()).setRid("drawtest");
+ ((Iris) getApplication()).setNickname("owner");
+ ((Iris) getApplication()).setTeam("r");
+ ((Iris) getApplication()).setMaster(true);
+ Call> call = roomsRest.getRoomMember("drawtest");
+ call.enqueue(new Callback>() {
+ @Override
+ public void onResponse(Call> call, Response> response) {
+ if (response.isSuccessful()){
+ System.out.println("通信成功:createDrawTest");
+ ((Iris) getApplication()).setMemberList(response.body());
+ }
+ }
+ @Override
+ public void onFailure(Call> call, Throwable t) {
+ System.out.println("通信失敗");
+ System.out.println(t);
+ }
+ });
+ Intent intent = new Intent(TestDrawingActivity.this,DrawingActivity.class);
+ startActivity(intent);
+ }
+ });
+
+ //memberとして参加
+ Button memButton = findViewById(R.id.member);
+ memButton.setOnClickListener(new View.OnClickListener() {
+ public void onClick(View v) {
+ ((Iris) getApplication()).setRid("drawtest");
+ ((Iris) getApplication()).setNickname("member");
+ ((Iris) getApplication()).setTeam("b");
+ ((Iris) getApplication()).setMaster(true);
+ Call> call = roomsRest.getRoomMember("drawtest");
+ call.enqueue(new Callback>() {
+ @Override
+ public void onResponse(Call> call, Response> response) {
+ if (response.isSuccessful()){
+ System.out.println("通信成功:createDrawTest");
+ ((Iris) getApplication()).setMemberList(response.body());
+ }
+ }
+ @Override
+ public void onFailure(Call> call, Throwable t) {
+ System.out.println("通信失敗");
+ System.out.println(t);
+ }
+ });
+ Intent intent = new Intent(TestDrawingActivity.this,DrawingActivity.class);
+ startActivity(intent);
+ }
+ });
+
+ //backボタン
+ Button backButton = findViewById(R.id.fromdraw);
+ backButton.setOnClickListener(new View.OnClickListener() {
+ public void onClick(View v) {
+ Intent intent = new Intent(TestDrawingActivity.this,TestEnterActivity.class);
+ startActivity(intent);
+ }
+ });
+
+ }
+}
diff --git a/app/src/main/java/org/ntlab/irisclient/TestEnterActivity.java b/app/src/main/java/org/ntlab/irisclient/TestEnterActivity.java
new file mode 100644
index 0000000..6897185
--- /dev/null
+++ b/app/src/main/java/org/ntlab/irisclient/TestEnterActivity.java
@@ -0,0 +1,47 @@
+package org.ntlab.irisclient;
+
+import android.content.Intent;
+import android.os.Bundle;
+import android.view.View;
+import android.widget.Button;
+import android.widget.ImageButton;
+
+import androidx.appcompat.app.ActionBar;
+import androidx.appcompat.app.AppCompatActivity;
+
+import org.ntlab.irisclient.MainActivity;
+import org.ntlab.irisclient.R;
+
+public class TestEnterActivity extends AppCompatActivity {
+
+ @Override
+ protected void onCreate(Bundle savedInstanceState) {
+ super.onCreate(savedInstanceState);
+ setContentView(R.layout.test_activity_entrance);
+
+ //上の表示を削除
+ ActionBar actionBar = getSupportActionBar();
+ if(actionBar != null) {
+ actionBar.hide();
+ }
+
+ //drawtestへ
+ Button drawButton = findViewById(R.id.dtestenter);
+ drawButton.setOnClickListener(new View.OnClickListener() {
+ public void onClick(View v) {
+ Intent intent = new Intent(TestEnterActivity.this,TestDrawingActivity.class);
+ startActivity(intent);
+ }
+ });
+
+ //gametestへ
+ Button gameButton =(Button)findViewById(R.id.gtestenter);
+ gameButton.setOnClickListener(new View.OnClickListener() {
+ public void onClick(View v){
+ Intent intent = new Intent(TestEnterActivity.this,TestGameActivity.class);
+ startActivity(intent);
+ }
+ });
+
+ }
+}
diff --git a/app/src/main/java/org/ntlab/irisclient/TestGameActivity.java b/app/src/main/java/org/ntlab/irisclient/TestGameActivity.java
new file mode 100644
index 0000000..de74e3b
--- /dev/null
+++ b/app/src/main/java/org/ntlab/irisclient/TestGameActivity.java
@@ -0,0 +1,167 @@
+package org.ntlab.irisclient;
+
+import android.content.Intent;
+import android.os.Bundle;
+import android.view.View;
+import android.widget.Button;
+
+import androidx.appcompat.app.ActionBar;
+import androidx.appcompat.app.AppCompatActivity;
+
+import org.ntlab.irisclient.models.Member;
+import org.ntlab.irisclient.resources.RoomsRest;
+
+import java.util.List;
+
+import retrofit2.Call;
+import retrofit2.Callback;
+import retrofit2.Response;
+import retrofit2.Retrofit;
+import retrofit2.converter.jackson.JacksonConverterFactory;
+
+public class TestGameActivity extends AppCompatActivity {
+
+ @Override
+ protected void onCreate(Bundle savedInstanceState) {
+ super.onCreate(savedInstanceState);
+ setContentView(R.layout.test_activity_game);
+
+ //サーバーとの通信を初期化
+ Retrofit retrofit = new Retrofit.Builder()
+ .baseUrl("http://nitta-lab-www.is.konan-u.ac.jp/iris/")
+ .addConverterFactory(JacksonConverterFactory.create())
+ .build();
+ final RoomsRest roomsRest = retrofit.create(RoomsRest.class);
+
+ //上の表示を削除
+ ActionBar actionBar = getSupportActionBar();
+ if (actionBar != null) {
+ actionBar.hide();
+ }
+
+ //RedSpy(owner)として参加
+ Button ownerButton = findViewById(R.id.ownergame);
+ ownerButton.setOnClickListener(new View.OnClickListener() {
+ public void onClick(View v) {
+ ((Iris) getApplication()).setRid("gametest");
+ ((Iris) getApplication()).setNickname("RedSpy(owner)");
+ ((Iris) getApplication()).setTeam("r");
+ ((Iris) getApplication()).setMaster(true);
+ Call> call = roomsRest.getRoomMember("gametest");
+ call.enqueue(new Callback>() {
+ @Override
+ public void onResponse(Call> call, Response> response) {
+ if (response.isSuccessful()){
+ System.out.println("通信成功");
+ ((Iris) getApplication()).setMemberList(response.body());
+ Intent intent = new Intent(TestGameActivity.this, GameMasterActivity.class);
+ startActivity(intent);
+ }
+ }
+ @Override
+ public void onFailure(Call> call, Throwable t) {
+ System.out.println("通信失敗");
+ System.out.println(t);
+ }
+ });
+ }
+ });
+
+ //RedAgentとして参加
+ Button mem1Button = findViewById(R.id.member1);
+ mem1Button.setOnClickListener(new View.OnClickListener() {
+ public void onClick(View v) {
+ ((Iris) getApplication()).setRid("gametest");
+ ((Iris) getApplication()).setNickname("RedAgent");
+ ((Iris) getApplication()).setTeam("r");
+ ((Iris) getApplication()).setMaster(false);
+ Call> call = roomsRest.getRoomMember("gametest");
+ call.enqueue(new Callback>() {
+ @Override
+ public void onResponse(Call> call, Response> response) {
+ if (response.isSuccessful()){
+ System.out.println("通信成功:createDrawTest");
+ ((Iris) getApplication()).setMemberList(response.body());
+ Intent intent = new Intent(TestGameActivity.this, GameMemberActivity.class);
+ startActivity(intent);
+ }
+ }
+ @Override
+ public void onFailure(Call> call, Throwable t) {
+ System.out.println("通信失敗:createDrawTest");
+ System.out.println(t);
+ }
+ });
+ }
+ });
+
+ //BlueSpyとして参加
+ Button mem2Button = findViewById(R.id.member2);
+ mem2Button.setOnClickListener(new View.OnClickListener() {
+ public void onClick(View v) {
+ ((Iris) getApplication()).setRid("gametest");
+ ((Iris) getApplication()).setNickname("BlueSpy");
+ ((Iris) getApplication()).setTeam("b");
+ ((Iris) getApplication()).setMaster(true);
+ Call> call = roomsRest.getRoomMember("gametest");
+ call.enqueue(new Callback>() {
+ @Override
+ public void onResponse(Call> call, Response> response) {
+ if (response.isSuccessful()){
+ System.out.println("通信成功:createDrawTest");
+ ((Iris) getApplication()).setMemberList(response.body());
+ Intent intent = new Intent(TestGameActivity.this, GameMasterActivity.class);
+ startActivity(intent);
+ }
+ }
+ @Override
+ public void onFailure(Call> call, Throwable t) {
+ System.out.println("通信失敗:createDrawTest");
+ System.out.println(t);
+ }
+ });
+ }
+ });
+
+ //BlueAgentとして参加
+ Button mem3Button = findViewById(R.id.member3);
+ mem3Button.setOnClickListener(new View.OnClickListener() {
+ public void onClick(View v) {
+ ((Iris) getApplication()).setRid("gametest");
+ ((Iris) getApplication()).setNickname("BlueAgent");
+ ((Iris) getApplication()).setTeam("b");
+ ((Iris) getApplication()).setMaster(false);
+ Call> call = roomsRest.getRoomMember("gametest");
+ call.enqueue(new Callback>() {
+ @Override
+ public void onResponse(Call> call, Response> response) {
+ if (response.isSuccessful()){
+ System.out.println("通信成功:createDrawTest");
+ ((Iris) getApplication()).setMemberList(response.body());
+ Intent intent = new Intent(TestGameActivity.this, GameMemberActivity.class);
+ startActivity(intent);
+ }
+ }
+ @Override
+ public void onFailure(Call> call, Throwable t) {
+ System.out.println("通信失敗:createDrawTest");
+ System.out.println(t);
+ }
+ });
+ }
+ });
+
+ //backボタン
+ Button backButton = findViewById(R.id.fromgame);
+ backButton.setOnClickListener(new View.OnClickListener() {
+ public void onClick(View v) {
+ Intent intent = new Intent(TestGameActivity.this, TestEnterActivity.class);
+ startActivity(intent);
+ }
+ });
+
+ }
+}
+
+
+
diff --git a/app/src/main/java/org/ntlab/irisclient/entities/GameJson.java b/app/src/main/java/org/ntlab/irisclient/entities/GameJson.java
new file mode 100644
index 0000000..07483f3
--- /dev/null
+++ b/app/src/main/java/org/ntlab/irisclient/entities/GameJson.java
@@ -0,0 +1,33 @@
+package org.ntlab.irisclient.entities;
+
+import org.ntlab.irisclient.models.Cell;
+import org.ntlab.irisclient.models.Drawing;
+
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+
+public class GameJson {
+
+ private Map drawingList = new HashMap<>();//
+ private List map = new ArrayList<>();//cno順にdnoを管理(要するに絵の並び)
+ private List colorList = new ArrayList<>();//cno順にr,g,b,dを管理:カードごとの色
+
+ //----------------------------------
+ public GameJson(){
+ }
+ //----------------------------------
+
+ //ゲッター
+
+ public Map getDrawingList() {return drawingList;}
+ public List getMap() {return map;}
+ public List getColorList() {return colorList;}
+
+ //セッター
+ public void setDrawingList(Map dlist) {drawingList = dlist;}
+ public void setMap(List map) {this.map = map;}
+ public void setColorList(List color) {this.colorList = color;}
+
+}
diff --git a/app/src/main/java/org/ntlab/irisclient/entities/MemberJson.java b/app/src/main/java/org/ntlab/irisclient/entities/MemberJson.java
new file mode 100644
index 0000000..fbb90f6
--- /dev/null
+++ b/app/src/main/java/org/ntlab/irisclient/entities/MemberJson.java
@@ -0,0 +1,49 @@
+package org.ntlab.irisclient.entities;
+import java.util.List;
+
+
+public class MemberJson {
+ private String nickname;
+ private String belongs; //r:赤チーム b:青チーム n:無所属
+ private boolean master;
+
+
+// public MemberJson(String nickname) {
+// this.nickname = nickname;
+// this.belongs = "n";
+// this.master = false;
+// }
+
+ public MemberJson() {
+ }
+
+ //-------------------------------------
+ // setter
+ public void setNickname(String nickname){
+ this.nickname = nickname;
+ }
+
+ public void setBelongs(String belongs){
+ this.belongs = belongs;
+ }
+
+ public void setMaster(boolean master){
+ this.master = master;
+ }
+
+ //---------------------------------------
+ // getter
+
+ public String getNickname(){
+ return this.nickname;
+ }
+
+ public String getBelongs(){
+ return this.belongs;
+ }
+
+ public boolean isMaster(){
+ return this.master;
+ }
+
+}
diff --git a/app/src/main/java/org/ntlab/irisclient/entities/RoomJson.java b/app/src/main/java/org/ntlab/irisclient/entities/RoomJson.java
new file mode 100644
index 0000000..02743a0
--- /dev/null
+++ b/app/src/main/java/org/ntlab/irisclient/entities/RoomJson.java
@@ -0,0 +1,50 @@
+package org.ntlab.irisclient.entities;
+
+import org.ntlab.irisclient.models.Member;
+
+
+import java.util.ArrayList;
+import java.util.Collection;
+
+public class RoomJson {
+
+ //フィールド
+ private String rid;
+ private Integer state;
+ private String ownerName;
+ //List members = new ArrayList<>();
+ //private ArrayList members = new ArrayList<>();
+
+ //--------------------------------------------------------------
+ public RoomJson(){
+ }
+
+ //--------------------------------------------------------------
+ //getter
+ public String getRid() {return this.rid;}
+
+ public Integer getState() {return this.state;}
+
+ public String getOwnerName() {return this.ownerName;}
+
+ //public Collection getMembers() {return this.members;}
+
+ //--------------------------------------------------------------
+ //setter
+ public void setRid(String rid) {
+ this.rid = rid;
+ }
+
+ public void setState(Integer state) {
+ this.state = state;
+ }
+
+ public void setOwnerName(String ownerName) {
+ this.ownerName = ownerName;
+ }
+
+// public void setMembers(ArrayList members){
+// this.members = members;
+// }
+
+}
\ No newline at end of file
diff --git a/app/src/main/java/org/ntlab/irisclient/entities/TurnJson.java b/app/src/main/java/org/ntlab/irisclient/entities/TurnJson.java
new file mode 100644
index 0000000..896df40
--- /dev/null
+++ b/app/src/main/java/org/ntlab/irisclient/entities/TurnJson.java
@@ -0,0 +1,71 @@
+package org.ntlab.irisclient.entities;
+
+import org.ntlab.irisclient.models.Cell;
+import org.ntlab.irisclient.models.Turn;
+
+import java.util.ArrayList;
+import java.util.List;
+
+public class TurnJson {
+ private String hint;
+ private String team;
+ private int max;
+ private int turnstate; //turn内でスパイマスターと諜報員の操作の切り替えに使用(0:スパイマスター, 1:諜報員)
+ private int endstate; //0:turn継続, 1:turn終了, 2:game終了
+ private List openlist = new ArrayList<>();
+
+ //---------------------------------------------------------
+ public TurnJson(){
+ }
+ //---------------------------------------------------------
+ //ゲッター
+
+ public String getHint() {
+ return hint;
+ }
+
+ public String getTeam() {
+ return team;
+ }
+
+ public int getMax() {
+ return max;
+ }
+
+ public int getTurnstate() {return turnstate;}
+
+ public int getEndstate() {return endstate;}
+
+ public List getOpenListAll() {return openlist;} //リストそのものを返す。
+
+ //---------------------------------------------------------
+ //セッター
+ public void setHint(String hint) {
+ this.hint = hint;
+ }
+
+ public void setTeam(String team) {
+ this.team = team;
+ }
+
+ public void setMax(int max) {
+ this.max = max;
+ }
+
+ public void setTurnstate(int turnstate) {this.turnstate = turnstate;}
+
+ public void setEndstate(int gamestate) {this.endstate = gamestate;}
+
+
+ //---------------------------------------------------------
+ //openlist操作
+
+ public Integer getOpenListSolo(int num){return openlist.get(num);}
+
+ public void addOpenList(Integer cno){openlist.add(cno);}
+
+ public void delieteOpenList(int num){openlist.remove(num);}
+
+ public int sizeOpenList(){return openlist.size();}
+
+}
diff --git a/app/src/main/java/org/ntlab/irisclient/models/Cell.java b/app/src/main/java/org/ntlab/irisclient/models/Cell.java
new file mode 100644
index 0000000..418d6af
--- /dev/null
+++ b/app/src/main/java/org/ntlab/irisclient/models/Cell.java
@@ -0,0 +1,34 @@
+package org.ntlab.irisclient.models;
+
+
+import com.fasterxml.jackson.annotation.JsonProperty;
+
+public class Cell {
+
+ private boolean isOpen;
+
+ public String color;
+
+ public int dno;
+
+ public int cno;
+
+ //setter
+ public void setIsOpen(boolean isOpen) {this.isOpen = isOpen;}
+
+ public void setColor(String color) {this.color = color;}
+
+ public void setDno(int dno) {this.dno = dno;}
+
+ public void setCno(int cno) {this.cno = cno;}
+
+ //getter
+ public boolean getIsOpen() {return this.isOpen;}
+
+ public String getColor() {return this.color;}
+
+ public int getDno() {return this.dno;}
+
+ public int getCno() {return this.cno;}
+
+}
diff --git a/app/src/main/java/org/ntlab/irisclient/models/Drawing.java b/app/src/main/java/org/ntlab/irisclient/models/Drawing.java
new file mode 100644
index 0000000..397a3be
--- /dev/null
+++ b/app/src/main/java/org/ntlab/irisclient/models/Drawing.java
@@ -0,0 +1,12 @@
+package org.ntlab.irisclient.models;
+
+public class Drawing {
+
+ private String drawingPath;
+
+ // getter
+ public String getDrawing() {return this.drawingPath;}
+
+ // setter
+ public void setDrawing(String drawing) {this.drawingPath = drawing;}
+}
diff --git a/app/src/main/java/org/ntlab/irisclient/models/DrawingState.java b/app/src/main/java/org/ntlab/irisclient/models/DrawingState.java
new file mode 100644
index 0000000..075fcab
--- /dev/null
+++ b/app/src/main/java/org/ntlab/irisclient/models/DrawingState.java
@@ -0,0 +1,21 @@
+package org.ntlab.irisclient.models;
+
+public class DrawingState {
+
+ //部屋の状態。2:お絵描き中 3:ゲーム中
+ private int state;
+
+ //自分に割り振られているdno
+ private int dno;
+
+ //-----------------------------------------------------------------
+ // getter
+ public int getState(){return state;}
+ public int getDno(){return dno;}
+
+ //-----------------------------------------------------------------
+ // setter
+ public void setState(int state){this.state = state;}
+ public void setDno(int dno){this.dno = dno;}
+
+}
diff --git a/app/src/main/java/org/ntlab/irisclient/models/Game.java b/app/src/main/java/org/ntlab/irisclient/models/Game.java
new file mode 100644
index 0000000..6147c93
--- /dev/null
+++ b/app/src/main/java/org/ntlab/irisclient/models/Game.java
@@ -0,0 +1,30 @@
+package org.ntlab.irisclient.models;
+
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+
+public class Game {
+
+ private Map drawingList = new HashMap<>();//
+ private Map keywordList = new HashMap<>();//
+ private Map cellList = new HashMap<>();//
+ private List map = new ArrayList<>();//cno順にdnoを管理
+ private List colorList = new ArrayList<>();//cno順にr,g,b,dを管理
+
+ //ゲッター
+ public Map getDrawingList() {return drawingList;}
+ public Map getKeywordList() {return keywordList;}
+ public Map getCellList() {return cellList;}
+ public List getMap() {return map;}
+ public List getColorList() {return colorList;}
+
+ //セッター
+ public void setDrawingList(Map dlist) {drawingList = dlist;}
+ public void setKeywordList(Map klist) {keywordList = klist;}
+ public void setCellList(Map clist) {cellList = clist;}
+ public void setMap(List map) {this.map = map;}
+ public void setColorList(List color) {this.colorList = color;}
+
+}
diff --git a/app/src/main/java/org/ntlab/irisclient/models/Member.java b/app/src/main/java/org/ntlab/irisclient/models/Member.java
new file mode 100644
index 0000000..dc0f65e
--- /dev/null
+++ b/app/src/main/java/org/ntlab/irisclient/models/Member.java
@@ -0,0 +1,39 @@
+package org.ntlab.irisclient.models;
+
+public class Member {
+
+ private String nickname;
+ //r:赤チーム b:青チーム n:無所属
+ private String belongs;
+ private boolean master;
+
+ //-----------------------------------------------------------------
+ //コンストラクト
+ public Member() {
+ }
+ public Member(String nickname) {
+ this.nickname = nickname;
+ this.belongs = "n";
+ this.master = false;
+ }
+ //-----------------------------------------------------------------
+ // getter
+ public String getNickname() {return this.nickname;}
+
+ public String getBelongs() {return this.belongs;}
+
+ public boolean getMaster() {return this.master;}
+
+ public boolean isMaster() {return this.master;}
+
+ //-----------------------------------------------------------------
+ // setter
+ public void setNickname(String nickname) {this.nickname = nickname;}
+
+ public void setBelongs(String belongs) {this.belongs = belongs;}
+
+ public void setMaster(boolean master) {this.master = master;}
+
+
+
+}
diff --git a/app/src/main/java/org/ntlab/irisclient/models/Room.java b/app/src/main/java/org/ntlab/irisclient/models/Room.java
new file mode 100644
index 0000000..74ab603
--- /dev/null
+++ b/app/src/main/java/org/ntlab/irisclient/models/Room.java
@@ -0,0 +1,95 @@
+package org.ntlab.irisclient.models;
+import org.ntlab.irisclient.entities.RoomJson;
+
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+
+public class Room {
+
+ //フィールド
+ private String rid;
+ private int state;
+ private String ownerName;
+ private Member redMaster;
+ private Member blueMaster;
+ private Map members= new HashMap<>();
+ private Settings settings = new Settings();
+
+ //--------------------------------------------------------------
+ public Room(String rid, String owner) {
+ this.rid = rid;
+ ownerName = owner;
+ }
+
+ //--------------------------------------------------------------
+ //getter
+ public String getRid(){
+ return rid;
+ }
+
+ public String getOwnerName() {
+ return ownerName;
+ }
+
+ public Member getRedMaster() {
+ return redMaster;
+ }
+
+ public Member getBlueMaster() {
+ return blueMaster;
+ }
+
+ public Member getMember(String nick) {
+ Member m = members.get(nick);
+ return m;
+ }
+
+ public List getMembers() {
+ List memberslist = new ArrayList(members.values()) ;
+ return memberslist;
+ }
+
+ public Settings getSettings() {
+ return settings;
+ }
+
+ public int getState() {
+ return state;
+ }
+
+ //--------------------------------------------------------------
+ //setter
+ public void setOwnerName(String ownerName) {
+ this.ownerName = ownerName;
+ }
+
+ public Member setMember(String nick) {
+ Member m = members.get(nick);
+ return m;
+ }
+
+ public void setRedMaster(Member redMaster) {
+ this.redMaster = redMaster;
+ }
+
+ public void setBlueMaster(Member blueMaster) {
+ this.blueMaster = blueMaster;
+ }
+
+ public Settings setSettings() {
+ return settings;
+ }
+
+ public void changeState(){
+ state += 1;
+ }
+
+ public void resetState(){
+ state = 0;
+ }
+
+ //--------------------------------------------------------------
+
+}
diff --git a/app/src/main/java/org/ntlab/irisclient/models/Settings.java b/app/src/main/java/org/ntlab/irisclient/models/Settings.java
new file mode 100644
index 0000000..37d4cd3
--- /dev/null
+++ b/app/src/main/java/org/ntlab/irisclient/models/Settings.java
@@ -0,0 +1,64 @@
+package org.ntlab.irisclient.models;
+
+public class Settings {
+
+ private boolean drawingTimer;
+ private int drawingTimerTimes;
+ private boolean gameTimer;
+ private int gameTimerTimes;
+ private int gameTimerFirstThinkingTimes;
+
+ //--------------------------------------------------------------------
+ //コンストラクタで初期値設定
+ public Settings(){
+ drawingTimer = false;
+ drawingTimerTimes = 40;
+ gameTimer = true;
+ gameTimerTimes = 90;
+ gameTimerFirstThinkingTimes = 10;
+ }
+
+ //--------------------------------------------------------------------
+ //setter & getter
+ public boolean isDrawingTimer() {
+ return drawingTimer;
+ }
+
+ public void setDrawingTimer(boolean drawingTimer) {
+ this.drawingTimer = drawingTimer;
+ }
+
+ public int getDrawingTimerTimes() {
+ return drawingTimerTimes;
+ }
+
+ public void setDrawingTimerTimes(int drawingTimerTimes) {
+ this.drawingTimerTimes = drawingTimerTimes;
+ }
+
+ public boolean isGameTimer() {
+ return gameTimer;
+ }
+
+ public void setGameTimer(boolean gameTimer) {
+ this.gameTimer = gameTimer;
+ }
+
+ public int getGameTimerTimes() {
+ return gameTimerTimes;
+ }
+
+ public void setGameTimerTimes(int gameTimerTimes) {
+ this.gameTimerTimes = gameTimerTimes;
+ }
+
+ public int getGameTimerFirstThinkingTimes() {
+ return gameTimerFirstThinkingTimes;
+ }
+
+ public void setGameTimerFirstThinkingTimes(int gameTimerFirstThinkingTimes) {
+ this.gameTimerFirstThinkingTimes = gameTimerFirstThinkingTimes;
+ }
+
+
+}
diff --git a/app/src/main/java/org/ntlab/irisclient/models/Turn.java b/app/src/main/java/org/ntlab/irisclient/models/Turn.java
new file mode 100644
index 0000000..b43e732
--- /dev/null
+++ b/app/src/main/java/org/ntlab/irisclient/models/Turn.java
@@ -0,0 +1,66 @@
+package org.ntlab.irisclient.models;
+
+import java.util.ArrayList;
+import java.util.List;
+
+public class Turn {
+
+ private String hint;
+ private String team;
+ private int max;
+ private int turnstate; //turn内でスパイマスターと諜報員の操作の切り替えに使用(0:スパイマスター, 1:諜報員)
+ private int gamestate; //0:turn継続, 1:game終了
+ private List openlist = new ArrayList<>();
+
+ //---------------------------------------------------------
+ //ゲッター
+
+// public String getHint() {
+// return hint;
+// }
+
+// public String getTeam() {
+// return team;
+// }
+
+// public int getMax() {
+// return max;
+// }
+
+ public int getTurnstate() {return turnstate;}
+
+ public int getGamestate() {return gamestate;}
+
+ public List getOpenListAll() {return openlist;} //リストそのものを返す。
+
+ //---------------------------------------------------------
+ //セッター
+
+ public void setHint(String hint) {
+ this.hint = hint;
+ }
+
+ public void setTeam(String team) {
+ this.team = team;
+ }
+
+ public void setMax(int max) {
+ this.max = max;
+ }
+
+ public void setTurnstate(int turnstate) {this.turnstate = turnstate;}
+
+ public void setGamestate(int gamestate) {this.gamestate = gamestate;}
+
+ //---------------------------------------------------------
+ //openlist操作
+
+ public Integer getOpenListSolo(int num){return openlist.get(num);}
+
+ public void addOpenList(Integer cno){openlist.add(cno);}
+
+ public void delieteOpenList(int num){openlist.remove(num);}
+
+ public int sizeOpenList(){return openlist.size();}
+
+}
diff --git a/app/src/main/java/org/ntlab/irisclient/resources/DrawingRest.java b/app/src/main/java/org/ntlab/irisclient/resources/DrawingRest.java
new file mode 100644
index 0000000..b776e54
--- /dev/null
+++ b/app/src/main/java/org/ntlab/irisclient/resources/DrawingRest.java
@@ -0,0 +1,51 @@
+package org.ntlab.irisclient.resources;
+
+import org.ntlab.irisclient.models.Drawing;
+import org.ntlab.irisclient.models.Member;
+
+import java.util.List;
+
+import retrofit2.Call;
+import retrofit2.http.Field;
+import retrofit2.http.FormUrlEncoded;
+import retrofit2.http.GET;
+import retrofit2.http.PUT;
+import retrofit2.http.Path;
+
+public interface DrawingRest {
+
+ //-----------------------------------------------
+ // 描いた絵を送る
+ @FormUrlEncoded
+ @PUT("rooms/{rid}/game/drawings/{dno}")
+ Call putDrawing(
+ @Path("rid") String rid,
+ @Path("dno") int dno,
+ @Field("drawing") String drawingStr
+ );
+
+ //-----------------------------------------------
+ // 現在のステージの、残り時間を取得する
+ @GET("rooms/{rid}/game/drawings/assignment/timer")
+ Call getTime(
+ @Path("rid") String rid
+ );
+
+ //-----------------------------------------------
+ // 割り当てられたdnoを取得
+ @GET("rooms/{rid}/game/drawings/assignment/{nickname}")
+ Call getDno(
+ @Path("rid") String rid,
+ @Path("nickname") String nickname
+ );
+
+ //-----------------------------------------------
+ // 今回のゲームで使われているキーワードをすべて取得
+ @GET("rooms/{rid}/game/keywords")
+ Call> getKeywords(
+ @Path("rid") String rid
+ );
+
+
+
+}
diff --git a/app/src/main/java/org/ntlab/irisclient/resources/GameRest.java b/app/src/main/java/org/ntlab/irisclient/resources/GameRest.java
new file mode 100644
index 0000000..d7c388b
--- /dev/null
+++ b/app/src/main/java/org/ntlab/irisclient/resources/GameRest.java
@@ -0,0 +1,184 @@
+package org.ntlab.irisclient.resources;
+
+import org.ntlab.irisclient.entities.GameJson;
+import org.ntlab.irisclient.entities.TurnJson;
+
+import java.util.List;
+
+import okhttp3.ResponseBody;
+import retrofit2.Call;
+import retrofit2.http.Field;
+import retrofit2.http.FormUrlEncoded;
+import retrofit2.http.GET;
+import retrofit2.http.POST;
+import retrofit2.http.PUT;
+import retrofit2.http.Path;
+
+public interface GameRest {
+
+ //-----------------------------------------------
+ //Gameの開始に必要な情報を取得する。
+ @GET("rooms/{rid}/game")
+ Call getGame(
+ @Path("rid") String rid
+ );
+
+ //-----------------------------------------------
+ // 今回のゲームで使われる16個のお題をdno順のリストで取得するメソッド
+ @GET("rooms/{rid}/game/keywords")
+ Call getkeywords(
+ @Path("rid") String rid
+ );
+
+ //-----------------------------------------------
+ // カード(絵)の並び順のMapを取得するメソッド
+ @GET("rooms/{rid}/game/map")
+ Call> getMap(
+ @Path("rid") String rid
+ );
+
+ //-----------------------------------------------
+ // カードの色を取得するメソッド
+ @GET("rooms/{rid}/game/color")
+ Call> getColorList(
+ @Path("rid") String rid
+ );
+
+ //-----------------------------------------------
+ // 現在開いているすべてのカードを取得するメソッド true=開いている false=開いてない
+ @GET("rooms/{rid}/game/opens")
+ Call> getOpens(
+ @Path("rid") String rid
+ );
+
+ //-----------------------------------------------
+ // 現在のターンがどちらのチームであるかを取得するメソッド
+ @GET("rooms/{rid}/game/turn")
+ Call getTeam(
+ @Path("rid") String rid
+ );
+
+ //-----------------------------------------------
+ // 現在までのターン数を取得するメソッド
+ @GET("rooms/{rid}/game/turns")
+ Call getTurnNumber(
+ @Path("rid") String rid
+ );
+
+ //-----------------------------------------------
+ // hint,openlist,maxを取得するメソッド
+ @GET("rooms/{rid}/game/turns/{tno}")
+ Call getTurns(
+ @Path("rid") String rid,
+ @Path("tno") int tno
+ );
+
+ //-----------------------------------------------
+ //{tno}//questionsのスラッシュがサーバー側で1個多かったため機能していなかった
+ @GET("rooms/{rid}/game/turns/{tno}//questions")
+ Call> getQ(
+ @Path("rid") String rid,
+ @Path("tno") Integer tno
+ );
+
+ //-----------------------------------------------
+ @GET("rooms/{rid}/game/turns/{tno}/hint")
+ Call getHint(
+ @Path("rid") String rid,
+ @Path("tno") Integer tno
+ );
+
+ //-----------------------------------------------
+ @GET("rooms/{rid}/game/turns/{tno}/max")
+ Call getMax(
+ @Path("rid") String rid,
+ @Path("tno") Integer tno
+ );
+
+ //-----------------------------------------------
+ @GET("rooms/{rid}/game/turns/{tno}/turnstate")
+ Call getTurnState(
+ @Path("rid") String rid,
+ @Path("tno") Integer tno
+ );
+
+ //-----------------------------------------------
+ @GET("rooms/{rid}/game/turns/{tno}/Endstate")
+ Call getEndState(
+ @Path("rid") String rid,
+ @Path("tno") Integer tno
+ );
+
+ //-----------------------------------------------
+ // tnoに指定したターンに開けたカードのcnoを取得するメソッド
+ @GET("rooms/{rid}/game/turns/{tno}/openlist")
+ Call> getOpenList(
+ @Path("rid") String rid,
+ @Path("tno") Integer tno
+ );
+
+ //-----------------------------------------------
+ // 現在のターンで開くカードのcnoを送信するメソッド
+ @FormUrlEncoded
+ @PUT("rooms/{rid}/game/turns/{tno}/openlist")
+ Call setOpenList(
+ @Path("rid") String rid,
+ @Path("tno") int tno,
+ @Field("cno") Integer cno
+ );
+
+ //-----------------------------------------------
+ // マスターのヒントを送信するメソッド + 最大回答数も送信
+ @FormUrlEncoded
+ @PUT("rooms/{rid}/game/turns/{tno}/hint")
+ Call putHint(
+ @Path("rid") String rid,
+ @Path("tno") int tno,
+ @Field("hint") String hint,
+ @Field("max") Integer max
+ );
+
+ //-----------------------------------------------
+ //Turnstateを1に変更
+ @PUT("/{rid}/game/turns/{tno}/turnstate")
+ Call setTurnState(
+ @Path("rid") String rid,
+ @Path("tno") int tno
+ );
+
+ //-----------------------------------------------
+ //Endstateを1に変更
+ @PUT("/{rid}/game/turns/{tno}/endstate")
+ Call setEndState(
+ @Path("rid") String rid,
+ @Path("tno") int tno
+ );
+
+ //-----------------------------------------------
+ /*
+ // マスターのヒント(数字)を送信するメソッド (putHintにまとめられて不要になりました。
+ @FormUrlEncoded
+ @PUT("rooms/{rid}/game/turns/{tno}/max")
+ Call putMax(
+ @Path("rid") String rid,
+ @Path("tno") int tno,
+ @Field("max") Integer max
+ );
+ */
+
+ //-----------------------------------------------
+ @FormUrlEncoded
+ @POST("rooms/{rid}/game/turns/{tno}/questions")
+ Call changeQ(
+ @Path("rid") String rid,
+ @Path("tno") int tno,
+ @Field("cno") Integer cno
+ );
+
+ //-----------------------------------------------
+ @POST("rooms/{rid}/game/turns")
+ Call addTurns(
+ @Path("rid") String rid
+ );
+
+}
diff --git a/app/src/main/java/org/ntlab/irisclient/resources/RoomsRest.java b/app/src/main/java/org/ntlab/irisclient/resources/RoomsRest.java
new file mode 100644
index 0000000..aaa7c08
--- /dev/null
+++ b/app/src/main/java/org/ntlab/irisclient/resources/RoomsRest.java
@@ -0,0 +1,124 @@
+package org.ntlab.irisclient.resources;
+
+import org.ntlab.irisclient.entities.RoomJson;
+import org.ntlab.irisclient.models.Settings;
+import org.ntlab.irisclient.models.Member;
+import java.util.List;
+
+import retrofit2.Call;
+import retrofit2.http.DELETE;
+import retrofit2.http.Field;
+import retrofit2.http.FormUrlEncoded;
+import retrofit2.http.GET;
+import retrofit2.http.POST;
+import retrofit2.http.PUT;
+import retrofit2.http.Path;
+
+public interface RoomsRest {
+
+ //----------------------------------------------
+ // ルームの作成メソッド
+ @FormUrlEncoded
+ @POST("rooms")
+ Call makeRooms(
+ @Field("nickname") String nickname
+ );
+
+ //-----------------------------------------------
+ // メンバー情報を取得するメソッド
+ @GET("rooms/{rid}")
+ Call> getRoomMember(
+ @Path("rid") String rid
+ );
+
+ //----------------------------------------------
+ //ルームを削除するメソッド
+ @DELETE("rooms/{rid}")
+ Call deleteRooms(
+ @Path("rid") String rid
+ );
+
+ //--------------------------------------------------
+ // ランダムなチーム編成を行うメソッド
+ @FormUrlEncoded
+ @PUT("rooms/{rid}/members")
+ Call putMembers(
+ @Path("rid") String rid,
+ @Field("nickname") String nickname
+ );
+
+ //------------------------------------------------
+ //自分のニックネームを送り、部屋に参加するメソッド
+ @FormUrlEncoded
+ @POST("rooms/{rid}/members")
+ Call postMembers(
+ @Path("rid") String rid,
+ @Field("nickname") String nickname
+ );
+
+ //----------------------------------------------------
+ //チーム変更、役職を変更するメソッド
+ @FormUrlEncoded
+ @PUT("rooms/{rid}/members/{nickname}")
+ Call putMember(
+ @Path("rid") String rid,
+ @Path("nickname") String nickname,
+ @Field("belongs") String belongs,
+ @Field("is-master") boolean isMaster
+
+ );
+
+ //--------------------------------------------------
+ //退出するメソッド
+ @DELETE("rooms/{rid}/members/{nickname}")
+ Call deleteMember(
+ @Path("rid") String rid,
+ @Path("nickname") String nickname
+ );
+
+ //----------------------------------------
+ //設定の情報を入手するメソッド
+ @GET("rooms/{rid}/settings")
+ Call getSettings(
+ @Path("rid") String rid
+ );
+
+ //-------------------------------------------------
+ //ゲームの設定を記録するメソッド
+ @FormUrlEncoded
+ @PUT("rooms/{rid}/settings")
+ Call putSettings(
+ @Path("rid") String rid,
+ @Field("drawingTimer") boolean dTimer,
+ @Field("drawingTimerTimes") int dTimerTimes,
+ @Field("gameTimer") boolean gTimer,
+ @Field("gameTimerTimes") int gTimerTimes,
+ @Field("gameTimerFirstThinkingTimes") int gTimerFTTimes
+ );
+
+ //-----------------------------------------------
+ //部屋の情報を入手するメソッド
+ @GET("rooms/{rid}/state")
+ //ここサーバー側はintになってます
+ Call getState(
+ @Path("rid") String rid
+ );
+
+ //-----------------------------------------------
+ //部屋の状態を記録するメソッド
+ @FormUrlEncoded
+ @PUT("rooms/{rid}/state")
+ Call putState(
+ @Path("rid") String rid,
+ @Field("nickname") String nickname,
+ @Field("state") Integer state
+ );
+
+ //-----------------------------------------------
+ //test部屋の更新(主にdrawtest)
+ @FormUrlEncoded
+ @PUT("rooms/test")
+ Call putTestRoom(
+ );
+
+}
diff --git a/app/src/main/java/org/ntlab/irisclient/viewmodels/DrawingStateViewModel.java b/app/src/main/java/org/ntlab/irisclient/viewmodels/DrawingStateViewModel.java
new file mode 100644
index 0000000..9f2b0bd
--- /dev/null
+++ b/app/src/main/java/org/ntlab/irisclient/viewmodels/DrawingStateViewModel.java
@@ -0,0 +1,210 @@
+package org.ntlab.irisclient.viewmodels;
+
+
+import android.graphics.Bitmap;
+
+import org.ntlab.irisclient.Iris;
+import org.ntlab.irisclient.models.Member;
+import org.ntlab.irisclient.resources.DrawingRest;
+import org.ntlab.irisclient.resources.RoomsRest;
+
+import androidx.lifecycle.LiveData;
+import androidx.lifecycle.MutableLiveData;
+
+import java.io.ByteArrayOutputStream;
+import java.io.IOException;
+import java.util.Base64;
+import java.util.List;
+
+import retrofit2.Retrofit;
+import retrofit2.Call;
+import retrofit2.Callback;
+import retrofit2.Response;
+import retrofit2.converter.jackson.JacksonConverterFactory;
+
+public class DrawingStateViewModel extends TimerViewModel {
+ //フィールド
+ final private MutableLiveData stateMutableLiveData=new MutableLiveData<>();
+ final private MutableLiveData dnoMutableLiveData=new MutableLiveData<>();
+ final private MutableLiveData drawingMutableLiveData = new MutableLiveData<>();
+ final private MutableLiveData> keywordsMutableLiveData = new MutableLiveData<>();
+ final private MutableLiveData timerMutableLiveData = new MutableLiveData<>();
+
+ final private Retrofit retrofit;
+ private Integer drawingStatePreData;
+ private Integer dnoPreData = null;
+ private Integer timerPreData = null;
+
+ private String drawingPreData;
+ private List keywords;
+
+
+ public DrawingStateViewModel() {
+ this.retrofit = new Retrofit.Builder()
+ .baseUrl("http://nitta-lab-www.is.konan-u.ac.jp/iris/")
+ .addConverterFactory(JacksonConverterFactory.create())
+ .build();
+ }
+
+ //ゲッター
+// public LiveData getDrawingStateLiveData(){
+// return this.stateMutableLiveData;
+// }
+
+ public void updateState(String rid) {
+
+ final RoomsRest roomsRest = retrofit.create(RoomsRest.class);
+ Call call = roomsRest.getState(rid);
+
+ call.enqueue(new Callback() {
+ @Override
+ public void onResponse(Call call, Response response) {
+ if (response.isSuccessful()){
+
+ if(response.body().equals(drawingStatePreData)){
+ //値が一緒なら書き換えない
+ }else{
+ //値が異なるときのみライブデータを上書き
+ stateMutableLiveData.setValue(response.body());
+ drawingStatePreData = response.body();
+ }
+ }
+ }
+
+ @Override
+ public void onFailure(Call call, Throwable t) {
+ }
+ });
+ }
+
+ public void updateDno(String rid, String nickname) {
+
+ final DrawingRest drawingRest = retrofit.create(DrawingRest.class);
+ Call call = drawingRest.getDno(rid,nickname);
+
+ call.enqueue(new Callback() {
+ @Override
+ public void onResponse(Call call, Response response) {
+ if (response.isSuccessful()){
+
+ if(dnoPreData == null){
+ dnoMutableLiveData.setValue(response.body());
+ dnoPreData = response.body();
+ } else if(response.body().equals(dnoPreData)){
+ System.out.println("test");
+ //値が一緒なら書き換えない
+ } else {
+ //値が異なるときのみライブデータを上書き
+ dnoMutableLiveData.setValue(response.body());
+ dnoPreData = response.body();
+ }
+ }
+ }
+
+ @Override
+ public void onFailure(Call call, Throwable t) {
+ }
+ });
+ }
+
+ public void updateKeywords(String rid){
+ final DrawingRest drawingRest = retrofit.create(DrawingRest.class);
+ Call> keywordsCall = drawingRest.getKeywords(rid);
+
+ keywordsCall.enqueue(new Callback>() {
+ @Override
+ public void onResponse(Call> keywordsCall, Response> response) {
+ if (response.isSuccessful()){
+ keywordsMutableLiveData.setValue(response.body());
+ }
+ }
+
+ @Override
+ public void onFailure(Call> keywordsCall, Throwable t) {
+ }
+ });
+
+ }
+ public void updateTimer(String rid) {
+
+ final DrawingRest drawingRest = retrofit.create(DrawingRest.class);
+ Call call = drawingRest.getTime(rid);
+
+ call.enqueue(new Callback() {
+ @Override
+ public void onResponse(Call call, Response response) {
+ if (response.isSuccessful()){
+ if(timerPreData == null){
+ timerMutableLiveData.setValue(response.body());
+ timerPreData = response.body();
+ }else if(response.body().equals(timerPreData)){
+ //値が一緒なら書き換えない
+ }else{
+ //値が異なるときのみライブデータを上書き
+ timerMutableLiveData.setValue(response.body());
+ timerPreData = response.body();
+ }
+ }
+ }
+
+ @Override
+ public void onFailure(Call call, Throwable t) {
+ }
+ });
+ }
+
+// public LiveData> getMembers(String rid){
+// RoomViewModel members = new RoomViewModel();
+// return members.getMembersLiveData();
+// }
+
+ public LiveData> getKeywords(){
+ return this.keywordsMutableLiveData;
+ }
+ public LiveData getDno(){
+ return this.dnoMutableLiveData;
+ }
+ public LiveData getState(){
+ return this.stateMutableLiveData;
+ }
+ public LiveData getTimer(){return this.timerMutableLiveData;}
+
+ public void start(int interval, Iris iris) {
+ super.start(interval, iris);
+ String rid = iris.getRid();
+ updateKeywords(rid);
+ }
+
+ @Override
+ public void update() {
+ String rid = iris.getRid();
+ String nickName = iris.getNickname();
+ updateState(rid);
+ updateDno(rid, nickName);
+ updateTimer(rid);
+ }
+
+ public void putDrawing(Bitmap image) {
+ ByteArrayOutputStream stream = new ByteArrayOutputStream();
+ image.compress(Bitmap.CompressFormat.PNG, 100, stream);
+ byte[] byteArray = stream.toByteArray();
+ Base64.Encoder encoder = Base64.getEncoder();
+ String encoded = encoder.encodeToString(byteArray);
+
+ final DrawingRest drawingRest = retrofit.create(DrawingRest.class);
+ Integer dno = dnoMutableLiveData.getValue();
+
+ Call call = drawingRest.putDrawing(iris.getRid(), dno, encoded );
+ call.enqueue(new Callback() {
+ @Override
+ public void onResponse(Call call, Response response) {
+ if (response.isSuccessful()){
+ System.out.println("success");
+ }
+ }
+ @Override
+ public void onFailure(Call call, Throwable t) {
+ }
+ });
+ }
+}
diff --git a/app/src/main/java/org/ntlab/irisclient/viewmodels/GameViewModel.java b/app/src/main/java/org/ntlab/irisclient/viewmodels/GameViewModel.java
new file mode 100644
index 0000000..e16880c
--- /dev/null
+++ b/app/src/main/java/org/ntlab/irisclient/viewmodels/GameViewModel.java
@@ -0,0 +1,640 @@
+package org.ntlab.irisclient.viewmodels;
+
+import org.ntlab.irisclient.entities.GameJson;
+import org.ntlab.irisclient.resources.GameRest;
+
+import androidx.lifecycle.LiveData;
+import androidx.lifecycle.MutableLiveData;
+
+import java.io.IOException;
+import java.util.List;
+
+import okhttp3.ResponseBody;
+import retrofit2.Call;
+import retrofit2.Callback;
+import retrofit2.Response;
+import retrofit2.Retrofit;
+import retrofit2.converter.jackson.JacksonConverterFactory;
+
+public class GameViewModel extends TimerViewModel {
+
+
+ //フィールド
+ private String rid;
+ private Integer tno;
+
+ final private MutableLiveData turnsMutableLiveData;
+ final private MutableLiveData hintMutableLiveData;
+ final private MutableLiveData> openListMutableLiveData;
+ final private MutableLiveData maxMutableLiveData;
+ final private MutableLiveData turnNumberMutableLiveData;
+ final private MutableLiveData turnStateMutableLiveData;
+ final private MutableLiveData endStateMutableLiveData;
+ final private MutableLiveData> colorMutableLiveData;
+ final private MutableLiveData> opensMutableLiveData;
+ final private MutableLiveData> mapMutableLiveData;
+ final private MutableLiveData imageMutableLiveData;
+ final private MutableLiveData> QMutableLiveData;
+ private GameJson game = new GameJson();
+ final private GameRest gameRest;
+ final private Retrofit retrofit;
+
+ //更新比較用フィールド
+ private Integer endStatePreData = null;
+ private String hintPreData = null;
+ private Integer maxPreData = null;
+ private List openListPreData = null;
+ private List opensPreData = null;
+ private Integer turnNumberPreData = null;
+ private String turnsPreData = null;
+ private Integer turnStatePreData = null;
+ private List QPreData = null;
+
+ //------------------------------------------------------------------
+ //コンストラクタ
+ public GameViewModel() {
+ this.colorMutableLiveData = new MutableLiveData<>();
+ this.endStateMutableLiveData = new MutableLiveData<>();
+ this.hintMutableLiveData = new MutableLiveData<>();
+ this.imageMutableLiveData = new MutableLiveData<>();
+ this.mapMutableLiveData = new MutableLiveData<>();
+ this.maxMutableLiveData = new MutableLiveData<>();
+ this.openListMutableLiveData = new MutableLiveData<>();
+ this.opensMutableLiveData = new MutableLiveData<>();
+ this.turnNumberMutableLiveData = new MutableLiveData<>();
+ this.turnsMutableLiveData = new MutableLiveData<>();
+ this.turnStateMutableLiveData = new MutableLiveData<>();
+ this.QMutableLiveData = new MutableLiveData<>();
+
+ this.retrofit = new Retrofit.Builder()
+ .baseUrl("http://nitta-lab-www.is.konan-u.ac.jp/iris/")
+ .addConverterFactory(JacksonConverterFactory.create())
+ .build();
+ this.gameRest = retrofit.create(GameRest.class);
+
+ }
+
+ //----------------------------------------------------
+ //setter
+ public void setRid(String rid) {
+ this.rid = rid;
+ //初期値呼び出し
+ testGame(); // 通信をして game に値をセットさせる関数
+ startColor();
+ startImage();
+ startMap();
+ }
+
+ //--------------------------------------------------------------
+ // getter
+ public LiveData getTurnsLiveData() {
+ return this.turnsMutableLiveData;
+ }
+ public LiveData getTurnStateLiveData() {
+ return this.turnStateMutableLiveData;
+ }
+ public LiveData getTurnNumberLiveData() {
+ return this.turnNumberMutableLiveData;
+ }
+ public LiveData getEndStateLiveData() {
+ return this.endStateMutableLiveData;
+ }
+ public LiveData getHintLiveData() {
+ return this.hintMutableLiveData;
+ }
+ public LiveData> getOpenListLiveData() {
+ return this.openListMutableLiveData;
+ }
+ public LiveData getMaxLiveData() {
+ return this.maxMutableLiveData;
+ }
+ public LiveData> getOpenLiveData() {
+ return this.opensMutableLiveData;
+ }
+ public LiveData getImageLiveData() {
+ return this.imageMutableLiveData;
+ }
+ public LiveData> getQLiveData() {
+ return this.QMutableLiveData;
+ }
+ public GameJson getGame() {
+ return game;
+ }
+
+ //ターン数変更
+ public void addTurns() {
+ Call call = gameRest.addTurns(rid);
+
+ call.enqueue(new Callback() {
+ @Override
+ public void onResponse(Call call, Response response) {
+ if (response.isSuccessful()){
+ //System.out.println("通信成功:addTurns");
+ }
+ }
+ @Override
+ public void onFailure(Call call, Throwable t) {
+ System.out.println("通信失敗:addTurns");
+ System.out.println(t);
+ }
+ });
+ }
+
+ //現在のEndStateを送信
+ public void sendEndState() {
+ Call call = gameRest.setEndState(rid, tno);
+
+ call.enqueue(new Callback() {
+ @Override
+ public void onResponse(Call call, Response response) {
+ if (response.isSuccessful()){
+ //System.out.println("通信成功:sendEndState");
+ }
+ }
+ @Override
+ public void onFailure(Call call, Throwable t) {
+ System.out.println("通信失敗:sendEndState");
+ System.out.println(t);
+ }
+ });
+ }
+
+ //マスターのヒント、最大回答数を送信
+ public void sendHint(String hint, Integer max) {
+ Call