Jump to content

Problem with accessing objects created outside method

- - - - -

  • Please log in to reply
2 replies to this topic

#1
snapple232

snapple232

    Newbie

  • Members
  • Pip
  • 5 posts
Hi, I'm writing a card game and I'm running into some trouble. I have an object 'Card', and several arrays of Cards representing the deck and player hands. The only way I've gotten it to work is to initialize the Deck and Card[] objects inside the paintComponent method, where I'm manipulating those objects. If I initialize deck and communityCards in startGame() instead, the functions inside paintComponent return nonsense and randomized results. I'm not totally sure how object scope works. I was under the impression that if i declared Deck and Card[] objects outside, I could access it from within any methods without problem. However, I'm suspecting that the randomized and nonsense results are because the functions inside paintComponent are pointing to the wrong memory location or something?


public class Game extends JPanel implements KeyListener {

	

	Image cardImage;

	Deck deck;

	Card[] communityCards;

	public Card[][] playerCards;

	int cardsDealt;

	

	public Game() {

		addKeyListener(this); // Tells Game object to listen for keyboard input

	}

	

	public void startGame() { // Main game loop

		deck = new Deck(); <----------------- If I initialize Deck and Card[] here, paintComponent returns nonsense results (like dozens of cards being printed on the screen randomly)

		communityCards = new Card[0];

		while(cardsDealt >= 0) {

			try {

				Thread.sleep(1000);

			} catch (InterruptedException x) { }

			//cardsDealt++;

			repaint();

		}

	}


	public void paintComponent(Graphics g) {

		super.paintComponent(g);

		g.drawString("" + deck.cards[0].rank, 200, 500);

		communityCards = ERS.dealCards(communityCards, deck, cardsDealt);

		paintCards(g, communityCards, 50, 50);

	}

	

	public Card[] dealCards(Card[] cards, Deck deck, int num) { // 'num' is number of cards to deal

		for (int i = 0; i < num; i++) { // Deals x number of random cards

			int rand = (int)(Math.random() * (deck.cards.length - i));

			cards = ArrayHelper.addCard(cards, deck.cards[rand]);

			deck.cards = ArrayHelper.deleteCard(deck.cards, deck.cards[rand]);

		}

		return cards;

	}

	

	public void paintCards(Graphics g, Card[] cards, int x, int y) {

		Toolkit tool = Toolkit.getDefaultToolkit();

		for (int i = 0; i < cards.length; i++) { // Draws the dealt cards

			String filename = "card" + cards[i].imageNum + ".png";

			cardImage = tool.getImage(filename);

			g.drawImage(cardImage, x + 80 * i, y, this);

		}

	}

	

	public void keyReleased(KeyEvent evt) { } // Keyboard events

	

	public void keyPressed(KeyEvent evt) { // Keyboard events

		int key = evt.getKeyCode();

		if (key == KeyEvent.VK_ENTER) {

			//cardsDealt++;

			repaint();

		}

	}

	

	public void keyTyped(KeyEvent evt) { } // Keyboard events

	


	

}


While the program works if I do something like this:

	public void paintComponent(Graphics g) {

		deck = new Deck(); <----------------- If I initialize it here instead, it works fine

		communityCards = new Card[0];

		super.paintComponent(g);

		g.drawString("" + deck.cards[0].rank, 200, 500);

		communityCards = ERS.dealCards(communityCards, deck, cardsDealt);

		paintCards(g, communityCards, 50, 50);

	}


It's not an optimal solution, because every time I call repaint() it creates an entirely new deck. I need the same deck to last for the whole game. I'm a pretty new programmer so I'm still trying to wrap my head fully around OOP and how scope works. Thanks for your help!

#2
eafkuor

eafkuor

    Programming Professional

  • Members
  • PipPipPipPipPip
  • 218 posts
A few points:

1 - You can declare all the variables as private.
2 - You don't need to pass communityCards to paintCards() since this method is in the same class and has access to it. Same thing for the dealCards() method.
3 - You are calling repaint() from inside the main loop (which is good) and from inside the keyPressed() method (which is useless and bad). You really should call it just from the main loop.
4 - In the "paint" methods you should just draw things, and not do other calculations. You might want to reorganize you main loop like this:


    public void startGame() { // Main game loop

		deck = new Deck(); <----------------- If I initialize Deck and Card[] here, paintComponent returns nonsense results (like dozens of cards being printed on the screen randomly)

		communityCards = new Card[0];

		while(cardsDealt >= 0) {

			try {

				Thread.sleep(1000);

			} catch (InterruptedException x) { }

			//cardsDealt++;

                        updateCards(); //organize the cards to be shown in this frame

			repaint(); //draw the cards

		}

	}


5 - What is ERS.dealCards()?

I modified you class a little bit, I don't know if it will solve your problems but it's a cleaner and more understandable code.

public class Game extends JPanel implements KeyListener {

	

	private Image cardImage;

	private Deck deck;

	private Card[] communityCards;

	private Card[][] playerCards;

	private int cardsDealt;

	

	public Game() {

		addKeyListener(this); // Tells Game object to listen for keyboard input

	}

	

	public void startGame() { // Main game loop

		deck = new Deck();

		communityCards = new Card[0];

		while(cardsDealt >= 0) {

			try {

				Thread.sleep(1000);

			} catch (InterruptedException x) { }

			//cardsDealt++;

                        updateStuff();

			repaint();

		}

	}


        private void updateStuff(){

            communityCards = dealCards();

        }


        //you just draw things here

	public void paintComponent(Graphics g) {

		super.paintComponent(g);

		g.drawString("" + deck.cards[0].rank, 200, 500);

		paintCards(g, 50, 50);

	}


        private void paintCards(Graphics g, int x, int y) {

		Toolkit tool = Toolkit.getDefaultToolkit();

		for (int i = 0; i < communityCards.length; i++) { // Draws the dealt cards

			String filename = "card" + communityCards[i].imageNum + ".png";

			cardImage = tool.getImage(filename);

			g.drawImage(cardImage, x + 80 * i, y, this);

		}

	}

	

	private Card[] dealCards() { // 'num' is number of cards to deal

		for (int i = 0; i < cardsDealt; i++) { // Deals x number of random cards

			int rand = (int)(Math.random() * (deck.cards.length - i));

			communityCards= ArrayHelper.addCard(communityCards, deck.cards[rand]);

			deck.cards = ArrayHelper.deleteCard(deck.cards, deck.cards[rand]);

		}

		return cards;

	}

	

}


        public void keyReleased(KeyEvent evt) { } // Keyboard events

	

	public void keyPressed(KeyEvent evt) { // Keyboard events

		int key = evt.getKeyCode();

		if (key == KeyEvent.VK_ENTER) {

			//cardsDealt++;

                        updateStuff(); //no need to call repaint() here since it's called automatically from the main loop

		}

	}

	

	public void keyTyped(KeyEvent evt) { } // Keyboard events



snapple232 said:

However, I'm suspecting that the randomized and nonsense results are because the functions inside paintComponent are pointing to the wrong memory location or something?

If you mean pointing to a random area of the RAM, that't not possible in Java :)

#3
snapple232

snapple232

    Newbie

  • Members
  • Pip
  • 5 posts
Thanks, that was helpful.




1 user(s) are reading this topic

0 members, 1 guests, 0 anonymous users