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 call = gameRest.putHint(rid, tno, hint, max); + + call.enqueue(new Callback() { + @Override + public void onResponse(Call call, Response response) { + if (response.isSuccessful()){ + //System.out.println("通信成功:sendHint"); + } + } + @Override + public void onFailure(Call call, Throwable t) { + System.out.println("通信失敗:sendHint"); + System.out.println(t); + } + }); + } + + //どのマスを開いたかを送信 + public void sendOpenList(Integer cno) { + Call call = gameRest.setOpenList(rid, tno, cno); + + call.enqueue(new Callback() { + @Override + public void onResponse(Call call, Response response) { + if (response.isSuccessful()){ + //System.out.println("通信成功:sendOpenList"); + } + + } + @Override + public void onFailure(Call call, Throwable t) { + System.out.println("通信失敗:sendOpenList"); + System.out.println(t); + } + }); + } + + //疑っているマスの番号を送信 + public void sendQ(Integer cno) { + Call call = gameRest.changeQ(rid, tno, cno); + + call.enqueue(new Callback() { + @Override + public void onResponse(Call call, Response response) { + if (response.isSuccessful()){ + //System.out.println("通信成功:sendQ " + cno); + } + } + @Override + public void onFailure(Call call, Throwable t) { + System.out.println("通信失敗:sendQ"); + System.out.println(t); + } + }); + } + + //現在のTurnStateを送信(未使用) + public void sendTurnState() { + Call call = gameRest.setTurnState(rid, tno); + + call.enqueue(new Callback() { + @Override + public void onResponse(Call call, Response response) { + if (response.isSuccessful()){ + //System.out.println("通信成功:sendTurnState"); + } + } + @Override + public void onFailure(Call call, Throwable t) { + System.out.println("通信失敗:sendTurnState"); + System.out.println(t); + } + }); + } + + //カードのカラー(r,b,g,d)の取得 + private void startColor() { + Call> call = gameRest.getColorList(rid); + + call.enqueue(new Callback>() { + @Override + public void onResponse(Call> call, Response> response) { + if (response.isSuccessful()){ + colorMutableLiveData.setValue(response.body()); + } + } + + @Override + public void onFailure(Call> call, Throwable t) { + System.out.println("通信失敗:updateColor"); + System.out.println(t); + } + }); + } + + //カード(画像)の取得 + private void startImage() { + Call call = gameRest.getGame(rid); + + call.enqueue(new Callback() { + @Override + public void onResponse(Call call, Response response) { + if (response.isSuccessful()) { + imageMutableLiveData.setValue(response.body()); + } + } + + @Override + public void onFailure(Call call, Throwable t) { + System.out.println("通信失敗:updateImage"); + System.out.println(t); + } + }); + + } + + //カードの並び順の取得 + private void startMap() { + Call> call = gameRest.getMap(rid); + + call.enqueue(new Callback>() { + @Override + public void onResponse(Call> call, Response> response) { + if (response.isSuccessful()) { + mapMutableLiveData.setValue(response.body()); + } + } + + @Override + public void onFailure(Call> call, Throwable t) { + System.out.println("通信失敗:updateMap"); + System.out.println(t); + } + }); + } + + + //----------------------------------------------------------------------------- + // updates + @Override + public void update() { + updateEndState(); + updateHint(); + updateMax(); + updateOpenList(); + updateOpens(); + updateTurnNumber(); + updateTurns(); + updateTurnState(); + updateQ(); + } + + //r,bの取得(今どちらのチームかの判別) + public void updateTurns() { + Call call = gameRest.getTeam(rid); + + call.enqueue(new Callback() { + @Override + public void onResponse(Call call, Response response) { + if (response.isSuccessful()){ + if(turnsPreData == null){ + //初回代入 + try { + turnsMutableLiveData.setValue(response.body().string()); + turnsPreData = turnsMutableLiveData.getValue(); + System.out.println("現在のチームは" + turnsPreData + "です"); + updateTurnNumber(); + } catch (IOException e) { + e.printStackTrace(); + } + + }else if(turnsPreData.equals(response.body().toString())){ + //値が一緒なら書き換えない + }else{ + //値が異なるときのみライブデータを上書き + try { + turnsMutableLiveData.setValue(response.body().string()); + turnsPreData = turnsMutableLiveData.getValue(); + updateTurnNumber(); + } catch (IOException e) { + e.printStackTrace(); + } + + System.out.println("現在のチームは" + turnsPreData + "です"); + } + } + } + + @Override + public void onFailure(Call call, Throwable t) { + System.out.println("通信失敗:updateTurns " + turnsPreData + "です"); + } + }); + } + + //Hintの更新 + public void updateHint() { + Call call = gameRest.getHint(rid, tno); + + call.enqueue(new Callback() { + @Override + public void onResponse(Call call, Response response) { + if (response.isSuccessful()) { + if (response.body() != null) { + if (hintPreData == null) { + try { + hintMutableLiveData.setValue(response.body().string()); + hintPreData = hintMutableLiveData.getValue(); + //System.out.println("今回のヒントは" + hintPreData + "です(初回)" + hintMutableLiveData.getValue()); + } catch (IOException e) { + e.printStackTrace(); + } + } else if (hintPreData.equals(response.body().toString())) { + //値が一緒なら書き換えない + } else { + try { + hintMutableLiveData.setValue(response.body().string()); + hintPreData = hintMutableLiveData.getValue(); + } catch (IOException e) { + e.printStackTrace(); + } + //System.out.println("今回のヒントは" + hintPreData + "です"); + } + } + } + } + + @Override + public void onFailure(Call call, Throwable t) { + System.out.println("通信失敗:updateHint"); + System.out.println(t); + } + }); + } + + //OpenListの更新 + public void updateOpenList() { + Call> call = gameRest.getOpenList(rid, tno); + + call.enqueue(new Callback>() { + @Override + public void onResponse(Call> call, Response> response) { + if (response.isSuccessful()){ + if(openListPreData == null){ + //初回代入 + openListMutableLiveData.setValue(response.body()); + openListPreData = response.body(); + }else if(response.body().equals(openListPreData)){ + //値が一緒なら書き換えない + }else{ + //値が異なるときのみライブデータを上書き + openListMutableLiveData.setValue(response.body()); + openListPreData = response.body(); + } + } + } + + @Override + public void onFailure(Call> call, Throwable t) { + System.out.println("通信失敗:updateOpenList"); + System.out.println(t); + } + }); + } + + //Maxの更新 + public void updateMax() { + Call call = gameRest.getMax(rid, tno); + + call.enqueue(new Callback() { + @Override + public void onResponse(Call call, Response response) { + if (response.isSuccessful()){ + if (response.body() != null) { + if (maxPreData == null) { + //初回代入 + maxMutableLiveData.setValue(response.body()); + maxPreData = response.body(); + } else if (response.body().equals(maxPreData)) { + //値が一緒なら書き換えない + } else { + //値が異なるときのみライブデータを上書き + maxMutableLiveData.setValue(response.body()); + maxPreData = response.body(); + } + } + } + } + + @Override + public void onFailure(Call call, Throwable t) { + System.out.println("通信失敗:updateMax"); + System.out.println(t); + } + }); + } + + //TurnNumberの更新 + public void updateTurnNumber() { + Call call = gameRest.getTurnNumber(rid); + + call.enqueue(new Callback() { + @Override + public void onResponse(Call call, Response response) { + if (response.isSuccessful()) { + if (turnNumberPreData == null) { + //初回代入 + turnNumberMutableLiveData.setValue(response.body()); + turnNumberPreData = response.body(); + tno = response.body(); + System.out.println("TurnNumberは" + turnNumberPreData + "です"); + } else if (response.body().equals(turnNumberPreData)) { + //値が一緒なら書き換えない + } else { + //値が異なるときのみライブデータを上書き + turnNumberMutableLiveData.setValue(response.body()); + turnNumberPreData = response.body(); + tno = response.body(); + System.out.println("TurnNumberは" + turnNumberPreData + "です"); + } + } + } + + @Override + public void onFailure(Call call, Throwable t) { + System.out.println("通信失敗:updateTurnNumber"); + System.out.println(t); + } + }); + } + + + //TurnStateの更新 + public void updateTurnState() { + Call call = gameRest.getTurnState(rid, tno); + + call.enqueue(new Callback() { + @Override + public void onResponse(Call call, Response response) { + if (response.isSuccessful()){ + if(turnStatePreData == null){ + //初回代入 + turnStateMutableLiveData.setValue(response.body()); + turnStatePreData = response.body(); + }else if(response.body().equals(turnStatePreData)){ + //値が一緒なら書き換えない + }else{ + //値が異なるときのみライブデータを上書き + turnStateMutableLiveData.setValue(response.body()); + turnStatePreData = response.body(); + System.out.println("TurnStateは" + turnStatePreData + "です"); + } + } + } + + @Override + public void onFailure(Call call, Throwable t) { + System.out.println("通信失敗:updateTurnState"); + System.out.println(t); + } + }); + } + + //EndStateの更新 + public void updateEndState() { + Call call = gameRest.getEndState(rid, tno); + + call.enqueue(new Callback() { + @Override + public void onResponse(Call call, Response response) { + if (response.isSuccessful()){ + if(endStatePreData == null){ + //初回代入 + endStateMutableLiveData.setValue(response.body()); + endStatePreData = response.body(); + }else if(response.body().equals(endStatePreData)){ + //値が一緒なら書き換えない + }else{ + //値が異なるときのみライブデータを上書き + endStateMutableLiveData.setValue(response.body()); + endStatePreData = response.body(); + } + } + } + + @Override + public void onFailure(Call call, Throwable t) { + System.out.println("通信失敗:updateEndState"); + } + }); + } + + + //現在開いているすべてのカードを取得([tffftffffftttff]みたいなリストを逐一更新する、マスが開くたびに更新) + public void updateOpens() { + Call> call = gameRest.getOpens(rid); + + call.enqueue(new Callback>() { + @Override + public void onResponse(Call> call, Response> response) { + if (response.isSuccessful()){ + if(opensPreData == null){ + //初回代入 + opensMutableLiveData.setValue(response.body()); + opensPreData = response.body(); + }else if(response.body().equals(opensPreData)){ + //値が一緒なら書き換えない + }else{ + //値が異なるときのみライブデータを上書き + opensMutableLiveData.setValue(response.body()); + opensPreData = response.body(); + } + } + } + + @Override + public void onFailure(Call> call, Throwable t) { + System.out.println("通信失敗:updateOpens"); + System.out.println(t); + } + }); + } + + + + //疑っているマス一覧の更新 + public void updateQ() { + Call> call = gameRest.getQ(rid, tno); + + call.enqueue(new Callback>() { + @Override + public void onResponse(Call> call, Response> response) { + if (response.isSuccessful()){ + if(QPreData == null){ + //初回代入 + QMutableLiveData.setValue(response.body()); + QPreData = response.body(); + //System.out.println("通信成功:updateQ初回"); + }else if(response.body().equals(QPreData)){ + //値が一緒なら書き換えない + }else{ + //値が異なるときのみライブデータを上書き + QMutableLiveData.setValue(response.body()); + QPreData = response.body(); + //System.out.println("通信成功:updateQ"); + } + } + } + + @Override + public void onFailure(Call> call, Throwable t) { + System.out.println("通信失敗:updateQ"); + System.out.println(t); + } + }); + } + + public void testGame() { + Call call = gameRest.getGame(rid); + + call.enqueue(new Callback() { + @Override + public void onResponse(Call call, Response response) { + if(response.isSuccessful()) { + game = response.body(); + imageMutableLiveData.setValue(response.body()); + } + } + + @Override + public void onFailure(Call call, Throwable t) { + System.out.println("通信失敗:testGame"); + System.out.println(t); + } + }); + } +} \ No newline at end of file diff --git a/app/src/main/java/org/ntlab/irisclient/viewmodels/RoomViewModel.java b/app/src/main/java/org/ntlab/irisclient/viewmodels/RoomViewModel.java new file mode 100644 index 0000000..64e4a7d --- /dev/null +++ b/app/src/main/java/org/ntlab/irisclient/viewmodels/RoomViewModel.java @@ -0,0 +1,430 @@ +package org.ntlab.irisclient.viewmodels; + +import org.ntlab.irisclient.models.Member; +import org.ntlab.irisclient.models.Settings; +import org.ntlab.irisclient.resources.RoomsRest; + +import androidx.lifecycle.LiveData; +import androidx.lifecycle.MutableLiveData; + +import java.util.ArrayList; +import java.util.List; +import java.util.Objects; + +import retrofit2.Call; +import retrofit2.Callback; +import retrofit2.Response; +import retrofit2.Retrofit; +import retrofit2.converter.jackson.JacksonConverterFactory; + +public class RoomViewModel extends TimerViewModel { + + //フィールド + private String rid; + final private Retrofit retrofit; + final private RoomsRest roomsRest; + + //更新比較用、保存用フィールド + private List sortedMembersList; + private List membersPreData; + private Settings settingsPreData; + private int preState = 0; + + //ライブデータ + final private MutableLiveData> membersLiveData; + final private MutableLiveData settingsMutableLiveData; + final private MutableLiveData stateLiveData; + + //----------------------------------------------------------------------------- + //コンストラクタ + public RoomViewModel() { + this.membersLiveData = new MutableLiveData<>(); + this.settingsMutableLiveData = new MutableLiveData<>(); + this.stateLiveData = new MutableLiveData<>(); + this.retrofit = new Retrofit.Builder() + .baseUrl("http://nitta-lab-www.is.konan-u.ac.jp/iris/") + .addConverterFactory(JacksonConverterFactory.create()) + .build(); + this.roomsRest = retrofit.create(RoomsRest.class); + } + + //----------------------------------------------------------------------------- + //setter + public void setRid(String rid){ + this.rid = rid; + } + + // getter + public LiveData> getMembersLiveData() { + return this.membersLiveData; + } + public LiveData getSettingsLiveData() { + return this.settingsMutableLiveData; + } + public LiveData getStateLiveData() { + return this.stateLiveData; + } + + //----------------------------------------------------------------------------- + //roomViewModelのみの機能的なメソッド + + //2つのメンバーリストを比較。異なればfalse、同じならtrueを返す + private boolean compareMembers(List a, List b) { + int i; + for(i = 0; i < a.size(); i++ ) { + if (Objects.equals(a.get(i).getNickname(), b.get(i).getNickname())) { + if (Objects.equals(a.get(i).getBelongs(), b.get(i).getBelongs())) { + if (a.get(i).getMaster() == b.get(i).getMaster()) { + //ここまで比較して要素が一緒ならi番目は同じなので次へ + }else { + return false; + } + }else{ + return false; + } + }else{ + return false; + } + } + + //全ての要素が一緒ならtrueを返す + return true; + } + + //メンバーリストを優先順位順に並び変えるメソッド + private List sortMembersList(List oldMembers) { + List sortedMembers = new ArrayList<>(); + List> priorityInteger = new ArrayList<>(5); + List list0 = new ArrayList(); + List list1 = new ArrayList(); + List list2 = new ArrayList(); + List list3 = new ArrayList(); + List list4 = new ArrayList(); + + /* + 並び順優先順位 + 0.赤チームスパイマスター + 1.赤チーム諜報員 + 2.青チームスパイマスター + 3.青チーム諜報員 + 4.無所属の人 + */ + + for(int i = 0 ; i < oldMembers.size();i++){ + + //赤チームなら + if (oldMembers.get(i).getBelongs().equals("r")){ + if(oldMembers.get(i).isMaster()){ + //赤マスター優先度0 + list0.add(i); + } else { + //赤諜報員優先度1 + list1.add(i); + } + + //青チームなら + } else if(oldMembers.get(i).getBelongs().equals("b")) { + if(oldMembers.get(i).isMaster()) { + //青マスター優先度2 + list2.add(i); + } else { + //青諜報員優先度3 + list3.add(i); + } + + //その他のチーム(n)なら + } else { + list4.add(i); + } + + } + priorityInteger.add(list0); + priorityInteger.add(list1); + priorityInteger.add(list2); + priorityInteger.add(list3); + priorityInteger.add(list4); + + for(int i = 0; i < 5; i++) { + priorityInteger.get(i).forEach(num -> sortedMembers.add(oldMembers.get(num))); + } + + return sortedMembers; + } + + //2つの設定情報データの比較(Settings) + private boolean compareSettings(Settings a, Settings b) { + + //Drawing関係 + if(a.isDrawingTimer() != b.isDrawingTimer()) { + return false; + } else if(a.getDrawingTimerTimes() != b.getDrawingTimerTimes()) { + return false; + } + + //Game関係 + if(a.isGameTimer() != b.isGameTimer()){ + return false; + } else if(a.getGameTimerTimes() != b.getGameTimerTimes()) { + return false; + } else if(a.getGameTimerFirstThinkingTimes() != b.getGameTimerFirstThinkingTimes()) { + return false; + } + + //全て同じ要素ならtrueを返す + return true; + } + + + //----------------------------------------------------------------------------- + //各Activityでのボタン処理 + + //チーム&マスター変更(Member & Owner Activity共通) + public void changeBelongsAndMaster(String rid, String nickname, String belongs, Boolean isMaster) { + Call call = roomsRest.putMember(rid, nickname, belongs, isMaster); + + call.enqueue(new Callback() { + @Override + public void onResponse(Call call, Response response) { + if (response.isSuccessful()){ + //System.out.println("通信成功:changeBelongsAndMaster"); + } else { + //System.out.println("通信可能:changeBelongsAndMaster: " + response.code()); + } + } + @Override + public void onFailure(Call call, Throwable t) { + //System.out.println("通信失敗:changeBelongsAndMaster"); + } + }); + } + + //メンバー削除(MemberActivityのみ) + public void deleteMember(String rid, String nickname) { + Call call = roomsRest.deleteMember(rid, nickname); + + call.enqueue(new Callback() { + @Override + public void onResponse(Call call, Response response) { + if (response.isSuccessful()){ + //System.out.println("通信成功:deleteMember"); + } else { + //System.out.println("通信可能:deleteMember: " + response.code()); + } + } + @Override + public void onFailure(Call call, Throwable t) { + //System.out.println("通信失敗:deleteMember"); + } + }); + } + + //オーナーが退出ボタンを押した時の通信(OwnerActivityのみ) + public void ownerLeaving(String rid, String nickname) { + Call call = roomsRest.putState(rid,nickname,-1); + + call.enqueue(new Callback() { + @Override + public void onResponse(Call call, Response response) { + if (response.isSuccessful()){ + deleteRoom(rid); + //System.out.println("通信成功:ownerLeaving"); + } + } + @Override + public void onFailure(Call call, Throwable t) { + //System.out.println("通信失敗:ownerLeaving"); + } + }); + } + + //スタートボタンの処理(OwnerActivityのみ) + public void startDrawing(String rid, String nickname) { + Call call = roomsRest.putState(rid,nickname,2); + + call.enqueue(new Callback() { + @Override + public void onResponse(Call call, Response response) { + if (response.isSuccessful()){ + //System.out.println("通信成功:startDrawing"); + } else { + //System.out.println("通信可能:startDrawing: " + response.code()); + } + } + @Override + public void onFailure(Call call, Throwable t) { + //System.out.println("通信失敗:startDrawing"); + } + }); + } + + //ランダムボタンの処理(OwnerActivityのみ) + public void randomTeam(String rid, String nickname) { + Call call = roomsRest.putMembers(rid, nickname); + + call.enqueue(new Callback() { + @Override + public void onResponse(Call call, Response response) { + //System.out.println("ランダムにチーム変更へ"); + } + + @Override + public void onFailure(Call call, Throwable t) { + //System.out.println("通信失敗:randomTeam"); + } + }); + } + + //設定情報の変更処理(OwnerActivityのみ) + public void changeSettings(String rid, boolean dTimer, int dTimerTimes, boolean gTimer, int gTimerTimes, int gTimerFTTimes) { + Call call = roomsRest.putSettings(rid, dTimer, dTimerTimes, gTimer, gTimerTimes, gTimerFTTimes); + + call.enqueue(new Callback() { + @Override + public void onResponse(Call call, Response response) { + if (response.isSuccessful()){ + //System.out.println("通信成功:changeSettings"); + } + } + @Override + public void onFailure(Call call, Throwable t) { + //System.out.println("通信失敗:changeSettings"); + } + }); + } + + //部屋の削除(ViewModel内で呼び出し) + public void deleteRoom(String rid){ + Call call = roomsRest.deleteRooms(rid); + + call.enqueue(new Callback() { + @Override + public void onResponse(Call call, Response response) { + //System.out.println("通信成功:deleteRoom"); + } + + @Override + public void onFailure(Call call, Throwable t) { + //System.out.println("通信失敗:deleteRoom"); + } + }); + } + + //----------------------------------------------------------------------------- + // updates + @Override + public void update(){ + updateMembers(rid); + updateSettings(rid); + updateState(rid); + } + + //部屋の情報の更新(List) + public void updateMembers(String rid) { + Call> call = roomsRest.getRoomMember(rid); + + call.enqueue(new Callback>() { + @Override + public void onResponse(Call> call, Response> response) { + if (response.isSuccessful()){ + + if (membersPreData != null) { + + if (response.body().isEmpty()) { + //もしもレスポンスが空なら何もしない + } else { + + if (response.body().size() != membersPreData.size()) { + //配列のサイズが異なるならその時点で並び替えてライブデータ書き換え + sortedMembersList = sortMembersList(response.body()); + membersLiveData.setValue(sortedMembersList); + membersPreData = sortedMembersList; + iris.setMemberList(sortedMembersList); + } else { + //配列のサイズが同じ時は比較開始 + if (compareMembers(sortMembersList(response.body()), membersPreData)) { + //比較してtrueなら何もしない + } else { + //比較してfalseなら並び替えてライブデータ書き換え + sortedMembersList = sortMembersList(response.body()); + membersLiveData.setValue(sortedMembersList); + membersPreData = sortedMembersList; + iris.setMemberList(sortedMembersList); + } + } + } + + } else { //(memberPreData == null) + //最初のアップデートは無条件でライブデータ書き換え + sortedMembersList = sortMembersList(response.body()); + membersLiveData.setValue(sortedMembersList); + membersPreData = sortedMembersList; + iris.setMemberList(sortedMembersList); + } + } + + } + + @Override + public void onFailure(Call> call, Throwable t) { + //System.out.println("通信失敗:updateMembers"); + } + }); + } + + //設定情報の更新(Settings) + public void updateSettings(String rid) { + Call call = roomsRest.getSettings(rid); + + call.enqueue(new Callback() { + @Override + public void onResponse(Call call, Response response) { + if (response.isSuccessful()){ + + if(settingsPreData != null) { + + if (response.body() == null) { + //もしもレスポンスが空なら何もしない + } else { + if(!compareSettings(response.body(), settingsPreData)) { + settingsMutableLiveData.setValue(response.body()); + settingsPreData = response.body(); + } + } + + } else { //(settingsPreData == null) + settingsMutableLiveData.setValue(response.body()); + settingsPreData = response.body(); + } + + } + } + + @Override + public void onFailure(Call call, Throwable t) { + } + }); + } + + //部屋の状態情報の更新(Integer) + public void updateState(String rid) { + Call call = roomsRest.getState(rid); + + call.enqueue(new Callback() { + @Override + public void onResponse(Call call, Response response) { + if (response.isSuccessful()){ + + //値が一緒なら書き換えない + if(preState != response.body()){ + preState = response.body(); + stateLiveData.setValue(response.body()); + } + } + } + + @Override + public void onFailure(Call call, Throwable t) { + } + }); + } +} diff --git a/app/src/main/java/org/ntlab/irisclient/viewmodels/TimerViewModel.java b/app/src/main/java/org/ntlab/irisclient/viewmodels/TimerViewModel.java new file mode 100644 index 0000000..ad31daf --- /dev/null +++ b/app/src/main/java/org/ntlab/irisclient/viewmodels/TimerViewModel.java @@ -0,0 +1,52 @@ +package org.ntlab.irisclient.viewmodels; + + +import android.util.Log; + import android.view.MotionEvent; + + import androidx.lifecycle.LiveData; + import androidx.lifecycle.MutableLiveData; + import androidx.lifecycle.ViewModel; + +import org.ntlab.irisclient.Iris; + +import java.util.ArrayList; + import java.util.Collection; + import java.util.HashMap; + import java.util.Random; + import java.util.concurrent.ScheduledThreadPoolExecutor; + import java.util.concurrent.TimeUnit; + + +//----------------------------------------------------------------- +// +abstract class TimerViewModel extends ViewModel implements Runnable { + + private ScheduledThreadPoolExecutor thread = null; + protected Iris iris; + + + //----------------------------------------------------------------- + // 一定間隔でサーバー上の筆跡を取得する(GET) + @Override + public void run() { + update(); + } + + public abstract void update(); + + //----------------------------------------------------------------- + //何ミリ秒ごとにrun()を実行するかを決める + public void start(int interval,Iris iris) { + this.iris = iris; + thread = new ScheduledThreadPoolExecutor(1); + thread.scheduleWithFixedDelay(this, interval, 1000L, TimeUnit.MILLISECONDS); + } + + //----------------------------------------------------------------- + // + public void stop() { + thread.shutdown(); + } + //----------------------------------------------------------------- +} \ No newline at end of file diff --git a/app/src/main/res/drawable-v24/backbottom.jpeg b/app/src/main/res/drawable-v24/backbottom.jpeg new file mode 100644 index 0000000..cc28209 --- /dev/null +++ b/app/src/main/res/drawable-v24/backbottom.jpeg Binary files differ diff --git a/app/src/main/res/drawable-v24/ic_launcher_foreground.xml b/app/src/main/res/drawable-v24/ic_launcher_foreground.xml new file mode 100644 index 0000000..2b068d1 --- /dev/null +++ b/app/src/main/res/drawable-v24/ic_launcher_foreground.xml @@ -0,0 +1,30 @@ + + + + + + + + + + + \ No newline at end of file diff --git a/app/src/main/res/drawable/black_image.png b/app/src/main/res/drawable/black_image.png new file mode 100644 index 0000000..6d1c1b3 --- /dev/null +++ b/app/src/main/res/drawable/black_image.png Binary files differ diff --git a/app/src/main/res/drawable/blue_image.png b/app/src/main/res/drawable/blue_image.png new file mode 100644 index 0000000..b27805a --- /dev/null +++ b/app/src/main/res/drawable/blue_image.png Binary files differ diff --git a/app/src/main/res/drawable/border.xml b/app/src/main/res/drawable/border.xml new file mode 100644 index 0000000..f7ee6d5 --- /dev/null +++ b/app/src/main/res/drawable/border.xml @@ -0,0 +1,7 @@ + + + + \ No newline at end of file diff --git a/app/src/main/res/drawable/copy_icon.png b/app/src/main/res/drawable/copy_icon.png new file mode 100644 index 0000000..efd4310 --- /dev/null +++ b/app/src/main/res/drawable/copy_icon.png Binary files differ diff --git a/app/src/main/res/drawable/eraser.png b/app/src/main/res/drawable/eraser.png new file mode 100644 index 0000000..2632152 --- /dev/null +++ b/app/src/main/res/drawable/eraser.png Binary files differ diff --git a/app/src/main/res/drawable/frame_style.xml b/app/src/main/res/drawable/frame_style.xml new file mode 100644 index 0000000..7c5a1e5 --- /dev/null +++ b/app/src/main/res/drawable/frame_style.xml @@ -0,0 +1,16 @@ + + + + + + + + + + + + + \ No newline at end of file diff --git a/app/src/main/res/drawable/gray_image.png b/app/src/main/res/drawable/gray_image.png new file mode 100644 index 0000000..7a22cdb --- /dev/null +++ b/app/src/main/res/drawable/gray_image.png Binary files differ diff --git a/app/src/main/res/drawable/home_icon.png b/app/src/main/res/drawable/home_icon.png new file mode 100644 index 0000000..88f3e34 --- /dev/null +++ b/app/src/main/res/drawable/home_icon.png Binary files differ diff --git a/app/src/main/res/drawable/ic_launcher_background.xml b/app/src/main/res/drawable/ic_launcher_background.xml new file mode 100644 index 0000000..07d5da9 --- /dev/null +++ b/app/src/main/res/drawable/ic_launcher_background.xml @@ -0,0 +1,170 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/app/src/main/res/drawable/pen.png b/app/src/main/res/drawable/pen.png new file mode 100644 index 0000000..b904578 --- /dev/null +++ b/app/src/main/res/drawable/pen.png Binary files differ diff --git a/app/src/main/res/drawable/red_image.png b/app/src/main/res/drawable/red_image.png new file mode 100644 index 0000000..af4abd8 --- /dev/null +++ b/app/src/main/res/drawable/red_image.png Binary files differ diff --git a/app/src/main/res/drawable/skin_image.png b/app/src/main/res/drawable/skin_image.png new file mode 100644 index 0000000..15161e7 --- /dev/null +++ b/app/src/main/res/drawable/skin_image.png Binary files differ diff --git a/app/src/main/res/drawable/star.png b/app/src/main/res/drawable/star.png new file mode 100644 index 0000000..8a04eea --- /dev/null +++ b/app/src/main/res/drawable/star.png Binary files differ diff --git a/app/src/main/res/drawable/test01.jpg b/app/src/main/res/drawable/test01.jpg new file mode 100644 index 0000000..ba20055 --- /dev/null +++ b/app/src/main/res/drawable/test01.jpg Binary files differ diff --git a/app/src/main/res/drawable/test02.jpg b/app/src/main/res/drawable/test02.jpg new file mode 100644 index 0000000..935a0aa --- /dev/null +++ b/app/src/main/res/drawable/test02.jpg Binary files differ diff --git a/app/src/main/res/layout/activity_create_room.xml b/app/src/main/res/layout/activity_create_room.xml new file mode 100644 index 0000000..86e5436 --- /dev/null +++ b/app/src/main/res/layout/activity_create_room.xml @@ -0,0 +1,60 @@ + + + +