External class error

Hello, I’m new to Java.

I have a basic class called “GameClass” and external class “MyClass” where I’m creating a card (for a simple card game).
But I get an error when I’m trying to create an object of the “MyClass” in the “GameClass”.
What am I doing wrong? I can’t get it.
Thanks.

GameClass:

package tests;

import org.newdawn.slick.AppGameContainer;
import org.newdawn.slick.BasicGame;
import org.newdawn.slick.GameContainer;
import org.newdawn.slick.Graphics;
import org.newdawn.slick.Image;
import org.newdawn.slick.SlickException;


public class GameClass extends BasicGame {
	
	
	private Image card = null;
	private int cardX = 300;
	private int cardY = 350;
	public MyClass card2;

	
	
	
	

	public GameClass(String title) {
		super(title);
		
	}

	public static void main(String[] args) throws SlickException {
		
		
		
		
		AppGameContainer app = new AppGameContainer(new GameClass("GAME"));
		app.setDisplayMode(800, 600, false);
		app.start();
		
		

	}

	@Override
	public void render(GameContainer gc, Graphics g) throws SlickException {
		
		card.draw(cardX, cardY, card.getWidth()/2, card.getHeight()/2);
		
		card2.draw(50, 50);
	
		
	}

	@Override
	public void init(GameContainer gc) throws SlickException {
		
		card = new Image("img/card.png");
		
		card2 = new MyClass();
		card2.cardCreated();
		
	}

	@Override
	public void update(GameContainer gc, int delta) throws SlickException {
		
	
		
		
	}

}

MyClass

package tests;

import org.newdawn.slick.Image;
import org.newdawn.slick.SlickException;



public class MyClass extends Image {
	
	public static Image cardImage;
	
	
	//CONSTRUCTOR
	
	public MyClass(){
		
		
		
	}
	
	public void cardCreated(){
		
		System.out.println("The card is created");
	}
	
	
	@Override
	public void draw(){
		
		cardImage.draw();
	}
	
	public static void main(String[] args) throws SlickException{
		
		
		cardImage = new Image("img/card.png");
		
				
			
	}
	
	
}

java.lang.NullPointerException
at org.newdawn.slick.Image.draw(Image.java:772)
at org.newdawn.slick.Image.draw(Image.java:683)
at org.newdawn.slick.Image.draw(Image.java:547)
at tests.GameClass.render(GameClass.java:47)
at org.newdawn.slick.GameContainer.updateAndRender(GameContainer.java:688)
at org.newdawn.slick.AppGameContainer.gameLoop(AppGameContainer.java:411)
at org.newdawn.slick.AppGameContainer.start(AppGameContainer.java:321)
at tests.GameClass.main(GameClass.java:36)
Mon Feb 13 12:37:11 VLAT 2017 ERROR:Game.render() failure - check the game code.
org.newdawn.slick.SlickException: Game.render() failure - check the game code.
at org.newdawn.slick.GameContainer.updateAndRender(GameContainer.java:691)
at org.newdawn.slick.AppGameContainer.gameLoop(AppGameContainer.java:411)
at org.newdawn.slick.AppGameContainer.start(AppGameContainer.java:321)
at tests.GameClass.main(GameClass.java:36)

Did you instantiate card2? I don’t see this happening.

The error message refers to an NPE on line 47, which is why I am asking about the card2 variable.

You have

[icode] cardImage = new Image(“img/card.png”); [/icode]

within the MyClass.java file inside a main method, it should be inside the constructor. [icode] cardImage [/icode] is currently not being created anywhere within MyClass.java.

A program has only 1 entry point, which is your GameClass.java.

Only GameClass.java should have the [icode] public static void main(String[] args) [/icode] function.

Delete lines 33 to 40 within MyClass.java and put [icode] cardImage = new Image(“img/card.png”); [/icode] at line 16 (within the constructor) of MyClass.java.

I put cardImage = new Image(“img/card.png”); within the constructor of MyClass.java, but I got an error again. Also in the MyClass constructor it requests for an exception.
If I comment the line 47 it works well, on my thougths the problem is in draw method.

java.lang.NullPointerException
at org.newdawn.slick.Image.draw(Image.java:772)
at org.newdawn.slick.Image.draw(Image.java:683)
at org.newdawn.slick.Image.draw(Image.java:547)
at tests.GameClass.render(GameClass.java:47)
at org.newdawn.slick.GameContainer.updateAndRender(GameContainer.java:688)
at org.newdawn.slick.AppGameContainer.gameLoop(AppGameContainer.java:411)
at org.newdawn.slick.AppGameContainer.start(AppGameContainer.java:321)
at tests.GameClass.main(GameClass.java:36)
Tue Feb 14 13:40:37 VLAT 2017 ERROR:Game.render() failure - check the game code.
org.newdawn.slick.SlickException: Game.render() failure - check the game code.
at org.newdawn.slick.GameContainer.updateAndRender(GameContainer.java:691)
at org.newdawn.slick.AppGameContainer.gameLoop(AppGameContainer.java:411)
at org.newdawn.slick.AppGameContainer.start(AppGameContainer.java:321)
at tests.GameClass.main(GameClass.java:36)

package tests;

import org.newdawn.slick.Image;
import org.newdawn.slick.SlickException;



public class MyClass extends Image {
	
	public static Image cardImage;
	
	
	//CONSTRUCTOR
	
	public MyClass() throws SlickException{
		
		cardImage = new Image("img/card.png");
		
	}
	
		
	
	@Override
	public void draw(){
		
		cardImage.draw();
	}
	

	
	
}


package tests;

import org.newdawn.slick.AppGameContainer;
import org.newdawn.slick.BasicGame;
import org.newdawn.slick.GameContainer;
import org.newdawn.slick.Graphics;
import org.newdawn.slick.Image;
import org.newdawn.slick.SlickException;


public class GameClass extends BasicGame {
	
	
	private Image card = null;
	private int cardX = 300;
	private int cardY = 350;
	public MyClass card2;

	
	
	
	

	public GameClass(String title) {
		super(title);
		
	}

	public static void main(String[] args) throws SlickException {
		
		
		
		
		AppGameContainer app = new AppGameContainer(new GameClass("GAME"));
		app.setDisplayMode(800, 600, false);
		app.start();
		
		

	}

	@Override
	public void render(GameContainer gc, Graphics g) throws SlickException {
		
		card.draw(cardX, cardY, card.getWidth()/2, card.getHeight()/2);
		
		card2.draw(50, 50);
	
		
	}

	@Override
	public void init(GameContainer gc) throws SlickException {
		
		card = new Image("img/card.png");
		
		card2 = new MyClass();
		
		
	}

	@Override
	public void update(GameContainer gc, int delta) throws SlickException {
		
	
		
		
	}

}

Line 57

OK, I see the init (line 57). Not clear to me when Slick calls Init (I don’t know slick very well, haven’t used it in a long time), but it seems to me that the root of your question is elsewhere.

Is there a particular reason you want to create MyClass instead of just having card2 be an Image?

If your goal is to create a “wrapper” class for Image, following are two approaches. The problem I am seeing is that your original MyClass combines the two approaches in a way that isn’t working.

  1. MyClass ‘contains’ an Image.

In this case, do not Extend Image. Just hold a copy of the Image and provide a means for populating MyClass with the desired Image (either hardcode in constructor, or pass an argument in the constructor or a set() method) and a draw method that calls the draw method of the image.

For example:


public class MyClass
{
   Image cardImage;

   public MyClass() throws SlickException
   {   
      cardImage = new Image("img/card.png");
   }

   // alternative constructor for allowing different images to be specified
   public MyClass(String imgAddr) throws SlickException
   {   
      cardImage = new Image(imgAddr); 
   }

   public void draw(int x, int y)
   {
      cardImage.draw(x, y);  // I'm guessing this is the Slick syntax for an image draw method.
   }

   // Additional code that provides functionality that is not part of slick.Image

}
  1. MyClass extends Image.

In this case, you will want super(cardImage); in the MyClass constructor. As for drawing, if you don’t override the draw method of Image, you can call it directly on MyClass.


public class MyClass extends Image
{

   public MyClass() throws SlickException
   {
      super("img/card.png");
   }

   // alternate constructor, allowing you to specify different cards
   public MyClass(String imgAddr) throws SlickException
   {
       super(imgAddr);   
   }

   // Additional code that provides functionality that is not part of slick.Image

}

[quote]Is there a particular reason you want to create MyClass instead of just having card2 be an Image?
[/quote]
It’s just an exercise for me. I want to create an inner class card named “card1” and external one “card2”. Just to practice.

Thanks a lot! It works.