I have an applet for a small game me and a friend are working on for our computer science class. We are attempting to make a menu that opens at the start of the applet, then after 1 second displays a class selection screen. However, after the one second, the screen just turns white, but outputs the print statement assigned to signal the class selection screen has loaded, I am unsure of why this is happening and would like to solve this.
I have tried putting the code to show the class selection screen in another thread so nothing else will be holding it back when it runs, however, this has changed nothing. I have also made sure the conditions to show the screen are true, and to show it every .2 seconds, yet nothing seems to work. I tried to make the code run in the constructor for the character, and it is supposed to run once, it runs once, but the problem with it running once is that it immediately exits the menu and goes to the next phase of the game for no reason.
import java.awt.*;
import java.applet.*;
import java.awt.event.KeyListener;
import java.awt.event.KeyEvent;
import java.awt.event.*;
import java.io.*;
import javax.swing.*;
import java.util.*;
public class FinalProjectTest extends Applet implements KeyListener, Runnable, MouseListener
{
int xCoord = 50;
int yCoord = 600;
int moveScale = 20;
int xSize = 20;
int ySize = 20;
int leftWall = 0;
int rightWall = 1000;
int topWall = 0;
int bottomWall = 650;
public volatile Graphics graphics;
boolean isInMenu = false;
boolean firstRun = true;
boolean drawMap = true;
int hostileAmount = 1000;
Character P1;
#Override
public void init()
{
addKeyListener(this);
addMouseListener( this );
}
public void Looper(Graphics g)
{
drawPlayer(g);
// Enemy 1
HostileObject enemy = new HostileObject(100, 250);
enemy.CreateHostile(g);
}
public void paint(Graphics g)
{
if (firstRun)
{
firstRun = false;
isInMenu = true;
System.out.println("Character Created");
P1 = new Character(g);
}
if (!isInMenu && !firstRun)
{
System.out.println("Game has begun!");
Map1 firstMap = new Map1(g);
Looper(g);
}
}
public void drawPlayer(Graphics g)
{
g.setColor(Util.black);
g.fillRect(xCoord - xSize, yCoord - ySize, xSize, ySize);
}
public void MovePlayer(int x, int y)
{
if (CheckPosition(xCoord + x, yCoord + y))
{
xCoord += x;
yCoord += y;
}
}
public boolean CheckPosition(int x, int y)
{
if (WallCheck1(x,y) && WallCheck2(x,y) && CheckBorders(x, y))
{
return true;
}
else
return false;
}
public boolean CheckBorders(int x, int y)
{
if (y + ySize <= bottomWall && y - ySize >= topWall && x - xSize >= leftWall && x + xSize <= rightWall)
{
return true;
}
else
return false;
}
public boolean WallCheck1(int x, int y)
{
if ((y - ySize >= Map1.wall1y1 || y + ySize <= Map1.wall1y2 + 20) || x - xSize >= Map1.wall1x2)
{
return true;
}
else
return false;
}
public boolean WallCheck2(int x, int y)
{
if ((y - ySize >= Map1.wall2y1 || y + ySize <= Map1.wall2y2 + 20) || x - xSize <= Map1.wall2x2)
{
return true;
}
else
return false;
}
boolean keyIsHeld;
char moveChar;
public void keyReleased( KeyEvent e )
{
keyIsHeld = false;
moveChar = ' ';
}
public void keyTyped( KeyEvent e ) { }
public void keyPressed( KeyEvent a )
{
char c = a.getKeyChar();
if ( c == 'w' )
{
moveChar = 'w';
keyIsHeld = true;
}
else if ( c == 'a')
{
moveChar = 'a';
keyIsHeld = true;
}
else if ( c == 's')
{
moveChar = 's';
keyIsHeld = true;
}
else if ( c == 'd')
{
moveChar = 'd';
keyIsHeld = true;
}
}
public void mouseClicked(MouseEvent e)
{
int x = e.getX();
int y = e.getY();
if (isInMenu && P1.ClassID == 0)
{
if (x < 500 && y > 100 && y < 375)
{
P1.ClassID = 1;
isInMenu = false;
System.out.println(P1.Pseudo + " has chosen class: Warrior!");
}
if (x < 500 && y >= 375)
{
P1.ClassID = 3;
isInMenu = false;
System.out.println(P1.Pseudo + " has chosen class: UO3!");
}
if (x >= 500 && y > 100 && y < 375)
{
P1.ClassID = 2;
isInMenu = false;
System.out.println(P1.Pseudo + " has chosen class: Thief!");
}
if (x >= 500 && y >= 375)
{
P1.ClassID = 4;
isInMenu = false;
System.out.println(P1.Pseudo + " has chosen class: Mage!");
}
repaint();
}
}
public void mouseEntered(MouseEvent e){}
public void mouseExited(MouseEvent e) {}
public void mousePressed(MouseEvent e) {}
public void mouseReleased(MouseEvent e) {}
public boolean mouseDown(Event e, int x, int y){return true;}
public void run()
{
while (!isInMenu || !firstRun)
{
if (moveChar == 'w')
{
MovePlayer(0, -moveScale);
}
else if (moveChar == 'a')
{
MovePlayer(-moveScale, 0);
}
else if (moveChar == 's')
{
MovePlayer(0, moveScale);
}
else if (moveChar == 'd')
{
MovePlayer(moveScale, 0);
}
Util.wait(200);
repaint();
}
}
Thread moveThread;
Graphics g;
boolean increaseDecrease = false;
public void SetUpGraphics(Graphics graphics)
{
g = graphics;
}
public void start ()
{
if (moveThread == null)
{
moveThread = new Thread(this);
moveThread.start();
}
}
}
class Map1 extends FinalProjectTest
{
protected static int wall1x1 = 0;
protected static int wall1y1 = 500;
protected static int wall1x2 = 810;
protected static int wall1y2 = 440;
protected static int wall2x1 = 1000;
protected static int wall2y1 = 200;
protected static int wall2x2 = 190;
protected static int wall2y2 = 140;
public Map1(Graphics g)
{
Walls wall1 = new Walls(g, wall1x1, wall1y1, wall1x2, wall1y2);
Walls wall2 = new Walls(g, wall2x1, wall2y1, wall2x2, wall2y2);
}
}
class HostileObject
{
private int startPosX, startPosY;
private int xSize = 35;
private int ySize = 35;
public int health = 100;
public HostileObject(int x, int y)
{
startPosX = x;
startPosY = y;
}
public void CreateHostile(Graphics g)
{
g.setColor(Util.black);
//Util.fillRect(g ,startPosX,startPosY,xSize,ySize);
}
}
class Walls
{
private static int wallCount = 2;
public Walls(Graphics g, int x1, int y1, int x2, int y2)
{
Util.fillRect(g, x1, y1, x2, y2);
}
}
class Character extends FinalProjectTest implements MouseListener, Runnable
{
protected int ClassID = 0;
protected int PlayerID = 0;
protected int GP = 100;
protected String Pseudo = "Muritor";
protected boolean DebuggingMode = false;
protected Graphics menuGraphics;
Thread startMenuThread;
public Character(Graphics g)
{
g.setColor(Util.black);
Util.fillRect(g, 1, 1, 1000, 650);
Util.drawButton(g, 1, 1, 1000, 100, "3 Floors", 2);
Util.wait(1000);
menuGraphics = g;
startMenuThread = new Thread(this);
startMenuThread.start();
}
public void run()
{
while (Thread.currentThread() == startMenuThread)
{
Util.fillRect(menuGraphics, 1, 1, 1000, 650);
Util.drawButton(menuGraphics, 1, 1, 1000, 100, "Choose a Class", 2);
Util.drawButton(menuGraphics, 1, 100, 500, 375, "Warrior", 1);
Util.drawButton(menuGraphics, 501, 100, 1000, 375, "Thief", 1);
Util.drawButton(menuGraphics, 1, 376, 500, 650, "UO3", 1);
Util.drawButton(menuGraphics, 501, 376, 1000, 650, "Mage", 1);
repaint();
System.out.println("Menu loaded");
Util.wait(200);
}
}
public static void ButtonSelection(Graphics g)
{
}
}
class Util
{
static final Color black = Color.black;
static final Color white = Color.white;
public static void wait(int mil)
{
try
{
Thread.sleep((mil));
}
catch(InterruptedException ex)
{
Thread.currentThread().interrupt();
}
}
public static void fillRect(Graphics g, int x1, int y1, int x2, int y2)
{
int widthPlaceholder = x2 - x1;
int heightPlaceholder = y2 - y1;
g.fillRect(x1,y1,widthPlaceholder,heightPlaceholder);
}
public static void drawButton(Graphics g, int x1, int y1, int x2, int y2, String title, int fontType)
{
g.setColor(Util.black);
int widthPlaceholder = x2 - x1;
int heightPlaceholder = y2 - y1;
g.fillRect(x1,y1,widthPlaceholder,heightPlaceholder);
g.setColor(Util.white);
widthPlaceholder = x2 - x1;
heightPlaceholder = y2 - y1;
for (int k = 0; k < 3; k++)
{
g.drawRect(x1+k,y1+k,widthPlaceholder-k,heightPlaceholder-k);
}
switch(fontType)
{
case 1:
Font characterCreateButton = new Font("SansSerif", Font.PLAIN, 75);
g.setFont(characterCreateButton);
g.drawString(title, x1+100, y1+100);
break;
case 2:
Font characterCreateTitle = new Font("SansSerif", Font.BOLD, 100);
g.setFont(characterCreateTitle);
g.drawString(title, x1+25, y1+80);
break;
case 3:
Font mainMenu = new Font("Arial", Font.ITALIC, 50);
g.setFont(mainMenu);
break;
}
}
}
I expect it to say "Menu Loaded" every .2 seconds and refresh the actual menu screen at the same rate, I get the message, but the applet window is just white.
Problem #1
public class FinalProjectTest extends Applet implements KeyListener, Runnable, MouseListener {
I don't know about you, but when I compile your code, I get
Note: .../FinalProjectTest.java uses or overrides a deprecated API.
Note: Recompile with -Xlint:deprecation for details.
So, if I enable the compiler flag, I get...
Compiling 1 source file to .../build/classes
.../FinalProjectTest.java:18: warning: [deprecation] Applet in java.applet has been deprecated
public class FinalProjectTest extends Applet implements KeyListener, Runnable, MouseListener {
.../FinalProjectTest.java:179: warning: [deprecation] mouseDown(Event,int,int) in Component has been deprecated
public boolean mouseDown(Event e, int x, int y) {
^
.../FinalProjectTest.java:179: warning: [deprecation] Event in java.awt has been deprecated
public boolean mouseDown(Event e, int x, int y) {
^
3 warnings
This should be raising alarm bells.
Applets have been actively been deprecated and are simply no longer supported and believe have been removed in the latest versions of the API, seriously time to move on.
In fact, when I run the code, I get:
Warning: Applet API and AppletViewer are deprecated.
Problem #2
public void paint(Graphics g) {
if (firstRun) {
firstRun = false;
isInMenu = true;
System.out.println("Character Created");
P1 = new Character(g);
}
if (!isInMenu && !firstRun) {
System.out.println("Game has begun!");
Map1 firstMap = new Map1(g);
Looper(g);
}
}
Painting should paint state, not make logical decisions or change the state, in fact, what's ever more worrying is...
P1 = new Character(g);
You should never maintain a reference to a Graphics context you did not create yourself. The painting system in AWT/Swing uses a shared context, so all components will use the same Graphics context, there's also no guarantee that the context will be the same between paint cycles.
This also highlights that you don't understand how the painting system works in AWT/Swing.
Start with Performing Custom Painting and Painting in AWT and Swing for more details about how painting actually works and how you should work with it
Problem ♾
Okay, so from there on in, every thing else is just compounding based on the above, make a bad situation infinitely worse, for example...
public void run() {
while (Thread.currentThread() == startMenuThread) {
Util.fillRect(menuGraphics, 1, 1, 1000, 650);
Util.drawButton(menuGraphics, 1, 1, 1000, 100, "Choose a Class", 2);
Util.drawButton(menuGraphics, 1, 100, 500, 375, "Warrior", 1);
Util.drawButton(menuGraphics, 501, 100, 1000, 375, "Thief", 1);
Util.drawButton(menuGraphics, 1, 376, 500, 650, "UO3", 1);
Util.drawButton(menuGraphics, 501, 376, 1000, 650, "Mage", 1);
repaint();
System.out.println("Menu loaded");
Util.wait(200);
}
}
This "might" seem okay, but if you understood how the painting, you'd understand the calling repaint will trigger and paint pass and cause paint to be called again and ... wait, hang on...
class Character extends FinalProjectTest implements MouseListener, Runnable {
Why does Character extend from FinalProjectTest?? It's not even added to any container which could paint it...oh dear ...
Answer...
Start again.
No, seriously, throw away what you've done and start again. This time start by reading (and understanding)...
Basic OO design concepts of "separation of responsibility". Rather then compounding all you logic into a single method, seperate the responsibility of each part of your program into their own class(es). The menu should be a single, stand alone component, the game canvas should be it's own, stand alone component, you should then have a "controller" which can, based on feedback from these components (via a observer pattern) decide when each should be shown (and how).
Model-View-Controller (which bleeds into the previous comment)
Performing Custom Painting and Painting in AWT and Swing
How to Use Key Bindings because KeyListener is not a good choice here
Concurrency in Swing because Swing, like most GUI frameworks, is not thread and is single threaded and you should know how to handle it.
How to Make Frames (Main Windows) because Applets are dead
How to Use CardLayout as this will help make your lives easier
Use JavaFX. At the very least you should be using Swing, but if you can, use JavaFX
Related
I am working on homework for class, and its late because I can't seem to understand the material despite all the research that I am doing. I am a beginner and do not know much in the way of java. Also, this is my first post so please be forgiving when you are reading this.
I am building on source code from my textbook, which I updated recently for past homework, but now I am trying to generate a class that draws multiple squares and moves those objects independently and at different speeds. They will all need to rebound off the walls as well. I followed the instructions and created two arrays that will hold the random x and y values between 1 and 10. However, I struggle with arrays and I am sure that I am not doing it correctly. So, I would love some feedback to see if I have it set up correctly.
I have a the jpanel pulling up and drawing, and as long as there is 1 square it is working fine bouncing off the walls, but things change when I draw more than one. The do not move independently and they also share the same speed. Some even disappear from time to time. This has really thrown me off. I appreciate any help!
In short, I am trying to paint new squares that all travel in different directions and at different speeds. Per the instructions we are suppose create and use a two arrays that handle the x and y values.
Here is what I have so far:
public class DotsPanel extends JPanel
{
private int delay = 15;
private final int SIZE = 7, IMAGE_SIZE = 3; // radius of each dot
private Timer timer;
private int x, y, i;
private ArrayList<Point> pointList;
static int [] xarray = new int [1000];
static int [] yarray = new int [1000];
Random rand = new Random();
//-----------------------------------------------------------------
// Constructor: Sets up this panel to listen for mouse events.
//-----------------------------------------------------------------
public DotsPanel()
{
pointList = new ArrayList<Point>();
int [] xarray = new int [1000];
int [] yarray = new int [1000];
timer = new Timer(delay, new ReboundListener());
addMouseListener (new DotsListener());
addMouseMotionListener (new DotsListener());
setBackground(Color.gray);
setPreferredSize(new Dimension(700, 500));
for(int i = 0; i < xarray.length; i++)
{
xarray[i] = rand.nextInt(7);
yarray[i] = rand.nextInt(7);
}
timer.start();
}
//-----------------------------------------------------------------
// Draws all of the dots stored in the list.
//-----------------------------------------------------------------
public void paintComponent(Graphics page)
{
super.paintComponent(page);
page.setColor(Color.BLUE);
for (Point spot : pointList)
{
page.fillRect(spot.x-SIZE, spot.y-SIZE, 25, 25);
page.drawString("Count: " + pointList.size(), 5, 15);
}
}
//*****************************************************************
// Represents the listener for mouse events.
//*****************************************************************
private class DotsListener implements MouseListener, MouseMotionListener
{
//--------------------------------------------------------------
// Adds the current point to the list of points and redraws
// the panel whenever the mouse button is pressed.
//--------------------------------------------------------------
public void mousePressed(MouseEvent event)
{
pointList.add(event.getPoint());
repaint();
}
public void mouseDragged(MouseEvent event)
{
// initially I had two xarray and yarray in here just like in
// mouseClicked
// but it did not change anything when removed
}
//--------------------------------------------------------------
// Provide empty definitions for unused event methods.
//--------------------------------------------------------------
public void mouseClicked(MouseEvent event)
{
xarray[i] = rand.nextInt(7);
yarray[i] = rand.nextInt(7);
}
public void mouseReleased(MouseEvent event) {}
public void mouseEntered(MouseEvent event) {}
public void mouseExited(MouseEvent event) {}
public void mouseMoved(MouseEvent e) {}
}
private class ReboundListener implements ActionListener
{
//--------------------------------------------------------------
// Updates the position of the image and possibly the direction
// of movement whenever the timer fires an action event.
//--------------------------------------------------------------
public void actionPerformed(ActionEvent event)
{
for (Point spot : pointList)
{
spot.x += xarray[i];
spot.y += yarray[i];
if (spot.x <= 0 || spot.x >= 700)
xarray[i] = xarray[i] * -1;
if (spot.y <= 0 || spot.y >= 500)
yarray[i] = yarray[i] * -1;
repaint();
}
}
}
}
However, I struggle with arrays and I am sure that I am not doing it correctly.
I wouldn't use Arrays.
Instead, have a Ball object manage its own state. Then you can have different color, speed, size etc for each Ball. Then when the Timer fires you just calculate the new position and repaint the Ball.
Here is an example to get you started:
import java.awt.*;
import java.awt.event.*;
import java.awt.image.*;
import java.util.*;
import javax.swing.*;
import javax.swing.Timer;
public class BallAnimation4
{
private static void createAndShowUI()
{
BallPanel panel = new BallPanel();
JFrame frame = new JFrame("BallAnimation4");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.add( panel );
frame.setSize(800, 600);
frame.setLocationRelativeTo( null );
//frame.setExtendedState(JFrame.MAXIMIZED_BOTH);
frame.setVisible( true );
panel.addBalls(5);
panel.startAnimation();
}
public static void main(String[] args)
{
EventQueue.invokeLater(new Runnable()
{
public void run()
{
createAndShowUI();
}
});
}
}
class BallPanel extends JPanel implements ActionListener
{
private ArrayList<Ball> balls = new ArrayList<Ball>();
public BallPanel()
{
setLayout( null );
setBackground( Color.BLACK );
}
public void addBalls(int ballCount)
{
Random random = new Random();
for (int i = 0; i < ballCount; i++)
{
Ball ball = new Ball();
ball.setRandomColor(true);
ball.setLocation(random.nextInt(getWidth()), random.nextInt(getHeight()));
ball.setMoveRate(32, 32, 1, 1, true);
// ball.setMoveRate(16, 16, 1, 1, true);
ball.setSize(32, 32);
balls.add( ball );
}
}
#Override
public void paintComponent(Graphics g)
{
super.paintComponent(g);
for (Ball ball: balls)
{
ball.draw(g);
}
}
public void startAnimation()
{
Timer timer = new Timer(75, this);
timer.start();
}
public void actionPerformed(ActionEvent e)
{
move();
repaint();
}
private void move()
{
for (Ball ball : balls)
{
ball.move(this);
}
}
class Ball
{
public Color color = Color.BLACK;
public int x = 0;
public int y = 0;
public int width = 1;
public int height = 1;
private int moveX = 1;
private int moveY = 1;
private int directionX = 1;
private int directionY = 1;
private int xScale = moveX;
private int yScale = moveY;
private boolean randomMove = false;
private boolean randomColor = false;
private Random myRand = null;
public Ball()
{
myRand = new Random();
setRandomColor(randomColor);
}
public void move(JPanel parent)
{
int iRight = parent.getSize().width;
int iBottom = parent.getSize().height;
x += 5 + (xScale * directionX);
y += 5 + (yScale * directionY);
if (x <= 0)
{
x = 0;
directionX *= (-1);
xScale = randomMove ? myRand.nextInt(moveX) : moveX;
if (randomColor) setRandomColor(randomColor);
}
if (x >= iRight - width)
{
x = iRight - width;
directionX *= (-1);
xScale = randomMove ? myRand.nextInt(moveX) : moveX;
if (randomColor) setRandomColor(randomColor);
}
if (y <= 0)
{
y = 0;
directionY *= (-1);
yScale = randomMove ? myRand.nextInt(moveY) : moveY;
if (randomColor) setRandomColor(randomColor);
}
if (y >= iBottom - height)
{
y = iBottom - height;
directionY *= (-1);
yScale = randomMove ? myRand.nextInt(moveY) : moveY;
if (randomColor) setRandomColor(randomColor);
}
}
public void draw(Graphics g)
{
g.setColor(color);
g.fillOval(x, y, width, height);
}
public void setColor(Color c)
{
color = c;
}
public void setLocation(int x, int y)
{
this.x = x;
this.y = y;
}
public void setMoveRate(int xMove, int yMove, int xDir, int yDir, boolean randMove)
{
this.moveX = xMove;
this.moveY = yMove;
directionX = xDir;
directionY = yDir;
randomMove = randMove;
}
public void setRandomColor(boolean randomColor)
{
this.randomColor = randomColor;
switch (myRand.nextInt(3))
{
case 0: color = Color.BLUE;
break;
case 1: color = Color.GREEN;
break;
case 2: color = Color.RED;
break;
default: color = Color.BLACK;
break;
}
}
public void setSize(int width, int height)
{
this.width = width;
this.height = height;
}
}
}
Since your Arrays only contain the Point you want to paint you don't have any information about the speed each point should be moved at. The best you could do is create a random amount each point should be moved each time its location is changed. This would give erratic movement as each time you move a point the distance would be random.
If you want more constant speed then you would need to create a second Array to contain the distance each point should move every time.
This starts to get messy creating a new Array every time you want a new property to be unique for the object you want to paint. That is why the approach to create a custom Object with multiple properties is easier to manage.
I am attempting to embed a game into my website that I programmed in java. I have no idea how to take my code from eclipse(which is what my JDE is) and put it into my website. I am using a weebly.com website. I do have several unfinished classes, I want to upload my incomplete games as well as complete just to show progress. so I ask you, how do I get this code from eclipse, to my website. Thanks for the help and the following is my code.
This is my Main class:
import java.applet.Applet;
import java.awt.Graphics;
import java.awt.Image;
public class Main extends Applet implements Runnable {
private static final long serialVersionUID = 1L;
Thread th = new Thread(this);
boolean running = true;
public int Jweidth = 400, Jheight = 400;
Image dbImage;
Graphics dbGraphics;
Bullet b;
Player p;
Enemy e, e2, e3, e4, e5, e6, e7, e8;
HealthBar hb;
NameSign ns;
Restart r;
private boolean BFire;
public void init() {
//set window size
setSize(Jweidth, Jheight);
//calls player class
p = new Player(this);
//calls healthBar
hb = new HealthBar(this, p);
//calls enemy class
e = new Enemy(this);
e2 = new Enemy(42, 0, this);
e3 = new Enemy(84, 0, this);
e4 = new Enemy(126, 0, this);
e5 = new Enemy(0, 42, this);
e6 = new Enemy(42, 42, this);
e7 = new Enemy(84, 42, this);
e8 = new Enemy(126, 42, this);
//calls bullet class
b = new Bullet(this);
//calls nameSign class
ns = new NameSign(this);
//calls Restart class
r = new Restart(this);
}
public void start() {
//starts a new thread
th.start();
}
public void stop() {
running = false;
}
public void destroy() {
running = false;
}
public void run() {
while (running) {
setBFire(b.getFire());
//calls update method from player class
p.update(this);
//calls update method from enemy class
e.update(this, p);
e2.update(this, p);
e3.update(this, p);
e4.update(this, p);
e5.update(this, p);
e6.update(this, p);
e7.update(this, p);
e8.update(this, p);
//calls update method from fire class if BFire is true
if (setBFire(true)) {
b.update(this, p);
}
//calls update method from HealthBar class
hb.update(this, p);
//calls update method from NameSign class
ns.update(this);
//calls update method from Restart class
r.update(this, p);
repaint();
//sets Thread to repeat every 17 milliseconds
try {
Thread.sleep(17);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
//doublebuffer
public void update(Graphics g) {
dbImage = createImage(Jweidth, Jheight);
dbGraphics = dbImage.getGraphics();
paint(dbGraphics);
g.drawImage(dbImage, 0, 0, this);
}
//paint class
public void paint(Graphics g) {
//calls paint method from player class
p.paint(g, this);
//calls paint method from enemy class
e.paint(g, this);
e2.paint(g, this);
e3.paint(g, this);
e4.paint(g, this);
e5.paint(g, this);
e6.paint(g, this);
e7.paint(g, this);
e8.paint(g, this);
//calls paint method from bullet class
b.paint(g, this);
//calls paint method from healthBar class
hb.paint(g, this);
//calls paint method from nameSign class
ns.paint(g, this);
//calls paint method from Restart class
r.paint(g);
}
public int getJweidth() {
return Jweidth;
}
public int getJheight() {
return Jheight;
}
//ignore all boolean Bfire methods
public boolean isBFire() {
return BFire;
}
public boolean setBFire(boolean bFire) {
BFire = bFire;
return bFire;
}
}
This is my Enemy class:
import java.awt.*;
import java.net.URL;
public class Enemy {
//Enemy ints
private int x = 0, y = 0, speed = 2;
private URL url;
private Image Enemy;
//adds image
public Enemy(Main m){
url = m.getDocumentBase();
Enemy = m.getImage(url, "Enemy.png");
}
public Enemy(int i, int j, Main m) {
url = m.getDocumentBase();
Enemy = m.getImage(url, "Enemy.png");
x = i;
y = j;
}
//same as run method but just for the enemy
public void update(Main m, Player p){
x += speed;
if(x <= 0){
speed = 2;
y += 32;
}
else if(x > m.getJweidth() - 32){
speed = -2;
y += 32;
}
//calls collision method
collision(p);
}
//enemy player hitbox
private void collision(Player p) {
int Px = p.getX();
int Py = p.getY();
int Pr = p.getRadious();
if(Px - Pr <= x && Px + Pr >= x && Py - Pr <= y && Py + Pr >= y){
p.hit();
}
}
//Graphics for enemy
public void paint(Graphics g, Main m){
g.drawImage(Enemy, x, y, m);
}
}
This is my Bullet class (this game is a work in progress and this class isn't working, but that is just unfinished work that I will do soon)
import java.awt.Graphics;
import java.awt.Image;
import java.awt.event.KeyEvent;
import java.awt.event.KeyListener;
import java.net.URL;
public class Enemy {
//Enemy ints
private int x = 0, y = 0, speed = 2;
private URL url;
private Image Enemy;
//adds image
public Enemy(Main m) {
url = m.getDocumentBase();
Enemy = m.getImage(url, "Enemy.png");
}
public Enemy(int i, int j, Main m) {
url = m.getDocumentBase();
Enemy = m.getImage(url, "Enemy.png");
x = i;
y = j;
}
//same as run method but just for the enemy
public void update(Main m, Player p) {
x += speed;
if (x <= 0) {
speed = 2;
y += 32;
} else if (x > m.getJweidth() - 32) {
speed = -2;
y += 32;
}
//calls collision method
collision(p);
}
//enemy player hitbox
private void collision(Player p) {
int Px = p.getX();
int Py = p.getY();
int Pr = p.getRadious();
if (Px - Pr <= x && Px + Pr >= x && Py - Pr <= y && Py + Pr >= y) {
p.hit();
}
}
//Graphics for enemy
public void paint(Graphics g, Main m) {
g.drawImage(Enemy, x, y, m);
}
}
This is my Restart class(once again unfinished but on the way)
import java.awt.Graphics;
import java.awt.event.KeyEvent;
import java.awt.event.KeyListener;
public class Restart implements KeyListener {
private int x, y;
private int pHealth;
private String string = "Would you like to play again?";
private boolean restart = false;
public Restart(Main m) {
x = 600;
y = 600;
}
public void update(Main m, Player p) {
//checks if players health = 0 and if restart is true
pHealth = p.getpHealth();
if (setRestart(true && pHealth <= 0)) {
System.out.println("Restart");
x = m.Jweidth / 2 - 75;
y = m.Jheight / 2;
}
//reset ints for player
//TODO
//reset ints for enemy
//TODO
//reset ints for bullet
//TODO
//reset ints for healthbar
//TODO
}
public void paint(Graphics g) {
g.drawString(string, x, y);
}
public void keyPressed(KeyEvent e) {
switch (e.getKeyCode()) {
case KeyEvent.VK_F1: {
setRestart(true);
break;
}
}
}
public void keyReleased(KeyEvent e) {
switch (e.getKeyCode()) {
case KeyEvent.VK_F1: {
setRestart(false);
break;
}
}
}
public void keyTyped(KeyEvent arg0) {
}
//ignore all boolean methods
public boolean isRestart() {
return restart;
}
public boolean setRestart(boolean restart) {
this.restart = restart;
return restart;
}
}
You will have to use Applets to embed your Java program in a browser, or Java Web Start if you just want to start it from the web in a new window.
Some security issues may apply depending on the Java version you are using.
Here are some examples on how to do it:
https://docs.oracle.com/javase/tutorial/deployment/applet/
http://www.javatpoint.com/java-applet
And here for the Java Web Start:
https://docs.oracle.com/javase/tutorial/deployment/webstart/
You're gonna need to make a .jar file and a compiled .class file, no .java file. To implement Java code in HTML, you can use the deprecated <applet> tag, or the new <object> tag.
<object codetype="application/java" classid="java:yourclass.class" archive="yourjar.jar" width="1000" height="1000"></object>
codetype="application/java" - The type of code, use application/java.
classid="?" - Java class to run, eg. java:MyApplet.class
archive="url" - Address or filename of the Java archive file (.jar) containing the class files.
width="?" - The width of the window, in pixels.
height="?" - The height of the window, in pixels.
Just telling you, I'm not sure that it'll work.
I am trying to get three different blocks to move back and forth from one side of the screen to the other. If the block on the far right reaches the game frame's width, it's velocity is reversed and it starts moving to the left side. However, my problem exists with the other two blocks. I put in my code a method that states once the second block reaches the (game width - 100), with 100 just being the width of each blocks, it's velocity should be reversed. The third block is suppose to work the same except once it reaches the x point (game width - 200). My attempt to change the velocity of the second and third blocks can be seen under the UpdateBlocks method in the PlayState class posted below.
Another thing I want to point out is that in update method in the block class, the x value is being reversed too. I tried at first to make it read the blocks from the PlayState then change the corresponding velocities but I got a thread error. That's why I am bringing my current predicament to you.
Here is the block class:
package com.jamescho.game.model;
import java.awt.Rectangle;
import com.jamescho.framework.util.RandomNumberGenerator;
import com.jamescho.game.main.GameMain;
import com.jamescho.game.state.PlayState;
public class Block {
private float x, y;
private int width, height, velX = 700;
private Rectangle rect;
private PlayState play;
private boolean visible;
private static final int UPPER_Y = 275;
private static final int LOWER_Y = 355;
public Block(float x, float y, int width, int height) {
this.x = x;
this.y = y;
this.width = width;
this.height = height;
rect = new Rectangle((int) x, (int) y, width, height);
visible = false;
}
// Note: Velocity value will be passed in from PlayState!
public void update(float delta) {
x += velX * delta;
if (x <= 0 || x >= GameMain.GAME_WIDTH - 100) {
velX = -velX;
}
updateRect();
}
public void updateRect() {
rect.setBounds((int) x, (int) y, width, height);
}
public void invisible() {
visible = false;
}
public void visible() {
visible = true;
}
public void stop() {
velX = 0;
}
public void reverse() {
velX = -velX;
}
public float getX() {
return x;
}
public float getY() {
return y;
}
public boolean isVisible() {
return visible;
}
public Rectangle getRect() {
return rect;
}
}
Here is the PlayState where everything is going on:
package com.jamescho.game.state;
import java.awt.Color;
import java.awt.Font;
import java.awt.Graphics;
import java.awt.event.KeyEvent;
import java.awt.event.MouseEvent;
import java.util.ArrayList;
import com.jamescho.game.main.GameMain;
import com.jamescho.game.main.Resources;
import com.jamescho.game.model.Block;
public class PlayState extends State {
private ArrayList<Block> row1;
private ArrayList<Block> row2;
private ArrayList<Block> row3;
private Block block;
private Font scoreFont;
private int playerScore = 0;
private static final int BLOCK_HEIGHT = 100;
private static final int BLOCK_WIDTH = 100;
private int blockSpeed = -200;
private static final int PLAYER_WIDTH = 66;
private static final int PLAYER_HEIGHT = 92;
#Override
public void init() {
row1 = new ArrayList<Block>();
row2 = new ArrayList<Block>();
scoreFont = new Font("SansSerif", Font.BOLD, 25);
for (int i = 0; i < 3; i++) {
Block b = new Block(i * 105, GameMain.GAME_HEIGHT - 101,
BLOCK_WIDTH, BLOCK_HEIGHT);
row1.add(b);
b.visible();
for (int h = 0; h < 3; h++) {
Block b2 = new Block(h * 105, b.getY() - 208,
BLOCK_WIDTH, BLOCK_HEIGHT);
row2.add(b2);
b2.invisible();
}
}
}
#Override
public void update(float delta) {
playerScore += 1;
if (playerScore % 500 == 0 && blockSpeed > -280) {
blockSpeed -= 10;
}
Resources.runAnim.update(delta);// starts iterating through its frames
updateBlocks(delta);
}
private void updateBlocks(float delta) { // time from last update
for (Block b : row1) { //foreach statement; for each iteration of "b" the code is executed, one "b" at a time
if(row1.get(1).getX() == GameMain.GAME_WIDTH - BLOCK_WIDTH - 5) {
row1.get(1).reverse();
}
else if(row1.get(2).getX() == GameMain.GAME_WIDTH - 2 * BLOCK_WIDTH - 5) {
row1.get(2).reverse();
}
b.update(delta);
}
for (Block c : row2) { //foreach statement; for each iteration of "b" the code is executed, one "b" at a time
// used with objects; can't use primitive
c.update(delta);
if (c.isVisible()) {
}
}
}
#Override
public void render(Graphics g) {
g.setColor(Color.BLACK);
g.fillRect(0, 0, GameMain.GAME_WIDTH, GameMain.GAME_HEIGHT);
renderPlayer(g);
renderBlocks(g);
renderScore(g);
}
private void renderScore(Graphics g) {
g.setFont(scoreFont);
g.setColor(Color.GRAY);
g.drawString("" + playerScore / 100, 20, 30);
}
private void renderPlayer(Graphics g) {
}
private void renderBlocks(Graphics g) {
for (Block b : row1) {
if (b.isVisible()) {
g.drawImage(Resources.blue_panel, (int) b.getX(), (int) b.getY(),
BLOCK_WIDTH, BLOCK_HEIGHT, null); // change null if you want the object to know about object
}
}
for (Block c : row2) {
if (c.isVisible()) {
g.drawImage(Resources.blue_panel, (int) c.getX(), (int) c.getY()+105,
BLOCK_WIDTH, BLOCK_HEIGHT, null); // change null if you want the object to know about object
}
}
}
#Override
public void onClick(MouseEvent e) {
}
#Override
public void onKeyPress(KeyEvent e) {
if (e.getKeyCode() == KeyEvent.VK_SPACE) {
for (Block b : row1) {
b.stop();
for (Block c : row2) {
if (c.isVisible() == true) {
c.stop();
}
}
}
}
else if (e.getKeyCode() == KeyEvent.VK_DOWN) {
}
}
#Override
public void onKeyRelease(KeyEvent e) {
if(e.getKeyCode() == KeyEvent.VK_SPACE) {
for (Block c: row2) {
c.visible();
}
}
}
public float getb1X() {
return row1.get(1).getX();
}
}
Sorry I haven't gone through your entire code. But this is how I would do it:
int x , int y -- are the coordinates of each block on the screen.
a block can move on the screen in 4 ways / directions / quadrants:
1) x = x + deltaX, y = y + deltaY
2) x = x - deltaX, y = y + deltaY
3) x = x + deltaX, y = y - deltaY
4) x = x - deltaX, y = y - deltaY
Thus in order to change the direction when a block hits any side you should multiply deltaX with -1 if it hits left or right side and deltaY with -1 if it hits the bottom or top. this will reverse its direction.
Closed. This question does not meet Stack Overflow guidelines. It is not currently accepting answers.
This question appears to be off-topic because it lacks sufficient information to diagnose the problem. Describe your problem in more detail or include a minimal example in the question itself.
Closed 9 years ago.
Improve this question
I created a GUI named Menu class for my Start, Help and Exit button. my problem is my game won't start, it hangs everytime I press the Start button. Can someone check my error and explain it to me because its my case study at school.
package spaceSip;
import javax.swing.*;
import java.awt.*;
import java.awt.event.*;
import java.awt.image.BufferedImage;
public class Menu extends JFrame implements ActionListener
{
private JLabel titleL;
private JButton startB, helpB, exitB;
static JFrame frame1 = new JFrame();
public Menu()
{
frame1.setSize(500,250);
Container mainP = frame1.getContentPane();
mainP.setLayout(null);
titleL = new JLabel("WELCOME");
startB = new JButton("Start");
helpB = new JButton("Help");
exitB = new JButton("Exit");
mainP.add(titleL);
titleL.setFont(new Font("Chiller",Font.BOLD,50));
titleL.setBounds(100, 30, 200, 50);
mainP.add(startB);
startB.setMnemonic(KeyEvent.VK_S);
startB.setBounds(200, 80, 100, 20);
mainP.add(helpB);
helpB.setMnemonic(KeyEvent.VK_H);
helpB.setBounds(200, 100, 100, 20);
mainP.add(exitB);
exitB.setMnemonic(KeyEvent.VK_E);
exitB.setBounds(200, 120, 100, 20);
startB.addActionListener(this);
helpB.addActionListener(this);
exitB.addActionListener(this);
frame1.setVisible(true);
frame1.setResizable(false);
}
public void actionPerformed(ActionEvent e)
{
String key = e.getActionCommand();
if(key == "Start")
{
frame1.dispose();
new SpaceShipMain();
}
else if(key == "Help")
{
}
else
System.exit(0);
}
public static void main(String[]args)
{
new Menu();
}
}
package spaceSip;
import javax.swing.*;
import java.util.*;
import java.awt.*;
import java.awt.event.*;
import java.io.*;
public class SpaceShipMain implements MouseListener
{
private JFrame background;
private SpaceShipPanel back;
public static boolean paused;
public static boolean crashed;
public static boolean started;
public static boolean playedOnce;
public boolean goingUp;
private double upCount;
public static int distance;
public static int maxDistance;
public final int XPOS;
public final int NUMRECS;
public final int RECHEIGHT;
public final int RECWIDTH;
private int moveIncrement;
private int numSmoke;
private ArrayList<SpaceShipImage> toprecs;
private ArrayList<SpaceShipImage> bottomrecs;
private ArrayList<SpaceShipImage> middlerecs;
private ArrayList<SpaceShipImage> smoke;
private SpaceShipImage helicopter;
public SpaceShipMain()
{
NUMRECS = 100;
RECHEIGHT = 70;
RECWIDTH = 30;
XPOS = 200;
playedOnce = false;
maxDistance = 0;
load(new File("C:\\Users/Travelmate/workspace/GAME/src/spaceSip/Best.txt"));
initiate();
}
public void load(File file)
{
try
{
Scanner reader = new Scanner(file);
while(reader.hasNext())
{
int value = reader.nextInt();
if(value > maxDistance)
maxDistance = value;
}
}
catch(IOException i )
{
System.out.println("Error. "+i);
}
}
public void save()
{
FileWriter out;
try
{
out = new FileWriter("C:\\Users/Travelmate/workspace/GAME/src/spaceSip/Best.txt");
out.write("" + maxDistance);
out.close();
}
catch(IOException i)
{
System.out.println("Error: "+i.getMessage());
}
}
public void initiate()
{
if(!playedOnce)
{
background = new JFrame("Space Ship Game");
background.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); //closes the program when the window is closed
background.setResizable(false); //don't allow the user to resize the window
background.setSize(new Dimension(800,500));
background.setVisible(true);
back = new SpaceShipPanel("C:\\Users/Travelmate/workspace/GAME/src/spaceSip/starfield.jpg");
background.add(back);
back.addMouseListener(this);
}
playedOnce = true;
goingUp = false;
paused = false;
crashed = false;
started = false;
distance = 0;
upCount = 0;
moveIncrement = 2;
numSmoke = 15;
toprecs = new ArrayList<SpaceShipImage>();
middlerecs = new ArrayList<SpaceShipImage>();
bottomrecs = new ArrayList<SpaceShipImage>();
smoke = new ArrayList<SpaceShipImage>();
helicopter = new SpaceShipImage("C:\\Users/Travelmate/workspace/GAME/src/spaceSip/rocketship.GIF",XPOS,200);
for(int x = 0; x < NUMRECS; x++)
toprecs.add(new SpaceShipImage("C:\\Users/Travelmate/workspace/GAME/src/spaceSip/rec2.JPG",RECWIDTH*x,5));
for(int x = 0; x < NUMRECS; x++)
bottomrecs.add(new SpaceShipImage("C:\\Users/Travelmate/workspace/GAME/src/spaceSip/rec2.JPG",RECWIDTH*x,410));
middlerecs.add(new SpaceShipImage("C:\\Users/Travelmate/workspace/GAME/src/spaceSip/asteroid2.jpg",1392,randomMidHeight()));
middlerecs.add(new SpaceShipImage("C:\\Users/Travelmate/workspace/GAME/src/spaceSip/asteroid2.jpg",1972,randomMidHeight()));
drawRectangles();
}
public void drawRectangles()
{
long last = System.currentTimeMillis();
long lastCopter = System.currentTimeMillis();
long lastSmoke = System.currentTimeMillis();
long lastSound = System.currentTimeMillis();
int firstUpdates = 0;
double lastDistance = (double)System.currentTimeMillis();
while(true)
{
if(!paused && !crashed && started && (double)System.currentTimeMillis() - (double)(2900/40) > lastDistance)
{
lastDistance = System.currentTimeMillis();
distance++;
}
if(!paused && !crashed && started && System.currentTimeMillis() - 10 > lastCopter)
{
lastCopter = System.currentTimeMillis();
updateCopter();
updateMiddle();
}
if(!paused && !crashed && started && System.currentTimeMillis() - 100 > last)
{
last = System.currentTimeMillis();
updateRecs();
}
if(!paused && !crashed && started && System.currentTimeMillis() - 75 > lastSmoke)
{
lastSmoke = System.currentTimeMillis();
if (firstUpdates < numSmoke)
{
firstUpdates++;
smoke.add(new SpaceShipImage("C:\\Users/Travelmate/workspace/GAME/src/spaceSip/smoke.GIF",187,helicopter.getY()));
for(int x = 0; x < firstUpdates; x++)
smoke.set(x,new SpaceShipImage("C:\\Users/Travelmate/workspace/GAME/src/spaceSip/smoke.GIF",smoke.get(x).getX() - 12, smoke.get(x).getY()));
}
else
{
for(int x = 0; x < numSmoke - 1; x++)
smoke.get(x).setY(smoke.get(x+1).getY());
smoke.set(numSmoke - 1,new SpaceShipImage("C:\\Users/Travelmate/workspace/GAME/src/spaceSip/smoke.GIF",187,helicopter.getY()));
}
}
back.updateImages(middlerecs,helicopter,smoke);
}
}
public void updateRecs()
{
for(int x = 0; x < (NUMRECS - 1); x++) //move all but the last rectangle 1 spot to the left
{
toprecs.set(x,new SpaceShipImage("C:\\Users/Travelmate/workspace/GAME/src/spaceSip/rec2.JPG",RECWIDTH*x,toprecs.get(x+1).getY()));
bottomrecs.set(x,new SpaceShipImage("C:\\Users/Travelmate/workspace/GAME/src/spaceSip/rec2.JPG",RECWIDTH*x,bottomrecs.get(x+1).getY()));
}
}
public void randomDrop()
{
toprecs.get(26).setY(toprecs.get(26).getY() + (463 - bottomrecs.get(26).getY()));
bottomrecs.get(26).setY(463);
}
public int randomMidHeight()
{
int max = 10000;
int min = 0;
for(int x = 0; x < NUMRECS; x++)
{
if(toprecs.get(x).getY() > min)
min = (int)toprecs.get(x).getY();
if(bottomrecs.get(x).getY() < max)
max = (int)bottomrecs.get(x).getY();
}
min += RECHEIGHT;
max -= (RECHEIGHT + min);
return min + (int)(Math.random() * max);
}
//moves the randomly generated middle rectangles
public void updateMiddle()
{
if(middlerecs.get(0).getX() > -1 * RECWIDTH)
{
middlerecs.set(0,new SpaceShipImage("C:\\Users/Travelmate/workspace/GAME/src/spaceSip/asteroid.gif",middlerecs.get(0).getX() - (RECWIDTH/5), middlerecs.get(0).getY()));
middlerecs.set(1,new SpaceShipImage("C:\\Users/Travelmate/workspace/GAME/src/spaceSip/asteroid.gif",middlerecs.get(1).getX() - (RECWIDTH/5), middlerecs.get(1).getY()));
}
else
{
middlerecs.set(0,new SpaceShipImage("C:\\Users/Travelmate/workspace/GAME/src/spaceSip/asteroid.gif",middlerecs.get(1).getX() - (RECWIDTH/5), middlerecs.get(1).getY()));
middlerecs.set(1,new SpaceShipImage("C:\\Users/Travelmate/workspace/GAME/src/spaceSip/asteroid.gif",middlerecs.get(0).getX() + 580,randomMidHeight()));
}
}
public boolean shoot()
{
for(int x = 3; x <= 7; x++)
if(helicopter.getY() >= bottomrecs.get(x).getY())
return true;
for(int y = 3; y <= 7; y++)
if(helicopter.getY() <= toprecs.get(y).getY())
return true;
for(int z = 0; z <= 1; z++)
if(isInMidRange(z))
return true;
return false;
}
public boolean isInMidRange(int num)
{
Rectangle middlecheck = new Rectangle((int)middlerecs.get(num).getX(),(int)middlerecs.get(num).getY(),RECWIDTH,RECHEIGHT);
Rectangle coptercheck = new Rectangle((int)helicopter.getX(),(int)helicopter.getY(),70,48); //asteroid X and y bump
return middlecheck.intersects(coptercheck);
}
public void crash()
{
crashed = true;
if(distance > maxDistance)
{
maxDistance = distance;
save();
}
int reply = JOptionPane.showConfirmDialog(null, " RESTART ?", "GAME OVER", JOptionPane.YES_NO_OPTION);
if(reply == JOptionPane.YES_OPTION)
initiate();
else
System.exit(0);
initiate();
}
//moves the spaceship
public void updateCopter()
{
upCount += .10;
if(goingUp)
{
if(upCount < 3.5)
helicopter.setPosition(XPOS,(double)(helicopter.getY() - (.3 + upCount)));
else
helicopter.setPosition(XPOS,(double)(helicopter.getY() - (1.2 + upCount)));
helicopter.setImage("C:\\Users/Travelmate/workspace/GAME/src/spaceSip/rocketship.GIF");
}
else
{
if(upCount < 1)
helicopter.setPosition(XPOS,(double)(helicopter.getY() + upCount));
else
helicopter.setPosition(XPOS,(double)(helicopter.getY() + (1.2 + upCount)));
helicopter.setImage("C:\\Users/Travelmate/workspace/GAME/src/spaceSip/rocketship.GIF");
}
if(shoot())
crash();
}
//Called when the mouse exits the game window
public void mouseExited(MouseEvent e)
{
paused = true;
}
//Called when the mouse enters the game window
public void mouseEntered(MouseEvent e)
{
}
//Called when the mouse is released
public void mouseReleased(MouseEvent e)
{
goingUp = false;
upCount = -1;
if(paused)
paused = false;
}
//Called when the mouse is pressed
public void mousePressed(MouseEvent e)
{
if (!started)
started = true;
goingUp = true;
upCount = 0;
}
//Called when the mouse is released
public void mouseClicked(MouseEvent e)
{
}
}
package spaceSip;
import java.awt.Image;
import javax.swing.ImageIcon;
public class SpaceShipImage
{
private Image image; //The picture
private double x; //X position
private double y; //Y position
//Construct a new Moving Image with image, x position, and y position given
public SpaceShipImage(Image img, double xPos, double yPos)
{
image = img;
x = xPos;
y = yPos;
}
//Construct a new Moving Image with image (from file path), x position, and y position given
public SpaceShipImage(String path, double xPos, double yPos)
{
this(new ImageIcon(path).getImage(), xPos, yPos);
//easiest way to make an image from a file path in Swing
}
//They are set methods. I don't feel like commenting them.
public void setPosition(double xPos, double yPos)
{
x = xPos;
y = yPos;
}
public void setImage(String path)
{
image = new ImageIcon(path).getImage();
}
public void setY(double newY)
{
y = newY;
}
public void setX(double newX)
{
x = newX;
}
//Get methods which I'm also not commenting
public double getX()
{
return x;
}
public double getY()
{
return y;
}
public Image getImage()
{
return image;
}
}
package spaceSip;
import java.awt.Color;
import java.awt.Dimension;
import java.awt.Font;
import java.awt.Graphics;
import java.awt.Image;
import java.util.ArrayList;
import javax.swing.ImageIcon;
import javax.swing.JPanel;
class SpaceShipPanel extends JPanel
{
private Image background;
private ArrayList<SpaceShipImage> middle;
private SpaceShipImage copter;
private ArrayList<SpaceShipImage> smoke;
//Constructs a new ImagePanel with the background image specified by the file path given
public SpaceShipPanel(String img)
{
this(new ImageIcon(img).getImage());
//The easiest way to make images from file paths in Swing
}
//Constructs a new ImagePanel with the background image given
public SpaceShipPanel(Image img)
{
background = img;
Dimension size = new Dimension(img.getWidth(null), img.getHeight(null));
//Get the size of the image
//Thoroughly make the size of the panel equal to the size of the image
//(Various layout managers will try to mess with the size of things to fit everything)
setPreferredSize(size);
setMinimumSize(size);
setMaximumSize(size);
setSize(size);
middle = new ArrayList<SpaceShipImage>();
smoke = new ArrayList<SpaceShipImage>();
}
//This is called whenever the computer decides to repaint the window
//It's a method in JPanel that I've overwritten to paint the background and foreground images
public void paintComponent(Graphics g)
{
//Paint the background with its upper left corner at the upper left corner of the panel
g.drawImage(background, 0, 0, null);
//Paint each image in the foreground where it should go
for(SpaceShipImage img : middle)
g.drawImage(img.getImage(), (int)(img.getX()), (int)(img.getY()), null);
for(SpaceShipImage img : smoke)
g.drawImage(img.getImage(), (int)(img.getX()), (int)(img.getY()), null);
if(copter != null)
g.drawImage(copter.getImage(), (int)(copter.getX()), (int)(copter.getY()), null);
drawStrings(g);
}
public void drawStrings(Graphics g)
{
g.setColor(Color.WHITE);
g.setFont(new Font("Arial",Font.BOLD,20));
g.drawString("Distance: " + SpaceShipMain.distance,30,440);
g.setFont(new Font("Arial",Font.BOLD,20));
if (SpaceShipMain.distance > SpaceShipMain.maxDistance)
g.drawString("Best: " + SpaceShipMain.distance,650,440);
else
g.drawString("Best: " + SpaceShipMain.maxDistance,650,440);
if(SpaceShipMain.paused)
{
g.setFont(new Font("Chiller",Font.BOLD,72));
g.drawString("Paused",325,290);
g.setFont(new Font("Chiller",Font.BOLD,30));
g.drawString("Click to unpause.",320,340);
}
}
//Replaces the list of foreground images with the one given, and repaints the panel
public void updateImages(ArrayList<SpaceShipImage> newMiddle,SpaceShipImage newCopter,ArrayList<SpaceShipImage> newSmoke)
{
copter = newCopter;
middle = newMiddle;
smoke = newSmoke;
repaint(); //This repaints stuff... you don't need to know how it works
}
}
You compare Strings with equals(value equality) not with ==(reference equality). For more information read this previous question How do I compare strings in Java?
As #AndrewThompson always advice don't use NullLayout
Java GUIs might have to work on a number of platforms, on different
screen resolutions & using different PLAFs. As such they are not
conducive to exact placement of components. To organize the
components for a robust GUI, instead use layout managers, or
combinations of
them1, along
with layout padding & borders for white
space2.
As you say that your gui is blocked, that may be cause some of your execution code takes too more time and it's executed in the same thread as gui stuff (The Event Dispatch Thread). As you have a while(true) that's block the gui so use a SwingTimer for execute repeatidly task or if that code that takes long time execute it in a background thread using a Swing Worker. Here you have a complete example. When you perform custom painting you should override paintComponent and in first line you have to call super.paintComponent(..) to follow correct chaining. Read more in Painting in AWT-Swing.
Another error i see is that you are adding components after calling setVisible(true) without calling revalidate() repaint(). So i recommend to first add components to container then call setVisible(true) at final step.
I am making a JFrame holding several images that refresh using repaint(). The problem, however, was that the more images I added (or as the area that was being rendered increased) the framerate drastically decreased.
I was initially attempting to reduce the lag that Swing's unpredictable Timer experiences, but was unsuccessful. This time, I tried to call
repaint()
every 10 milliseconds based on system time. (To bypass the timer, desktop.screenPaint.drawWindow(); is called instead of repaint())
while(true)
{
long starttime = System.currentTimeMillis();
while(System.currentTimeMillis()-starttime < 10)
{
}
desktop.screenPaint.drawWindow();
desktop2.screenPaint.drawWindow();
}
Each "desktop" is just one of the draggable windows that you see if you run the code below. I noticed that when only "desktop" is added to "frame," there is no flickering. However, when "desktop2" is also added, flickering does not go away until the time until each refresh is set to 20 or more milliseconds. It is extremely strange, because when I was still using the timer, even thought the wait was set to 10 milliseconds, the framerate would lower to a frame every 20 milliseconds! I tested a little and noticed a trend: you will get flickering until the wait time to the amount of time that the 10 millisecond timer lagged behind. My question: Why is this happening? And is there any way to prevent the flickering, other than going back to the timer?
import javax.swing.JFrame;
import javax.swing.*;
import java.awt.*;
import java.awt.event.*;
import java.awt.image.*;
import javax.swing.SwingUtilities.*;
import static java.awt.GraphicsDevice.WindowTranslucency.*;
import java.io.File;
import java.io.IOException;
public class Display extends JPanel
{
public static int width, height;
public static JFrame frame = new JFrame("");
private static int rh = 10;
public static Display desktop = new Display();
public static Display desktop2 = new Display();
public static void main(String[] args)
{
Dimension screen = new Dimension();
screen = java.awt.Toolkit.getDefaultToolkit().getScreenSize();
width = (int)screen.getWidth();
height = (int)screen.getHeight();
frame.setLayout(null);
frame.setLocation(0, 0);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setLayout(null);
desktop.setBounds(0, 0, 620, 500+rh);
desktop2.setBounds(1000, 200, 620, 500+rh);
frame.add(desktop);
frame.add(desktop2);
frame.setUndecorated(true);
frame.setSize(width, height);
frame.setVisible(true);
while(true)
{
long starttime = System.currentTimeMillis();
while(System.currentTimeMillis()-starttime < 10)
{
}
desktop.screenPaint.drawWindow();
//desktop2.screenPaint.drawWindow();
}
}
private BufferedImage image;
private Graphics2D g;
public Listener screenPaint = new Listener();
private Display identify;
public Display()
{
identify = this;
image = new BufferedImage(620, 500+rh, BufferedImage.TYPE_INT_RGB);
g = (Graphics2D)image.getGraphics();
Timer timer = new Timer(1, screenPaint);
timer.start();
addMouseListener(new mMouse());
addMouseWheelListener(new wWheel());
setFocusable(true);
}
private BufferedImage toCompatibleImage(BufferedImage image)
{
GraphicsConfiguration gfx_config = GraphicsEnvironment.
getLocalGraphicsEnvironment().getDefaultScreenDevice().
getDefaultConfiguration();
if (image.getColorModel().equals(gfx_config.getColorModel()))
return image;
BufferedImage new_image = gfx_config.createCompatibleImage(
image.getWidth(), image.getHeight(), image.getTransparency());
}
public void paint(Graphics view)
{
g.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
view.drawImage(toCompatibleImage(image), 0, 0, 620, 500+rh, null);
view.dispose();
}
private class Listener implements ActionListener
{
int y = 0;
int wy = 0;
int b = 500;
int c = 1500;
int iy = (int)(wy/(c/(double)b));
int a = -1;
int i = -1;
int j = -1;
boolean d = false;
boolean u = false;
int f = 0;
public void moveY(int sy)
{
f += sy;
}
public void actionPerformed(ActionEvent e)
{
//drawWindow();
}
public void drawWindow()
{
int lx = (int)(identify.getLocation().getX());
int ly = (int)(identify.getLocation().getY());
g.setColor(Color.white);
g.fillRect(0, 0, 620, 500+rh);
g.drawImage(new ImageIcon("image.png").getImage(), 0, wy+rh, 610, c, null);
if(c > b)
{
if(d || Mouse.withinRect(610+lx, (int)(-wy/(c/(double)b))+rh+ly, 10, (int)Math.ceil(Math.pow(b, 2)/(double)c)))
{
if(Mouse.pressLeft())
{
if(!d)d = true;
if(a == -1)a = Mouse.y()-(int)(-wy/(c/(double)b));
y = (int)((Mouse.y()-a)*(c/(double)b));
f = y;
g.setColor(Color.black);
}
else
{
if(d)d = false;
if(a != -1)a = -1;
g.setColor(new Color(60, 60, 60));
}
}
else
{
g.setColor(Color.gray);
if(a != -1)a = -1;
}
if(y == f){}
else if(y < f)
{
y += (int)((f-y)*0.1);
if(y < f)y++;
}
else
{
y -= (int)((y-f)*0.1);
if(y > f)y--;
}
if(y < 0)
{
y = 0;
f = 0;
}
else if(y > c-b)
{
y = c-b;
f = y;
}
wy = -y;
if(u || Mouse.withinRect(lx, ly, 620, 10))
{
if(Mouse.pressLeft())
{
if(!u)u = true;
if(i == -1)i = Mouse.x()-lx;
if(j == -1)j = Mouse.y()-ly;
identify.setLocation(Mouse.x()-i, Mouse.y()-j);
}
else
{
if(u)u = false;
if(i != -1)i = -1;
if(j != -1)j = -1;
}
}
else
{
if(u)u = false;
if(i != -1)i = -1;
if(j != -1)j = -1;
}
int scrollBarLength = (int)Math.ceil(Math.pow(b, 2)/(double)c);
g.fillRect(610, (int)(-wy/(c/(double)b))+rh, 10, scrollBarLength);
}
else
{
g.setColor(new Color(200, 200, 200));
g.fillRect(610, rh, 10, b);
}
g.setColor(new Color(50, 50, 50));
g.fillRect(0, 0, 620, rh);
if(identify == desktop)
repaint();
else if(false)
{}
}
}
}
public static boolean LMPress, LMRelease = false;
public static boolean LMRight, LMLeft = false;
private class mMouse extends MouseAdapter
{
public void mousePressed(MouseEvent e)
{
LMPress = true; LMRelease = false;
if(SwingUtilities.isRightMouseButton(e))
{
LMRight = true;
LMLeft = false;
}
else if(SwingUtilities.isLeftMouseButton(e))
{
LMLeft = true;
LMRight = false;
}
}
public void mouseReleased(MouseEvent e)
{
LMRelease = true; LMPress = false;
if(SwingUtilities.isRightMouseButton(e))
{
LMRight = true;
LMLeft = false;
}
else if(SwingUtilities.isLeftMouseButton(e))
{
LMLeft = true;
LMRight = false;
}
}
}
private class wWheel implements MouseWheelListener
{
public void mouseWheelMoved(MouseWheelEvent e)
{
int notches = e.getWheelRotation();
if (e.getScrollType() == MouseWheelEvent.WHEEL_UNIT_SCROLL) {}
e.getScrollAmount();
screenPaint.moveY(e.getUnitsToScroll()*60); //desired pixel jump: 120
}
}
}
Mouse class:
import java.awt.*;
import java.awt.event.*;
public class Mouse {
public static int x() {
PointerInfo a = MouseInfo.getPointerInfo();
Point b = a.getLocation();
return (int) b.getX();
}
public static int y() {
PointerInfo a = MouseInfo.getPointerInfo();
Point b = a.getLocation();
return (int) b.getY();
}
public static boolean withinRect(int x, int y, int w, int h) {
if (x() >= x && x() < x + w && y() >= y && y() < y + h) return true;
else return false;
}
public static boolean press() {
return Display.LMPress;
}
public static boolean release() {
return Display.LMRelease;
}
public static boolean pressLeft() {
if (Display.LMPress && Display.LMLeft)
return true;
else return false;
}
public static boolean releaseLeft() {
if (Display.LMRelease && Display.LMLeft)
return true;
else return false;
}
public static boolean pressRight() {
if (Display.LMPress && Display.LMRight)
return true;
else return false;
}
public static boolean releaseRight() {
if (Display.LMRelease && Display.LMRight)
return true;
else return false;
}
}
Updating the view at 1 kHz is unrealistic; instead, consider the alternatives cited here. See this AnimationTest for an example of self-timing to determine your animation budget.
Addendum: The while(true) loop at the top is running at 100 Hz.
The available resolution of System.currentTimeMillis() may vary by platform.
Addendum: I am reopening this question because I was not able to fix it. Any more help?
Absent a Minimal, Complete, Tested and Readable Example, it's hard to say. You appear to be overriding paint(); was noted in Painting in AWT and Swing: The Paint Methods, "Swing programs should override paintComponent()." Moreover, you need to invoke super.paintComponent(), as shown here, to avoid visual artifacts.