How can I render a image with a certain field of view? - java

Good evening! I have successfully displayed an image using java and the graphics object.
This is my 'Renderer'-Class:
public class Renderer {
private static BufferStrategy bs;
private static Graphics g;
private static Window win;
public static final int MIN_BUFFER_COUNT = 1;
public static final int MAX_BUFFER_COUNT = 4;
public static void prepareRenderer(BufferStrategy bs) {
Renderer.bs = bs;
g = bs.getDrawGraphics();
}
public static BufferStrategy createBufferStrategy(Window window, int bufferCount) {
if(window.getCanvas().getBufferStrategy() == null) {
window.getCanvas().createBufferStrategy(bufferCount);
}
win = window;
BufferStrategy _bs = window.getCanvas().getBufferStrategy();
return _bs;
}
public static void clearWindow(Window window) {
g.clearRect(0, 0, window.getWidth(), window.getHeight());
}
public static void drawRectangle(int x, int y, int width, int height) {
g.fillRect(x, y, width, height);
}
public static void setColor(Color color) {
g.setColor(color);
}
public static void drawImage(BufferedImage image, int x, int y, int width, int height) {
g.drawImage(image, x, y, win.getWidth() / width * Config.getField_of_view(), win.getHeight() / height * Config.getField_of_view(), null);
}
public static void drawSprite(Sprite sprite, int x, int y, int width, int height) {
g.drawImage(sprite.getImage(), x, y, (int) (win.getWidth() / width * Config.getField_of_view()), (int) (win.getHeight() / height * Config.getField_of_view()), null);
}
public static void closeRenderer() {
bs.show();
g.dispose();
}
I made this strange code in the renderer because I want to have a certain field of view no matter what window size.
This is what I wrote in the Main-Class:
#Override
public void render() {
//Prepare
Renderer.prepareRenderer(Renderer.createBufferStrategy(window, Renderer.MAX_BUFFER_COUNT));
//Clear
Renderer.clearWindow(window);
//Draw
Renderer.drawSprite(sprite, 0, 0, 100, 100);
//Close
Renderer.closeRenderer();
}
But now I have a problem because when I make the window into a rectangle it looks pretty stretched.

This worked with Math.min(win.getWidth(), win.getHeight()) thanks

Related

Strange behavior when I move a JComponent in a JPanel

I am in the process of implementing a simple graph editor. It should be possible to create any Node (Sphere object) by mouse click and move it by drag and move. It works as far as it goes, but it behaves very strangely. When I click on the node, it slides away from the cursor. The hitbox from every Sphere object is strange too, but I can't explain why. Is there a better solution for my code?
This behavior
public class EditorPanelView extends Panel
{
private static EditorPanelView instance = null;
private static GraphController graphController = GraphController.getInstance();
private EditorPanelView(Color color, int x, int y, int width, int height) {
super(new BorderLayout(), color, x, y, width, height);
addMouseAdapter();
}
private void addMouseAdapter() {
MouseAdapter mouseAdapter = new MouseAdapter() {
private Sphere sphere;
#Override
public void mousePressed(MouseEvent e) {
if (getComponentAt(e.getX(), e.getY()) instanceof Sphere) {
sphere = (Sphere) getComponentAt(e.getPoint());
}
}
#Override
public void mouseClicked(MouseEvent e) {
Sphere sphere = new Sphere(e.getX(), e.getY());
add(sphere);
System.out.println("MOUSE CLICKED ON EDITORPANEL; SPHERE CREATED!");
revalidate();
repaint();
}
#Override
public void mouseDragged(MouseEvent e) {
Point p2 = e.getPoint();
Point loc = sphere.getLocation();
loc.translate(p2.x - sphere.getX(), p2.y - sphere.getY());
sphere.setLocation(loc);
}
#Override
public void mouseReleased(MouseEvent e) {
sphere = null;
System.out.println("Mouse released!");
}
};
addMouseListener(mouseAdapter);
addMouseMotionListener(mouseAdapter);
}
public static EditorPanelView getInstance(Color color, int x, int y, int width, int height) {
return Objects.requireNonNullElseGet(instance, () -> new EditorPanelView(color, x, y, width, height));
}
}
public class Sphere extends JComponent{
private int positionX;
private int positionY;
private final int width = 50;
private final int height = 50;
public Sphere(int x, int y) {
this.positionX = x;
this.positionY = y;
}
#Override
public void paintComponent(Graphics graphics) {
Graphics2D sphere = (Graphics2D) graphics;
sphere.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
sphere.setPaint(Color.BLACK);
sphere.fillOval(positionX -(width/2), positionY -(height/2), width, height);
}
}
public class FrameView extends JFrame {
private static FrameView instance = null;
private static final Color FRAMECOLOR = Color.darkGray;
private FrameView() {
Dimension size = Toolkit.getDefaultToolkit().getScreenSize();
GraphController graphController = GraphController.getInstance();
getContentPane().setBackground(FRAMECOLOR);
setTitle("Graph Editor");
setSize((int) size.getWidth()-200, (int) size.getHeight()-200);
setLocationRelativeTo(null);
setDefaultCloseOperation(EXIT_ON_CLOSE);
setResizable(false);
getContentPane().setLayout(new GroupLayout(getContentPane()));
setJMenuBar(MenuBarView.getInstance());
add(EditorPanelView.getInstance(Color.LIGHT_GRAY, 260, 53, getWidth()-270, getHeight()-113));
add(OverviewPanelView.getInstance(Color.gray, 10, 53, 240, getHeight()-113));
add(ButtonPanelView.getInstance(FRAMECOLOR, 5, 5, getWidth()-10, 42));
}
public static JFrame getInstance() {
return Objects.requireNonNullElseGet(instance, FrameView::new);
}
}
public class Panel extends JPanel {
LayoutManager layout;
public Panel(LayoutManager layout, Color color, int x, int y, int width, int height) {
this.layout = layout;
setLayout(this.layout);
setBounds(x, y, width, height);
setBackground(color);
}
}
I tried to change the x and y coordinates in EditorPanelView::addMouseAdapter()

Looking at YouTube and google I created Code for a simple Jpanel with Button However What the videos don't tell me is what Design patterns am i using

I created an application which allows instantiating shapes which can be circle rectangle or anything and used sorting technique (Bubble Sort) to sort the six shapes based on interfaces.
The problem is I am not familiar with Design patterns and what patterns are being used- I am new so i followed youtube videos and played around with it and it worked.
I have 1 main class where I have
MAIN :
public class Main {
public static void main(String[] args) {
JButton btnLoadShapes, btnSortShapes;
btnLoadShapes = new JButton("Load Shapes");
btnLoadShapes.setBounds(150, 10, 150, 30);
btnSortShapes = new JButton("Sort Shapes");
btnSortShapes.setBounds(310, 10, 150, 30);
JPanel panelShapes = new JPanel() {
public void paintComponent(Graphics g) {
Graphics2D g2d = (Graphics2D) g;
Shape shape = new Shape();
g2d.setColor(Color.RED);
Square s = shape.getS();
g2d.fillRect(s.getX(),s.getY(),s.getWidth(), s.getHeight());
g2d.setColor(Color.BLUE);
Circle c = shape.getC();
g2d.fillOval(c.getX(),c.getY(), c.getWidth(), c.getHeight());
g2d.setColor(new Color(131, 21, 1));
Rectangle r = shape.getR();
g2d.fillRect(r.getX(), r.getY(), r.getWidth(), r.getHeight());
g2d.setColor(Color.PINK);
Circle C1 = shape.getC1();
g2d.fillOval(C1.getX(),C1.getY(), C1.getWidth(), C1.getHeight());
g2d.setColor(Color.green);
Square S1 = shape.getS1();
g2d.fillRect(S1.getX(),S1.getY(),S1.getWidth(), S1.getHeight());
g2d.setColor(Color.magenta);
Rectangle r2 = shape.getR2();
g2d.fillRect(r2.getX(),r2.getY(),r2.getWidth(), r2.getHeight());
}
};
panelShapes.setBounds(10, 50, 560, 500);
panelShapes.setBorder(BorderFactory.createLineBorder(Color.BLACK));
panelShapes.setVisible(false);
btnLoadShapes.addActionListener(new ActionListener() {
#Override
public void actionPerformed(ActionEvent e) {
panelShapes.setVisible(true);
}
});
and i have created 3 different classes Circle Rectangle and Square - from which i call for rectangle = shape.getC();
For example
public class Circle {
private int x, y, width, height;
public Circle(int x, int y, int width, int height) {
this.x = x;
this.y = y;
this.width = width;
this.height = height;
}
public int getX() {
return x;
}
public void setX(int x) {
this.x = x;
}
public int getY() {
return y;
}
public void setY(int y) {
this.y = y;
}
public int getWidth() {
return width;
}
public void setWidth(int width) {
this.width = width;
}
public int getHeight() {
return height;
}
public void setHeight(int height) {
this.height = height;
}
}
Now the lastly I created 2 more classes called Shape and Sorting
where in shape i intiated public shape s = new Square with dimensions and set getters and setters and lastly i used sorting technique.
Can someone help me understand what are the design patterns that are being used here?
( I assume that Factory method is being used = since i defined main (* interface) and created subclasses ( Shapes rectangle circle) to instantiate.
Sorry if i sound out the place- I am just trying to understand and learn it.
A "factory" creates "something", the important thing in this context is, you don't care "how" it's created, only that it conforms to the specified type.
For example, you have a ShapeFactory which can create different shapes, you don't care "how" those shapes are defined or implemented, only that they conform to the notion of a "shape"
So, lets start with a basic concept...
public interface Shape {
public void paint(Graphics2D g2d);
}
This just defines a basic concept and states that it can be painted.
Next, we need something to create those shapes...
public class ShapeFactory {
enum ShapeType {
CIRCLE, RECTANGE, SQUARE;
}
public static Shape create(ShapeType type, int x, int y, int width, int height, Color storkeColor, Color fillColor) {
return null;
}
}
Ok, as it stands, that's pretty boring, it's only ever going to return null right now, but this gives us a basic contract.
"Please factory, create me shape of the specified type, within the specified bounds, with the specified colors"
Now, as I said, the implementation is unimportant, to the caller, and we could have a dynamic factory which could delegate the creation to other factories which could create shapes differently based on a wide ranging set of needs ... but that's getting ahead of ourselves.
Let's go about creating some actual shapes...
public abstract class AbstractShape implements Shape {
private int x;
private int y;
private int width;
private int height;
private Color storkeColor;
private Color fillColor;
public AbstractShape(Color storkeColor, Color fillColor) {
this.storkeColor = storkeColor;
this.fillColor = fillColor;
}
public AbstractShape(int x, int y, int width, int height, Color storkeColor, Color fillColor) {
this(storkeColor, fillColor);
this.x = x;
this.y = y;
this.width = width;
this.height = height;
}
public int getX() {
return x;
}
public int getY() {
return y;
}
public int getWidth() {
return width;
}
public int getHeight() {
return height;
}
protected void setX(int x) {
this.x = x;
}
protected void setY(int y) {
this.y = y;
}
protected void setWidth(int width) {
this.width = width;
}
protected void setHeight(int height) {
this.height = height;
}
public Color getStorkeColor() {
return storkeColor;
}
public Color getFillColor() {
return fillColor;
}
#Override
public void paint(Graphics2D g2d) {
Graphics2D g = (Graphics2D) g2d.create();
Color storkeColor = getStorkeColor();
Color fillColor = getFillColor();
if (fillColor != null) {
g.setColor(fillColor);
paintFilled(g);
}
if (storkeColor != null) {
g.setColor(storkeColor);
paintStroked(g);
}
g.dispose();
}
abstract protected void paintFilled(Graphics2D g2d);
abstract protected void paintStroked(Graphics2D g2d);
}
public class CircleShape extends AbstractShape {
public CircleShape(int x, int y, int width, int height, Color storkeColor, Color fillColor) {
super(storkeColor, fillColor);
int size = Math.min(width, height);
x = x + ((width - size) / 2);
y = y + ((height - size) / 2);
setX(x);
setY(y);
setWidth(size);
setHeight(size);
}
#Override
protected void paintFilled(Graphics2D g2d) {
g2d.fillOval(getX(), getY(), getWidth(), getHeight());
}
#Override
protected void paintStroked(Graphics2D g2d) {
g2d.drawOval(getX(), getY(), getWidth(), getHeight());
}
}
public class SquareShape extends AbstractShape {
public SquareShape(int x, int y, int width, int height, Color storkeColor, Color fillColor) {
super(storkeColor, fillColor);
int size = Math.min(width, height);
x = x + ((width - size) / 2);
y = y + ((height - size) / 2);
setX(x);
setY(y);
setWidth(size);
setHeight(size);
}
#Override
protected void paintFilled(Graphics2D g2d) {
g2d.fillRect(getX(), getY(), getWidth(), getHeight());
}
#Override
protected void paintStroked(Graphics2D g2d) {
g2d.drawRect(getX(), getY(), getWidth(), getHeight());
}
}
public class RectagleShape extends AbstractShape {
public RectagleShape(int x, int y, int width, int height, Color storkeColor, Color fillColor) {
super(x, y, width, height, storkeColor, fillColor);
}
#Override
protected void paintFilled(Graphics2D g2d) {
g2d.fillRect(getX(), getY(), getWidth(), getHeight());
}
#Override
protected void paintStroked(Graphics2D g2d) {
g2d.drawRect(getX(), getY(), getWidth(), getHeight());
}
}
I always like a abstract class to carry the "common" functionality and to help make life a little simpler.
The important thing here is to note that both CircleShape and SquareShape, by their nature are, well, square (they have equal width and height). So, in this implementation, I define them to fit within the middle of the specified bounds - this is a "implementation" detail.
"But isn't that what I'm doing you?" you ask. Well, no, not really. When you call shape.getS(), for example, it's return a concrete class, which I assume has the same properties as the last object created by it, otherwise it will move all over the place.
Instead, what I'm doing is allowing you to define the properties you want the shape to have and then making it.
You want a cake? Sure, pass me the ingredients and I'll make you a cake, you still end up with a cake, but depending on the ingredients it's a different "type" of cake.
So, based on the above, we could do something like...
public class TestPane extends JPanel {
private List<Shape> shapes = new ArrayList<>(25);
public TestPane() {
shapes.add(ShapeFactory.create(ShapeFactory.ShapeType.CIRCLE, 10, 10, 200, 100, Color.RED, Color.BLUE));
shapes.add(ShapeFactory.create(ShapeFactory.ShapeType.RECTANGE, 10, 120, 200, 100, Color.BLUE, Color.GREEN));
shapes.add(ShapeFactory.create(ShapeFactory.ShapeType.SQUARE, 10, 240, 200, 100, Color.GREEN, Color.YELLOW));
}
#Override
public Dimension getPreferredSize() {
return new Dimension(220, 350);
}
#Override
protected void paintComponent(Graphics g) {
super.paintComponent(g);
Graphics2D g2d = (Graphics2D) g.create();
for (Shape shape : shapes) {
shape.paint(g2d);
}
g2d.dispose();
}
}
I could have made the ShapeFactory with dedicated createCircle, createRectangle and createSquare methods, I could have had them return interfaces of Circle, Square and Rectangle (and I would have based those of Shape because I'm like that) and it would still be a factory.
One of things to keep in mind is, a "factory" should be implementation independent. I should be able to make use of "different" shape factories to get different effects, but at the end of the day, they'd still just be generating Shapes
Remember, a factory will take something and it will create something from it.

java graphics - cannot save shapes drawn

I have a java application that i have been coding, it is an application that can allow me to draw shapes like a rectangle. My application can draw shapes but I cannot save them because when i try to draw a new shape and I click somewhere else the previously drawn shape disappears and is replaced by a new one. I tried array list to save my shapes but it does not work.
here is my code:
public class Toile extends JPanel {
Vector<Forme> forme = new Vector<Forme>();
private Color couleur;
private int x;
private int y;
private int x2;
private int y2;
private Oval oval;
private Rectangl rect;
public Toile(){
initComponents();
}
public void initComponents(){
addMouseListener(new java.awt.event.MouseAdapter() {
public void mousePressed(java.awt.event.MouseEvent evt) {
formMousePressed(evt); }
public void mouseReleased(java.awt.event.MouseEvent evt) {
formMouseReleased(evt); } });
addMouseMotionListener(new java.awt.event.MouseMotionAdapter() {
public void mouseDragged(java.awt.event.MouseEvent evt) {
formMouseDragged(evt); } });
}
public void paintComponent(Graphics g) {
super.paintComponent(g);
g.setColor(couleur);
drawfillRect(g, x, y, x2, y2);
}
public void setStartPoint(int x, int y) {
this.x = x;
this.y = y;
}
public void setEndPoint(int x, int y) {
x2 = (x);
y2 = (y);
}
public void drawfillRect(Graphics g, int x, int y, int x2, int y2) {
int px = Math.min(x,x2);
int py = Math.min(y,y2);
int pw=Math.abs(x-x2);
int ph=Math.abs(y-y2);
//g.fillRect(px, py, pw, ph);
Rectangl rect = new Rectangl(px,y,x2,py,pw,ph,couleur,true);
rect.dessinerfrect(g);
forme.add(rect);
}
}
private void formMousePressed(java.awt.event.MouseEvent evt) {
setStartPoint(evt.getX(), evt.getY());
repaint();
}
private void formMouseReleased(java.awt.event.MouseEvent evt) {{
setEndPoint(evt.getX(), evt.getY());
repaint();
//dessiner(this.getGraphics());
}
}
private void formMouseDragged(java.awt.event.MouseEvent evt){{
setEndPoint(evt.getX(), evt.getY());
repaint();
//dessiner(this.getGraphics());
}
}
As you can see this is the class that does the drawings, the rectangle that will be drawn is an object from a class that I created and this class is a subclass of a super class Forme. As I said previously, the application can draw shapes but the shapes that are drawn are not saved. Also I removed the getters and setters from my post because I wanted to keep only what was essential and I wanted to make my post clearer.
Here is the class Rectangl:
public class Rectangl extends Forme {
private int largeur;
private int hauteur;
private Rectangle rectangle;
public Rectangl(int x1,int y1, int x2 ,int y2,int largeur,int hauteur,Color couleur,Boolean plein){
super(x1,y1,x2,y2,couleur,plein);
this.largeur = largeur;
this.hauteur = hauteur;
}
public void dessinerrect(Graphics g){
g.setColor(couleur);
g.drawRect((int)point1.getX(), (int)point2.getY(), largeur, hauteur);
}
public void dessinerfrect(Graphics g){
g.setColor(couleur);
g.fillRect((int)point1.getX(), (int)point2.getY(), largeur, hauteur);
}
}
You'll need to implement a display list. This is a data structure that represents all the items currently in the drawing. The component painter just traverses the list and draws each item (usually after erasing the screen so that deleted objects don't appear in the new drawing). It also optionally draws the "rubberband cursor" if the mouse has been pressed and not yet released. The mouse actions (usually releasing the mouse button just modify status variables including display list (add, select, delete, etc.) and then repaint the drawing surface so the component painter is called.
A Java ArrayList is a reasonable way to implement a simple display list. The items themselves are a classical use of interfaces and/or inheritance:
interface DisplayListItem {
void draw(Graphics g);
}
abstract class AbstractRectangle implements DisplayListItem {
protected int x, y, w, h;
protected Color color;
Rectangle(int x, int y, int w, int h, Color color) {
this.x = x;
this.y = y;
this.w = w;
this.h = h;
this.color = color;
}
}
class Rectangle extends AbstractRectangle {
Rectangle(int x, int y, int w, int h, Color color) {
super(x, y, w, h, color);
}
#Override
void draw(Graphic g) {
g.setColor(color);
g.drawRect(x, y, w, h);
}
}
class FilledRectangle extends AbstractRectangle {
FilledRectangle(int x, int y, int w, int h, Color color) {
super(x, y, w, h, color);
}
#Override
void draw(Graphic g) {
g.setColor(color);
g.fillRect(x, y, w, h);
}
}
private List<DisplayListItem> displayList = new ArrayList<>();
private int xPress, yPress, xDrag, yDrag;
private boolean mousePressed = false;
#Override
public void paintComponent(Graphics g) {
super.paintComponent(g);
for (DisplayListItem item : displayList) {
item.draw(g);
}
if (mousePressed) {
// Draw the click-and-drag cursor.
g.setColor(Color.RED);
g.drawRect(xPress, yPress, xDrag - xPress, yDrag - yPress);
}
}
private void formMousePressed(MouseEvent evt) {
xPress = evt.getX();
yPress = evt.getY();
mousePressed = true;
}
private void formMouseDragged(MouseEvent evt) {
if (!mousePressed) return;
xDrag = evt.getX();
yDrag = evt.getY();
repaint();
}
private void formMouseReleased(MouseEvent evt) {
if (!mousePressed) return;
xDrag = evt.getX();
yDrag = evt.getY();
// Adding a rectangle to the display list makes it permanent.
displayList.add(new Rectangle(xPress, yPress, xDrag - xPress, yDrag - yPress));
mousePressed = false;
repaint();
}
Caveat: This is uncompiled, untested code. Use at your own risk.
Swing has the useful Shape interface which has been implemented into several concrete classes that could serve your purpose well.
There are several different Shapes (Ellipse2D, Rectangle2D, RoundRectangle2D) are stored in an ArrayList of Shape objects, and then these are drawn within the JPanel's paintComponent method after first casting the Graphics object into a Graphics2D.

How to draw a sprite with bufferedimage

I've made a spritesheet and have one sprite on there. But I want to display that sprite. I got the main class(called Game), a Sprite class, a SpriteSheet class, an Entity class and an Enemy class. In the main class I've got the main game loop(It's going to be a game), a run method, some other stuff, a init method and a render method. I want to render it with BufferedImage. this is my code:
Game:
package com.vos.rekenspel;
public class Game extends Canvas implements Runnable {
private static final long serialVersionUID = 1L;
public static final int WIDTH = 130;
public static final int HEIGHT = WIDTH / 12 * 9;
public static final int SCALE = 3;
public static final String NAME = "REKENSPEL";
private JFrame frame;
public boolean running = false;
public int tickCount = 0;
private BufferedImage image = new BufferedImage(WIDTH, HEIGHT, BufferedImage.TYPE_INT_RGB);
private int[] pixels = ((DataBufferInt) image.getRaster().getDataBuffer()).getData();
public static SpriteSheet sheet;
public static Sprite enemy1;
public static Sprite enemy2;
public static Sprite enemy3;
public Game() {
setMinimumSize(new Dimension(WIDTH * SCALE, HEIGHT * SCALE));
setMaximumSize(new Dimension(WIDTH * SCALE, HEIGHT * SCALE));
setPreferredSize(new Dimension(WIDTH * SCALE, HEIGHT * SCALE));
frame = new JFrame(NAME);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setLayout(new BorderLayout());
frame.add(this, BorderLayout.CENTER);
frame.pack();
frame.setResizable(false);
frame.setLocationRelativeTo(null);
frame.setVisible(true);
}
private void init(){
sheet = new SpriteSheet("/sprite_sheet.png");
enemy1 = new Sprite(sheet, 1, 1);
}
public synchronized void start(){
running = true;
new Thread(this).start();
}
public synchronized void stop(){
running = false;
}
public void run() {
init();
long lastTime = System.nanoTime();
double nsPerTick = 1000000000D/60D;
int ticks = 0;
int frames = 0;
long lastTimer = System.currentTimeMillis();
double delta = 0;
while(running){
long now = System.nanoTime();
delta += (now - lastTime) / nsPerTick;
lastTime = now;
boolean shouldRender = false;
while(delta >= 1){
ticks++;
tick();
delta -= 1;
shouldRender = true;
}
if(shouldRender){
frames++;
render();
}
if(System.currentTimeMillis() - lastTimer >= 1000){
lastTimer += 1000;
System.out.println("Frames: " + frames + ", Ticks:" + ticks);
ticks = 0;
frames = 0;
}
}
}
private void tick() {
tickCount++;
for(int i = 0; i < pixels.length; i++){
pixels[i] = i * tickCount * i * tickCount;
}
}
private void render() {
BufferStrategy bs = getBufferStrategy();
if(bs == null){
createBufferStrategy(3);
return;
}
Graphics g = bs.getDrawGraphics();
g.setColor(Color.BLACK);
g.fillRect(0, 0, getWidth(), getHeight());
g.drawImage(image, 0, 0, getWidth(), getHeight(), null);
g.dispose();
bs.show();
}
public static void main(String[] args){
new Game().start();
}
}
SpriteSheet + Sprite:
package com.vos.rekenspel.gfx;
public class SpriteSheet {
private BufferedImage sheet;
public SpriteSheet(String path){
try {
sheet = ImageIO.read(getClass().getResource(path));
} catch (IOException e) {
e.printStackTrace();
}
}
public BufferedImage getSprite(int x, int y){
return sheet.getSubimage(x*8-8, y*8-8, 8, 8);
}
}
package com.vos.rekenspel.gfx;
public class Sprite {
public static SpriteSheet sheet;
public BufferedImage image;
public Sprite(SpriteSheet sheet, int x, int y){
image = sheet.getSprite(x, y);
}
public BufferedImage getBufferedImage(){
return image;
}
}
Enemy + Entity:
package com.vos.rekenspel.entity;
public class Enemy extends Entity{
public Enemy(int x, int y, int width, int height, boolean solid) {
super(x, y, width, height, solid);
}
public void render(Graphics g){
g.drawImage(Game.enemy1.getBufferedImage(), x, y, width, height, null);
}
}
package com.vos.rekenspel.entity;
public class Entity {
public int x, y;
public int width, height;
public boolean solid;
public Entity(int x, int y, int width, int height, boolean solid){
this.x = x;
this.y = y;
this.width = width;
this.height = height;
this.solid = solid;
}
public void render(Graphics g){
}
}
But I can't get it appear on screen.
Does anyone know a solution?
Thanks in advance.
Kind regards,
Tom
Your render method from Enemy class is never called.

Java changing colour of shape

i'm trying to make a rectangle in Java, done. I can also fill it in with solid colour, done. But I want to actually change the solid colour of the shape itself. I know with Graphics you can use g.setColor(); but I have had my component setup a special way as shown below:
public class Design extends JComponent {
private static final long serialVersionUID = 1L;
private List<Shape> shapesDraw = new ArrayList<Shape>();
private List<Shape> shapesFill = new ArrayList<Shape>();
GraphicsDevice gd = GraphicsEnvironment.getLocalGraphicsEnvironment().getDefaultScreenDevice();
int screenWidth = gd.getDisplayMode().getWidth();
int screenHeight = gd.getDisplayMode().getHeight();
public void paint(Graphics g) {
super.paintComponent(g);
Graphics2D g2d = (Graphics2D) g;
for(Shape s : shapesDraw){
g2d.draw(s);
}
for(Shape s : shapesFill){
g2d.fill(s);
}
}
public void drawRect(int xPos, int yPos, int width, int height) {
shapesDraw.add(new Rectangle(xPos, yPos, width, height));
repaint();
}
public void fillRect(int xPos, int yPos, int width, int height) {
shapesFill.add(new Rectangle(xPos, yPos, width, height));
repaint();
}
public void drawTriangle(int leftX, int topX, int rightX, int leftY, int topY, int rightY) {
shapesDraw.add(new Polygon(
new int[]{leftX, topX, rightX},
new int[]{leftY, topY, rightY},
3));
repaint();
}
public void fillTriangle(int leftX, int topX, int rightX, int leftY, int topY, int rightY) {
shapesFill.add(new Polygon(
new int[]{leftX, topX, rightX},
new int[]{leftY, topY, rightY},
3));
repaint();
}
public Dimension getPreferredSize() {
return new Dimension(screenWidth, screenHeight);
}
public int getWidth() {
return screenWidth;
}
public int getHeight() {
return screenHeight;
}
}
As you can see, instead of just drawing and filling, it uses a list to draw off of that. Is there a way I can change the colour inside the list< shape >? I preferably want the colour to be changeable inside each draw/fill shape.
Thanks for the help.
Updated from answer:
My class as follows from your ShapeWrapper example:
public class Design extends JComponent {
private static final long serialVersionUID = 1L;
private List<ShapeWrapper> shapesDraw = new ArrayList<ShapeWrapper>();
private List<ShapeWrapper> shapesFill = new ArrayList<ShapeWrapper>();
GraphicsDevice gd = GraphicsEnvironment.getLocalGraphicsEnvironment().getDefaultScreenDevice();
int screenWidth = gd.getDisplayMode().getWidth();
int screenHeight = gd.getDisplayMode().getHeight();
public void paintComponent(Graphics g) {
super.paintComponent(g);
Graphics2D g2d = (Graphics2D) g;
for(ShapeWrapper s : shapesDraw){
g2d.setColor(s.color);
g2d.draw(s.shape);
}
for(ShapeWrapper s : shapesFill){
g2d.setColor(s.color);
g2d.fill(s.shape);
}
}
public void drawRect(int xPos, int yPos, int width, int height) {
shapesDraw.add(new Rectangle(xPos, yPos, width, height));
repaint();
}
public void fillRect(int xPos, int yPos, int width, int height) {
shapesFill.add(new Rectangle(xPos, yPos, width, height));
repaint();
}
public void drawTriangle(int leftX, int topX, int rightX, int leftY, int topY, int rightY) {
shapesDraw.add(new Polygon(
new int[]{leftX, topX, rightX},
new int[]{leftY, topY, rightY},
3));
repaint();
}
public void fillTriangle(int leftX, int topX, int rightX, int leftY, int topY, int rightY) {
shapesFill.add(new Polygon(
new int[]{leftX, topX, rightX},
new int[]{leftY, topY, rightY},
3));
repaint();
}
public Dimension getPreferredSize() {
return new Dimension(getWidth(), getHeight());
}
public int getWidth() {
return screenWidth;
}
public int getHeight() {
return screenHeight;
}
}
class ShapeWrapper {
Color color;
Shape shape;
public ShapeWrapper(Color color , Shape shape){
this.color = color;
this.shape = shape;
}
}
Now I am coding in Eclipse and everything works fine except for ONE thing!!
Every time it says shapesDraw/shapesFill.add() it says:
The method add(ShapeWrapper) in the type List is not applicable for the arguments (Rectangle)
So close! Please respond.
You can use something like:
private class ShapeWrapper {
private Color color;
private Shape shape;
public ShapeWrapper(Color color , Shape shape){
this.color = color;
this.shape = shape;
}
}
instead of plain Shape for storing Shape+Color.
And paint them like next :
public void paintComponent(Graphics g) {
super.paintComponent(g);
Graphics2D g2d = (Graphics2D) g;
for(ShapeWrapper s: shapesDraw){
g2d.setColor(s.color);
g2d.draw(s.shape);
}
for(ShapeWrappers s : shapesFill){
g2d.setColor(s.color);
g2d.fill(s.shape);
}
}
EDIT: according your exception, you try to add to typed list(ShapeWrapper) an object of another class(Shape), fix your methods like next :
public void drawRect(int xPos, int yPos, int width, int height) {
ShapeWrapper wr = new ShapeWrapper(Color.RED,new Rectangle(xPos, yPos, width, height));
shapesDraw.add(wr);
repaint();
}

Categories

Resources