LibGDX render function not being called - java

I'm handling the rendering of my player object inside my Player class. My Player class extends an Entity class which is only responsible for handling physics interactions with other objects for now. My render method in my Player class looks like this:
public class Player extends Entity {
...
#Override
public void render(SpriteBatch batch) {
batch.draw(image, pos.x, pos.y, getWidth(), getHeight());
System.out.println("Player render called");
}
...
}
and the render function inside the Entity class is an abstract.
public abstract void render (SpriteBatch batch);
I have a very similar setup to render my game's map, which works with no issues. However, despite calling super.render(); inside my main class, which extends Game, the render method inside my Player class is not being called. What is going wrong here?
Main class:
public class Main extends Game {
...
#Override
public void create(){
player.create();
}
...
#Override
public void render(){
...
super.render();
}
}
Those are the only significant pieces in the Main class for what I'm trying to accomplish.

Related

Passing Parameters In Abstract Method

I have an abstract class in Java that has this method called
public abstract void onImageRendered(BufferedImage render)
I want the user to access the rendered image with this method. I have another method called
public void render()
That renders the image. The buffered image in the abstract method should not be any image but the rendered image from this method.
How do I pass the rendered image from that method as the parameter of the abstract method?
Here is my code:
public static void render(Scene scene) throws MORISIllegalMethodCallException{
if(propertiesAreSet){
Camera activeCamera = scene.getActiveCamera();
for (int x = 0; x < activeCamera.getWidth(); x++) {
for (int y = 0; y < activeCamera.getHeight(); y++) {
Ray ray = Ray.shootAt(activeCamera.getOrigin(), new Vector(x - activeCamera.getWidth()/2.0, activeCamera.getHeight()/2.0 - y, -(activeCamera.getHeight()/2.0)/Math.tan(activeCamera.getFov() * 0.5)).mul(activeCamera.getDirection()).normalize());
for (Renderable object : scene.getSceneObjects()) {
if (object.intersects(ray)){
//Assign colors to buffered image object "this.image" and do other necessary things
}
}
}
}
}else {
throw new MORISIllegalMethodCallException("The method moris.renderer.MORISRT.setProperties(int, double) should be executed before invoking the method moris.renderer.MORISRT.render(moris.scene.Scene)");
}
}
abstract void onImageRendered(BufferedImage renderedImage);//Here, the BufferedImage object should be "this.image"
The rendered image is something like this:
I tried searching StackOverflow for similar questions and also checked some other sources but they didn't seem to help.
Any suggestions would be appreciated.
Thanks in advance.
abstract void onImageRendered(BufferedImage renderedImage);//Here, the BufferedImage object should be "this.image"
First thing to say is that you are trying to add an implementation detail to an abstract method. That is wrong by definition. If it is an abstract method implementation is delegated to subclasses. But that just means that you are free to use this.image in every subclass. What you can do is, in your abstract class, is having a...
protected BufferedImage image;
...that you can reference from every sublcass as this.image.
But you will have to change the signature of the method render(). It cannot be static if you want to reference this. static methods can only access static attributes, and this always references an instance attribute.
Update
You can call the abstract method in the abstract class:
public abstract class MyAbstractClass {
private BufferedImage image;
public void render() {
// ...
onImageRendered(this.image);
// ...
}
public abstract void onImageRendered(BufferedImage renderedImage);
}
public class MyConcreteClass extends MyAbstractClass {
#Override
public abstract void onImageRendered(BufferedImage renderedImage) {
// do stuff with renderedImage, which will always be the image
// in the rendered metho called on the parent class
}
}

How can I override methods?

I'm trying to override the methods init(), render() and release(), but can't get it to work. I've looked at tutorials on overriding and have checked the following:
Overriding of methods takes place inside the subclass of the original methods
The method names are the exact same
The parameters are the same (none in this case)
I have 2 classes:
public class Game {
public void run() {
System.out.println("Running!");
init();
render();
release();
}
public void init() {}
public void render() {}
public void release() {}
}
and
public class Loader extends Game {
#Override
public void init() {
System.out.println("Initializing");
}
#Override
public void render() {
System.out.println("Rendering");
}
#Override
public void release() {
System.out.println("Releasing.");
}
}
Why is the only thing printed to the console "Running!"?
You have to use run() method from overriding class Loader object and not from Game object to get desired result.
You have to override the Game#run function by creating a method in the subclass with the #Override annotation.
public class Loader extends Game {
#Override
public void run() {
System.out.println("Running from Loader!");
}
}
When you define the Game object you have to instantiate a new Loader object.
Game game = new Loader();
game.run(); // this object is an instance of Loader so Loader#run() is called.

Making different screens using Processing in Eclipse

I have been having some issue's with using proclipsing (or processing in eclipse). I want to make it starts in one class, and draws everything in the other. Here is my code:
CLASS "Class1":
import processing.core.PApplet;
public class Class1 extends PApplet {
public void setup() {
size(600,600);
}
public void draw() {
background(0);
Class2 ChangeClass = new Class2();
ChangeClass.draw();
}
}
CLASS "Class2":
import processing.core.PApplet;
public class Class2 extends PApplet{
public void draw() {
background(100);
}
}
And when I attempt to run the program from Class1, this appears in the console:
Exception in thread "Animation Thread" java.lang.NullPointerException
at processing.core.PApplet.background(PApplet.java:15122)
at Class2.draw(Class2.java:6)
at Class1.draw(Class1.java:11)
at processing.core.PApplet.handleDraw(PApplet.java:2386)
at processing.core.PGraphicsJava2D.requestDraw(PGraphicsJava2D.java:240)
at processing.core.PApplet.run(PApplet.java:2256)
at java.lang.Thread.run(Unknown Source)
Can you tell me why this appears and why it doesn't work?
If you're using eclipse, then you must have a main() method that looks something like this:
public static void main(String args[]){
PApplet.main(new String[] {"Class1"});
}
In order to use another PApplet, you have to also call its main function:
public static void main(String args[]){
PApplet.main(new String[] {"Class1"});
PApplet.main(new String[] {"Class2"});
}
The whole thing would look something like this:
Class1.java
import processing.core.PApplet;
public class Class1 extends PApplet {
public void setup(){
size(600, 600);
}
public void draw(){
background(0);
}
public static void main(String args[]){
PApplet.main(new String[] {"Class1"});
PApplet.main(new String[] {"Class2"});
}
}
Class2.java
import processing.core.PApplet;
public class Class2 extends PApplet {
public void draw(){
background(100);
}
}
You could even move the main() function into its own file.
Roughly speaking, you should only have 1 PApplet. It grabs control of the drawing context (like a canvas) and owns it. In the draw method, it draws everything you want on that canvas and unless you explicitly pass the canvas somewhere else, it won't be able to draw on it. The error is happening because the second PApplet class is requesting to draw on the canvas and the original PApplet doesn't expect or allow that.
I would suggest that you don't instantiate the class Class2 in every draw method, that's 60 times a second (or whatever) you'll be creating a new object. Instead, consider this approach:
import processing.core.PApplet;
public class Class1 extends PApplet {
Class2 changeClass;
public void setup() {
size(600,600);
changeClass = new Class2();
}
public void draw() {
background(0);
changeClass.draw();
}
}
Now, this is not enough because the changeClass draw method will not receive enough info to draw by itself. It will need that canvas.
The proper way to do what you want is probably to use 'handleDraw' or 'registerMethod' from the documentation. It seems like these are designed to let you specify another object to handle the drawing (or a library to do so).
Finally, it's probably not kosher, but you could grab the drawing context as a PGraphics object and pass it to your draw method and draw everything directly to that, but using the provided methods above is probably cleaner.
Edit: Adding a quick code example as requested.
I'm afraid I don't have Eclipse or Proclipsing any more, but hopefully this Processing example is easily ported:
void setup()
{
size(800, 600, OPENGL);
// Register the Drawer Object as the method to call "draw" on after the PApplet draw is called
registerMethod("draw", new Drawer());
// States set here will apply to both draw methods
rectMode(CENTER);
}
void draw()
{
// This happens first...
background(255, 255, 255);
// More drawing if need be...
}
public class Drawer
{
void draw()
{
// This happens second (every draw)
translate(width/2, height/2);
rect(0, 0, frameCount, frameCount);
// more drawing if need be...
}
}
Just adding to the already great answers: another option could be passing a reference to the sketches' graphics so a second class can draw into:
import processing.core.PApplet;
import processing.core.PGraphics;
public class Class1 extends PApplet {
Class2 changeClass = new Class2();
public void setup() {
size(600,600);
}
public void draw() {
background(0);
changeClass.draw(g);
}
public static void main(String[] args) {
PApplet.main(Class1.class.getCanonicalName());
}
}
class Class2{
public void draw(PGraphics g) {
g.background(100);
}
}

Multiple type custom arraylist

I currently am trying to make a simple RPG-ish game. I want monsters to spawn randomly on the map. I have it set up so that when I want one to spawn it is added to an ArrayList called monsters. I will be having many different types of monsters by the time I am done, and each one has its own class (ex. Zombie, Ghost...) each class will have a method to draw the monster called draw. I want to know how I can do this.
Monsters is an ArrayList<Object> so it will be able to have the different classes in it, but It won't let my do Monsters.get(i).draw(); Is this actually possible, or am I being stupid.
You failed to cast the object ArrayList<Object> back to Monster
// Monster.get(i) == Object
// (Monster) Monsters.get(i) == Monster
// cast the list item i from Object to Monster
((Monster) Monsters.get(i)).draw();
A better solution:
interface Monster {
void draw();
}
// implement draw on each
class Zombie implements Monster {}
class Ghost implements Monster {}
ArrayList<Monster> monsters = new ArrayList<>();
// legal
monsters.add(new Zombie());
monsters.add(new Ghost());
// legal
monsters.get(i).draw();
You can go with class -> extends solution or this interface -> implements. Either way this is a very bare bones example of a better way to implement your Monsters.
Yes, it is possible, first you need to create an interface, like IMonster which contains a draw method. Then, have each monster type implement this interface.
Your ArrayList will look like this:
List<IMonster> monsters = new ArrayList<IMonster>();
monsters.add(new Ghost());
monsters.add(new Goblin());
So here is an example:
import java.util.ArrayList;
import java.util.List;
public class Monsters {
private static List<IMonster> monsters = new ArrayList<IMonster>();
public static void main(String[] args) {
monsters.add(new Ghost());
monsters.add(new Goblin());
monsters.add(new Devil());
for (IMonster monster : monsters) {
monster.draw();
}
}
}
interface IMonster {
public void draw();
}
abstract class AbstractMonster implements IMonster {
#Override
public void draw() {
System.out.println("Shared drawing code for all monsters");
}
}
class Ghost extends AbstractMonster {
#Override
public void draw() {
super.draw();
System.out.println("Ghost drawing code");
}
}
class Goblin extends AbstractMonster {
#Override
public void draw() {
super.draw();
System.out.println("Goblin drawing code");
}
}
class Devil extends AbstractMonster {
#Override
public void draw() {
super.draw();
System.out.println("Devil drawing code");
}
}
You have to cast your item get from the ArrayList like this -
Object item = Monsters.get(i);
Monster monster = (Monster) item;
monster.draw();
Or better you may use some Interface. You may use an interface (for example Drawable ). Your Monsterand other drawable class would implement it. Then use the ArrayList of Drawable.
interface Drawable{
public void draw();
}
public class Monster implements Drawable {
public void draw(){
//implementation of monster's draw
}
}
...
...
ArrayList<Drawable> monsters = new ArrayList<Drawable>();
...
...
monsters.get(i).draw();

Java interface - Return on method call

I've been struggling a couple of days trying to understand how the code below works.
I simply have: an abstract class:
public abstract class Screen {
protected final Game game;
public Screen(Game game) {
this.game = game;
}
public abstract void update(float deltaTime);
public abstract void paint(float deltaTime);
public abstract void pause();
public abstract void resume();
public abstract void dispose();
public abstract void backButton();
}
and an interface:
public interface Game {
public void setScreen(Screen screen);
public Screen getInitScreen();
}
I understood that the interface methods have no body because they say what classes can do, not how.
Then, when I call the method below from a class that extends the Screen abstract class:
game.getInitScreen();
What exactly this method will return? A new Screen? But there is nothing on this Screen class...no canvas, no SurfaceView...what's the point of such call?
Because, at run-time, there will be a class that provides a concrete implementation of a Screen. Exactly what that class is could be determined with something like game.getInitScreen().getClass().getName()

Categories