I'm a beginner in Java and I am making a basic game for practice. I'm almost done, but I have one further obstacle to overcome.
I would like to know how to make the game loop on the game() method after pressing no as a choice when asked whether to end the game.
Here is my code:
private static void game() //game method
{
//...
int play = JOptionPane.showOptionDialog(null
,"End"
, "Do you want to play again?"
, JOptionPane.PLAIN_MESSAGE
,JOptionPane.DEFAULT_OPTION
, null
, again
, again[1]);
//end of game
if (play == 0)
System.exit(0);//exit
else
/* what do I put here to restart the program in the same method(game())
after pressing the No button on the JOptionPane??? */
System.out.println("Service not available");
To anybody who can help, I thank you very much!
Given the current state of your program, the easiest simplest most straightforward readable method is recursion. Just call your game method again. Note that there's probably a recursion limit, so the loop is the recommended method, even if it does involve restructuring your code a bit.
else{
game();
}
Loop method: declare play at the beginning and use a loop:
private static void game(){
boolean play = true;
while (play){
//...
//find out if user wants to play again
//set play to false if player doesn't want to play anymore
}
}
Extract the JOptionPane part from your game() function code
int play=0;
do{
game();
play = JOptionPane.showOptionDialog(null
,"End"
, "Do you want to play again?"
, JOptionPane.PLAIN_MESSAGE
,JOptionPane.DEFAULT_OPTION
, null
, again
, again[1]);
}while(play);
If you just want to make it work you can do something like this :
private static void game()//game method
{
boolean exit = false;
while(!exit){
//...int play = JOptionPane.showOptionDialog(null,"Play Again?", "Do you want to play again?", JOptionPane.PLAIN_MESSAGE,JOptionPane.DEFAULT_OPTION, null, again, again[1]);
//end of game
if (play == 0) {
exit = true;
}
}
System.exit(0);//exit
But a better more professionnal approach would be to refactor your code, so you extract game logic and separate it from User dialog interaction.
You can use this method which i am very sure will work in your program since it is something that i have done before. You'll use Desktop class of the system that will initiate the opening of the program. The program will look like this
public static void restart()
{
Desktop desktop = Desktop.getDesktop();
try {
desktop.open(new File("name_of_your_jarfile.jar").getCanonicalFile());
// desktop.open(new File("name_of_your_exe.exe").getCanonicalFile());//for exe
} catch (IOException e) {
//if this happen try looking whether the name of your jar file is correct
e.printStackTrace();
}
}
private static void game() //game method
{
//...
int play = JOptionPane.showOptionDialog(null
,"End"
, "Do you want to play again?"
, JOptionPane.PLAIN_MESSAGE
,JOptionPane.DEFAULT_OPTION
, null
, again
, again[1]);
//end of game
if (play == 0)
System.exit(0);//exit
else
/* what do I put here to restart the program in the same
after pressing the No button on the JOptionPane??? */
System.out.println("Service not available");
restart();//this will reopen your jar/exe file
System.exit(0);
}
Related
I'm trying to write a logic in memory game that when I click on cards and they are not a pair (different ID), program should swap them back after 1s. If they are same, then leave them as they are.
The problem is that when I first click and the card appears, after second clicking on another (different) card it doesn't appear and swap the first card after 1s. someone knows why the second card does not appear after clicking?
Btw when the pair is correct, everything works fine, here is my fragment of the code responsible for that logic in listener:
final int copy = i;
card2.addActionListener((e) -> {
card2.setIcon(new ImageIcon(icons[copy].getAbsolutePath()));
if(firstClick == null)
{
firstClick = (Card)e.getSource();
}
else
{
Card secondClick = (Card)e.getSource();
if(firstClick.getID() != secondClick.getID())
{
try
{
Thread.sleep(1000);
} catch (InterruptedException e1)
{
//e1.printStackTrace();
}
firstClick.setIcon(new ImageIcon(background.getAbsolutePath()));
secondClick.setIcon(new ImageIcon(background.getAbsolutePath()));
firstClick = null;
}
else
firstClick = null;
}
});
While method actionPerformed is executing, the GUI cannot react to mouse and keyboard events, so basically your code is "freezing" your GUI for one second. I believe that the class javax.swing.Timer is what you need and at first glance it looks like the duplicate question that MadProgrammer referred to may help you.
So first off is just some text showing my thought process on the way the code should work. I am super new to programming in general and just started learning java only a few days ago. I think I have a basic understanding of how oop works but I can't implement it well into my code. The use of while loops makes a bit of sense to me though so I'm just starting out with those ;D
Things I want:
a main menu with 3 options
Menu (camp)
Quest (activates the quest loop)
Go to Town (activates the town loop)
quit game (exits the program)
Quest
Gameplay loop of fighting random monsters and gaining gold/score
"monster appears"
fight monster
does damage to monster
monster does damage back
back to main loop
use item
choose item
use item
item effects applied
back to main loop
run
return back to main menu (activates main menu)
Town
allows you to spend gold on "gear" to increase health and damage values
"I am the blacksmith blah blah blah"
Upgrade Weapon (increases damage)
Upgrade Armor (increases health)
Leave Town (returns player back to main menu)
Game Ends when player dies or chooses quit game
Display a Score and thank player for playing game
Below is just a prototype of the logic
I feel like this should work but every time I run it,
it doesn't work right and just ends up doing an
infinite loop. I'm hoping one of you guys will be able
to see why it doesn't work and kinda steer me in the right
direction. Anything would be greatly appreciated!
Also any comments on those booleans for camp, dungeon, town?
I don't know if I really needed those and its probably just
an extra bit of useless code but I'm really not sure.
import java.util.Scanner;
public class logic
{
public static void main(String[] args)
{
boolean running = true;
Scanner in = new Scanner(System.in);
System.out.println("This is a test");
while(running)
{
boolean camp = true;
boolean dungeon = false;
boolean town = false;
String input = in.nextLine();
while(camp)
{
System.out.println("what u do?");
System.out.println("1. go dungeon");
System.out.println("2. go town");
System.out.println("3. quit");
if (input.equals("1"))
{
dungeon = true;
while(dungeon)
{
System.out.println("you are in the dungeon");
dungeon = false;
break;
}
}
else if (input.equals("2"))
{
dungeon = false;
town = true;
while(town)
{
System.out.println("you are in the town");
town = false;
break;
}
}
else if (input.equals("3"))
{
break;
}
else
{
System.out.println("invalid command!");
}
}
}
}
}
Personally, I wouldn't use so much while loops and instead put each section's logic into its own function then use an if-else-if / switch statement to decide which function should be called and do this in a while loop, sadly I can't test this because I haven;t got a Java environment and its been a while since I used Java.
This is the new code I came up with. I was able to figure out how to break all the different areas up into their own methods. This should make building the game world much easier :D
import java.util.Scanner;
public class LogicTest
{
Scanner in = new Scanner(System.in);
public static void main(String[] args)
{
LogicTest game;
game = new LogicTest(); // a new instance of the public class folder has to be created in order to use all the other methods
game.run();
}
public void run() // this method is used to run the game from the main method
{
camp();
}
public void quest()
{
System.out.println("you go on quest");
camp();
}
public void town()
{
System.out.println("you go to town");
camp();
}
public void camp() // this method acts as the game hub where the player can choose what they want to do next
{
System.out.println("you are in your camp");
System.out.println("----------------------");
System.out.println("what do you want to do?");
System.out.println("1. go quest");
System.out.println("2. go town");
System.out.println("3. quit");
String input = in.nextLine();
// each one of these options just calls its respective method
// the methods are what have the menus and everything for each location
if (input.equals("1"))
{
quest();
}
else if (input.equals("2"))
{
town();
}
else if(input.equals("3")) // by leaving this empty the program has nothing else to read with this option and so it closes
{
}
else
{
camp();
}
}
}
I made clone of ""Flappy bird" game by watching video tutorials.i programmed it so that when the bird falls or collides with the tubes a game over message appears on the screen and the game restarts when the player taps on the screen.
The problem is that when the user fails to tap the bird in time and it collides with the tube,the game over screen appears immediately and the user happens to tap on the game over screen which results in restarting of the game.
This makes the user unable to see the score.I have already tried using Thread.sleep().Following is the code
(gameState == 2)
{
batch.draw(gameOver,Gdx.graphics.getWidth()/2-gameOver.getWidth()/2,Gdx.graphics.getHeight()/2-gameOver.getHeight()/2);
try
{
Thread.sleep(2000);
}
catch(InterruptedException ex)
{
Thread.currentThread().interrupt();
}
if (Gdx.input.justTouched()) {
gameState = 1;
startGame();
score =0;
scoringTube = 0;
velocity = 0;
}
}
With this code the problem is that even the gameover image is being delayed and the previous problem is still occuring but now with a delay.I basically need a way so that justTouched method becomes inactive for a while when the game over screen is there.Please help.
I really wouldn't recommend using Thread.sleep; instead, you could try to use a boolean that is changed once the game ended, and prevent the method from executing in that case. Combine that with e.g a Timer that resets it after a fixed delay, and you should have the solution to your problem.
Example Usage for the timer:
new java.util.Timer().schedule(
new java.util.TimerTask() {
#Override
public void run() {
//execute code here (change boolean state)
}
},
yourDelayHere
);
I am writing a board game where I need to check for enemies on the the player is moving and prompt to make an attack. However because of how the game is made the move method is called on the JavaFX application thread, I want to be able to prompt the user if they want to fight an enemy.
My dialogue box which works fine normal uses wait and notify which dont work on the main thread without crashing the program, does anyone know how to pause the execution of this thread until a user clicks one of the buttons.
I apologise for the description, its late.
Method that checks for enemies
This method checks for the enemies and returns the enemy if the user selected yes. It runs on the JavaFX Thread.
private Ship pathBattle(Vector gridPosition){
//Check if there are ships on the path to the destination
for(Button cell : activeButtons){
//Check the button position is not that of the current button, dont go past the current button
Vector pixPosition = new Vector(cell.getLayoutX(), cell.getLayoutY());
//Convert to a grid referance
Vector gridPos = Vector.pixToGrid(pixPosition);
if(!gridPos.equals(gridPosition)){
//This button is not the destination
//Check for any ships on that cell
Ship collided = Ship.isOccupiedButton(cell);//Returns the ship if there is one on the cell
if(collided != null){
//There is a ship, prompt to battle
boolean battle = UtilPopups.showConfirmationDialog("Do you want to battle " + collided.getName(), "YAR!", "NAY!");
Game.printError("Ship collision");
if(battle){
return collided; //Return the ship to battle
}
}
}
//On to the next button
}
return null;
}
The code to display the Popup
This does work in other areas of the porgram with no issue
public static boolean showConfirmationDialog(String lblPrompt, String btnYes, String btnNo){
//Check if the confirmation controller is not null
if(confirmationDialog != null){
confirmationDialog.lbl_prompt.setText(lblPrompt);
confirmationDialog.btn_no.setText(btnNo);
confirmationDialog.btn_yes.setText(btnYes);
//Show the base
show(confirmationDialog.base_pane);
//Pause this thread until user input is given from GUI thread
synchronized (confirmationDialog) {
try{
confirmationDialog.wait();
} catch (Exception e) {
e.printStackTrace();
}
}
//Program resumed, user input given and stored in response
if(confirmationDialog.response.equals("yes")){
confirmationDialog.response = null; //Set back to null
return true;
} else {
confirmationDialog.response = null; //Set back to null
return false;
}
}
//Class not initialized
Game.printError("UtilPopups->showConfirmationDialog: Dialog NULL!");
return false;
}
For blocking any caller thread during showing dialog, for example:
static private void showAndBlock(Dialog dialog) {
if (Platform.isFxApplicationThread()) {
dialog.showAndWait();
} else {
CountDownLatch lock = new CountDownLatch(1);
Platform.runLater(() -> {
dialog.showAndWait();
lock.countDown();
});
try {
lock.await();
} catch (InterruptedException e) {
// Just in case you call yourTherad.interrupt(),
// the thread will be joined forcibly through here.
}
}
}
But I'm not sure whether or not it works in your threading design.
The collided method literally doesnt nothing, it doesn't ask for a input so it can't work.
I think, sorry not good english
I'm searching on the internet for hours and i cannot find the right answer that works for me.
So.. I made a game called 'seabattle'
After playing that game the console comes with the question to play again.
System.out.println("Well done! " + whosturn.getName() + ". A ship down!" );
System.out.println("Hurraaaaaayyyyy, All boats down!!");
System.out.println("Do you want to play this game again? (y/n) ");
input = scanner.next().toLowerCase();
if(input == "y"){
System.out.println("The game should start again now..");
System.out.println("Butttttttt, I don't know how to...");
}
else{
System.out.println("Thank you for player Battleships!");
System.out.println("See you next time ;)");
}
}
else{
FiredPosition.setDisplayValue('*');
System.out.println("Good job, you hit a ship!");
switchTurn();
}
If the user types y in console. The game should start again.
I read something about Main(args) or something like that.. That didn't work for me because this is another class.
I hope you guys can help me?
Ciaoo
If your main class SeaBattle is currently as this:
public class SeaBattle {
public static void main(String[] args) {
...
}
}
you could change it the following way:
public class SeaBattle {
private static String[] args;
public static void run() {
//do the same than main() previously
}
public static void main(String[] args) {
SeaBattle.args = args;
run();
}
}
Then to relaunch the game,
SeaBattle.run();
A simple answer is: Whatever you do to start the game in the first place, do it again when you detect the 'y'.
However, a more in depth answer involves the use of an object to store and update the game state, it is not fully clear from your description whether you are currently doing this. So if it is a battleships type game the object may contain a 2d array for the game area, and perhaps a variable to store whose turn it is. This object would have an 'initialise' method where you randomly select where the ships are in the game area, set the value for whose turn it is, etc.
Your main method would interact with this object, so it would call the game object's initialise method, and after each turn it would call another method (e.g. 'isGameFinished') to check whether the game is over. The isGameFinished method would check if all of the ships have been destroyed and return true if so. If it returns true, then the user would be prompted for a new game. If they enter 'y', then you can either create a completely new object of the game state or just call the game state's initialise method again. You will then have a new game state to begin a new game with.