Game Catching Coins - Array for the coins

This is my game im doing for my programming class, it almost complete but i have just 1 problem.

When i make the coins spaw faster, it despaws the coin and spaws it in the beggining, instead of having other coin.

I know it is something to do with arrays but i have no clue how to do it


package jogo;

import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
import javax.swing.event.*;
import java.util.*;
import java.util.logging.Level;
import java.util.logging.Logger;
import javax.swing.Timer;

class MenuPanel extends JPanel{

	JButton play = new JButton("");
	JButton help = new JButton("");
	JButton exit = new JButton("");
	
	Image menubkg = new ImageIcon("images\\menubkg.png").getImage();  //menu background
	
	/* Setting icons on buttons */
	ImageIcon playbtn = new ImageIcon("buttons\\play.png"); 
	ImageIcon helpbtn = new ImageIcon("buttons\\help.png");
	ImageIcon exitbtn = new ImageIcon("buttons\\exit.png");

	JPanel center = new JPanel(); //adding another jpanel in a panel for boxLayout
	
	MenuPanel(){
		
		center.setLayout(new BoxLayout(center,BoxLayout.Y_AXIS)); //setting box layout 
		add(center); //adding the panel to anothe JPanel
		
		/* setting icons on buttons */
		play.setIcon(playbtn); 
		help.setIcon(helpbtn);
		exit.setIcon(exitbtn);
		
		/* adding the buttons in the panel */
		center.add(play);
		center.add(help);
		center.add(exit);
				
		/* adding mouseListeners on buttons */
		play.addMouseListener(new Click());
		help.addMouseListener(new Click());
		exit.addMouseListener(new Click());
		
	}//end constructor
	
	class Click extends MouseAdapter{ //internal friendly class
	
       
		public void mouseClicked(MouseEvent me){
			if(me.getSource()== play){
				Jogo.cl.show(Jogo.cards, "GamePanel"); //show gamePanel when play is clicked
			}
			if(me.getSource()== help){
				Jogo.cl.show(Jogo.cards, "HelpPanel"); //show helpPanel when help is clicked
			}	
			if(me.getSource()== exit){
				System.exit(0);  //exit application when exit is clicked
			}
		}//end mouseClick
	}//end mouseAdapter
	

	public void paintComponent(Graphics g){
		super.paintComponent(g); 
		Graphics2D g2d = (Graphics2D)g; 
		setFocusable(true);		 
		
		g2d.drawImage(menubkg, 0,0, null); 
		repaint();
	}
}

///////////////////////////////// Help Panel \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
class HelpPanel extends JPanel{

	Image helpbkg = new ImageIcon("images\\helpbkg.png").getImage(); //help image background
	JButton back = new JButton("Back"); //back button
	
	HelpPanel(){
		setFocusable(true);
		add(back);
		
		back.addMouseListener(new MouseAdapter(){
                 
			public void mouseClicked(MouseEvent me){
						Jogo.cl.show(Jogo.cards, "MenuPanel");
			}	
		  });
	}
	
       
	public void paintComponent(Graphics g){
		super.paintComponent(g);
		Graphics2D g2d = (Graphics2D)g;
		g2d.drawImage(helpbkg, 0,0, null);
		repaint();
	}
}


/////////////////////////////////// GAME PANEL \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
class GamePanel extends JPanel{ 
	
	Image gamebkg = new ImageIcon("images\\gamebkg.png").getImage();
	Image cesto  = new ImageIcon("images\\cesto.png").getImage();
	Image coin     = new ImageIcon("images\\coin.png").getImage();
	Image gameOverbkg= new ImageIcon("images\\gameOverbkg.png").getImage();
	Image tempbkg; //temporary background
	
	int x_carteira,y_carteira; //carteira x and y  coordinates
	int x_coin,y_coin; // x and y coord of coin
	Random rand = new Random(); // for randomizing xcoord of coins
	
	JLabel time;
	JLabel points;
	
	int pointsCount = 0;
	int timeleft = 59;
	int counter  = 0;
	
	boolean gameOver = false;
	
	GamePanel(){
		
		setLayout(null);
		setFocusable(true);
		tempbkg = gamebkg;
		
		x_carteira = 450; y_carteira = 600;
		x_coin = (int)rand.nextInt(1000);
		y_coin = 0;
		
	    time = new JLabel("Time: 59");
		time.setBounds(20, 10, 50, 20); //setting the time label on screen
	    
	    
	    points = new JLabel("Points: 0");
		points.setBounds(100,10,100,20);
		
		/*adding both components in jpanel*/
		add(time);
		add(points);
		
                		addKeyListener(new KeyAdapter(){
                
                public void keyPressed(KeyEvent ke){
                
                if(ke.getKeyCode() == ke.VK_LEFT & x_carteira>10){
                x_carteira-=30;
                repaint(); // redraw at new position
                }
                if(ke.getKeyCode() == ke.VK_RIGHT & x_carteira<1000){
                x_carteira+=30; // redraw at new position
                repaint();
                }
                }
                
                
                
                
                });
	}
	
	void fallCoin() throws InterruptedException{
		if(timeleft<40) {
                if(y_coin >=1000){
			y_coin = 0;
			x_coin = rand.nextInt(1000);
		}
		else
                    y_coin++;
                }
                if(timeleft<25){ 
                if(y_coin >=500){
			y_coin = 0;
			x_coin = rand.nextInt(1000);
		}
		else
                    y_coin++;
                }
                if(timeleft<15){ 
                if(y_coin >=100){
			y_coin = 0;
			x_coin = rand.nextInt(1000);
		}
		else
                    y_coin++;   
                }
                if(y_coin >=1650){
			y_coin = 0;
			x_coin = rand.nextInt(1000);
		}
		else
                    y_coin++;
        
                     Thread.sleep(5);
                    


    }
	
	void updateTime(){
		counter++;
		if(counter == 120) //we count to 60 and then dec timeleft by 1 for slowing speed
		{
		   timeleft--;  //dec time left after 60 counts
		   counter = 0; //reset counter
		}
		time.setText("Time:"+timeleft);
	}
	
	void detectCollision(){
		Rectangle carteiraRect = new Rectangle(x_carteira,y_carteira,100,65); //making a rectangle on the carteira
		Rectangle coinRect    = new Rectangle(x_coin,y_coin,45,67); //making a rectangle on coin
		
		if(coinRect.intersects(carteiraRect)){
			pointsCount+=5; // give 5 points on each catch
			points.setText("Points:"+pointsCount); // set the count
			y_coin = 0; // for next coin
			x_coin = rand.nextInt(1000); // again randomizing x axis of coin
		}
	}//end collision detection
	
	void checkGameOver(){
		if(timeleft <= 0)
		{
			JLabel yourScore = new JLabel("Your SCORE :" + pointsCount);
			tempbkg = gameOverbkg;
			yourScore.setBounds(400, 400, 200, 100);
			gameOver = true;
			yourScore.setForeground(Color.RED);
			add(yourScore);
		}
	}
	

	public void paintComponent(Graphics g){
		super.paintComponent(g);
		Graphics2D g2d = (Graphics2D)g;
		g2d.drawImage(tempbkg,0,0,null); //game background
		
		checkGameOver();
		
		if(gameOver == false){
			setFocusable(true);
			grabFocus();
			updateTime();
			
                    try {
                        fallCoin();
                    } catch (InterruptedException ex) {
                        Logger.getLogger(GamePanel.class.getName()).log(Level.SEVERE, null, ex);
                    }
			detectCollision();
		
			g2d.drawImage(coin, x_coin, y_coin,null); //drawing coin at new position
			g2d.drawImage(cesto, x_carteira, y_carteira, null); //drawing carteira
		}
		
		repaint();	
	}
}

/////////////////////////// Catch the Money Game Panel \\\\\\\\\\\\\\\\\\\\\\\\\
public class Jogo extends JFrame{
	
	static MenuPanel mp = new MenuPanel();
	static HelpPanel hp = new HelpPanel();
	static GamePanel gp = new GamePanel();
	
	static CardLayout cl = new CardLayout();
	static JPanel cards = new JPanel(); // to contain the panels as cards
	
	Jogo(){
		
		cards.setLayout(cl);// setting the layout to cardlayout
		cards.add(mp, "MenuPanel");
		cards.add(hp, "HelpPanel");
		cards.add(gp, "GamePanel");
		cl.show(cards, "MenuPanel");
		add(cards); //adding the panel with cardlayout in JFrame
		
		setTitle("Catch The Money Game");
		setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
		setSize(1024, 700); //frame size
		setVisible(true);   //frame visibility	
	}
	
	public static void main(String args[]){
            Jogo jogo = new Jogo();
	}
}


Well you’ll going to need to use a list. You need to add the coin to said list; when it spawns. Then every update/collision you need to check all the coins and remove then if needed. You will need to read up about iterators for removing coins from lists, on the fly as well.

Also, posting a large amount of code should be done via a code hosting website. You need to be more specific with your question, people aren’t going to read through hundreds of lines of code looking for an issue and likely won’t spoon feed the answer straight up unless you’re really stuck/have no understanding of the topic/have tried to fix the code.

If you can point to where you think the issue is I can try and help you :point:

This, basically. Like he said, you’ll want to use an List or ArrayList (I don’t think it really matters), and use the add(Object o) to add the coins and get(int index) to check collisions ([icode]if (list.get(i).collisionTest() == true)[/icode] or something), and use remove(Object o) to remove the coin objects once they’ve been picked up

here is the code that says when to spawn coins

void fallCoin() throws InterruptedException{
    if(timeleft<40) {
            if(y_coin >=1000){
        y_coin = 0;
        x_coin = rand.nextInt(1000);
    }
    else
                y_coin++;
            }
            if(timeleft<25){ 
            if(y_coin >=500){
        y_coin = 0;
        x_coin = rand.nextInt(1000);
    }
    else
                y_coin++;
            }
            if(timeleft<15){ 
            if(y_coin >=100){
        y_coin = 0;
        x_coin = rand.nextInt(1000);
    }
    else
                y_coin++;   
            }
            if(y_coin >=1650){
        y_coin = 0;
        x_coin = rand.nextInt(1000);
    }
    else
                y_coin++;

                 Thread.sleep(5);
}

and here is the code that draws the coins

public void paintComponent(Graphics g){
    super.paintComponent(g);
    Graphics2D g2d = (Graphics2D)g;
    g2d.drawImage(tempbkg,0,0,null); //game background

    checkGameOver();

    if(gameOver == false){
        setFocusable(true);
        grabFocus();
        updateTime();

                try {
                    fallCoin();
                } catch (InterruptedException ex) {
                    Logger.getLogger(GamePanel.class.getName()).log(Level.SEVERE, null, ex);
                }
        detectCollision();

        g2d.drawImage(coin, x_coin, y_coin,null); //drawing coin at new position
        g2d.drawImage(cesto, x_carteira, y_carteira, null); //drawing carteira
    }

    repaint();  
}

So I would do this in the following way. Bear in mind that i’m typing this code inside the editor and not in and IDE so it might have some errors and you will need to fit it to your need.

First off, you need to make a class for the coins. Each coin should have an x, y, fallspeed? and any other values such as the bounds of the coin for checking collision. Then to add a new coin it’s pretty simple


// Just a simply class for our coins
public class Coin{
    private int x;
    private int y;
    private int fallSpeed;
    private Rectangle bounds;
    // Not sure if Java has a rectangle/overlap feature by default so I made this bit up

    public Coin(float x, float y, fallSpeed){
        this.x = x;
        this.y = y;
        this.fallSpeed = fallSpeed;
        bounds = new Rectangle(x, y, widthOfCoin, heightOfCoin);
   }
   public Rectangle getBounds(){
      return bounds;
   }
}
// Other class
public class WhatEverNameOfClassIs{

   private ArrayList<Coin> activeCoins = new ArrayList<Coin>(); // Create the arraylist that will hold all the coins

    public void spawnCoin(){ // Method for spawning the coins
        if(timePassed){
            // Add the coin to the list
            activeCoins.add(new Coin(x, y, fallSpeed));
        }
    }
}

To remove a coin it’s a bit more difficult.


public void coinChecker(){
Iterator it = activeCoins.Interator(): // Point the iterator at your list

    while(it.hasNext()){ // While there is a coin in the list
        Coin coin = it.next(); // Get the next coin
        if(coin.getBounds().overlaps(player.getBounds())){
            it.remove(); // This will remove the coin
            setScore(getScore + 5);

          // ... Anything else to do with scores, adjust speed, playing sounds, effects can all be done here
        }
    }
}

This is very basic and I wrote it in about 5 mins but it gives you the general idea. You need to do some reading on lists and iterators if you don’t know about them already :slight_smile:

Thanks for the help :smiley:

But i have no idea how to put that on my code, i think i would need to change a lot of it.

Yeah, you would, your code does have a lot of problems right now. A list is the only way you’re going to be able to have more coins spawning in the game :frowning:

Pardon me, but I’m new to this forum, so please ignore my formatting and all that fun stuff…

You’d have to take the code you copied for fallcoin and painting, along with any other attributes for the coin, then put that into it’s own object. From there you are able to do a basic loop to iterate through them while painting. Then remove them after that. Same thing with collisions. The point is to keep it as simple as you can Group together what you are doing with your naming convention into an object and reference that. Once you have 1 coin working so you can do something like: mycoin.fallcoin();
Then you can expand upon that and create multiple.

No matter what you do, you need to break out of your scripting and make an Object to make it easy on yourself… Or… you can always make a giant mess of arrays or variables like I did growing up with Basic, but you should try to save a headache if you can and utilize the language and Object Orientated Methodologies since you are able to.