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);
}
}
Related
I saw the following code in a tutorial. My question is why the interface Drawable is not implemented by the class LambdaExpressionExample2? I am familiar with composition between classes. Is that the case here as well ? Thank you.
#FunctionalInterface //It is optional
interface Drawable{
public void draw();
}
public class LambdaExpressionExample2 {
public static void main(String[] args) {
int width=10;
//with lambda
Drawable d2=()->{
System.out.println("Drawing "+width);
};
d2.draw();
}
}
You can implement in main class also:
public class LambdaExpressionExample2 implements Drawable{
#Override
public void draw() {
System.out.println("Implemented it in main class !!!");
}
public static void main(String[] args) {
LambdaExpressionExample2 lm = new LambdaExpressionExample2();
lm.draw();
}
}
But that won't be lambda.
Or you can define another implementation like :
public class DrawableImpl implements Drawable {
#Override
public void draw() {
System.out.println("I have implemented Drawable !!!");
}
}
public class LambdaExpressionExample2{
public static void main(String[] args) {
DrawableImpl dm = new DrawableImpl();
dm.draw();
}
}
But that is also not lambda.
You can also use anonymous class as below (old style):
public class LambdaExpressionExample2 {
public static void main(String[] args) {
Drawable anonymus_class = new Drawable() {
#Override
public void draw() {
System.out.println("Anonymus class");
}
};
anonymus_class.draw();
}
}
If you compare all, you will see lambda notation is most precise and intuitive.
The interface is used for the lambda function itself, not the LambdaExpressionExample2 class.
To see what I mean let's have a look at other ways you could achieve this functionality.
Instead of using a lambda, you could use an anonymous inner class. Before lambda functions became a thing in Java 8, this is how you would have had to do it.
public static void main(String[] args) {
int width=10;
// with anonymous inner class
Drawable d1 = new Drawable() {
#Override
public void draw() {
System.out.println("Anonymous Class: Drawing " + width);
}
};
d1.draw();
}
Here you can see the anonymous class is implementing the Drawable interface, by providing an implementation for the draw method.
We could use a concrete class that implements the Drawable interface
#FunctionalInterface
interface Drawable{
public void draw();
}
class ConcreteDrawable implements Drawable {
#Override
public void draw() {
System.out.println("Concrete Class: Drawing");
}
}
public class LambdaExpressionExample2 {
public static void main(String[] args) {
// with concrete class
Drawable d1 = new ConcreteDrawable();
d1.draw();
}
}
In this example, we no longer have access to the local width variable in the draw method. But you can see that the ConcreteDrawable class also provides an implementation of the Drawable interface.
Or finally we can use a lambda function.
public static void main(String[] args) {
int width = 10;
// with lambda
Drawable d1 = () -> { System.out.println("Lambda: Drawing " + width); };
d1.draw();
}
Here the lambda function is implementing the Drawable interface, by giving an implementation of the draw method. The only reason why we can use a lambda function here is that the Drawable interface only declares one method.
So in summary, it is not the LambdaExpressionExample2 class that should implement Drawable but instead the lambda function itself.
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.
I have this code here using my API:
package org.midnightas.os.game.dots;
import java.awt.Graphics2D;
import org.midnightas.os2.Key;
import org.midnightas.os2.MidnightasOS;
import org.midnightas.os2.gameapi.Game;
public class Dots extends Game {
public Dots(MidnightasOS midnightasos) {
super(midnightasos);
}
#Override
public void init() {
}
#Override
public void keyPressed(Key arg0) {
}
#Override
public void render(Graphics2D arg0) {
}
#Override
public void tick() {
}
static {
System.out.println("MOS Dots crashed.");
MidnightasOS.setGame(Dots.class);
}
}
The static block is supposed to be ran calling MidnightasOS.setGame(Class);
However that is not happening.
I have also debugged using System.out to no avail.
Is the problem within MidnightasOS? I will post it's code if necessary.
I'm doing this because I'm trying to create an artificial operating system with Linux and the Raspberry PI.
This shall be a game console like the Game Boy.
I'm trying to load all Game classes so at least one of them would use MidnightasOS.setGame(Class);
Thanks for reading.
When is Dots class loaded by classloader. It will be loaded on the first reference of this class. See if you ever refer to this class
You can even dynamically load the class
And to find all the subtypes of a class and load them all you can use this library
public class MainClass {
public static void main(String[] args){
ClassLoader classLoader = MainClass.class.getClassLoader();
Reflections reflections = new Reflections("org.midnightas");
Set<Class<? extends Game>> subTypes = reflections.getSubTypesOf(Game.class);
for(Class<? extends Game> subType : subTypes){
try {
Class aClass = classLoader.loadClass(subType);
System.out.println("subType.getName() = " + subType.getName());
} catch (ClassNotFoundException e) {
e.printStackTrace();
}
}
}
The static blocks in a class are executed as soon as the classloader loads the class for the first time. There are several possibilities to achieve this. Consider the following class:
public class SomeClass {
static {
System.out.println("static block in SomeClass");
}
static void someMethod() {
System.out.println("some static method");
}
}
Loading it by creating an object:
SomeClass foo = new SomeClass();
Loading it by calling a static method:
SomeClass.someMethod();
Loading it directly:
Class.forName("SomeClass");
These are only some of the possibilities you have! Please remark that you'll have to include the package structure into the third approach (if the class is in the package some.package it'll be: Class.forName("some.package.SomeClass");
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();
So lets say i have the following code.
public class ImageMaker {
// Variables
static ArrayList<Shape> shapes = new ArrayList<Shape>();//all the shapes contained in the image
public static void main (String[] args) {
shapes.add(new Rect()); //here i want to add an object Rect
}
}
and in a different class called Shape shown below. Now I want to add an object of type Rect to my shapes array list but i cannot as it says Rect cannot be resolved to a type. How can i implement this? Of course i have more instance variables and methods but i did not show them. Let me know if you need more info to answer. Thanks!
public class Shape {
public class Rect extends Shape {
//rect instance variables
public Rect(){
super();
System.out.print("Youve made a rect within shape");
}
}
As #tsnorri mentioned in comment, you should simply declare Rectas class out of Shapeone.
public class Shape {
}
public class Rect extends Shape {
//rect instance variables
public Rect(){
super();
System.out.print("Youve made a rect within shape");
}
}
In case you want to learn more about nested classes in Java this is a good starting point: http://docs.oracle.com/javase/tutorial/java/javaOO/nested.html
Edit (working example)
In general I recommend you some reading about basics of OO programming and JAVA in general.
here's a working example of adding both Shape and Rect to an ArrayList.
import java.util.ArrayList;
class ImageMaker
{
static ArrayList<Shape> shapes = new ArrayList<Shape>();//all the shapes contained in the image
public static void main(String args[])
{
shapes.add(new Shape());
shapes.add(new Rect());
}
public static class Shape {
System.out.print("Created new Shape");
}
public static class Rect extends Shape {
//rect instance variables
public Rect(){
super();
System.out.print("You've made a rect within shape");
}
}
}
cheers
Make the class static:
public static class Rect extends Shape {
Then use new Shape.Rect()
However, that seems like poor use of nested classes and you should consider defining Rect outside Shape in it's own file.