I am making a 4-class RPG. It has Player class which allows us to move the player. It has Board class which is for the map in the game. There is a Battle class which is for the battle phase. RPG is the main class responsible for running the game.
What I want is the when the player comes to coordinates(500x500) I want the program to open a new window and it will have the JPanel of battle on it.
EDIT : Updated display() and actionPerformed() methods
import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
public class Player {
private int dx,dy,x,y;
private Image image;
private ImageIcon front = new ImageIcon("player_front.png");
private ImageIcon left = new ImageIcon("player_left.png");
private ImageIcon right = new ImageIcon("player_right.png");
private ImageIcon back = new ImageIcon("player_back.png");
public Player() {
initplayer();
}
private void initplayer() {
image = front.getImage();
x = 0;
y = 0;
}
public void move() {
x += dx;
y += dy;
}
public int getX() {
return x;
}
public void setX(int x){
this.x = x;
}
public int getY() {
return y;
}
public void setY(int y) {
this.y = y;
}
public Image getImage() {
return image;
}
public void keyPressed(KeyEvent e) {
int key = e.getKeyCode();
dx = 0;
dy = 0;
if (key == KeyEvent.VK_LEFT && x >= 0) {
image = left.getImage();
dx = -1;
}
if (key == KeyEvent.VK_RIGHT && x <= 850) {
image = right.getImage();
dx = 1;
}
if (key == KeyEvent.VK_UP && y >= 0) {
image = back.getImage();
dy = -1;
}
if (key == KeyEvent.VK_DOWN && y <= 850) {
image = front.getImage();
dy = 1;
}
}
public void keyReleased(KeyEvent e) {
int key = e.getKeyCode();
if (key == KeyEvent.VK_LEFT) {
dx = 0;
}
if (key == KeyEvent.VK_RIGHT) {
dx = 0;
}
if (key == KeyEvent.VK_UP) {
dy = 0;
}
if (key == KeyEvent.VK_DOWN) {
dy = 0;
}
}
}
import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
public class Board extends JPanel implements ActionListener {
private Battle battle;
private Timer timer;
private Player player;
private final int DELAY = 10;
private Image image;
private JLabel label;
public Board() {
initBoard();
}
private void initBoard() {
image = Toolkit.getDefaultToolkit().createImage("map.png");
addKeyListener(new TAdapter());
setFocusable(true);
player = new Player();
timer = new Timer(DELAY, this);
timer.start();
}
public Image getImage(){
return image;
}
#Override
public void paintComponent(Graphics g) {
super.paintComponent(g);
g.drawImage(image,0,0,null);
doDrawing(g);
}
private void doDrawing(Graphics g) {
Graphics2D g2d = (Graphics2D) g;
g2d.drawImage(player.getImage(), player.getX(), player.getY(), this);
}
public boolean checkBattle(){
if(player.getX() == 500 && player.getY() == 500){
return true;
}
return false;
}
public void actionPerformed(ActionEvent e) {//UPDATED
player.move();
if(checkBattle()){
battle.display();
}
repaint();
}
private class TAdapter extends KeyAdapter {
#Override
public void keyReleased(KeyEvent e) {
player.keyReleased(e);
}
#Override
public void keyPressed(KeyEvent e) {
player.keyPressed(e);
}
}
}
import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
import java.util.*;
public class Battle extends JPanel{
private JFrame frame;
private JPanel panel1, panel2;
private JLabel label1, label2, label3, label4;
private JButton button1, button2, button3, button4;
private int playerHealth = 100;
private int opponentHealth = 50;
private int maxOpponentHealth = 50;
private int level = 0;
private int playerDamage, opponentDamage, chance, levelDamage;
private ImageIcon image;
public Battle(){
setPreferredSize(new Dimension(500,500));
setLayout(new BorderLayout());
panel1 = new JPanel();
panel1.setLayout(new FlowLayout());
label1 = new JLabel("You : " + Integer.toString(playerHealth) + " / 100");
label2 = new JLabel("Opponent : " + Integer.toString(opponentHealth) + " / 50");
button1 = new JButton("Power Attack!(%50 hit chance)");
button2 = new JButton("Normal Attack!(%70 hit chance)");
button3 = new JButton("Quick Attack!(%90 hit chance)");
button4 = new JButton("NEXT LEVEL!");
panel2 = new JPanel();
ImageIcon image = new ImageIcon("player_vs_rival.png");
label4 = new JLabel(image);
ButtonListener listener = new ButtonListener();
button1.addActionListener(listener);
button2.addActionListener(listener);
button3.addActionListener(listener);
button4.addActionListener(listener);
panel1.add(button1);
panel1.add(button2);
panel1.add(button3);
panel1.add(button4);
panel2.add(label4);
label3 = new JLabel("");
add(label1, BorderLayout.WEST);
add(label2, BorderLayout.EAST);
add(label3, BorderLayout.SOUTH);
add(panel1, BorderLayout.CENTER);
add(panel2, BorderLayout.NORTH);
}
public void powerAttack(){
Random random = new Random();
playerDamage = random.nextInt(5) + 10;
}
public void normalAttack(){
Random random = new Random();
playerDamage = random.nextInt(10) + 5;
}
public void quickAttack(){
Random random = new Random();
playerDamage = random.nextInt(5) + 5;
}
public void opponentAttack(){
Random random = new Random();
opponentDamage = random.nextInt(5) + 5;
}
public boolean checkPowerAttack(){
Random random = new Random();
chance = random.nextInt(100);
if(chance >= 50){
return true;
}
return false;
}
public boolean checkNormalAttack(){
Random random = new Random();
chance = random.nextInt(100);
if(chance >= 30){
return true;
}
return false;
}
public boolean checkQuickAttack(){
Random random = new Random();
chance = random.nextInt(100);
if(chance >= 10){
return true;
}
return false;
}
public boolean checkOpponentAttack(){
Random random = new Random();
chance = random.nextInt(100);
if(chance >= 25){
return true;
}
return false;
}
public void levelDamage(){
Random random = new Random();
levelDamage = random.nextInt(5);
levelDamage = levelDamage * level;
}
public void display(){//UPDATED
JFrame newFrame = new JFrame("New Window");
Battle battle = new Battle();
newFrame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
newFrame.setVisible(true);
newFrame.pack();
newFrame.getContentPane().add(battle);
}
}
private class ButtonListener implements ActionListener{
public void actionPerformed(ActionEvent e){
Object source = e.getSource();
if(source == button1){
if(checkPowerAttack() == true){
powerAttack();
}
else
playerDamage = 0;
opponentHealth = opponentHealth - playerDamage;
}
if(source == button2){
if(checkNormalAttack() == true){
normalAttack();
}
else
playerDamage = 0;
opponentHealth = opponentHealth - playerDamage;
}
if(source == button3){
if(checkQuickAttack() == true){
quickAttack();
}
else
playerDamage = 0;
opponentHealth = opponentHealth - playerDamage;
}
if((source == button1 || source == button2) || source == button3){
if(checkOpponentAttack() == true){
opponentAttack();
}
else
opponentDamage = 0;
playerHealth = playerHealth - opponentDamage - levelDamage;
}
if(source == button4){
level++;
opponentHealth = opponentHealth + 25;
maxOpponentHealth = opponentHealth;
}
if(playerHealth <= 0 && opponentHealth > 0){
JOptionPane.showMessageDialog(null,"YOU LOSE");
}
if(opponentHealth <= 0 && playerHealth > 0){
JOptionPane.showMessageDialog(null,"YOU WIN");
}
label1.setText("You : " + Integer.toString(playerHealth) + " / 100");
label2.setText("Opponent : " + Integer.toString(opponentHealth) + " / " + Integer.toString(maxOpponentHealth));
if(playerDamage != 0 && opponentDamage != 0){
label3.setText("You made " + Integer.toString(playerDamage) + " damage to your opponent. " + http://stackoverflow.com/editing-help
"Your opponent give " + Integer.toString(opponentDamage + levelDamage) + " damage to you.");
}
else if(playerDamage == 0 && opponentDamage != 0){
label3.setText("YOU MISSED YOUR ATTACK! " +
"Your opponent give " + Integer.toString(opponentDamage + levelDamage) + " damage to you.");
}
else if(playerDamage != 0 && opponentDamage == 0){
label3.setText("You made " + Integer.toString(playerDamage) + " damage to your opponent. " +
"YOUR OPPONENT MISSED HIS ATTACK!");
}
else if(playerDamage == 0 && opponentDamage == 0){
label3.setText("YOU MISSED YOUR ATTACK! " +
"YOUR OPPONENT ALSO MISSED HIS ATTACK!");
}
}
}
}
import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
public class RPG extends JFrame {
private Board board = new Board();
private Battle battle = new Battle();
public RPG() {
initUI();
}
private void initUI() {
add(board);
setSize(900, 900);
setResizable(false);
setTitle("RPG");
setLocationRelativeTo(null);
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
}
public static void main(String[] args) {
EventQueue.invokeLater(new Runnable() {
public void run() {
RPG ex = new RPG();
ex.setVisible(false);
}
});
}
}
Opening a new window is as simple as creating a new frame like you've already done in your display() function. For instance, this:
JFrame newFrame = new JFrame("New Window");
newFrame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
newFrame.setVisible(true);
Should be enough to open a new window with nothing in it (you'll probably want to add something to it you did in your display() method). Since you want to do this when the player reaches a certain position, just check the player coordinates on movement and call similar code to open a new frame.
EDIT:
Upon looking again, it looks like you can just call display() in your checkBattle() function? It looks like you already have most of the logic here. If you're wondering where to call checkBattle() from, I'd put it in the Player.move() function.
Related
I am making a simple maze game, and am trying to make a main menu for it. Basically, whenever a JButton is pressed, an ActionListener is called, and creates a new window with the game inside of it. inside the game, there is a KeyListener so that you can move around with the arrow keys. However, when I run it, the arrow keys do not work, and the button stays pressed. Here is the code for the MainMenu:
import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
import java.io.*;
public class MainMenu extends JFrame
{
private int timer;
private JLabel Timer;
public MainMenu(String title, int width, int height){
JButton maze1 = new JButton("Maze 1");
JButton maze2 = new JButton("Maze 2");
JButton maze3 = new JButton("Maze 3");
JButton maze4 = new JButton("Maze 4");
JButton maze5 = new JButton("Maze 5");
JLabel instructions = new JLabel();
instructions.setText("Pick a maze!");
Timer = new JLabel();
Timer.setBounds(0, 150, 220, 20);
Timer.setText("0.0");
maze1.addActionListener(new ActionListener(){
public void actionPerformed(ActionEvent arg0){
try{playMaze(1);}catch(FileNotFoundException e){}
}
});
maze2.addActionListener(new ActionListener(){
public void actionPerformed(ActionEvent arg0){
try{playMaze(2);}catch(FileNotFoundException e){}
}
});
maze3.addActionListener(new ActionListener(){
public void actionPerformed(ActionEvent arg0){
try{playMaze(3);}catch(FileNotFoundException e){}
}
});
maze4.addActionListener(new ActionListener(){
public void actionPerformed(ActionEvent arg0){
try{playMaze(4);}catch(FileNotFoundException e){}
}
});
maze5.addActionListener(new ActionListener(){
public void actionPerformed(ActionEvent arg0){
try{playMaze(5);}catch(FileNotFoundException e){}
}
});
add(instructions);
add(maze1);
add(maze2);
add(maze3);
add(maze4);
add(maze5);
setTitle(title);
setLayout(new FlowLayout());
setSize(width, height);
timer = 0;
}
public void playMaze(int i) throws FileNotFoundException{
MazeCreator creator = new MazeCreator();
creator.createMaze("MAZE" + i + ".txt");
MazeRunner runner = new MazeRunner(creator.getMaze(), 0, 5, timer);
runner.run();
timer = runner.getTime();
Timer.setText("" + timer/10.0);
}
}
The MazeRunner:
import java.awt.Canvas;
import java.awt.Dimension;
import java.awt.Graphics2D;
import java.awt.image.BufferStrategy;
import java.awt.event.*;
import javax.swing.*;
import java.awt.*;
public class MazeRunner implements Runnable
{
private JFrame frame;
private Canvas canvas;
private BufferStrategy bufferStrategy;
private String[][] maze;
private int x;
private int y;
private boolean win;
private int timer;
public MazeRunner(String[][] Maze, int Y, int X, int t){
frame = new JFrame("Maze Game");
JPanel panel = (JPanel) frame.getContentPane();
panel.setPreferredSize(new Dimension(220, 250));
panel.setLayout(null);
canvas = new Canvas();
canvas.setBounds(0, 0, 220, 250);
canvas.setIgnoreRepaint(true);
panel.add(canvas);
canvas.addKeyListener(new KeyAdapter() {
#Override
public void keyPressed(KeyEvent evt) {
move(evt);
}
});
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.pack();
frame.setResizable(false);
frame.setVisible(true);
canvas.createBufferStrategy(2);
bufferStrategy = canvas.getBufferStrategy();
canvas.requestFocus();
maze = Maze;
x = X;
y = Y;
maze[y][x] = "#";
win = false;
timer = t;
}
public boolean checkWin(){return win;}
public void run(){
while(!win){
Paint();
try {
Thread.sleep(100);
} catch (InterruptedException e) {
}
timer++;
}
maze[y][x] = "#";
Paint();
try{Thread.sleep(1000);}catch(InterruptedException e){}
frame.dispose();
}
public void move(KeyEvent evt) {
switch (evt.getKeyCode()) {
case KeyEvent.VK_DOWN:
moveDown();
break;
case KeyEvent.VK_UP:
moveUp();
break;
case KeyEvent.VK_LEFT:
moveLeft();
break;
case KeyEvent.VK_RIGHT:
moveRight();
break;
}
}
public void moveUp(){
maze[y][x] = "-";
if(!(y > 0)){
}else if(maze[y - 1][x].equals("*")){
}else if(maze[y - 1][x].equals("#")){
y -= 1;
win = true;
}else{
y -= 1;
}
maze[y][x] = "#";
}
public void moveDown(){
maze[y][x] = "-";
if(!(y < 10)){
}else if(maze[y + 1][x].equals("*")){
}else if(maze[y + 1][x].equals("#")){
y += 1;
win = true;
}else{
y += 1;
}
maze[y][x] = "#";
}
public void moveLeft(){
maze[y][x] = "-";
if(!(x > 0)){
}else if(maze[y][x - 1].equals("*")){
}else if(maze[y][x - 1].equals("#")){
x -= 1;
win = true;
}else{
x -= 1;
}
maze[y][x] = "#";
}
public void moveRight(){
maze[y][x] = "-";
if(!(x < 10)){
}else if(maze[y][x + 1].equals("*")){
}else if(maze[y][x + 1].equals("#")){
x += 1;
win = true;
}else{
x += 1;
}
maze[y][x] = "#";
}
public void printMaze(){
System.out.println("\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n");
for(int i = 0; i < 11; i++){
for(int e = 0; e < 11; e++){
System.out.print(maze[i][e] + " ");
}
System.out.println();
}
}
public void Paint() {
Graphics2D g = (Graphics2D) bufferStrategy.getDrawGraphics();
g.clearRect(0, 0, 500, 500);
Paint(g);
bufferStrategy.show();
}
protected void Paint(Graphics2D g) {
for(int i = 0; i < 11; i++){
for(int e = 0; e < 11; e++){
if(maze[i][e].equals("*")){
g.setColor(Color.BLACK);
g.fillRect(e*20, i*20, 20, 20);
}else if(maze[i][e].equals("#")){
g.setColor(Color.RED);
g.fillOval(e*20, i*20, 20, 20);
}else if(maze[i][e].equals("#")){
g.setColor(Color.BLUE);
g.fillRect(e*20, i*20, 20, 20);
}
}
}
g.setColor(Color.BLACK);
g.drawString("" + (timer / 10.0), 190, 240);
if(win){
g.setFont(new Font("Dialouge", Font.BOLD, 20));
g.drawString("YOU WIN!", 10, 240);
}
}
public String mazeToString(int y){
String toString = "";
for(int e = 0; e < 11; e++){
toString += maze[y][e] + " ";
}
return toString;
}
public int getTime(){return timer;}
}
And the MazeCreator:
import java.util.*;
import java.io.*;
public class MazeCreator
{
private String[][] maze;
private int xPos;
private int yPos;
private File file;
private Scanner input;
public MazeCreator(){
maze = new String[11][11];
}
public String[][] getMaze(){return maze;}
public void createMaze(String File) throws FileNotFoundException{
input = new Scanner(new File("C:/Users/Owner/Maze/" + File));
for(int i = 0; i < 11; i++){
for(int e = 0; e < 11; e++){
maze[i][e] = input.next();
//System.out.print(maze[i][e] + " ");
}
input.nextLine();
//System.out.println();
}
}
}
Any help that anyone could give would be great.
I have been working on a snake game, but an improvement I wanted to make was adding text to the game, giving instructions and keeping track of points. I messed around with JPanel and a few other things that all open a new, mini window that displays the text rather than printing it on the primary window
EDIT:
Thanks to several helpful people, I understand the correct use, but when I use it while attempting to change the color, it changes the color of the background as well. I was under the assumption this is because it's in the same class as the background, so when I put g.setColor under the background's color, it changed it.
I tried making a new object using paintComponent() while the background was in paint(), and the text didn't show up.
Any advice?
Here is the main java file:
import javax.swing.JPanel;
import java.awt.*;
import java.awt.event.*;
import java.util.ArrayList;
import java.util.Random;
public class Gamepanel extends JPanel implements Runnable, KeyListener {
private static final long serialVersionUID = 1L;
public static final int WIDTH = 500, HEIGHT = 500; //window size
private Thread thread;
private boolean running; //allows the game to be started/stopped
private boolean right = true, left = false, up = false, down = false; //setting default movement
private BodyPart b;
private ArrayList<BodyPart> snake;
private Food food;
private ArrayList<Food> foods;
private Random r; //creating random integer for food spawn
private int xCoor = 10, yCoor = 10, size = 5; //setting location and coordinate size, along with snake length
private int ticks = 0;
private int points = 0;
public Gamepanel() {
setFocusable(true);
setPreferredSize(new Dimension(WIDTH, HEIGHT)); //window size
addKeyListener(this); //allows key input from user
snake = new ArrayList <BodyPart>();
foods = new ArrayList <Food>();
r = new Random(); //random integer
}
public void start() {
running = true; //allows the game to start
thread = new Thread(this);
thread.start();
}
public void stop() {
running = false; //stops the game from running
try {
thread.join();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
public void tick() {
if(snake.size() == 0) { //sets location
b = new BodyPart(xCoor, yCoor, 10);
snake.add(b);
}
ticks++; //constant tick increase
if(ticks > 750000) { //sets speed (higher = slower)
if(right) xCoor ++;
if(left) xCoor --;
if(up) yCoor --;
if(down) yCoor ++;
ticks = 0;
b = new BodyPart(xCoor, yCoor, 10);
snake.add(b);
if(snake.size() > size) {
snake.remove(0); //removes earliest value in snake size
}
}
if(foods.size() == 0) { //sets food in window range(multiplies by 10)
int xCoor = r.nextInt(48);
int yCoor = r.nextInt(48);
points++;
food = new Food(xCoor, yCoor, 10);
foods.add(food);
}
for (int i = 0 ; i < foods.size(); i++) { //spawns new food when old food is eaten
if(xCoor == foods.get(i).getxCoor() && yCoor == foods.get(i).getyCoor()) {
size ++;
foods.remove(i);
i++;
}
}
//player body collision
for(int i = 0 ; i < snake.size(); i++) {
if(xCoor == snake.get(i).getxCoor() && yCoor == snake.get(i).getyCoor()) {
if(i != snake.size() - 1) {
System.out.print("Game Over! " + "Points: " + points);
stop();
}
}
}
//border collision
if(xCoor < 0 || xCoor > 49 || yCoor < 0 || yCoor > 49) {
System.out.println("Game Over! " + "Points: " + points);
stop();
}
}
public void paint(Graphics g) { //background color/size setter
g.clearRect(0, 0, WIDTH, HEIGHT);
g.setColor(Color.BLACK); //background color
g.fillRect(0, 0, WIDTH, HEIGHT);
for(int i = 0; i < WIDTH/10 ; i++) {
g.drawLine(i * 10, 0, i * 10, HEIGHT);
}
for(int i = 0; i < HEIGHT/10 ; i++) {
g.drawLine(0, i * 10, HEIGHT, i * 10);
}
for(int i = 0 ; i < snake.size(); i++) {
snake.get(i).draw(g);
}
for(int i = 0 ; i < foods.size(); i++) {
foods.get(i).draw(g);
}
}
#Override
public void run() {
while(running) {
tick(); //runs ticks while running is true
repaint();
}
}
#Override
public void keyPressed(KeyEvent e) {
int key = e.getKeyCode();
if(key == KeyEvent.VK_RIGHT && !left) { //right key = right movement
right = true;
up = false;
down = false;
}
if(key == KeyEvent.VK_LEFT && !right) { //left key = left movement
left = true;
up = false;
down = false;
}
if(key == KeyEvent.VK_UP && !down) { //up key = up movement
up = true;
right = false;
left = false;
}
if(key == KeyEvent.VK_DOWN && !up) { //down key = down movement
down = true;
right = false;
left = false;
}
if(key == KeyEvent.VK_SPACE) {
snake.clear();
start();
size = 5;
points = 0;
xCoor = 10;
yCoor = 10;
}
}
#Override
public void keyReleased(KeyEvent arg0) {
}
#Override
public void keyTyped(KeyEvent arg0) {
}
}
Did you try this ?
public void paintComponent(Graphics g) {
super.paintComponent(g);
Font font = new Font("Verdana", Font.BOLD, 14);
g.setFont(font);
g.setColor(Color.black);
g.drawString("instructions", 75, 75);
}
as noted by #Hovercraft maybe you should be overriding the paintComponent() method instead of paint()
I'm new to Java and trying to make a simple Player vs. Computer "Tic-Tac-Toe" game using Swing. In the code I use paintComponent() method to paint certain components and call the repaint() method after the player or computer plays. The problem is that, the game freezes after the third (sometimes the second) time I click the mouse. In GameWindow class I create the instance of Map class.
public class GameWindow extends JFrame{
private final int sizeX = 3;
private final int sizeY = 3;
public GameWindow(){
setLocation(400,150);
setSize(406, 452);
setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);
setResizable(false);
Map map = new Map(sizeX, sizeY);
add(map, BorderLayout.CENTER);
JPanel bottomPanel = new JPanel();
bottomPanel.setLayout(new GridLayout(1, 2));
add(bottomPanel, BorderLayout.SOUTH);
Button newGame = new Button("Новая игра");
newGame.addActionListener(new ActionListener() {
#Override
public void actionPerformed(ActionEvent e) {
System.out.println("Начинаем новую игру");
}
});
Button exit = new Button("Выход");
exit.addActionListener(new ActionListener() {
#Override
public void actionPerformed(ActionEvent e) {
System.exit(0);
}
});
bottomPanel.add(newGame);
bottomPanel.add(exit);
setVisible(true);
}
}
Here is the listener for the mouse click in the Map class:
public class Map extends JPanel {
private final int sizeX;
private final int sizeY;
private int cellWidth;
private int cellHeight;
private int cellX = -1;
private int cellY = -1;
private String lastPlayer = "nobody";
private String[][] table = new String[3][3];
public Map(int sizeX, int sizeY) {
this.sizeX = sizeX;
this.sizeY = sizeY;
setBackground(Color.WHITE);
for (int i = 0; i < table.length; i++) {
for (int j = 0; j < table.length; j++) {
table[i][j] = "empty";
}
}
addMouseListener(new MouseAdapter() {
#Override
public void mouseReleased(MouseEvent e) {
super.mouseReleased(e);
cellX = e.getX() / cellWidth;
cellY = e.getY() / cellHeight;
if (!winOrDraw()) {
boolean playerProgress = playerProgress();
if(playerProgress) {
botProgress();
}
}
}
});
}
Both in playerProgress() and botProgress() methods I call repaint() method to add new components to the screen. I can't really find out what is the problem in this code and why the program freezes after actually 6th call of repaint() method?
Here are winOrDraw(), playerProgress() and botProgress() methods:
private boolean winOrDraw(){
for (int i = 0; i < table.length; i++) {
if(table[i][0] == table[i][1] && table[i][1] == table[i][2] && !table[i][0].equals("empty")) return true;
else if(table[0][i] == table[1][i] && table[1][i] == table[2][i] && !table[0][i].equals("empty")) return true;
else if(table[0][0] == table[1][1] && table[1][1] == table[2][2] && !table[0][0].equals("empty")) return true;
else if(table[2][0] == table[1][1] && table[1][1] == table[0][2] && !table[2][0].equals("empty")) return true;
}
int i, j = 0;
for (i = 0; i < table.length; i++) {
for (j = 0; j < table.length; j++) {
if(table[i][j].equals("empty")) break;
}
}
if(i == table.length && j == table.length) { lastPlayer = "nobody"; return true; }
else return false;
}
private boolean playerProgress(){
if(!table[cellY][cellX].equals("empty")){
System.out.println("This cell is not empty");
return false;
} else {
lastPlayer = table[cellY][cellX] = "player";
repaint();
return true;
}
}
private void botProgress(){
do{
if(winOrDraw()){
switch (lastPlayer) {
case "player":
System.out.println("You won!");
System.exit(0);
case "bot":
System.out.println("Bot won");
System.exit(0);
default:
System.out.println("Draw");
System.exit(0);
}
}
Random random = new Random();
cellX = random.nextInt(2);
cellY = random.nextInt(2);
if(table[cellY][cellX].equals("empty")) {
lastPlayer = table[cellY][cellX] = "bot";
break;
}
}while (!table[cellY][cellX].equals("empty"));
System.out.println("Bot's turn");
repaint();
}
You are adding your Swing components directly to the JFrame-AWT-container. You should not do that. Instead you should do this:
JPanel panel = new JPanel();
myFrame.setContentPane(panel);
panel.setLayout(...)
panel.add(...);
panel.validate();
This should solve your problem.
I am new to Java. I started to learn by creating a bouncing ball GUI.
I have managed to do all i wanted to do with it except one thing. I can't get the ball to change its color whenever it bounces off the Frame Borders.
I know i can't use getGraphics for drawing but in this case i can also not use the paint Method as i already use it for the initial settings at the beginning of the Program. If i call the paint method from within the loop, it does change the color but all the JButtons in the North Side of the Layout mysteriously vanish.
The one Thing that makes the whole thing even more complicated for me is the fact that i am looping the ball bounce in a void run method of the Runnable Interface.
I couldn't figure out how to solve it elsewise.
You Guys can copy my code in your IDE. The one thing that doesn't work is that the ball remains black and doesn't changes it'S color. Everything else is running fine.
So Please help me figure out how i can change the ball's color whenever it bounces.
Thanks
Code:
import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
public class Ball extends JFrame implements Runnable, ActionListener {
private JButton start;
private JButton stop;
private JButton fast;
private JButton slow;
private JButton reset;
private int ball_x;
private int ball_y;
private int dx = 10;
private int dy = 20;
private int size = 50;
private boolean active;
private int i = 20;
private int R = 255;
private int G = 0;
private int B = 255;
private Color rgb;
private MyPanel screen;
private class MyPanel extends JPanel {
public void paintComponent(Graphics g) {
super.paintComponent(g);
ball_x = screen.getWidth() / 2 - 25;
ball_y = screen.getHeight() / 2 - 25;
i = 20;
g.setColor(rgb);
g.fillOval(ball_x, ball_y, size, size);
}
public void clr() {
if (R <= 10) {
R = 255;
}
R = R - 10;
if (G >= 255) {
G = 0;
}
G = G + 15;
if (B <= 20) {
B = 255;
}
B = B - 20;
}
}
public void start() {
active = true;
start.setText("Start");
start.setEnabled(false);
start.setText("Jumping...");
Thread th = new Thread(this); // Thread anlegen
th.start(); // Thread starten
}
public void stop() {
if (active) {
start.setText("Continue");
}
active = false;
start.setEnabled(true);
}
public void reset() {
active = false;
size = 50;
screen.repaint();
start.setText("Start");
start.setEnabled(true);
}
public void slow() {
i = i + 2;
if (i >= 60) {
i = 60;
}
}
public void fast() {
i = i - 2;
if (i <= 5) {
i = 5;
}
}
public void actionPerformed(ActionEvent ereignis) {
if (ereignis.getSource() == start) {
start();
}
if (ereignis.getActionCommand() == "G+") {
fast();
}
if (ereignis.getActionCommand() == "G-") {
slow();
}
if (ereignis.getActionCommand() == "Reset") {
reset();
}
if (ereignis.getActionCommand() == "Pause") {
stop();
}
}
public Ball() {
this.setTitle("Jumping Ball \u00a9 The One");
Container panel = new Container();
panel.setLayout(new BorderLayout());
JPanel subpanel = new JPanel();
//subpanel.setLayout(new GridLayout());
screen = new MyPanel();
this.setVisible(true);
this.setSize(1366, 768);
this.setContentPane(panel);
this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
start = new JButton("Start");
fast = new JButton("G+");
slow = new JButton("G-");
reset = new JButton("Reset");
stop = new JButton("Pause");
subpanel.add(start);
subpanel.add(fast);
subpanel.add(slow);
subpanel.add(reset);
subpanel.add(stop);
panel.add(subpanel, "North");
panel.add(screen, "Center");
start.addActionListener(this);
stop.addActionListener(this);
reset.addActionListener(this);
slow.addActionListener(this);
fast.addActionListener(this);
}
public void run() {
while (active) {
screen.getGraphics().clearRect(ball_x, ball_y, size, size);
if (ball_x > (screen.getWidth() - 30) || ball_x < 25) {
dx = -dx;
size = size + 3;
screen.clr();
}
if (ball_y > (screen.getHeight() - 30) || ball_y < 25) {
dy = -dy;
size = size + 3;
screen.clr();
}
ball_x = ball_x + dx;
ball_y = ball_y + dy;
rgb = new Color(R, G, B);
screen.getGraphics().setColor(rgb);
screen.getGraphics().fillOval(ball_x, ball_y, size, size);
try {
Thread.sleep(i);
} catch (InterruptedException x) {
x.printStackTrace();
}
}
}
public static void main(String[] args) {
Ball bouncer = new Ball();
} // End of Method Main
}
Thank You
While complete, your example has several critical problems:
It is incorrectly synchronized.
It calls setVisible() prematurely.
It relies on the frame's geometry, rather than an enclosed panel.
Instead, start with the example cited here using a Swing Timer. Note that the color changes with each repaint(), and a sound is played with each bounce. Add a member variable, bounced.
private boolean bounced;
When the ball bounces, set bounced = true in the actionPerformed() method of the Timer.
if (ballX - RADIUS < 0) {
…
bounced = true;
} else if (ballX + RADIUS > BOX_WIDTH) {
…
bounced = true;
}
In paintComponent(), change the color accordingly.
g.setColor(clut.peek());
if (bounced) {
clut.add(clut.remove());
bounced = false;
}
It may be easier to see the change with a smaller clut.
private static final float N = 16;
Well i got it to work but i don't think this is the best way to do it! I had to ditch Threads and go for Timer.
I have been reading everywhere that one shouldn't mix AWT and Swing but i don't see any other possibility than panel.setLayout(new BorderLayout()); or public void paintComponent(Graphics g)
This is obviously mixing AWT and Swing Components but i didn't find any pure Swing way to do it.
Anyways this is my entire Code:
import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
public class Ball extends JFrame implements ActionListener {
private JButton start;
private JButton stop;
private JButton fast;
private JButton slow;
private JButton reset;
private int ball_x;
private int ball_y;
private int dx = 10;
private int dy = 20;
private boolean active;
private int i = 30;
private int R = 255;
private int G = 255;
private int B = 0;
private Color rgb;
private Timer trigger = new Timer(i, this);
private MyPanel screen;
private class MyPanel extends JPanel {
public void paintComponent(Graphics g) {
super.paintComponent(g);
if (start.getText() == "Start") {
ball_x = screen.getWidth() / 2 - 50;
ball_y = screen.getHeight() / 2 - 50;
}
if (start.getText() == "Jumping...") {
g.clearRect(ball_x, ball_y, 100, 100);
}
ball_x = ball_x + dx;
ball_y = ball_y + dy;
rgb = new Color(R, G, B);
g.setColor(rgb);
g.fillOval(ball_x, ball_y, 100, 100);
if (ball_x > (screen.getWidth() - 100) || ball_x < 10) {
dx = -dx;
screen.clr();
}
if (ball_y > (screen.getHeight() - 100) || ball_y < 10) {
dy = -dy;
screen.clr();
}
}
public void clr() {
if (R <= 10) {
R = 255;
}
R = R - 10;
if (G <= 20) {
G = 255;
}
G = G - 20;
if (B >= 255) {
B = 0;
}
B = B + 15;
}
}
public void start() {
active = true;
start.setText("Start");
start.setEnabled(false);
start.setText("Jumping...");
trigger.start();
screen.repaint();
}
public void stop() {
if (active) {
start.setText("Continue");
}
active = false;
start.setEnabled(true);
trigger.stop();
}
public void reset() {
active = false;
start.setText("Start");
start.setEnabled(true);
i = 100;
trigger.stop();
screen.repaint();
}
public void slow() {
i = i + 10;
if (i >= 100) {
i = 100;
}
trigger.setDelay(i);
}
public void fast() {
i = i - 10;
if (i <= 10) {
i = 10;
}
trigger.setDelay(i);
}
public void actionPerformed(ActionEvent ereignis) {
if ((ereignis.getSource() == start) || (trigger.isRunning() == true)) {
start();
}
if (ereignis.getActionCommand() == "G+") {
fast();
}
if (ereignis.getActionCommand() == "G-") {
slow();
}
if (ereignis.getActionCommand() == "Reset") {
reset();
}
if (ereignis.getActionCommand() == "Pause") {
stop();
}
}
public Ball() {
this.setTitle("Jumping Ball \u00a9 The One");
JPanel panel = new JPanel();
panel.setLayout(new BorderLayout());
this.setContentPane(panel);
JPanel subpanel = new JPanel();
panel.add(subpanel, "North");
screen = new MyPanel();
screen.setBackground(Color.WHITE);
panel.add(screen, "Center");
start = new JButton("Start");
fast = new JButton("G+");
slow = new JButton("G-");
reset = new JButton("Reset");
stop = new JButton("Pause");
subpanel.add(start);
subpanel.add(fast);
subpanel.add(slow);
subpanel.add(reset);
subpanel.add(stop);
start.addActionListener(this);
stop.addActionListener(this);
reset.addActionListener(this);
slow.addActionListener(this);
fast.addActionListener(this);
this.setSize(1280, 720);
this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
this.setVisible(true);
}
public static void main(String[] args) {
Ball fenster = new Ball();
} // Ende der Methode Main
}
I know this is not the professional way to do it but this is the best i could do and it does what i wanted it to do.
I will be more than happy if someone could point out some absolute no-go's in my Code.
Thanx
This is a pong game I made, but the only thing that is not working is the paddles moving. I am not sure how to make the keyboard work with the program. Here is the code for the main game:
//Project: A program where you play the game pong
//This module defines the properties of the user interface
import java.awt.*;
import javax.swing.*;
import java.awt.event.*;
public class pongframe extends JFrame
{
private JLabel playerlefttitle;
private JLabel playerrighttitle;
private JLabel speedtitle;
private JTextField speedfield;
private JTextField playerleftscorefield;
private JTextField playerrightscorefield;
private JButton newgame;
private JButton gobutton;
private JButton pausebutton;
private JButton quitgame;
private Timer systemclock;
private Timer paddleclock;
private String speedstring;
private int speed;
private int leng = 10;
private int delayinterval;
private float millisecondpersecond = 1000.0f;
private boolean win = false;
private int playerleftscore=0;
private int playerrightscore=0;
private boolean rightup = false;
private boolean rightdown = false;
private boolean leftup = false;
private boolean leftdown = false;
private boolean barhit = true;
private double direction=0;
private pongoperations graphicalpanel;
private Clockhandlerclass clockhandler;
private PaddleClockHandlerClass paddleclockhandler;
private PaddleHandlerClass paddlehandler;
public pongframe()
{
super("Pong");
JPanel panel1 = new JPanel(new GridBagLayout());
GridBagConstraints c = new GridBagConstraints();
graphicalpanel = new pongoperations();
graphicalpanel.setBackground(Color.GREEN);
add(graphicalpanel, BorderLayout.CENTER);
add(panel1, BorderLayout.SOUTH);
c.insets = new Insets(0,0,10,10);
newgame = new JButton("New");
c.gridx = 0;
c.gridy = 1;
panel1.add(newgame, c);
speedtitle = new JLabel("Speed");
c.gridx = 1;
c.gridy = 0;
panel1.add(speedtitle, c);
speedfield = new JTextField(3);
c.gridx = 1;
c.gridy = 1;
panel1.add(speedfield, c);
quitgame = new JButton("Quit");
c.gridx = 2;
c.gridy = 1;
panel1.add(quitgame, c);
playerlefttitle = new JLabel("Player Left");
c.gridx = 0;
c.gridy = 3;
panel1.add(playerlefttitle, c);
playerrighttitle = new JLabel("Player Right");
c.gridx = 3;
c.gridy = 3;
panel1.add(playerrighttitle, c);
playerleftscorefield = new JTextField(2);
playerleftscorefield.setEditable(false);
c.gridx = 0;
c.gridy = 4;
panel1.add(playerleftscorefield, c);
gobutton = new JButton("Go");
c.gridx = 1;
c.gridy = 4;
panel1.add(gobutton, c);
pausebutton = new JButton("Pause");
c.gridx = 2;
c.gridy = 4;
panel1.add(pausebutton, c);
playerrightscorefield = new JTextField(2);
playerrightscorefield.setEditable(false);
c.gridx = 3;
c.gridy = 4;
panel1.add(playerrightscorefield, c);
buttonhandler myhandler = new buttonhandler();
newgame.addActionListener(myhandler);
gobutton.addActionListener(myhandler);
pausebutton.addActionListener(myhandler);
quitgame.addActionListener(myhandler);
clockhandler = new Clockhandlerclass();
paddleclockhandler = new PaddleClockHandlerClass();
paddlehandler = new PaddleHandlerClass();
}
private class buttonhandler implements ActionListener
{
public void actionPerformed(ActionEvent event)
{
graphicalpanel.reset();
if(event.getSource() == newgame)
{
speedfield.setText("");
playerleftscore = 0;
playerrightscore = 0;
playerleftscorefield.setText("0");
playerrightscorefield.setText("0");
graphicalpanel.reset();
graphicalpanel.repaint();
gobutton.setEnabled(true);
speedfield.setEditable(true);
newgame.setEnabled(false);
}
else if(event.getSource() == gobutton)
{
speedstring = speedfield.getText();
leng = speedstring.length();
if(leng == 0)
speed = 0;
else
{
speed = Integer.parseInt(speedstring);
gobutton.setEnabled(false);
speedfield.setEditable(false);
}
newgame.setEnabled(false);
delayinterval = (int)Math.floor(millisecondpersecond/speed + 0.5f);
systemclock = new Timer(delayinterval, clockhandler);
systemclock.start();
paddleclock = new Timer(delayinterval, paddleclockhandler);
paddleclock.start();
}
else if(event.getSource() == pausebutton)
{
gobutton.setEnabled(true);
newgame.setEnabled(true);
systemclock.stop();
}
else if(event.getSource() == quitgame)
{
System.exit(0);
}
else
System.out.println("Unkown error");
}
}
private class Clockhandlerclass implements ActionListener
{
public void actionPerformed(ActionEvent event)
{
if(event.getSource() == systemclock)
{
graphicalpanel.grabFocus();
graphicalpanel.moveball(speed,delayinterval, direction, barhit);
direction = graphicalpanel.changedirection(direction);
if(win == false)
{
barhit = graphicalpanel.barhits(barhit);
graphicalpanel.repaint();
win = graphicalpanel.winner();
playerleftscore = graphicalpanel.playerleftwin(playerleftscore);
playerrightscore = graphicalpanel.playerrightwin(playerrightscore);
playerleftscorefield.setText(Integer.toString(playerleftscore));
playerrightscorefield.setText(Integer.toString(playerrightscore));
}
else if(win == true)
{
graphicalpanel.reset();
win = false;
systemclock.restart();
if(playerleftscore == 10)
{
newgame.setEnabled(true);
systemclock.stop();
}
else if(playerrightscore == 10)
{
newgame.setEnabled(true);
systemclock.stop();
}
graphicalpanel.repaint();
}
}
else
System.out.printf("%s\n", "There is a bug in the clock.");
}
}
private class PaddleClockHandlerClass implements ActionListener
{
public void actionPerformed(ActionEvent event)
{
if(event.getSource() == paddleclock)
{
graphicalpanel.moveplayer1(rightup, rightdown);
graphicalpanel.moveplayer2(leftup, leftdown);
graphicalpanel.repaint();
}
}
}
private class PaddleHandlerClass implements KeyListener
{
public void keyTyped(KeyEvent event)
{
}
public void keyPressed(KeyEvent event)
{
if(event.getKeyCode() == KeyEvent.VK_UP)
{
rightup = true;
System.out.println("Up");
}
else if(event.getKeyCode() == KeyEvent.VK_DOWN)
rightdown = true;
if(event.getKeyCode() == KeyEvent.VK_W)
leftup = true;
else if(event.getKeyCode() == KeyEvent.VK_S)
leftdown = true;
}
public void keyReleased(KeyEvent event)
{
if(event.getKeyCode() == KeyEvent.VK_UP)
rightup = false;
else if(event.getKeyCode() == KeyEvent.VK_DOWN)
rightdown = false;
if(event.getKeyCode() == KeyEvent.VK_W)
leftup = false;
else if(event.getKeyCode() == KeyEvent.VK_S)
leftdown = false;
}
}
}
This next bit of code are the functions that I am using for the game:
//Project: A program where you play the game pong
//This module contains the graphics and algorithms used by this project.
import java.awt.Graphics;
import javax.swing.JPanel;
import java.awt.Color;
public class pongoperations extends JPanel
{
int widthofgraphicalarea;
int heightofgraphicalarea;
final int ballradius = 8;
int ballxcoordinate;
double ballycoordinate;
int paddle1xcoordinate;
int paddle1ycoordinate;
int paddle2xcoordinate;
int paddle2ycoordinate;
public void paintComponent(Graphics graphicarea)
{//function to paint the area
super.paintComponent(graphicarea);
this.setBackground(Color.GREEN);
widthofgraphicalarea = getWidth();
heightofgraphicalarea = getHeight();
//create paddle 1
graphicarea.setColor(Color.BLUE);
graphicarea.fillRect(paddle1xcoordinate, paddle1ycoordinate, 10, 50);
//create paddle 2
graphicarea.setColor(Color.RED);
graphicarea.fillRect(paddle2xcoordinate, paddle2ycoordinate, 10, 50);
//Give the ball a white color
graphicarea.setColor(Color.WHITE);
//The 3rd and 4th parameters below represent the diameter of the ball.
graphicarea.fillOval(ballxcoordinate,(int)ballycoordinate,2*ballradius,2*ballradius);
}//End of method paintComponent
public void moveplayer1(boolean rightup, boolean rightdown)
{
if(rightup == true)
paddle1ycoordinate -= 5;
else if(rightdown == true)
paddle1ycoordinate += 5;
positionPlayer1(paddle1xcoordinate, paddle1ycoordinate);
}
public void moveplayer2(boolean leftup, boolean leftdown)
{
if(leftup == true)
paddle2ycoordinate -= 5;
else if(leftdown == true)
paddle2ycoordinate += 5;
positionPlayer2(paddle2xcoordinate, paddle2ycoordinate);
}
public void positionPlayer1(int x, int y)
{
this.paddle1xcoordinate = x;
this.paddle1ycoordinate = y;
repaint();
}
public void positionPlayer2(int x, int y)
{
this.paddle2xcoordinate = x;
this.paddle2ycoordinate = y;
repaint();
}
public void moveball(int speed, int delayinterval, double direction, boolean barhit)
{
if(barhit == true)
ballxcoordinate+=1;
else if(barhit == false)
ballxcoordinate-=1;
if(direction > 0)
ballycoordinate = ballycoordinate + (double)Math.sin(Math.toRadians(direction));
else if(direction < 0)
ballycoordinate = ballycoordinate + (double)Math.sin(Math.toRadians(direction));
}
public boolean barhits(boolean barhit)
{
if(ballxcoordinate == paddle1xcoordinate+10 && (ballycoordinate >= paddle1ycoordinate && ballycoordinate <= paddle1ycoordinate+50))
barhit = true;
else if(ballxcoordinate+2*ballradius == paddle2xcoordinate && (ballycoordinate+2*ballradius >= paddle2ycoordinate && ballycoordinate+2*ballradius <= paddle2ycoordinate+50))
barhit = false;
return barhit;
}
public boolean winner()
{
if(ballxcoordinate+2*ballradius >= widthofgraphicalarea)
return true;
else if(ballxcoordinate+2*ballradius <= 16)
return true;
return false;
}
public int playerleftwin(int playerleftscore)
{
if(ballxcoordinate+2*ballradius >= widthofgraphicalarea)
playerleftscore+=1;
return playerleftscore;
}
public int playerrightwin(int playerrightscore)
{
if(ballxcoordinate+2*ballradius <= 16)
playerrightscore+=1;
return playerrightscore;
}
public double changedirection(double direction)
{//function to change the direction of the ball to bounce of walls
if((int)ballycoordinate+2*ballradius >= heightofgraphicalarea || (int)ballycoordinate+2*ballradius < 16)
direction = -direction;
return direction;
}
public void reset()
{//reset the ball at middle of left side
ballxcoordinate = widthofgraphicalarea/2 - ballradius;
ballycoordinate = heightofgraphicalarea/2 - ballradius;
paddle1xcoordinate = 10;
paddle1ycoordinate = heightofgraphicalarea/2-25;
paddle2xcoordinate = widthofgraphicalarea-20;
paddle2ycoordinate = heightofgraphicalarea/2-25;
}
}
Please someone help. Thanks in advance.
Another question if you can help is once this is finished how do I switch this over to applet form?
Do not use a KeyListener Swing components use KeyBindings.
Dont extend JFrame class unnecessarily
Swing components should be created on Event Dispatch Thread
To set the size of your app (without setSize(..) call on JFrame) use appropiate LayoutManager when adding components buttons etc (which you do) and when drawing in paintComponent override JPanel getPreferredSize() and return an appropriate size which fits all drawings than call pack() on JFrame before setting it visible
Dont forget to call setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); on JFrame so when X is pressed the Event Dispatch Thread and Initial thread are exited, or app will remain running in background.
But to solve your problem after paddlehandler = new PaddleHandlerClass(); add:
graphicalpanel.addKeyListener(paddlehandler);
the problem is you never added the KeyListener to any Component to listen for events.
The proper solution would be KeyBindings which would change your PaddleHandlerClass like this:
private class PaddleHandlerClass {
public PaddleHandlerClass(JComponent jc) {
jc.getInputMap(JComponent.WHEN_IN_FOCUSED_WINDOW).put(KeyStroke.getKeyStroke("UP"), "up");
jc.getActionMap().put("up", new AbstractAction() {
#Override
public void actionPerformed(ActionEvent ae) {
rightup = true;
System.out.println("Up");
}
});
jc.getInputMap(JComponent.WHEN_IN_FOCUSED_WINDOW).put(KeyStroke.getKeyStroke("released UP"), "rel up");
jc.getActionMap().put("rel up", new AbstractAction() {
#Override
public void actionPerformed(ActionEvent ae) {
rightup = false;
}
});
}
}
than simply create the paddleHandler and pass instance of JPanel which keys we want to get:
paddlehandler = new PaddleHandlerClass(graphicalpanel);