I have two functions within a class
void display()
and
void write(PGraphics pdf)
I use display() to display elements to the screen. Is there a way of invoking the code within display() so that I do not have to write out each of the functions again within write(pdf)? e.g.
line(0,0,100,100) to pdf.line(0,0,100,100) etc
You could do this by drawing to a PGraphics image instead of drawing directly to the screen, then draw that image to the screen. That way you could swap it out for the PDF PGraphics without changing any code. Something like this:
PGraphics pg;
PGraphics pdf;
boolean usePdf = false;
void setup() {
size(100, 100);
pg = createGraphics(width, height);
pdf = //whatever
}
void draw(){
if(usePdf){
display(pdf);
}
else{
display(pg);
image(pg, 0, 0);
}
}
void display(PGraphics g) {
g.beginDraw();
g.background(100);
g.stroke(255);
g.line(20, 20, mouseX, mouseY);
g.endDraw();
}
If you want to use all of the code jsut call it inside (but I guess you don't want to do that)
You should refractor the code and put the stuff you want to use in both methods into it's own method like:
private void hopefullyIGetABetterName(...) {...}
You can call this method inside of display as well as in write
I hope this helps, otherwise feel free to ask :-)
extract a common interface between drawing to screen and to the PDF (lets call it Drawable)
Implement Drawable for drawing to the screen.
Implement Drawable for drawing to the PDF
Create a single draw method that takes that interface.
Change display() to call draw(screenDrawable)
Change write(...) to call draw(pdfDrawable)
Related
im playing around with graphics and hit a bit of a roadblock. I can't seem to call my other class containing my graphics. Thanks in advance. As you can see i tried to call it as gameOBJ.Draw but its giving me errors.
This is the error:
The method Draw(Graphics) in the type GameObjects is not applicable for the arguments ()
public class Testing{
public boolean running = true;
public static void main(String[] args) {
GameObjects gameOBJ = new GameObjects();
gameOBJ.Draw();
Window window = new Window(Window.WIDTH, Window.HEIGHT, Window.TITLE);
}
public class GameObjects{
public void Draw(Graphics g) {
g.setColor(Color.BLACK);
g.fillRect(0, 0, Window.WIDTH, Window.HEIGHT);
}
}
To fix of that compilation error you can pass a graphics object.
For example you can use windows graphics (But this may not be the requirement of your task/project. With JDK 10 Window.TITLE is not present, I doubt if it was there in earlier versions as well.)
Optionally: By conventions method names in Java should start with small cases characters so the method name should be draw.
public static void main(String[] args) {
GameObjects gameOBJ = new GameObjects();
//Pass the graphics object to the Draw method
Window window = new Window(Window.WIDTH, Window.HEIGHT, Window.TITLE);
Graphics graphics =window.getGraphics() ;
gameOBJ.Draw(graphics);
}
Here:
gameOBJ.Draw();
There:
public void Draw(Graphics g)
The method signature expects you to pass an argument, your invokation does not. Simply can't work that way.
The key thing here: you have to understand what you are doing: when your draw() method should draw "on something" then you have to pass that something to it, for example by first creating that window, to then fetch the graphics object belonging to the window.
So for my 2D game I want to use an image to represent a player but when I try to use an image, it tells me that it couldn't be "instantiated". I don't know what that means:
public class PlayerOne extends Entity{
private Image img = new Image();
[...]
#Override
public void render(Graphics g){
g.drawImage( img , x, y, Color.BLUE, new ImageObserver());
}
}
I tried it in another class with BufferedImages but that somehow doesn't work.
So it can't create Objects of neither Image nor the ImageObserver. Does anyone know a fix for this error ?
You cannot instantiate an abstract class. Please see link.
Following syntax would be operational:
private Image image = new BufferedImage(200,200,BufferedImage.TYPE_INT_RGB);
Also see link for more information on BufferedImage. Additionally, here is a tutorial which ilustrates an example implementation;
You should have an image file (*.png for example ) to start with. Then use
Image img = new ImageIcon("img.png").getImage();
Since I'm new I can't post more than two links, but this is an x-post from reddit.com/r/learnprogramming, just for full disclosure.
I'll basically just be pasting what I said there to here. Thanks for your help, if you can help.
I'm writing somewhat of a graphing application. I currently only have it able to graph sin(x), but that's not the point of this question. I am not able to draw to my main panel. Here is what it currently looks like.
I had an overridden paint function in my Window.java class, which drew the sin(x) function and the axes, but when I made an inner class which extended JPanel(), it would no longer draw.
I then tried to make a separate file, but that didn't draw anything either.
What could be preventing it from drawing?
Here are all my files in question.
edit: code in question:
GraphDraw.java:
//import stuff
Public class GraphDraw extends JPanel {
SinX sinx = new SinX();
GraphPanel p = new GraphPanel();
#Override
public void paintComponent(Graphics gc) {
super.paintComponent(gc);
Graphics2D g = gc;
p.paintComponent(g);
sinx.paint(g);
}
}
And in Window.java, I initialize GraphDraw and add it to my main panel, which is underneath the buttons in the picture and above the x/y min/max labels.
GraphDraw drawer = new GraphDraw();
/*
GUI code
*/
mainPanel.add(drawer);
SinX.java
//import stuff
public class SinX extends Component {
public void paint(Graphics g) {
g.setColor(Color.red);
for(double x=-400;x<=400;x=x+0.5) {
double y = 50 * sin(x*((Math.PI)/180));
int Y = (int)y;
int X = (int)x;
g.drawLine(400+X,300-Y,400+X,300-Y);
}
}
}
First, before anything else, do the following:
Change you object from Component to JComponent
Do not ever, ever call paintComponent() or paint() on a graphics object from swing or awt, use object.repaint(); (For reasons I won't go into here, because it's long and complicated)
From there I would try calling setVisible(true); on all your objects. If you are getting this code from a tutorial, then stop and use a different tutorial. You need to learn how swing and the AWT library work before you can start making user interfaces. Nobody uses AWT anymore because Swing is much better. For reasons why, look at the following page. If you are too lazy to do that, its because it's more optimized and more powerful.
What is the difference between Swing and AWT?
I'm making a game with Libgdx and I'm using isometric perspective.
I have a problem when rendering my character because the map is loaded from Tiled Map Editor and character is a Sprite.
If I have a wall on layer 0 of the map, when drawing the wall before the Sprite, if the sprite is behind the wall, we will see the Sprite instead of wall (we should see the wall), if rendering the Sprite first, we will see the wall instead of the Sprite when the sprite is in front of the wall (we should see the Sprite). Any idea about fixing this?
I haven't really worked with tiled maps, but I think it goes something like this.
First, in TileEd, create an object layer that will be used for your character sprite. So the layer should be between background stuff and stuff that should obscure your player. Name it something like "characters".
Then, create a MapObject subclass that can render a sprite. Something like this:
public class SpriteMapObject extends MapObject {
private Sprite sprite;
public SpriteMapObject (Sprite sprite) {
this.sprite = sprite;
}
#Override
public Color getColor () {
return sprite.getColor();
}
#Override
public void setColor(Color color){
sprite.setColor(color);
}
public void render(Batch batch){
Color spriteColor = sprite.getColor();
float originalAlpha = spriteColor.a;
spriteColor.a *= getOpacity();
sprite.draw(batch);
spriteColor.a = originalAlpha;
}
}
Now after you load your map and your sprite, you can put the sprite on that layer you prepared:
map.getLayers().get("characters").add(new SpriteMapObject(playerSprite));
You also need to subclass the map renderer so it will render the sprite for you. Use your subclassed version instead of the original. For instance:
public class SpritesOrthogonalTiledMapRenderer extends OrthogonalTiledMapRenderer {
//Override whichever constructor(s) you need
public SpritesOrthogonalTiledMapRenderer (TiledMap map, Batch batch) {
super(map, batch);
}
#Override
public void renderObject(MapObject object) {
super.renderObject(object);
if(object instanceof SpriteMapObject) {
((SpriteMapObject) object).render(batch);
}
}
}
That's the basics of how it works. But if you want your player to be able to be in front or behind of a wall like you described, then you will need to create multiple extra layers, and move your sprite object to different layers when necessary.
Looks to me like Libgdx could use a feature enhancement to OrthogonalTiledMapRenderer so it can draw objects automatically merged into a TileLayer and inserting them into the draw order based on row.
I found an "answer" somewhere else so I share it with you so if any1 else had the problem:
- get players tile location.
- get each tile in that stack ( aka, get a reference to every tile in that cell across each layer.
- check for visibility exceptions on each of those tiles. Store exceptions as properties defined in Tiled. ( will cover properties shortly )
- handle accordingly, most likely by raising or lowering the players render layer for that frame.
I have a BufferedImage displayed in a JFrame through my own class. I opted to display the BufferedImage using my own class so I can scale it. My paintComponent and update
public class MyBuffIm{
public void paintComponent(Graphics canvas) {
if (bi == null) {
} else {
//bi, maxWidth, and maxHeight were passed to constructor
canvas.drawImage(bi, 0, 0, maxWidth, maxHeight, null);
}
}
public void update(Graphics canvas) {
super.update(canvas);
if(bi != null){
//Got this from some tutorial in the net.
//Done out of desperation :|
paintComponent(bi.getGraphics());
}
}
}
I overrode update since the docs are saying something like "If this component is not a lightweight component, the AWT calls the update method in response to a call to repaint". I'm not exactly sure if my component is lightweight or not.
In any case, I have the following code in my Runnable (does not work as I expect it to):
BufferedImage p = SomeMyBuffIm.getBuffIm();
Vector<Point> randomPixels = getRandomPixels(500);
int limit = randomPixels.size()
for (i = 0; i < limit; i++) {
Point rp = randomPixels.get(i)
p.setRGB(rp.x, rp.y, Color.red.getRGB());
}
SomeMyBuffIm.repaint();
mainFrame.repaint(); //JFrame call to repaint
I'd like to think that, since I'm scaling my image, I just can't discern the difference between the new and old images. But I've tried the largest values for getRandomPixels still to no effect. My test image, by the way, is just a white sheet so red pixels should stand out in it.
Anything wrong I'm doing?
I overrode update since the docs are saying something like "If this component is not a lightweight component, the AWT calls the update method in response to a call to repaint". I'm not exactly sure if my component is lightweight or not.
No you should NOT override update(). You would do that with AWT but not with Swing.
If you update the BufferedImage then all you need to do is invoke repaint() on your instance of the MyBuffin class.
If you need more help than post your SSCCE that demonstrates the problem.