イントロダクション
ここ数日の戦いを経て、ようやく先に進めます。※下は戦闘履歴です。
- Eclipse アプリ作成 Lv5〜惨敗:CubeにTextureを貼る〜「惨敗」
- Java 3DGame LWJGL Retry Lv3 Texture〜動かして理解する3〜「負け越し」
- Java 3DGame LWJGL Retry Lv4 デバック〜動かして理解する4〜「黒星」
- Java 3DGame LWJGL Retry Lv5 遊んでみる〜動かして理解する5〜「引分け」
- Java 3DGame LWJGL Retry Lv6 遊んでみる2〜動かして理解する6〜「白星」
家計簿作成を再開しようと思いますが、その前に戦果の方を見ていただきたく思います。
<現在>
家計簿のためのカレンダー部分が完成しました。
現状では、まだまだわかりづらいのは否めません。。。
しかし、初めに比べれば。。。
<作成当初>
家計簿作成再始動
今回はよりカレンダーらしくするために、カレンダークラスを使用してカレンダーの様にCubeを配置する様にプログラムを変更します。
まずはカレンダー作成
Javaの基本的なクラス(java.util.Calendar)を使用します。作成するクラスは「CalendarPosit」クラスです。
<要件の整理:どんな機能を持たせるか考える>
Cubeを使ってカレンダーを作成しますので。以下の要件を満たす必要があります。→プログラム設計になります。
- 対象月の月初の曜日を取得する
- 今月の最大日数を取得する
- Calendarクラスから取得した曜日が何曜日か判定する
- 日曜始まりをデフォルトとして、月曜始まりの場合でも曜日の値(Calendar.DAY_OF_WEEK)を返却する(配列の位置)
実行結果:木のCubeも移動しています
<月曜始まり>の実行結果(isStartMon=true)
<日曜始まり>の実行結果(isStartMon=false)
実装内容:ソースはこちら(Gitでみる)
isStartMonのハンドルを行なっているクラス(DummyGame#init())のソース(2018/11/10現在)
//// 参照しているフィールド変数(抜粋) ////
/**
* 曜日の表示順
* true: 月曜始まり false: 日曜始まり
*/
private boolean isStartMon;
private static final String[] WEEK_TEXTURE_SUN = new String[]{"Sun", "Mon", "Tue", "Wed", "Thi", "Fri", "Sat"};
@Override
public void init(Window window) throws Exception {
renderer.init(window);
isStartMon = true;// 月曜始まり、日曜始まりは「false」
CalendarPosit pos = new CalendarPosit();
// 月初の曜日
int firstDayOfWeek = pos.getStartPoint(isStartMon);
// 今月の最大日数
int maxDayOfMonth = pos.getMaxDayOfMonth();
// Cubeの高さ
ArrayList<float[]> floats = new ArrayList<>();
floats.add(new float[] {0.0001f, 0.12f, 0.3f, 0.001f, 0.1f, 0.25f, 0.1f});
floats.add(new float[] {0.15f, 0.19f, 0.23f, 0.2f, 0.08f, 0.13f, 0.12f});
floats.add(new float[] {0.1f, 0.2f, 0.4f, 0.001f, 0.2f, 0.05f, 0.15f});
floats.add(new float[] {0.11f, 0.12f, 0.3f, 0.001f, 0.1f, 0.25f, 0.1f});
floats.add(new float[] {0.12f, 0.13f, 0.14f, 0.015f, 0.16f, 0.17f, 0.18f});
floats.add(new float[] {0.12f, 0.13f, 0.14f, 0.015f, 0.16f, 0.17f, 0.18f});
// Cubeの底面のサイズ(正方形)
final float cubeSize = 0.1f;
// x軸の初期値
final float xInit = -0.5f;
// y軸の初期値
final float yInit = -0.8f;
// z軸の初期値
final float zInit = -2;
// x軸の増減幅
final float xWidth = 0.185f;
// y軸の増減幅
final float yWidth = 0.033f;
// z軸の増減幅
final float zWidth = 0.1f;
ArrayList arr = new ArrayList();
// マスのカウント
int box = 0;
// 日数
int day = 0;
// 初めの1回目だけ曜日のテキストプレートを作成する
boolean isCreateTexture = false;
// 1ヶ月分(5週間分のマスを作る)
for(int j = 1; j <= 6; j++) {
// 開始点より一列ずらす
// X軸の開始点
float xStart = xInit - (0.1f * j);
// Y軸の開始点
float yStart = yInit + (0.06f * j) ;
// Z軸の開始点
float zStart = zInit - (0.16f * j);
// 1週間分
float[] weekArr = floats.get(j-1);
// 1回目だけテクスチャを作成する
isCreateTexture = j == 1 ? true: false;
for(int i = 1; i <= 7; i++) {
float xAdd = xWidth * i;
float yAdd = yWidth * i;
float zAdd = zWidth * i;
// 日付をインクリメント
box++;
if (isCreateTexture) {
arr.add(putOnTexturePlate(xStart + xAdd + 0.01f , yStart + yAdd - 0.03f, zStart - zAdd + 0.03f, i-1));
}
if (box < firstDayOfWeek) { System.out.println("開始: " + firstDayOfWeek); continue; } day++; if (day >= maxDayOfMonth) {
break;
}
float val = weekArr[i - 1];
arr.add(createCube(val,
cubeSize, xStart + xAdd, yStart + yAdd, zStart - zAdd));
}
}
// 配列の要素数を指定する
GameItem[] items = new GameItem[arr.size()];
// 配列の取り出し
gameItems = arr.toArray(items);
// DEBUG
//debug();
}
ここでのポイントは月曜始まりと、日曜始まりを変更できる様にしたところです。
/**
* 対象月の月初の曜日を取得する
* @return Calendar.MONDAY〜SUNDAY
*/
public int getStartPoint(boolean isStartMon) {
int day_week = 0;
cal.set(Calendar.DATE, 1);
day_week = cal.get(Calendar.DAY_OF_WEEK);
if (isStartMon) {
day_week = day_week == 1 ? 7 : day_week - 1;
}
return day_week;
}
赤字の部分が工夫の部分です、条件文を使って「if文」を使わずに1行で済むし可読性も良い。これを使わないと以下の様なコードになります。(if文を抜粋)
if (isStartMon) { if (day_week == 1) { day_week = 7; } else { day_week = day_week -1; } }
微妙なコードです、なぜかというとif文はネストすると確認しなくてはいけないことが増えるからです。→単純にコード量が多いのもあります。
一応「条件演算子」について、サンプルとして四捨五入の場合です。
/* * 返却する値 = 条件式 ? TRUE時の値(式) : FALSE時の値(式) * System.in() // 標準入力 */ int i = System.in; // 4以下は「0」、5以上は「10」を「response」に代入 int response = i < 5 ? 0 : 10;
そして作成したのが以下のクラス(Gitでみる)です。(ちょっとコード量が多いですが。。。)
package zenryokuservice.gui.lwjgl.kakeibo.util; import java.util.Calendar; /** * 家計簿の各数値を表示するための領域(日)を作成する * @author takunoji * * 2018/11/10 */ public class CalendarPosit { /** 日本語の曜日 */ private static final String[] ja_week = new String[] {"日", "月", "火", "水", "木", "金", "土"}; /** 英語の曜日 */ private static final String[] en_week = new String[] {"Sun", "Mon", "Tue", "Wed", "thu", "Fri", "Sat"}; private Calendar cal = null; public CalendarPosit() { cal = Calendar.getInstance(); } /** * 今月の最大日数を返す * @return 最大日数 */ public int getMaxDayOfMonth() { return cal.getMaximum(Calendar.DATE); } /** * 今月の最大日数を返す * @move 今月の月からずらす月数 * move=1 -> 1ヶ月たす * mobe=-1 -> 1ヶ月引く * * * 現在:10月 * move= 1 -> 11月の最大日数 * move= -1 -> 9月の最大日数 * @return 最大日数 */ public int getMaxDayOfMonth(int move) { Calendar tmpCal = cal; tmpCal.add(Calendar.MONTH, move); return tmpCal.getMaximum(Calendar.DATE); } /** * 対象月の月初の曜日を取得する * @return Calendar.MONDAY〜SUNDAY */ public int getStartPoint(boolean isStartMon) { int day_week = 0; cal.set(Calendar.DATE, 1); day_week = cal.get(Calendar.DAY_OF_WEEK); if (isStartMon) { day_week = day_week == 1 ? 7 : day_week - 1; } return day_week; } /** * 現在の年の指定した月初の曜日を返却する * @param month 1-12を指定する * @return 対象月の、月初曜日 */ public int getStartPoint(int month, boolean isStartMon) { int day_week = 0; Calendar cal = Calendar.getInstance(); cal.set(Calendar.MONTH, month - 1); cal.set(Calendar.DATE, 1); day_week = cal.get(Calendar.DAY_OF_WEEK); return day_week; } /** * カレンダークラスを返却する。 * @return */ public Calendar getCalendar() { return this.cal; } /** * 開始日付に対応する曜日の値を返す。 * @return 曜日の文字列 */ public String getDayOfWeek(boolean isStartMon) { return ja_week[getStartPoint(isStartMon)]; } /** * 引数の値が何曜日か判定して返却する * @param value Calendarクラスより取得した、DAY_OF_WEEK * @return 対象の曜日の値 */ public int chkWeek(int value, boolean isStartMon) { int day_of_week = 0; switch(value) { case Calendar.MONDAY: day_of_week = Calendar.MONDAY; break; case Calendar.TUESDAY: day_of_week = Calendar.TUESDAY; break; case Calendar.WEDNESDAY: day_of_week = Calendar.TUESDAY; break; case Calendar.THURSDAY: day_of_week = Calendar.TUESDAY; break; case Calendar.FRIDAY: day_of_week = Calendar.TUESDAY; break; case Calendar.SATURDAY: day_of_week = Calendar.TUESDAY; break; case Calendar.SUNDAY: day_of_week = Calendar.TUESDAY; break; default: // TODO-[例外処理の実装] System.out.println("想定外の曜日です[day_of_week]: " + day_of_week); System.exit(-1); } // 日曜始まり=true, 月曜始まり=false if (isStartMon == false) { day_of_week = day_of_week < 7 ? day_of_week + 1 : 1; } return day_of_week; } }
いろんなパターンに対応できる様に先にコードだけ作りました。
関連ページ一覧
<家計簿アプリ作成>
- Eclipse アプリ作成 Lv1〜家計簿を作る準備〜
- Eclipse アプリ作成 Lv2〜家計簿を作る土台作り〜
- Eclipse アプリ作成 Lv3〜3Dグラフ用Cube作り〜
- Eclipse アプリ作成 Lv4〜3Dグラフ用Cubeに高さを与える〜
- Eclipse アプリ作成 Lv5〜惨敗:CubeにTextureを貼る〜
- Eclipse アプリ作成 Lv7〜Cubeを日付順に並べる
Java Basic
- Java Basic Level 1 〜Hello Java〜
- Java Basic Level2 〜Arithmetic Calculate〜
- Java Basic Level3 〜About String class〜
- Java Basic Level 4〜Boolean〜
- Java Basic Level 5〜If Statement〜
- Java Basic Summary from Level1 to 5
- Java Basic Level 6 〜Traning of If statement〜
- Java Basic Level8 〜How to use for statement〜
- Java Basic Level 8.5 〜Array〜
- Java Basic Level 9〜Training of for statement〜
- Java Basic Level 10 〜While statement 〜
- Java Basic Swing〜オブジェクト指向〜
- Java Basic Swing Level 2〜オブジェクト指向2〜
- サンプル実装〜コンソールゲーム〜
- Java Basic インターフェース・抽象クラスの作り方
- Java Basic クラスとは〜Step2_1〜
- Java Basic JUnit 〜テストスイートの作り方〜