This site requires JavaScript, please enable it in your browser!
Greenfoot back
ProfessionalNoob
ProfessionalNoob wrote ...

2015/4/7

Have card attack only once?

1
2
ProfessionalNoob ProfessionalNoob

2015/4/7

#
I'm wondering how to make a card attack only once during the player's turn. I believe that setting a boolean value at the world or player class that resets once the turn has ended would work, but I don't know how to do that. Here's my world class:
import greenfoot.*; 
 
public class CardWorld extends World
{
    int playerCount = 2;
    int turn;
    int HeroPowers = 2;
    boolean turnBoolean;
    Player[] Player = new Player[playerCount];
    GreenfootImage FireBlast = new GreenfootImage("Spell.png");
    public GreenfootImage BackCard = new GreenfootImage("CardBack.png");
    Spells[] Spells = new Spells[2]; 
    Cards Card = new Cards();
    String Key = Greenfoot.getKey();

    public CardWorld()

    {    
        super(845, 570, 1);

        for (int i=0; i<playerCount; i++)
        {
            Player[i] = new Player(); 
            addObject(Player[i], 436, 100+340*i);
        }
        Player[1].setImage("Master2.png"); 
        for(int i = 0; i < HeroPowers; i++)
        {
            Spells[i] = new Spells();
            addObject(Spells[i], 535, 100+350*i); 
        }
    }
    
 
    public void act()
    {
        int value = turn%playerCount;
        if (Greenfoot.mouseClicked(Player[turn%playerCount]))
        {  
            Card.setImage(BackCard);
            Player[turn%playerCount].CardSelect();
            Player[turn%2].showCards();        
            Player[(turn+1)%2].hideCards();

            turn ++;             
        }
       

    }
     

}

        
    
    
Here's my card class:
import greenfoot.*;

/**
 * Write a description of class Ogre here.
 * 
 * @author (your name) 
 * @version (a version number or a date)
 */
public class Cards extends Actor
{
    
    private static Cards attacker;
    SomeDice dice = new SomeDice();
    int health;
    int cost;
    int attack;
    int number;
    boolean click;
    boolean Selected;
    public GreenfootSound[] CardSounds = { new GreenfootSound("KittyPlaySound.mp3"),
                                                         new GreenfootSound("HoundPlaySound.mp3"),
                                                         new GreenfootSound("OgrePlaySound.mp3"),
                                                         new GreenfootSound("RaptorPlaySound.mp3"),
                                                         new GreenfootSound("MurlocPlaySound.mp3"),
                                                         new GreenfootSound("GrommashPlaySound.mp3")};
    public static final GreenfootImage[] CardImages = { new GreenfootImage("Kitty.png"),
                                                         new GreenfootImage("Hound.png"),
                                                         new GreenfootImage("Ogre.png"),
                                                         new GreenfootImage("Raptor.png"),
                                                         new GreenfootImage("Murloc.png"),
                                                         new GreenfootImage("Grommash.png")};
                                                         
    private boolean visible;
    public GreenfootImage BackCard = new GreenfootImage("CardBack.png");
    boolean Grab = false;
    boolean MouseHover = false;
    boolean Deployment = false; 
    boolean OnBoard = false;
    boolean Dep = false;
    boolean val = false;
    boolean battleposition;
    boolean initialized = false;
    boolean attacked;
    boolean Grabbed;
    int NormalHeight = CardImages[number].getHeight();
    int NormalWidth = CardImages[number].getWidth(); 
    int position;
    int limit;
    int Cardvalue;
    boolean healthpoints;
    GifImage explosion = new GifImage("Explosion.gif");
    public void act() 
    {
   int x = getX();
   int y = getY();
   String HP = Integer.toString(health);
    if (click == false)
    { 
        Generation(); 
        click = true;
    }
        mouseDragging();  
        Deployment();
    if(!Dep && Deployment)
    {
        Position();
        position++; 
        Dep = true; 
    }
 
    
    
    if(Deployment && Greenfoot.mouseClicked(this))
    {
        getWorld().showText(""+HP, x+26, y+40);
        if (attacker == null) attacker = this;
        else if(attacker != this)
        {
         loseHealth(attacker.attack);
         attacker.loseHealth(attack);
         getWorld().showText(""+HP, x+26, y+40);
         if (health <= 0)
         {
             animateExplosion(); 
             getWorld().removeObject(this); 

         }
            attacker = null;
        }
        else attacker = null;

    }
    
}
    public void CardImage()
    {
        if(getY() > 400)
        {
            for (Object PlayerCards: getObjectsInRange(100, Cards.class))
            {
                Cards a = (Cards) PlayerCards;
                a.setImage(BackCard);
            }
        }
        
        if(getY() < 400)
        {
            for (Object PlayerCards: getObjectsInRange(100, Cards.class))
           {
               Cards a = (Cards) PlayerCards;
               a.setImage(BackCard);
           }
           
        }
    }
   public int Generation()
   {

    number = dice.Roll();
    CardImages[number].scale(NormalWidth / 2, NormalHeight / 2); 
    setImage(CardImages[number]);

    switch(number)
    {
        case 0:
            cost = 0;
            attack = 1;
            health = 1;
            return cost;
        case 1:
            cost = 7;
            attack = 9;
            health = 5;
            return cost;
        case 2:
            cost = 6;
            attack = 6;
            health = 7;
            return cost;
        case 3:
            cost = 2;
            attack = 3;
            health = 2;
            return cost;
        case 4:
            cost = 1;
            attack = 2;
            health = 1;
            return cost;
        case 5:
            cost = 8;
            attack = 4;
            health = 9;
            return cost;
    }
    return 10;
}
public void setVisible(boolean state)
{
    visible = state; 
    if(!Deployment)
    {
    if(visible == true)
    {
        setImage(CardImages[number]);
    }
    else if (visible == false)
    {
        setImage(BackCard);
    }
}
}
public void show()
{
    setVisible(true);
}
public void hide()
{
    setVisible(false);
}
public boolean isVisible()
{
    return visible;
}
public void mouseDragging()
{
    if (Greenfoot.mousePressed(this) && !Grab)
    {
        Grab = true;
        return;
    }
    if ((Greenfoot.mouseDragged(this)) && Grab)
    {
        MouseInfo Mouse = Greenfoot.getMouseInfo();
        setLocation(Mouse.getX(), Mouse.getY());
        return;
    }
    if (Greenfoot.mouseDragEnded(this) && Grab)
    {
        Grab = false;
        Grabbed = true; 
        return;
    }
}
public void Deployment()
{
    if(Deployment) return;
    if (!MouseHover && Greenfoot.mouseMoved(this))
        {
            CardImages[number].scale(NormalWidth, NormalHeight); 
            MouseHover = true;
        }
    if (MouseHover && Greenfoot.mouseMoved(null) && ! Greenfoot.mouseMoved(this))
        {
            CardImages[number].scale(NormalWidth / 2, NormalHeight / 2); 
            MouseHover = false;
        }
    if(MouseHover && Greenfoot.mouseMoved(null) && Greenfoot.mouseMoved(this) && getY() < 400 && Grabbed)
    {
        MouseHover = false;
        CardImages[number].scale(NormalWidth / 2, NormalHeight / 2); 
        Deployment = true; 
    }

}
public boolean DeploymentBoolean()
{
    return Deployment;
}
public void Position()
{

     if(limit < 8)
    {
       setLocation(130, 300);
       while (isTouching(Cards.class)) move(50);
       CardSounds[number].play();
       limit++;
    }
    
}
public void loseHealth(int damage)
{
    health -= damage;
}

public void animateExplosion()
{
                 setImage(explosion.getCurrentImage()); 
                 return;
               
}
}
ProfessionalNoob ProfessionalNoob

2015/4/7

#
Should I put the boolean in the cards or world class to make them attack only once?
danpost danpost

2015/4/8

#
Would not setting 'attacker' back to 'null' at the end of the first attack prevent an immediate second attack? (I believe you already have it in line 88)
ProfessionalNoob ProfessionalNoob

2015/4/9

#
danpost wrote...
Would not setting 'attacker' back to 'null' at the end of the first attack prevent an immediate second attack? (I believe you already have it in line 88)
Unfortunately, setting the attacker to null still allows me to attack as much as possible. Should I set my cards class null as well?
Super_Hippo Super_Hippo

2015/4/9

#
I don't think that it is related to your problem, but in line 79 and 80, both cards attack each other which might be what you want but only for the attacker it is checked if it died, not the one which was attacked. Your 'Generation' method returns an int, but you don't use this int.
ProfessionalNoob ProfessionalNoob

2015/4/9

#
Thanks for the insight on the other issue. Does this fix it?
f(Deployment && Greenfoot.mouseClicked(this))          //Method for attacking
    {
        getWorld().showText(""+HP, x+26, y+40);             //Shows current HP. 
        if (attacker == null) attacker = this;          //Attack yourself if nobody is attacking.
        else if(attacker != this)                   
        {
         loseHealth(attacker.attack);
         attacker.loseHealth(attack);               //If you are attacking someone, have both loose health.
         getWorld().showText(""+HP, x+26, y+40);        //Keep displaying HP.
         if (health <= 0)
         {
             getWorld().removeObject(this);             //Remove object.

         }
         if(attacker.health <= 0)
         {
             getWorld().removeObject(attacker); 
         }
            attacker = null;   
        }
        else attacker = null;

    }
Super_Hippo Super_Hippo

2015/4/9

#
I don't know if this solves the problem. There is something else which might be wrong. You still use the HP in line 9 which isn't updated to the new health. The displayed health of the one which got attacked doesn't update I think. What does the 'Deployment' boolean do btw? I think I would do something like this:
    if (Deployment && Greenfoot.mouseClicked(this))          //Method for attacking
    {
        //changed comment in next line, I think you misunderstood what it does
        if (attacker == null) attacker = this;          //set attacker
        else if(attacker != this)        //if there already is an attacker, attack this with the attacker
        {
             loseHealth(attacker.attack);
             attacker.loseHealth(attack);               //If you are attacking someone, have both loose health.
             attacker = null;
         }
    }
     
    public void loseHealth(int damage)
    {
        health -= damage;
        if (health<=0) getWorld().removeObject(this);
        else getWorld().showText(""+health, getX()+26, getY()+40); //updates displayed health
    }
What might cause the problem is that this code runs in all Cards objects if I understood it correctly and this somehow creates this bug then.
ProfessionalNoob ProfessionalNoob

2015/4/9

#
Should I add something in my player class?
Super_Hippo Super_Hippo

2015/4/9

#
What is the Player class doing or better, what are the objects of the Player class doing? You could put all the controlling things which effect the cards into the world class.
ProfessionalNoob ProfessionalNoob

2015/4/9

#
The only thing the player class truly does right now is add the card objects. However, I plan to make it so that each player can only select their own cards in the future.
import greenfoot.*;
import javax.swing.JOptionPane;
import java.util.ArrayList;
import java.util.List;
 
/**
 * Write a description of class Player here.
 * 
 * @author (your name) 
 * @version (a version number or a date)
 */
public class Player extends Actor
{
    int health = 30;                      //The player health

    int position;                         //Variable used for card positioning.  
    int CurrentMana;                      //Current mana
    int MaxMana;                          //Max mana
    Cards[] playerCards = {new Cards(),new Cards(),new Cards(),new Cards(),new Cards(),new Cards()}; 
    //Card object being declared.


    public Player()
    {
         int CurrentMana = 0; //Initializing mana variables
         int MaxMana = 0;
    }
    
     
   public void CardSelect()
   {

               CurrentMana ++;          //Increasing current and max mana
               MaxMana++; 
               int value = Greenfoot.getRandomNumber(6-position);        //Value used for cards indexing.
               if (position == 6) return;                   //Cannot have more than six cards.
               Cards card = playerCards[value];
               
               if(getY() > 400)                             //Determines player position for card positioning.
               {
               getWorld().addObject(card, 40 + (50*(position+1)^2), getY()+60);
            }
            
            if(getY() < 400)
            {
                getWorld().addObject(card, 40 + (50*(position+1)^2), getY() -40);
            }
               position++;                          //Increases value of position.
               playerCards[value] = playerCards[6-position];        //changes value based on position.
               playerCards[6-position] = card;              //Turns array value into a single variable. 
               if(card.Deployment && Greenfoot.mouseClicked(this))
               {
                   loseHealth(card.attack);         //Looses health if card attacks plaer.
               }
                
    }
              
   public void act() 
   {  
        int x = getX();                 //Get the location of player.
        int y = getY();
        
        getWorld().showText(""+health, x+26, y+40);     //Shows player health. 
       
       String manaDisplay = Integer.toString(CurrentMana);            
       String mana = Integer.toString(MaxMana);     
       getWorld().showText(manaDisplay, 600, 550);                    //Shows player mana.
       getWorld().showText("/" + mana, 620, 550);     
       
   }
    
    public void hideCards()
    {
        for (Cards Card : playerCards) Card.hide();         //Hide opponents cards.
    }
 
    public void showCards()
    {
        for (Cards Card : playerCards) Card.show();        //Show player's cards. 
    }
                                                         
    
    public void loseHealth(int damage)
    {
        health -= damage;               //Loose health based on attack value of card.
    }
}
  

 
        
Super_Hippo Super_Hippo

2015/4/10

#
I think I misunderstand the game play. There are two players and each have a maximum of 6 cards. One player chooses an own card and attacks a card of the opponent. Each card has health values and so on, but the player has a health value too. Why? If this is useful and should be as it is, only update the displayed health and mana when it is changed (in the loseHealth method). In line 35 you give 'value' a random number and you say that you use this int as an index. Why should an index be random? In line 36 you check if 'position' is 6. If it would be 6, line 35 would already give you an Exception because 'getRandomNumber' needs a positive argument (6-6=0), so swap lines 35 and 36. An array in line 49 for example could handle the 6 though. (The first element has the index 0.) In lines 25 and 26 you don't initialize the mana fields to 0. Instead, you create a new ones. This doesn't make sense, but it is also not needed because there are set to 0 when they are created (lines 17 and 18). To see that it doesn't work as you think, you can change the 0 in line 26 to 100 for example. You won't see any difference. In lines 41 and 46, you are using the ^ operator. I think you want to exponentiate there, but you don't. Example: If you want to calculate x*x (which is x^2), then you would use 'Math.pow(x,2)' and not 'x^2'.
ProfessionalNoob ProfessionalNoob

2015/4/11

#
The gameplay goes as follows: Each player has a current mana and a maximum mana. At the end of every player's turn, their maximum mana will raise by one. For example, player 1 will start with one mana. At the end of his turn, player 2 will also start with one mana. Player one will then start with two mana on his next turn. Each card has a "cost". The better the card, the greater the cost. Players have a health of 30 points. The goal of the game is to get the other player down from 30 health to 0. I believe making the index random will also add a bit more randomness to the deck. I do not want to exponentiate there.
ProfessionalNoob ProfessionalNoob

2015/4/11

#
I'm still wondering how to make a card attack only once.
ProfessionalNoob ProfessionalNoob

2015/4/11

#
This seems to do the trick:
    boolean hasAttacked; 
if(Deployment && Greenfoot.mouseClicked(this) && !hasAttacked)          //Method for attacking
    {
        //changed comment in next line, I think you misunderstood what it does
    if (attacker == null) attacker = this;          //set attacker
    else if(attacker != this)        //if there already is an attacker, attack this with the attacker
    {
         loseHealth(attacker.attack);
         attacker.loseHealth(attack);               //If you are attacking someone, have both loose health.
         attacker = null;
         hasAttacked = true; 
     }
    }
Though I need it to reset after every turn so it doesn't make it so that they can't attack for the whole game.
danpost danpost

2015/4/11

#
Ahhh -- I understand what you meant now. Another way would be to use a List object. If the card is not on the list, it can attack; once it attacks, it is added to the list; at the end of the turn, clear the list.
There are more replies on the next page.
1
2