Hi im having trouble with how to user the super() keyword properly. It's a bit difficult to explain so please try to understand.
So I have a class called "Window" which is a subclass of another class called "Room".
This is Room class with a constructor
public class Room {
private Position position;
private Color color;
public Room(Position pos, Color colour){
this.position = pos;
this.color = color;
}
}
SO I want to give the doors a color Color.RED A Window object is constructed with an input position parameter.
What I have so far is:
public class Window extends Room{
private Color color;
public Window(Position position, Color color) {
super(position, color);
this.colour = Color.RED;
}
However in my other classes there is code that create a new Window with only a position parameter
This is example code
public class example{
private Window window;
private Position position;
public example() {
}
#Before
public void create() {
position = new Position(4,3);
window = new Window(position);
}
So then it becomes a required and found error, telling me that the length is not right. I understand what the error is telling me.
So here is my question. How do I redo the Window constructor so that it will satisfy both the super class and my other classes without those classes being changed.
Create new constructor in Window and set default color.
public Window(Position position) {
//Set default color
super(position, Color.RED);
this.colour = Color.RED;
}
Add another constructor to your Window class:
public class Window extends Room {
public Window(Position position) {
super(position, null);
}
Alternatively, define a default color which gets passed instead of null.
Related
SOLVED: The set setRoomImage method was never called on the RoomTile Object. Thanks to #sorifiend for noticing this!
I currently place JLabels using this method:
public void spawnItem(Entity e, int x, int y, int i, int j) {
bgLabel[i][j] = new JLabel();
bgLabel[i][j].setBounds(x,y,e.width,e.height);
bgLabel[i][j].setIcon(e.sprite);
layeredPane.add(bgLabel[i][j], e.layer);
}
Where bgLabel[][] is an array of JLabels and e.sprite is an imageIcon as shown in the Entity Class below. As well, e.layer is the appropriate Integer (i.e. 0, 100, 200).
The Entity Class looks like this:
import javax.swing.*;
public class Entity {
public int width, height;
ImageIcon sprite;
Integer layer;
}
And I extend the entity class like this:
import java.net.URL;
public class RoomTile extends Entity{
boolean light;
public RoomTile(boolean isLight) {
height = 52;
width = 52;
layer = 0;
light = isLight;
}
public void setRoomImage(String s) {
URL url;
if (light) {
url = getClass().getResource("Assets/" + s + ".png");
} else {
url = getClass().getResource("Assets/Dark" + s + ".png");
}
sprite = new ImageIcon(url);
}
}
All JLabels are placed by nested for loop iterating over a 2d array, the object is then added to the layered pane using the spawnItem method. This all works properly and a grid of objects, such as rooms, are placed and visible. However, when attempting to change the icon of these JLabels, they simply disappear.
I am using the method setLight to receive the label that is desired to be changed:
public void setLight(int i, int j) {
RoomTile lightRoom = new RoomTile(true);
bgLabel[i][j].setIcon(lightRoom.sprite);
repaint();
revalidate();
}
The setLight method is within a class which extends JFrame.
When setLight is called, the JLabel at the grid position provided, simply disappears, rather than its icon changing. I'm not sure where I've gone wrong and any help would be greatly appreciated.
I have a JPanel that I draw upon. The shapes I draw are some objects stored in a list. I would like to register MouseOvers over these drawn objects. What I am currently doing is adding a MouseMotionListener that checks the list of objects for a hit every time the mouse moves. This is of course pretty inefficient once there are a lot of objects. Is there a better way to check for MouseOvers than just checking all the objects every time the mouse moves?
Here is a minimal example:
class Ui.java:
public class Ui {
private static JFrame frame;
private static DrawPanel drawPanel;
public static void main(String[] args) {
SwingUtilities.invokeLater(() -> { createGui();
});
}
private static void createGui() {
frame = new JFrame("Test");
drawPanel = new DrawPanel();
frame.setContentPane(drawPanel);
frame.pack();
frame.setVisible(true);
frame.setExtendedState(JFrame.MAXIMIZED_BOTH);
}
}
class SomeObject.java:
public class SomeObject {
//class that represents some object that will be drawn. note that this is
//just a minmal example and that in my actual application, there are
//other aspects and functions to this class that have nothing to do with drawing.
//This is just kept small for the sake being a minimal example
private String id;
private Point2D origin;
private int length;
private int height;
public SomeObject(String id, Point2D origin, int length, int height) {
this.id = id;
this.origin = origin;
this.length = length;
this.height = height;
}
public String getId() {
return id;
}
public Point2D getOrigin() {
return origin;
}
public int getLength() {
return length;
}
public int getHeight() {
return height;
}
}
class CustomMouseMotionListener.java:
public class CustomMouseMotionListener implements java.awt.event.MouseMotionListener {
public CustomMouseMotionListener() { }
#Override
public void mouseDragged(MouseEvent e) {
}
#Override
public void mouseMoved(MouseEvent e) {
for (SomeObject object: DrawPanel.objectsToDraw) {
Shape s = new Rectangle((int)object.getOrigin().getX(), (int)object.getOrigin().getY(), object.getLength(), object.getHeight());
if (s.contains(e.getPoint())) {
System.out.println("hit: " + object.getId());
}
}
}
}
class DrawPanel.java:
public class DrawPanel extends JPanel {
public static List<SomeObject> objectsToDraw = new ArrayList<>();
public DrawPanel() {
objectsToDraw.add( new SomeObject("a", new Point2D.Float(20,1), 20,20));
objectsToDraw.add( new SomeObject("b", new Point2D.Float(20,45), 20,20));
addMouseMotionListener(new CustomMouseMotionListener());
setFocusable(true);
setVisible(true);
grabFocus();
}
protected void paintComponent(Graphics g) {
Graphics2D g2D = (Graphics2D) g;
super.paintComponent(g2D);
for (SomeObject object: objectsToDraw) {
g.drawRect((int)object.getOrigin().getX(), (int)object.getOrigin().getY(), object.getLength(), object.getHeight());
}
}
}
Instead of using your SomeObject class, i recommend using Shape or Area. The whole purpose of SomeObject seems to be to be turned into a Shape anyway, right? Not only that, but with an ArrayList of Shapes, you can eliminate creating rectangles for your shapes in every mouseMove.
BTW, years ago I put together a package for treating Areas like 1st class Components. You can see this here: https://sourceforge.net/p/tus/code/HEAD/tree/tjacobs/ui/shape/
(Start with AreaManager and AreaModel). Area has some advantages and disadvantages: Advantages: Easy to manage as a group, fairly easy to test if they are overlapping. Disadvantage: You lose the information about how the Area was constructed (ex. Polygon points, circle radius, etc)
You've already taken this a long way, so kudos to you. This answer is (a) responding to your question about efficiency, but also pointing you in some ways you could choose to go
There is more to SomeObject than just being drawn, so I think I can't just replace it with Shape,
Then you keep a Rectangle instance as part of your SomeObject class, instead of your Point and length/height variables.
Then you modify your methods to return the values from the Rectangle.
This will prevent you from continually creating new Rectangle instances, make the process more memory efficient and reducing garbage collection.
But, you should also be able to extend the Rectangle class and add your extra functionality in the same way that you extend JPanel to add custom painting logic.
I need help calling different classes.
I want to create a class for, a menu, the game, an option menu, credits etc.
I just need to know how to call a different class
//Ok i have edited my post, hope i provided enough information.
game class
//Add Screens
private MenuScreen menuScreen;
public final static int MENU=0;
public void changeScreens(int screen){
switch(screen){
case MENU:
if(menuScreen==null){
menuScreen=new MenuScreen(this);
}
}
}
//Render (When you click on the button)
if(drawplay) {
menuScreen=new MenuScreen(this);
setScreen( menuScreen);
//MenuScreen Class
ublic class MenuScreen implements Screen {
private rugby parent;
public MenuScreen(rugby rugby){
parent = rugby;
}
#Override
public void render(float delta) {
Gdx.app.log( "Play","Play" );
}
In my Game World class I wish to have an array of all of my enemies that are using a super class called Fighters.
public Array<Fighters> enemies;
I initialize it in the constructor of my Game World.
enemies = new Array<Fighters>();
This is the Fighters Super class.
public class Fighters {
protected Vector3 position;
protected Vector3 velocity;
protected Texture texture;
public Vector3 getPos() {
return position;
}
public Vector3 getVelocity() {
return velocity;
}
public Texture getTexture() {
return texture;
}
public void setPos(Vector3 newPos) {
position = newPos;
}
}
And a class that is a subclass of Fighters.
public class RedFighter extends Fighters {
public static final int value = 1;
public RedFighter() {
position = new Vector3(-10, -10, 0);
velocity = new Vector3(0, -10, 0);
texture = new Texture("redfighter.png");
}
}
When I call a method called spawn enemies, it should be filling the array with redfighters. However, I keep getting a NullPointException when I try to add it.
Fighters fighter;
fighter = new RedFighter();
enemies.add(fighter);
What am I doing wrong and how do I fix it? Thank you!
I figured it out!
Turns out that I didn't really have a constructor for my game world. Instead of using public GameWorld() as my declaration, I was using public void GameWorld() and so it didn't know it was my constructor. I realize that I should have posted the whole class. Thanks so much everyone! I'll make sure to post everything relevant next time.
As for where Array comes from, it's an array from the libgdx library.
I have a game that is similar to the game of life. the game deals with creating a house and rearranging the neighbors and such. I WANT to restart the game, simply need to set all of these values back to the original start values. How do I do that with a code. I understand the English of it but cant seem to convert it to a code.
This is some of my main program (If anyone want me to post the whole main program I can) but to make it simple and I dont want to confuse you guys.
So what I WANT: to restart the game, simply I want to set all of these values back to the original start values.
Some Of Main Program:
public class Ghetto extends JFrame implements ActionListener, MouseListener,MouseMotionListener
{
protected Grids theGrid;
JButton resetButton;
javax.swing.Timer timer; // generates ticks that drive the animation
public final static int SIZE = 5;
public final static int BLUE = 10;
public final static int RED = 8;
public final static int DIVERSITY_PERCENTAGE = 70;
public static void main(String[] args)
{
new Ghetto();
}
public Ghetto() {
setDefaultCloseOperation(EXIT_ON_CLOSE);
addMouseListener(this);
addMouseMotionListener(this);
setLayout(new FlowLayout());
theGrid = new Grids(SIZE, BLUE, RED, DIVERSITY_PERCENTAGE);
add(theGrid);
resetButton = new JButton("Reset");
add(resetButton);
resetButton.addActionListener(new ActionListener() {
#Override
public void actionPerformed(ActionEvent e) {
resetWithCurrent();
}
});
setSize(new Dimension(550, 600));
setVisible(true);
}
//public void resetWithCurrent()
//{
//}
#Override
public void actionPerformed(ActionEvent e)
{
timer.addActionListener(new ActionListener()
{
public void actionPerformed(ActionEvent e)
{
performStep();
}
});
}
}
Typically, the eaiest way to "reset" is not to. Just throw away the object and make a brand new one! The constructor will take care of everything for you, and you won't have to worry about missing something. If you really need to, you can make a reset method that performs all the necessary setting, and have the constructor call it. You have to be sure to catch everything, so in particular you can't use any field initializations that look like Foo x = bar and you can't use any initializer blocks.
The approach I suggest:
Ghetto ghetto = new Ghetto();
//Do stuff with the ghetto.
ghetto = new Ghetto();
//BLAM! The old ghetto is *gone*, and we have a new one to play with.
If these "values" are stored in a separate class, say class "GameProperties" then you just need to invoke the constructor by creating a new instance of the GameProperties.
The constructor should take care of assigning default values.
So, assuming you have an instance of GameProperties within Ghetto class named props:
Add new instance of GameProperties class and change resetWithCurrent in Ghetto class:
GameProperties props = new GameProperties();
public void resetWithCurrent(){
//This will reset the values to their defaults as defined in the constructor
props = new GameProperties();
}
Remove the values constants as you are using your GameProperties. Use the getters methods
to obtain the properties values.
Create new class:
public class GameProperties {
//assign initial default values
private int size= 5;
private int blue= 10;
private int red= 8;
private int diversity_percentage= 70;
//calling default constructor will set the properties default values
public GameProperties(){
}
public int getSize(){
return size;
}
public int getBlueValue(){
return size;
}
public int getRedValue(){
return size;
}
public int getDiversityPercentage(){
return diversity_percentage;
}
}
Hope it helps.