I am pretty new to java, I am working on implementing a pacman game, I initialized a ghost my using one image, and currently using one object in my game, but I want to have multiple images so I can have different colored ghosts. But when I initialized multiple images the just overlaps on another. Here's how I intialized the Ghost
private Image RedGhost;
private Image pacman1, pacman2up, pacman2left, pacman2right, pacman2down;
here the code that I use to moveGhosts
private void moveGhosts(Graphics2D g2d) {
short i;
int pos;
int count;
for (i = 0; i < nrofghosts; i++) {
if (ghostx[i] % blocksize == 0 && ghosty[i] % blocksize == 0) {
pos = ghostx[i] / blocksize + nrofblocks * (int) (ghosty[i] / blocksize);
count = 0;
if ((screendata[pos] & 1) == 0 && ghostdx[i] != 1) {
dx[count] = -1;
dy[count] = 0;
count++;
}
if ((screendata[pos] & 2) == 0 && ghostdy[i] != 1) {
dx[count] = 0;
dy[count] = -1;
count++;
}
if ((screendata[pos] & 4) == 0 && ghostdx[i] != -1) {
dx[count] = 1;
dy[count] = 0;
count++;
}
if ((screendata[pos] & 8) == 0 && ghostdy[i] != -1) {
dx[count] = 0;
dy[count] = 1;
count++;
}
if (count == 0) {
if ((screendata[pos] & 15) == 15) {
ghostdx[i] = 0;
ghostdy[i] = 0;
} else {
ghostdx[i] = -ghostdx[i];
ghostdy[i] = -ghostdy[i];
}
} else {
count = (int) (Math.random() * count);
if (count > 3) {
count = 3;
}
ghostdx[i] = dx[count];
ghostdy[i] = dy[count];
}
}
ghostx[i] = ghostx[i] + (ghostdx[i] * ghostspeed[i]);
ghosty[i] = ghosty[i] + (ghostdy[i] * ghostspeed[i]);
drawGhost(g2d, ghostx[i] + 1, ghosty[i] + 1);
//drawblueGhost(g2d, ghostx[i] + 1, ghosty[i] + 1);
if (pacmanx > (ghostx[i] - 12) && pacmanx < (ghostx[i] + 12)
&& pacmany > (ghosty[i] - 12) && pacmany < (ghosty[i] + 12)
&& ingame) {
dying = true;
}
}
}
In summery all the Ghosts are currently Red, I would like it to be different colors
With your current code, you could modify the drawGhost method to take an identifier for the color of the ghost being drawn. You could then have another array that holds the identifier for each ghost's color.
However, since you are using Java I would recommend taking advantage of OOP and create a Ghost class that holds all of a ghost's properties (x position, y position, color, etc). You can then have a collection of Ghost objects that represent each individual ghost.
Here is an example:
Make a Ghost class that holds all the properties a ghost can have:
public class Ghost {
private String color;
private int x;
private int y;
private boolean alive;
// getters and setters. You could even move the logic for moving a ghost to this class
...
}
Then you would initialize the ghosts like this:
Ghost redGhost = new Ghost("Red");
Ghost greenGhost = new Ghost("Green");
Ghost pinkGhost = new Ghost("Pink");
You could store them in a set:
Set<Ghost> ghostSet = new HashSet<Ghost>();
ghostSet.add(redGhost);
...
Then your method can change to something like this:
private void moveGhosts(Graphics2D g2d) {
// Utilize an enhanced for loop
for(Ghost ghost : ghosts){
...
...
ghostx[i] = ghostx[i] + (ghostdx[i] * ghostspeed[i]);
ghosty[i] = ghosty[i] + (ghostdy[i] * ghostspeed[i]);
drawGhost(g2d, ghost);
if (pacmanx > (ghostx[i] - 12) && pacmanx < (ghostx[i] + 12)
...
...
}
}
Now the drawGhost method would look at the fields within the ghost class (by calling getter and setter methods) to determine the x and y to start drawing. The color field is used to determine which image to draw.
Related
This question already has answers here:
What is the meaning of "this" in Java?
(22 answers)
When should I use "this" in a class?
(17 answers)
Closed 11 months ago.
I'm trying to make a checkers game as practice for personal reasons, as I am somewhat newer to Java and am trying to learn.
In class Board, I'm trying to call a method that requires a Board type as input, to see which pieces a specific piece could possibly jump.
Here's Board:
public class Board {
private Piece[][] board;
public Board(){
board = new Piece[8][8];
}
public Piece pieceAtLocation(int x, int y){
return board[x][y];
}
public boolean movePiece(int startX, int startY, int newX, int newY, String movementType){
Piece temp = board[startX][startY];
if(movementType.equals("move")){
board[newX][newY] = temp;
board[startX][startY] = null;
return true;
} else if(movementType.equals("jump")){
int[][] possibleSpaces = temp.jumpableSpaces(this);
}
return false;
}
}
Here's the Piece class it's calling from
public class Piece {
private boolean isKinged;
private boolean teamSided;
private int x;
private int y;
public Piece(boolean teamSided, int x, int y){
this.isKinged = false;
this.teamSided = teamSided;
this.x = x;
this.y = y;
}
public boolean team(){
return teamSided;
}
public boolean kinged(){
return isKinged;
}
public int[][] jumpableSpaces(Board board){
int[][] jumpTo = new int[4][2];
if(x - 2 >= 0 && y + 2 < 8){
if(board.pieceAtLocation(x - 2, y + 2) == null && board.pieceAtLocation(x - 1, y + 1).team() != teamSided){
jumpTo[0][0] = x - 2;
jumpTo[0][1] = y + 2;
} else{
jumpTo[0][0] = -1;
jumpTo[0][1] = -1;
}
}
if(x + 2 < 8 && y + 2 < 8){
if(board.pieceAtLocation(x + 2, y + 2) == null && board.pieceAtLocation(x + 1, y + 1).team() != teamSided){
jumpTo[1][0] = x + 2;
jumpTo[1][1] = y + 2;
} else{
jumpTo[1][0] = -1;
jumpTo[1][1] = -1;
}
}
if(isKinged){
if(x - 2 >= 0 && y - 2 >= 0){
if(board.pieceAtLocation(x - 2, y - 2) == null && board.pieceAtLocation(x - 1, y - 1).team() != teamSided){
jumpTo[2][0] = x - 2;
jumpTo[2][1] = y - 2;
}
}
if(x - 2 >= 0 && y + 2 < 8){
if(board.pieceAtLocation(x - 2, y + 2) == null && board.pieceAtLoaction(x - 1, y + 1).team() != teamSided){
jumpTo[3][0] = x - 2;
jumpTo[3][1] = y + 2;
}
}
} else{
jumpTo[2][0] = -1;
jumpTo[2][1] = -1;
jumpTo[3][0] = -1;
jumpTo[3][1] = -1;
}
return jumpTo;
}
}
My question involves line 19 of Board. Is it possible to leave it as is and have it input itself using "this" or will I have to do something else? I'm not yet fully understanding of what "this" means, as I heard about its use in the constructors from a friend.
You can absolutely pass 'this' as a parameter to an internal function. 'This' basically refers to the specific instance of the object, so any value that is stored within it will be passed along as well.
Currently I'm trying to implement heuristics for a 3D tic-tac-toe but it seems like my counter is way of it,f but I'm unsure where I've done wrong, I'm not gonna post all of the code since it's a lot, but here is a part:
public void countDiagonal(GameState gameState) {
/*
* yz-plane (negativ)
*/
int z;
for (int x = 0; x < GameState.BOARD_SIZE; x++) {
for (int y = 0; y < GameState.BOARD_SIZE; y++) {
z = y;
if (gameState.at(x, y, z) == myPlayer) {
myCounter++;
opponentCounter = 0;
}
if (gameState.at(x, y, z) == opponentPlayer) {
opponentCounter++;
myCounter = 0;
}
if (gameState.at(x, y, z) == Constants.CELL_EMPTY) {
emptyCells++;
}
}
evaluateBoard();
myCounter = 0;
opponentCounter = 0;
emptyCells = 0;
}
The evaluation is done here:
public void evaluateBoard() {
if (myCounter == 1 && emptyCells == 3) {
myScore = myScore + 5;
}
if (myCounter == 2 && emptyCells == 2) {
myScore = myScore + 10;
}
if (myCounter == 3 && emptyCells == 1) {
myScore = myScore + 20;
}
if (myCounter == 4) {
myScore = myScore + 1000;
}
if (opponentCounter == 1 && emptyCells == 3) {
opponentScore = opponentScore + 5;
}
if (opponentCounter == 2 && emptyCells == 2) {
opponentScore = opponentScore + 10;
}
if (opponentCounter == 3 && emptyCells == 1) {
opponentScore = opponentScore + 20;
}
if (opponentCounter == 4) {
opponentScore = opponentScore + 1000;
}
}
When I try to run it, I use alpha-beta prune, but it seems like the calculation are done horrbly wrong, when I use the value, I take myScore - opponentScore and I use an alpha-beta tree with depth 1, but even after only playing one move, I'm down -15 in points, as I'm a noob in java, im therefore asking for help, is there an obvious mistake in my way of trying to evaluate the board?
I'm working on a program which contains a 2-dimensional 16x32 char array. What I want to do is, starting from a given element in this array, find all the elements that share the same value (in my case a blank space ' ') and that are horizontally and/or vertically linked to each other.
The method I'm using stores the indexes that it finds inside another array, called toShow (public static int toShow[][] = new int[30][30];). The problem is that this method does not seem to process towards the right side. Strangely enough, it seems to work on the other sides... Here's an example:
X1 123
31 1X
211 24
1X1 112X
111 12X34
111•2X32X
1X113X211
In this case, starting from the element marked as •, the method should store every ' ' character and all the neighbor numbers... but this is the result:
1••
1••
1•
1•
1•
1•
It does however usually work if it starts in the lower left corner, even though it does have to turn right!
I don't understand what's wrong with my code... Anyways here is the odd method:
public static void getEmptySurrounding(int xcoord, int ycoord) {
if (toShow[xcoord][ycoord] == 1) {
return;
}
else {
toShow[xcoord][ycoord] = 1;
}
//DOWN
if((ycoord!=29) && ycoord + 1 < 16) {
if (board[xcoord][ycoord] == ' ') {
getEmptySurrounding(xcoord, ycoord + 1);
}
}
//RIGHT
if((xcoord!=15) && xcoord + 1 < 30) {
if (board[xcoord][ycoord] == ' ') {
getEmptySurrounding(xcoord + 1, ycoord);
}
}
//UP
if((ycoord!=0) && ycoord - 1 >= 0) {
if (board[xcoord][ycoord] == ' ') {
getEmptySurrounding(xcoord, ycoord - 1);
}
}
//LEFT
if((xcoord!=0) && xcoord - 1 >= 0) {
if (board[xcoord][ycoord] == ' ') {
getEmptySurrounding(xcoord - 1, ycoord);
}
}
}
Thank you!
Based on the information you provided I made an application to test your method:
public class Mine {
private static char board[][] = new char[16][32];
private static int toShow[][] = new int[30][30];
public static void main(String[] args) {
int n = 0;
insert(n++, "X1 123");
insert(n++, "31 1X");
insert(n++, "211 24");
insert(n++, "1X1 112X");
insert(n++, "111 12X34");
insert(n++, "111 2X32X");
insert(n++, "1X113X211");
getEmptySurrounding(3, 5);
for (int i = 0; i < 30; i++) {
for (int j = 0; j < 30; j++) {
System.out.print(toShow[j][i]);
}
System.out.println();
}
}
public static void getEmptySurrounding(int xcoord, int ycoord) {
if (toShow[xcoord][ycoord] == 1) {
return;
}
else {
toShow[xcoord][ycoord] = 1;
}
// DOWN
if ((ycoord != 29) && ((ycoord + 1) < 16)) {
if (board[xcoord][ycoord] == ' ') {
getEmptySurrounding(xcoord, ycoord + 1);
}
}
// RIGHT
if ((xcoord != 15) && ((xcoord + 1) < 30)) {
if (board[xcoord][ycoord] == ' ') {
getEmptySurrounding(xcoord + 1, ycoord);
}
}
// UP
if ((ycoord != 0) && ((ycoord - 1) >= 0)) {
if (board[xcoord][ycoord] == ' ') {
getEmptySurrounding(xcoord, ycoord - 1);
}
}
// LEFT
if ((xcoord != 0) && ((xcoord - 1) >= 0)) {
if (board[xcoord][ycoord] == ' ') {
getEmptySurrounding(xcoord - 1, ycoord);
}
}
}
public static void insert(int n, String a) {
for (int i = 0; i < 16; i++) {
board[i][n] = a.length() <= i ? ' ' : a.charAt(i);
}
}
}
At the end it prints out the content of toShow, the relevant part is:
011111100000000000000000000000
011111110000000000000000000000
001111110000000000000000000000
001111100000000000000000000000
001110000000000000000000000000
001110000000000000000000000000
000100000000000000000000000000
000000000000000000000000000000
000000000000000000000000000000
000000000000000000000000000000
which suggest that the method works correctly.
So probably the problem lies elsewhere in your program.
i have 2 classes , inputHandlerMenu and GameWorld , and i want to get an integer from inputHanlerMenu and use it in GameWorld ! it tried a lot but i didnt work . can any one help me ?
i declared : public GameWorld seter;
#Override
public boolean touchUp(int screenX, int screenY, int pointer, int button) {
screenX = scaleX(screenX);
screenY = scaleY(screenY);
if (menuButtons.get(0).isTouchUp(screenX, screenY)) {
world.getMenuObject().getPad().end();
seter.setModes(1);
for (int i = 0; i < menuButtons.size(); i++) {
menuButtons.get(i).end();
}
world.getMenuObject().getVolumeButton().end();
menuButtons.get(0).tranToGameScreen();
}if (menuButtons.get(1).isTouchUp(screenX, screenY)) {
world.getMenuObject().getPad().end();
seter.setModes(2);
for (int i = 0; i < menuButtons.size(); i++) {
menuButtons.get(i).end();
}
world.getMenuObject().getVolumeButton().end();
menuButtons.get(1).tranToGameScreen();
}if (menuButtons.get(2).isTouchUp(screenX, screenY)) {
world.getMenuObject().getPad().end();
seter.setModes(3);
for (int i = 0; i < menuButtons.size(); i++) ....
i declared mode as public int mode;
public void setModes (int mode){
this.mode = mode;
}
private void collisions() {
{
if (!ball.hasCollided()) {
for (int i = 0; i < pad.getcolCircles().size(); i++)
if (Intersector.overlaps(pad.getcolCircles().get(i), ball.getColCircle())) {
ball.collide();
ball.setCollided(true);
//Gdx.app.log("Angle", ball.getVelocity().toString());
//double perp = 2.0 * ball.getVelocity().cpy().dot(pad.returnNormal(i));
//Vector2 reflectDir = ball.getVelocity().cpy().sub((pad.returnNormal(i).scl((float) perp))).scl(1);
float newAngle = getAngle2Vecs(ball.getVelocity(), pad.returnNormal(i));
//Gdx.app.log("Angle", newAngle + "");
ball.setVelocity(new Vector2(gameWidth / 2 - ball.getColCircle().x, gameHeight / 2 - ball.getColCircle().y));
int rand = (int) Math.random() * 90 + 5;
if (pad.getAngularVelocity() < 0) {
ball.setVelocity(ball.getVelocity().cpy().rotate((float) (rand + Math.random() * 50)));
} else if (pad.getAngularVelocity() > 0) {
ball.setVelocity(ball.getVelocity().cpy().rotate((float) (-rand - Math.random() * 50)));
} else {
ball.setVelocity(ball.getVelocity().cpy().rotate(Math.random() < 0.5 ? -rand : rand));
System.out.println(mode);
if (mode == 1) {
if (score <= 5) {
ball.setVelocity(ball.getVelocity().cpy().scl(Configuration.E_VELOCITY_OVER_0));
} else if (score >= 5 && score < 50) {
ball.setVelocity(ball.getVelocity().cpy().scl(Configuration.E_VELOCITY_OVER_5));
} else if (score >= 10 && score < 50) {
ball.setVelocity(ball.getVelocity().cpy().scl(Configuration.E_VELOCITY_OVER_10));
} else if (score >= 20 && score < 50) {
ball.setVelocity(ball.getVelocity().cpy().scl(Configuration.E_VELOCITY_OVER_20));
} else if (score >= 35 && score < 50) {
ball.setVelocity(ball.getVelocity().cpy().scl(Configuration.E_VELOCITY_OVER_35));
} else if (score >= 50 && score < 75) {
ball.setVelocity(ball.getVelocity().cpy().scl(Configuration.E_VELOCITY_OVER_50));
} else if (score >= 65 && score < 75) {
ball.setVelocity(ball.getVelocity().cpy().scl(Configuration.E_VELOCITY_OVER_65));
} else if (score >= 75 && score < 100) {
ball.setVelocity(ball.getVelocity().cpy().scl(Configuration.E_VELOCITY_OVER_75));
} else if (score >= 100 ) {
ball.setVelocity(ball.getVelocity().cpy().scl(Configuration.E_VELOCITY_OVER_100));
} ....
i use for every button her mode , like if he pressed button 0 , velocity will change , button 1 => velocity change ...
here the int stay at 0 . it doesnt change !
any one know how to do it ! ?
You can use shared preferences and store the integer value in Input Handler Menu and then you can get the value in GameWorld as shown below.
In Input Handler:
SharedPreferences sharedPreferences = getSharedPreferences("MyData" , Context.MODE_PRIVATE);
SharedPreferences.Editor editor = sharedPreferences.edit();
editor.putInt("Key" , your_int_value);
editor.commit();
In GameWorld:
SharedPreferences sharedPreferences = getSharedPreferences("MyData", Context.MODE_PRIVATE);
int position = sharedPreferences.getInt("key", Default_Value);
The integer value stored will be assigned to position, you can use that where ever you want.
Hope this might help you.
Add this method to your GameWorld class and make sure mode is public int
public int mode;
public int getModes(){
return mode
}
Now in your other class whenever you need the integer simply call
int getthatint = seter.getModes();
I have been working on a versions of Conway's Game of Life for school and I have run into a problem: cells are becoming dead or alive in the wrong places.
How can I fix that?
if (alive == 3 && aryBOARD[x][y] == 0) { //rule 4
aryCHANGE[x][y] = 1;
}
if (alive > 3 && aryBOARD[x][y] == 1) { //rule 3
aryCHANGE[x][y] = 0;
}
if (alive >= 2 && alive <= 3 && aryBOARD[x][y] == 1) { //rule 2
aryCHANGE[x][y] = 1;
}
if (alive < 2 && aryBOARD[x][y] == 1) { //rule 1
aryCHANGE[x][y] = 0;
}
if (dead > 5) { //rule check
aryCHANGE[x][y] = 0;
}
That is where I assume the problem is but if having the whole code would help:
package gameoflife2;
public class Game {
public static void main(String[] args) {
int[][] aryBOARD = new int[5][5];
int x = 0;
int y = 0;
int dead = 0;
int alive = 0;
int i, j;
// Board numbers
// 00011
// 00001
// 01000
// 01100
// 00000
aryBOARD[0][0] = 0;
aryBOARD[0][1] = 0;
aryBOARD[0][2] = 0;
aryBOARD[0][3] = 1;
aryBOARD[0][4] = 1;
aryBOARD[1][0] = 0;
aryBOARD[1][1] = 0;
aryBOARD[1][2] = 0;
aryBOARD[1][3] = 0;
aryBOARD[1][4] = 1;
aryBOARD[2][0] = 0;
aryBOARD[2][1] = 1;
aryBOARD[2][2] = 0;
aryBOARD[2][3] = 0;
aryBOARD[2][4] = 0;
aryBOARD[3][0] = 0;
aryBOARD[3][1] = 1;
aryBOARD[3][2] = 1;
aryBOARD[3][3] = 0;
aryBOARD[3][4] = 0;
aryBOARD[4][0] = 0;
aryBOARD[4][1] = 0;
aryBOARD[4][2] = 0;
aryBOARD[4][3] = 0;
aryBOARD[4][4] = 0;
// end of array
int[][] aryCHANGE = aryBOARD.clone(); // array change is equal to array
// board
// printing array
int rows = 5;
int colums = 5;
for (i = 0; i < rows; i++) {
for (j = 0; j < colums; j++) {
System.out.print(aryBOARD[i][j] + " ");
}
System.out.println("");
}
System.out.println("---------------------------");
// done printing array
// check for dead or alive cells
for (x = 0; x <= 4; x++) {
for (y = 0; y <= 4; y++) {
alive = 0;
dead = 0;
if ((x + 1 < 4) && (x + 1 > 0)) { // right
if (aryBOARD[x + 1][y] == 0) {
dead++;
} else {
alive++;
}
}
if (((y - 1 < 4) && (y - 1 > 0) && (x + 1 < 4) && (x + 1 > 0))) { // bottom
// right
// corner
if (aryBOARD[x + 1][y - 1] == 0) {
dead++;
} else {
alive++;
}
}
if (((y + 1 < 4) && (y + 1 > 0) && (x + 1 < 4) && (x + 1 > 0))) { // top
// right
// corner
if (aryBOARD[x + 1][y + 1] == 0) {
dead++;
} else {
alive++;
}
}
if ((y + 1 < 4) && (y + 1 > 0)) {// top middle
if (aryBOARD[x][y] == 0) {
dead++;
} else {
alive++;
}
}
if (((y + 1 < 4) && (y + 1 > 0) && (x - 1 < 4) && (x - 1 > 0))) {// top
// left
// corner
if (aryBOARD[x - 1][y + 1] == 0) {
dead++;
} else {
alive++;
}
}
if ((x - 1 < 4) && (x - 1 > 0)) {// left
if (aryBOARD[x - 1][y] == 0) {
dead++;
} else {
alive++;
}
}
if (((y - 1 < 4) && (y - 1 > 0) && (x - 1 < 4) && (x - 1 > 0))) {// bottom
// left
// corner
if (aryBOARD[x - 1][y - 1] == 0) {
dead++;
} else {
alive++;
}
}
// x++
if ((y - 1 < 4) && (y - 1 > 0)) {// bottom middle
if (aryBOARD[x][y - 1] == 0) {
dead++;
} else {
alive++;
}
}
// RULES
// 1 Any live cell with fewer than two live neighbors dies, as if caused
// by under-population.
// 2 Any live cell with two or three live neighbors lives on to the next
// generation.
// 3 Any live cell with more than three live neighbors dies, as if by
// overcrowding.
// 4 Any dead cell with exactly three live neighbors becomes a live
// cell, as if by reproduction.
// test alive and dead
if (alive == 3 && aryBOARD[x][y] == 0) {// rule 4
aryCHANGE[x][y] = 1;
}
if (alive > 3 && aryBOARD[x][y] == 1) {// rule 3
aryCHANGE[x][y] = 0;
}
if (alive >= 2 && alive <= 3 && aryBOARD[x][y] == 1) {// rule 2
aryCHANGE[x][y] = 1;
}
if (alive < 2 && aryBOARD[x][y] == 1) {// rule 1
aryCHANGE[x][y] = 0;
}
if (dead > 5) {// rule check
aryCHANGE[x][y] = 0;
}
}
}
for (i = 0; i < rows; i++) {
for (j = 0; j < colums; j++) {
System.out.print(aryCHANGE[i][j] + " ");
}
System.out.println("");
}
System.out.println("---------------------------");
} // end main
} // end class
You need to think a lot more about structuring your code and breaking things up into smaller chunks. That will help you a lot, especially when you move onto larger projects in the future.
For example write a simple method to count the number of living cells around a given cell.
Now your main loop through just becomes:
for (int x=0;x<width;x++) {
for (int y=0;y<height;y++) {
switch(countLivingAround(x,y)) {
case 0: // Less than 2 always dies
case 1:
grid(x,y) = 0;
break;
case 2: // Do nothing, keep current state
break;
case 3: // Breed
grid(x,y) = 1;
break;
case 4: // Dies from overcrowding
grid(x,y) = 0;
break;
}
}
}
Your count function can be simple, it just adds up the values at [x-1,y],[x,y+1], etc, remember to check for the edges of the board and handle that case correctly though.
In addition to breaking the logic up into different methods you need to either use a debugger to step thru the code or use printlns to display the x and y values your evaluating (See the sample below) You'll see that some of your calculations on the adjoining cells x and y coordinates need work.
for (x = 0; x <= 4; x++) {
for (y = 0; y <= 4; y++) {
alive = 0;
dead = 0;
System.out.println("evaluating cell x=" + x + ", y = " + y);
if ((x + 1 < 4) && (x + 1 > 0)) {// right
if (aryBOARD[x + 1][y] == 0) {
dead++;
}
else {
alive++;
}
System.out.println(" check 1 x=" + (x + 1) + ", y = " + y);
}