Related
Hi every one i am having a bit of trouble with my java game, it is very simply made as i am new to java. and the game works fine well as good as i can achieve. But i am stuck on how i can change the images in real time. I am trying to figure out how to make my Monsters face me "the hero frylark" when they chase me. i have made 2 simple methods in my monster class. left and right How could i apply these methods to make the image change from image = getImage("/Game/images/police-right.png"); to image = getImage("/Game/images/police-left.png");.
Oh and in my project library is golden_0_2_3.jar which contains some game engine stuff.
Please.
Many thanks from edwin.
import com.golden.gamedev.*;
import java.awt.*;
import java.awt.image.BufferedImage;
import java.util.Random;
import java.awt.event.KeyEvent;
public class MyGame extends Game {
// set the values
public Random random;
private Hero frylark;
private Monster[] monsters = new Monster[3];
private Token coin;
private GameBackGround grass;
private BufferedImage image;
public void initResources() {
// set a new random number
random = new Random();
// get the background image.
image = getImage("/Game/images/background.png");
// set the name "grass" to background and given the image from the image set above.
grass = new GameBackGround("grass", image);
// get the monsters image.
image = getImage("/Game/images/police.png");
// give the monsters their names "" and set them their image from the image set above.
monsters[0] = new Monster("Monster", image);
monsters[1] = new Monster("Monster2", image);
monsters[2] = new Monster("Monster3", image);
// get the tokens image.
image = getImage("/Game/images/donut.png");
// set the name "coin" for the token, then its x and y position, and set the image from the image set above.
coin = new Token("coin", 400, 300, image);
// get the heros image.
image = getImage("/Game/images/snake.png");
// set the name "frylark" for the hero, then his score "0" and lives "5".
frylark = new Hero("Frylark", 0, 5);
//set the monsters random x and y positions.
monsters[0].setX(random.nextInt(750));
monsters[0].setY(random.nextInt(550));
monsters[1].setX(random.nextInt(750));
monsters[1].setY(random.nextInt(550));
monsters[2].setX(random.nextInt(750));
monsters[2].setY(random.nextInt(550));
}
// update method
public void update(long elapsedTime) {
// Pause the hero "frylark" on hold of the space bar.
if (!keyDown(KeyEvent.VK_SPACE)){
// if dead stop frylark moving on the 5 second game over sequence, being displays details and playing the game over sound.
if (Hero.dead(frylark)){
if(keyDown(KeyEvent.VK_LEFT))
{
// Move left
frylark.moveLeft();
}
if (keyDown(KeyEvent.VK_RIGHT))
{
// Move right
frylark.moveRight();
}
if (keyDown(KeyEvent.VK_UP))
{
// Move up on press of up key
frylark.moveUp();
}
if (keyDown(KeyEvent.VK_DOWN))
{
// Move down on press of down key
frylark.moveDown();
}
}
if (keyDown(KeyEvent.VK_ESCAPE))
{
// Exit game on press of esc key.
System.exit(0);
}
}
if (!keyDown(KeyEvent.VK_SPACE))
{
// Pause the monsters on hold of the space bar
monsters[0].chase(frylark);
monsters[1].chase(frylark);
monsters[2].chase(frylark);
}
// if monster 0 has eaten frylark move to a random position and lose a life, plus play the lose life sound.
if (monsters[0].eaten(frylark)) {
monsters[0].setX(random.nextInt(750));
monsters[0].setY(random.nextInt(550));
frylark.loseLife();
playSound("/Game/sounds/lost_a_life.wav");
}
// if monster 1 has eaten frylark move to a random position and lose a life, plus play the lose life sound.
if (monsters[1].eaten(frylark)) {
monsters[1].setX(random.nextInt(750));
monsters[1].setY(random.nextInt(550));
frylark.loseLife();
playSound("/Game/sounds/lost_a_life.wav");
}
// if monster 2 has eaten frylark move to a random position and lose a life, plus play the lose life sound.
if (monsters[2].eaten(frylark)) {
monsters[2].setX(random.nextInt(750));
monsters[2].setY(random.nextInt(550));
frylark.loseLife();
playSound("/Game/sounds/lost_a_life.wav");
}
// if coin is collected increase score and move to a random position, and play the coin collect sound.
if (coin.collected(frylark)) {
coin.setX (random.nextInt(750));
coin.setY (random.nextInt(550));
frylark.increaseScore();
playSound("/Game/sounds/coin.wav");
}
}
public void render(Graphics2D g) {
// draw all the monsters, hero, and coin and background.
g.drawImage(grass.getImage(),grass.getX(),grass.getY(),null);
g.drawImage(monsters[0].getImage(), monsters[0].GetX(), monsters[0].GetY(), null);
g.drawImage(monsters[1].getImage(), monsters[1].GetX(), monsters[1].GetY(), null);
g.drawImage(monsters[2].getImage(), monsters[2].GetX(), monsters[2].GetY(), null);
g.drawImage(image,frylark.getX(),frylark.getY(),null);
g.drawImage(coin.getImage(),coin.getX(),coin.getY(),null);
// if monster 0 overlaps another monster mover him back
if (monsters[0].overlap(monsters)){
monsters[0].x -=20;
monsters[0].y -=70;
}
// if monster 1 overlaps another monster mover him back
if (monsters[1].overlap(monsters)){
monsters[1].x -=21;
monsters[1].y -=70;
}
// if monster 2 overlaps another monster mover him back
if (monsters[2].overlap(monsters)){
monsters[2].x -=22;
monsters[2].y -=70;
}
// draw the lives bar, and set the font colour and size
g.setColor(Color.RED);
g.setFont(new Font("default", Font.BOLD, 18));
for (int i = 0; i < frylark.getLives(); i++) {
g.fillRect( (i + 1) * 15, 10, 10, 10);
}
// draw the score
g.setColor(Color.GREEN);
g.drawString("Score: " + frylark.getScore(), 10, 50);
// draw the level
g.setColor(Color.YELLOW);
g.drawString("level: " + frylark.getScoreNum(), 10, 80);
// game over sequence, changes the font to size 40 and displays game over, as well as the payers score and level reached plus the game over sound.
if (frylark.getLives() ==0){
g.setColor(Color.RED);
g.setFont(new Font("override", Font.BOLD, 40));
g.drawString("Game over !", 280, 290);
playSound("/Game/sounds/game_over.wav");
g.drawString("You reached Level " + frylark.getScoreNum() + " Your Score: " + frylark.getScore(), 60, 330);
}
}
// main method which after all classes have been read and checked, "Game development environment OK! " will be printed to the console.
// then a new game is created and given dimensions and launched.
public static void main(String args[]) {
System.out.println("Game development environment OK! ");
GameLoader gameLoader = new GameLoader();
MyGame myGame = new MyGame();
gameLoader.setup(myGame,new Dimension(800,600),false);
gameLoader.start();
}
}
and my Monster class
import java.util.Random;
import java.awt.image.BufferedImage;
public class Monster {
private String name;
int x;
int y;
private BufferedImage image;
Random rand;
public Monster (String nameIn, BufferedImage imageIn)
{
name = nameIn;
x = 0;
y = 0;
image = imageIn;
}
public void chase(Hero hero) {
if (hero.getX() < x) { // if hero is to the left
x--;
}
if (hero.getX() > x) { // if hero is to the right
x++ ;
}
if (hero.getY() < y) { // if hero is to the above
y--;
}
if (hero.getY() > y) { // if hero is to the below
y++;
}
}
public boolean overlap(Monster monsters[]){
if (monsters[0].x == monsters[1].x && monsters[0].y == monsters[1].y || monsters[0].x == monsters[2].x && monsters[0].y == monsters[2].y ||
monsters[1].x == monsters[0].x && monsters[1].y == monsters[0].y || monsters[1].x == monsters[2].x && monsters[1].y == monsters[2].y ||
monsters[2].x == monsters[0].x && monsters[2].y == monsters[0].y || monsters[2].x == monsters[1].x && monsters[2].y == monsters[1].y) {
return true;
}
else{
return false;
}
}
public boolean eaten(Hero hero) {
if (hero.getX() == x && hero.getY() == y) {
return true;
}
else {
return false;
}
}
public BufferedImage getImage() {
return image;
}
public int GetX(){
return x;
}
public int GetY(){
return y;
}
public String getName()
{
return this.name;
}
public void setX(int xIn) {
x = xIn;
}
public void setY(int yIn) {
y = yIn;
}
public boolean left(Hero hero) {
if (hero.getX() < x) {
return true;
}
else {
return false;
}
}
public boolean right(Hero hero) {
if (hero.getX() > x) {
return true;
}
else {
return false;
}
}
}
I would modify your Monster constructor to accept both images. Then modify Monster.getImage() to call left() and return the correct one based on the result. You probably don't need to call right() as well, since if the monster is not facing left then you know it needs to face right. Unless you want to get more sophisticated and also add a view facing straight forward or backward.
Closed. This question needs debugging details. It is not currently accepting answers.
Edit the question to include desired behavior, a specific problem or error, and the shortest code necessary to reproduce the problem. This will help others answer the question.
Closed 8 years ago.
Improve this question
So I am making a simple tic tac toe game and ran into a problem at the last minute
I am trying to draw a line at the win location but on the final win location(index), the line gets hidden behind the JButton not entirly sure why it is doing this.
I know alot of people say do not use getGraphics(), and I am wondering if that is the source of my issues they say to override the paintComponent method but that is not working for me either
I have attached a pic of what the result is looking like and code snips of how I am trying to perform these actions
PS I am using a JFrame, if any more code is needed I will be glad to show it
if(win[i] == 264){ // if one of the the combinations equal 'X','X','X' which equals 264, then there is a winner
System.out.println("X is the winner!!!");
System.out.println("Game Over!");
number = i;
draw(); }// call draw method
private void draw(){ // drawing a line at winning location
Graphics2D g1 = (Graphics2D) GUI.getFrame().getGraphics(); // declaring graphics on our Jframe
Stroke stroke3 = new BasicStroke(12f, BasicStroke.CAP_ROUND, BasicStroke.JOIN_MITER); // make our strokes cap off round
if(number == 0){ // statements will determine the win location, so at win0, XXX,
g1.setStroke(stroke3); // we will add stroke to our line
g1.drawLine(0,104,500,104); // draw the line starting at the 0,104 and end it at coordinates 500,104
}
here is a more runnable code, it is alot though
import java.awt.BasicStroke;
import java.awt.Color;
import java.awt.Font;
import java.awt.Graphics2D;
import java.awt.GridLayout;
import java.awt.Stroke;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import javax.swing.ButtonModel;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JOptionPane;
import javax.swing.SwingUtilities;
import javax.swing.UIManager;
import javax.swing.border.Border;
import javax.swing.border.LineBorder;
import javax.swing.event.ChangeEvent;
import javax.swing.event.ChangeListener;
public class tic implements Runnable {
final static int row = 3; // our rows
final static int col = 3; // our col
final static int sizeOfBoard = row * col;
// the size of our board is not going to change so we make it final
static JButton[] clickButton;
char[] templateOfBoard; // our board, TicTacToe field, static
char userTurn; // users turn , only one letter, tracks whether it is a X or O
int count; // keeps track of user moves
static JFrame frame; // our JFrame
int number;
public tic(JFrame frame) {
tic.frame = new JFrame("TicTacToe GAME");
clickButton = new JButton[9];
count = 0; // number of turns starts at 0;
number = 0;
setUserTurn('X'); // first turn will always be X
setTemplateOfBoard(new char[sizeOfBoard]); // size of the board we are going to make it
try{
for(int spaces=0; spaces<sizeOfBoard; spaces++){ // size of Board is in the GUI class
getTemplateOfBoard()[spaces] = ' '; // the board is being created, looping through all rows and col
//every index of the board not has a char value equal to a space
//determine if everything came out correctly
//should equal of a total of 9
// 3x3
}
System.out.println("Board template created"); // means the board now has all spaces
}
catch(Exception e){
System.out.println("Could not initalize the board to empty char");
e.printStackTrace();
}
}
public static void main(String[] args){
try{
SwingUtilities.invokeLater(new tic(frame)); // run
}
catch(Exception e){ // wanted to test to ensure that Runnable could be invoked
System.out.println("Could not excute Runnable application");
e.printStackTrace();
}
}
public void run() {
setup(); // going to run out setup method, what our game is made out of
}
public void setup() {
// setting up the Board
// board is composed of JButton
// and a 3x3 frame
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); // when the user closes the window JFrame will exit
//going to design the board now
//the dimensations of the board = sizeOfBoard
getFrame().setLayout(new GridLayout(row, col)); // this is the outline rows * col
// sizes out row * col based on what we define those numbers as
//i.e 3x3
getFrame().setBounds(0,0,500,500); // location at 0,0, size 500 x 500
Border border = new LineBorder(Color.DARK_GRAY, 2); // color of JButton border
System.out.println("Your board game is being created!");
try{
getFrame().setVisible(true); // shows the board,
// this is going to display everything to the screen
System.out.println("Board is now visable");
}
catch(Exception e){
System.out.println("Board was not displayed");
}
// 9 different buttons, for every index there will be a button
for(int i =0; i<sizeOfBoard;i++){ // going to fill the board with clickableButtons by looping through every index and placing a button there
final int move = i;
clickButton[i] = new JButton(); // at a certain index there is a new button
clickButton[i].setSize(250,250); // size of each button
clickButton[i].setBackground(Color.WHITE); // color of the JButton
getFrame().add(clickButton[i]); // we are going to add the actual the button at that index on the frame
clickButton[i].setFont(new Font("Arial", Font.BOLD, 70)); // size of the text
clickButton[i].setBorder(border); // adding border
clickButton[i].getModel().addChangeListener(new ChangeListener() { //going to overRide what happens when we rollover and press a Butotn
public void stateChanged(ChangeEvent e) {
ButtonModel button = (ButtonModel) e.getSource(); // manages the state of the button, i.e lets me control what happens to the button
if(clickButton[move] != null){ // if we do not include this argument
// the buttons are not made yet on the new game, meaning clickButton[i] = null
//so boolean(!button.isRollover()) will return true, since on the new game you can not have your mouse hovered over
// but when it returns true, it will return a null value, giving a null pointer exception
// so best thing to do, is to only run these cases below when the buttons are not null
if (button.isRollover()) { // when the mouse hovers over the index
clickButton[move].setBackground(Color.BLACK); // color will equal black
}
else if(!button.isRollover()){ // when the button is not hovered over
clickButton[move].setBackground(Color.WHITE); // color will be whte, just like our background
}
}
}
});
clickButton[i].addActionListener(new ActionListener() {
//our click events, going to override to let it know what we want to happen
//once we click on the button
public void actionPerformed(ActionEvent e) {
clickButton[move].setEnabled(false); //going to disable the button after it is clicked
//ORDER: button gets clicked first, then the test is added
mouseListener(e, move); // our mouseListenerEvent in game class
//
}
});
}
}
public static void playAgain() {
try{
System.out.println("NEW GAME");
SwingUtilities.invokeLater(new tic(frame)); // run the run(class) again
}
catch(Exception e){ // wanted to test to ensure that Runnable could be invoked
System.out.println("Could not excute Runnable application");
e.printStackTrace();
}
}
public static JFrame getFrame() {
return frame;
}
public tic userMove(int moveMade){
getTemplateOfBoard()[moveMade] = getUserTurn();
// index of the board, or in simpler terms, where the user
// inserts there turn i.e X or O, 0-8
//System.out.println(userMove);
//boolean statement to determine the turns
// So user X starts first
//if the turn is X, the nextTurn is now O,
if(getUserTurn() == 'X'){
setUserTurn('O');
}
else {
setUserTurn('X');
}
count++;
return this; // going to return the userTurn
// issue actually entering the userTurn is not giving right value, but using 'this' does
}
// for some odd reason the toString is causing some issues, keep getting #hash code
//saw online to override it like this
// will make the board out of emepty strings
// going to return a string representation of an object
public String toString(){
return new String(getTemplateOfBoard());
}
public void mouseListener(ActionEvent e, int moveMade){
// mouse click events
// what happens after a button is clicked
if(getTemplateOfBoard()[moveMade] == ' '){ // the user can only space a click, so an letter on the field if it is empty
((JButton)e.getSource()).setText(Character.toString(getUserTurn())); // when the button is clicked, we want an X placed there
if (getUserTurn() == 'X'){
UIManager.getDefaults().put("Button.disabledText",Color.RED); // when the but gets disabled the test will turn red
}
else{
UIManager.getDefaults().put("Button.disabledText",Color.BLUE);
}
//calling the method userTurn to determine who goes next
//problem is that is expects a String
//going to override the toString method
userMove(moveMade); // calling userMove in moveMade, moveMade is the index at which the user put either an X or a O
winner(); // we want to check each time to ensure there was/was not a winner
}
}
public tic winner() { // determines who is the winner
//list below defines all the possible win combinations
// the index of where a X or O can be place
// placed the locations to a int value
int win1 = templateOfBoard[0] + templateOfBoard[1] + templateOfBoard[2];
int win2 = templateOfBoard[3] + templateOfBoard[4] + templateOfBoard[5];
int win3 = templateOfBoard[6] + templateOfBoard[7] + templateOfBoard[8];
int win4 = templateOfBoard[0] + templateOfBoard[3] + templateOfBoard[6];
int win5 = templateOfBoard[1] + templateOfBoard[4] + templateOfBoard[7];
int win6 = templateOfBoard[2] + templateOfBoard[5] + templateOfBoard[8];
int win7 = templateOfBoard[0] + templateOfBoard[4] + templateOfBoard[8];
int win8 = templateOfBoard[2] + templateOfBoard[4] + templateOfBoard[6];
int[] win = new int[]{win1,win2,win3,win4,win5,win6,win7,win8};
// making a array to go through all the possibile wins
//possible total of wins is 8
for(int i = 0;i<win.length;i++){
// looping through the win possibilities
if(win[i] == 264){ // if one of the the combinations equal 'X','X','X' which equals 264, then there is a winner
System.out.println("X is the winner!!!");
System.out.println("Game Over!");
number = i;
draw(); // call draw method
return this; // if statement is true, it will return this(gameOver)
}
else if(win[i] == 237 ){ // if one of the the combinations equal 'O','O','O' which equals 234, then there is a winner
System.out.println("O is the winner!!!");
System.out.println("Game Over!");
number = i;
//draw(); // call draw method
return this;
}
if (count == 9) {
// if none of the statements above are true, it automatically comes done to here
//so if there is nine moves and no win, it is a draw
}
}
return this;
// going to return this method ;
}
private void draw(){ // drawing a line at winning location
Graphics2D g1 = (Graphics2D) getFrame().getGraphics(); // declaring graphics on our Jframe
Stroke stroke3 = new BasicStroke(12f, BasicStroke.CAP_ROUND, BasicStroke.JOIN_MITER); // make our strokes cap off round
if(number == 0){ // statements will determine the win location, so at win0, XXX,
g1.setStroke(stroke3); // we will add stroke to our line
g1.drawLine(0,104,500,104); // draw the line starting at the 0,104 and end it at coordinates 500,104
}
else if(number == 1){
g1.setStroke(stroke3);
g1.drawLine(0,257,500,257);
}
else if(number == 2){
g1.setStroke(stroke3);
g1.drawLine(0,411,500,411);
}
else if(number == 3){
g1.setStroke(stroke3);
g1.drawLine(88,0,88,500);
}
else if(number == 4){
g1.setStroke(stroke3);
g1.drawLine(250,0,250,500);
}
else if(number == 5){
g1.setStroke(stroke3);
g1.drawLine(411,0,411,500);
}
else if(number == 6){
g1.setStroke(stroke3);
g1.drawLine(-22,0,500,500);
}
else if(number == 7){
g1.setStroke(stroke3);
g1.drawLine(520,0,0,500);
}
}
// want to be able to access the private variables
//so we will make getter and setter methods for the ones that we need
public char getUserTurn() { // getter method for userTurn
return userTurn;
}
public void setUserTurn(char userTurn) { // setter method
this.userTurn = userTurn;
}
public char[] getTemplateOfBoard() { //getter method
return templateOfBoard;
}
public void setTemplateOfBoard(char[] templateOfBoard) { // setter method
this.templateOfBoard = templateOfBoard;
}
}
Painting over the top of components can be troublesome, you can't override the paintComponent method of the container which contains the components, because this paints in the background, you can't override the paint method of the container, as child components can be painted without the parent container been notified...
You could add a transparent component over the whole lot, but this just introduces more complexity, especially when a component already already exists ...
public class ConnectTheDots {
public static void main(String[] args) {
new ConnectTheDots();
}
public ConnectTheDots() {
EventQueue.invokeLater(new Runnable() {
#Override
public void run() {
try {
UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
} catch (Exception ex) {
}
PaintPane pp = new PaintPane();
JFrame frame = new JFrame("Test");
frame.setGlassPane(pp);
pp.setVisible(true);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.add(new DotsPane(pp));
frame.pack();
frame.setLocationRelativeTo(null);
frame.setVisible(true);
}
});
}
public class PaintPane extends JPanel {
private List<JButton[]> connections;
private JButton lastSelected;
public PaintPane() {
setOpaque(false);
connections = new ArrayList<>(25);
}
#Override
protected void paintComponent(Graphics g) {
super.paintComponent(g);
Graphics2D g2d = (Graphics2D) g.create();
if (lastSelected != null) {
g2d.setColor(Color.RED);
int x = lastSelected.getX() + ((lastSelected.getWidth() - 8) / 2);
int y = lastSelected.getY() + ((lastSelected.getHeight() - 8) / 2);
g2d.fillOval(x, y, 8, 8);
}
for (JButton[] group : connections) {
g2d.setColor(Color.BLUE);
Point startPoint = group[0].getLocation();
Point endPoint = group[1].getLocation();
startPoint.x += (group[0].getWidth() / 2);
startPoint.y += (group[1].getHeight()/ 2);
endPoint.x += (group[0].getWidth() / 2);
endPoint.y += (group[1].getHeight()/ 2);
g2d.draw(new Line2D.Float(startPoint, endPoint));
}
g2d.dispose();
}
protected void buttonClicked(JButton btn) {
if (lastSelected == null) {
lastSelected = btn;
} else {
connections.add(new JButton[]{lastSelected, btn});
lastSelected = null;
}
revalidate();
repaint();
}
}
public class DotsPane extends JPanel {
private PaintPane paintPane;
public DotsPane(final PaintPane pp) {
paintPane = pp;
ActionListener al = new ActionListener() {
#Override
public void actionPerformed(ActionEvent e) {
JButton btn = (JButton) e.getSource();
paintPane.buttonClicked(btn);
}
};
setLayout(new GridLayout(6, 6));
for (int index = 0; index < 6 * 6; index++) {
JButton btn = new JButton(".");
add(btn);
btn.addActionListener(al);
}
}
#Override
public Dimension getPreferredSize() {
return new Dimension(200, 200);
}
}
}
Take a look at How to Use Root Panes for more details
This question already has an answer here:
Loop doesn't see value changed by other thread without a print statement
(1 answer)
Closed 7 years ago.
I am writing a basic Tic-Tac-Toe Single player game using basic swing graphics. I completed the game, but there is a weird problem I am facing. At one place, I used a while loop with a SOP statement. If I omit this statement, program works differently and nothing happens (like some kind of infinite loop), and if I keep it, it works just fine. I don't know what's happening in the code. Please help.
Below is the source code which causing problem. Sorry for my amateur coding style.
import java.util.Random;
public class SinglePlayer implements Runnable{
public final int MINIMUM = -1000000;
private GameBoard game;
public SinglePlayer(){
game = new GameBoard("Single Player");
}
public static void main(String[] args){
SinglePlayer gameSingle = new SinglePlayer();
gameSingle.run();
}
public void run(){
boolean machinePlayed = true, userPlayed = false;
// Outer loop is to maintain re-match option of program
while(this.game.quitTwoPlayer == false){
// Inner loop is a single game b/w user and machine
while(this.game.GameQuitStatus() == false){
/* I kept two conditions to switch b/w machine and user mode
* of game and they just keep changing to simulate the game
* b/w machine and user.
*/
if(machinePlayed == false && userPlayed){
try {
MachineMove("O");
} catch (CloneNotSupportedException e) {
e.printStackTrace();
break;
}
this.game.ChangePlayerLabels();
machinePlayed = true;
userPlayed = false;
}
else if(machinePlayed && userPlayed == false){
int earlierCount = this.game.CountSteps();
/* THIS IS THE WHILE LOOP I AM TALKING ABOUT.
* If I omit the print statement inside the body of loop,
* program behaves differently, but when I keep it,
* it working just fine.
* */
while(earlierCount == this.game.CountSteps()){
System.out.println("Player User thinking");
}
this.game.ChangePlayerLabels();
machinePlayed = false;
userPlayed = true;
}
this.game.DeclareResult();
}
this.game.dispose();
}
}
public void MachineMove(String player) throws CloneNotSupportedException{
/* If board is empty, play at center of the board */
if(this.game.CountSteps() == 0){
this.game.MakeMove(1, 1);
}
/* If center is blank, play it there. Otherwise, pick a corner randomly */
else if(this.game.CountSteps() == 1){
if(this.game.IsEmpty(1, 1))
this.game.MakeMove(1, 1);
else{
Random randomNum = new Random();
int num = randomNum.nextInt(4);
if(num == 0)
this.game.MakeMove(0, 0);
else if(num == 1)
this.game.MakeMove(2, 0);
else if(num == 2)
this.game.MakeMove(0, 2);
else if(num == 3)
this.game.MakeMove(2, 2);
}
}
else{
/* If the next move is such that it should be taken, otherwise opponent will win */
String opponent = "";
if(this.game.GetCurrentPlayer().equals("O"))
opponent = "X";
else
opponent = "O";
for(int i = 0; i<3; i++){
for(int j = 0; j<3; j++){
if(this.game.IsEmpty(i,j)){
GameBoard tempGame = new GameBoard(this.game, "Single Player");
tempGame.MakePossibleMove(i, j, opponent);
if(tempGame.GameWinner().equals(opponent + " wins")){
this.game.MakeMove(i,j);
return;
}
}
}
}
/* If the next move is not such that if missed, game is lost, then play most optimal move towards winning */
Move tempMove = new Move(MINIMUM, 0, 0);
Move bestMove = new Move(MINIMUM, 0, 0);
for(int i = 0; i<3; i++){
for(int j = 0; j<3; j++){
if(this.game.IsEmpty(i,j)){
GameBoard tempGame = new GameBoard(this.game, "Single Player");
tempMove = MakeMoves(tempGame, i, j);
if(tempMove.score > bestMove.score){
bestMove.row = tempMove.row;
bestMove.col = tempMove.col;
bestMove.score = tempMove.score;
}
}
}
}
this.game.MakeMove(bestMove.row, bestMove.col);
}
}
public Move MakeMoves(GameBoard tempGame, int row, int col){
String player = tempGame.GetCurrentPlayer();
tempGame.MakeMove(row, col);
if(tempGame.GameWinner().equals("Match Draw")){
return new Move(0, row, col);
}
else if(tempGame.GameWinner().equals("X wins")){
if(player.equals("X")){
return new Move(1, row, col);
}
else{
return new Move(-1, row, col);
}
}
else if(tempGame.GameWinner().equals("O wins")){
if(player.equals("O")){
return new Move(1, row, col);
}
else{
return new Move(-1, row, col);
}
}
else{
Move bestMove = new Move(MINIMUM, 0, 0);
Move tempBestMove = new Move(0, 0, 0);
for(int i = 0; i<3; i++){
for(int j = 0; j<3; j++){
if(tempGame.IsEmpty(i,j)){
GameBoard newGame = new GameBoard(tempGame, "Single Player");
tempBestMove = MakeMoves(newGame, i, j);
if(tempBestMove.score > bestMove.score)
bestMove = tempBestMove;
}
}
}
return bestMove;
}
}
}
class Move{
public int score;
public int row;
public int col;
public Move(int score, int row, int col){
this.score = score;
this.row = row;
this.col = col;
}
}
Your loop is likely typing up your processor, and the SOP slows the loop enough to allow other processes to occur. But regardless and most importantly, you don't want to have this loop present in the first place. You state that you have a,
Tic-Tac-Toe Single player game using basic swing graphics
Remember that Swing is an event driven GUI library, so rather than loop as you would in a linear console program, let events occur, but respond to them based on the state of the program.
In other words, give your class several fields including a boolean variable that tells whose turn it is, such as boolean playersTurn, a boolean variable gameOver, ..., and change the state of these variables as the game is played, and base the games behavior depending on these states. For instance the game would ignore the player's input if it was not his turn.
I am making a simple 2d game in java and i am trying to get fighting to work. I am going to do pokemon-style fighting, so what i am doing is when i press the spacebar, it checks if i am colliding with an enemy, finds that enemy in an arrayList, and then executes the fight method using that enemy. This works most of the time, but sometimes it can't seem to find the enemy in the ArrayList. My code for checking this is:
if (space) {
for (Rectangle collideable : Enemy.ens) {
if (intersects(playerR, collideable)) {
System.out.println("Colliding with Enemy!");
x = locx;
y = locy;
playerR.setLocation(x, y);
for (int i = 0; i < Game.enemies.size(); i++) {
if (Enemy.ens.get(i).equals(collideable)) {
System.out.println("Can't find enemy to fight");
System.out.println(Game.enemies.get(i).getName());
fightQuestion(Game.enemies.get(i), i);
break;
}
}
break;
}
}
}
Enemy.ens is created when i render each enemy. Game.enemies is created when I read in all of the enemy stats, and then i add each enemy to that ArrayList. For every enemy i try to fight, it is getting to the point where it prints out that it is colliding, but not always to the fight part. Any ideas as to why this is happening would be fantastic!
EDIT
Code for when Game.Enemies is filled:
public static void loadEnemies() {
im = getImageManager();
Scanner qwe;
try {
qwe = new Scanner(new File("enemyStats.txt"));
while (qwe.hasNextLine()) {
String name = qwe.nextLine();
String origin = qwe.nextLine();
String weapon = qwe.nextLine();
String gear = qwe.nextLine();
String spec = qwe.nextLine();
int hp = qwe.nextInt();
int att = qwe.nextInt();
int def = qwe.nextInt();
int randX = (int) (Math.random()*(18*SCALE*TILESIZE)); //Give random x coordinate
int randY = (int) (Math.random()*(18*SCALE*TILESIZE)); //Give random y coordinate
if(qwe.hasNextLine()){
qwe.nextLine();
}
enemies.add(new Enemy(randX,randY,im,name,origin,weapon,gear,spec,hp,att,def)); //adds enemy into arrayList
int randI = (int) (Math.random()*enemies.size());
for(int i = 0; i < 4;i++){ //adds enemy to arrayList to be rendered
enemiestoRend.add(enemies.get(randI) );
}
}
}
catch (FileNotFoundException e) {
e.printStackTrace();
}
}
Why do you execute the statement:
System.out.println("Can't find enemy to fight");
for each iteration in the second loop, regardless of checking a condition first? And why does the second loop check:
i < Game.enemies.size();
instead of:
i < Enemy.ens.size();
For a school project, I created the following program:
BlckJckUI.java
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import javax.swing.*;
public class BlckJckUI {
public static void main(String args[])
{
JFrame GUI = new JFrame("Blackjack Advisor");
GUI.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
GUI.setSize(800,800);
GUI.setVisible(true);
ImageIcon Ace = new ImageIcon("C:\\Users\\Hieu Vo\\workspace\\Deck-2014-01-03\\Deck\\Ace.jpg");
JButton ace = new JButton(Ace);
ace.setSize(300, 100);
ace.setLocation(100, 100);
ace.addActionListener(new ActionListener()
{
public void actionPerformed(ActionEvent e)
{
Arrays array = new Arrays();
Math math = new Math();
if (array.playerhandtotal <= 21)
{
math.cardvalue = 11;
}
else
{
math.cardvalue = 1;
}
array.clicktracker++;
JOptionPane.showMessageDialog(null,array.result);
}
});
GUI.add(ace);
ImageIcon Two = new ImageIcon("C:\\Users\\Hieu Vo\\workspace\\Deck-2014-01-03\\Deck\\2.jpg");
JButton two = new JButton(Two);
two.setSize(300, 100);
two.setLocation(100, 200);
two.addActionListener(new ActionListener ()
{
public void actionPerformed(ActionEvent e)
{
Arrays array = new Arrays();
Math math = new Math();
math.cardvalue = 2;
array.clicktracker++;
JOptionPane.showMessageDialog(null,array.result);
}
});
GUI.add(two);
ImageIcon Three = new ImageIcon("C:\\Users\\Hieu Vo\\workspace\\Deck-2014-01-03\\Deck\\3.jpg");
JButton three = new JButton(Three);
three.setSize(300, 100);
three.setLocation(100, 300);
three.addActionListener(new ActionListener ()
{
public void actionPerformed(ActionEvent e)
{
Arrays array = new Arrays();
Math math = new Math();
math.cardvalue = 3;
array.clicktracker++;
;
JOptionPane.showMessageDialog(null,array.result);
}
});
GUI.add(three);
ImageIcon Four = new ImageIcon("C:\\Users\\Hieu Vo\\workspace\\Deck-2014-01-03\\Deck\\4.jpg");
JButton four = new JButton(Four);
four.setSize(300, 100);
four.setLocation(100, 400);
four.addActionListener(new ActionListener ()
{
public void actionPerformed(ActionEvent e)
{
Arrays array = new Arrays();
Math math = new Math();
math.cardvalue = 4;
array.clicktracker++;
;
JOptionPane.showMessageDialog(null,array.result);
}
});
GUI.add(four);
ImageIcon Five = new ImageIcon("C:\\Users\\Hieu Vo\\workspace\\Deck-2014-01-03\\Deck\\5.jpg");
JButton five = new JButton(Five);
five.setSize(300, 100);
five.setLocation(100, 500);
five.addActionListener(new ActionListener ()
{
public void actionPerformed(ActionEvent e)
{
Arrays array = new Arrays();
Math math = new Math();
math.cardvalue = 5;
array.clicktracker++;
;
JOptionPane.showMessageDialog(null,array.result);
}
});
GUI.add(five);
ImageIcon Six = new ImageIcon("C:\\Users\\Hieu Vo\\workspace\\Deck-2014-01-03\\Deck\\6.jpg");
JButton six = new JButton(Six);
six.setSize(300, 100);
six.setLocation(900, 100);
six.addActionListener(new ActionListener ()
{
public void actionPerformed(ActionEvent e)
{
Arrays array = new Arrays();
Math math = new Math();
math.cardvalue = 6;
array.clicktracker++;
;
JOptionPane.showMessageDialog(null,array.result);
}
});
GUI.add(six);
ImageIcon Seven = new ImageIcon("C:\\Users\\Hieu Vo\\workspace\\Deck-2014-01-03\\Deck\\7.jpg");
JButton seven = new JButton(Seven);
seven.setSize(300, 100);
seven.setLocation(900, 200);
seven.addActionListener(new ActionListener()
{
public void actionPerformed(ActionEvent e)
{
Arrays array = new Arrays();
Math math = new Math();
math.cardvalue = 7;
array.clicktracker++;
;
JOptionPane.showMessageDialog(null,array.result);
}
});
GUI.add(seven);
ImageIcon Eight = new ImageIcon("C:\\Users\\Hieu Vo\\workspace\\Deck-2014-01-03\\Deck\\8.jpg");
JButton eight = new JButton(Eight);
eight.setSize(300, 100);
eight.setLocation(900, 300);
eight.addActionListener(new ActionListener()
{
public void actionPerformed(ActionEvent e)
{
Arrays array = new Arrays();
Math math = new Math();
math.cardvalue = 8;
array.clicktracker++;
;
JOptionPane.showMessageDialog(null,array.result);
}
});
GUI.add(eight);
ImageIcon Nine = new ImageIcon("C:\\Users\\Hieu Vo\\workspace\\Deck-2014-01-03\\Deck\\9.jpg");
JButton nine = new JButton(Nine);
nine.setSize(300, 100);
nine.setLocation(900, 400 );
nine.addActionListener(new ActionListener()
{
public void actionPerformed(ActionEvent e)
{
Arrays array = new Arrays();
Math math = new Math();
math.cardvalue = 9;
array.clicktracker++;
;
JOptionPane.showMessageDialog(null,array.result);
}
});
GUI.add(nine);
ImageIcon Ten = new ImageIcon("C:\\Users\\Hieu Vo\\workspace\\Deck-2014-01-03\\Deck\\ten.jpg");
JButton ten = new JButton(Ten);
ten.setSize(300, 100);
ten.setLocation(900, 500);
ten.addActionListener(new ActionListener()
{
public void actionPerformed(ActionEvent e)
{
Arrays array = new Arrays();
Math math = new Math();
math.cardvalue = 10;
array.clicktracker++;
JOptionPane.showMessageDialog(null,array.result);
}
});
GUI.add(ten);
JButton start = new JButton("Start/Reset");
start.setSize(300, 100);
start.setLocation(500,500);
start.addActionListener(new ActionListener ()
{
public void actionPerformed(ActionEvent e)
{
;
Arrays array = new Arrays();
array.playerhand.clear();
array.dealer = 0;
array.clicktracker = 0;
array.playerhandtotal = 0;
array.result = null;
JOptionPane.showMessageDialog(null,"Please select the card \nthat the dealer is showing :)");
}
});
GUI.add(start);
GUI.setLayout(null);
GUI.pack();
//start.setSize(somethinghere);
//start.setLocation(Somethinghere);
}
}
Math.java
public class Math
{
public int cardvalue;
public Math()
{
Arrays array = new Arrays();
if (array.clicktracker == 1)
{
array.dealer = cardvalue;
array.result = "Please select the first card you have :)";
}
else if (array.clicktracker == 2)
{
array.playerhand.add(cardvalue);
array.result = "Please select the second card you have :)";
}
else if (array.clicktracker >= 3)
{
array.playerhand.add(cardvalue);
if (array.playerhandtotal <= 8)
{
// array.result = result statement
array.result = "You should just hit until you're safe. If the dealer 6 or below,\n"
+ " the chances are that he'll bust and if not, remain low above 17.\n"
+ " As long as you can pull a 17 or higher, you should be safe. Pick \n"
+ "another card or reset.";
}
else if (array.playerhandtotal == 9)
{
if (3 <= array.dealer && array.dealer <= 6)
{
array.result = "Double down. The chances of him busting is high,\n"
+ "chances of him not having a high total is high as well. \n"
+ "Chances you'll get a 10 is high as well. Pick another card or reset.";
}
else
{
array.result = "Your best option is to Hit, and it's a luck thing from there. The dealer has some room with a 2; it's highly likely for him to get right below 21 and well above 16, and given that you'll have to beat him in the end, you have to hit until you're high. With 7 plus, he's set: He gets a 10 and he can stop, and again in the end, you'll have to beat his score. May the Goddess of Luck favor you, because you'll need it. Pick another card or reset.";
}
}
else if (array.playerhandtotal == 10)
{
if (2 <= array.dealer && array.dealer <= 9)
{
array.result = "Double down, since Assumption Rule wins out in your favor, if you have a 10, you're golden. The dealer has very little chance of beating you: chances are that he busts or loses to your almighty 20. Even if you bust, the chance that he busts is sufficiently high as well. Very unlikely for him to get 21. Pick another card or reset.";
}
else
{
array.result = "Hit. Dealer is in green zone, Assumption Rule states that he'll get a 20 or 21. Gotta beat him, no way around it. Hope for the best. A double will never cut it, since you're gambling on 1 card to get 20-21. Better safe than sorry. Pick another card or reset.";
}
}
else if (array.playerhandtotal == 11)
{
if (2 <= array.dealer && array.dealer <= 10)
{
array.result = "Double down, since Assumption Rule wins out in your favor, if you have a 10, you're golden. The dealer has very little chance of beating you: chances are that he busts ors loses to your almighty 21. Even if you bust, the chance that he busts is sufficiently high as well. Pick another card or reset.";
}
else
{
array.result = "Hit. He's going to have a 10 due to Assumption Rule. You may as well, but remember, you're less likely to. Thus, hit to be safe. You have to beat to win, and if you Double Down, you lock yourself into a position where the chances of you beating the dealer is slim. (At least, slimmer than hitting.) Pick another card or reset.";
}
}
else if (array.playerhandtotal == 12)
{
if ((array.dealer == 2 || array.dealer == 3) || (array.dealer >= 7))
{
array.result = "Hit. You're likely to lose anyways, per the Assumption Rule. However, there's always a chance that you won't. Doubling makes no sense, and it will reduce your chance of winning. The dealer has some room with a 2; it's highly likely for him to get right below 21 and well above 16, and given that you'll have to beat him in the end, you have to hit until you're high. With 7 plus, he's set: He gets a 10 and he can stop, and again in the end, you'll have to beat his score. Pick another card or reset.";
}
else
{
array.result = "Stand. You have a high chance of bust, but the dealer does as well. If you stay, chances are, dealer will bust. Pick another card or reset.";
}
}
else if (13 <= array.playerhandtotal && array.playerhandtotal <= 16)
{
if (array.dealer >= 7)
{
array.result = "Hit. Might as well. Chances are against you severely, but you still have to play on chance. Hitting is the safest option. Pick another card or reset.";
}
else
{
array.result = "Stand. Dealer may bust; ride on that chance. Pick another card or reset.";
}
}
else if (17 <= array.playerhandtotal && array.playerhandtotal <= 21)
{
array.result = "Stand. You're golden. Just hope for the best and let Lady Luck work her magic. Rest please.";
}
else if (array.playerhandtotal >= 22)
{
array.result = " Oi. You've busted. Reset please.";
}
}
}
}
Arrays.java
import java.util.*;
public class Arrays
{
public String result;
ArrayList<Integer> playerhand = new ArrayList<Integer>();
public int dealer = 0;
public int clicktracker = 0;
public int playerhandtotal = 0;
{
for (int element: playerhand)
{
playerhandtotal = element + playerhandtotal;
}
}
}
The program is supposed to be a Black Jack Advisory tool, and when you click "start/reset" it should ask you to click 1 card (which is the card that the dealer shows.) When you click a card , it then asks you to click the first card you have. When you click that, it then asks for your second card, etc. etc.
When you click start, it works fine, however, when you click ANY of the number cards, the JOptionPanel doesn't say anything.
I'm pretty sure this is because the value of the string its supposed to put out is "null," which I don't want it to be.
How do I make it so that it takes the value of array.result in the if-else statements?
Check your Arrays class. Your missing a method definition around your for statement. And my best guess is to give your result variable a default empty value ->
public String result = "";