Get object who called current object - java

I have a class Player, with a an object player_1, and an another class Weapon.
From my object player_1 i call a method who is located in class Weapon player_1.getWeapon().changeDurability(int x)
void changeDurability( int x) {
// changing durability
// and then i want to do something like this :
if( durability <= 0) player1.setWeaponBroken(true)
}
But i don't know how to get the player1 from the Weapon object,
and is there a way to do this instead of changing the method to something like this:
void changeDurability(Player player, int x)
Thanks in advance for any helping answers.

Whether or not a weapon is broken is information that belongs to that weapon, not to the player using it. I would recommend that you move the isBroken variable to the Weapon class and then have a method like this in your Player class:
boolean isWeaponBroken(){
return this.getWeapon().isBroken
}

You may fix your call to the player's weapon - without fixing Weapon class:
// Player code
public void changeWeaponDurability(int x) {
player_1.getWeapon().changeDurability(x);
if (player_1.getWeapon().getDurability() <= 0) {
player_1.setWeaponBroken(true);
}
}

Related

Accessing an object of a class from another class object

Starting of I want to apologise for my english as I'm not a native speaker. The title might be a bit off since I was not sure how to phrase it but hopefully it will come through once I show my code.
The problem I'm phasing is I want to use the shop class to handle any purchases while storing the money variable on the player class.
Is there any way to access the money integer of the player class without creating an object of the player class in the shop class ?
I was thinking about using a static integer to store the data in but from what I've read online its bad practice to use static datatypes.
public class Beta {
public static void main(String[] args) {
Player p1 = new Player("Test");
Shop s1 = new Shop();
p1.setMoney(100);
s1.clerk(p1.getMoney());
}
}
public class Player {
private int money;
private String name;
public Player(String name) {
this.name = name;
}
public int getMoney() {
return money;
}
public void setMoney(int x) {
this.money +=x;
}
}
public class Shop {
private int money;
public void clerk(int x) {
this.money = x;
if (this.money >= total) {
question4 = false;
System.out.println("Your purchase was successful!");
if (blue > 0) {
this.addInventory("Blue", blue);
}
if (red > 0) {
this.addInventory("Red", red);
}
if (green > 0) {
this.addInventory("Green", green);
}
}
else {
question4 = false;
System.out.println("Sorry you cant afford that!");
}
}
}
}
So I cut down my code to show you only the essential parts.
What I want to do is access p1:s money variable from the player class from within the Shop class.
So far I have been passing the variable when calling it from main. Is this the only option I have or can it be accessed in any other way ?
Any help would be much appreciated!
I believe the option that follows Object-Oriented Programming principles best is to pass the actual Player in as an argument, instead of just the money.
Basically, passing just the player's money in instead of the player themselves is like just handing your wallet over to the cashier. You wouldn't do that, right?
This way, the clerk can ask the customer if they have enough money by calling player.getMoney(), and the customer can tell them the answer.
After making the purchase, the player can remove the money from their wallet themselves when the clerk asks them to via player.setMoney().
Now, you asked in a comment about "passing the actual player as an argument without creating a new object of the player class." Java passes arguments by value, and all objects' values are simply the address that hold the information for that particular instance.
So for Player p1 in Beta, let's pretend all of p1's information is stored in a block starting at...let's say, address 21343. In this case, the variable p1 only contains that single number, 21343.
Since Java passes by value, then when you call s1.clerk(Player player), the player variable will also contain 21343. Since it's editing the items contained at the same address, you've essentially passed on p1 itself instead of creating a new Player. In short, the clerk and the main method work with the same object.
The fact that Java passes by value is also why passing just the player's money in doesn't adjust it automatically: The money is an int rather than an object. Since it's an int, when you pass it to the clerk, you're just saying "Hey, clerk, this is the amount of money being worked with." But the clerk has no idea who the money belongs to, so while it can take money, or even give it some, it's essentially just setting it down on the counter, and it's the responsibility of the player to pick it up from there when they're done. By passing in the player instead, the clerk knows who the money belongs to because it's actually asking the player how much money they have.
Another potential solution would be to make p1 and s1 static variables in the Beta class. It'd look something like this:
public class Player
{
public static Player p1;
public static Shop s1;
public static void main(String[] args)
{
p1 = new Player("Test");
s1 = new Shop();
p1.setMoney(100);
s1.clerk(p1.getMoney());
}
}
From there, you'd import the Beta class in Shop, then call Beta.p1 in Shop to access p1.
Hope this helps!

how to use method on specific object from arraylist

EDIT2: Sorry all... I believe it is due to the lack of understanding of question that cause this misconception. After reading through, I think what they want is for the return value of getWinningPoint() be the biggest number among the players and yet still <=21. so that in the game output, can loop each player to get their card point again and compare it to this winningpoint. I thank all of your input and help. Moderator or Admin can close this thread. Thanks again.
I would like to find out how to access the particular object in the arraylist so that i can cast the method on it. In a overall view, I am able to make method that apply to all items in the arraylist of players (distributeCardsToPlayer). But my 2nd method of getWinningPoints() is a int that sum up all the cards the particular player in arraylist players have. The winningPoint is a individual result which will ultimately be used in printWinners() method. I'm only familiar with accessing a obj with "Player player = players.get(0);" but in this case the "player" itself will be calling getWinningPoints() to check their own result.
P.S - I am not sure how to put it properly,and hopefully someone can point me to the right direction.
import java.util.*;
public class ModifiedBlackJack
{
protected ArrayList<Card> gameDeck;
protected ArrayList<Player> players;
public ModifiedBlackJack(ArrayList<Player> players)
{
this.players=players;
}
public void distributeCardsToPlayers()
{
Scanner console = new Scanner(System.in);
for (Player player : players)
{
player.drawACard(getACardFromDeck());
player.drawACard(getACardFromDeck());
System.out.println(player.getName()+": " + player.toString());
System.out.print("Draw another card? (y/n): ");
char input = console.nextLine().toLowerCase().charAt(0);
if(input == 'y')
{
player.drawACard(getACardFromDeck());
}
}
EDIT2: After reading through, I think what they want is for the return value of getWinningPoint() be the biggest number among the players and yet still <=21. so that in the game output, can loop each player to get their card point again and compare it to this winningpoint.
public int getWinningPoints()
{
int wp=0;;
int point=0;
for (Player player:players)
{
point = player.getCardsPoints();
if (point>=21 && point>wp)
{
wp=point;
}
}
return wp;
}
In the Player class, there is a function for summing up all the cards point
public int getCardsPoints()
{
int point=0;
for (Card c: cards)
{
point=point+c.getPoints();
}
return point;
}
I am new to java and any help or guidance is very much appreciated.
Thank You
You may be overthinking this, and the method getWinningPoints isn't entirely required.
Because you already have getCardsPoints declared in Player, and you already have an instance of Player to work with in your loop, the only thing you realistically need to do is...invoke it.
System.out.println(player.getName() + "Chips: " + player.getChips() + "[]" + player.getCardsPoints());
Whatever conditions you need to satisfy the min parameter should be done inside of this loop; that is, conditionally print the values that are larger than min.
If you want to invoke a Player class method you need to have a player object to call a method that it "owns".
Pass the player object to the method and accept the player object in getWinningPoints().
Call
getWinningPoints(player)
Declaration
public int getWinningPoints(Player localPlayer)
{
return localPlayer.getCardsPoints();
}

How do I check if I have just clicked on a certain object from an array?

Basicly I am creating a game that you click on falling objects, E.G cookies, and I need to know how to check and see if a certain cookie has been pressed so it can disappear but the problem is that its in an array.
Here is a bit of my code:
Input class...
public class Input implements MouseListener, MouseMotionListener{
#Override
public void mousePressed(MouseEvent e) {
if(e.getSource().equals(MainGame.CG)){
if(MainGame.MG.inGame){
//There is actually something else here but its classified (haha sorry about that)
if(e.getPoint().x > /*I NEED SOMETHING HERE*/){
//tells you if the object has been pressed
MainGame.CG.cookieClicked = true; //CG = ClickerGame
}
}
}
}
}
class with array...
public class ClickerGame extends JPanel{
public int amount;
public FallingObject[] fo = new FallingObject[120]; //THE ARRAY I'M HAVING TROUBLES WITH
/*THE REST IS A SECRET (SORRY ABOUT THAT)*/
}
If you don't understand here is a picture to demonstrate what I need...
In order to avoid having to check the coordinates of 120 different items on each click, make every element inside FallingObject[] aware of three things:
Its own area of influence (see sn00fy's answer)
The containing class (in this case probably ClickerGame
Its location in the array (an int)
To do this, you would need to change your FallingObject constructor to look something like this:
public void FallingObject(ClickerGame master, int index); //add whatever else is needed for Falling Object.
Then you could instantiate the array as follows.
for(int i = 0; i < 120; i++) {
fo[i] = new FallingObject(this, i ); //add anything else needed for the constructor
}
Then each FallingObject is responsible for its own state, and when clicked it is able to report back to the ClickerGame instance. All you need now is a method in ClickerGame which each FallingObject can call.
public void clickedObj(int index) {
FallingObject temp = null;
if(index >= 0 && index < 120) {
temp = fo[index];
//Do stuff with temp :)
}
}
To call this method from within FallingObject just reference the 'master' variable (which you should probably save as a global variable within the class.
You have to check every element in your FallingObject[] array if it intersects with the mouse pointer coordinates at the moment of the click.
You can implement a simple rectangle test or use a circle for each cookie as explained here:
Equation for testing if a point is inside a circle

Creating Array of weapons for Math.Random to choose from

I am just a little bit confused as of what to do. I have Two Weapons Classes. One for the M16 and another for the M4. I then have those Classes implementing an interface named Armory. But I am having issues with the Combat class. In the combat class I have a Random number Generator that will generate a random number and depending on what number it is, will either give the player a weapon or do nothing. I will post the Code Below:
Interface:
public interface Armory {
public Integer weaponAmmo(int wepAmmo);
public Integer weaponDamage(int wepDamage);
public String weaponName(String wepName);
}
M4 Class(M4 and M16 Classes are the same except for damage and ammo amounts):
public class M4 implements Armory {
public Integer weaponAmmo(int wepAmmo) {
wepAmmo = 10;
return wepAmmo;
}
public Integer weaponDamage(int wepDamage) {
wepDamage = 2;
return wepDamage;
}
public String weaponName(String wepName) {
wepName = "M4";
return wepName;
}
And Finally, the Combat Class(This is where I am having Issues):
public class Combat {
final int chanceOfDrop = 3;
Weapons[] wepArray = {new M4(), new M16()}; //Issues here.. Don't really know how to implement this.
static boolean[] hasWeapon = {false, true};
public static int ranNumberGen(int chanceOfDrop) {
return (int) (Math.random()*1);
}
private void enemyDead() {
boolean canDrop = false;
if(ranNumberGen(chanceOfDrop)==0){
canDrop = true;
}
if(canDrop == true){
givePlayerWeapon(wepArray[Combat.ranNumberGen(wepArray.length)] } //Issues here also.
private static void givePlayerWeapon(int w) {
hasWeapon[w] = true;
for (int i = 0; i < hasWeapon.length; ++i)
{
if (hasWeapon[i]) System.out.println(( wepArray[i]).weaponName()); //And, last but not least, I am having Issues here
}
}
}
NOTE: I have a Weapons Class, But nothing is in it. I don't really know what to put in it.
Any Suggestions?
Thanks in advance:
Shandan
Several issues -
A. To put m16 and m14 elements in the weapons array , these classes must either extend (if Weapons is a class) or implmeent (if weapons is interface) Weapons.
Another option is to have a method of
Weapons toWeapons() in both M16 and M14 classes.
B. Correct me if I'm wrong (Not native english speaker - but Armory is a place that provides Weapons, so your choice of name is not good.
M16 and M14 should implement an interface named "Weapon" and this (In my humble opinion) should be the type of the array.
C. If I understood, you want to provide in some cases no weapon to the user -
One way to have this done, and not get into ugly if (to check existence or not) is to have a NoWeapon class implements Weapon (in your current code - implements Armory).
Its methods will have an applicative meaning of "do nothing".
For example -
weaponAmmo will always return 0.

Creating weapon classes and a Combat Class

I am creating a text based game and I am having some issues.. This is what I have so far. So far I have a Combat Class, and two Classes for two different Weapons. I am trying to assign hit points to the weapons themselves. But my biggest issue is in the Combat class. I am trying to create it to were there will be random weapon drops at random times and also random Weapons. So far in the Combat class I have this:
public class Combat {
final int chanceOfDrop = 3;
static Weapons[] wepArray = {new M4(), new M16()}
static boolean[] hasWeapon = {false, true};
public static int ranNumberGen(int chanceOfDrop) {
return (int) (Math.random()*1);
}
private void enemyDead() {
boolean canDrop = false;
if(ranNumberGen(chanceOfDrop)==0){
canDrop = true;
}
if(canDrop == true){
givePlayerWeapon(Weapon[Combat.ranNumberGen(Weapons.length)]);
}
private static void givePlayerWeapon(int w) {
hasWeapon[w] = true;
for w <(Weapons.length-1) {
if has weapon[w] {
System.out.println(wepArray[w].getWeaponName);
}
}
}
}
}
}
I have issues when I am creating the new M4(), and the new M16() it says Type mismatch: cannot convert form M4 to Weapons. I do have a class named Weapons, could that be the problem?
And here is my M4 Class, both M4 and M16 Classes are identical
public abstract class M4 {
private Integer weaponDamage = 5;
private Integer weaponAmmo = 25;
private String weaponName = "M4";
public M4(String name, int ammo, int damage) {
name = weaponName;
ammo = weaponAmmo;
damage = weaponDamage;
}
public String getWeaponName() {
return weaponName;
}
public Integer getAmmo() {
return weaponAmmo;
}
public Integer getDamage() {
return weaponDamage;
}
}
I don't think I have any issues here. Maybe my problem lies within this though. Although, I have a Weapons class, but nothing in it. Do I need that?
A few things to fix at first sight:
Create a generic Weapon class that defines some properties that apply to each weapon, like name, damage, ammo, scope multiplier, etc... Then create subclasses for Weapon, like M4 and M16, that specify the properties and eventually add weapon-specific properties.
Add brackets to this line:
System.out.println(wepArray[w].getWeaponName); // Change to getWeaponName()
Remove the abstract keyword from M4.
Fix the ranNumberGen method because it will always return 0 right now. Math.random() returns a float in the range [0,1[. This means that casting it to an int will always result in 0. Multiply it by n to have a random int in the range of [0, n[. You probably want this:
public static int ranNumberGen(int max) {
return (int) (Math.random() * max);
}
Change this line:
givePlayerWeapon(Weapon[Combat.ranNumberGen(Weapons.length)]);
to:
givePlayerWeapon(wepArray[Combat.ranNumberGen(wepArray.length)]);
The syntax of a for-loop is like this:
for (variable-initialization; condition; increment)
So in your case, you want:
for (int i = 0; i < hasWeapon.length; ++i)
{
if (hasWeapon[i]) System.out.println(wepArray[i].getWeaponName());
}
You might want to revisit your decision to use an inheritance-style heirarchy for game objects before it is too late.
In practice, I've found a component-entity model and/or prototype model to be much more effective. You could take a look at the code in my old Java roguelike game Tyrant for inspiration:
Weapon definitions: mikera/tyrant/Weapon.java (Github is down right now so can't find the exact link, but should be easy enough to Google)
The idea is that you make your objects by setting properties / composing compoenents in a Map-like game object rather than using static inheritance.
When you want to create a random weapon in this model, you can just get a list of all the possible weapon prototypes, and clone one of them at random to make a new weapon.
the mean of abstract in "public abstract class M4" is that you cannot make a new object with this class.
So you can put all commons fields of your weapons in the weapon class and make m4 and m16 extends the weapon and you code would compile.

Categories