Simple card game with updating GUI
$begingroup$
I have coded a simple card game that updates the GUI each second and contains many nodes in game which are used to display game events and animation.
People who have tried the game said that their system slows down and memory and CPU usage goes up (I was shocked when I saw from one of my friend's screen that it used around 1.4 GB RAM) is this supposed to happen?
I have checked some questions related to JavaFX memory usage problems but could not relate to my matter. In one article, I read that using many nodes in a JavaFX game might result in high memory usage.
In a short runtime:
minimum memory usage is around 100-250 MB
maximum memory usage is around 800-1200 MB
average memory usage is around 500-700 MB
IMPORTANT:
THERE ARE 100 BUTTONS IN A 10X10 GRIDPANE WHICH DO NOT HAVE FX IDS
In gameButtonClicked
matches are found buttons.indexOf(event.getSource())
UML DIAGRAM
Main.java
import javafx.application.Application;
import javafx.application.Platform;
import javafx.fxml.FXMLLoader;
import javafx.scene.Parent;
import javafx.scene.Scene;
import javafx.scene.media.Media;
import javafx.scene.media.MediaPlayer;
import javafx.stage.Stage;
import javafx.util.Duration;
import java.net.URL;
import java.util.ArrayList;
import java.util.Collections;
import java.util.HashMap;
import java.util.Random;
import java.util.concurrent.atomic.AtomicLong;
public class Main extends Application {
static boolean isMuted;
static Stage window;
static MediaPlayer mediaPlayerBGM;
static MediaPlayer mediaPlayerSFX;
private static HashMap<String, Media> sounds;
private static ArrayList<Long> usage;
private final String SOUND_LIST = {"bgm_credits.mp3", "bgm_game.mp3", "bgm_game_1.mp3", "bgm_game_2.mp3", "bgm_game_3.mp3",
"bgm_how_to.mp3", "bgm_menu.mp3", "bgm_victory.mp3", "sfx_button_clicked.wav",
"sfx_card_unfold.wav", "sfx_toggle.wav"
};
public static void main(String args) {
launch(args);
AtomicLong sum = new AtomicLong();
usage.forEach(sum::addAndGet);
long average = sum.get() / usage.size();
System.out.printf("minimum usage: %d, maximum usage: %d, average usage: %d",
Collections.min(usage), Collections.max(usage), average);
}
static void playBGM(String key) {
mediaPlayerBGM.stop();
mediaPlayerBGM.setStartTime(Duration.ZERO);
if (key.equals("bgm_game")) {
String suffix = {"", "_1", "_2", "_3"};
Random random = new Random();
mediaPlayerBGM = new MediaPlayer(sounds.get(key + suffix[random.nextInt(4)]));
} else {
mediaPlayerBGM = new MediaPlayer(sounds.get(key));
}
mediaPlayerBGM.setCycleCount(MediaPlayer.INDEFINITE);
if (isMuted) {
mediaPlayerBGM.setVolume(0.0);
}
mediaPlayerBGM.play();
}
static void playSFX(String key) {
if (mediaPlayerSFX != null) {
mediaPlayerSFX.stop();
}
mediaPlayerSFX = new MediaPlayer(sounds.get(key));
if (isMuted) {
mediaPlayerSFX.setVolume(0.0);
}
mediaPlayerSFX.play();
}
@Override
public void start(Stage primaryStage) throws Exception {
sounds = new HashMap<>();
usage = new ArrayList<>();
isMuted = false;
for (String soundName :
SOUND_LIST) {
URL resource = getClass().getResource("/" + soundName);
System.out.println(soundName);
System.out.println(resource.toString());
sounds.put(soundName.substring(0, soundName.lastIndexOf('.')), new Media(resource.toString()));
}
mediaPlayerBGM = new MediaPlayer(sounds.get("bgm_menu"));
mediaPlayerBGM.setCycleCount(MediaPlayer.INDEFINITE);
mediaPlayerBGM.play();
window = primaryStage;
Parent root = FXMLLoader.load(getClass().getResource("menu.fxml"));
// long running operation runs on different thread
Thread thread = new Thread(() -> {
Runnable updater = () -> {
if (!Game.isGameIsOver() && Game.getScore() != 0 && window.getTitle().equals("The Main Pick") &&
Game.firstClickHappened()) {
Game.scoreCalculator();
}
};
while (true) {
try {
usage.add(Runtime.getRuntime().totalMemory() - Runtime.getRuntime().freeMemory());
System.out.printf("Used memory: %dn", Runtime.getRuntime().totalMemory() - Runtime.getRuntime().freeMemory());
Thread.sleep(1000);
} catch (InterruptedException ex) {
System.out.println("Interrupted");
}
// UI update is run on the Application thread
Platform.runLater(updater);
}
});
// don't let thread prevent JVM shutdown
thread.setDaemon(true);
thread.start();
window.setTitle("Main Menu");
window.setScene(new Scene(root, 600, 600));
window.setResizable(false);
window.show();
}
}
Controller.java
package com.sample;
import javafx.animation.FadeTransition;
import javafx.collections.ObservableList;
import javafx.event.ActionEvent;
import javafx.fxml.FXML;
import javafx.fxml.FXMLLoader;
import javafx.scene.Node;
import javafx.scene.Parent;
import javafx.scene.Scene;
import javafx.scene.control.Button;
import javafx.scene.control.Label;
import javafx.scene.control.RadioButton;
import javafx.scene.layout.GridPane;
import javafx.util.Duration;
import java.io.IOException;
public class Controller
{
@FXML
public RadioButton musicOnOff;
@FXML
public Button newGame;
@FXML
public Button howTo;
@FXML
public Button credits;
@FXML
public Button exit;
@FXML
public Button menu;
@FXML
public GridPane pane;
@FXML
public Label score;
@FXML
public Label time;
@FXML
public Label tries;
private boolean animating;
public void initialize() {
if (score != null && time != null && tries != null) {
score.textProperty().bind(Game.scoreProperty);
time.textProperty().bind(Game.timeProperty);
tries.textProperty().bind(Game.triesProperty);
animating=false;
}
if (musicOnOff!=null){
if(Main.isMuted){
musicOnOff.setSelected(true);
}
}
}
public void newGameButtonClicked() {
try {
Main.playSFX("sfx_button_clicked");
new Game();
Main.window.hide();
Main.window.setScene(getScene("game"));
Main.window.setTitle("The Main Pick");
Main.window.setMaximized(true);
Main.playBGM("bgm_game");
Main.window.show();
} catch (IOException e) {
System.out.println("could not change the scene to: game");
}
}
public void menuButtonClicked() {
try {
Main.playSFX("sfx_button_clicked");
Main.playBGM("bgm_menu");
if (Main.window.getTitle().equals("The Main Pick")) {
Main.window.hide();
Game.setGameOver();
Main.window.setScene(getScene("menu"));
Main.window.setMaximized(false);
Main.window.show();
} else {
Main.window.setScene(getScene("menu"));
}
Main.window.setTitle("Main Menu");
} catch (IOException e) {
System.out.println("could not change the scene to: game");
}
}
public void gameButtonClicked(ActionEvent event) {
ObservableList<Node> buttons = pane.getChildren();
int index = buttons.indexOf(event.getSource());
int column = index % 10;
int row = (index - index % 10) / 10;
if (!((Button) event.getSource()).getStyleClass().toString().equals("button button-treasure") &&
!((Button) event.getSource()).getStyleClass().toString().equals("button button-uncovered"))
{
FadeTransition transition = new FadeTransition();
transition.setNode((Button) event.getSource());
transition.setDuration(new Duration(500));
transition.setFromValue(1.0);
transition.setToValue(0.0);
transition.setCycleCount(1);
transition.setOnFinished(actionEvent -> {
if (((Button) event.getSource()).getStyleClass().toString().equals("button button-treasure")) {
loadVictoryScene();
}
if (!((Button) event.getSource()).getStyleClass().toString().equals("button button-treasure") &&
!((Button) event.getSource()).getStyleClass().toString().equals("button button-uncovered"))
{
transition.setFromValue(0.0);
transition.setToValue(1.0);
System.out.println(((Button) event.getSource()).getStyleClass().toString());
((Button) event.getSource()).getStyleClass().remove("button-covered");
((Button) event.getSource()).getStyleClass().add(Game.click(row, column));
transition.play();
transition.setOnFinished(ActionEvent->animating=false);
}
});
System.out.println(animating);
if(!animating){
animating=true;
transition.play();
Main.playSFX("sfx_card_unfold");}
}
System.out.printf("button index:%d,row:%d,column:%dn", index, row, column);
}
public void howToPlayButtonClicked() {
try {
Main.playSFX("sfx_button_clicked");
Main.playBGM("bgm_how_to");
Main.window.setScene(getScene("howTo"));
Main.window.setTitle("How to Play");
} catch (IOException e) {
System.out.println("could not change the scene to: how to play");
}
}
public void creditsButtonClicked() {
try {
Main.playSFX("sfx_button_clicked");
Main.playBGM("bgm_credits");
Main.window.setScene(getScene("credits"));
Main.window.setTitle("Credits");
} catch (IOException e) {
System.out.println("could not change the scene to: credits");
}
}
public void exitButtonClicked() {
Main.playSFX("sfx_button_clicked");
Main.window.close();
}
public void musicOnOffRadioButtonChecked() {
Main.playSFX("sfx_toggle");
if (musicOnOff.isSelected()) {
Main.isMuted=true;
Main.mediaPlayerBGM.setVolume(0.0);
Main.mediaPlayerSFX.setVolume(0.0);
System.out.println("now selected");
} else {
Main.isMuted=false;
Main.mediaPlayerBGM.setVolume(1.0);
Main.mediaPlayerSFX.setVolume(1.0);
System.out.println("unselected");
}
}
private void loadVictoryScene() {
try {
Main.window.hide();
Main.playBGM("bgm_victory");
Main.window.setScene(getScene("victory"));
Main.window.setTitle("Victory");
Main.window.setMaximized(false);
Main.window.show();
} catch (IOException e) {
System.out.println("could not change the scene to: victory");
}
}
private Scene getScene(String name) throws IOException {
Parent root = FXMLLoader.load(getClass().getResource(name + ".fxml"));
if (name.equals("game")) {
return new Scene(root, 800, 800);
}
return new Scene(root, 600, 600);
}
}
Game.java
package com.sample;
import javafx.beans.property.SimpleStringProperty;
import javafx.beans.property.StringProperty;
import java.util.Random;
public class Game {
static StringProperty scoreProperty;
static StringProperty timeProperty;
static StringProperty triesProperty;
private static int time;
private static int score;
private static int tries;
private static int tiles;
private static boolean gameIsOver;
private static boolean firstClick;
public Game() {
System.out.println("Game created...");
tries = 0;
score = 100000;
time = 0;
gameIsOver = false;
firstClick = false;
scoreProperty = new SimpleStringProperty("" + score);
timeProperty = new SimpleStringProperty("0");
triesProperty = new SimpleStringProperty("0");
tiles = new int[10][10];
Random random = new Random();
int treasureColumn = random.nextInt(10);
int treasureRow = random.nextInt(10);
tiles[treasureRow][treasureColumn] = 1;
}
static boolean firstClickHappened() {
return firstClick;
}
static void setGameOver() {
gameIsOver = true;
}
static boolean isGameIsOver() {
return gameIsOver;
}
static int getScore() {
return score;
}
static void scoreCalculator() {
time++;
if (time < 10) {
score = score - 100;
} else if (time < 20) {
score = score - 200;
} else if (time < 30) {
score = score - 300;
} else if (time < 50) {
score = score - 500;
} else {
score = score - 1000;
}
if (score < 0) {
score = 0;
}
scoreProperty.setValue("" + score);
timeProperty.setValue("" + time);
triesProperty.setValue("" + tries);
System.out.printf("Score:%s,Time:%s,Tries%sn", scoreProperty.getValue(), timeProperty.getValue(), triesProperty.getValue());
}
static String click(int row, int column) {
if (!firstClickHappened()) firstClick = true;
System.out.println(row + "," + column);
int clickValue = tiles[row][column];
System.out.println(clickValue);
if (clickValue == 0) {
tries++;
score -= 1000;
} else {
setGameOver();
}
return (clickValue == 1) ? "button-treasure" : "button-uncovered";
}
}
java javafx
New contributor
$endgroup$
add a comment |
$begingroup$
I have coded a simple card game that updates the GUI each second and contains many nodes in game which are used to display game events and animation.
People who have tried the game said that their system slows down and memory and CPU usage goes up (I was shocked when I saw from one of my friend's screen that it used around 1.4 GB RAM) is this supposed to happen?
I have checked some questions related to JavaFX memory usage problems but could not relate to my matter. In one article, I read that using many nodes in a JavaFX game might result in high memory usage.
In a short runtime:
minimum memory usage is around 100-250 MB
maximum memory usage is around 800-1200 MB
average memory usage is around 500-700 MB
IMPORTANT:
THERE ARE 100 BUTTONS IN A 10X10 GRIDPANE WHICH DO NOT HAVE FX IDS
In gameButtonClicked
matches are found buttons.indexOf(event.getSource())
UML DIAGRAM
Main.java
import javafx.application.Application;
import javafx.application.Platform;
import javafx.fxml.FXMLLoader;
import javafx.scene.Parent;
import javafx.scene.Scene;
import javafx.scene.media.Media;
import javafx.scene.media.MediaPlayer;
import javafx.stage.Stage;
import javafx.util.Duration;
import java.net.URL;
import java.util.ArrayList;
import java.util.Collections;
import java.util.HashMap;
import java.util.Random;
import java.util.concurrent.atomic.AtomicLong;
public class Main extends Application {
static boolean isMuted;
static Stage window;
static MediaPlayer mediaPlayerBGM;
static MediaPlayer mediaPlayerSFX;
private static HashMap<String, Media> sounds;
private static ArrayList<Long> usage;
private final String SOUND_LIST = {"bgm_credits.mp3", "bgm_game.mp3", "bgm_game_1.mp3", "bgm_game_2.mp3", "bgm_game_3.mp3",
"bgm_how_to.mp3", "bgm_menu.mp3", "bgm_victory.mp3", "sfx_button_clicked.wav",
"sfx_card_unfold.wav", "sfx_toggle.wav"
};
public static void main(String args) {
launch(args);
AtomicLong sum = new AtomicLong();
usage.forEach(sum::addAndGet);
long average = sum.get() / usage.size();
System.out.printf("minimum usage: %d, maximum usage: %d, average usage: %d",
Collections.min(usage), Collections.max(usage), average);
}
static void playBGM(String key) {
mediaPlayerBGM.stop();
mediaPlayerBGM.setStartTime(Duration.ZERO);
if (key.equals("bgm_game")) {
String suffix = {"", "_1", "_2", "_3"};
Random random = new Random();
mediaPlayerBGM = new MediaPlayer(sounds.get(key + suffix[random.nextInt(4)]));
} else {
mediaPlayerBGM = new MediaPlayer(sounds.get(key));
}
mediaPlayerBGM.setCycleCount(MediaPlayer.INDEFINITE);
if (isMuted) {
mediaPlayerBGM.setVolume(0.0);
}
mediaPlayerBGM.play();
}
static void playSFX(String key) {
if (mediaPlayerSFX != null) {
mediaPlayerSFX.stop();
}
mediaPlayerSFX = new MediaPlayer(sounds.get(key));
if (isMuted) {
mediaPlayerSFX.setVolume(0.0);
}
mediaPlayerSFX.play();
}
@Override
public void start(Stage primaryStage) throws Exception {
sounds = new HashMap<>();
usage = new ArrayList<>();
isMuted = false;
for (String soundName :
SOUND_LIST) {
URL resource = getClass().getResource("/" + soundName);
System.out.println(soundName);
System.out.println(resource.toString());
sounds.put(soundName.substring(0, soundName.lastIndexOf('.')), new Media(resource.toString()));
}
mediaPlayerBGM = new MediaPlayer(sounds.get("bgm_menu"));
mediaPlayerBGM.setCycleCount(MediaPlayer.INDEFINITE);
mediaPlayerBGM.play();
window = primaryStage;
Parent root = FXMLLoader.load(getClass().getResource("menu.fxml"));
// long running operation runs on different thread
Thread thread = new Thread(() -> {
Runnable updater = () -> {
if (!Game.isGameIsOver() && Game.getScore() != 0 && window.getTitle().equals("The Main Pick") &&
Game.firstClickHappened()) {
Game.scoreCalculator();
}
};
while (true) {
try {
usage.add(Runtime.getRuntime().totalMemory() - Runtime.getRuntime().freeMemory());
System.out.printf("Used memory: %dn", Runtime.getRuntime().totalMemory() - Runtime.getRuntime().freeMemory());
Thread.sleep(1000);
} catch (InterruptedException ex) {
System.out.println("Interrupted");
}
// UI update is run on the Application thread
Platform.runLater(updater);
}
});
// don't let thread prevent JVM shutdown
thread.setDaemon(true);
thread.start();
window.setTitle("Main Menu");
window.setScene(new Scene(root, 600, 600));
window.setResizable(false);
window.show();
}
}
Controller.java
package com.sample;
import javafx.animation.FadeTransition;
import javafx.collections.ObservableList;
import javafx.event.ActionEvent;
import javafx.fxml.FXML;
import javafx.fxml.FXMLLoader;
import javafx.scene.Node;
import javafx.scene.Parent;
import javafx.scene.Scene;
import javafx.scene.control.Button;
import javafx.scene.control.Label;
import javafx.scene.control.RadioButton;
import javafx.scene.layout.GridPane;
import javafx.util.Duration;
import java.io.IOException;
public class Controller
{
@FXML
public RadioButton musicOnOff;
@FXML
public Button newGame;
@FXML
public Button howTo;
@FXML
public Button credits;
@FXML
public Button exit;
@FXML
public Button menu;
@FXML
public GridPane pane;
@FXML
public Label score;
@FXML
public Label time;
@FXML
public Label tries;
private boolean animating;
public void initialize() {
if (score != null && time != null && tries != null) {
score.textProperty().bind(Game.scoreProperty);
time.textProperty().bind(Game.timeProperty);
tries.textProperty().bind(Game.triesProperty);
animating=false;
}
if (musicOnOff!=null){
if(Main.isMuted){
musicOnOff.setSelected(true);
}
}
}
public void newGameButtonClicked() {
try {
Main.playSFX("sfx_button_clicked");
new Game();
Main.window.hide();
Main.window.setScene(getScene("game"));
Main.window.setTitle("The Main Pick");
Main.window.setMaximized(true);
Main.playBGM("bgm_game");
Main.window.show();
} catch (IOException e) {
System.out.println("could not change the scene to: game");
}
}
public void menuButtonClicked() {
try {
Main.playSFX("sfx_button_clicked");
Main.playBGM("bgm_menu");
if (Main.window.getTitle().equals("The Main Pick")) {
Main.window.hide();
Game.setGameOver();
Main.window.setScene(getScene("menu"));
Main.window.setMaximized(false);
Main.window.show();
} else {
Main.window.setScene(getScene("menu"));
}
Main.window.setTitle("Main Menu");
} catch (IOException e) {
System.out.println("could not change the scene to: game");
}
}
public void gameButtonClicked(ActionEvent event) {
ObservableList<Node> buttons = pane.getChildren();
int index = buttons.indexOf(event.getSource());
int column = index % 10;
int row = (index - index % 10) / 10;
if (!((Button) event.getSource()).getStyleClass().toString().equals("button button-treasure") &&
!((Button) event.getSource()).getStyleClass().toString().equals("button button-uncovered"))
{
FadeTransition transition = new FadeTransition();
transition.setNode((Button) event.getSource());
transition.setDuration(new Duration(500));
transition.setFromValue(1.0);
transition.setToValue(0.0);
transition.setCycleCount(1);
transition.setOnFinished(actionEvent -> {
if (((Button) event.getSource()).getStyleClass().toString().equals("button button-treasure")) {
loadVictoryScene();
}
if (!((Button) event.getSource()).getStyleClass().toString().equals("button button-treasure") &&
!((Button) event.getSource()).getStyleClass().toString().equals("button button-uncovered"))
{
transition.setFromValue(0.0);
transition.setToValue(1.0);
System.out.println(((Button) event.getSource()).getStyleClass().toString());
((Button) event.getSource()).getStyleClass().remove("button-covered");
((Button) event.getSource()).getStyleClass().add(Game.click(row, column));
transition.play();
transition.setOnFinished(ActionEvent->animating=false);
}
});
System.out.println(animating);
if(!animating){
animating=true;
transition.play();
Main.playSFX("sfx_card_unfold");}
}
System.out.printf("button index:%d,row:%d,column:%dn", index, row, column);
}
public void howToPlayButtonClicked() {
try {
Main.playSFX("sfx_button_clicked");
Main.playBGM("bgm_how_to");
Main.window.setScene(getScene("howTo"));
Main.window.setTitle("How to Play");
} catch (IOException e) {
System.out.println("could not change the scene to: how to play");
}
}
public void creditsButtonClicked() {
try {
Main.playSFX("sfx_button_clicked");
Main.playBGM("bgm_credits");
Main.window.setScene(getScene("credits"));
Main.window.setTitle("Credits");
} catch (IOException e) {
System.out.println("could not change the scene to: credits");
}
}
public void exitButtonClicked() {
Main.playSFX("sfx_button_clicked");
Main.window.close();
}
public void musicOnOffRadioButtonChecked() {
Main.playSFX("sfx_toggle");
if (musicOnOff.isSelected()) {
Main.isMuted=true;
Main.mediaPlayerBGM.setVolume(0.0);
Main.mediaPlayerSFX.setVolume(0.0);
System.out.println("now selected");
} else {
Main.isMuted=false;
Main.mediaPlayerBGM.setVolume(1.0);
Main.mediaPlayerSFX.setVolume(1.0);
System.out.println("unselected");
}
}
private void loadVictoryScene() {
try {
Main.window.hide();
Main.playBGM("bgm_victory");
Main.window.setScene(getScene("victory"));
Main.window.setTitle("Victory");
Main.window.setMaximized(false);
Main.window.show();
} catch (IOException e) {
System.out.println("could not change the scene to: victory");
}
}
private Scene getScene(String name) throws IOException {
Parent root = FXMLLoader.load(getClass().getResource(name + ".fxml"));
if (name.equals("game")) {
return new Scene(root, 800, 800);
}
return new Scene(root, 600, 600);
}
}
Game.java
package com.sample;
import javafx.beans.property.SimpleStringProperty;
import javafx.beans.property.StringProperty;
import java.util.Random;
public class Game {
static StringProperty scoreProperty;
static StringProperty timeProperty;
static StringProperty triesProperty;
private static int time;
private static int score;
private static int tries;
private static int tiles;
private static boolean gameIsOver;
private static boolean firstClick;
public Game() {
System.out.println("Game created...");
tries = 0;
score = 100000;
time = 0;
gameIsOver = false;
firstClick = false;
scoreProperty = new SimpleStringProperty("" + score);
timeProperty = new SimpleStringProperty("0");
triesProperty = new SimpleStringProperty("0");
tiles = new int[10][10];
Random random = new Random();
int treasureColumn = random.nextInt(10);
int treasureRow = random.nextInt(10);
tiles[treasureRow][treasureColumn] = 1;
}
static boolean firstClickHappened() {
return firstClick;
}
static void setGameOver() {
gameIsOver = true;
}
static boolean isGameIsOver() {
return gameIsOver;
}
static int getScore() {
return score;
}
static void scoreCalculator() {
time++;
if (time < 10) {
score = score - 100;
} else if (time < 20) {
score = score - 200;
} else if (time < 30) {
score = score - 300;
} else if (time < 50) {
score = score - 500;
} else {
score = score - 1000;
}
if (score < 0) {
score = 0;
}
scoreProperty.setValue("" + score);
timeProperty.setValue("" + time);
triesProperty.setValue("" + tries);
System.out.printf("Score:%s,Time:%s,Tries%sn", scoreProperty.getValue(), timeProperty.getValue(), triesProperty.getValue());
}
static String click(int row, int column) {
if (!firstClickHappened()) firstClick = true;
System.out.println(row + "," + column);
int clickValue = tiles[row][column];
System.out.println(clickValue);
if (clickValue == 0) {
tries++;
score -= 1000;
} else {
setGameOver();
}
return (clickValue == 1) ? "button-treasure" : "button-uncovered";
}
}
java javafx
New contributor
$endgroup$
$begingroup$
What is your definition of "adequate resources"?
$endgroup$
– Mast
9 hours ago
$begingroup$
@Mast I am a second year cs student so I do not know many things about performance stuff, by adequate I mean for example calculating the sum of positive integers 5-10 can be easily done with a loop and will require less time and processing(?) but doing it recursively will require more time and processing; so maybe "optimum values"?
$endgroup$
– Altuğ Ceylan
8 hours ago
add a comment |
$begingroup$
I have coded a simple card game that updates the GUI each second and contains many nodes in game which are used to display game events and animation.
People who have tried the game said that their system slows down and memory and CPU usage goes up (I was shocked when I saw from one of my friend's screen that it used around 1.4 GB RAM) is this supposed to happen?
I have checked some questions related to JavaFX memory usage problems but could not relate to my matter. In one article, I read that using many nodes in a JavaFX game might result in high memory usage.
In a short runtime:
minimum memory usage is around 100-250 MB
maximum memory usage is around 800-1200 MB
average memory usage is around 500-700 MB
IMPORTANT:
THERE ARE 100 BUTTONS IN A 10X10 GRIDPANE WHICH DO NOT HAVE FX IDS
In gameButtonClicked
matches are found buttons.indexOf(event.getSource())
UML DIAGRAM
Main.java
import javafx.application.Application;
import javafx.application.Platform;
import javafx.fxml.FXMLLoader;
import javafx.scene.Parent;
import javafx.scene.Scene;
import javafx.scene.media.Media;
import javafx.scene.media.MediaPlayer;
import javafx.stage.Stage;
import javafx.util.Duration;
import java.net.URL;
import java.util.ArrayList;
import java.util.Collections;
import java.util.HashMap;
import java.util.Random;
import java.util.concurrent.atomic.AtomicLong;
public class Main extends Application {
static boolean isMuted;
static Stage window;
static MediaPlayer mediaPlayerBGM;
static MediaPlayer mediaPlayerSFX;
private static HashMap<String, Media> sounds;
private static ArrayList<Long> usage;
private final String SOUND_LIST = {"bgm_credits.mp3", "bgm_game.mp3", "bgm_game_1.mp3", "bgm_game_2.mp3", "bgm_game_3.mp3",
"bgm_how_to.mp3", "bgm_menu.mp3", "bgm_victory.mp3", "sfx_button_clicked.wav",
"sfx_card_unfold.wav", "sfx_toggle.wav"
};
public static void main(String args) {
launch(args);
AtomicLong sum = new AtomicLong();
usage.forEach(sum::addAndGet);
long average = sum.get() / usage.size();
System.out.printf("minimum usage: %d, maximum usage: %d, average usage: %d",
Collections.min(usage), Collections.max(usage), average);
}
static void playBGM(String key) {
mediaPlayerBGM.stop();
mediaPlayerBGM.setStartTime(Duration.ZERO);
if (key.equals("bgm_game")) {
String suffix = {"", "_1", "_2", "_3"};
Random random = new Random();
mediaPlayerBGM = new MediaPlayer(sounds.get(key + suffix[random.nextInt(4)]));
} else {
mediaPlayerBGM = new MediaPlayer(sounds.get(key));
}
mediaPlayerBGM.setCycleCount(MediaPlayer.INDEFINITE);
if (isMuted) {
mediaPlayerBGM.setVolume(0.0);
}
mediaPlayerBGM.play();
}
static void playSFX(String key) {
if (mediaPlayerSFX != null) {
mediaPlayerSFX.stop();
}
mediaPlayerSFX = new MediaPlayer(sounds.get(key));
if (isMuted) {
mediaPlayerSFX.setVolume(0.0);
}
mediaPlayerSFX.play();
}
@Override
public void start(Stage primaryStage) throws Exception {
sounds = new HashMap<>();
usage = new ArrayList<>();
isMuted = false;
for (String soundName :
SOUND_LIST) {
URL resource = getClass().getResource("/" + soundName);
System.out.println(soundName);
System.out.println(resource.toString());
sounds.put(soundName.substring(0, soundName.lastIndexOf('.')), new Media(resource.toString()));
}
mediaPlayerBGM = new MediaPlayer(sounds.get("bgm_menu"));
mediaPlayerBGM.setCycleCount(MediaPlayer.INDEFINITE);
mediaPlayerBGM.play();
window = primaryStage;
Parent root = FXMLLoader.load(getClass().getResource("menu.fxml"));
// long running operation runs on different thread
Thread thread = new Thread(() -> {
Runnable updater = () -> {
if (!Game.isGameIsOver() && Game.getScore() != 0 && window.getTitle().equals("The Main Pick") &&
Game.firstClickHappened()) {
Game.scoreCalculator();
}
};
while (true) {
try {
usage.add(Runtime.getRuntime().totalMemory() - Runtime.getRuntime().freeMemory());
System.out.printf("Used memory: %dn", Runtime.getRuntime().totalMemory() - Runtime.getRuntime().freeMemory());
Thread.sleep(1000);
} catch (InterruptedException ex) {
System.out.println("Interrupted");
}
// UI update is run on the Application thread
Platform.runLater(updater);
}
});
// don't let thread prevent JVM shutdown
thread.setDaemon(true);
thread.start();
window.setTitle("Main Menu");
window.setScene(new Scene(root, 600, 600));
window.setResizable(false);
window.show();
}
}
Controller.java
package com.sample;
import javafx.animation.FadeTransition;
import javafx.collections.ObservableList;
import javafx.event.ActionEvent;
import javafx.fxml.FXML;
import javafx.fxml.FXMLLoader;
import javafx.scene.Node;
import javafx.scene.Parent;
import javafx.scene.Scene;
import javafx.scene.control.Button;
import javafx.scene.control.Label;
import javafx.scene.control.RadioButton;
import javafx.scene.layout.GridPane;
import javafx.util.Duration;
import java.io.IOException;
public class Controller
{
@FXML
public RadioButton musicOnOff;
@FXML
public Button newGame;
@FXML
public Button howTo;
@FXML
public Button credits;
@FXML
public Button exit;
@FXML
public Button menu;
@FXML
public GridPane pane;
@FXML
public Label score;
@FXML
public Label time;
@FXML
public Label tries;
private boolean animating;
public void initialize() {
if (score != null && time != null && tries != null) {
score.textProperty().bind(Game.scoreProperty);
time.textProperty().bind(Game.timeProperty);
tries.textProperty().bind(Game.triesProperty);
animating=false;
}
if (musicOnOff!=null){
if(Main.isMuted){
musicOnOff.setSelected(true);
}
}
}
public void newGameButtonClicked() {
try {
Main.playSFX("sfx_button_clicked");
new Game();
Main.window.hide();
Main.window.setScene(getScene("game"));
Main.window.setTitle("The Main Pick");
Main.window.setMaximized(true);
Main.playBGM("bgm_game");
Main.window.show();
} catch (IOException e) {
System.out.println("could not change the scene to: game");
}
}
public void menuButtonClicked() {
try {
Main.playSFX("sfx_button_clicked");
Main.playBGM("bgm_menu");
if (Main.window.getTitle().equals("The Main Pick")) {
Main.window.hide();
Game.setGameOver();
Main.window.setScene(getScene("menu"));
Main.window.setMaximized(false);
Main.window.show();
} else {
Main.window.setScene(getScene("menu"));
}
Main.window.setTitle("Main Menu");
} catch (IOException e) {
System.out.println("could not change the scene to: game");
}
}
public void gameButtonClicked(ActionEvent event) {
ObservableList<Node> buttons = pane.getChildren();
int index = buttons.indexOf(event.getSource());
int column = index % 10;
int row = (index - index % 10) / 10;
if (!((Button) event.getSource()).getStyleClass().toString().equals("button button-treasure") &&
!((Button) event.getSource()).getStyleClass().toString().equals("button button-uncovered"))
{
FadeTransition transition = new FadeTransition();
transition.setNode((Button) event.getSource());
transition.setDuration(new Duration(500));
transition.setFromValue(1.0);
transition.setToValue(0.0);
transition.setCycleCount(1);
transition.setOnFinished(actionEvent -> {
if (((Button) event.getSource()).getStyleClass().toString().equals("button button-treasure")) {
loadVictoryScene();
}
if (!((Button) event.getSource()).getStyleClass().toString().equals("button button-treasure") &&
!((Button) event.getSource()).getStyleClass().toString().equals("button button-uncovered"))
{
transition.setFromValue(0.0);
transition.setToValue(1.0);
System.out.println(((Button) event.getSource()).getStyleClass().toString());
((Button) event.getSource()).getStyleClass().remove("button-covered");
((Button) event.getSource()).getStyleClass().add(Game.click(row, column));
transition.play();
transition.setOnFinished(ActionEvent->animating=false);
}
});
System.out.println(animating);
if(!animating){
animating=true;
transition.play();
Main.playSFX("sfx_card_unfold");}
}
System.out.printf("button index:%d,row:%d,column:%dn", index, row, column);
}
public void howToPlayButtonClicked() {
try {
Main.playSFX("sfx_button_clicked");
Main.playBGM("bgm_how_to");
Main.window.setScene(getScene("howTo"));
Main.window.setTitle("How to Play");
} catch (IOException e) {
System.out.println("could not change the scene to: how to play");
}
}
public void creditsButtonClicked() {
try {
Main.playSFX("sfx_button_clicked");
Main.playBGM("bgm_credits");
Main.window.setScene(getScene("credits"));
Main.window.setTitle("Credits");
} catch (IOException e) {
System.out.println("could not change the scene to: credits");
}
}
public void exitButtonClicked() {
Main.playSFX("sfx_button_clicked");
Main.window.close();
}
public void musicOnOffRadioButtonChecked() {
Main.playSFX("sfx_toggle");
if (musicOnOff.isSelected()) {
Main.isMuted=true;
Main.mediaPlayerBGM.setVolume(0.0);
Main.mediaPlayerSFX.setVolume(0.0);
System.out.println("now selected");
} else {
Main.isMuted=false;
Main.mediaPlayerBGM.setVolume(1.0);
Main.mediaPlayerSFX.setVolume(1.0);
System.out.println("unselected");
}
}
private void loadVictoryScene() {
try {
Main.window.hide();
Main.playBGM("bgm_victory");
Main.window.setScene(getScene("victory"));
Main.window.setTitle("Victory");
Main.window.setMaximized(false);
Main.window.show();
} catch (IOException e) {
System.out.println("could not change the scene to: victory");
}
}
private Scene getScene(String name) throws IOException {
Parent root = FXMLLoader.load(getClass().getResource(name + ".fxml"));
if (name.equals("game")) {
return new Scene(root, 800, 800);
}
return new Scene(root, 600, 600);
}
}
Game.java
package com.sample;
import javafx.beans.property.SimpleStringProperty;
import javafx.beans.property.StringProperty;
import java.util.Random;
public class Game {
static StringProperty scoreProperty;
static StringProperty timeProperty;
static StringProperty triesProperty;
private static int time;
private static int score;
private static int tries;
private static int tiles;
private static boolean gameIsOver;
private static boolean firstClick;
public Game() {
System.out.println("Game created...");
tries = 0;
score = 100000;
time = 0;
gameIsOver = false;
firstClick = false;
scoreProperty = new SimpleStringProperty("" + score);
timeProperty = new SimpleStringProperty("0");
triesProperty = new SimpleStringProperty("0");
tiles = new int[10][10];
Random random = new Random();
int treasureColumn = random.nextInt(10);
int treasureRow = random.nextInt(10);
tiles[treasureRow][treasureColumn] = 1;
}
static boolean firstClickHappened() {
return firstClick;
}
static void setGameOver() {
gameIsOver = true;
}
static boolean isGameIsOver() {
return gameIsOver;
}
static int getScore() {
return score;
}
static void scoreCalculator() {
time++;
if (time < 10) {
score = score - 100;
} else if (time < 20) {
score = score - 200;
} else if (time < 30) {
score = score - 300;
} else if (time < 50) {
score = score - 500;
} else {
score = score - 1000;
}
if (score < 0) {
score = 0;
}
scoreProperty.setValue("" + score);
timeProperty.setValue("" + time);
triesProperty.setValue("" + tries);
System.out.printf("Score:%s,Time:%s,Tries%sn", scoreProperty.getValue(), timeProperty.getValue(), triesProperty.getValue());
}
static String click(int row, int column) {
if (!firstClickHappened()) firstClick = true;
System.out.println(row + "," + column);
int clickValue = tiles[row][column];
System.out.println(clickValue);
if (clickValue == 0) {
tries++;
score -= 1000;
} else {
setGameOver();
}
return (clickValue == 1) ? "button-treasure" : "button-uncovered";
}
}
java javafx
New contributor
$endgroup$
I have coded a simple card game that updates the GUI each second and contains many nodes in game which are used to display game events and animation.
People who have tried the game said that their system slows down and memory and CPU usage goes up (I was shocked when I saw from one of my friend's screen that it used around 1.4 GB RAM) is this supposed to happen?
I have checked some questions related to JavaFX memory usage problems but could not relate to my matter. In one article, I read that using many nodes in a JavaFX game might result in high memory usage.
In a short runtime:
minimum memory usage is around 100-250 MB
maximum memory usage is around 800-1200 MB
average memory usage is around 500-700 MB
IMPORTANT:
THERE ARE 100 BUTTONS IN A 10X10 GRIDPANE WHICH DO NOT HAVE FX IDS
In gameButtonClicked
matches are found buttons.indexOf(event.getSource())
UML DIAGRAM
Main.java
import javafx.application.Application;
import javafx.application.Platform;
import javafx.fxml.FXMLLoader;
import javafx.scene.Parent;
import javafx.scene.Scene;
import javafx.scene.media.Media;
import javafx.scene.media.MediaPlayer;
import javafx.stage.Stage;
import javafx.util.Duration;
import java.net.URL;
import java.util.ArrayList;
import java.util.Collections;
import java.util.HashMap;
import java.util.Random;
import java.util.concurrent.atomic.AtomicLong;
public class Main extends Application {
static boolean isMuted;
static Stage window;
static MediaPlayer mediaPlayerBGM;
static MediaPlayer mediaPlayerSFX;
private static HashMap<String, Media> sounds;
private static ArrayList<Long> usage;
private final String SOUND_LIST = {"bgm_credits.mp3", "bgm_game.mp3", "bgm_game_1.mp3", "bgm_game_2.mp3", "bgm_game_3.mp3",
"bgm_how_to.mp3", "bgm_menu.mp3", "bgm_victory.mp3", "sfx_button_clicked.wav",
"sfx_card_unfold.wav", "sfx_toggle.wav"
};
public static void main(String args) {
launch(args);
AtomicLong sum = new AtomicLong();
usage.forEach(sum::addAndGet);
long average = sum.get() / usage.size();
System.out.printf("minimum usage: %d, maximum usage: %d, average usage: %d",
Collections.min(usage), Collections.max(usage), average);
}
static void playBGM(String key) {
mediaPlayerBGM.stop();
mediaPlayerBGM.setStartTime(Duration.ZERO);
if (key.equals("bgm_game")) {
String suffix = {"", "_1", "_2", "_3"};
Random random = new Random();
mediaPlayerBGM = new MediaPlayer(sounds.get(key + suffix[random.nextInt(4)]));
} else {
mediaPlayerBGM = new MediaPlayer(sounds.get(key));
}
mediaPlayerBGM.setCycleCount(MediaPlayer.INDEFINITE);
if (isMuted) {
mediaPlayerBGM.setVolume(0.0);
}
mediaPlayerBGM.play();
}
static void playSFX(String key) {
if (mediaPlayerSFX != null) {
mediaPlayerSFX.stop();
}
mediaPlayerSFX = new MediaPlayer(sounds.get(key));
if (isMuted) {
mediaPlayerSFX.setVolume(0.0);
}
mediaPlayerSFX.play();
}
@Override
public void start(Stage primaryStage) throws Exception {
sounds = new HashMap<>();
usage = new ArrayList<>();
isMuted = false;
for (String soundName :
SOUND_LIST) {
URL resource = getClass().getResource("/" + soundName);
System.out.println(soundName);
System.out.println(resource.toString());
sounds.put(soundName.substring(0, soundName.lastIndexOf('.')), new Media(resource.toString()));
}
mediaPlayerBGM = new MediaPlayer(sounds.get("bgm_menu"));
mediaPlayerBGM.setCycleCount(MediaPlayer.INDEFINITE);
mediaPlayerBGM.play();
window = primaryStage;
Parent root = FXMLLoader.load(getClass().getResource("menu.fxml"));
// long running operation runs on different thread
Thread thread = new Thread(() -> {
Runnable updater = () -> {
if (!Game.isGameIsOver() && Game.getScore() != 0 && window.getTitle().equals("The Main Pick") &&
Game.firstClickHappened()) {
Game.scoreCalculator();
}
};
while (true) {
try {
usage.add(Runtime.getRuntime().totalMemory() - Runtime.getRuntime().freeMemory());
System.out.printf("Used memory: %dn", Runtime.getRuntime().totalMemory() - Runtime.getRuntime().freeMemory());
Thread.sleep(1000);
} catch (InterruptedException ex) {
System.out.println("Interrupted");
}
// UI update is run on the Application thread
Platform.runLater(updater);
}
});
// don't let thread prevent JVM shutdown
thread.setDaemon(true);
thread.start();
window.setTitle("Main Menu");
window.setScene(new Scene(root, 600, 600));
window.setResizable(false);
window.show();
}
}
Controller.java
package com.sample;
import javafx.animation.FadeTransition;
import javafx.collections.ObservableList;
import javafx.event.ActionEvent;
import javafx.fxml.FXML;
import javafx.fxml.FXMLLoader;
import javafx.scene.Node;
import javafx.scene.Parent;
import javafx.scene.Scene;
import javafx.scene.control.Button;
import javafx.scene.control.Label;
import javafx.scene.control.RadioButton;
import javafx.scene.layout.GridPane;
import javafx.util.Duration;
import java.io.IOException;
public class Controller
{
@FXML
public RadioButton musicOnOff;
@FXML
public Button newGame;
@FXML
public Button howTo;
@FXML
public Button credits;
@FXML
public Button exit;
@FXML
public Button menu;
@FXML
public GridPane pane;
@FXML
public Label score;
@FXML
public Label time;
@FXML
public Label tries;
private boolean animating;
public void initialize() {
if (score != null && time != null && tries != null) {
score.textProperty().bind(Game.scoreProperty);
time.textProperty().bind(Game.timeProperty);
tries.textProperty().bind(Game.triesProperty);
animating=false;
}
if (musicOnOff!=null){
if(Main.isMuted){
musicOnOff.setSelected(true);
}
}
}
public void newGameButtonClicked() {
try {
Main.playSFX("sfx_button_clicked");
new Game();
Main.window.hide();
Main.window.setScene(getScene("game"));
Main.window.setTitle("The Main Pick");
Main.window.setMaximized(true);
Main.playBGM("bgm_game");
Main.window.show();
} catch (IOException e) {
System.out.println("could not change the scene to: game");
}
}
public void menuButtonClicked() {
try {
Main.playSFX("sfx_button_clicked");
Main.playBGM("bgm_menu");
if (Main.window.getTitle().equals("The Main Pick")) {
Main.window.hide();
Game.setGameOver();
Main.window.setScene(getScene("menu"));
Main.window.setMaximized(false);
Main.window.show();
} else {
Main.window.setScene(getScene("menu"));
}
Main.window.setTitle("Main Menu");
} catch (IOException e) {
System.out.println("could not change the scene to: game");
}
}
public void gameButtonClicked(ActionEvent event) {
ObservableList<Node> buttons = pane.getChildren();
int index = buttons.indexOf(event.getSource());
int column = index % 10;
int row = (index - index % 10) / 10;
if (!((Button) event.getSource()).getStyleClass().toString().equals("button button-treasure") &&
!((Button) event.getSource()).getStyleClass().toString().equals("button button-uncovered"))
{
FadeTransition transition = new FadeTransition();
transition.setNode((Button) event.getSource());
transition.setDuration(new Duration(500));
transition.setFromValue(1.0);
transition.setToValue(0.0);
transition.setCycleCount(1);
transition.setOnFinished(actionEvent -> {
if (((Button) event.getSource()).getStyleClass().toString().equals("button button-treasure")) {
loadVictoryScene();
}
if (!((Button) event.getSource()).getStyleClass().toString().equals("button button-treasure") &&
!((Button) event.getSource()).getStyleClass().toString().equals("button button-uncovered"))
{
transition.setFromValue(0.0);
transition.setToValue(1.0);
System.out.println(((Button) event.getSource()).getStyleClass().toString());
((Button) event.getSource()).getStyleClass().remove("button-covered");
((Button) event.getSource()).getStyleClass().add(Game.click(row, column));
transition.play();
transition.setOnFinished(ActionEvent->animating=false);
}
});
System.out.println(animating);
if(!animating){
animating=true;
transition.play();
Main.playSFX("sfx_card_unfold");}
}
System.out.printf("button index:%d,row:%d,column:%dn", index, row, column);
}
public void howToPlayButtonClicked() {
try {
Main.playSFX("sfx_button_clicked");
Main.playBGM("bgm_how_to");
Main.window.setScene(getScene("howTo"));
Main.window.setTitle("How to Play");
} catch (IOException e) {
System.out.println("could not change the scene to: how to play");
}
}
public void creditsButtonClicked() {
try {
Main.playSFX("sfx_button_clicked");
Main.playBGM("bgm_credits");
Main.window.setScene(getScene("credits"));
Main.window.setTitle("Credits");
} catch (IOException e) {
System.out.println("could not change the scene to: credits");
}
}
public void exitButtonClicked() {
Main.playSFX("sfx_button_clicked");
Main.window.close();
}
public void musicOnOffRadioButtonChecked() {
Main.playSFX("sfx_toggle");
if (musicOnOff.isSelected()) {
Main.isMuted=true;
Main.mediaPlayerBGM.setVolume(0.0);
Main.mediaPlayerSFX.setVolume(0.0);
System.out.println("now selected");
} else {
Main.isMuted=false;
Main.mediaPlayerBGM.setVolume(1.0);
Main.mediaPlayerSFX.setVolume(1.0);
System.out.println("unselected");
}
}
private void loadVictoryScene() {
try {
Main.window.hide();
Main.playBGM("bgm_victory");
Main.window.setScene(getScene("victory"));
Main.window.setTitle("Victory");
Main.window.setMaximized(false);
Main.window.show();
} catch (IOException e) {
System.out.println("could not change the scene to: victory");
}
}
private Scene getScene(String name) throws IOException {
Parent root = FXMLLoader.load(getClass().getResource(name + ".fxml"));
if (name.equals("game")) {
return new Scene(root, 800, 800);
}
return new Scene(root, 600, 600);
}
}
Game.java
package com.sample;
import javafx.beans.property.SimpleStringProperty;
import javafx.beans.property.StringProperty;
import java.util.Random;
public class Game {
static StringProperty scoreProperty;
static StringProperty timeProperty;
static StringProperty triesProperty;
private static int time;
private static int score;
private static int tries;
private static int tiles;
private static boolean gameIsOver;
private static boolean firstClick;
public Game() {
System.out.println("Game created...");
tries = 0;
score = 100000;
time = 0;
gameIsOver = false;
firstClick = false;
scoreProperty = new SimpleStringProperty("" + score);
timeProperty = new SimpleStringProperty("0");
triesProperty = new SimpleStringProperty("0");
tiles = new int[10][10];
Random random = new Random();
int treasureColumn = random.nextInt(10);
int treasureRow = random.nextInt(10);
tiles[treasureRow][treasureColumn] = 1;
}
static boolean firstClickHappened() {
return firstClick;
}
static void setGameOver() {
gameIsOver = true;
}
static boolean isGameIsOver() {
return gameIsOver;
}
static int getScore() {
return score;
}
static void scoreCalculator() {
time++;
if (time < 10) {
score = score - 100;
} else if (time < 20) {
score = score - 200;
} else if (time < 30) {
score = score - 300;
} else if (time < 50) {
score = score - 500;
} else {
score = score - 1000;
}
if (score < 0) {
score = 0;
}
scoreProperty.setValue("" + score);
timeProperty.setValue("" + time);
triesProperty.setValue("" + tries);
System.out.printf("Score:%s,Time:%s,Tries%sn", scoreProperty.getValue(), timeProperty.getValue(), triesProperty.getValue());
}
static String click(int row, int column) {
if (!firstClickHappened()) firstClick = true;
System.out.println(row + "," + column);
int clickValue = tiles[row][column];
System.out.println(clickValue);
if (clickValue == 0) {
tries++;
score -= 1000;
} else {
setGameOver();
}
return (clickValue == 1) ? "button-treasure" : "button-uncovered";
}
}
java javafx
java javafx
New contributor
New contributor
edited 10 mins ago
Jamal♦
30.3k11116227
30.3k11116227
New contributor
asked 10 hours ago
Altuğ CeylanAltuğ Ceylan
11
11
New contributor
New contributor
$begingroup$
What is your definition of "adequate resources"?
$endgroup$
– Mast
9 hours ago
$begingroup$
@Mast I am a second year cs student so I do not know many things about performance stuff, by adequate I mean for example calculating the sum of positive integers 5-10 can be easily done with a loop and will require less time and processing(?) but doing it recursively will require more time and processing; so maybe "optimum values"?
$endgroup$
– Altuğ Ceylan
8 hours ago
add a comment |
$begingroup$
What is your definition of "adequate resources"?
$endgroup$
– Mast
9 hours ago
$begingroup$
@Mast I am a second year cs student so I do not know many things about performance stuff, by adequate I mean for example calculating the sum of positive integers 5-10 can be easily done with a loop and will require less time and processing(?) but doing it recursively will require more time and processing; so maybe "optimum values"?
$endgroup$
– Altuğ Ceylan
8 hours ago
$begingroup$
What is your definition of "adequate resources"?
$endgroup$
– Mast
9 hours ago
$begingroup$
What is your definition of "adequate resources"?
$endgroup$
– Mast
9 hours ago
$begingroup$
@Mast I am a second year cs student so I do not know many things about performance stuff, by adequate I mean for example calculating the sum of positive integers 5-10 can be easily done with a loop and will require less time and processing(?) but doing it recursively will require more time and processing; so maybe "optimum values"?
$endgroup$
– Altuğ Ceylan
8 hours ago
$begingroup$
@Mast I am a second year cs student so I do not know many things about performance stuff, by adequate I mean for example calculating the sum of positive integers 5-10 can be easily done with a loop and will require less time and processing(?) but doing it recursively will require more time and processing; so maybe "optimum values"?
$endgroup$
– Altuğ Ceylan
8 hours ago
add a comment |
0
active
oldest
votes
Your Answer
StackExchange.ifUsing("editor", function () {
return StackExchange.using("mathjaxEditing", function () {
StackExchange.MarkdownEditor.creationCallbacks.add(function (editor, postfix) {
StackExchange.mathjaxEditing.prepareWmdForMathJax(editor, postfix, [["\$", "\$"]]);
});
});
}, "mathjax-editing");
StackExchange.ifUsing("editor", function () {
StackExchange.using("externalEditor", function () {
StackExchange.using("snippets", function () {
StackExchange.snippets.init();
});
});
}, "code-snippets");
StackExchange.ready(function() {
var channelOptions = {
tags: "".split(" "),
id: "196"
};
initTagRenderer("".split(" "), "".split(" "), channelOptions);
StackExchange.using("externalEditor", function() {
// Have to fire editor after snippets, if snippets enabled
if (StackExchange.settings.snippets.snippetsEnabled) {
StackExchange.using("snippets", function() {
createEditor();
});
}
else {
createEditor();
}
});
function createEditor() {
StackExchange.prepareEditor({
heartbeatType: 'answer',
autoActivateHeartbeat: false,
convertImagesToLinks: false,
noModals: true,
showLowRepImageUploadWarning: true,
reputationToPostImages: null,
bindNavPrevention: true,
postfix: "",
imageUploader: {
brandingHtml: "Powered by u003ca class="icon-imgur-white" href="https://imgur.com/"u003eu003c/au003e",
contentPolicyHtml: "User contributions licensed under u003ca href="https://creativecommons.org/licenses/by-sa/3.0/"u003ecc by-sa 3.0 with attribution requiredu003c/au003e u003ca href="https://stackoverflow.com/legal/content-policy"u003e(content policy)u003c/au003e",
allowUrls: true
},
onDemand: true,
discardSelector: ".discard-answer"
,immediatelyShowMarkdownHelp:true
});
}
});
Altuğ Ceylan is a new contributor. Be nice, and check out our Code of Conduct.
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
StackExchange.ready(
function () {
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fcodereview.stackexchange.com%2fquestions%2f212409%2fsimple-card-game-with-updating-gui%23new-answer', 'question_page');
}
);
Post as a guest
Required, but never shown
0
active
oldest
votes
0
active
oldest
votes
active
oldest
votes
active
oldest
votes
Altuğ Ceylan is a new contributor. Be nice, and check out our Code of Conduct.
Altuğ Ceylan is a new contributor. Be nice, and check out our Code of Conduct.
Altuğ Ceylan is a new contributor. Be nice, and check out our Code of Conduct.
Altuğ Ceylan is a new contributor. Be nice, and check out our Code of Conduct.
Thanks for contributing an answer to Code Review Stack Exchange!
- Please be sure to answer the question. Provide details and share your research!
But avoid …
- Asking for help, clarification, or responding to other answers.
- Making statements based on opinion; back them up with references or personal experience.
Use MathJax to format equations. MathJax reference.
To learn more, see our tips on writing great answers.
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
StackExchange.ready(
function () {
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fcodereview.stackexchange.com%2fquestions%2f212409%2fsimple-card-game-with-updating-gui%23new-answer', 'question_page');
}
);
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
$begingroup$
What is your definition of "adequate resources"?
$endgroup$
– Mast
9 hours ago
$begingroup$
@Mast I am a second year cs student so I do not know many things about performance stuff, by adequate I mean for example calculating the sum of positive integers 5-10 can be easily done with a loop and will require less time and processing(?) but doing it recursively will require more time and processing; so maybe "optimum values"?
$endgroup$
– Altuğ Ceylan
8 hours ago