Adding a timer to a for loop - java

I'm writing code that moves a token piece around a monopoly board based on certain coordinates. Currently, it prints it in each square but I'm trying to get it to print in each square, with a timer so you can see each square printing and when it prints in one square, it removes the print in the previous square so the token can only be in one square at a time. This is the code I have so far:
for(int g=0;g<10;g++)
{
JLabel redtoken = new JLabel(new ImageIcon ("src/TokenRed.png"));
redtoken.setBounds(x[g],y[g], 10, 10); // Size and position set
LPane.add(redtoken, new Integer(3)); // Red token set as layer 3
}
Test using a selection of coordinates: (Token is Red Square)

If I understand correctly, you want to see a red token hopping from square to square.
I suggest something like that :
Object lastPrinted = null;
for(int g=0;g<10;g++)
{
if(alreadyPrinted != null){
deleteToken(alreadyPrinted);
}
printNewToken(g)
try {
Thread.sleep(300);
} catch (InterruptedException e) {
Thread.currentThread().interrupt();
System.err.println(e);
}
}

Related

How to fix bug with endless writing of numbers using FileWriter with append argument

I faced one problem which I’m struggling to solve.
Imagine simple game, where some object , lets call it car, remains motionless on X-axis ( x = 50 ) and is able to move only on Y-axis (up and down). At the same time, another objects are created beyond the screen at random point ( and move toward my first object ) , so their coordinates decrementing on X-axis. As soon as every object reaches my first object coordinates, some variable int scores; increments.
int scores;
if(cars.getX() == getCarPos_X() && cars.getY() != getCarPos_Y() )
scores++;
Basically this game looks like car which goes between other cars and avoid hitting, and counter scores increments every time my car pass next moving car.
So what is the problem?
I use timer which count time between repainting. All objects pass to the paintComponent where actually all graphic draw. In actionPerformed I call methods for all moves, and one method which checks if collision with another car occurred. In case of collision, game stops, and scores should be written in some txt file.
The problem is that while two objects have same coordinates, JVM write endless number of figures (scores) into the file ( I think it’s because coordinates stop decrementing and every timer interval it checks for collision and it’s == true , as game is stoped , and object remains where they are.)
So my scores in txt file looks like :
0
0
0
0
In one column.
Or it displays any score which I’ve got.
And so on...
Here is the crucial code snippet which I used
public void actionPerformed(ActionEvent e)
{
animate();
checkTouch();
}
private void animate()
{
//here code that creates obstacles and moves them
}
checkTouch()
{
//objects creating in some inner class Cars and add to ArrayList ( I don’t mention about it as it is beside the point )
for(Cars car : cars)
{
if((cars.getX() == getCarPos_X && cars. getY() == getCarPos_Y())
{
//boolean var which stops game
inGame = false;
writeScore();
}
}
}
public void writeScore()
{
File scoresTxt = new File("scores.txt");
FileWriter fw = null;
BufferedWriter bw = null;
try
{
fw = new FileWriter(scoresTxt, true);
bw = new BufferedWriter(fw);
bw.write(scores + "\n");
}catch (IOException e)
{
e.printStackTrace();
}finally
{
try
{
bw.flush();
bw.close();
fw.close();
}catch(IOException e)
{
e.printStackTrace();
}
}
}
public void paintComponent (Graphics g)
{
if(inGame)
{
g.drawImage(myCar, 50, 100, this);
for(Cars car : cars)
{
g.drawImage(obstacleCar, car.getX(), car.getY(), this);
}
}
}
Should you need some extra code I used, write comment and I’ll add it.
And again I need to fix bug which write endless column of numbers instead of one final score from the moment of collision.
What’s wrong with my code , and how to solve this problem?
Give me advice for simplest decision, as I’m beginner.
Thanks in advance!
If your timer is started like this, or something similar, the you could cancel it when the inGame variable becomes false. Nice article on timers.
TimerTask task = new TimerTask() {
public void run() {
if (!inGame)
cancel();
else
// whatever it is that you are doing now
}
};
You might also want to stop processing events in the actionPerformed(e) method in a similar way.
if (!inGame)
return;

return origin color values of a picture

I'm doing an assignment about editing picture in java. The assignment asks to make a code changing an image's colors into 3 different shades and animate it so it'll be like a GIF. I completed the tasks but somehow when it change between the shades the picture get loose of detail and leave out just a blue blank color on the third shade change. I tried add a code return the color value to origin before changing the next one but still this issue happen. Might be I get the code wrong. Can someone help me with this.
/* Assignment 3, Part 1 - Go Psychedelic! */
public class Assignment3Part1
{
//
public static void main(String [] args) throws InterruptedException
{
String filename;
if (args.length > 0) {
// got a filename passed into program as a parameter
// don't change this part of the code needed by TA for grading
filename = args[0];
System.out.println("Filename passed in: " + filename);
} else {
// ask user for a picture
filename = FileChooser.pickAFile();
System.out.println("User picked file: " + filename);
}
Picture pic = new Picture(filename); // Picture to modify
//
pic.show(); // Show the original picture
Thread.sleep(1000); // Pause for 1 second. You can pause for less if you like
// TODO: insert method call to tint your picture
pic.tintRed(50);
pic.repaint(); // Show the tinted picture
Thread.sleep(1000); // Pause for 1 second
// TODO: insert method call to tint your picture
pic.tintRed(-50);
pic.tintGreen(20);
pic.repaint(); // Show the tinted picture
Thread.sleep(1000); // Pause for 1 second
// TODO: insert method call to tint your picture
pic.tintGreen(0);
pic.tintBlue(10);
pic.repaint(); // Show the tinted picture
Thread.sleep(1000); // Pause for 1 second
} // End of main method
} // End of class
Codes for the method
public void tintRed(int percent)
{
Pixel[] pixelArray = this.getPixels();
Pixel pixel = null;
int value = 0;
int i = 0;
//loop through all the pixels in the array
while (i<pixelArray.length)
{
// get the current pixel
pixel = pixelArray[i];
// get the value
value = pixel.getRed();
// set the value to % of what it was
pixel.setRed((int)(value*percent));
// increment the index
i++;
}
}
Same for Blue and Green values
You are saturating the colors to a point where everything is 100% a color (a blank picture). You have to play with your shading algorithm to be more gentle: like 25%, 50%, 75% for instance

Can't Run Method and Its GUI From Inside a Try Catch

I am trying to execute the lines:
Balldemo bd = new BallDemo();
bd.bounce(myInt);
In the below code:
public void actionPerformed(ActionEvent evt) {
String text = textField.getText();
try {
myInt=Integer.parseInt(textField.getText());
BallDemo bd = new BallDemo();
bd.bounce(myInt);
int newInt = myInt + 5;
System.out.println("Integer is: "+newInt);
}
catch (NumberFormatException ex) {
System.out.println("Not a number");
}
//Make sure the new text is visible, even if there
//was a selection in the text area.
textArea.setCaretPosition(textArea.getDocument().getLength());
}
But is does not boot the program correctly as follows:
program is a canvas with two balls that move, bounce(int numberOfBalls) will draw the balls on the canvas and start them moving.
In the above code, the canvas is created but the balls do not appear.
However, in a different class under the main method it works fine.
Basically don't understand why it won't successfully execute in a try-catch loop.
I suspect your BallDemo object (bd) is going out of scope as soon as the try block ends. Try declaring it outside the try block.

Gridbag layout or Grid layout?

I am a little new to swing. In order to learn to use the API correctly, I am designing the following project:
The project is a solving block puzzle solver sliding block puzzle similar to the rush-hour puzzles common in toy stores - https://en.wikipedia.org/wiki/Rush_Hour_(board_game) except there is no escape for a special car.
By dragging the blocks from an off board area to the board, the user specifies the starting configuration of the puzzle. The user, in the same way, specifies an ending goal configuration which dictates where some (or all) of the blocks the user specified initially must be at the end of the puzzle - the ending configuration can be specified using only SOME of the blocks, making multiple legal ending configurations.
The algorithm for solving the puzzle is already complete - I just need to design the interface and I am getting stuck. For designing the tray, I used a grid layout. Since blocks need to be entered at certain positions, I need to be able to place blocks in specific cells in the grid and move them around.
A 'block' object has four attributes - its height, width, its top row, and its left most column (ie - each block is addressed by its top left corner).
I used the suggestion here ( https://stackoverflow.com/questions/2510159/can-i-add-a-component-to-a-specific-grid-cell-when-a-gridlayout-is-used ) for the grid layout.
Right now I have only programmed to the point where java reads the puzzle from a .txt file and is supposed to display it on the screen ( I have not designed any user interactablity yet ).
First, here is the code I have written so far.
public class SolverPuzzleGUI extends JFrame {
//Specs from the puzzle.
Board initBoard;
ArrayList<Block> goalBlocks;
LinkedList<Move> moveList;
JLayeredPane layeredpane;
JPanel Board;
Dimension boardsize = new Dimension(400, 500);
JPanel[][] panelHolder = new JPanel[5][4];
public SolverPuzzleGUI(Board startBoard, ArrayList<Block> startGoalBlocks,
LinkedList<Move> startMoveList) {
this.initBoard = startBoard;
this.goalBlocks = startGoalBlocks;
this.moveList = startMoveList;
} // end constructor.
//gives the actual simulation
public void runSimulation() {
// Initalizing the main window.
setSize(500, 600);
setName("Solution");
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
setMinimumSize(getMinimumSize());
//Using layered pane
layeredpane = new JLayeredPane();
add(layeredpane);
layeredpane.setPreferredSize(boardsize);
layeredpane.setBackground(Color.YELLOW);
layeredpane.setVisible(true);
// adding the game tray
Board = new JPanel();
layeredpane.add(Board, JLayeredPane.DEFAULT_LAYER);
Board.setLayout(new GridLayout(5, 4));
// centering the game tray.
Board.setPreferredSize(boardsize);
Board.setMinimumSize(boardsize);
Board.setMaximumSize(boardsize);
Box box = new Box(BoxLayout.Y_AXIS);
box.add(Box.createVerticalGlue());
box.add(Board);
box.add(Box.createVerticalGlue());
add(box);
//Adding placeholders to the board for creating blocks
for (int i = 0; i < 5; i++) {
for (int j = 0; j < 4; j++) {
panelHolder[i][j] = new JPanel();
panelHolder[i][j].setBackground(Color.DARK_GRAY);
Board.add(panelHolder[i][j]);
layeredpane.setLayer(panelHolder[i][j], JLayeredPane.DEFAULT_LAYER);
panelHolder[i][j].setVisible(false);
} // end 'j' for
} // end 'i' for
ArrayList<Block> initBlocks = initBoard.getBlocks();
//int count = 0; //DEBUG
for (Block block : initBlocks) {
this.drawBlock(block);
//count++;
//if(count > 4) { break; }
} // end 'for'
Board.setBackground(Color.DARK_GRAY);
Board.setVisible(true);
setVisible(true);
} // end 'run'
private void drawBlock(Block block) {
Dimension blockSize = new Dimension(block.getWidth()*100, block.getHeight()*100);
System.out.println(blockSize.width);
System.out.println(blockSize.height);
JPanel screenBlock = new JPanel();
screenBlock.setPreferredSize(blockSize);
screenBlock.setMinimumSize(blockSize);
screenBlock.setMaximumSize(blockSize);
screenBlock.setSize(blockSize);
screenBlock.setBackground(Color.BLUE);
screenBlock.setBorder(BorderFactory.createLineBorder(Color.BLACK));
layeredpane.setLayer(screenBlock, JLayeredPane.MODAL_LAYER);
int leftRow = block.getRow();
int leftCol = block.getColumn();
panelHolder[leftRow][leftCol].setSize(blockSize);
panelHolder[leftRow][leftCol].setVisible(true);
panelHolder[leftRow][leftCol].add(screenBlock);
layeredpane.setLayer(panelHolder[leftRow][leftCol], JLayeredPane.MODAL_LAYER);
screenBlock.setVisible(true);
}// end 'drawBlock'
public static void main(String[] args) {
String file = "C:\\Users\\Tim\\Desktop\\init.from.handout.txt";
String goal = "C:\\Users\\Tim\\Desktop\\goal.2.from.handout.txt";
/*
A SolverPuzzle object is the object which actually solves the algorithm -
when the class is constructed, it takes the file path of the inital
configuration as an input, as well as the file path of the goal
configuration. It has the following fields:
A 'board' object which specifies the inital configuration of the board.
It contains an ArrayList of Block objects(Remember block objects store
the height and width of the block, as well as the address of the
top left corner of block) which specify the starting
blocks, an ArrayList of EmptySpace objects which specify the empty
spaces on the board, an ArrayList of Move objects, which contain
the legal moves of the configuration, and the height and width of
the tray (in this application, the tray will always be 5 x 4).
An ArrayList of Block objects which specify the ending configuration.
A LinkedList of Move objects which specify the shortest possible
list of Moves which brings the configuration to a position which
satisfies the goal position. A Move object has three fields -
The block object being moved, and the row and column of the
top left corner of the block in the new position.
*/
SolverPuzzle test;
try { test = new SolverPuzzle(file, goal); }
catch (IOException ex) {
System.out.println("IOException");
return;
}
Board testBoard = test.getStartBoard();
ArrayList<Block> testGoalBlocks = test.getGoalBlocks();
LinkedList<Move> testMoveSolution = test.getMoveList();
// testing the gui
SolverPuzzleGUI testGUI = new SolverPuzzleGUI(testBoard, testGoalBlocks,
testMoveSolution);
testGUI.runSimulation();
}
} // end class 'SolverPuzzleGUI'
Here's the current output vs desired output.
http://imgur.com/a/ykXXP
So specifically, I have two questions:
1 - Why is the image only showing the top left corners of the blocks instead of the whole block?
2 - Is it better to continue using the GridLayout or switch to GridBagLayout?
Thanks
GridBagLayout would definitely be suitable for want you want to do. For example, you can expand components to envelop more than one column or row - just like what you want to do. Check out the java tutorials for how to use them.
A key point to remember when using GridBagLayoutis that you need to reset the Constraints after each component, assuming that they're unique to that particular component.
Also - I can't discern what you mean by only showing the top-left - it looks likes its showing the whole thing to me...

Slick2d, How can i draw a string on screen for a few seconds?

I've been trying to figure this out, all I want to do is be able to draw a string for longer than just a frame, but when I call it in the method I want it to flash up then disappear immediately, any advice would be appreciated :) I'm using something like this:
g.drawString("You got a Key!", 100, 100);
I'm doing this in a method which is called after an Item is picked up
public void addItemFound(Graphics g){
ip.mainInventory[ip.getFirstEmptyStack()] = getItemStackFound();
System.out.println(this.getItemFound() + " added");
g.drawString("You Got a Key!", 100, 100);
}
That's the full method if you were interested :) Thanks!Also apologies for the dumb question, i'm a newbie to this :P
I believe that the best way to do this project would be to draw the scene at regular intervals e.g. 10 milliseconds using a Thread.sleep(). This way, you can simply add a variable to show the message for, say, 100 loops (1 second) like this:
private LinkedList<String> drawStringList= new LinkedList<>();
private LinkedList<Integer> drawStringTimeout= new LinkedList<>();
private LinkedList<Integer[]> drawStringPos= new LinkedList<>();
public void addText(String stringToWrite, int posX, int posY, int timeOut) {
drawStringList.add(stringToWrite);
int[] pos = new int[2];
pos[0] = posX;
pos[1] = posY;
drawStringPos.add(pos);
drawStringTimeout.add(timeOut);
}
private void mainLoop() {
...items to be drawn here...
for(int i=0;i<drawStringList.size();i++){
g.drawString(drawStringList.get(i),drawStringPos.get(i)[0],drawStringPos.get(i)[1]);
drawStringTimeout.set(i,drawStringTimeout.get(i)-1);
if(drawStringTimeout.get(i)<=0) {
drawStringList.remove(i);
drawStringTimeout.remove(i);
drawStringPos.remove(i);
}
}
try { Thread.sleep(10); } catch (Exception e) {}
}
In this code, you must add the string you want to draw to drawStringList, add the number of loops you want it to stay for to drawStringTimeout and add the position you would like to draw it in to drawStringPos as an array (you could use a point if you wanted to). I have made a method to do this.
I don't know what Dan300 is trying to tell you to do but that's way, way, way over complicated. Slick2D works on gamestates:
http://slick.ninjacave.com/javadoc/org/newdawn/slick/state/GameState.html
The gamestate has a method called render(). The render() is called every single cycle of the loop to update your screen with drawing information. If you want to draw the text on the screen for a longer time you should be drawing the text somewhere within the stack space of this render() function.
What is happening now is you have a function with one specific purpose that only exists every so briefly: add an item to the player. The game comes across this statement and when adding an item within that 1 cycle the text will be drawn. But the next cycle when the player isn't picking up an item it won't come by that drawString statement and you won't have your string on your screen longer than 1 game cycle.

Categories