Related
For my class I need to create a one player pong game. We need to use what we've learned so its simple code and the problem is, while the "while loop" is running, my Keydown thread doesn't seem to work. My teacher isn't helpful at all so that's why i'm here. Please help by only using methods and such that are used in my program.
I've tried moving the ball code into a run thread but i can never seem to actually get that thread running.
public class PongGame extends Applet {
int startup = 0;
int x = 400;
int y = 500;
int x2 = (int) (Math.random() * (600 + 1));
int y2 = (int) (Math.random() * (600 + 1));
int xVelocity = 1;
int yVelocity = 1;
int x2Velocity = 1;
int y2Velocity = 1;
int curry = 700;
int currx = 600;
int counter = 2;
#Override
public void init() {
setSize(1440, 900);
setBackground(Color.black);
setFont(new Font("Helvetica", Font.BOLD, 36));
}
#Override
public boolean keyDown(Event evt, int key) {
startup = startup + 1;
repaint();
if (key == Event.RIGHT) {
currx += 10;
}
if (key == Event.LEFT) {
currx -= 10;
}
if (currx == 1400) {
currx = 10;
}
if (currx == 20) {
currx = 1399;
}
repaint();
return false;
}
public void run(Graphics g) {
startup = 0;
while (counter > 0) {
try {
Thread.sleep(30);
} catch (InterruptedException e) {
}
x += xVelocity;
y += yVelocity;
g.setColor(Color.blue);
g.fillRect(currx, curry, 300, 25);
g.setColor(Color.red);
g.fillOval(x, y, 30, 30);
for (int j = 0; j < 20000000; j++);
g.setColor(Color.black);
g.fillOval(x, y, 30, 30);
//Bounce the ball off the wall or paddle
if (x >= 1400 || x <= 0) {
xVelocity = -xVelocity;
}
if (y >= 800 || y <= 0) {
yVelocity = -yVelocity;
}
if (((y == 675)) && ((currx <= x) && (currx + 300) >= x)) {
yVelocity = -yVelocity;
y = y - 10;
repaint();
}
}
}
public void paint(Graphics g) {
if (startup == 0) {
g.setColor(Color.white);
g.drawString("Welcome To PONG", 0, 100);
g.drawString("Created by Caden Anton", 0, 200);
g.drawString("copyright May 3rd, 2019 ©", 0, 300);
g.drawString("Press any key to continue", 0, 400);
}
if (startup == 1) {
g.setColor(Color.white);
g.drawString("RULES:", 0, 100);
g.drawString("Press the arrwow keys to move the paddle", 0, 200);
g.drawString("Your objective is to keep the ball from touching the ground", 0, 300);
g.drawString("Once the ball hits the ground you lose the game", 0, 400);
}
if (startup >= 2) {
//Input Run thread start here.
}
}
}
This is my first time trying to build a GUI and I've reached an impasse which I can't seem to find the solution to. Currently I have parts of my GUI set up but I want to insert a graph I've created on another class, however, I'm not sure how to link it with my current JFrame. I can get it to work as a separate entity, but not together.
MainDisplay Class:
public static void main(String args[]) {
/* Set the Nimbus look and feel */
//<editor-fold defaultstate="collapsed" desc=" Look and feel setting code (optional) ">
/* If Nimbus (introduced in Java SE 6) is not available, stay with the default look and feel.
* For details see http://download.oracle.com/javase/tutorial/uiswing/lookandfeel/plaf.html
*/
try {
for (javax.swing.UIManager.LookAndFeelInfo info : javax.swing.UIManager.getInstalledLookAndFeels()) {
if ("Nimbus".equals(info.getName())) {
javax.swing.UIManager.setLookAndFeel(info.getClassName());
break;
}
}
} catch (ClassNotFoundException ex) {
java.util.logging.Logger.getLogger(MainDisplay.class.getName()).log(java.util.logging.Level.SEVERE, null, ex);
} catch (InstantiationException ex) {
java.util.logging.Logger.getLogger(MainDisplay.class.getName()).log(java.util.logging.Level.SEVERE, null, ex);
} catch (IllegalAccessException ex) {
java.util.logging.Logger.getLogger(MainDisplay.class.getName()).log(java.util.logging.Level.SEVERE, null, ex);
} catch (javax.swing.UnsupportedLookAndFeelException ex) {
java.util.logging.Logger.getLogger(MainDisplay.class.getName()).log(java.util.logging.Level.SEVERE, null, ex);
}
//</editor-fold>
//</editor-fold>
/* Create and display the form */
java.awt.EventQueue.invokeLater(new Runnable() {
public void run() {
new MainDisplay().setVisible(true);
}
});
float LvBTC;
float LvLTC;
float LvETH;
float[] HBTC;
float[] HLTC;
float[] HETH;
float CurETH;
float CurBTC;
float CurLTC;
WebScraper WS1 = new WebScraper();
LvBTC = WS1.LvScrapeBTC();
LvLTC = WS1.LvScrapeLTC();
LvETH = WS1.LvScrapeETH();
HBTC = WS1.HScrapeBTC();
HLTC = WS1.HScrapeLTC();
HETH = WS1.HScrapeETH();
System.out.println("Bitcoin's Current Price is: $"+LvBTC);
System.out.println("Litecoin's Current Price is: $"+LvLTC);
System.out.println("Ethereum's Current Price is: $"+LvETH);
Graph G1 = new Graph();
G1.CurrentValues(HBTC);
for (int i = 0; 5 > i;) {
System.out.println("Day " + (i + 1) + ": $" + G1.CurValues[i]);
i++;
}
System.out.println("Index of largest value: " + G1.IndexLarge(G1.CurValues));
System.out.println("Index of smallest value: " + G1.IndexSmall(G1.CurValues));
Graph Graphing = new Graph();
}
Graph Class:
package comsci_ia;
import java.awt.Color;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.Point;
import java.util.ArrayList;
import java.util.Arrays;
import javax.swing.JFrame;
public class Graph extends JFrame {
int IndexL;
int IndexS;
int DistanceDay1;
int DistanceDay2;
int DistanceDay3;
int DistanceDay4;
int DistanceDay5;
float[] CurValues = new float[5];
ArrayList<Point> points = new ArrayList<>();
public float[] CurrentValues(float[] array) {
DatabaseBrowser DB1 = new DatabaseBrowser();
WebScraper WS1 = new WebScraper();
float[] HBTC = WS1.HScrapeBTC();
float[] HETH = WS1.HScrapeETH();
float[] HLTC = WS1.HScrapeLTC();
float CurHold = 0;
boolean BTCCheck = false;
BTCCheck = Arrays.equals(HBTC, array);
boolean LTCCheck = false;
LTCCheck = Arrays.equals(HLTC, array);
boolean ETHCheck = false;
ETHCheck = Arrays.equals(HETH, array);
if (BTCCheck == true) {
CurHold = DB1.RetriveBTC();
}
if (LTCCheck == true) {
CurHold = DB1.RetriveLTC();
}
if (ETHCheck == true) {
CurHold = DB1.RetriveETH();
}
float pick;
for (int i = 0; 5 > i;) {
for (int z = 0; z < array.length; z++) {
pick = array[z];
pick = pick * CurHold;
CurValues[i] = pick;
i++;
}
}
return CurValues;
}
public int IndexLarge(float[] array) {
float temp = 0;
for (int i = 0; 5 > i;) { //Cycles through ArrayList and replaces temp with the Largest value
if (array[i] > temp) {
temp = array[i];
}
i++;
}
int IndexCheck = 0; //Searches and records the index of "temp" value (Largest value in array)
for (IndexCheck = 0; 5 > IndexCheck;) {
if (array[IndexCheck] == temp) {
break;
}
IndexCheck++;
}
IndexL = IndexCheck;
return IndexL;
}
public int IndexSmall(float[] array) {
float temp = 1000000;
for (int i = 0; 5 > i;) { //Cycles through ArrayList and replaces temp with the smallest value
if (array[i] < temp) {
temp = array[i];
}
i++;
}
int IndexCheck = 0; //Searches and records the index of "temp" value (smallest value in array)
for (IndexCheck = 0; 5 > IndexCheck;) {
if (array[IndexCheck] == temp) {
break;
}
IndexCheck++;
}
IndexS = IndexCheck;
return IndexS;
}
public void Plotter(float[] array) {
/* int DayRefL = IndexL + 1;
int DayRefS = IndexS + 1; */
float ValRange;
float ValPx;
points = null;
ValRange = array[IndexL] - array[IndexS];
ValPx = (300f/ ValRange); //Number is the pixel distance between highest and lowest values
DistanceDay1 = (int) ((int) 50 + ((array[IndexL] - array[0]) * ValPx));
DistanceDay2 = (int) ((int) 50 + ((array[IndexL] - array[1]) * ValPx));
DistanceDay3 = (int) ((int) 50 + ((array[IndexL] - array[2]) * ValPx));
DistanceDay4 = (int) ((int) 50 + ((array[IndexL] - array[3]) * ValPx));
DistanceDay5 = (int) ((int) 50 + ((array[IndexL] - array[4]) * ValPx));
}
public void paintComponent(Graphics g) {
Graphics2D g2 = (Graphics2D) g;
int DotSize = 10;
int width = g2.getFontMetrics().stringWidth("Today");
int middle = width / 2;
g2.setColor(Color.BLACK);
/* g2.drawLine(10, 10, 10, 410); //Frame Boundaries
g2.drawLine(410, 10, 10, 10); //Frame Boundaries
g2.drawLine(410, 10, 410, 410); //Frame Boundaries
g2.drawLine(410, 410, 10, 410); //Frame Boundaries */
//Axis
g2.drawLine(30, 30, 30, 370);
g2.drawLine(370, 370, 30, 370);
//Points & Connections
PlotPoints(g2, 98, DistanceDay1, DotSize);
g2.drawLine(98, DistanceDay1, 166, DistanceDay2);
PlotPoints(g2, 166, DistanceDay2, DotSize);
g2.drawLine(166, DistanceDay2, 234, DistanceDay3);
PlotPoints(g2, 234, DistanceDay3, DotSize);
g2.drawLine(234, DistanceDay3, 302, DistanceDay4);
PlotPoints(g2, 302, DistanceDay4, DotSize);
g2.drawLine(302, DistanceDay4, 370, DistanceDay5);
PlotPoints(g2, 370, DistanceDay5, DotSize);
//Labels
g2.drawString("Today", 370 - middle, 390);
/* g2.drawString("Test", 98 - middle, 40);
g2.drawString("Test", 146, 25); */
}
private void PlotPoints(Graphics2D g, int x, int y, int r) {
x = x - (r / 2);
y = y - (r / 2);
g.fillOval(x, y, r, r);
}
}
If I run the Graph class as a separate entity it'll result in this: Graph pop-up
Here's a separate version of the Graph code in which a frame will pop up displaying the graph:
package graphing;
import java.awt.Color;
import java.awt.Graphics;
import java.awt.Graphics2D;
import javax.swing.JFrame;
import javax.swing.JPanel;
public class Graphing extends JPanel {
#Override
public void paintComponent(Graphics g) {
Graphics2D g2 = (Graphics2D) g;
int DotSize = 10;
int width = g2.getFontMetrics().stringWidth("Test");
int middle = width / 2;
g2.setColor(Color.BLACK);
g2.drawLine(10, 10, 10, 390); //Frame Boundaries
g2.drawLine(390, 10, 10, 10); //Frame Boundaries
g2.drawLine(390, 10, 390, 390); //Frame Boundaries
g2.drawLine(390, 390, 10, 390); //Frame Boundaries
//Axis
g2.drawLine(30, 30, 30, 370);
g2.drawLine(370, 370, 30, 370);
//Points & Connections
PlotPoints(g2, 98, 55, DotSize);
g2.drawLine(98, 55, 166, 40);
PlotPoints(g2, 166, 40, DotSize);
g2.drawLine(166, 40, 234, 100);
PlotPoints(g2, 234, 100, DotSize);
g2.drawLine(234, 100, 302, 332);
PlotPoints(g2, 302, 332, DotSize);
g2.drawLine(302, 332, 370, 40);
PlotPoints(g2, 370, 40, DotSize);
//Labels
g2.drawString("Test", 98 - middle, 40);
g2.drawString("Test", 146, 25);
}
private void PlotPoints(Graphics2D g, int x, int y, int r) {
x = x - (r / 2);
y = y - (r / 2);
g.fillOval(x, y, r, r);
}
public static void main(String[] args) {
JFrame frame = new JFrame();
frame.setSize(420, 420);
frame.setLocationRelativeTo(null);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
Graphing app = new Graphing();
frame.setContentPane(app);
frame.setVisible(true);
frame.invalidate();
}
}
So, my immediate issue is, you're extending from JFrame, which isn't a good, as this locks the UI into in a single use case (it's not easily re-usable)
My second issue is, you've created a method called paintComponent in JFrame, but since JFrame doesn't use this style of painting, it is never called
So, the first thing I would do is change Graph so it extends from JPanel instead...
public class Graph extends JPanel {
//...
I would then update your paintComponent so it supports the painting process properly...
#Overrride
protected void paintComponent(Graphics g) {
super.paintComponent(g);
Graphics2D g2 = (Graphics2D) g;
//...
Now, the next problem is, you're going to need to provide some sizing hints so that the layout manager of the container you add it to has some idea about how best to layout the component...
#Override
public Dimension getPreferredSize() {
// I've not been through your code in detail
// so I've not calculated what the actual
// preferred size might be and this is just an
// example you'll have to update
return new Dimension(200, 200);
}
Now, you can create an instance of Graph and add it to what ever container you want
Ok so I am very new to Java Swing and a beginner in Java in general. My current problem is I have designed a "cityscape". I am working on a UFO flying around, but my randomly generated buildings continue to get regenerated. I am wondering if there is a way to save my instance of buildings to an ArrayList as I have attempted, and paint that selection from that list each time paint is called. I tried what I thought of and I believe it just crashed it when run, because it didn't even open a JFrame and instead produced errors upon errors. Here is what I have:
CityScape class (the main class):
import java.awt.*;
import javax.swing.*;
public class CityScape extends JPanel
{
Buildings a = new Buildings ();
UFO b = new UFO();
#Override
public void paint (Graphics g)
{
//RememberBuildings.buildingList.get(1).paint(g);
a.paint(g);
b.paint(g);
}
public void move()
{
b.move();
}
public static void main(String[] args) throws InterruptedException
{
JFrame frame = new JFrame("Frame");
CityScape jpe = new CityScape();
frame.add(jpe);
frame.setSize(800, 750);
frame.setBackground(Color.BLACK);
frame.setLocationRelativeTo(null);
frame.setVisible(true);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
System.out.println(frame.getContentPane().getSize());
while (true)
{
jpe.move(); //Updates the coordinates
jpe.repaint(); //Calls the paint method
Thread.sleep(10); //Pauses for a moment
}
}
}
Buildings class (the class that generates the buildings):
import java.awt.*;
public class Buildings
{
private int maxX = 784;
private int maxY = 712;
private int width = (int)(Math.random()*100+100);
private int height = (int)(Math.random()*350+100);
private int rows = Math.round((height)/25);
private int columns = Math.round(width/25);
public void addBuilding()
{
RememberBuildings.addBuilding();
}
public void paint(Graphics g)
{
Graphics2D g2d = (Graphics2D) g;
Color transYellow = new Color (255, 255, 0, 59);
g2d.setColor(Color.BLACK);
g2d.fillRect(0, 0, maxX, maxY);
g2d.setColor(Color.WHITE);
g2d.fillRect(5, 5, 25, 25);
int a = 0;
for (int i =10; i<634; i+=(a+10))//buildings
{
g2d.setColor(Color.GRAY);
g2d.drawRect(i, maxY-height, width, height);
g2d.fillRect(i, maxY-height, width, height);
rows = Math.round((height)/25);
columns = Math.round(width/25);
for (int j = 1; j<=columns; j++)//windows
{
for (int k = 1; k<=rows; k++)
{
g2d.setColor(Color.BLACK);
g2d.drawRect(i+5*j+20*(j-1), (maxY-height)+5*k+20*(k-1), 20, 20);
if (Math.random()<0.7)
{
g2d.setColor(Color.YELLOW);
g2d.fillRect(i+5*j+20*(j-1), (maxY-height)+5*k+20*(k-1), 20, 20);
}
else
{
g2d.setColor(Color.BLACK);
g2d.fillRect(i+5*j+20*(j-1), (maxY-height)+5*k+20*(k-1), 20, 20);
g2d.setColor(transYellow);
g2d.fillRect(i+5*j+20*(j-1), (maxY-height)+5*k+20*(k-1), 20, 20);
}
}
}
addBuilding();
a = width;
height = (int)(Math.random()*462+100);
width = (int)(Math.random()*100+100);
}
}
}
RememberBuildings class (the point of this is to add an instance to an ArrayList):
import java.util.*;
public class RememberBuildings
{
public static ArrayList<Buildings> buildingList = new ArrayList<Buildings>();
public static void addBuilding()
{
buildingList.add(new Buildings());
}
}
And finally my UFO class (creates the UFO flying by):
import java.awt.*;
import javax.swing.*;
public class UFO extends JPanel
{
private int x = 20; //x and y coordinates of the ball
private int y = 20;
private int xa = 1;
public void move() //Increase both the x and y coordinates
{
if (x + xa < 0) {
xa = 1;
}
if (x + xa > 784-75)
{
xa = -1;
}
x = x + xa;
}
public void paint(Graphics g)
{
super.paint(g); //Clears the panel, for a fresh start
Graphics2D g2d = (Graphics2D) g;
g2d.setColor(Color.LIGHT_GRAY);
g2d.fillOval(x,y,75,25); //Draw the ball at the desired point
}
}
Avoid overriding paint, use paintComponent instead. Always call the super paint method before you do any custom painting to ensure that the paint chain is maintained. See Painting in AWT and Swing and Performing Custom Painting for more details
Beware, Swing is not thread safe and it's unwise to update any component (or any variable that a component may rely on) from outside the context of the Event Dispatching Thread. A simple solution might be to use a Swing Timer instead of a while (true) loop and Thread.sleep. See How to use Swing Timers for more details.
You should also only create and modify UI components from within the context of the event dispatching thread, see Initial Threads for more details
If you have a problem with your code not working, you should consider providing a runnable example which demonstrates your problem. This is not a code dump, but an example of what you are doing which highlights the problem you are having. This will result in less confusion and better responses. Providing code which is not runnable and is missing classes makes it difficult to know why it's not working and how to fix it.
A few things here:
To address the paintComponent note and view an example, check out this other thread: Concerns about the function of JPanel: paintcomponent()
There seems to be a bit of a disconnect between the logic you've got going and the object-oriented programming logic that I think will help sort things out (for general info on OOP: https://en.wikipedia.org/wiki/Object-oriented_programming):
What You've Got:
The Structure you've got going is as follows:
CityScape :: here's where you've extended JPanel and setup the main function
UFO :: an object class that represents 1 UFO
Building :: a class that has methods for drawing randomized buildings and calling methods in RememberBuildings
RememberBuildings :: I think this is intended to track buildings that have been drawn
The issue here is that your Building class's paint method continually draws multiple newly randomized buildings instead of a set building that retains its structure.
My Suggestion:
There are plenty of solutions to this issue and different ways to implement each solution, but my recommendation is to remodel your Building class in an OOP fashion, meaning that it would represent 1 single building (truer to the name of the class). This would contain a constructor that initializes all of the randomized dimensions of that single building once and draws that single building on the jpanel. Then you would need to keep an array or list of some sort in the cityscape that contains buildings that are part of the cityscape, eliminating the need for a "RememberBuildings" class. so roughly:
CityScape extends JPanel:
variables:
Building[] buildings; //might be useful to use an arraylist/stack/queue instead of an array depending on implementation
UFO craft;
constructor:
setup new Building objects and add to list buildings
initialize craft to new UFO
paintComponent:
calls the paint methods for each building & the ufo craft
Building:
variables:
int x, y; // position of building
int height, width; // of this building
constructor:
initializes x, y // probably needs to be inputed from CityScape with this setup
calc height and width randomly // stored in this.height/width
paint:
paints single building based on it's variables
//side-note, you'll probably need getters for the x/y/width to build each building from CityScape
Everything else should be much the same.
Good Luck !
So, every time Buildings#paint is called, it regenerates all the builds, which is done randomly.
public void paint(Graphics g) {
Graphics2D g2d = (Graphics2D) g;
Color transYellow = new Color(255, 255, 0, 59);
g2d.setColor(Color.BLACK);
g2d.fillRect(0, 0, maxX, maxY);
g2d.setColor(Color.WHITE);
g2d.fillRect(5, 5, 25, 25);
int a = 0;
for (int i = 10; i < 634; i += (a + 10))//buildings
{
g2d.setColor(Color.GRAY);
g2d.drawRect(i, maxY - height, width, height);
g2d.fillRect(i, maxY - height, width, height);
rows = Math.round((height) / 25);
columns = Math.round(width / 25);
for (int j = 1; j <= columns; j++)//windows
{
for (int k = 1; k <= rows; k++) {
g2d.setColor(Color.BLACK);
g2d.drawRect(i + 5 * j + 20 * (j - 1), (maxY - height) + 5 * k + 20 * (k - 1), 20, 20);
if (Math.random() < 0.7) {
g2d.setColor(Color.YELLOW);
g2d.fillRect(i + 5 * j + 20 * (j - 1), (maxY - height) + 5 * k + 20 * (k - 1), 20, 20);
} else {
g2d.setColor(Color.BLACK);
g2d.fillRect(i + 5 * j + 20 * (j - 1), (maxY - height) + 5 * k + 20 * (k - 1), 20, 20);
g2d.setColor(transYellow);
g2d.fillRect(i + 5 * j + 20 * (j - 1), (maxY - height) + 5 * k + 20 * (k - 1), 20, 20);
}
}
}
addBuilding();
a = width;
height = (int) (Math.random() * 462 + 100);
width = (int) (Math.random() * 100 + 100);
}
}
There's two ways you might be able to solve this, which you use will depend on what you want to achieve. You could render the buildings directly to a BufferedImage and simply paint that on each paint cycle or you could cache the information you need in order to re-create the buildings.
The BufferedImage approach is quicker, but can't be animated, so if you want to animate the buildings in some way (make the lights flicker), you will need to build up a series of information which allows you to simply repaint them.
I'm going for the second, as you've asked about painting assets from a ArrayList.
I started by translating your "paint" code into a single concept of a virtual building, which has also has information about it's own lights.
public class Building {
protected static final Color TRANS_YELLOW = new Color(255, 255, 0, 59);
private int x, y, width, height;
private List<Light> lights;
public Building(int x, int y, int width, int height) {
this.x = x;
this.y = y;
this.width = width;
this.height = height;
lights = new ArrayList<>(25);
int rows = Math.round((height) / 25);
int columns = Math.round(width / 25);
for (int j = 1; j <= columns; j++)//windows
{
for (int k = 1; k <= rows; k++) {
Color color = null;
if (Math.random() < 0.7) {
color = Color.YELLOW;
} else {
color = TRANS_YELLOW;
}
lights.add(new Light(x + 5 * j + 20 * (j - 1), y + 5 * k + 20 * (k - 1), color));
}
}
}
public void paint(Graphics2D g2d) {
g2d.setColor(Color.GRAY);
g2d.drawRect(x, y, width, height);
g2d.fillRect(x, y, width, height);
for (Light light : lights) {
light.paint(g2d);
}
}
public class Light {
private int x, y;
private Color color;
public Light(int x, int y, Color color) {
this.x = x;
this.y = y;
this.color = color;
}
public void paint(Graphics2D g2d) {
g2d.setColor(Color.BLACK);
g2d.fillRect(x, y, 20, 20);
g2d.setColor(color);
g2d.fillRect(x, y, 20, 20);
}
}
}
This allows you to generate the primary parameters for the Building and simple cache the results and when needed, simply paint it.
For example...
public class Buildings {
private int maxX = 784;
private int maxY = 712;
private List<Building> buildings;
public Buildings() {
buildings = new ArrayList<>(25);
for (int i = 10; i < 634; i += 10)//buildings
{
int width = (int) (Math.random() * 100 + 100);
int height = (int) (Math.random() * 350 + 100);
int x = i;
int y = maxY - height;
buildings.add(new Building(x, y, width, height));
}
}
public void paint(Graphics g) {
Graphics2D g2d = (Graphics2D) g;
for (Building building : buildings) {
building.paint(g2d);
}
}
}
I also changed your UFO class so it no longer extends from JPanel, as it just doesn't need to and is probably the primary cause of confusion with your painting.
I then updated your paint method in your CityScape to use paintComponent instead...
public class CityScape extends JPanel {
Buildings a = new Buildings();
UFO b = new UFO();
#Override
protected void paintComponent(Graphics g) {
super.paintComponent(g);
a.paint(g);
b.paint(g);
}
As a runnable example...
import java.awt.Color;
import java.awt.EventQueue;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.util.ArrayList;
import java.util.List;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.Timer;
import javax.swing.UIManager;
import javax.swing.UnsupportedLookAndFeelException;
public class CityScape extends JPanel {
Buildings a = new Buildings();
UFO b = new UFO();
#Override
protected void paintComponent(Graphics g) {
super.paintComponent(g); //To change body of generated methods, choose Tools | Templates.
a.paint(g);
b.paint(g);
}
public void move() {
b.move();
}
public static void main(String[] args) throws InterruptedException {
EventQueue.invokeLater(new Runnable() {
#Override
public void run() {
try {
UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
} catch (ClassNotFoundException | InstantiationException | IllegalAccessException | UnsupportedLookAndFeelException ex) {
ex.printStackTrace();
}
JFrame frame = new JFrame("Frame");
CityScape jpe = new CityScape();
frame.add(jpe);
frame.setSize(800, 750);
frame.setBackground(Color.BLACK);
frame.setLocationRelativeTo(null);
frame.setVisible(true);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
System.out.println(frame.getContentPane().getSize());
Timer timer = new Timer(10, new ActionListener() {
#Override
public void actionPerformed(ActionEvent e) {
jpe.move(); //Updates the coordinates
jpe.repaint(); //Calls the paint method
}
});
timer.start();
}
});
}
public class Buildings {
private int maxX = 784;
private int maxY = 712;
private List<Building> buildings;
public Buildings() {
buildings = new ArrayList<>(25);
for (int i = 10; i < 634; i += 10)//buildings
{
int width = (int) (Math.random() * 100 + 100);
int height = (int) (Math.random() * 350 + 100);
int x = i;
int y = maxY - height;
buildings.add(new Building(x, y, width, height));
}
}
public void paint(Graphics g) {
Graphics2D g2d = (Graphics2D) g;
for (Building building : buildings) {
building.paint(g2d);
}
}
}
public static class Building {
protected static final Color TRANS_YELLOW = new Color(255, 255, 0, 59);
private int x, y, width, height;
private List<Light> lights;
public Building(int x, int y, int width, int height) {
this.x = x;
this.y = y;
this.width = width;
this.height = height;
lights = new ArrayList<>(25);
int rows = Math.round((height) / 25);
int columns = Math.round(width / 25);
for (int j = 1; j <= columns; j++)//windows
{
for (int k = 1; k <= rows; k++) {
Color color = null;
if (Math.random() < 0.7) {
color = Color.YELLOW;
} else {
color = TRANS_YELLOW;
}
lights.add(new Light(x + 5 * j + 20 * (j - 1), y + 5 * k + 20 * (k - 1), color));
}
}
}
public void paint(Graphics2D g2d) {
g2d.setColor(Color.GRAY);
g2d.drawRect(x, y, width, height);
g2d.fillRect(x, y, width, height);
for (Light light : lights) {
light.paint(g2d);
}
}
public class Light {
private int x, y;
private Color color;
public Light(int x, int y, Color color) {
this.x = x;
this.y = y;
this.color = color;
}
public void paint(Graphics2D g2d) {
g2d.setColor(Color.BLACK);
g2d.fillRect(x, y, 20, 20);
g2d.setColor(color);
g2d.fillRect(x, y, 20, 20);
}
}
}
public class UFO {
private int x = 20; //x and y coordinates of the ball
private int y = 20;
private int xa = 1;
public void move() //Increase both the x and y coordinates
{
if (x + xa < 0) {
xa = 1;
}
if (x + xa > 784 - 75) {
xa = -1;
}
x = x + xa;
}
public void paint(Graphics g) {
Graphics2D g2d = (Graphics2D) g;
g2d.setColor(Color.LIGHT_GRAY);
g2d.fillOval(x, y, 75, 25); //Draw the ball at the desired point
}
}
}
This is my code:
import java.awt.*;
import java.awt.event.*;
import java.util.*;
import javax.swing.*;
public class Draw extends JComponent implements KeyListener {
Random r = new Random();
int x = 0;
int y = 0;
int a = 5 * r.nextInt(150);
int b = 5 * r.nextInt(90);
Image img1 = Toolkit.getDefaultToolkit().getImage("C:/Users/Administrator/eclipse/My Projects/Game/src/bluebackground1.png");
public Draw(){
addKeyListener(this);
setFocusable(true);
}
//display
public void paint(Graphics g){
g.drawImage(img1, 0, 0, this);
g.setColor(Color.CYAN);
g.fill3DRect(x, y, 50, 50, true);
g.setColor(Color.RED);
g.draw3DRect(a, b, 50, 50, true);
g.setColor(Color.BLACK);
g.drawLine(0, 500, 800, 500);
g.setColor(Color.BLACK);
g.drawString("Press R to restart the game", 10, 540);
g.drawString("Use arrow keys to move", 600, 540);
if(x == a && y == b){
g.setColor(Color.BLACK);
g.setFont(new Font("", Font.PLAIN, 50));
g.drawString("Victory", 300, 550);
}
}
//controls
public void keyPressed(KeyEvent k) {
if(k.getKeyCode() == KeyEvent.VK_UP){
y -= 5;
} else if(k.getKeyCode() == KeyEvent.VK_DOWN){
y += 5;
} else if(k.getKeyCode() == KeyEvent.VK_LEFT){
x -= 5;
} else if(k.getKeyCode() == KeyEvent.VK_RIGHT){
x += 5;
}
if(k.getKeyCode() == KeyEvent.VK_R){
restart();
}
//border
if(x < 0){
x += 5;
} else if(x > 745){
x -= 5;
} else if(y < 0){
y += 5;
} else if (y > 450){
y -= 5;
}
repaint();
}
public void keyReleased(KeyEvent k) {}
public void keyTyped(KeyEvent k) {}
//restart function
public void restart(){
x = 0;
y = 0;
a = 5 * r.nextInt(150);
b = 5 * r.nextInt(90);
}
}
What I want is when the cyan rectangle which is moveable gets inside the red rectangle which is not moveable the red rectangle disappears permanently because the game is not over and the cyan rectangle will have to move more.
How do I remove the red rectangle when it collides with the cyan one?
Store Shape instances in a List. At time of painting, iterate the list and draw each one. When one shape is removed, remove it from the list and call repaint().
Paint components with paintComponent(Graphics g) where g is a local variable. my problem is whenever i do this it gives my a nullPointerException! i want to be able to output new data later on with another method so i need to stor it as a boject that can be changed later.
Map() {
setPreferredSize(new Dimension(500, 500));
makeMap();
}
public void paintComponent(Graphics g) {
super.paintComponent(g);
for (int x = 25; x <= 500; x += 25) {
for (int y = 25; y <= 500; y += 25) {
g.drawRect(0, 0, x, y);
}
}
for (int i = 2; i <= 399; i++) {
int rand = (int) ((Math.random() * (7)) + 1);
if (rand == 1) {
space = i;
// System.out.println(space);
int x = 0;
int y = 0;
space -= 1;
if ((space / 20.0) >= 1.0) {
x = space % 20;
y = space / 20;
x *= 25;
y *= 25;
g.setColor(Color.BLACK);
g.fillRect(x, y, 25, 25);
} else {
y = space;
y *= 25;
g.setColor(Color.BLACK);
g.fillRect(y, 0, 25, 25);
}
mapInfo.put(i, 1);
}
if ((rand == 2) || (rand == 3)) {
mapInfo.put(i, 2);
} else if (rand == 4) {
mapInfo.put(i, 3);
} else {
mapInfo.put(i, 0);
}
}
mapInfo.put(1, 1234);
mapInfo.put(400, 1234);
}
public void makeMap() {
frame = new JFrame();
panel = new JPanel();
frame.getContentPane().add(panel);
frame.pack();
frame.setVisible(true);
frame.setTitle("MAP");
frame.setBounds(600, 0, 516, 538);
frame.setResizable(false);
panel.setLayout(new BorderLayout());
panel.add(this);
}
public void blockSpace(int space) {
}
public int getEvent(int space) {
return mapInfo.get(space);
}
public static void setPlayerPos() {
g.setColor(Color.BLUE);
g.fillRect(475, 475, 25, 25);
}
}