How do you make a java single player version of agario? I would like to use Object Oriented Programming. So there should be Dot, Blob, and a Controller Object.
(I just want to share my code so don't vote down :)
I made it this way. There is the dots with random color, blob that starts as 20 size. A thread check every couple milliseconds for collision.
Dot:
package agario;
import java.awt.Color;
import java.awt.Component;
import java.awt.Graphics;
import java.util.Random;
public class Dot extends Component{
public int x;
public int y;
public Color c;
public int size;
Dot(int x, int y){
this.x = x;
this.y = y;
Random rand = new Random();
int r = rand.nextInt(255);
int green = rand.nextInt(255);
int b = rand.nextInt(255);
this.c = new Color(r,green,b);
this.size = rand.nextInt(50);
}
public void paint(Graphics g){
g.setColor(c);
g.fillOval(this.x, this.y, this.size, this.size);
}
}
Blob:
package agario;
import java.awt.Color;
import java.awt.Component;
import java.awt.Graphics;
public class Blob extends Component{
public int x;
public int y;
public int size;
public Color color;
public static Blob blob = new Blob(800,100,40,Color.blue);
Blob(int x, int y, int size, Color c){
this.x = x;
this.y = y;
this.size = size;
this.color = c;
}
public void paint(Graphics g){
g.setColor(color);
g.fillOval(x, y, size, size);
}
}
Controller:
package agario;
import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Frame;
import java.awt.Graphics;
import java.awt.Label;
import java.awt.Rectangle;
import java.awt.event.MouseEvent;
import java.awt.event.MouseMotionAdapter;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.Random;
public class Controller {
ArrayList<Blob> blobs = new ArrayList<Blob>();
public ArrayList<Dot> dots = new ArrayList<Dot>();
Blob b = new Blob(50,50,10,Color.CYAN);
MyFrame mf = new MyFrame("Agario");
Label l = new Label("10");
int mouseX = 0;
int mouseY = 0;
static int score = 30;
static int xDis = 0;
static int yDis = 0;
public static void main(String[] args){
new Controller().startGame();
}
public void startGame(){
mf.addMouseMotionListener(new MyMouseMoveListener());
mf.add(l,BorderLayout.NORTH);
Refresh rf = new Refresh();
Thread t = new Thread(rf);
t.start();
while(true){
try{
Random r = new Random();
Thread.sleep(r.nextInt(40));
double dis = Math.sqrt(xDis*xDis + yDis*yDis);
double easingAmount = 20;
b.x += xDis / easingAmount;
b.y += yDis / easingAmount;
if(r.nextInt(10) == 5){
int randX = r.nextInt(600);
int randY = r.nextInt(600);
Dot d = new Dot(randX,randY);
synchronized(dots){
dots.add(d);
}
mf.add(d);
mf.repaint();
}
}catch(Exception e){
}
}
}
class Refresh implements Runnable{
public void run() {
while(true){
Random ran = new Random();
try{
Thread.sleep(ran.nextInt(20));
}catch(Exception e){
System.out.println("error");
}
Rectangle r = new Rectangle(b.x,b.y,b.size,b.size);
synchronized(dots){
Iterator i = dots.iterator();
while(i.hasNext()){
Dot d = (Dot) i.next();
Rectangle r1 = new Rectangle(d.x,d.y,d.size,d.size);
if(r1.intersects(r)){
i.remove();
b.size += 1;
l.setText(String.valueOf(Integer.parseInt(l.getText())+1));
score += 1;
}
}
}
mf.repaint();
}
}
}
class MyMouseMoveListener extends MouseMotionAdapter{
public void mouseMoved(MouseEvent m){
mouseX = m.getX();
mouseY = m.getY();
xDis = mouseX-b.x;
yDis = mouseY-b.y;
}
}
class MyFrame extends Frame{
MyFrame(String s){
super(s);
setBounds(0,0,900,900);
add(b);
blobs.add(b);
setVisible(true);
}
public void paint(Graphics g){
for(Blob b : blobs)
b.paint(g);
synchronized(dots){
Iterator i = dots.iterator();
while(i.hasNext()){
Dot d = (Dot) i.next();
d.paint(g);
}
}
}
}
}
Related
I am developing a space invaders application for a college assignment and I've come into a problem where the aliens change direction one by one as they hit a wall rather than the whole array of objects switching direction when any alien touches the boundary. I hae a feeling it is an issue in my for loop where my move method containing reverseDirection() method acts on each element individually but I do not know how to fix this and any help would be greatly appreciated. Here is my code for you;
import java.awt.Color;
import java.awt.Dimension;
import java.awt.Graphics;
import java.awt.Image;
import java.awt.event.*;
import javax.swing.*;
import java.awt.image.*;
public class InvadersApplication extends JFrame implements Runnable {//, KeyListener {
private static final Dimension WindowSize = new Dimension(800, 600);
private static final int NUMALIENS = 16;
private Alien AliensArray[] = new Alien[NUMALIENS];
private Image alienImage;
private Image playerImage;
private String workingDirectory = "C:\\Users\\brads\\IdeaProjects\\Assignment3\\src\\workingDirectory\\";
private Player playerShip;
private BufferStrategy strategy;
public InvadersApplication() {
System.out.println(System.getProperty("user.dir"));
setDefaultCloseOperation(EXIT_ON_CLOSE);
Dimension screenSize = java.awt.Toolkit.getDefaultToolkit().getScreenSize();
int x = screenSize.width / 2 - WindowSize.width / 2;
int y = screenSize.height / 2 - WindowSize.height / 2;
setBounds(x, y, WindowSize.width, WindowSize.height);
this.setTitle("Alien Invaders App");
ImageIcon playerIcon = new ImageIcon(workingDirectory + "player_ship.png");
playerImage = playerIcon.getImage();
ImageIcon alienIcon = new ImageIcon(workingDirectory + "alien_ship_1.png");
alienImage = alienIcon.getImage();
playerShip = new Player(playerImage);
// addKeyListener(this);
setVisible(true);
createBufferStrategy(2);
strategy = getBufferStrategy();
for (int i = 0; i < NUMALIENS; i++) {
AliensArray[i] = new Alien(alienImage);
AliensArray[i].setPosition(70 * (i%4), 70 * (i/4));
AliensArray[i].setXspeed(1);
}
Thread thread1 = new Thread(this);
thread1.start();
repaint();
}
#Override
public void run(){
while(true){
try{
for(int i = 0; i < NUMALIENS; i++) {
AliensArray[i].move();
}
repaint();
Thread.sleep(5);
} catch (Exception e) {
e.printStackTrace();
}
}
}
/* public void keyPressed(KeyEvent e) {
int KeyCode = e.getKeyCode();
if (KeyCode == KeyEvent.VK_LEFT) {
playerShip.movePlayer(-8);
} else if (KeyCode == KeyEvent.VK_RIGHT) {
playerShip.movePlayer(8);
}
}
*/
public void keyReleased(KeyEvent e){
}
public void keyTyped(KeyEvent e){}
public void paint(Graphics g){
g = strategy.getDrawGraphics();
g.setColor(Color.BLACK);
g.fillRect(0,0,800,600);
for(int i=0; i < NUMALIENS; i++){
AliensArray[i].paint(g);
}
// playerShip.paint(g);
//playerShip.paintPlayer(g);
strategy.show();
this.repaint();
}
public static void main(String[] args){
InvadersApplication x = new InvadersApplication();
}
}
Sprite2D class;
public class Sprite2D{
protected int x = 0,y = 30;
protected Image myImage;
public Sprite2D(Image myImage){
this.x = x;
this.y = y;
this.myImage = myImage;
}
public void setPosition(int xx, int yy){
x = xx;
y = yy;
}
public void paint(Graphics g){
g.drawImage(myImage, x,y, null);
}
}
Alien subclass of sprite2D;
import java.awt.*;
import java.util.Random;
import javax.swing.*;
public class Alien extends Sprite2D {
private int xi;
private int xj;
public Alien(Image myImage) {
super(myImage);
this.myImage = myImage;
this.x = x;
this.y = y;
this.xi = xi;
this.xj = xj;
}
// #Override
// public void setPosition(int xx, int yy){
// xx = x;
// yy = y;
//
// }
public void move() {
y+=xj;
x+= xi;
if(x >= 750) {
reverseDirection();
x = x + xi;
}
else if (x < 0)
{
reverseDirection();
x = x + xi;
}
}
public void setXspeed(int xi) {
this.xi = xi;
}
public void setYspeed(int xj) {
this.xj = xj;
}
public void reverseDirection() {
xi = -xi;
System.out.println("reverse");
}
// #Override
// public void paint(Graphics g) {
//
//
// g.drawImage(myImage, xx, yy, null);
// }
}
I'm trying to do this code to output the same result as the picture
it should start with one black circle then when I click the button, a white circle appear with shift the right and get bigger by 20 pixels and so on
after the 4th circle it should clear the window and start from the beginning and I keep getting only one circle color or two circles together
here's the code
import java.awt.*;
import java.awt.event.*;
import java.util.ArrayList;
import java.util.List;
import javax.swing.*;
import javax.swing.WindowConstants;
public class CircleList extends JFrame implements ActionListener {
JButton addCircle;
int nCircle = 1;
int step = 0;
int shift = 0;
int d = 0;
public static void main (String [] args){
new CircleList();
}
private class Circle {
public int x1;
public int y1;
public int w;
public int h;
public Color color;
}
private List<Circle> whiteList = new ArrayList<>();
private List<Circle> blackList = new ArrayList<>();
public CircleList() {
super("CircleList");
setSize(500,500);
setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);
getContentPane().setBackground(Color.gray);
addCircle = new JButton("Add Circle");
add(addCircle,BorderLayout.SOUTH);
addCircle.addActionListener(this);
repaint();
setVisible(true);
}
public void paint(Graphics g){
super.paint(g);
g.fillOval(35, 35, 35, 35);
if (d==1) {
for (Circle s: whiteList ) {
paintWhiteCircle(g, s);
}
addWhiteCircle();
}
else if (d==2) {
for (Circle s: blackList ) {
paintBlackCircle(g, s);
}
addBlackCircle();
}
}
public void paintWhiteCircle(Graphics g, Circle circle) {
g.setColor(circle.color);
g.fillOval(circle.x1, circle.y1, circle.w, circle.h);
}
public void paintBlackCircle(Graphics g, Circle circle) {
g.setColor(circle.color);
g.fillOval(circle.x1, circle.y1, circle.w, circle.h);
}
public void addBlackCircle(){
Circle circle = new Circle();
circle.x1 = 40 + shift;
circle.y1 = 30 ;
circle.w = 30 + step;
circle.h = 30 + step;
circle.color = new Color(0,0,0);
this.blackList.add(circle);
}
public void addWhiteCircle() {
Circle circle = new Circle();
circle.x1 = 100 + shift;
circle.y1 = 30 ;
circle.w = 50 + step;
circle.h = 50 + step;
circle.color = new Color(255*65536+255*256+255);
this.whiteList.add(circle);
}
public void actionPerformed(ActionEvent e) {
Object source = e.getSource();
d = 0;
if (source == addCircle) {
for (nCircle = 2; nCircle <= 5; nCircle++) {
if (nCircle == 2) {
d = 1;
step+=20;
shift += 20;
nCircle++;
}
else if (nCircle == 3) {
d = 2;
step+=20;
shift += 20;
}
else if (nCircle == 4) {
d=1;
step+=20;
shift += 20;
}
else if (nCircle == 5)
repaint(); // it should clear the window and start with one circle like the beginning
}
repaint();
}
}
}
the output should be like this
I've corrected your example. It works now.
import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Dimension;
import java.awt.Graphics;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.util.ArrayList;
import java.util.List;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.SwingUtilities;
import javax.swing.WindowConstants;
public class CircleList extends JPanel implements ActionListener, Runnable {
private static final int INTERVAL = 20;
private static final int INITIAL_DIAMETR = 20;
private int actualXPos;
private final List<Circle> circleList = new ArrayList<>();
public static void main(String[] args) {
SwingUtilities.invokeLater(new CircleList());
}
#Override
public void run() {
JFrame frm = new JFrame(getClass().getSimpleName());
frm.setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);
frm.getContentPane().add(this);
frm.pack();
frm.setLocationRelativeTo(null);
frm.setVisible(true);
}
public CircleList() {
setLayout(new BorderLayout());
setPreferredSize(new Dimension(500, 500));
setBackground(Color.gray);
JButton addCircle = new JButton("Add Circle");
add(addCircle, BorderLayout.SOUTH);
addCircle.addActionListener(this);
addCircle();
}
#Override
public void paintComponent(Graphics g) {
super.paintComponent(g);
for (Circle c : circleList) {
c.paint(g);
}
}
private void addCircle() {
Circle circle = new Circle();
int num = circleList.size();
circle.x1 = 40 + actualXPos;
circle.y1 = 30;
circle.w = 30 + INITIAL_DIAMETR * (num + 1);
circle.h = 30 + INITIAL_DIAMETR * (num + 1);
circle.color = num % 2 == 0 ? Color.BLACK : Color.WHITE;
circleList.add(circle);
actualXPos += circle.w + INTERVAL;
}
#Override
public void actionPerformed(ActionEvent e) {
if (circleList.size() == 4) {
circleList.clear();
actualXPos = 0;
}
addCircle();
repaint();
}
private static class Circle {
private int x1;
private int y1;
private int w;
private int h;
private Color color;
public void paint(Graphics g) {
g.setColor(color);
g.fillOval(x1, y1, w, h);
}
}
}
So I've got this challenge to make one of those spirograph drawrings in an applet. The problem is, I'm new to Java and have absolutely no idea how to get any components appearing on the screen. I'm hoping someone can just add an extra line of code to fix this, though I'm really grateful for any answers :)
import javax.swing.JApplet;
import javax.swing.JOptionPane;
import javax.swing.JTextField;
import java.awt.BorderLayout;
import java.awt.event.KeyAdapter;
import java.awt.event.KeyEvent;
import java.awt.Color;
import java.awt.Graphics;
import java.awt.Rectangle;
import java.awt.Dimension;
import java.awt.Toolkit;
public class SpaceCadets3_WB extends JApplet {
int numOfPoints = 1080;
int[] x = new int[numOfPoints];
int[] y = new int[numOfPoints];
int x1, x2, y1, y2, width, height, animationSleep = 0;
int R = 75;
int r = 10;
int O = 75;
JTextField changeNumOfPoints = new JTextField(15);
public SpaceCadets3_WB() {
}
public void start() {
this.setSize(600, 600);
this.setBackground(new Color(100,100,255));
this.getContentPane().setLayout(null);
this.getContentPane().add(changeNumOfPoints);
changeNumOfPoints.setVisible(true);
changeNumOfPoints.setLocation(width - changeNumOfPoints.getSize().width - 25, 25);
}
public void calculatePoints(){
width = SpaceCadets3_WB.this.getWidth();
height = SpaceCadets3_WB.this.getHeight();
for(int t = 0; t<numOfPoints; t++){
x[t] = (int) ((R+r)*Math.cos(t) - (r+O)*Math.cos(((R+r)/r)*t) + width/2);
y[t] = (int) ((R+r)*Math.sin(t) - (r+O)*Math.sin(((R+r)/r)*t) + height/2);
}
}
public void paint(Graphics g){
g.setColor(Color.RED);
calculatePoints();
for(int i = 0; i<numOfPoints;i++){
x1 = x[i];
x2 = x[i+1];
y1 = y[i];
y2 = y[i+1];
g.drawLine(x1, y1, x2, y2);
try {
Thread.sleep(animationSleep);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}
Your sleeping the paint method, something you should never do. It's bad to call Thread.sleep(...) on the Swing event thread, but it's a sin to do it in any painting method. So now the applet can't draw. Remember that any painting method must do nothing but painting, and must do it blazingly fast. It shouldn't do any program logic, it shouldn't directly do animation, it should just paint. Use a Swing timer as any similar question will show you how to do.
Also, never draw directly in the applet but instead in the paintComponent method of a JPanel that the applet holds.
So create your JPanel, override its paintComponent method, and draw using fields of the class. Then change the state of those fields in your Timer and call repaint() on the JPanel.
Edit
And yes, you should avoid using null layouts as that's preventing you from easily and adequately adding components to your GUI. Instead in this situation, a FlowLayout, the default layout for JPanel, would work great.
For example:
import java.awt.Color;
import java.awt.Dimension;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.Point;
import java.awt.RenderingHints;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.image.BufferedImage;
import java.beans.PropertyChangeEvent;
import java.beans.PropertyChangeListener;
import java.lang.reflect.InvocationTargetException;
import java.util.concurrent.ExecutionException;
import javax.swing.*;
#SuppressWarnings("serial")
public class SpaceCadets extends JApplet {
#Override
public void init() {
try {
SwingUtilities.invokeAndWait(new Runnable() {
public void run() {
SpaceCadetsPanel panel = new SpaceCadetsPanel();
getContentPane().add(panel);
setSize(SpaceCadetsPanel.PREF_W, SpaceCadetsPanel.PREF_H);
}
});
} catch (InvocationTargetException | InterruptedException e) {
e.printStackTrace();
}
}
}
#SuppressWarnings("serial")
class SpaceCadetsPanel extends JPanel {
public static final int PREF_W = 600;
public static final int PREF_H = 600;
public final static int TOTAL_POINTS = 1080;
private static final int R = 75;
private static final int R2 = 10;
private static final int O = 75;
private static final Color DRAW_COLOR = Color.RED;
private static final int ANIMATION_DELAY = 20;
private Point[] pts;
private JSpinner pointCountSpinner = new JSpinner(new SpinnerNumberModel(
800, 100, 1080, 1));
private JButton doItButton = new JButton(new DoItBtnAction("Do It!"));
private BufferedImage bufImg = new BufferedImage(PREF_W, PREF_H,
BufferedImage.TYPE_INT_ARGB);
private Timer timer;
public int imageIndex;
private CalcWorker calcWorker;
public Graphics2D g2;
public SpaceCadetsPanel() {
System.out.println(pointCountSpinner.getEditor().getClass());
add(pointCountSpinner);
add(doItButton);
setBackground(Color.white);
}
#Override
public Dimension getPreferredSize() {
if (isPreferredSizeSet()) {
return super.getPreferredSize();
}
return new Dimension(PREF_W, PREF_H);
}
#Override
protected void paintComponent(Graphics g) {
super.paintComponent(g);
if (bufImg != null) {
g.drawImage(bufImg, 0, 0, this);
}
}
class DoItBtnAction extends AbstractAction {
public DoItBtnAction(String name) {
super(name);
int mnemonic = (int) name.charAt(0);
putValue(MNEMONIC_KEY, mnemonic);
}
#Override
public void actionPerformed(ActionEvent e) {
imageIndex = 0;
if (timer != null && timer.isRunning()) {
timer.stop();
}
if (g2 != null) {
g2.dispose();
}
pts = new Point[0];
bufImg = new BufferedImage(PREF_W, PREF_H, BufferedImage.TYPE_INT_ARGB);
g2 = bufImg.createGraphics();
g2.setRenderingHint(RenderingHints.KEY_ANTIALIASING,
RenderingHints.VALUE_ANTIALIAS_ON);
g2.setColor(DRAW_COLOR);
int totalPoints = 0;
totalPoints = ((Integer) pointCountSpinner.getValue()).intValue();
timer = new Timer(ANIMATION_DELAY, new TimerListener(totalPoints));
calcWorker = new CalcWorker(totalPoints);
calcWorker.addPropertyChangeListener(new CalcWorkerListener());
calcWorker.execute();
}
}
class CalcWorker extends SwingWorker<Point[], Void> {
private int totalPoints;
public CalcWorker(int totalPoints) {
this.totalPoints = totalPoints;
}
#Override
protected Point[] doInBackground() throws Exception {
Point[] pts2 = new Point[totalPoints];
for (int i = 0; i < pts2.length; i++) {
int x = (int) ((R + R2) * Math.cos(i) - (R2 + O)
* Math.cos(((R + R2) / R2) * i) + PREF_W / 2);
int y = (int) ((R + R2) * Math.sin(i) - (R2 + O)
* Math.sin(((R + R2) / R2) * i) + PREF_H / 2);
pts2[i] = new Point(x, y);
}
return pts2;
}
}
class CalcWorkerListener implements PropertyChangeListener {
#Override
public void propertyChange(PropertyChangeEvent evt) {
if (SwingWorker.StateValue.DONE == evt.getNewValue()) {
try {
pts = calcWorker.get();
timer.start();
} catch (InterruptedException | ExecutionException e) {
e.printStackTrace();
}
}
}
}
class TimerListener implements ActionListener {
private int totalPoints;
public TimerListener(int totalPoints) {
this.totalPoints = totalPoints;
}
#Override
public void actionPerformed(ActionEvent e) {
int x1 = pts[imageIndex].x;
int y1 = pts[imageIndex].y;
int x2 = pts[imageIndex + 1].x;
int y2 = pts[imageIndex + 1].y;
g2.drawLine(x1, y1, x2, y2);
repaint();
imageIndex++;
if (imageIndex == totalPoints - 1) {
((Timer) e.getSource()).stop();
}
}
}
}
Which displays as,
I need to make a system where a obstacle is drawn on the screen, when it scrolls off the screen, another one will be drawn at a random value (up to a max of a certain value) on the screen after that one.
I have some code here:
public int xElapsed = 0;
this is just incremented all the time, it is how much the player has moved.
obstacleHole.paint(g);
if(obstacleHole.getX() <= 0){
obstacleHole.paint(g);
}
This is the paint function. The first obstacle is painted straight away, and the second after that condition is met. This is not working as intended, however.
x = position.nextInt(500 + player.xElapsed * 2);
and this is how the x coordinate of the obstacle is set. "position" is a random value generator.
This code is not working because only one obstacle ever shows up. How can I fix this to work as intended? I can provide extra code if necessary.
Here is the ObstacleHole class:
import java.awt.Color;
import java.awt.Graphics;
import java.awt.Rectangle;
import java.util.Random;
public class ObstacleHole {
Player player = new Player();
Random position = new Random();
int x;
int y;
int dx = 1;
int width = 100;
int height = 100;
public ObstacleHole(){
x = position.nextInt(500 + player.xElapsed * 2);
y = 250;
}
public void move(){
x = x - player.playerSpeed;
}
public void paint(Graphics g){
g.setColor(Color.BLACK);
g.fillRect(x, y, width, height);
}
public Rectangle bounds(){
return (new Rectangle(x, y, width, height));
}
public int getX() {
return x;
}
}
Screen.java
import java.awt.Graphics;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.KeyEvent;
import java.awt.event.KeyListener;
import javax.swing.JPanel;
import javax.swing.Timer;
public class Screen extends JPanel implements ActionListener, KeyListener{
Player player = new Player();
ObstacleHole obstacleHole = new ObstacleHole();
public Screen(){
addKeyListener(this);
setDoubleBuffered(true);
setFocusable(true);
Timer tick = new Timer(5, this);
tick.start();
}
public void actionPerformed(ActionEvent e) {
repaint();
player.move();
obstacleHole.move();
System.out.println(player.getXElapsed());
}
public void paint(Graphics g){
super.paint(g);
player.paint(g);
obstacleHole.paint(g);
if(obstacleHole.getX() <= 0){
obstacleHole.paint(g);
}
}
public void keyPressed(KeyEvent e) {
int key = e.getKeyCode();
if(player.jumpReady){
if(key == KeyEvent.VK_UP){
player.dy = -1;
player.jumpReady = false;
}
}
}
public void keyReleased(KeyEvent e) {
}
public void keyTyped(KeyEvent e) {
}
}
Player.java
import java.awt.Color;
import java.awt.Graphics;
public class Player {
int x;
int y;
int dx;
public int xElapsed = 0;
public int dy;
int width = 64;
int height = 64;
public int playerSpeed = 3;
public boolean isMoving = true;
public boolean hasJumped = false;
public boolean jumpReady = true;
public Player(){
x = 150;
y = 250;
}
public void move(){
x = x + dx;
y = y + dy;
xElapsed++;
if(hasJumped == true){
dy = -1;
}
if(y == 150){
dy = 1;
}
if(y == 250){
dy = 0;
jumpReady = true;
}
}
public void paint(Graphics g){
g.setColor(Color.RED);
g.fillRect(x, y, width, height);
}
public int getX(){
return x;
}
public int getY(){
return y;
}
public int getXElapsed(){
return xElapsed;
}
}
In your code you are painting obstacleHole, then when the x value of obstacleHole is less than or equal to 0, you draw it again. All you are doing is sending two calls to the paint() method of the same object.
If you want to paint a second one, you will need to create another object. Or, alternatively, move the original object back onto the screen after it leaves.
It is hard to give you sample code when you have provided so little context, but try something like this:
MyObject obstacleHoleA = new MyObject();
MyObject obstacleHoleB = new MyObject();
obstacleHoleA.paint(g);
if(obstacleHoleA.getX() <= 0){
obstacleHoleB.paint(g);
}
Or this:
obstacleHole.paint(g);
if(obstacleHole.getX() <= 0){
obstacleHole.setX(randomValueUpToAMaxOfCertainValue);
}
Edit: There are a lot of things I would do a lot differently with the above code, but they are outside the scope of the question.
Try this for your ObstacleHole class:
import java.awt.Color;
import java.awt.Graphics;
import java.awt.Rectangle;
import java.util.Random;
public class ObstacleHole {
Player player = new Player();
Random position = new Random();
int x;
int y;
int dx = 1;
int width = 100;
int height = 100;
public ObstacleHole(){
x = getNewPosition();
y = 250;
}
public void move(){
x = x - player.playerSpeed;
if(x < 0 - width) {
x = getNewPosition();
}
}
public void paint(Graphics g){
g.setColor(Color.BLACK);
g.fillRect(x, y, width, height);
}
public Rectangle bounds(){
return (new Rectangle(x, y, width, height));
}
public int getX() {
return x;
}
private int getNewPosition() {
return 200 + position.nextInt(300);
}
}
Note the change to the constructor and move() method, along with the new method getNewPosition().
I believe the code will speak for itself, but in general the point of the code is the have a Map class that will take in an array of BufferedImages, x values, and y values, to compose a map of many layers (first layer being the BufferedImage array at 0, starting at the x value at 0 and the y value at 0, and so on). The main job of the map class, is to take each pixel of each image and convert them to Block Objects, which are just simply rectangles with a color (Includes a BufferedImage, because after it works, I will replace the color with the Image. Also includes an integer to specify which layer (1 being index 0) its allowed on with 0 meaning it can exist among all layers). In the end, when I call Render() on a Map object, the map object should do all the work in rendering the blocks into the correct positions. The largest problem with all of this is that I get no sytax or compiler errors, so my logic is what is messed up and I can not figure it out!
Thanks in advance, and if the question is confusing please tell me!
The Map Class:
import java.awt.Graphics2D;
import java.awt.image.BufferedImage;
import java.util.ArrayList;
public class Map {
private int width;
private int height;
public int getWidth() { return width; }
public int getHeight() { return height; }
private int xPos;
private int yPos;
public int getX(int i)
{
return xPos;
}
public int getY(int i)
{
return yPos;
}
public void setPosition(int x, int y) { xPos = x; yPos = y; }
private int[] xStarts;
private int[] yStarts;
private ArrayList<BufferedImage> layersList = new ArrayList<BufferedImage>();
public void addLayer(BufferedImage image) { layersList.add(image); }
public void setLayer(int i, BufferedImage image) { layersList.set(i, image); }
private Block[][][] blocksArray;
private boolean beenInitialized = false;
public Map(BufferedImage[] images, int[] x, int[] y){
for (BufferedImage image : images){
layersList.add(image);
xStarts = x;
yStarts = y;
}
}
public void initialize(){
int widthMax = 0;
int heightMax = 0;
for (BufferedImage image : layersList){
if (image.getHeight() > heightMax) { heightMax = image.getHeight(); }
if (image.getWidth() > widthMax) { widthMax = image.getWidth(); }
}
width = widthMax;
height = heightMax;
blocksArray = new Block[layersList.size()][width][height];
for (int i = 0; i < layersList.size(); i++){
int currentLayer = i;
for (int y = 0; y < layersList.get(i).getHeight(); y++){
for (int x = 0; x < layersList.get(i).getWidth(); x++){
int colorCode = layersList.get(i).getRGB(x, y);
boolean error = true;
Block b = null;
for (int c = 0; c < Block.BLOCKS.size(); c++){
if (Block.BLOCKS.get(i).getColorCode() == colorCode && (Block.BLOCKS.get(i).getLayerCode() == currentLayer || Block.BLOCKS.get(i).getLayerCode() == 0)){
b = Block.BLOCKS.get(c);
error = false;
}
}
if (!error){
blocksArray[currentLayer][x][y] = b;
} else {
Block bb = new Block(false, colorCode);
bb.initialize();
blocksArray[currentLayer][x][y] = bb;
}
}
}
}
beenInitialized = true;
}
public void render(Graphics2D g2d){
if (beenInitialized){
for (int i = 0; i < layersList.size(); i++){
for (int y = yStarts[i]; y < layersList.get(i).getHeight() + yStarts[i]; y += Block.SIZE){
int currentY = 0;
for (int x = xStarts[i]; x < layersList.get(i).getWidth() + xStarts[i]; x += Block.SIZE){
int currentX = 0;
blocksArray[i][currentX][currentY].setPosition(x, y);
blocksArray[i][currentX][currentY].render(g2d);
currentX ++;
}
currentY++;
}
}
}
}
public void updatePosition(int x, int y){
xPos += x;
yPos += y;
}
}
The Block Class:
import java.awt.Color;
import java.awt.Graphics2D;
import java.awt.Rectangle;
import java.awt.image.BufferedImage;
import java.util.ArrayList;
public class Block {
public static final int SIZE = 32;
public static final boolean DEBUG = true;
public static ArrayList<Block> BLOCKS = new ArrayList<Block>();
private Color debugColor;
public Color getColor() { return debugColor; }
public void setColor(Color color) { debugColor = color; }
private BufferedImage blockIcon;
public BufferedImage getIcon() { return blockIcon; }
public void setIcon(BufferedImage icon) { blockIcon = icon; }
private int xPos;
private int yPos;
public int getX() { return xPos; }
public int getY() { return yPos; }
public void setPosition(int x, int y) { xPos = x; yPos = y; }
private Rectangle blockShape;
public Rectangle getShape() { return blockShape; }
private int colorCode;
public int getColorCode() { return colorCode; }
private boolean colides;
public boolean doesColide() { return colides; }
private int layerCode;
public int getLayerCode() { return layerCode; }
private boolean beenInitialized = false;
public Block(boolean colides, int layerCode){
this.colides = colides;
this.layerCode = layerCode;
}
public void initialize(){
blockShape = new Rectangle(xPos, yPos, SIZE, SIZE);
int r = (colorCode >> 16) & 0x000000FF;
int g = (colorCode >> 8) & 0x000000FF;
int b = (colorCode) & 0x000000FF;
debugColor = new Color(r, g, b);
BLOCKS.add(this);
beenInitialized = true;
}
public void render(Graphics2D g2d){
if (beenInitialized){
if (DEBUG){
g2d.setColor(debugColor);
if (colides){
g2d.fill(blockShape);
} else {
g2d.draw(blockShape);
}
} else{
}
}
}
}
And finally the Game Class (I threw this together JUST to show a window for testing):
import java.awt.BorderLayout;
import java.awt.Dimension;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.image.BufferedImage;
import javax.imageio.ImageIO;
import javax.swing.JFrame;
import javax.swing.JPanel;
public class Game extends JFrame{
public Game(){
super("Test");
try{
layer1 = ImageIO.read(getClass().getResourceAsStream("/layer1.png"));
layer2 = ImageIO.read(getClass().getResourceAsStream("/layer2.png"));
} catch (Exception ex) { ex.printStackTrace(); }
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
setResizable(false);
setLayout(new BorderLayout());
add(new panel(), BorderLayout.CENTER);
pack();
setLocationRelativeTo(null);
setVisible(true);
}
public static void main(String[] args){
new Game();
}
private int[] xStartPositions = {0, 0};
private int[] yStartPositions = {0, 0};
private BufferedImage layer1;
private BufferedImage layer2;
private BufferedImage[] imageArray = {layer1, layer2};
private Map map;
public class panel extends JPanel{
public panel(){
setMinimumSize( new Dimension(1200, 675));
setMaximumSize( new Dimension(1200, 675));
setPreferredSize( new Dimension(1200, 675));
setVisible(true);
map = new Map(imageArray, xStartPositions, yStartPositions);
}
public void paint(Graphics g){
Graphics2D g2d = (Graphics2D) g;
map.render(g2d);
}
}
}
The initialize method of Map is never called, therefore Map will never render...
Some feedback...
Don't ever override paint, use paintComponent instead (it's very rare that you would need to override paint...
Make sure you are calling super.paintXxx - there's a lot of important working going on in the background that you don't want to miss or replicate...
Instead of extending from a top level container like JFrame, start by extending from JPanel and add this to a frame you create instead
Beware of static variables, this might cause you more problems ;)
You may also want to have a read through Initial Threads