I am trying to create graphics for a very simple 2D game. I have arrayLists of imageIcons that will get drawn in succession when the player moves. One for up, one for down, etc. As of right now, I do not have the finished sprites so I replaced each separate one with a temporary image.
//this is inside the constructor
playerUp.add(new ImageIcon("Player1.png"); //will be a different image, but this image still exists
playerUp.add(new ImageIcon("Player1.png"); //will be a different image, but this image still exists
playerUp.add(new ImageIcon("PLayer1.png"); //will be a different image, but this image still exists
Then I draw them to an offscreen image that I later draw to the screen to prevent flickering.
//offg is the graphics object of the offscreen image and g is for the panel
offg.clearRect(0, 0, panel.getWidth(), panel.getHeight());
playerUp.get(0).paintIcon(panel, offg, x, y);
g.drawImage(offscreen, 0, 0, panel); //this is where the error occurs!
Anyways There is some kind of error in the code I tried using:
playerUp.add(new ImageIcon(getClass().getResource("Player1.png")));
but I do not know if I needed to, or how to use it properly (when researching I saw it a lot), however, That did not fix the problem. Also, I made sure that the image is in the same folder as the .class and .java files.
Also, I created a separate class that just drew an ImageIcon straight to the panel, and it used a completely different image.
ImageIcon ii = new ImageIcon("downlaodedimage.png"); //downlaodedimage.png is the different image
ii.paintIcon(panel, g, 0, 0);
And that gives a null pointer exception. I used:
System.out.println(ii);
And it printed out downloadedimage.png, so I do not know what the issue is?
the issue is that something on that line hasn't been initialized yet. Try debugging it to find which one is null, and making sure it is initialized prior to the call. Alternatively, if this occurs during a game loop, and the variable is initialized later in the loop, you can surround it with a try - catch to wait until the variable has been initialized.
Related
I cant keep the past line i draw with "g2d.drawLine(w, x, y, z);",
I call "repaint()" to update the Jpanel and it just draws a new Line, I need to keep the past Lines i have draw.
What it should do: enter image description here
What id do:enter image description here
You could use an ArrayList of Point objects, every time you do whatever calculation you're doing, just save the end point to it. Every time the panel repaints, just draw lines between all of the points in your ArrayList, in the same order they were added.
I've spent all night trying to figure out why I can't draw a series of bitmaps completely adjacent to each other (with no gaps in between), using Android.
For context, I am building a spectrogram application which displays a vertical bitmap for each 'window' of audio data that comes in, providing the user with a heatmap of frequencies. At the moment I'm using pre-recorded audio so I can perform all my calculations before I have to display anything - I have an ArrayList of integer arrays, each of which represents one window's bitmap, which is drawn to a canvas using a timer thread.
I am aware that the approach below will ultimately break when the application tries to draw past the dimensions of the screen, but I am not worrying about that for now. The problem I would like to solve is that the below code results in a one-pixel (ish) gap between the drawn bitmaps, when I would actually like them to be absolutely adjacent.
This is the run() method for my timer thread:
public void run() {
Canvas c = null;
try {
c = sh.lockCanvas(null);
synchronized(sh) {
doDraw(c);
}
} finally {
if (c!=null) {
sh.unlockCanvasAndPost(c);
}
}
}
This is the doDraw() method which draws the bitmaps, and then skips along to the end of that drawn bitmap in order to draw the next one. It simply does so by incrementing the 'windowsDrawn' field:
private void doDraw(Canvas canvas) {
canvas.drawBitmap(spec.getBitmapWindow(windowsDrawn), 0, 1, windowsDrawn, 0, 1, h, false, null);
System.out.println("Windows drawn: "+windowsDrawn);
windowsDrawn++;
}
spec.getBitmapWindow(windowsDrawn) simply returns an integer array of pixel values for the vertical window to be drawn.
Here's a screenshot to show what I'm talking about.The image looks as if it is behind tiny prison bars and I would like to get rid of these.
Thanks!
I found out what I was doing wrong. The 'prison bars' effect was actually a side-effect of me writing incremental updates to the back-buffer, which was presumably being flipped every so often (hence losing some of my updates to the other buffer, giving the black vertical lines). The problem was solved by ensuring that I was instead writing to a buffer bitmap and then redrawing the entire frame each time. Incremental updates to the screen (like I was trying to do) are not allowed in Android.
I'll start off by telling you what Im trying to do if thats OK, as Im not certain the route Im struggling with is even the best way of achieving my ends.
I have a JFrame containing two JPanels. One contains a number of buttons (buttonPanel), the other is, initially, blank (displayPane). When buttons are pressed the stuff shown in displayPanel changes. The way this is working is each press of a button creates a new object that extends JPanel and then adds that to displayPane
So all the above is working fine and dandy (although I freely admit it may not be the best way of doing it) except for one particular case.
In this particular case I need to create a JLayeredPanel and then draw a clipped image on it. JLayeredPanel because I want to draw some stuff on top of it, clipped because I only want to show part of the area (which exact part is passed to the constructor).
Now, the problem Im having is this. The only way I know to draw a clipped image is through g=thingie.getGraphics(), g.setClip(Shape shape), g.drawImage(various). However, all of that relies on being able to get graphics. But because I am assembling the object first there is no graphics object associated with the JLayeredPane (because its not displayed) so getGraphics is returning null and g.setClip() is throwing a Null Pointer Exception.
Obviously I am doing this wrong somehow and somewhere. Any help would be appreciated, sorry if the question is confusing. I tried to include as much detail as possible and now I am a little concerned I've muddied the issue. I'll keep an eye on this and clarify if required.
Warning!: Wrong answer, see below the line
Why don't you just create a new Graphics object, paint on it and then use it with the update() method?
Graphics g = new Graphics();
g.drawStuff();
thingie.update(g);
This showd be correct
As stated on the comments the previous solution was wrong but it can be done with an Double buffer, create a buffered image and draw on it, then override the paint method of the jLayeredPane pane to draw the image.
private void addStuff() {
BufferedImage bi =
new BufferedImage(100, 100, BufferedImage.TYPE_4BYTE_ABGR);
Graphics bufferedGraphics = bi.getGraphics();
//Paint stuff
bufferedGraphics.drawLine(0, 0, 50, 50);
javax.swing.JLayeredPane layered;
layered = new JLayeredPane() {
#Override
public void paint(Graphics g) {
g.drawImage(bi, 0, 0, null);
}
};
this.add(layered);
this.validate();
this.repaint();
}
I`m building an android App, and i got stuck with a simple thing: How do i draw (or "add") a Canvas object, to another Canvas object, like "merging" them?
If that`s not possible, what is the best solution for doing that?
Thanks!
This depends entirely on your implementation.
If each Canvas draws objects directly from an array (of shapes, etc.) each frame, you could simply append one array to the other. This way, your Canvas does not need to be drastically altered, it only has to add one array to another (possibly an ArrayList would be the way to go here).
If the above is not the case, you may have to make some more drastic changes. When I encountered a similar problem, I created a new method called commitChanges(), which added a series of changes to an existing Canvas (adding lines on top, etc.).
I first invalidated the affected area, then created a Bitmap with the size of the Canvas: Bitmap bmp = Bitmap.createBitmap(width, height, Bitmap.Config.RGBA_8888);.
Next, I created a canvas from that Bitmap: Canvas workingDrawing = new Canvas(bmp);.
Then, I drew everything I needed onto that new Canvas. In this case, that would be the data from one of your Canvases.
Now, in your other Canvas, you have to get the Bitmap you just drew, then draw it onto this Canvas. Like so: canvas.drawBitmap(yourDrawnBitmap, 0.0f, 0.0f, null);.
I think the difficulty you'll face is transferring the data from one Canvas to another. But, regardless of your implementation, one of the above methods should work effectively for you.
Im trying to make a turn-based game, progressing OK so far, however now I came to the part where I want to be able to move units around. I use images to determine different types of terrain, and another image to display a unit, but I can't get the unit to come out OVER the terrain, it only pops up under the terrain. Seems like I'm the first one ever to bump into this problem, so am I going at it the wrong way?
The tile with a terrain-image:
protected void paintComponent(Graphics paintIt) //paints this sexy-hex
{
super.paintComponent(paintIt); //not sure if we need this? lol
paintIt.setColor(is); //sets the color (later not even used, we need pics and shit)
//paintIt.fillPolygon(hex); //fills the hexagon with the desired color, will not be used later on either
if(isExplored)
paintIt.drawImage(image, 0, 0, null);
else
paintIt.fillPolygon(hex); // I want to paint it black
if (hoover) //are we pointing at this cell?
{
paintIt.setColor(Color.WHITE); //we want the nice line around the cell to be white
Graphics2D g2 = (Graphics2D) paintIt;
g2.setStroke(new BasicStroke(3)); //and 3 pixels wide (we are allowed to change it, supposedly in proportion to "rad"
g2.drawPolygon(hex); //draws the line around the hexagon
}
}
The unit:
protected void paintComponent(Graphics paintIt)
{
if(!selected)
{
paintIt.drawImage(image, 0, 0, null);
paintIt.drawImage(image2,0,0,null);
/*
super.paintComponent(paintIt);
paintIt.setColor(Color.BLACK);
paintIt.drawPolygon(shape); */
}
else
{
super.paintComponent(paintIt);
paintIt.setColor(Color.RED);
paintIt.drawPolygon(shape);
}
}
Sorry for the comments, and sorry for some code that's not even used, just think it's best to have it until the project's finished if we need to get back to somewhere.
The unit image is smaller than the terrain, so it fits. I've tested without painting out the terrain so I know the unit is painted under it.
If there's still code you would need to get an idea what I'm doing, tell me, just thought this was the relevant parts.
EDIT #2
The tile is a class created from another class which extends JFrame. The unit-class is created from that JFrame class but is beeing stored in the tile. Both tile and unit are JComponents.
Fix'd, I had to draw the units image within the terrain-class to make it come out on top. Since I already stored the unit in the class I don't know why I didn't do it this way from the beginning.
Thanks anyhoo <3