How do I call a constructor? - java

I am currently done making a sokoban game with GUI and everything and I am working on optimzation, I would like to keep the objects as sensible as possible and therefore need to be able to call the constructor from a method in the class/object. Suppose:
public class BoardGame() {
public BoardGame)() {
this(1)
}
public BoardGame(int level){
//Do stuff, like calling filelevel-to-board loaderclass
}
How do I create a method that calls the constructor of this object/class in the object/class itself? Eg:
public BoardGame nextLevel() {
return BoardGame(currentLevel+1);
}
The above is apparently undefined!
Such that if I want to use this object in another class I should be able to do:
GameBoard sokoban = new GameBoard(); //lvl1
draw(GameBoard);
draw(GameBoard.nextLevel()); //draws lvl2

You need to use the new keyword to call the constructor.
public BoardGame nextLevel() {
return new BoardGame(currentLevel + 1);
}

Calling the constructor requires the new keyword and always creates a new instance. For instance, in your example code
GameBoard sokoban = new GameBoard(); //lvl1
draw(sokoban );
draw(sokoban.nextLevel()); //draws lvl2
sokoban <-- still level 1
Maybe you want the GameBoard to be mutable:
public class GameBoard {
public GameBoard() {
setLevel(1);
}
private void setLevel(int i) {
currentLevel = i;
....
}
public void nextLevel() {
setLevel(currentLevel+1);
}
}

Related

Variables (possibly) get out of scope

Ok, so have two classes Player and child class Classes. I use the child class to set the player stats inside main class through switch statement that lets user choose his class. But for some reason the set variables fall out of scope when executed in main class. For the love of me, I can't figure why is it happening
Here is the Player class:
public class Player {
private int HP;
private int ATK;
private int DEF;
private int DAMAGE;
void setHP(int a){
HP=a;
}
void setATK(int a){
ATK=a;
}
void setDEF(int a){
DEF=a;
}
void setDAMAGE(){
DAMAGE = damageCalculation();
}
int damageCalculation(){
int damage = (2*ATK);
return damage;
}
Player(String Class){
Classes classes = new Classes();
switch(Class){
case "Barbarian":
classes.Barbar();
System.out.println("Done");
break;
case "Rogue":
break;
default: System.out.println("Error");
}
}
void getStats(){
System.out.format("Player stats:"
+ "\nHP: %d"
+ "\nATK: %d"
+ "\nDEF: %d"
+ "\nDAMAGE: %d\n",HP,ATK,DEF,DAMAGE);
}
}
Here is the Classes class(note that in child class get stats return valid values):
public class Classes extends Player {
public void Barbar(){
Player player = new Player();
player.setHP(60);
player.setATK(15);
player.setDEF(25);
player.setDAMAGE();
player.getStats();
}
}
And here is the main class:
import java.util.Scanner;
public class SurvivalGame {
public static void main(String[] args) {
Scanner scan = new Scanner(System.in,"Windows-1250");
System.out.println("Enter your class");
Player player = new Player(scan.nextLine());
player.getStats(); //here getStats return zeros,
//possibly out of scope variables if player enters Barbarian
}
}
public void Barbar(){
Player player = new Player();
If you look closely you are creating a new Player and adding values to that, not the Player in main method.
You're creating an extra instance of Player that is never accessed. Just walk through your code:
/* Main Method */
// You get a new Player object using direct user input
// (Which is somewhat dangerous, you should do some data validation first)
Player player = new Player(scan.nextLine())
/* Player constructor */
// Let's say user entered correctly "Barbarian". You are in the process of constructing
// a new Player object when you call this:
classes.Barbar();
/* Barbar method */
// The very first line creates a brand new player - different from one you were
// in the process of constructing.
Player player = new Player();
// Then you assign values to the new Player, which goes out of scope as soon as the
// method ends.
Instead of having Classes extend Player (which seems a bit odd to me, to be honest), I'd just make the Barbar method belong to the Player class itself (which can then be called during your switch statement). Then you can just modify the current Player's values directly, instead of relying on a different class to do that for you.
For example:
public class Player
{
public Player(String class)
{
switch (class)
{
case "Barbarian":
Barbar();
break;
}
}
public void Barbar()
{
HP = 60;
ATK = 15;
DEF = 25;
setDAMAGE();
}
}
When you extend a class, you get something that is an instance of the superclass, but with the extra methods and fields that you choose to add in the subclass. So when you write
public class Classes extends Player {
//...
}
Your Classes instances already have the HP (etc.) fields in them. Your Barbar method can modify them without needing to create a new instance of Player:
public void Barbar(){
setHP(60);
setATK(15);
setDEF(25);
setDAMAGE();
getStats();
}
You're confusing composition and inheritance.

How to use a variable in two classes?

I need to be able to see in all of these classes if the variable is true.
public void performAction() {
if (door.intersects(HERO)) {
System.out.println("ActionPerformed!");
HeroX = 0;
HeroY = 0;
inside = true;
}
}
This is every time I press SPACE and now I want to draw the inside of the House.
In the Main class where I draw everything I want to say something like:
public void paintComponent(Graphics g) {
if (!inside) {
g.drawImage(Background, 0, 0, null);
achilles.Draw(g);
}else if (inside) {
g.drawImage(HouseInside, 0, 0, null);
}
}
I don't know how to change the "inside" in the Hero class and use it in the Main class. I have tried so many things and I don't know what to do.
inside is a property of a HERO object, so, if the property is public, you can access it with heroname.inside
If the property is private (which it generally should be), you have to use a public access function inside the HERO class, such as HERO.isInside, and set it with a setting function like HERO.setInside and HERO.setOutside.
this is often called "getters and setters"
What you probably want are global variables
public class Global{
public static int value;
}
You can then access them from anywhere:
Global.value;
If you Main class has a reference to all instances of the Hero class, then the usual best practice would be for the Hero class to expose a method like this:
public boolean isInside () {
return (inside);
}
If there is only ever one instance of the Hero class (unlikely, but ok), then one option is to make inside a public static variable like this:
public static boolean inside;
referenced from Main like this:
if (! Hero.inside) {
or make inside a private static variable with a getter like this:
private static boolean inside;
public static boolean isInside () {
return (inside);
}
referenced from Main like this:
if (! Hero.isInside ()) {
Try using a getter to get the inside attribute outside of Hero, and a setter to change it:
public class Hero {
private boolean inside;
...
public boolean isInside() {
return this.inside;
}
public void setInside(boolean inside) {
this.inside = inside;
}
}
I'd also recommend reading more about encapsulation; it'll give you a better idea about how to work with objects in Java.
You could model it differently:
public class House {
Location currentLocation=Location.OUTSIDE;
Map<Location, String> layout=new HashMap<>();
public House(){
layout.put(Location.INSIDE,"Draw the inner parts");
layout.put(Location.INSIDE,"Draw the outer parts");
}
public void enterDoor(){
currentLocation=(currentLocation==Location.OUTSIDE)?Location.INSIDE:Location.OUTSIDE;
}
public void draw(){
System.out.println(layout.get(currentLocation));
}
}
Here enterDoor is something, which could be fired by an event in your game-environment. So your House knows how to draw itself depending on its state.
Say your character moves to some coordinates (x|y), where the door is, the enterDooris called upon House, which in turn switches the layout.

Making a static duplicate of non-static integer

For my programming class in first year engineering I have to make a D-game in Java, with only very little knowledge of Java.
In one class I am generating a random integer via
public int rbug = (int)(Math.random() * 18);
every so many ticks. I have to use this integer in another class (in the requirements for an if-loop), and apparently it needs to be static. But when I change the variable to public int static, the value doesn't change any more.
Is there an easy way to solve this problem?
Edit: part of code added:
public int rbug = (int)(Math.random() * 18);
which is used in
public void render(Graphics g){
g.drawImage(bugs.get(rbug), (int)x, (int)y, null);
And in another class:
if(Physics.Collision(this, game.eb, i, BadBug.rbug)){
}
As error for BadBug.rbug I get the message
Cannot make a static reference to a non-static field
Using static to make things easier to access is not a very good ideal for design. You would want to make variables have a "getter" to access them from another class' instance, and possibly even a "setter". An example of this:
public class Test {
String sample = 1337;
public Test(int value) {
this.sample = value;
}
public Test(){}
public int getSample() {
return this.sample;
}
public void setSample(int setter) {
this.sample = setter;
}
}
An example of how these are used:
Test example = new Test();
System.out.println(example.getSample()); // Prints: 1337
example = new Test(-1);
System.out.println(example.getSample()); // Prints: -1
example.setSample(12345);
System.out.println(example.getSample()); // Prints: 12345
Now you might be thinking "How do I get a string from the class that made the instance variable within the class?". That's simple as well, when you construct a class, you can pass a value of the class instance itself to the constructor of the class:
public class Project {
private TestTwo example;
public void onEnable() {
this.example = new TestTwo(this);
this.example.printFromProject();
}
public int getSample() {
return 1337;
}
}
public class TestTwo {
private final Project project;
public TestTwo(Project project) {
this.project = project;
}
public void printFromProject() {
System.out.println(this.project.getSample());
}
}
This allows you to keep single instances of classes by passing around your main class instance.
To answer the question about the "static accessor", that can also be done like this:
public class Test {
public static int someGlobal = /* default value */;
}
Which allows setting and getting values through Test.someGlobal. Note however that I would still say that this is a horrible practice.
Do you want to get a new number every time that you want BadBug.rbug? Then convert it from a variable to a method.

How can I access a Local Variable which is an object from within another class? - Java

My understanding is that you can't do what I'm asking. If you look at the starred (*) commented errors in the code below, you can see what I'm trying to access. I feel like I need to be able to do this so that I can use a method to dynamically create many objects and then access all of those objects from other objects.
Is there a way to do this that I'm missing, or am I just messing something up? If not, how should I go about doing this to enable me to get the same functionality as below? If there's any way to do this other than passing the objects around, it would be appreciated (passing objects seems like so much work - especially with multi-dimensional arrays of objects - there should be an easy way to instantiate package-private objects that can be accessed anywhere else in the package). But if passing is the only way, please let me know the best way to do it, especially when I'm passing a two-dimensional array of a bunch of objects. Thanks!
package simpleclasswithinclasstest;
class Game {
static int boardSize;
Engine gameEngine;
Game() {
}
public void run() {
gameEngine = new Engine();
gameEngine.play();
}
public int getBoardSize() {
return boardSize;
}
}
class Engine {
int boardSize;
Engine() {
}
public void play() {
this.boardSize = currentGame.getBoardSize(); // *****1 Error is here.
// *****It doesn't recognize currentGame, but I want it to.
}
void doNothing() {
}
}
class Board {
Board() {
}
void Test() {
gameEngine.doNothing(); // 2 *****Error is here.
// *****It doesn't recognize gameEngine.
}
}
public class SimpleClassWithinClassTest {
static Game currentGame;
public static void main(String[] args) {
currentGame = new Game();
currentGame.run();
}
}
You will get access to gameEngine through your Board class by passing it as a parameter to Board. When you instantiate your Board, you could do something like this:
class Engine {
int boardSize;
Engine () {
Board board = new Board(this);
}
public void play() {
}
void doNothing() {
// magic stuff in here
}
}
class Board {
Engine engine;
Board (Engine gameEngine) {
this.engine = gameEngine
}
void Test() {
engine.doNothing(); // No error here :-) and this engine is your main one
}
}
Take a look at the concept of message-driven communication. Things might get clearer for you by reading this answer.
In the following picture, which I took from the answer linked above, you can imagine f as your engine object within the Engine class, and c as your engine within the Board class. You are actually manipulating the same object.
As for your other problem (the first one): it can't recognize currentGame because you don't have any variable with that name in your scope.
There is no variable of any type named 'currentGame' in scope at that point in the code.
Furthermore, while boardSize is a static package-protected variable, the method getBoardSize() is an instance variable. One possible solution is to make the method static and package protected, then you can do this:
public void play() {
this.boardSize = Game.getBoardSize();
}
This is like initializing an int variable in 1 function and trying to access it from another function.The objects(you are trying to access) are out of scope in the part of the code where you are trying to access.You can resolve this issue by sending this
as a parameter and recieving it as an object in the corresponding method.
We can use class reference to call static methods only. So you can make the play a static method.
class Engine {
int boardSize;
Engine() {
}
public void play() {
this.boardSize = currentGame.getBoardSize(); // *****1 Error is here.
// *****It doesn't recognize currentGame, but I want it to.
}
static void doNothing() {
}
}
class Board {
Board() {
}
void Test() {
Engine.doNothing();
}
}
The other way is to make an Object from the class and access the non static methods within that object.
class Engine {
int boardSize;
Engine() {
}
public void play() {
this.boardSize = currentGame.getBoardSize(); // *****1 Error is here.
// *****It doesn't recognize currentGame, but I want it to.
}
void doNothing() {
}
}
class Board {
Board() {
}
void Test() {
Engine gameEngine = new Engine();
gameEngine.doNothing();
}
}

java.lang.NullPointerException when filling an array of objects

There's something I'm missing here. with this code I get a java.lang.NullPointerException:
public static void main(String[] args) {
Board board = new Board();
board.Initialise();
}
public class Board {
private Obj[][] tableau;
public void Board() {
tableau = new Obj[8][8];
}
public void Fill_Board() {
tableau[0][0]= new Obj('B');
}
}
But with this other code I get no error. What I am doing wrong, and how to initialize properly this array of object?
public class Board {
private Obj[][] tableau = new Obj[8][8];
public void Board() {
}
public void Fill_Board() {
tableau[0][0]= new Obj('B');
}
}
Board() ends up being a member function and not a constructor, and therefore never gets called. The problem is the void keyword, which needs to be removed:
public Board() { /* removed the `void' */
tableau = new Obj[8][8];
}
I get no error when I run this code (changing Obj to an actual class), perhaps you can provide a more concrete example with a main method of what you're trying to do?
If you're looking at making a constructor then it needs to be the same name as your class, i.e. Tab and have no return type.
So you would need to add:
public Tab() {
// initialization code here
}
You're constructor will run whenever you create a new instance of that class. You want to use it to initialize all of your variables.
Tab t = new Tab(); // Constructor runs
Edit:
You're main method uses class Board but you have given us a class called Tab. I can assume that you really want class Board so you should change all Tab to Board in the above example, if that's what you're looking for.

Categories

Resources