I am trying to rotate a player to follow the mouse. To do this I use a Graphics obj casted to a Graphics2D object and use the rotate method. Here is my Panel draw:
public void paint(Graphics g){
g.setColor(Color.white);
g.clearRect(0, 0, this.getWidth(), this.getHeight());
player.draw(g);
enemy.draw(g);
mouseSelection.draw(g);
wallBoard.draw(g);
//draw the existing walls
for(Wall w : walls)
w.draw(g);
//draw the potential wall
potentialWall.draw(g);
//draw the lineWalls
for(Wall w : lineWalls)
w.draw(g);
}
All my rotation stuff is happening in player.draw(g), but I figured it would be better to have more information than less. Here is my player.draw(g)
public void draw(Graphics g){
//draw the player as a circle for now
g.setColor(Color.black);
Graphics2D g2d = (Graphics2D)g;
g2d.drawOval(getX(), getY(), 20, 20);
sword.draw(g2d);
g2d.rotate(rotation);
g2d.rotate(0);
}
I have tried many combinations of the g2d.rotate and drawing the shapes. Any advice as how i can rotate the player and the sword, but not the entire world itself?
I would try drawing your player to its own image (with its own graphics object), rotating THAT image, and then drawing that image on your main graphics.
You'll run into some potentially annoying hurdles to get across, like transparency on the temporary image, but they aren't anything that can't be gotten around with a little blood sweat and tears.
Related
I'm new to Java GUI. I have two questions. Is there a way to repeat a gradient image horizontally like you would when working with CSS? If not, what is the conventional way of creating a gradient in Java?
In Swing, the GradientPaint class can be used to draw a gradient. Below is an example that will draw a square containing a linear gradient between white and red (assuming this code is within a class that extends JComponent):
public void paintComponent(Graphics g){
super.paintComponent(g);
Graphics2D g2d = (Graphics2D)g;
GradientPaint gradient = new GradientPaint(0,0,Color.WHITE, 100, 0, Color.RED);
g2d.setPaint(gradient);
g2d.fillRect(0,0,100,100);
}
Changing the BasicStroke of a Graphics2D object to anything other than 1 causes it to not draw something on the center of a JPanel on startup.
This is a JPanel which is on a JFrame. This is the basic idea of my project, but it is not the entire thing.
public void paintComponent(Graphics g) {
Graphics2D g2 = (Graphics2D) g;
if(this.centered){
this.myShape.setCenterX(this.getWidth()/2);
this.myShape.setCenterY(this.getHeight()/2);
}
g2.setStroke(new BasicStroke(3)); //new BasicStroke(1) works fine
g2.draw(this.myShape);
}
When you click and drag the myShape, myShape will immediately jump to the center. But when I initially compile and run it, paintComponent() paints it about a centimeter above the center of the screen if the stroke is not 1.
Is there something wrong with how I'm centering? I defined the MyShape class, so there could be an error there. Maybe the distance between the center and the drawing point is the space between JPanel and the top of the JFrame? How do I fix it?
Edit: added picture
http://s21.postimage.org/dfpmz73et/Untitled_1.png
The first shape is right where I want it. The other two are above where I want it. But it appears the displacement from the center are the same regardless of stroke size.
Yes, I believe this is the normal behaviour for a shape. It assumes an outline of 1 pixel. So you need to change the center calculation when you know you are going to change the basic stroke size. Something like:
public void paintComponent(Graphics g) {
Graphics2D g2 = (Graphics2D) g;
BasicStroke stroke = new BasicStroke(3);
int adjustment = stroke.getLineWidth() - 1;
if(this.centered){
this.myShape.setCenterX(this.getWidth() + adjustment / 2);
this.myShape.setCenterY(this.getHeight() + adjustment / 2);
}
g2.setStroke(stroke);
g2.draw(this.myShape);
}
I have coded a simple Java game where there are two rectangles on the screen, one of the rectangles moves and the other stays still, the moving Rectangle moves with keyboard arrow input and can move either up, down, left or right. The problem I am having is drawing my rectangles on the screen, I mean I have the 2 rectangles set up with my variables as shown:
Rectangle rectOne = new Rectangle(shiftX, shiftY,90,90);
Rectangle rectTwo = new Rectangle(500 + buckyPositionX, 330 + buckyPositionY, 210, 150);
I have made a render method to draw the things on the screen which I want shown:
public void render(GameContainer gc, StateBasedGame sbg, Graphics g) throws SlickException{
}
The problem I am having is showing my rectangles on the screen by writing the code in the render method, I could do the following:
g.fillRect(x, y,90,90);
g.fillRect(500 + buckyPositionX, 330 + buckyPositionY, 210, 150);
Which makes 2 rectangles on the screen but I need the rectangles to be drawn using the Rectangle code written with the variables, I have been told this can be done using Graphics2D but I am wondering if there is a simpler way of just using the graphics function, if not could you please help me set this up?
Thank you in advance.
You can access attributes of the Rectangle instances easily:
g.fillRect(rectOne.getX(), rectOne.getY(), rectOne.getWidth(), rectOne.getHeight());
In any case mind that usually the Graphics object is a Graphics2D instance at runtime so this could work easily too:
Graphics2D g2d = (Graphics2D)g;
g2d.fill(rectOne);
Just use:
g.fillRect(myRect.getX(), myRect.getY(), myRect.getWidth(), myRect.getHeight());
where myRect is the rectangle you want to draw. You could even make a custom method drawRect(Graphics g, Rectangle myRect); if you have lots of rectangles to draw.
Using Graphics2D is not that difficult as well, as the provide Graphics object normally is a Graphics2D object:
Graphics2D g2d = (Graphics2D) g;
g2d.fill(myRect);
When I try and apply a rotation to the current g2d object, it doesn't rotate it, it renders it in the same place (in my context on top of the other). From what I understand of the rotate method, it applies a transformation to the current graphics context, transforming the pixels of any rendering that comes after it (this might be where I'm going wrong). Here's the code in question:
#Override
public void paint(final Graphics graphics) {
super.paint(graphics);
final Graphics2D g2d = (Graphics2D) graphics;
....
....
g2d.setColor(Color.RED);
g2d.setStroke(new BasicStroke(SMALL_LINE_THICKNESS));
if (isLattice1Drawn) {
g2d.setComposite(AlphaComposite.getInstance(AlphaComposite.SRC_OVER, 1));
// lattice1 and lattice2 are Polygon objects
g2d.draw(lattice1);
// This fades in the second Polygon over the first
g2d.setComposite(AlphaComposite.getInstance(AlphaComposite.SRC_OVER, alpha));
// This line should rotate it, but doesn't
g2d.rotate(Math.toRadians(210));
g2d.draw(lattice2);
.....
Thanks, Mike
Edit 1
As a suggestion from Jeff, I tried having just the rotation and drawing in paint, leaving me with the following code:
#Override
public void paint(final Graphics graphics) {
super.paint(graphics);
final Graphics2D g2d = (Graphics2D) graphics;
g2d.rotate(Math.toRadians(210));
g2d.draw(lattice2);
return;
// Rest of paint .................
Unfortunately this did not help, any other suggestions would be most welcome.
Edit 2:
When I don't call rotate, the polygon is rendered, however when I do nothing happens. Can anyone explain this?
What I understand from Edit 2 is: the rotation actually works. However, since rotation is around origin the rotated coordinates of the polygon ends up outside of the visible area. You can test this by rotating smaller degrees.
Then, if the desired operation is to rotate a polygon around its center of mass, use the following Graphics2D method instead:
void rotate(double theta, double x, double y)
I'm working on a custom Swing Component for my application, and I started drawing things with the public void paintComponent(Graphics g). Everything works fine except for the fact that I can't draw any rectangles. I think the problem is with the getX() and getY() part, but I don't know that for sure. Here's my code:
#Override
public void paintComponent(Graphics g) {
super.paintComponent(g);
if (mouseEntered) {
g.setColor(HIGHLIGHTED_COLOR);
} else {
g.setColor(BACKGROUND_COLOR);
}
g.fillRect(getX(), getY(), getWidth(), getHeight());
//Draw rest of stuff (works fine)
The API says that it is supposed to be used like this: g.fillRect(x, y, width, height), and that's what I'm doing.
The rest of the drawing works perfectly, but I can't figure out why this isn't drawing. Any suggestions?
I'm not exactly sure how your Component is defined, but the default value for a Component's getX() method is the X coordinate of the Component's upper left hand corner (relative to the root Component).
When you are drawing in a Component's paintComponent(Graphics) method in Swing, the origin of the Graphics context that you are drawing to is typically located at the top-left of the Component itself, not the root Component.
So by doing this call:
g.fillRect(getX(), getY(), getWidth(), getHeight());
You are likely drawing the rectangle outside of the clip bounds of the Component!
(e.g. if the Component is located at 100, 100 and it has a width of 20 and height of 20, the rectangle you are drawing, in absolute coordinates, is at (200, 200) to (220, 220))
If you want to draw a rectangle that encompasses the entire component, you may want to try something more like this:
g.fillRect(0, 0, getWidth(), getHeight());
This will draw from the origin (again, likely the top-left hand corner of the Component) down to the width and height of the component.
(Using previous example: Component is at 100, 100, and width/height of 20, the rectangle this would draw is at (100, 100) to (120, 120))
Hope this helps =)