How do I add a keypress action in my program? - java

I am making a very basic Java based RPG game with many of options as you go along and I want to make it so when you get the ability to type, if you press "x" it will automatically quit the game. I don't want to continuously add the "if-then" statement every time the user progresses.
What I don't want to do: (I would have to do this over 50 times for: inventory, quit game, character information and more)
switch (choice1)
{
case "x":
System.out.println("\nYou quit the game!");
System.exit(0);
break;
}
What I have: (Doesn't work)
import java.util.Scanner;
import java.awt.*;
import java.awt.event.*;
public class TheDungeon extends KeyAdapter
{
public void keyPressed(KeyEvent e) {
char ch = e.getKeyChar();
if (ch == 'a')
{
System.out.println("You pressed A");
}
}
public static void main(String[] args)
{
/* My variables...
*/
System.out.println("e: Check experience and level");
System.out.println("c: Character Information");
System.out.println("i: Inventory");
System.out.println("x: Quit Game");
choice1 = keyboard.nextLine();
switch (choice1)
{
case "x": //This section
System.out.println("\nYou quit the game!"); //here works
System.exit(0); //but I don't
break; //want to add this section
} //every time the user
//progresses.

To use KeyAdapters and/or KeyListeners you will need to construct a Gui in which to add these Adapters/Listners too.
The way you are currently reading in the users action is a valid way to do it for a console app.
Edit Extending on BlakeP's Answer if you have your determineAction method you could have a Map of the text your print out like so then you only need to add the special actions for the keys.
Map<Character, String> actionText = new HashMap<Character, String>();
actionText.put('x', "\nYou quit the game!");
actionText.put('i', "\nInventory Items:\n Things are here");
private void determineAction(char choice) {
System.out.println(actionText.get(choice));
switch (choice1)
{
case "x":
System.exit(0);
break;
}
}
Or you should have another method to do each special action, this will keep your switch shorter and easier to read. Like so
private void determineAction(char choice) {
System.out.println(actionText.get(choice));
switch (choice1)
{
case "x":
doExit();
break;
case "i":
printInventory();
break;
}
}
private void doExit()
{
System.out.println("\nYou quit the game!");
System.exit(0);
}
private void printInventory()
{
System.out.println("\nInventory Items:");
System.out.println("\n Things are here");
}

The KeyAdapter class is meant for GUI apps (notice the AWT package that it is in), and it sounds like you are doing just a console app. As far as I know, there is no "keypress" listener for console apps.
I would suggest putting the switch statement in a method such as "determineAction" and then return what you need (if anything).
Example method:
private void determineAction(char choice) {
switch (choice1)
{
case "x":
System.out.println("\nYou quit the game!");
System.exit(0);
break;
case "i":
System.out.println("\nInventory Items:");
System.out.println("\n Things are here");
break;
}
}
So after every time you ask for the choice, put this line --
determineAction(choice);
And it will run the switch statement without you having to copy it each time.

Related

Java predator-prey simulation with GUI can't run simulation properly

I'm trying to add a GUI to the predator-prey simulation. It can allow users to choose which simulation(species involved) they want to do, set the simulation field size they want, and show the progress of the simulation and result.
I asked a question before, and I kinda figure it out what caused the problem.
But now I encounter another question:
How do I let the simulation buttons use the same object method which generate button use, but also don't generate the field again?
As the code shown below,
(1)after I generate the field and press "Reset" button, it will generate the field again then reset simulation(show up a new field window with different data);
(2)after I generate the field and press "Next step" button, it will generate the field again then show next step simulation(show up a new field window and don't inherit the initial data I generate);
(3)after I generate the field and press "long run step" button, it will generate the field again then show next hundred step simulation result(show up a new field window and don't inherit the initial data I generate and don't show the progress);
private class ButtonHandler implements ActionListener{//Generate field
public void actionPerformed(ActionEvent e){
String depthstr = depthtxt.getText();
String widthstr = widthtxt.getText();
int depth = Integer.parseInt(depthstr);
int width = Integer.parseInt(widthstr);
switch(version) {//Different specices simulation choosed by user
case 0:
Simulator set = new Simulator();
set.Simulator(depth,width);
break;
case 1:
SimulatorRF setRF = new SimulatorRF();
setRF.SimulatorRF(depth,width);
break;
case 2:
SimulatorRW setRW = new SimulatorRW();
setRW.SimulatorRW(depth,width);
break;
...
case 25:
SimulatorFWBH setFWBH = new SimulatorFWBH();
setFWBH.SimulatorFWBH(depth,width);
break;
}
reset_butt.setEnabled(true);
nextstep_butt.setEnabled(true);
longstep_butt.setEnabled(true);
}
}
private class SimulateOption implements ActionListener{
public void actionPerformed(ActionEvent e){
switch(version) {
case 0:
Simulator set = new Simulator();
set.Simulator(depth,width);
if(e.getSource() == reset_butt){
set.reset();
}
else if(e.getSource() == nextstep_butt){
set.simulateOneStep();
}
else if(e.getSource() == longstep_butt){
set.runLongSimulation();
}
break;
case 1:
SimulatorRF setRF = new SimulatorRF();
setRF.SimulatorRF(depth,width);
if(e.getSource() == reset_butt){
setRF.reset();
}
else if(e.getSource() == nextstep_butt){
setRF.simulateOneStep();
}
else if(e.getSource() == longstep_butt){
setRF.runLongSimulation();
}
break;
case 2:
SimulatorRW setRW = new SimulatorRW();
setRW.SimulatorRW(depth,width);
if(e.getSource() == reset_butt){
setRW.reset();
}
else if(e.getSource() == nextstep_butt){
setRW.simulateOneStep();
}
else if(e.getSource() == longstep_butt){
setRW.runLongSimulation();
}
break;
...
case 25:
SimulatorFWBH setFWBH = new SimulatorFWBH();
setFWBH.SimulatorFWBH(depth,width);
if(e.getSource() == reset_butt){
setFWBH.reset();
}
else if(e.getSource() == nextstep_butt){
setFWBH.simulateOneStep();
}
else if(e.getSource() == longstep_butt){
setFWBH.runLongSimulation();
}
break;
}
reset_butt.setEnabled(true);
nextstep_butt.setEnabled(true);
longstep_butt.setEnabled(true);
}
}
}
Is there a way to fix my code to solve the problem?
I hope that
(1)after I click the "reset" button, it reset the field I generated (don't show up a new field window)
(2)after I click the "next step" button, it simulate next step of the field I generated (inherit the initial data I generate and don't show up a new field window)
(3)after I click the "next hundred step" button, it simulate next hundred step of the field I generated and show the process (inherit the initial data I generate and don't show up a new field window)
Here are my full codes if you are intrested:
https://github.com/KasmaJC/predator-prey-simulation-with-GUI
*There is a BlueJ project rar. at button
Well I figure it out myself again...
I put all of my Classes into a package(name as PredatorPreySimulation), and change all simulator classes' method into static method.
By doing so, I don't need to create an instance of the class to call a static method, and I can let the simulation buttons use the same method which generate button use, but also don't generate the field again.
In this case, I can use the code below:
import PredatorPreySimulation.Simulation;
import PredatorPreySimulation.SimulationRF;
...
and
public class ButtonHandler implements ActionListener{//Generate field
public void actionPerformed(ActionEvent e){
String depthstr = depthtxt.getText();
String widthstr = widthtxt.getText();
int depth = Integer.parseInt(depthstr);
int width = Integer.parseInt(widthstr);
switch(version) {//Different specices simulation choosed by user
case 0:
Simulator.Simulator(depth,width);
break;
case 1:
SimulatorRF.SimulatorRF(depth,width);
break;
...
case 25:
SimulatorFWBH.SimulatorFWBH(depth,width);
break;
}
reset_butt.setEnabled(true);
nextstep_butt.setEnabled(true);
longstep_butt.setEnabled(true);
}
}
private class SimulateOption implements ActionListener{
public void actionPerformed(ActionEvent e){
switch(version) {
case 0:
if(e.getSource() == reset_butt){
Simulator.reset();
}
else if(e.getSource() == nextstep_butt){
Simulator.simulateOneStep();
}
else if(e.getSource() == longstep_butt){
Simulator.runLongSimulation();
}
break;
case 1:
if(e.getSource() == reset_butt){
SimulatorRF.reset();
}
else if(e.getSource() == nextstep_butt){
SimulatorRF.simulateOneStep();
}
else if(e.getSource() == longstep_butt){
SimulatorRF.runLongSimulation();
}
break;
...
case 25:
if(e.getSource() == reset_butt){
SimulatorFWBH.reset();
}
else if(e.getSource() == nextstep_butt){
SimulatorFWBH.simulateOneStep();
}
else if(e.getSource() == longstep_butt){
SimulatorFWBH.runLongSimulation();
}
break;
}
reset_butt.setEnabled(true);
nextstep_butt.setEnabled(true);
longstep_butt.setEnabled(true);
}
}
}
I might be bad at expressing questions... I'll try to improve my asking skill ...

How do I make a selected Combobox value display different text?

I am new to Java and couldn't find any answers for my problem that I was able to understand.
I want to make a selected value in my ComboBox change what text is displayed in the textfield.
For example, if the user selects an artist in the combobox, then the artists' albums are displayed in the textfield.
Any help is appreciated. Thanks!
private void jComboBox1ActionPerformed(java.awt.event.ActionEvent evt) {
String a = (String)jComboBox1.getSelectedItem();
int artists = 0;
switch (artists){
case 0: jTextField1.setText("Take Care, Nothing Was The Same, Views, More Life, Scorpion");
break;
case 1: jTextField1.setText("Stoney, Beerbongs & Bentleys");
break;
case 2: jTextField1.setText("One Love, Listen, Nothing But the Beat");
break;
case 3: jTextField1.setText("Ready for the Weekend, 18 Months, Motion");
break;
case 4: jTextField1.setText("Cole World: The Sideline Story, 2014 Forest Hills Drive, 4 Your Eyez Only");
break;
case 5: jTextField1.setText("My Beautiful Dark Twisted Fantasy, Yeezus, The Life of Pablo, ye");
break;
case 6: jTextField1.setText("Parachutes, a Rush of Blood to the Head, X&Y, Viva La Vida, Mylo Xyloto");
}
}
Here is a full working example:
import java.awt.GridLayout;
import javax.swing.*;
public class ChangeTextViaCheckbox extends JFrame {
public ChangeTextViaCheckbox() {
setVisible(true);
setDefaultCloseOperation(EXIT_ON_CLOSE);
setLayout(new GridLayout(3, 1));
JCheckBox cb1 = new JCheckBox("Checkbox 1");
JCheckBox cb2 = new JCheckBox("Checkbox 2");
JTextField tf = new JTextField();
cb1.addActionListener(e -> tf.setText("CB 1 is active"));
cb2.addActionListener(e -> tf.setText("CB 2 is active"));
add(cb1);
add(cb2);
add(tf);
}
public static void main(String[] args) {
ChangeTextViaCheckbox frame = new ChangeTextViaCheckbox();
frame.pack();
}
}
The both ActionListener listen on a performed action. If thats the case, they set a new Text in the JTextField.
But it would be better, if you implement it via JRadioButton and a ButtonGroup. With this there can't be a multiple choice.
Your question is lacking details and examples, you should post the important parts of your code that you've already written, for example I have no idea now what [GUI] API are you using(for example swing or AWT), so I strongly advise you to edit your question and provide more details, but either way I'm going to give you a simple example.
I'm going to assume your using the swing api, but it shouldn't be that different if your using another GUI api (like AWT).
import javax.swing.*;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
public class SwingExample extends JFrame{
public SwingExample(){
String[] artists = {"artist1","artist2","artist3"};
Map<String,String> albumOfArtists = new HashMap<String,String>();
albumOfArtists.put("artist1","album1");
albumOfArtists.put("artist2","album2");
albumOfArtists.put("artist3","album3");
JComboBox combo1 = new JComboBox<String>(artists);
JTextField field1 = new JTextField();
//You implement an action listener to define what should be done when
//an user performs certain operation. An action event occurs,
//whenever an action is performed by the user. Examples: When the user
//clicks a button, chooses a menu item, presses Enter in a text field.
//add action listener to your combobox:
combo1.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent event) {
String selectedString=(String)combo1.getSelectedItem();
field1.setText(albumOfArtists.get(selectedString));
//for example if you select artist1 then the text displayed in the text field is: album1
}
}
add(combo1);
add(field1);
}
private static void createAndShowGUI() {
JFrame frame = new CreateNewJTextField();
frame.pack();
frame.setVisible(true);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
}
public static void main(String[] args) {
createAndShowGUI();
}
}
You can use switch() for your combobox. I've written a code which has the name defined to combobox as cb1. The getSelectedItem() method is used for cb1. You can define the corresponding command for each case (starting from index 0).
String a = (String)cb1.getSelectedItem();
int i = 0;
switch (i){
case 0:
break;
}
Make sure to end each case with break; or your code will execute repeatedly.
Now if the textfield you're using is t1 then the following code is generalised,
switch (i) {
case 0: t1.setText(<whatever you want to display>);
break;
}
Hope this helps.
Here's the revisited code:
String a = (String)cb1.getSelectedItem();
int i = 0;
switch(i){
case 0: t1.setText("Take Care, Nothing Was The Same, Views, More Life, Scorpion");
// for combobox option Drake index = 0
break;
case 1: t1.setText("Stoney, Beerbongs & Bentleys");
// for combobox option post_malone index = 1
break;
case 2: t1.setText("One Love, Listen, Nothing But the Beat");
// for combobox option david_guetta
break;
}
switch is a selection statement that successively tests the value of an expression against alist of integers or characters constants. When a match is found, the statements associated with that constant are executed. Here, the variable i is the expression(the option you choose from combobox) which is evaluated.
Hope this helps again!

How can I use while loops in a text based game Java?

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();
}
}
}

Alternate displayed image

I'm doing a TicTacToe, and the idea is that in the first time I click one button it shows the image "X" , if i click other button it shows the image "O" ... and it continues, showing the images alternately. I was also trying that with one click at the button it shows one image, but if i click again at that button the image disappear.
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import javax.swing.ImageIcon;
import javax.swing.JButton;
public class XOButton extends JButton implements ActionListener{
ImageIcon X;
ImageIcon O;
byte value=0;
byte k=0;
public XOButton(){
try {
X=new ImageIcon(this.getClass().getResource("X.png"));
O=new ImageIcon(this.getClass().getResource("O.png"));
addActionListener(this);
} catch (NullPointerException e) {
System.out.println("The image is not Available");
}
}
#Override
public void actionPerformed(ActionEvent e) {
value++;
value %= 2;
if( k%2 == 0) {
switch(value){
case 0:
setIcon(null);
break;
case 1:
setIcon(X);
System.out.println("KX= " + k);
break;
}
k++;
}
else {
switch(value){
case 0:
setIcon(null);
break;
case 1:
setIcon(O);
System.out.println("K0= " + k);
break;
}
k++;
}
}
}
Your logic is broken, and the main problem I see is that each XOButton has its own ActionListener, one that is completely independent of all others, and so the value int will always be equal to 0 whenever any button is pushed for the first time, regardless of the state of the previously pushed buttons.
I suggest that
You don't extend JButton but rather use JButtons
That you give all JButton's the same Action or ActionListener
That this listener stores the state of the xo of the last button press
That this listener checks to see if the currently pressed button is in a null, or X or O state, and then acts accordingly.
For an example of a working Tic Tac Toe program that uses image icons, please have a look at this answer of mine to a similar question.

How should i program mouse/key input in an advanced java game?

I am a self taught programmer, so I do not know the proper ways to do things. I have made simple games like asteroids and snake, but in those games, you can easily modify the variables within the keyevent functions. Here is how I did it in my simple Asteroids game:
/*
* key listener events
*/
public void keyReleased(KeyEvent k){
int keyCode = k.getKeyCode();
switch(keyCode){
case KeyEvent.VK_LEFT:
turnLeft = false;
break;
case KeyEvent.VK_RIGHT:
turnRight = false;
break;
case KeyEvent.VK_UP:
accel = false;
break;
case KeyEvent.VK_1:
cls = true;
break;
case KeyEvent.VK_ENTER:
break;
case KeyEvent.VK_SPACE:
fire = false;
}
}
public void keyTyped(KeyEvent K){}
public void keyPressed(KeyEvent k){
int keyCode = k.getKeyCode();
switch(keyCode){
case KeyEvent.VK_LEFT:
turnLeft = true;
break;
case KeyEvent.VK_RIGHT:
turnRight = true;
break;
case KeyEvent.VK_UP:
accel = true;
break;
case KeyEvent.VK_1:
cls = false;
break;
case KeyEvent.VK_ENTER:
clearAllBullets();
break;
case KeyEvent.VK_SPACE:
fire = true;
}
}
If I were to make a more advanced game (with a main menu, options, main game, etc.) How should I do the key/mouse input?
Also, if I were to go into the single-player, should I put all of the gameplay code into one class? Is there a way to put the single player code into a separate class and somehow have the key input still modify the variables and such?
Thank you for your time!
P.S. Any links or source is extremely appreciated. :D
"Is there a way to put the single player code into a separate class and somehow have the key input still modify the variables and such?"
Yes, there is way to encapsulate all event-based behaviours- http://en.wikipedia.org/wiki/Mediator_pattern but, it can make yor code very complicated, so firstly try to implement your game in more "normal" way.
Anyway - you will need other classes, to present domain model of your game (Player, Gameboard, UserInterfaces etc...)

Categories

Resources