my JAVA code skipping a line without any reason why - java

i'm doing a pac-man game in JAVA, right now the ghosts are moving (just by 1 square) only after pac-man moves and pac-man moving (also just by 1 square) only when one of the arrows on the keyboard is pressed, and i want to make the ghosts to move in constant speed no matter what (lets say for example, 2 squares per second)...
i have this loop, which basically working fine except the screen won't refresh itself:
while(true) {
isGot = redG.moves(packguy.getCurrentPanel().getLoc());
if (isGot)
while (true)
JOptionPane.showMessageDialog(frame, "you lost!");
if (steps == 2) {
pinkG = new Ghost(panelGrid[10][14], 0, 5);
}
if (steps > 1) {
isGot = pinkG.moves(packguy.getCurrentPanel().getLoc());
if (isGot)
while (true)
JOptionPane.showMessageDialog(frame, "you lost!");
if (steps == 3) {
orangeG = new Ghost(panelGrid[10][14], 0, 4);
}
if (steps > 2) {
isGot = orangeG.moves(packguy.getCurrentPanel().getLoc());
if (isGot)
while (true)
JOptionPane.showMessageDialog(frame, "you lost!");
if (steps == 4) {
cyanG = new Ghost(panelGrid[10][14], 0, 6);
}
if (steps > 3) {
isGot = cyanG.moves(packguy.getCurrentPanel().getLoc());
if (isGot)
while (true)
JOptionPane.showMessageDialog(frame, "you lost!");
}
}
}
framePaint();
//
try {
Thread.sleep(500);
}
catch (InterruptedException e) {
Thread.currentThread().interrupt();
}
steps++;
}
the function framePaint() is a function i made which put on every square the thing that supposed to be in this square (rather it's ghost, pac-man himself...). First the function remove every object in each square, afterwards it is checking what's supposed to be in the square and put the match photo (which work pretty well). at the end of the function there is those lines:
frame.repaint();
frame.validate();
if im putting a JOptionPane.showMessageDialog(frame, "some message"); in the line where I put the \\ the screen does refreshing when i get the message...
can you all please help me figure this out?
advanced thanks :)

I assume you have a keylistener that reacts whenever a key is pressed. In that you calculate all the new positions.
Instead create a background thread that will periodically (two times per second?) calculate the positions. For the player object, use the last direction of movement to make pacman continue walking.
In the keylistener just set the direction for pacman and use that in the background thread. Whenever the background thread moved something on the screen, it shall call the component's repaint() method. The Swing framework will then call paintComponent() to really draw the game.

Related

main menu with switch statement

So for a school project, I have to create a game with a program called 'Processing'.
I am creating a main menu with the switch statement. For that I want to use the buttons 'Start', 'Help', and 'exit'.i would like to use those buttons to change the variables of the switch statement. Therefore I'm using "mousePressed". The problem is that which button I'm pressing, is giving me the same result as the 'exit' button. Could somebody give me tips on how I can structure my menu better or even make my button work? I am using a library on Processing called 'ControlP5' to make my buttons.
here is my code so far:
int mode; // 1: intro screen, 2: game , 3: game over
final int INTRO = 1;
final int PLAY = 2;
final int GAMEOVER = 3;
//==============================================================
void setup(){
size(1920,1080);
mode = 1;
}
//========================================================
void draw(){
if(mode == 1){
introScreen();
}
else if (mode == 2){
gameItself();
}
else if (mode == 3){
gameOver();
}
else println("mode error");{
}
}
void introScreen(){
mode = 1;
static int Page = 0;
import controlP5.*;
ControlP5 cp5;
cp5= new ControlP5(this);
switch(Page){
case 0: // main menu
cp5.addButton("Start").setValue(0).setPosition(1420,250).setSize(400,100);
cp5.addButton("Exit").setValue(0).setPosition(1420,650).setSize(400,100);
cp5.addButton("Help").setValue(0).setPosition(1420,450).setSize(400,100);
break;
case 1: //help menu
cp5.addButton("Back").setValue(0).setPosition(1420,450).setSize(400,100);
break;
}
public void Start(){
if(mousePressed){
mode = 2; // switching to the game itself
}
println("Start");
}
public void Exit(){
if(mousePressed){
exit(); }
println("Exit");
}
public void Help(){
Page = 1;
println("Help");
}
public void Back(){
if(mousePressed){
Page = 0;
}
println("Back");
}
void gameItself(){
// game and stuff
}
void gameOver(){
//gameover
}
Take a look at how the mousePressed event works. You may use this information useful.
To achieve your goal as to change the Page variable by clicking buttons, there are multiple options. First, I'll go with the easier one, the one which doesn't need an import but just check for coordinates. Then I'll do the same thing, but with controlP5.
1. Just checking where the clicks lands
I'll go with the most basic one: detecting the "click" and checking if it's coordinates are inside a button.
First, we'll add the mouseClicked() method. This method is called every time a mouse button is pressed.
// I'm typing this out of IDE si there may be some quirks to fix in the code
void mouseClicked() {
switch(Page) {
case 0:
if (mouseX > 1420 && mouseX < 1420+400 && mouseY > 250 && mouseY < 250+100) {
// You're in the main menu and Start was clicked
}
if (mouseX > 1420 && mouseX < 1420+400 && mouseY > 650 && mouseY < 650+100) {
// You're in the main menu and Exit was clicked
}
if (mouseX > 1420 && mouseX < 1420+400 && mouseY > 450 && mouseY < 450+100) {
// You're in the main menu and Help was clicked
}
// You should use 'else if' instead of 3 different if, but I coded it like that so it would be easier to see the small differences between the coordinates
case 1:
if (mouseX > 1420 && mouseX < 1420+400 && mouseY > 450 && mouseY < 450+100) {
// You're un the help menu and Back was clicked
}
}
}
As you can see, I just used the coordinates and size of your buttons to check if the click was located inside one. That's kind of ninja-ing my way out of this issue. I don't know how far into programming you are, or else I would recommand to build a class to handle user inputs, but this way is easy to manage for small exercises like homework.
2. Designing controlP5 buttons
I'm not a ControlP5 expert, so we'll keep close to the basics.
I'll be blunt, the code you provided is ripe with problems, and it's not so many lines, so instead of pointing where it goes wrong I'll give you some skeleton code which will work and on which you can build some understanding. I'll give you the tools and then you can make your project work.
When you design your buttons, if you design them all in the same object, they'll share some properties. For an example, all your buttons will be visible or invisible at the same time. You don't need to redraw them all the time, because they already handle this, so you need to manage them with another method.
You should design your buttons as global objects (as you did), and add them to the ControlP5 object which makes the most sense. You can have one button per object if you want, or many if they are linked together, for an example all the "menu" buttons which appears at the same time could be owned by the same object. Design your buttons in the setup() method if you design them only one time for the whole program. Of course, if this was more than an homework, you may want to avoid the buttons being globals, but it'll be much easier to keep them in memory for a short project.
The "name" of the button is also the name of the method that it'll try to call if you click on it. Two buttons cannot share the same "name". Buttons can have a set value which will be sent to the method that they call.
You don't need to use Processing's mouse events for the buttons to work. They are self-contained: they have their own events, like being clicked on or detecting when the mouse is over them. Here's the documentation for the full list of the methods included in the ControlP5 buttons.
You don't need to manage the buttons in the draw() loop. They manage themselves.
Here's some skeleton code to demonstrate what I just said. You can copy and paste it in a new Processing project and run it to see what's going on.
ControlP5 cp5;
ControlP5 flipVisibilityButton;
int Page = 0;
void setup() {
size(1920, 800);
textAlign(CENTER, CENTER);
textSize(60);
fill(255);
cp5 = new ControlP5(this); // this is ONE object, which will own buttons.
cp5.addButton("MenuButton0") // this is the name of the button, but also the name of the method it will call
.setValue(0) // this value will be sent to the method it calls
.setPosition(1420, 250)
.setSize(400, 100);
cp5.addButton("MenuButton1")
.setValue(1)
.setPosition(1420, 450)
.setSize(400, 100);
cp5.addButton("MenuButton2")
.setValue(2)
.setPosition(1420, 650)
.setSize(400, 100);
flipVisibilityButton = new ControlP5(this); // this is a different object which own it's own controls (a button in this case)
flipVisibilityButton.addButton("flipVisibility")
.setValue(2)
.setPosition(200, height/2)
.setSize(200, 100);
}
void draw() {
// No button management to see here
background(0);
// showing which button has been pressed while also keeping watch to see if the mouse is over one of the cp5 buttons
text(Page + "\n" + cp5.isMouseOver(), width/2, height/2);
}
void MenuButton0(int value) {
ChangePage(value);
}
void MenuButton1(int value) {
ChangePage(value);
}
void MenuButton2(int value) {
ChangePage(value);
}
void ChangePage(int value) {
Page = value;
}
void flipVisibility(int value) {
// When the buttons are invisible, they are also unclickable
cp5.setVisible(!cp5.isVisible());
}
You should be able to expand on this example to do your project, but if you have difficulties don't hesitate to comment here and ask further questions. Have fun!

memory game java gui

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.

how to display the "Game over" image in android for a fixed amount of time and restart the game when user taps the screen after a specified interval?

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

Do not change right the icon,java

i have a problem with my code. I think that my problem is easy,but i have compiled for 3 days without good results. I have three images. They are put on screen one-one each time. User choose from 4 button if image's side is up, down, right or left. Also, i want to understand if user was wrong and then i will count errors. When user make 3 errors then the game will stop. I have shown code below. Please help me if you have any good idea.
The problem is that at the first loop,run right.It goes at the first if. After that it do the loop and then it does not go to second if.
if it is more helpful,some details:
i want to make a programma that it will show to user an image.This image has 4 sides (up,down,right,left).When the image is at "up side",user has to click on up button,when the image is at "down side",user has to click on down button etc. User can do 3 errors max. At first,program show the image at right side,if user clicks on right button then i want to show the "second image" at left side.If user does not at left side,then i want to add an error(error++) and after it shows the third image at up side etc. I hope it is more helpful to understand. If you can't please let me know.
My program is at Netbeans,java.
Thank you
public void actionPerformed(ActionEvent e)
{
while(errors<3)
{
image.setIcon(createImageIcon("visual1" + e.getActionCommand() + ".PNG"));
if (k==1)
{
if(e.getSource() == right_button)
{
image.setIcon(createImageIcon("visual2" + e.getActionCommand() + ".PNG"));
}
}
else if ( k==2 )
{
if(e.getSource() == left_button )
{
image.setIcon(createImageIcon("visual3" + e.getActionCommand() + ".PNG"));
}
}
else if (k==3 )
{
if(e.getSource() == up_button)
{
System.out.print("if3");
}
}
else
{
errors++;
}
k=k+1;
}
}
You should consider calling Repaint and Invalidate, right after you update your GUI like this -
mainframe.repaint();
mainframe.invalidate();
here mainframe is your JFrame object.
A problem I see with your while loop is that it is at risk of getting stuck in an infinite loop, since the variable used as an exit criterion is only updated some of the time, in an else block. I think you should re-arrange your logic:
Get rid of that while loop as it will only cause trouble. It is useful for a linear command line program but not for an event-driven GUI program like yours.
Read in all images and create all ImageIcons in the class constructor, and store them in variables. There's no need to re-read the images multiple times (unless they're huge).
Instead of using a while loop, increment the error variable in your method above, and then write the method so that it will change behaviors depending on the value of error (depending on the state of the class).
e.g.,
// somewhere in your code create your icons
Icon rightIcon = ......;
Icon leftIcon = .....;
Icon upIcon = .....;
Icon downIcon = .....;
// elsewhere in your code
public void actionPerformed(ActionEvent e) {
if (errors >= 3) {
// notify user of error
return; // end this method
}
// check if current icon matches image
// if so, change icon
// if not increment error
}
Note that an enum Direction {UP, DOWN, LEFT, RIGHT} and a Map<Direction, Icon> could be helpful here.

ActionEvent in Java moves multiple buttons

Okay so I am pretty much doing a crash course through creating a java application and am having an issue with executing an action. The program is the 15 puzzle, the game where you slide one piece at a time and try to get all numbers in order, so I allow for an 'Auto' mode option that will solve the board for the user once clicked. So my code reads the solution from a text file which is working fine just none of the 'squares' (JButtons) move when I click the auto button. So i am not sure if I just don't understand the action even process completely or not. heres my code, I can supply more of it if necessary.
if (e.getSource() == ctrButtons[0]) {
System.out.println("Auto Mode started\n");
Scanner s = null;
try {
s = new Scanner(new BufferedReader(new FileReader("move_list.txt")));
int count = 0;
while (s.hasNext()) {
//Cycle through to move in move_list
if (count != 18) {
s.next();
count+=1;
}
else {
int cur_move = Integer.parseInt(s.next());
count = 0;
/*Use cur_move to move blank space accordingly
*UP------------3
*LEFT----------2
*RIGHT---------1
*DOWN----------0
*/
int zero_index = -1;
for (int j=0; j<jbnButtons.length; j++) {
if (Integer.parseInt(jbnButtons[j].getText()) == 0) {
zero_index = j;
break;
}
}
Point zero = jbnButtons[zero_index].getLocation();
//Check if move is up
if (cur_move == 3) {
Point next = jbnButtons[zero_index-4].getLocation();
jbnButtons[zero_index].setLocation(next);
jbnButtons[zero_index-4].setLocation(zero);
}
//Check if move is left
else if (cur_move == 2) {
Point next = jbnButtons[zero_index-1].getLocation();
jbnButtons[zero_index].setLocation(next);
jbnButtons[zero_index-1].setLocation(zero);
}
//Check if move is right
else if (cur_move == 1) {
Point next = jbnButtons[zero_index+1].getLocation();
jbnButtons[zero_index].setLocation(next);
jbnButtons[zero_index+1].setLocation(zero);
}
//Check if move is down
else {
System.out.println("Current move = 0");
Point next = jbnButtons[zero_index+4].getLocation();
jbnButtons[zero_index].setLocation(next);
jbnButtons[zero_index+4].setLocation(zero);
}
}
}
}
So my code executes when I click the 'Auto' button and I was printing output to the screen to see if it was looping through the code which it was, just none of the buttons move each time through the loop. Any ideas??
You code is executing on the Event Dispatch Thread. The GUI can't repaint itself until the code finishes executing, so you won't see the intermediate steps only the final location of each component.
Read tje section from the Swing tutorial on Concurrency for a more complete explanation.
Maybe you should use a Swing Timer (the tutorial also has a section on this). Each time the Timer fire you do the next move.

Categories

Resources