I'm trying to draw a grid inside the content pane of my JFrame but when I do, everything is off. The grid starts too wide and offset (presumably set where the border of the window overlaps the contentpane) and it doesn't draw the entire grid correctly. When i use frame.setUndecorated(true); everything works perfectly.
import javax.swing.*;
import java.awt.*;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.awt.geom.*;
#SuppressWarnings("serial")
class Creator extends JFrame{
JFrame frame;
int[][] Grid = new int[18][27];
public Creator(){
frame = this;
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
for(int i = 0; i < 18; i++) {
for(int j = 0; j < 27; j++) {
Grid[i][j] = 0;
}
}
setSize(864, 544);
getContentPane().addMouseListener(new MouseAdapter() {
#Override
public void mouseClicked(MouseEvent e) {
int yLocation = e.getX()/32;
int xLocation = e.getY()/32;
System.out.println(xLocation + " " + yLocation);
if(e.getButton() == 1){
if(xLocation < 1 || yLocation < 1){
Grid[xLocation][yLocation] = 2;
System.out.println("Enemy Added");
}else if(xLocation > 16 || yLocation > 25){
Grid[xLocation][yLocation] = 2;
System.out.println("Enemy Added");
}else {
Grid[xLocation][yLocation] = 1;
System.out.println("Obstacle Added");
}
}else {
Grid[xLocation][yLocation] = 0;
System.out.println("Item Removed");
}
frame.invalidate();
frame.validate();
frame.repaint();
}
});
}
public void paint(Graphics g) {
g.clearRect(0, 0, 864, 544);
Graphics2D g2 = (Graphics2D) g;
for(int i =0; i < 18; i++) {
for(int j =0; j < 27; j++) {
if(Grid[i][j] != 0){
if( i < 1 || j < 1 || i > 26 || j > 17) {
g2.setColor(Color.RED);
g2.fillRect(j*32, i*32, 32, 32);
}else {
g2.setColor(Color.BLUE);
g2.fillRect(j*32, i*32, 32, 32);
}
}
//System.out.print(Grid[i][j]);
}
//System.out.println();
}
for(int i = 0; i < 27; i++) {
Line2D lin = new Line2D.Float(i*32, 0, i*32, 544);
g2.draw(lin);
}
for(int i = 0; i < 18; i++) {
Line2D lin = new Line2D.Float(0, i*32, 864, i*32);
g2.draw(lin);
}
}
public static void main(String []args){
Creator s=new Creator();
s.setVisible(true);
}
}
Don't set the size of the frame.
Instead, create a subclass of JPanel or JComponent, override paintComponent() to paint your grid, and override getPreferredSize() to return the size it should have (864 x 544). Add this panel to your frame and call pack() to make sure that the frame size adjusts itself to the size needed to display its component with their preferred size.
EDIT: example:
public class GridPanel extends JPanel {
#Override
public void paintComponent(Graphics g) {
// paint the grid here
}
#Override
public Dimension getPreferredSize() {
return new Dimension(864, 544);
}
}
and in the JFrame constructor:
GridPanel gridPanel = new GridPanel();
this.add(gridPanel);
this.pack();
JB Nizet, gives you the excellent solution. Change your code as follows:
import javax.swing.*;
import java.awt.*;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.awt.geom.*;
#SuppressWarnings("serial")
class Creator extends JPanel{
static int[][] Grid = new int[18][27];
public Creator(){
setSize(getPreferredSize());
}
public void paint(Graphics g) {
g.clearRect(0, 0, getWidth(), getHeight());
Graphics2D g2 = (Graphics2D) g;
for(int i =0; i < 18; i++) {
for(int j =0; j < 27; j++) {
if(Grid[i][j] != 0){
if( i < 1 || j < 1 || i > 26 || j > 17) {
g2.setColor(Color.RED);
g2.fillRect(j*32, i*32, 32, 32);
}else {
g2.setColor(Color.BLUE);
g2.fillRect(j*32, i*32, 32, 32);
}
}
//System.out.print(Grid[i][j]);
}
//System.out.println();
}
for(int i = 0; i < 27; i++) {
Line2D lin = new Line2D.Float(i*32, 0, i*32, getHeight());
g2.draw(lin);
}
for(int i = 0; i < 18; i++) {
Line2D lin = new Line2D.Float(0, i*32, getWidth(), i*32);
g2.draw(lin);
}
}
public static void main(String []args){
JFrame frame=new JFrame();
Creator s=new Creator();
frame.setSize(864, 544);
frame.add(s);
frame.setVisible(true);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.getContentPane().addMouseListener(new MouseAdapter() {
#Override
public void mouseClicked(MouseEvent e) {
int yLocation = e.getX()/32;
int xLocation = e.getY()/32;
System.out.println(xLocation + " " + yLocation);
if(e.getButton() == 1){
if(xLocation < 1 || yLocation < 1){
Grid[xLocation][yLocation] = 2;
System.out.println("Enemy Added");
}else if(xLocation > 16 || yLocation > 25){
Grid[xLocation][yLocation] = 2;
System.out.println("Enemy Added");
}else {
Grid[xLocation][yLocation] = 1;
System.out.println("Obstacle Added");
}
}else {
Grid[xLocation][yLocation] = 0;
System.out.println("Item Removed");
}
// frame.invalidate();
// frame.validate();
// frame.repaint();
}
});
// s.setUndecorated(true);
}
}
Related
I'm trying to implement the game dots and boxes by using 3 JLabel arrays:
the dots for the game board.
the vertical lines
the horizontal lines
the ide is when you click using MouseInputAdapter to get the coordinates of the mouse the it should check if the coordinates of mouse point are in one of the labels of the verticals or horizontal lines. But when I run the program my JPanel is completly empty. And other times when I run it and it's not empty all the labels just vanish after I click.
package gameframes;
import java.awt.event.MouseEvent;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.border.LineBorder;
import javax.swing.event.MouseInputAdapter;
import java.awt.Color;
public class LinesAndBoxesFrame extends JFrame {
JLabel[][] dots = new JLabel[8][8];
JLabel[][] herizontalLines = new JLabel[8][7];
JLabel[][] verticallLines = new JLabel[8][7];
public LinesAndBoxesFrame(String title) {
super(title);
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
setSize(620, 640);
setLocationRelativeTo(null);
setVisible(true);
setLayout(null);
JPanel p=new JPanel();
p.setSize(600,600);
add(p);
for (int i = 0; i < dots.length; i++) {
for (int j = 0; j < dots.length; j++) {
dots[i][j] = new JLabel();
dots[i][j].setBounds(20 + i * (20 + 50), 20 + j * (20 + 50), 20, 20);
dots[i][j].setOpaque(true);
dots[i][j].setBackground(Color.red);
p.add(dots[i][j]);
p.repaint();
}
}
for (int i = 0; i < herizontalLines.length; i++) {
for (int j = 0; j < herizontalLines[0].length; j++) {
herizontalLines[i][j] = new JLabel();
herizontalLines[i][j].setBounds(40 + j * (20 + 50), 20 + i * (20 + 50), 50, 20);
herizontalLines[i][j].setOpaque(true);
herizontalLines[i][j].setBackground(Color.green);
herizontalLines[i][j].setVisible(false);
p.add(herizontalLines[i][j]);
p.repaint();
}
}
for (int i = 0; i < verticallLines.length; i++) {
for (int j = 0; j < verticallLines[0].length; j++) {
verticallLines[i][j] = new JLabel();
verticallLines[i][j].setBounds(20 + i * (20 + 50), 40 + j * (20 + 50), 20, 50);
verticallLines[i][j].setOpaque(true);
verticallLines[i][j].setBackground(Color.green);
verticallLines[i][j].setVisible(false);
p.add(verticallLines[i][j]);
p.repaint();
}
}
p.addMouseListener(new MouseInputAdapter() {
int count = 0;
#Override
public void mouseClicked(MouseEvent e) {
int mX = e.getX();
int mY = e.getY();
System.out.println(mX);
System.out.println(mY);
boolean b = false;
for (JLabel[] l : herizontalLines) {
for (JLabel l1 : l) {
b = checkBounds(l1, mX, mY);
if (b) {
l1.setVisible(true);
break;
}
}
}
if (!b) {
for (JLabel[] l : verticallLines) {
for (JLabel l1 : l) {
b = checkBounds(l1, mX, mY);
if (b) {
l1.setVisible(true);
break;
}
}
}
}
System.out.println(b + " metod finished! " + count);
p.revalidate();
p.repaint();
count++;
}
});
// add(p);
// repaint();
p.revalidate();
p.repaint();
}
public boolean checkBounds(JLabel l, int x, int y) {
return (x >= l.getX() && x <= l.getX() + l.getWidth()) && (y >= l.getY() && y <= l.getY() + l.getHeight());
}
public static void main(String[] args) {
new LinesAndBoxesFrame("Dots and Boxes");
}
}
Update:
I just needed to set the layout of my JPanel to null and that fixes it.
I created a very simple shooting game utilizing JPanel as shown in the code below. I also wanted to experiment with rotating the game and trying it out. I have one issue, where the game I was able to successfully rotate the game but the dimension seems to cut out, and I have to set each position of the enemy and myself to the rotated position.
I was wondering if there was a way to rotate the result as a whole, instead of simply rotating the shape so that the position of the ship and the missiles would also rotate all at once.
Edited code: added three lives to the player and tried implementing heart image with BufferedImage.
public class game extends JFrame{
public game(){
}
public static void main(String[] args){
new game();
}
public class MyJPanel extends JPanel implements ActionListener, MouseListener,
MouseMotionListener,KeyListener
{
//variables for player
int my_x;
int player_width,player_height;
private int lives = 3;
int heart_width, heart_height;
//variables for player's missiles
int my_missile_x, my_missile_y;
int missile_flag;
public static final int MY_Y = 600;
//variables for enemies' missiles
int e_missile_flag[];
int e_missile_x[];
int e_missile_y[];
int e_missile_move[];
Image image,image2;
Timer timer;
private BufferedImage heart;
public MyJPanel(){
missile_flag = 0;
/*** initialize enemies' info ***/
ImageIcon icon2 = new ImageIcon("enemy.jpg");
image2 = icon2.getImage();
enemy_width = image2.getWidth(this);
enemy_height = image2.getHeight(this);
try {
heart = ImageIO.read(getClass().getResource("heart.jpg"));
}catch(IOException e) {
}
heart_width = heart.getWidth(this);
heart_height = heart.getHeight(this);
n = 14; //number of enemies
enemy_x = new int[n];
enemy_y = new int[n];
enemy_move = new int[n];
enemy_alive = new int[n];
int distance = 40;
e_missile_flag = new int[n];
e_missile_x = new int[n];
e_missile_y = new int[n];
e_missile_move = new int[n];
// place enemies in 7x2
for (int i = 0; i < 7; i++) {
enemy_x[i] = (enemy_width + distance) * i + 50;
enemy_y[i] = 50;
}
for (int i = 7; i < n; i++) {
enemy_x[i] = (enemy_width + distance) * (i - 5) + 50;
enemy_y[i] = 100;
}
for (int i = 0; i < n; i++) {
enemy_alive[i] = 1; //all alive
enemy_move[i] = -10; //moves to left
}
for (int i = 0; i < n; i++) {
e_missile_flag[i] = 0;
e_missile_x[i] = 0;
e_missile_y[i] = 0;
e_missile_move[i] = 7 + n%3;
}
/*** setup system ***/
setBackground(Color.black);
setFocusable(true);
addMouseListener(this);
addMouseMotionListener(this);
addKeyListener(this);
timer = new Timer(50, this);
timer.start();
}
private void updateEnemiesPosition(){
//update enemies' position
Dimension dim = getSize();
for (int i = 0; i < n; i++) {
enemy_x[i] += enemy_move[i];
if ((enemy_x[i] < 0) || (enemy_x[i] > (dim.width - enemy_width))) {
enemy_move[i] = -enemy_move[i];
}
}
}
private void updateMyPosition() {
if(my_x < 0) {
my_x = 800;
}
if(my_x > 800) {
my_x = 0;
}
}
private void activateMyMissile(){
//shoot a missile
if(missile_flag == 0){
my_missile_x = my_x + player_width / 2;
my_missile_y = MY_Y; //MY_Y=400
missile_flag = 1;
}
}
private void updateMyMissile(){
//update missile position if alive
if (missile_flag == 1) {
my_missile_y -= 15;
if (0 > my_missile_y) {
missile_flag = 0;
}
}
}
private void activateEnemiesMissile(){
//activate enemies' missile if enemy is alive and its missile is not alive
for(int i = 0; i < n; i++){
if (enemy_alive[i] == 1 && e_missile_flag[i] == 0) {
e_missile_x[i] = enemy_x[i] + enemy_width/2;
e_missile_y[i] = enemy_y[i];
e_missile_flag[i] = 1;
}
}
}
private void updateEnemiesMissile(){
//update enemies' missile position if alive
Dimension dim = getSize();
for(int i = 0; i < n; i++){
if (e_missile_flag[i] == 1) {
e_missile_y[i] += e_missile_move[i];
if (e_missile_y[i] > dim.height) {
e_missile_flag[i] = 0;
}
}
}
}
private void checkHitToEnemy(){
for(int i = 0; i < n; i++){
if(missile_flag == 1 && enemy_alive[i] == 1){
if(
my_missile_x > enemy_x[i] &&
my_missile_x < (enemy_x[i] + enemy_width) &&
my_missile_y > enemy_y[i] &&
my_missile_y < (enemy_y[i] + enemy_height)
){
//hit
missile_flag = 0;
enemy_alive[i] = 0;
}
}
}
}
private boolean checkClear(){
int cnt = 0;
for(int i = 0; i < n; i++){
if(enemy_alive[i] == 0) cnt++;
}
return (n == cnt);
}
if(lives>0) {
int x = 0;
int y = getHeight()- heart.getHeight();
for(int index = 0; index < lives; index++) {
g.drawImage(heart, x, y, this);
x += heart.getWidth();
}
}
g2d.dispose();
}
public void actionPerformed(ActionEvent e){
if (e.getSource() == timer) {
updateEnemiesPosition();
updateMyPosition();
updateMyMissile();
updateEnemiesMissile();
activateEnemiesMissile();
if(checkHitToPlayer()){
System.out.println("===== Game Over =====");
System.exit(0);
}
checkHitToEnemy();
if(checkClear()){
System.out.println("===== Game Clear =====");
System.exit(0);
}
repaint();
}
}
public void mouseClicked(MouseEvent me)
{ }
public void mousePressed(MouseEvent me)
{
activateMyMissile();
}
public void mouseReleased(MouseEvent me)
{ }
public void mouseExited(MouseEvent me)
{ }
public void mouseEntered(MouseEvent me)
{ }
public void mouseMoved(MouseEvent me)
{ }
public void mouseDragged(MouseEvent me)
{ }
public void keyReleased(KeyEvent e){
}
public void keyTyped(KeyEvent e){
}
}
}
The original size of the component is going to be less then 800x500 (I say less then, because the actual size will be 800x500 - the frame decorations - this is why you should be setting the size of the window directly).
When you rotate it 90 degrees, it becomes (less then) 500x800. So, no, there's no "easy" way to resolve this, without making the game square.
I added...
g2d.setColor(Color.DARK_GRAY);
g2d.fillRect(0, 0, getWidth(), getHeight());
after the rotation, which highlights the issue.
To do this, you should override getPreferredSize of the JPanel and the call pack on the frame. This will ensure that that game canvas is sized to it's preferred size and the window decorations are then packed around it.
import java.awt.Color;
import java.awt.Container;
import java.awt.Dimension;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.Image;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.KeyEvent;
import java.awt.event.KeyListener;
import java.awt.event.MouseEvent;
import java.awt.event.MouseListener;
import java.awt.event.MouseMotionListener;
import javax.swing.ImageIcon;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.Timer;
public class Lec12 extends JFrame {
public Lec12() {
setTitle("Game Example");
setDefaultCloseOperation(EXIT_ON_CLOSE);
MyJPanel myJPanel = new MyJPanel();
Container c = getContentPane();
c.add(myJPanel);
pack();
setVisible(true);
}
public static void main(String[] args) {
new Lec12();
}
public class MyJPanel extends JPanel implements ActionListener, MouseListener,
MouseMotionListener, KeyListener {
//variables for player
int my_x;
int player_width, player_height;
//variables for enemies
int enemy_width, enemy_height;
int n;
int enemy_x[];
int enemy_y[];
int enemy_move[];
int enemy_alive[];
//variables for player's missiles
int my_missile_x, my_missile_y;
int missile_flag;
public static final int MY_Y = 400;
//variables for enemies' missiles
int e_missile_flag[];
int e_missile_x[];
int e_missile_y[];
int e_missile_move[];
Image image, image2;
Timer timer;
public MyJPanel() {
/**
* * initialize player's info **
*/
my_x = 250;
ImageIcon icon = new ImageIcon("player.jpg");
image = icon.getImage();
player_width = image.getWidth(this);
player_height = image.getHeight(this);
missile_flag = 0;
/**
* * initialize enemies' info **
*/
ImageIcon icon2 = new ImageIcon("enemy.jpg");
image2 = icon2.getImage();
enemy_width = image2.getWidth(this);
enemy_height = image2.getHeight(this);
n = 14; //number of enemies
enemy_x = new int[n];
enemy_y = new int[n];
enemy_move = new int[n];
enemy_alive = new int[n];
int distance = 40;
e_missile_flag = new int[n];
e_missile_x = new int[n];
e_missile_y = new int[n];
e_missile_move = new int[n];
// place enemies in 7x2
for (int i = 0; i < 7; i++) {
enemy_x[i] = (enemy_width + distance) * i + 50;
enemy_y[i] = 50;
}
for (int i = 7; i < n; i++) {
enemy_x[i] = (enemy_width + distance) * (i - 5) + 50;
enemy_y[i] = 100;
}
for (int i = 0; i < n; i++) {
enemy_alive[i] = 1; //all alive
enemy_move[i] = -10; //moves to left
}
for (int i = 0; i < n; i++) {
e_missile_flag[i] = 0;
e_missile_x[i] = 0;
e_missile_y[i] = 0;
e_missile_move[i] = 7 + n % 3;
}
/**
* * setup system **
*/
setBackground(Color.black);
setFocusable(true);
addMouseListener(this);
addMouseMotionListener(this);
addKeyListener(this);
timer = new Timer(50, this);
timer.start();
}
#Override
public Dimension getPreferredSize() {
return new Dimension(800, 800);
}
private void updateEnemiesPosition() {
//update enemies' position
Dimension dim = getSize();
for (int i = 0; i < n; i++) {
enemy_x[i] += enemy_move[i];
if ((enemy_x[i] < 0) || (enemy_x[i] > (dim.width - enemy_width))) {
enemy_move[i] = -enemy_move[i];
}
}
}
private void updateMyPosition() {
if (my_x < 0) {
my_x = 800;
}
if (my_x > 800) {
my_x = 0;
}
}
private void activateMyMissile() {
//shoot a missile
if (missile_flag == 0) {
my_missile_x = my_x + player_width / 2;
my_missile_y = MY_Y; //MY_Y=400
missile_flag = 1;
}
}
private void updateMyMissile() {
//update missile position if alive
if (missile_flag == 1) {
my_missile_y -= 15;
if (0 > my_missile_y) {
missile_flag = 0;
}
}
}
private void activateEnemiesMissile() {
//activate enemies' missile if enemy is alive and its missile is not alive
for (int i = 0; i < n; i++) {
if (enemy_alive[i] == 1 && e_missile_flag[i] == 0) {
e_missile_x[i] = enemy_x[i] + enemy_width / 2;
e_missile_y[i] = enemy_y[i];
e_missile_flag[i] = 1;
}
}
}
private void updateEnemiesMissile() {
//update enemies' missile position if alive
Dimension dim = getSize();
for (int i = 0; i < n; i++) {
if (e_missile_flag[i] == 1) {
e_missile_y[i] += e_missile_move[i];
if (e_missile_y[i] > dim.height) {
e_missile_flag[i] = 0;
}
}
}
}
private void checkHitToEnemy() {
for (int i = 0; i < n; i++) {
if (missile_flag == 1 && enemy_alive[i] == 1) {
if (my_missile_x > enemy_x[i]
&& my_missile_x < (enemy_x[i] + enemy_width)
&& my_missile_y > enemy_y[i]
&& my_missile_y < (enemy_y[i] + enemy_height)) {
//hit
missile_flag = 0;
enemy_alive[i] = 0;
}
}
}
}
private boolean checkHitToPlayer() {
for (int i = 0; i < n; i++) {
if (e_missile_flag[i] == 1) {
if (e_missile_x[i] > my_x
&& e_missile_x[i] < (my_x + player_width)
&& e_missile_y[i] > MY_Y
&& e_missile_y[i] < (MY_Y + player_height)) {
e_missile_flag[i] = 0;
return true;
}
}
}
return false;
}
private boolean checkClear() {
int cnt = 0;
for (int i = 0; i < n; i++) {
if (enemy_alive[i] == 0) {
cnt++;
}
}
return (n == cnt);
}
public void paintComponent(Graphics g) {
super.paintComponent(g); //reset graphics
Graphics2D g2d = (Graphics2D) g.create();
System.out.println(getWidth() + "x" + getHeight());
int w2 = getWidth() / 2;
int h2 = getHeight() / 2;
g2d.rotate(-Math.PI / 2, w2, h2);
g2d.setColor(Color.DARK_GRAY);
g2d.fillRect(0, 0, getWidth(), getHeight());
//draw player
g2d.setColor(Color.BLUE);
g2d.fillRect(my_x, 400, 10, 10);
// g.drawImage(image, my_x, 400, this);
//draw enemies
for (int i = 0; i < n; i++) {
if (enemy_alive[i] == 1) {
g2d.setColor(Color.RED);
g2d.fillRect(enemy_x[i], enemy_y[i], 10, 10);
// g.drawImage(image2, enemy_x[i], enemy_y[i], this);
}
}
//draw players missiles
if (missile_flag == 1) {
g2d.setColor(Color.white);
g2d.fillRect(my_missile_x, my_missile_y, 2, 5);
}
//draw enemies' missiles
for (int i = 0; i < n; i++) {
if (e_missile_flag[i] == 1) {
g2d.setColor(Color.white);
g2d.fillRect(e_missile_x[i], e_missile_y[i], 2, 5);
}
}
g2d.dispose();
}
public void actionPerformed(ActionEvent e) {
if (e.getSource() == timer) {
updateEnemiesPosition();
updateMyPosition();
updateMyMissile();
updateEnemiesMissile();
activateEnemiesMissile();
if (checkHitToPlayer()) {
System.out.println("===== Game Over =====");
System.exit(0);
}
checkHitToEnemy();
if (checkClear()) {
System.out.println("===== Game Clear =====");
System.exit(0);
}
repaint();
}
}
public void mouseClicked(MouseEvent me) {
}
public void mousePressed(MouseEvent me) {
activateMyMissile();
}
public void mouseReleased(MouseEvent me) {
}
public void mouseExited(MouseEvent me) {
}
public void mouseEntered(MouseEvent me) {
}
public void mouseMoved(MouseEvent me) {
}
public void mouseDragged(MouseEvent me) {
}
public void keyPressed(KeyEvent e) {
int key = e.getKeyCode();
switch (key) {
case KeyEvent.VK_S:
my_x = my_x + 10;
break;
case KeyEvent.VK_W:
my_x = my_x - 10;
break;
case KeyEvent.VK_DOWN:
my_x = my_x + 10;
break;
case KeyEvent.VK_UP:
my_x = my_x - 10;
break;
case KeyEvent.VK_X:
if (missile_flag == 0) {
my_missile_x = my_x + player_width / 2;
my_missile_y = MY_Y;// MY_Y=400
missile_flag = 1;
}
break;
}
}
public void keyReleased(KeyEvent e) {
}
public void keyTyped(KeyEvent e) {
}
}
}
Also, beware, transformations of this nature are accumulative. You should, instead, take a snapshot of the Graphics context and dispose of it once you're done (see the above for an example).
Also, have look at How to Use Key Bindings as it will help resolve the focus issues related to KeyListener
I am currently making an applet that simulates a Tortoise vs. Hare Race. They each have individual moves, picked at random. My applet works, but it only displays the end of the race in which the Tortoise Wins. I would like it to display the individual moves that the tortoise/hare make, almost like a gif.
heres my code:
import java.applet.Applet;
import java.awt.Graphics;
import java.awt.Image;
import java.awt.Color;
import java.awt.Font;
public class Project2 extends Applet
{
Image tortoise, hare;
int tortoiseXPos = 180, hareXPos = 180;
final int tortoiseYPos = 50, hareYPos = 400, SQUARE = 20;
int move;
public void init()
{
tortoise = getImage(getDocumentBase(), "tortoise.gif");
hare = getImage(getDocumentBase(), "hare.gif");
}
public void gameControl()
{
//1200 is finish line
while((tortoiseXPos < 1200) || (hareXPos < 1200))
{
move = (int)(Math.random() * 10);
tortoiseMoves(move);
hareMoves(move);
for(int i = 0; i < 10; i++)
{
delay();
}
}
}
public void paint(Graphics field)
{
drawField(field);
drawMove(field);
//Display winner when they get to the finish line
if(tortoiseXPos >= 1200)
{
field.setFont(new Font("Times New Roman", Font.ITALIC, 72));
field.drawString("Tortoise Wins", 650, 240);
}
else if(hareXPos >= 1200)
{
field.setFont(new Font("Times New Roman", Font.ITALIC, 72));
field.drawString("Tortoise Wins!!", 650, 240);
}
}
public void drawField(Graphics field)
{
setBackground(Color.green);
Font f = new Font("Times New Roman", Font.BOLD, 48);
field.setFont(f);
field.drawString("Tortoise", 0, 75);
field.drawString("Hare", 0, 425);
//fill alternating black and white rectangles
field.setColor(Color.black);
int x = 180;
for(int i = 0; i < 25; i++)
{
field.fillRect(x, 50, SQUARE, 50);
field.fillRect(x, 400, SQUARE, 50);
x += (SQUARE * 2);
}
field.setColor(Color.white);
x = 200;
for(int i = 0; i < 25; i++)
{
field.fillRect(x, 50, SQUARE, 50);
field.fillRect(x, 400, SQUARE, 50);
x += (SQUARE * 2);
}
}
public void clearMove(Graphics s)
{
}
public void drawMove(Graphics s)
{
gameControl();
s.drawImage(tortoise, tortoiseXPos, 50, this);
s.drawImage(hare, hareXPos, 400, this);
}
public void tortoiseMoves(int move)
{
//Moves for Tortoise
if(move <= 5)
{
tortoiseXPos += (3 * SQUARE);
}
else if(move <= 8)
{
tortoiseXPos += SQUARE;
}
else if(move <= 10)
{
tortoiseXPos -= (6 * SQUARE);
}
if(tortoiseXPos < 0)
{
tortoiseXPos = 0;
}
if(tortoiseXPos > 1200)
{
tortoiseXPos = 1200;
}
}
public void hareMoves(int move)
{
//Moves for Hare
if(move <= 2)
{
hareXPos += (9 * SQUARE);
}
if(move <= 5)
{
hareXPos += (SQUARE);
}
if(move <= 6)
{
hareXPos -= (SQUARE);
}
if(move <= 8)
{
hareXPos -= (2 * SQUARE);
}
if(move <= 10)
{
hareXPos = hareXPos;
}
if(hareXPos < 0)
{
hareXPos = 0;
}
if(hareXPos > 1200)
{
hareXPos = 1200;
}
}
public void delay()
{
//To see individual moves
for(int i = 0; i <= 90000000; i++)
{}
}
}
If you guys could give me some pointers on what method to use or how I should go about doing this, I'd appreciate it. Thanks
Add two arrays to your class and store each move for each racer. Then, "paint" the points for each racer on the screen as the race is progressing.
Okay, in my class we're working on a project where we have to double every number in a program. We're doing this in order to scale an animation that we made for class. Here's my class scaling class:
import java.util.Scanner;
import java.io.*;
public class DoubleEmRight
{
public static void main(String[]args) throws Exception
{
File file = new File(args[0]);
Scanner kb = new Scanner(file);
FileWriter input = new FileWriter("HolidayGraphics2.java");
PrintWriter output = new PrintWriter(input);
String s;
do
{
int xn = 0;
int countnum = 0;
int xl = 0;
int countlet = 0;
boolean hasNum = false;
boolean mult = false;
s = kb.nextLine();
String[]spLet = s.split("\\D"); //array w/ nums
String[]spNum = s.split("\\d"); //array w/ letters
String[]blklst = {"try", "for", "Color", "if", "waves.addPoint(x"};
for (int i = 0; i < spLet.length; i++)
{
if (spLet[i].length() >=1)
{
countnum++;
}
}
String[]spLetNoSpc = new String[countnum];
for (int i = 0; i < spLet.length; i++)
{
if (spLet[i].length() >=1)
{
spLetNoSpc[xn] = spLet[i];
xn++;
}
}
for (int i = 0; i < spNum.length; i++)
{
if (spNum[i].length() >=1)
{
countlet++;
}
}
String[]spNumNoSpc = new String[countlet];
for (int i = 0; i < spNum.length; i++)
{
if (spNum[i].length() >=1)
{
spNumNoSpc[xl] = spNum[i];
}
}
search:
for (int x = 0; x < spLetNoSpc.length ; x++)
{
find:
for (int j = 0; j < blklst.length; j++)
{
if (s.contains(blklst[j]))
{
mult = true;
break find;
}
}
if (!(s.matches(".*[0-9].*")))
{
output.print(s);
break search;
}
else if (s.length() == 0)
{
output.print(s);
break search;
}
else if (s.matches("for (int x = 0; x < 500; x++)"))
{
output.print(spNumNoSpc[x] + (Integer.parseInt(spLetNoSpc[x])) * Integer.parseInt(args[1]));
if ((x == spLetNoSpc.length - 1)&&(spNumNoSpc.length > spLetNoSpc.length))
{
output.println(spNumNoSpc[x+1]);
}
break search;
}
else if (mult)
{
output.print(s);
break search;
}
else
{
output.print(spNumNoSpc[x] + (Integer.parseInt(spLetNoSpc[x])) * Integer.parseInt(args[1]));
if ((x == spLetNoSpc.length - 1)&&(spNumNoSpc.length > spLetNoSpc.length))
{
output.println(spNumNoSpc[x+1]);
}
}
}
output.println();
}while(kb.hasNextLine());
output.close();
input.close();
}
}
This doubles all of the numbers in my animation's java file and prints it in a new file, HolidayGraphics2.java. Unfortunately, it doesn't print lines like this:
import javax.swing.*;
But prints lines like this:
win.setSize(500,650);
Nor does it print any of my brackets.
These lines are supposed to print the original line from my animation program if the line does not contain a digit:
if (!(s.matches(".*[0-9].*")))
{
output.print(s);
break search;
}
Can anyone tell me why the lines that don't contain digits are not printing? Here's the code for animation, just in case you need it
import javax.swing.*;
import java.awt.*;
import javax.swing.ImageIcon;
//import java.awt.Graphics2D;
public class HolidayGraphics
{
public static void main (String[] args)
{
JFrame win;
Container contentPane;
Graphics g;
Panel controlPanel;
win = new JFrame("Holiday Graphics");
win.setSize(500,650);
win.setLocation(100,100);
win.setVisible(true);
contentPane = win.getContentPane(); // activates graphics in window
g = contentPane.getGraphics();
try {Thread.sleep(400);} catch (Exception e) {}
for(int w = 0; w < 10000; w++)
{
g.setColor(new Color(231,252,252)); //sky
g.fillRect(0,0,500,650);
g.setColor(Color.YELLOW); //sun
g.fillOval(20,20,80,80);
g.drawLine(60,110,60,145);
g.drawLine(40,90,5,125);
g.drawLine(80,90,115,125);
g.drawLine(80,30,115,0);
g.drawLine(110,60,145,60);
g.setColor(new Color(255,255,255)); //ice
g.fillRect(300,170,200,50);
Polygon waves = new Polygon(); //waves
for (int x = 0; x < 500; x++)
{
waves.addPoint(x, 180 + (int)Math.sin(x*((Math.PI)/2))*3);
}
waves.addPoint(500, 650);
waves.addPoint(0, 650);
g.setColor(new Color(67,129,243));
g.fillPolygon(waves);
g.setColor(new Color(67,129,243)); //water
g.fillRect(0,190,500,700);
g.setColor(new Color(255,255,255)); //ice over water
g.fillRect(300,170,200,30);
for (int i = 0; i < 21; i = i+2)
{
g.setColor(Color.WHITE);
g.fillRect(340,174 - i*6,10,6);
}
g.setColor(Color.RED);
g.fillRect(340,168,10,6);
g.setColor(Color.RED);
g.fillRect(340,156,10,6);
g.setColor(Color.RED);
g.fillRect(340,144,10,6);
g.setColor(Color.RED);
g.fillRect(340,132,10,6);
g.setColor(Color.RED);
g.fillRect(340,120,10,6);
g.setColor(Color.RED);
g.fillRect(340,108,10,6);
g.setColor(Color.RED);
g.fillRect(340,96,10,6);
g.setColor(Color.RED);
g.fillRect(340,84,10,6);
g.setColor(Color.RED);
g.fillRect(340,72,10,6);
g.setColor(Color.RED);
g.fillRect(340,60,10,6);
g.setColor(Color.WHITE); //sign
g.fillOval(305,24,80,30);
g.setColor(Color.RED);
g.drawOval(305,24,80,30);
g.setColor(Color.RED);
g.drawString("North Pole",313,43);
g.setColor(Color.ORANGE); //penguin
g.fillOval(400,178,20,10);
g.fillOval(425,178,20,10);
g.setColor(Color.BLACK);
g.fillOval(388,82,70,100);
g.fillOval(385,132,15,30);
g.fillOval(446,132,15,30);
g.setColor(Color.WHITE);
g.fillOval(400,102,25,25);
g.fillOval(421,102,25,25);
g.fillOval(398,123,50,55);
g.setColor(Color.BLACK);
g.fillOval(410,110,6,6);//eye
g.fillOval(430,110,6,6);//eye
g.drawLine(406,110,415,105);//eyebrow
g.drawLine(439,110,430,105);//eyebrow
g.setColor(Color.ORANGE);
g.fillOval(400,178,20,10);
g.fillOval(425,178,20,10);
Polygon nose = new Polygon();
nose.addPoint(415,118);
nose.addPoint(431,118);
nose.addPoint(423,126);
g.fillPolygon(nose);
g.setColor(new Color(255,122,119)); //house
g.fillRect(150,450,200,100);
g.setColor(Color.BLACK);
g.drawString("Santa's Workshop", 190, 470);
for (int i = 0; i < 7; i=i+2)
{
g.setColor(Color.RED);
g.fillRect(150,480 + 10*i,10,10);
}
for (int i = 1; i < 6; i=i+2)
{
g.setColor(Color.WHITE);
g.fillRect(150,480 + 10*i,10,10);
}
for (int i = 0; i < 7; i=i+2)
{
g.setColor(Color.RED);
g.fillRect(340,480 + 10*i,10,10);
}
for (int i = 1; i < 6; i=i+2)
{
g.setColor(Color.WHITE);
g.fillRect(340,480 + 10*i,10,10);
}
g.setColor(new Color(124,29,5)); //chimney
g.fillRect(170,400,10,50);
g.setColor(new Color(130,62,0)); //roof
Polygon tri1 = new Polygon();
tri1.addPoint(150,450);
tri1.addPoint(250,390);
tri1.addPoint(350,450);
g.fillPolygon(tri1);
for (int i = 0; i < 390; i++)
{
g.setColor(Color.ORANGE);
g.fillOval(70+i,350,40,20); //fish 1
Polygon fishtri1 = new Polygon();
fishtri1.addPoint(70+i,350);
fishtri1.addPoint(70+i,370);
fishtri1.addPoint(87+i,360);
g.fillPolygon(fishtri1);
g.fillOval(70+i,220,40,20); //fish 2
Polygon fishtri2 = new Polygon();
fishtri2.addPoint(70+i,220);
fishtri2.addPoint(70+i,240);
fishtri2.addPoint(87+i,230);
g.fillPolygon(fishtri2);
g.fillOval(430 - i,285,40,20); //fish 3
Polygon fishtri3 = new Polygon();
fishtri3.addPoint(470-i,285);
fishtri3.addPoint(470-i,305);
fishtri3.addPoint(453-i,295);
g.fillPolygon(fishtri3);
try {Thread.sleep(10);} catch (Exception e) {}
if (!(i==389))
{
g.setColor(new Color(67,129,243));
g.fillOval(70+i,350,40,20);
g.fillPolygon(fishtri1);
g.fillOval(70+i,220,40,20);
g.fillPolygon(fishtri2);
g.fillOval(430 - i,285,40,20);
g.fillPolygon(fishtri3);
}
}
for (int i = 0; i < 7; i++) //bubbles
{
g.setColor(Color.BLUE);
g.drawOval(167 - i*15, 380-i*30, 10 + i*i, 10 + i*i);
try {Thread.sleep(200*i);} catch (Exception e) {}
}
}
}
}
I am creating simple game in java. Here is my code. This is my GUI class:
public class GUI extends JFrame implements ActionListener{
JButton upbutton, downbutton, leftbutton, rightbutton;
Game game;
Player player;
Board b;
Maze maze;
Player pl;
public GUI () {
b= new Board();
Game game = new Game(b);
setSize(800,600);
Container cp = getContentPane();
upbutton = new JButton("UP");
downbutton = new JButton("DOWN");
leftbutton = new JButton("LEFT");
rightbutton= new JButton("RIGHT");
upbutton.addActionListener(this);
downbutton.addActionListener(this);
leftbutton.addActionListener(this);
rightbutton.addActionListener(this);
JPanel p = new JPanel();
BoxLayout boxLayout1 = new BoxLayout(p, BoxLayout.Y_AXIS);
p.setBorder(BorderFactory.createEmptyBorder(250, 0, 250, 0));
p.setLayout(boxLayout1);
JPanel panel_1 = new JPanel();
p.add(panel_1, BorderLayout.NORTH);
JPanel panel_2 = new JPanel();
p.add(panel_2);
JPanel panel_3 = new JPanel();
p.add(panel_3, BorderLayout.AFTER_LAST_LINE);
panel_1.add(upbutton);
panel_2.add(leftbutton);
panel_2.add(rightbutton);
panel_3.add(downbutton);
cp.setLayout(new BorderLayout());
cp.add(p, BorderLayout.EAST);
game= new Game(b);
cp.add(game, BorderLayout.CENTER);
}
public void actionPerformed(ActionEvent e) {
if(upbutton == e.getSource()){
game.movePlayerUp();
System.out.println("up");
}
if(downbutton == e.getSource()){
game.movePlayerDown();
System.out.println("down");
repaint();
}
if(leftbutton == e.getSource()){
game.movePlayerLeft();
repaint();
System.out.println("left");
}
if(rightbutton == e.getSource()){
game.movePlayerRight();
repaint();
System.out.println("right");
}
game.repaint();
}
public static void main(String[] args) {
GUI frame = new GUI();
frame.setVisible(true);
}
}
This is my Game class:
public class Game extends Canvas {
int m;
int n; // the margin
Board b;
double tokenSize, markingSize;
int[][] marking;
int pickupType;
int pickupX, pickupY;
Dimension lastSize;
Image picture;
Maze maze;
Player player;
boolean ingame = false;
boolean dying = false;
boolean finished = false;
Thread gamethread = null;
int pposition [][];
public int positiona;
public int positionb;
public final Font smallfont = new Font("Helvetica", Font.BOLD, 14);
public Game (Board db) {
pposition = new int[4][4];
maze = new Maze();
b=db;
m=20;
setBackground(Color.lightGray);
lastSize=getSize();
picture=createImage(lastSize.width, lastSize.height);
createPlayerBoard();
setInitialPlayerPosition();
}
public void paint (Graphics g){
update(g);
}
public synchronized void update(Graphics g1) {
Dimension d=getSize();
if (!d.equals(lastSize)) {
picture=createImage(d.width, d.height);
}
Graphics g=picture.getGraphics();
g.setColor(getBackground());
g.fillRect(0, 0, d.width, d.height);
g.setColor(getForeground());
g.drawRect(0, 0, d.width-1, d.height-1);
int h=getHeight();
int w=getWidth();
int squareSize = Math.max(0,(Math.min(h,w)-2*m))/8;
squareSize = squareSize+40;
Graphics2D g2 = (Graphics2D) g;
Image img1 = Toolkit.getDefaultToolkit().getImage("3down.jpg");
Image img2 = Toolkit.getDefaultToolkit().getImage("3left.jpg");
Image img3 = Toolkit.getDefaultToolkit().getImage("3right.jpg");
Image img4 = Toolkit.getDefaultToolkit().getImage("3up.jpg");
Image img5 = Toolkit.getDefaultToolkit().getImage("all4.jpg");
Image img6 = Toolkit.getDefaultToolkit().getImage("down_left.jpg");
Image img7 = Toolkit.getDefaultToolkit().getImage("down_right.jpg");
Image img8 = Toolkit.getDefaultToolkit().getImage("up_left.jpg");
Image img9 = Toolkit.getDefaultToolkit().getImage("up_right.jpg");
Image img10 = Toolkit.getDefaultToolkit().getImage("cyclops.gif");
//this code displays board
for (int i=0; i<5; i++) {
for (int j=0; j<5; j++) {
if(i==0&&j==0){
g2.drawImage(img7,m + i * squareSize, m + j * squareSize, squareSize, squareSize, this);
g2.finalize();}
else if(i==1&&j==0){
g2.drawImage(img1,m + i * squareSize, m + j * squareSize, squareSize, squareSize, this);
g2.finalize();}
else if (i==2&&j==0){
g2.drawImage(img1,m + i * squareSize, m + j * squareSize, squareSize, squareSize, this);
g2.finalize();}
else if (i==3&&j==0){
g2.drawImage(img1,m + i * squareSize, m + j * squareSize, squareSize, squareSize, this);
g2.finalize();}
else if (i==4 &&j==0){
g2.drawImage(img6,m + i * squareSize, m + j * squareSize, squareSize, squareSize, this);
g2.finalize();}
}
//this code will display the cyclop
loadPlayerPosition();
int x=positiona;
int y=positionb;
g2.drawImage(img10,m + x * squareSize, m + y * squareSize, squareSize, squareSize, this);
g2.finalize();
g1.drawImage(picture,0,0,null);
}
//this method creates player board and fills all places in array with 0
public void createPlayerBoard(){
for (int i = 0; i < pposition.length; i++){
for (int j = 0; j < pposition.length; j++){
pposition[i][j] = 0;
}
}
}
//this method sets the initial player position in array
public void setInitialPlayerPosition(){
pposition[0][0] = 1;
}
//this method changes the interger positiona and positib be, so integers represent the current player position
public void loadPlayerPosition(){
for (int i = 0; i < pposition.length; i++){
for (int j = 0; j < pposition.length; j++){
if(pposition [i][j] == 1){
positiona=i;
positionb=j;
}
}
}
}
//these methods change the number in player array from 0 to 1, deppending on which button player clicked
public void movePlayerUp(){
for (int i = 0; i < pposition.length; i++){
for (int j = 0; j < pposition.length; j++){
if(pposition [i][j] == 1){
pposition [i][j] = 0;
pposition [i][j+1] = 1;
}
}
}
}
public void movePlayerDown(){
for (int i = 0; i < pposition.length; i++){
for (int j = 0; j < pposition.length; j++){
if(pposition [i][j] == 1){
pposition [i][j] = 0;
pposition [i][j-1] = 1;
}
}
}
}
public void movePlayerLeft(){
for (int i = 0; i < pposition.length; i++){
for (int j = 0; j < pposition.length; j++){
if(pposition [i][j] == 1){
pposition [i][j] = 0;
pposition [i-1][j] = 1;
}
}
}
}
public void movePlayerRight(){
for (int i = 0; i < pposition.length; i++){
for (int j = 0; j < pposition.length; j++){
if(pposition [i][j] == 1){
pposition [i][j] = 0;
pposition [i+1][j] = 1;
}
}
}
}
}
This is my board class:
public class Board {
int[][] b;
Maze maze;
boolean alive = true;
public int playerscore = 0;
Maze m;
public Board() {
}
}
The program normally creates the windows with buttons, displays the board and displays the player icon. What I want to do is:
when player clicks on right button, the icon moves right on the array. When I click on the button, I get this error:
Exception in thread "AWT-EventQueue-0" java.lang.NullPointerException
I try to search the error and it says this happens when the program points to object which is null.However, I think my object is not null. Can somebody give me advice please? Thank you very much