質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.40%
Processing

Processingは、オープンソースプロジェクトによるCGのためのプログラミング言語です。Javaをベースにしており、グラフィック機能に特化しています。イメージの生成やアニメーションなど、視覚的なフィードバックを簡単に得ることが可能です。

Q&A

解決済

1回答

184閲覧

processingで記録を保存したい。

kain1270

総合スコア1

Processing

Processingは、オープンソースプロジェクトによるCGのためのプログラミング言語です。Javaをベースにしており、グラフィック機能に特化しています。イメージの生成やアニメーションなど、視覚的なフィードバックを簡単に得ることが可能です。

1グッド

0クリップ

投稿2024/07/10 07:23

実現したいこと

  • 記録を保存したい

前提

processingでタイマーアプリを作っているのですが、タイマーの記録が保存されません。一度停止したのちに起動するとタイマーの記録が0になってしまいます。エラーは出ていません。

該当のソースコード

processin

1ソースコード 2```PFont font; 3int currentScreen = 0; // 0:メニュー, 1:目標設定, 2:記録, 3:タイマー, 4:時間設定パネル 4boolean timerRunning = false; 5boolean timerStopped = false; 6int startTime, currentTime, totalTime; 7ArrayList<Integer> records = new ArrayList<Integer>(); 8 9int[] weeklyGoals = new int[7]; 10int[] dailyRecords = new int[7]; 11int currentDay = 0; // 仮の現在の曜日 12int selectedDay = -1; // 時間設定中の曜日 13String []days = {"月","火","水","木","金","土","日"}; 14 15void setup() { 16 size(480, 640); 17 font = createFont("Meiryo", 20); // メイリオフォントを使用 18 textFont(font); 19 20 loadRecords(); 21 loadGoals(); 22 updateCurrentDay(); // setup時に一度現在の曜日を取得 23 24} 25 26void draw() { 27 updateCurrentDay(); // 毎フレーム現在の曜日をチェックして更新 28 switch (currentScreen) { 29 case 0: 30 drawMenuScreen(); 31 break; 32 case 1: 33 drawGoalSettingScreen(); 34 break; 35 case 2: 36 drawRecordScreen(); 37 break; 38 case 3: 39 drawTimerScreen(); 40 break; 41 case 4: 42 drawTimeInputPanel(); 43 break; 44 } 45} 46 47void drawMenuScreen() { 48 background(220, 240, 255); 49 50 fill(0); 51 textAlign(CENTER); 52 textSize(24); 53 text("自習アプリ", width / 2, 50); 54 55 textSize(16); 56 fill(100, 150, 255); 57 rect(width / 2 - 100, 120, 200, 50, 10); 58 fill(0); 59 text("目標設定", width / 2, 150); 60 61 fill(100, 150, 255); 62 rect(width / 2 - 100, 220, 200, 50, 10); 63 fill(0); 64 text("記録", width / 2, 250); 65 66 fill(100, 150, 255); 67 rect(width / 2 - 100, 320, 200, 50, 10); 68 fill(0); 69 text("タイマー", width / 2, 350); 70} 71 72void drawGoalSettingScreen() { 73 background(255, 230, 230); 74 75 fill(0); 76 textAlign(LEFT); 77 textSize(24); 78 text("目標設定", 20, 50); 79 80 textSize(16); 81 for (int i = 0; i < 7; i++) { 82 fill(100, 150, 255); 83 rect(20, 100 + i * 70, 340, 50, 10); 84 fill(0); 85 textAlign(CENTER, CENTER-5); 86 text(days[i]+"曜日 " + ": " + convertToTime(weeklyGoals[i]), 90, 130 + i * 70); 87 88 // 時間設定ボタン 89 fill(150, 255, 150); 90 rect(370, 105 + i * 70, 90, 40, 10); 91 fill(0); 92 textAlign(CENTER, CENTER); 93 text("時間設定", 415, 125 + i * 70); 94 } 95 96 // メニューに戻るボタン 97 fill(100, 150, 255); 98 rect(width - 120, height - 50, 100, 30, 10); 99 fill(0); 100 textAlign(CENTER, CENTER); 101 text("メニュー", width - 70, height - 35); 102} 103 104void drawRecordScreen() { 105 background(230, 255, 230); // 淡い緑色の背景 106 107 fill(0); 108 textAlign(LEFT); 109 textSize(24); 110 text("記録", 20, 50); 111 112 textSize(16); 113 for (int i = 0; i < 7; i++) { 114 text(days[i] +"曜日 " + ": " + dailyRecords[i] + " 秒", 20, 100 + i * 50); 115 } 116 117 int totalRecordedTime = 0; 118 for (int i = 0; i < 7; i++) { 119 totalRecordedTime += dailyRecords[i]; 120 } 121 122 if (totalRecordedTime >= weeklyGoals[currentDay]) { 123 text("目標達成!", 20, 550); 124 } 125 126 // メニューに戻るボタン 127 fill(100, 150, 255); 128 rect(width - 120, height - 50, 100, 30, 10); 129 fill(0); 130 textAlign(CENTER, CENTER); 131 text("メニュー", width - 70, height - 35); 132} 133 134void drawTimerScreen() { 135 background(240, 240, 255); 136 137 fill(0); 138 textAlign(CENTER); 139 textSize(24); 140 text("タイマー", width / 2, 50); 141 142 if (timerRunning) { 143 currentTime = millis(); 144 } 145 146 textSize(48); 147 text((currentTime - startTime) / 1000 + " 秒", width / 2, height / 2); 148 149 textSize(16); 150 text("合計時間: " + totalTime / 1000 + " 秒", width / 2, height - 50); 151 152 // メニューに戻るボタン 153 fill(100, 150, 255); 154 rect(width - 120, height - 50, 100, 30, 10); 155 fill(0); 156 textAlign(CENTER, CENTER); 157 text("メニュー", width - 70, height - 35); 158} 159 160void drawTimeInputPanel() { 161 background(255); 162 163 fill(0); 164 textAlign(LEFT); 165 textSize(24); 166 text("時間設定", 20, 50); 167 168 textSize(16); 169 textAlign(CENTER, CENTER); 170 String[] buttons = { 171 "1", "2", "3", "4", "5", "6", "7", "8", "9", "0", "クリア", "設定" 172 }; 173 174 for (int i = 0; i < buttons.length; i++) { 175 int x = 20 + (i % 3) * 140; 176 int y = 100 + (i / 3) * 80; 177 fill(200, 200, 255); 178 rect(x, y, 120, 60, 10); 179 fill(0); 180 text(buttons[i], x + 60, y + 30); 181 } 182 183 // 現在の入力を表示 184 fill(0); 185 textAlign(LEFT); 186 textSize(20); 187 text("現在の入力: " + convertToTime(weeklyGoals[selectedDay]), 20, height - 100); 188 189 // メニューに戻るボタン 190 fill(100, 150, 255); 191 rect(width - 120, height - 50, 100, 30, 10); 192 fill(0); 193 textAlign(CENTER, CENTER); 194 text("戻る", width - 70, height - 35); 195} 196 197void mousePressed() { 198 switch (currentScreen) { 199 case 0: 200 if (mouseY > 120 && mouseY < 170) currentScreen = 1; 201 if (mouseY > 220 && mouseY < 270) currentScreen = 2; 202 if (mouseY > 320 && mouseY < 370) currentScreen = 3; 203 break; 204 case 1: 205 // 目標設定画面の操作 206 for (int i = 0; i < 7; i++) { 207 if (mouseY > 100 + i * 70 && mouseY < 150 + i * 70) { 208 if (mouseX > 370 && mouseX < 460) { 209 selectedDay = i; 210 currentScreen = 4; 211 } 212 } 213 } 214 // メニューに戻る 215 if (mouseX > width - 120 && mouseX < width - 20 && mouseY > height - 50 && mouseY < height - 20) { 216 saveGoals(); 217 currentScreen = 0; 218 } 219 break; 220 case 2: 221 // メニューに戻る 222 if (mouseX > width - 120 && mouseX < width - 20 && mouseY > height - 50 && mouseY < height - 20) { 223 saveRecords(); 224 currentScreen = 0; 225 } 226 break; 227 case 3: 228 // タイマー画面の操作 229 if (timerRunning) { 230 timerRunning = false; 231 timerStopped = true; 232 totalTime += currentTime - startTime; 233 records.add(currentTime - startTime); 234 dailyRecords[currentDay] += (currentTime - startTime) / 1000; 235 } else { 236 timerRunning = true; 237 timerStopped = false; 238 startTime = millis(); 239 } 240 // メニューに戻る 241 if (mouseX > width - 120 && mouseX < width - 20 && mouseY > height - 50 && mouseY < height - 20) { 242 saveRecords(); 243 currentScreen = 0; 244 timerRunning = false; 245 timerStopped = false; 246 startTime = 0; 247 currentTime = 0; 248 } 249 break; 250 case 4: 251 // 時間入力パネルの操作 252 String[] buttons = { 253 "1", "2", "3", "4", "5", "6", "7", "8", "9", "0", "クリア", "設定" 254 }; 255 for (int i = 0; i < buttons.length; i++) { 256 int x = 20 + (i % 3) * 140; 257 int y = 100 + (i / 3) * 80; 258 if (mouseX > x && mouseX < x + 120 && mouseY > y && mouseY < y + 60) { 259 if (buttons[i].equals("クリア")) { 260 weeklyGoals[selectedDay] = 0; 261 } else if (buttons[i].equals("設定")) { 262 currentScreen = 1; 263 } else { 264 int num = int(buttons[i]); 265 weeklyGoals[selectedDay] = weeklyGoals[selectedDay] * 10 + num * 3600; // 時間単位で加算 266 } 267 } 268 } 269 // メニューに戻る 270 if (mouseX > width - 120 && mouseX < width - 20 && mouseY > height - 50 && mouseY < height - 20) { 271 saveGoals(); 272 currentScreen = 1; 273 } 274 break; 275 } 276} 277 278// 秒を時間:分:秒の形式に変換する関数 279String convertToTime(int seconds) { 280 int hours = seconds / 3600; 281 int minutes = (seconds % 3600) / 60; 282 int secs = seconds % 60; 283 return nf(hours, 2) + ":" + nf(minutes, 2) + ":" + nf(secs, 2); 284} 285 286// 記録を保存する関数 287void saveRecords() { 288 Table table = new Table(); 289 table.addColumn("Day"); 290 table.addColumn("Seconds"); 291 292 for (int i = 0; i < 7; i++) { 293 TableRow row = table.addRow(); 294 row.setInt("Day", i); 295 row.setInt("Seconds", dailyRecords[i]); 296 } 297 298 saveTable(table, "records.csv"); 299} 300 301// 記録をロードする関数 302void loadRecords() { 303 Table table = loadTable("records.csv", "header"); 304 if (table == null) return; 305 306 for (TableRow row : table.rows()) { 307 int day = row.getInt("Day"); 308 int seconds = row.getInt("Seconds"); 309 dailyRecords[day] = seconds; 310 } 311} 312 313// 目標時間を保存する関数 314void saveGoals() { 315 Table table = new Table(); 316 table.addColumn("Day"); 317 table.addColumn("Seconds"); 318 319 for (int i = 0; i < 7; i++) { 320 TableRow row = table.addRow(); 321 row.setInt("Day", i); 322 row.setInt("Seconds", weeklyGoals[i]); 323 } 324 325 saveTable(table, "goals.csv"); 326} 327 328// 目標時間をロードする関数 329void loadGoals() { 330 Table table = loadTable("goals.csv", "header"); 331 if (table == null) return; 332 333 for (TableRow row : table.rows()) { 334 int day = row.getInt("Day"); 335 int seconds = row.getInt("Seconds"); 336 weeklyGoals[day] = seconds; 337 } 338} 339 340void updateCurrentDay() { 341 int newDay = (day() - 1) % 7; // 曜日は 0 (月曜日) から 6 (日曜日) 342 if (newDay != currentDay) { 343 currentDay = newDay; 344 saveRecords(); // 曜日が変わるときに記録を保存 345 dailyRecords[currentDay] = 0; // 新しい曜日の記録をリセット 346 } 347} 348
TN8001👍を押しています

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

guest

回答1

0

ベストアンサー

processingでタイマーアプリを作っているのですが、タイマーの記録が保存されません。

「タイマーの記録」とは、records.csvのことでしょうか。
保存されているかどうかはファイルを見れば一目瞭然ですよね(保存はされています)

一度停止したのちに起動するとタイマーの記録が0になってしまいます。

アプリを再起動すると「淡い緑色の背景画面」で、今日の曜日の記録がリセットされるということですね。

「記録をリセット」していそうなところは、updateCurrentDay()だけです。
currentDayを適切に初期化しておけばいいんじゃないですかね?(updateCurrentDay()内のnewDayも同様)

Processing

1//int currentDay = 0; // 仮の現在の曜日 2int currentDay = (java.util.Calendar.getInstance().get(java.util.Calendar.DAY_OF_WEEK) + 5) % 7;

Processingで曜日のデータを取得する | Free Style


Processingは毎フレームdrawが走るので、こういうデバッグに(表示が出すぎて)printlnは向かないです。

デバッガ(右上の虫みたいなボタン)の使い方を覚えましょう^^
processing pde デバッガ - Google 検索

投稿2024/07/10 10:28

編集2024/07/10 14:32
TN8001

総合スコア9640

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

TN8001

2024/07/10 10:31

仕様を完全には理解できていないので、それだけでいいのかは自信なし^^;
kain1270

2024/07/11 02:30

ちゃんと記録できました。 ありがとうございます。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.40%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問