So i have a game where if my user collides with an image it will increase the score by 1. However because i use this method of collision detection and an if statement to increment my score, during the duration of the collision the score will go up by about 30 as the collision method detects it colliding multiple times as they pass through each other. How would i stop it from incrementing by more than one each time.
Here is my code:
void draw () {
if (gameMode == Active) {
if(crash() == false) {
drawBackground();
textSize(32);
fill(22,100,8);
text("Score: " + score ,20,40); //calls the drawBackground method
alien1.update();
alien2.update(); //constantly calls the move and render method for the alien and defender
alien3.update();
user1.render();
Burger.update();
if(Bcrash() == true) {
if(Bcrash() == false) {
score = score + 1;
}
}
} else {
gameMode = End;
textSize(32);
fill(22,100,8);
text("Game Over, press 'r' to restart",150,200);
}
}
}
boolean Bcrash() {
return user1.crash(Burger));
}
// Burger.class (Editor's note: I guess it's User.class)
public class User {
boolean crash(Burger A) {
return(abs(x-A.x)<=30) && abs(y-A.y)<=30;
}
}
Check to see if collision is false before allowing it to add another number.
something like:
Boolean collisionInProgress = false;
if(collision == true && collisionInProgress == false){
score = score+1;
collisionInProgess = true;
}
…loop…
if(collision == false){
collisionInProgess = false;
}
Related
I am making a Tic-Tac-Toe game with a computer player. However, whenever I call the computer's makeMove method, the computer continues to play without the user being able to do anything. Just to be sure that the function stopped, I made it return after each move, but it still plays the entire game without the user's input.
Here are the relevant parts:
Board Class:
public String addToBoard(char c, int square) {
if (!spaceFull(board, square)) {
int[] coords = getRowAndColumn(square);
//System.out.println("[" + coords[0] + "][" + coords[1] + "]");
board[coords[0]][coords[1]] = c;
return "VALID";
} else {
System.out.println("Space Is Occupied");
return "OCCUPIED";
}
}
public boolean spaceFull(char[][] b, int square) {
return (twoDimenToOneDimen(b).get(square - 1) == 'X' || twoDimenToOneDimen(b).get(square - 1) == 'O');
}
Computer Class
public void makeMove() {
int square;
//Checks For Any Winning Computer Moves
System.out.println("Here");
if ((square = nextMoveWinCheck(playerChar)) != 0) {
board.addToBoard(playerChar, square);
return;
//Checks For Any Opponent Winning Moves
} else if ((square = nextMoveWinCheck(opponentChar)) != 0) {
board.addToBoard(playerChar, square);
return;
} else {
//Checks If Computer Has First Move
if (boardEmpty()) {
board.addToBoard(playerChar, 9);
return;
} else {
//Moves Into Opposite Corner if Bottom Corner is Occupied By Itself
if (!board.spaceFull(board.board,1) && board.board[2][2] == playerChar) {
board.addToBoard(playerChar, 1);
return;
//Move Into Center If Second Move or Possible
} else if (!board.spaceFull(board.board,5)) {
board.addToBoard(playerChar, 5);
return;
} else if ((square = emptyCorner()) != 0) {
board.addToBoard(playerChar, square);
return;
} else {
board.addToBoard(playerChar, randomEmptySpot());
return;
}
}
}
}
If you want the full code, it's:
Computer
Board
Player
Tic-Tac-Toe Main Class
Your problem lies in your class Computer. On line 57, you assign board.board to tempBoard. However tempBoard still holds the reference to the object board.board, so whatever modifications you make there is reflected on the actual board. To resolve this, COPY the board values to tempboard:
http://www.java2s.com/Code/Java/Collections-Data-Structure/clonetwodimensionalarray.htm
In my method under the if statement:
if (currentLocationX == 0 && currentLocationY == 4)
I have a break statement that should make the program exit out of the while loop and return true for 'answer' and for the method. Yet after some testing it seems that after returning true for 'answer', it goes back into the while loop giving the wrong results int the end. Why is my break statement not doing what it's supposed to? Thank you!
P.S. (this method calls on some other method that were not relevant to mention here)
public boolean solveMaze()
{
boolean answer = false;
int currentLocationX;
int currentLocationY;
//push starting location
pushX(2);
pushY(1);
while((isEmptyX() == false) && (isEmptyY() == false))
{
printMaze();
System.out.println();
currentLocationX = popX();
currentLocationY = popY();
//mark current location as visited
visited(currentLocationX, currentLocationY, maze);
System.out.println("Current Location: " + currentLocationX + ", " + currentLocationY);
if (currentLocationX == 0 && currentLocationY == 4)
{
answer = true;
break;
}
else
{
//push all unvisited OPEN neighbor locations into stack
if (checkEast(currentLocationX, currentLocationY) == 0)
{
pushX(eastX(currentLocationX));
pushY(eastY(currentLocationY));
}
else;
if (checkSouth(currentLocationX, currentLocationY)== 0)
{
pushX(southX(currentLocationX));
pushY(southY(currentLocationY));
}
else;
if (checkWest(currentLocationX, currentLocationY)== 0)
{
pushX(westX(currentLocationX));
pushY(westY(currentLocationY));
}
else;
if (checkNorth(currentLocationX, currentLocationY)== 0)
{
pushX (northX(currentLocationX));
pushY(northY(currentLocationY));
}
else;
}
}
return answer;
}
I wrote out the basic logic of your method as
public static boolean solveMaze() {
boolean answer = false;
int currentLocationX = 0;
int currentLocationY = 4;
while (true) {
if (currentLocationX == 0 && currentLocationY == 4) {
System.out.println("Hit the break");
break;
} else {
System.out.println("Missed the break");
}
}
return answer;
}
and if you execute it you get Hit the break. So your solveMaze() method is fine in terms of breaking out of the loop once it satisfies your if-statement. I would say that if you see your code subsequently going back into the while loop, it must be that solveMaze() was called a second time.
Hi I'm writing a checkers engine and defining a canEat(Point1,Point2) method for player class which returns true or false based on if player can eat eat the piece at the specified points by checking if the pieces and landing path is on board, if the two pieces belong to the same player or not and also considering the king/super status of piece.
Anyways it works pretty pleasantly without recursion, but without recursion method must get points of the pieces instead of the landing piece which is okay if I manage the recursion. But I want the method to also consider if it gets the landing point instead of piece location. When I run the code it fixes the location and calls itself again there is no problem with that but. I get NullPointerException on
caneat = Checker2.isAlive() ? true : false; because Checker2 is null. My pointToChecker method returns null on this guy so Checker2 is null. What is causing this I'm new to recursion, even OOP to be honest and
Here is my code and console error log
public boolean canEat(Point Piece, Point target)
{
//INITIALIZING
//POINT1 & CHECKER1-> piece which eats
//POINT2 & CHECKER2-> piece to eat
//POINT3 & CHECKER3-> landing path
if (samePoint(Piece, target))
return false;
boolean caneat = true;
boolean king1 = false;
Point Point1,Point2,Point3;
Checker Checker1,Checker2,Checker3;
int ownerID, victimID,axis;
axis = getDirection(Piece, target);
//CHECK IF PLAYER POINTED THE SQUARE AHEAD TARGET PIECE OR THE PIECE TO EAT
int distance = getStep(Piece, target);
if(distance == 2)
{
boolean resolution;
System.err.println("Recoordinated target");
Point fixed = getBackwards(target, axis);
System.err.println("Fixed is: " + Piece + " " + fixed);
resolution = canEat(Piece, fixed);
return resolution;
}
Point1 = Piece;
Point2 = target;
Point3 = findMovePosition(target, axis);
if(!inBoard(Point1) || !inBoard(Point2) || !inBoard(Point3))
{
System.err.println("Error: Invalid Move --> Thinking outside the box");
return false;
}
Checker1 = PointToPiece(Point1);
Checker2 = PointToPiece(Point2);
Checker3 = PointToPiece(Point3);
//CHECK IF PIECES ARE ALIVE
caneat = Checker1.isAlive() ? true : false;
caneat = Checker2.isAlive() ? true : false;
if(!Checker2.isAlive())
{
return false;
}
//THERE SHOULD BE TARGET AND VICTIM PIECES AND AN EMPTY LANDING POINT
if(!isOccupied(Piece))
{
System.err.println("#OccupyChecker invalid piece to move");
return false;
}
if(!isOccupiedbyEnemy(target))
{
System.err.println("#OccupyChecker invalid piece to eat");
return false;
}
if(!(Checker3 == null))
{
System.err.println("#OccupyChecker landing piece error");
return false;
}
ownerID = Checker1.getOwner().getID();
victimID = Checker2.getOwner().getID();
if(ownerID == victimID)
{
System.err.println("owner ID: " + ownerID + " victimID: " + victimID);
System.err.println("#OCCUPY identity");
return false;
}
if(ownerID == 1 && king1)
{
if(axis == 3 || axis == 4)
System.err.println("#OccupyPoint wrong axis");
caneat = false;
}
if(ownerID == 2 && king1)
{
if(axis == 1 || axis == 2)
System.err.println("#OccupyPoint wrong axis");
caneat = false;
}
return caneat;
}
Checker PointToPiece(Point piece)
{
Checker[] allPieces = allPieces();
Checker found = null;
for(Checker k : allPieces)
{
if(samePoint(k.getPosition(), piece))
found = k;
}
return found;
}
#Override
public boolean onTouchEvent(MotionEvent event)
{
synchronized (getHolder())
{
int aktion = event.getAction();
if (aktion == MotionEvent.ACTION_DOWN)
{
touched = true;
bar.shareTouch(event.getX(), event.getY(), touched);
}
else if (aktion == MotionEvent.ACTION_UP)
{
touched = false;
bar.shareTouch(event.getX(), event.getY(), touched);
}
if (aktion == MotionEvent.ACTION_POINTER_DOWN)
{
touched2 = true;
bar.shareTouch2(event.getX(), event.getY(), touched2);
}
else if (aktion == MotionEvent.ACTION_POINTER_UP)
{
touched2 = false;
bar.shareTouch2(event.getX(), event.getY(), touched2);
}
}
return true;
}
This is a Code to chech if first Finger is going onto the screen or leaving it. The same for another finger.
public void shareTouch2(float xTouch2, float yTouch2, boolean touched2)
{
if (xTouch2 <= gameViewWidth/2) {
if (touched2 == true) {
touchedLeft2 = true;
}
else if(touched2 == false) {
touchedLeft2 = false;
}
}
else if (xTouch2 > gameViewWidth/2) {
if (touched2 == true) {
touchedRight2 = true;
}
else if(touched2 == false) {
touchedRight2 = false;
}
}
}
public void shareTouch(float xTouch, float yTouch, boolean touched)
{
if (xTouch <= gameViewWidth/2) {
if (touched == true) {
touchedLeft = true;
}
else if(touched == false) {
touchedLeft = false;
}
}
else if (xTouch > gameViewWidth/2) {
if (touched == true) {
touchedRight = true;
}
else if(touched == false) {
touchedRight = false;
}
}
}
private void moveRight()
{
x += 3;
}
private void moveLeft()
{
x -= 3;
}
private void checkTouch() {
if ((touchedLeft == true && touchedRight2 == false) || (touchedLeft2 == true && touchedRight == false)) {
moveLeft();
}
else if ((touchedLeft == false && touchedRight2 == true) || (touchedLeft2 == false && touchedRight == true)) {
moveRight();
}
else if ((touchedLeft == true && touchedRight2 == true) || (touchedLeft2 == true && touchedRight == true)) {
}
}
The checkTouch() is called in the onDraw() Method. Now if I place a finger on the right side of the screen it moves right. Same for left. But if I touch left and the right without removing the left finger the Object still moves left although it should stop. Now when I leave the left finger it still moves left although it should move right.
I hope you understand my problem.
Hope you can help
You can't just assume the ACTION_POINTER_UP Event will only be sent for the same finger ACTION_POINTER_DOWN was sent.
Just as the ACTION_DOWN event is always fired for the first finger to touch down, the ACTION_UP event is only fired for the last finger to lift (i.e. when there are no more fingers on the screen). All others will get an ACTION_POINTER_UP event, even if it's the finger that started the gesture.
However, the Android documentation does specify
Each pointer has a unique id that is assigned when it first goes down [and] remains valid until the pointer eventually goes up.
So in theory, your first and second finger should still have the same ID, regardless whether the Event that reports them.
The solution is simple, then: Use getPointerCount() and getPointerID() to keep track of your fingers.
This may be easier if you refactor your code to account for more than two fingers by replacing the Booleans touchedLeft and touchedLeft2 with a single counter, e.g. fingersOnLeftSide - which has the neat side effect of only needing one shareTouch() method and otherwise reducing redundancy in your code.
EDIT:
Disclaimer: This is just off the top of my head, untested and written without knowledge of any of your code other than what you posted. Not necessarily the best way to solve your problem, but the shortest I could think of.
This is the Event handler:
public boolean onTouchEvent(MotionEvent event)
{
synchronized (getHolder())
{
int aktion = event.getAction();
if (aktion == MotionEvent.ACTION_DOWN || aktion == MotionEvent.ACTION_POINTER_DOWN
|| aktion == MotionEvent.ACTION_UP || aktion == MotionEvent.ACTION_POINTER_UP)
{
bar.clearTouches();
for (int i = 0; i < event.getPointerCount(); i++) {
bar.shareTouch(event.getX(i)); // we don't need the y coordinate anyway
}
}
}
return true;
}
The rewritten shareTouch() to go along with it, as well as clearTouches() I introduced to make this simpler:
private void shareTouch(float x)
{
if (x < gameViewWidth/2) {
fingersLeft++;
} else {
fingersRight++;
}
}
private void clearTouches()
{
fingersLeft = 0;
fingersRight = 0;
}
And finally, the new checkTouch():
public void checkTouch()
{
if (fingersLeft > fingersRight) {
moveLeft();
} else if (fingersRight > fingersLeft) {
moveRight();
}
}
I have two search loops for performing different operations, but I'm unhappy with how repetitive this looks.
The first method used to remove an item is as follows:
public void RemovePlayer(int theID){
boolean matchFound = false;
if (playerObjects.size() != 0){
for (int i = 0; i < playerObjects.size(); i++){
Person playerToRemove = (Person) playerObjects.get(i);
if (playerToRemove.getID() == theID){
playerObjects.remove(i);
System.out.println("Player with ID # " + theID + " removed");
matchFound = true;
// As ID is unique, once a player is found it is unnecessary to continue looping
break;
}
// If matchFound is never set to true then show appropriate error
if (matchFound == false) {
System.out.println("Player with ID # " + theID + " not found");
}
}
}
else {
System.out.println("No players have been added.");
}
}
And the second method, which is essentially the same code, but performs a different action if a match is found is as follows:
public void RetrievePlayer(int theID){
boolean matchFound = false;
if (playerObjects.size() != 0){
for (int i = 0; i < playerObjects.size(); i++){
Person playerToRetrieve = (Person) playerObjects.get(i);
if (playerToRetrieve.getID() == theID){
System.out.println("PLAYER FOUND:");
playerToRetrieve.GetDetails();
matchFound = true;
break;
}
// If matchFound is never set to true then show appropriate error
if (matchFound == false) {
System.out.println("Player with ID # " + theID + " not found");
}
}
} else {
System.out.println("No players have been added.");
}
}
How can I refactor this?
How about a method "FindPlayer" that returns the index i of the player? RemovePlayer and RetrievePlayer then just would be:
public void RemovePlayer(int theID){
int playerId = FindPlayer(theID);
if (playerId >= 0) {
playerObjects.remove(playerId);
}
}
public void RetrievePlayer(int theID){
int playerId = FindPlayer(theID);
if (playerId >= 0) {
Person player = (Person) playerObjects.get(playerId);
player.getDetails();
}
}
That "FindPlayer" method would be somewhat like this:
protected int FindPlayer(int theID){
if (playerObjects.size() != 0){
for (int i = 0; i < playerObjects.size(); i++){
Person player = (Person) playerObjects.get(i);
if (player.getID() == theID){
return i;
}
}
System.out.println("Player with ID # " + theID + " not found");
} else {
System.out.println("No players have been added.");
}
return -1;
}
Put the Players in a Map<Integer,Player>. Then use Map's basic methods (put, remove) instead of looping through a list.
If you split then up, you could have a find method returning a Player and a remove method that took the player as an argument. I'd prefer this over returning an index, since an index may be temporary (e.g. if someone else added to the list the index might become invalidated).
There's more you can do (perhaps a findAll or a filter method with a predicate), but I wouldn't look at these until you have a reason to do so (You Ain't Going to Need it)