Using if statements - java

In this program, the user will be asked to input 2 words, (firstWord and secondWord). The two words will automatically appear on the screen once the object is created.
firstWord is set to change its position on the screen via a while loop.
secondWord will stay in a fixed position.
I want the loop to end once the X position or Y position of firstWord is the same as secondWord.
The XY position of secondWord = (155, 361)
So for instance, something like:
if (word1.xPosition = 155) {
break;
}
Obviously, that code is wrong, it is just to give you
an idea of what I want to achieve.
So how would I write this if statement?
My code is pasted below:
public words(String w1, String w2)
{
// initialise instance variables
firstWord = new Text(w1);
firstWord.randomizePosition();
firstWord.changeColor("green");
firstWord.changeSize(48);
firstWord.makeVisible();
secondWord = new Text(w2);
secondWord.setPosition(155, 361);
secondWord.changeColor("orange");
secondWord.changeSize(48);
secondWord.makeVisible();
public void draw()
{
while(true) {
firstWord.randomizePosition();
}
if(firstWord.xPosition = ){
break;
}
}
Replace the if statement

If you want to align both elements on EITHER x OR y, you should change your while loop to:
while(firstWord's X == secondWord's X || firstWord's Y == secondWord's Y)
firstWord.randomizePosition();
According to your description, this should work. Of course, you can always add a small delay to be able to see the animation, if you want to.

I want the loop to end once the X position or Y position of firstWord is the same as secondWord
while (!( firstWord.getXPosition() == secondWord.getXPosition() ||
firstWord.getYPosition() == secondWord.getYPosition())
{
firstWord.randomizePosition();
}
"While the first position doesn't equal the second position's X or Y position, change the first position"
If you are expecting to draw these labels on a GUI, don't expect to see any movement without a Thread that redraws the elements between moves.

Related

Correct usage of Recursion

I am just wondering if my usage of recursion is correct. The code works for the intended purpose; however, I am not sure if it is actually doing recursion. I have tried tracing through my program, but I don't understand why my output is correct. Basically, the program takes in a data file of spaces and blobs of '*' and my program is supposed to recursively calculate the number of blobs given a certain row and column in the array of spaces and blobs. The problem is that I am not sure why exactly when I used variables like north, south, east, west, it would be able to successfully return the values to me, as it seems that during recursion, each variable just exists within that call. Also, I am not sure why exactly north = count(row,col+1) would give a value for north, since everytime I iterate through the recursion of count, it doesn't seem to stop at a definite value for north, as in like it doesn't seem to stop and say to return 1 as north.
public static int count(int row, int col) {
int north = 0, south = 0, east = 0, west = 0;
if (map[row][col] == BLOB) {
map[row][col] = MARKED;
if (map[row][col+1] == BLOB) {
north = count(row,col+1);
}
//Go South
if (map[row][col-1] == BLOB) {
south = count(row, col-1);
}
//Go East
if (map[row+1][col] == BLOB) {
east = count(row+1, col);
}
//Go West
if (map[row-1][col] == BLOB) {
west = count(row-1, col);
}
return (1 + north + south + east + west);
}
return 0;
Recursion is just having a method call its self. Therefore, this is recursion.
You are correct in that each variable only exists in the scope of each call. However, they are being defined based off of the other recursive calls.
It seems that this code is trying to fill in an array (and the end case is when the part of the array is filled in). This would be why it seems like it doesn't stop calling its self (as it would take many recursive calls before end cases are met).

Java - Loop gets executed, but header doesnt fit condition

This function should check if the explosion hit a box and should be canceled on the first box it hits.
For example bsp.getBomb().getStrength() is currently 2, when a box is hit i=3, but the loop is executed one more time even if the condition isn't met, why is that?
public void detectBomb(BombSpritePair bsp) {
for(int i = 0; i <= bsp.getBomb().getStrength(); i++) {
if(bd.detect(bsp.getBomb().getX(), bsp.getBomb().getY()+i)) {
Sprite sprite = new Sprite(new Texture("gras.png"));
sprite.setPosition(bsp.getBomb().getX()*16, (bsp.getBomb().getY()+i)*16);
// i = bsp.getBomb().getStrength()+1;
sprites.add(sprite);
System.out.println("RIP"+i);
System.out.println(bsp.getBomb().getStrength());
break;
}
}
}
Try adding break to the loop:
public void detectBomb(BombSpritePair bsp) {
for(int i = 0; i <= bsp.getBomb().getStrength(); i++) {
if(bd.detect(bsp.getBomb().getX(), bsp.getBomb().getY() + i)) {
Sprite sprite = new Sprite(new Texture("gras.png"));
sprite.setPosition(bsp.getBomb().getX()*16, (bsp.getBomb().getY()+i)*16);
sprites.add(sprite);
System.out.println("RIP"+i);
System.out.println(bsp.getBomb().getStrength());
break;
}
}
}
You may be seeing duplicate print statements if you are calling the detectBomb method multiple times. Putting a breakpoint or print statement at the beginning of this method will help determine what the problem is.
Another thing to keep in mind is that you are creating a new Texture for the Sprite every time the method get executed - it would be wise to only instantiate the Texture once and share it with all subsequent Sprite instances that require it.

How to take a second actionPerformed for moving a chess piece?

I am making a chess game and need to figure out how to move the pieces. I have my pieces stored in an array squaresGrid[][] and I want to use the method moveTo to move the pieces. Currently this method simply marks a piece selected but I need it to take a second mouse click to choose the square to move the selected piece to but am not sure how best to do this.
public void actionPerformed(ActionEvent e)
{
for(int x = 0; x < 8; x++)
{
for(int y = 0; y < 8; y++)
{
if(e.getSource() == squaresGrid[x][y])
{
moveTo(e, squaresGrid[x][y]);
}
}
}
}
public void moveTo(ActionEvent e, JButton clicked)
{
clicked.setIcon(selected);
}
You don't do a "second actionPerformed". What you do is keep around state, and when a click happens, look at the state, and decide what the action should be.
For example, keep around a field called currentlySelected, pointing to the currently selected square (containing its coordinates, for example).
In the actionPerformed, when you receive a click, you look at currentlySelected.
If it is null, it means you are supposed to select the clicked square and put it in currentlySelected.
If it is not null, and the current click is in the same square, the user probably wants to de-select it. De-select and clear (put null) in currentlySelected.
If it is not null and not the same square, it means that you have to check if the move is legal. If it is legal, you can do the move, and clear currentlySelected. If it is not legal, you do what you think is the proper thing to do: perhaps de-select the original place and select the new one. Or just de-select and tell the user the move is not legal. Or keep it selected.
Remember to always clear your currentlySelected in the appropriate situations.
You don't need a second ActionListener or actionPerformed method, but rather you need a state-ful ActionListener, one that knows whether the button push represents the first push or the 2nd. A boolean variable could be all that is required for this. Another option is to use a variable to represent the first pushed location, set it equal to null initially and then set it equal to the position on the first push. On the 2nd push check if it is null or non-null and if non-null, the button push represents the 2nd push. Then set it back to null.
For example
public void actionPerformed(ActionEvent e) {
for(int x = 0; x < 8; x++) {
for(int y = 0; y < 8; y++) {
if(e.getSource() == squaresGrid[x][y]) {
if (gridLocation == null) {
// class to hold x and y location
gridLocation = new GridLocation(x, y);
} else {
// use gridLocation here
int firstX = gridLocation.getX();
int firstY = gridLocation.getY();
moveTo(e, x, y, firstX, firstY);
gridLocation = null;
}
}
}
}
}

How to collect only one value from a JToggleButton when a mouse moves over the container?

I am working on doing a word finder puzzle game. When I am trying to get to happen is a user clicks on a letter then moves his mouse across other letters to create a word. I am having some problems with the listeners. I have been going back and fourth using mouseDragged and mouseMoved. So far mouseMoved seems to work better because it dynamically grabs values. The problem is I can't figure out how to get it only grab one value. In an ideal world it would move of a Button or label grab that value once and ignore the value till it reaches a new button or label. Currently it just grabs values at every instant a mouse is on that container. The logic for my Mouse method is below:
public void mouseMoved(MouseEvent e) {
int count = countClicked;
int num = 0;
for(JToggleButton row : puzzleGrid){
if(e.getComponent() == row && count == 1) {
if(num == 0){
num++;
for(JLabel l: solWords)
{
sb.append(row.getText());
System.out.println(l.getText()+" = "+ sb.toString());
if(l.getText().contentEquals(row.getText()))
System.out.println(row.getText());
}
}
}
}
}
I am using the value gathered from the containers to check against an array of JLabels containing the solution values.
You could store the last letter in a static variable:
static String lastLetter = null;
mouseMoved(...) {
if(row.getText().equals(lastLetter)) {
continue;
}
lastLetter = row.getText();
}

Trying to avoid a Force close after a bullet goes off screen

So I'm just messing around learning to create a Space invaders type game. I can get the bad guys to move, Great!!. Hero moves, Great!! Bullets move, Great!! However I try to remove my bullets once they leave the screen as to not eat up all resources and it force closes on me once it gets rid of the bullet. It goes off the screen. Hits the int of -2 and then we use the remove() and boom. Force Close.
Here is my code. I'm wondering if they access the size() at the same time and just cause a force close because of it.
//I removed everything that doesn't pertane to the bullets.
public class GameScreen{
Bullet bullet = world.bullet;
public GameScreen(Game game) {
super(game);
world = new World();
}
//Draws our bullets.
int bulletLength = bullet.bullets.size();
for(int i = 0; i < bulletLength; i++) {
Placement part = bullet.bullets.get(i);
x = part.x * 32 + 11;
y = part.y * 32;
g.drawPixmap(Assets.bullet, x, y);
}
Class that holds my bullets.
public class Bullet {
public List<Placement> bullets = new ArrayList<Placement>();
public Bullet() {
}
public void shoot(int x, int y){
bullets.add(new Placement(x,y));
}
public void advance(){
int len = bullets.size(); // gets all bullets.
for(int i = 0; i < len; i++) {
bullets.get(i).y --;
if (bullets.get(i).y <= -2){//removes them once they are off the screen.
bullets.remove(i);
}
}
}
This is what I use to keep track of placement.
package com.learning.planecomander;
public class Placement {
public int x, y;
public Placement(int x, int y) {
this.x = x;
this.y = y;
}
}
When going through your list to remove bullets, you can remove bullets from a list but that affects the list immediately instead of after your loop is done. Since you are traversing to the length of the list at the start, you are going off the end of the list since you've removed elements. An example is probably more helpful than that description.
Let's say you have a list with three bullets (which I'll call a, b, c to make the example easier). On a pass through the list, a and c are fine but b needs to be removed.
i = 0;
bullets[0] = a;
bullets[1] = b;
bullets[2] = c;
First loop goes fine, second loop starts like this
i = 1;
bullets[0] = a;
bullets[1] = b;
bullets[2] = c;
We remove b, but the loop keeps going
i = 2;
bullets[0] = a;
bullets[1] = c;
OH CRAP ARRAYINDEXOUTOFBOUNDS! PROGRAM CRASHES!
The way to solve this is to use a temp list to store the bullets that need to be removed, and then once your update loop is finished, make a call to bullets.removeAll(temp)
Doing two passes is a good answer. It makes the loops simpler and easy to understand. If you'd like to do it in one pass though, iterate through the list in reverse order, and when you remove a bullet you can go to the next one and not worry about blasting past the end of the ArrayList.
Alternatively, you can keep your bullets in a linked list, and run through the list with an Iterator, which you can also use to remove items from the list with. Removing from the beginning middle or end of an linked list is always a constant time operation. Whereas removing from the beginning of an ArrayList can be more expensive. If you need random access to the elements in the list, then they can be inefficient. Keep in mind though, if you're only dealing with a handful of objects, then it doesn't really matter.
For bonus points, you might want to put all of your objects in a list, and then have your central loop process them all and have your game objects respond polymorphically to calls like dead?, think, move, draw or whatever you think is appropriate.

Categories

Resources