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

2015/3/9

Switch between players?

ProfessionalNoob ProfessionalNoob

2015/3/9

#
I am making a card game in Greenfoot similar to hearthstone. I'm wondering how to switch between players? I want to make it so that as soon as one player does something, he cannot do it again until the next player does something.
ProfessionalNoob ProfessionalNoob

2015/3/9

#
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
import greenfoot.*;  // (World, Actor, GreenfootImage, Greenfoot and MouseInfo)
import javax.swing.JOptionPane;
 
 
/**
 * Write a description of class CrabWorld here.
 *
 * @author (your name)
 * @version (a version number or a date)
 */
public class CrabWorld extends World
{
 
   int playerNumbers = 2;
   int turnNumber = 0;
   int GameState = 0;
   Player[] Player = new Player[2];
   Player what = new Player();
   public void act()
{
   repaint();
   addObject(Player[0], 436, 440);
   addObject(Player[1], 436, 100);
   GameState = playGame(turnNumber);
}
    public CrabWorld()
    {   
    super(845, 570, 1);
    SomeDice myDice = new SomeDice();
 
    for (int i = 0; i < 2; i ++)
    {
    int turn = 0;
    Player[i] = new Player();
    //addObject(Player[i], 436, 400 * i * 2);
     
     
    }
      
    
}
public int playGame(int myTurnNumber){
        int myRound = turnNumber/playerNumbers; //check what round we are on
        int myTurn = turnNumber%playerNumbers;//whose turn is it?
        showText(""+myRound, getWidth()-20, 10);
        showText(""+myTurn, getWidth()-20, 35);
         
        if (myRound == playerNumbers*15){
            return 0;//game over state gets reached here
        }
        
        //turnNumber += players[myTurn].takeTurn(1);
        //return gameState;
        return 2;
         
    }
 
   
}
Here's the code in my world class. Here's my cards class:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
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
{
    boolean cardPossessed[] = new boolean[2];
    int[] Cards = new int[2];
    private boolean click = false;
    int health = 30;
    SomeDice playerdice = new SomeDice();
    int count = 0;
    int number;
    boolean button;
 
    public int position1 = 1;
    public int position2 = 1;
 
    SomeDice dice = new SomeDice();
    GreenfootImage[] playerImages ;
    Cards[] playerCards = {new Cards(),new Cards(),new Cards(),new Cards(),new Cards(),new Cards()};
    public Player()
    {
         
    }
    
     
    public void CardSelect()
    {
 
           if(getY() > 400 && Greenfoot.mouseClicked(this))
           {  
               int value = Greenfoot.getRandomNumber(6);
               getWorld().addObject(playerCards[value], 150 * position1^2, 320);
    
               position1++;
               return;
        }
         if(getY() < 400 && Greenfoot.mouseClicked(this))
       {     
       int value = Greenfoot.getRandomNumber(6);
       getWorld().addObject(playerCards[value], 150 * position2^2 , 220);
     //  playerCards[value].Stats(number);
       if(number == 1)
       {
           setLocation(20,20);
        }
       position2++;
       return;       
    }
             
    }
  
    public void act()
    
        CardSelect();
    }
     
     
 
}
 
        
danpost danpost

2015/3/9

#
Let us clean things up a bit. Then we will work on each issue one at a time (as there are many). Cleaning up the world class code, I get this (it is basically what you have above -- I eliminated all the comments, rearranged it slightly, and took the liberty of renaming a few things; we will address the issues from there in the next post):
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
import greenfoot.*;
 
public class CardWorld extends World
{
    int playerCount = 2;
    int turn;
    int gameState;
    Player[] player = new Player[playerCount];
 
    public CardWorld()
    {   
        super(845, 570, 1);
        SomeDice myDice = new SomeDice();
        for (int i=0; i<playerCount; i++)
        {
            Player[i] = new Player();
        }
    }
 
    public void act()
    {
        repaint();
        addObject(player[0], 436, 440);
        addObject(player[1], 436, 100);
        gameState = playGame();
    }
 
    public int playGame()
    {
        int round = turn/playerCount; //check what round we are on
        int play = turn%playerCount; //whose turn is it?
        showText(""+round, getWidth()-20, 10);
        showText(""+play, getWidth()-20, 35);
        if (round == playerCount*15) return 0;//game over state gets reached here
        return 2;
    }
}
danpost danpost

2015/3/9

#
Line 22, 'repaint;', unless there is a specific reason to force a repainting of the world, you should not have to do so. That line can be removed. Lines 23 and 24, adding the players into the world, should be done in the constructor of the class, not in the act method. Remove those lines and insert the following line at line 17:
1
addObject(player[i], 436, 100+340*I);
Line 25, 'gameState = playGame();', should only be called when a turn has been made, not every act cycle. Remove the line. Lines 28 through 36, the 'playGame' method (in general), can be made to set the value of 'gameState' by itself. That is, instead of returning the int value, just set the value of 'gameState' to that value. Change 'int' on line 28 to 'void' and change both occurrences of 'return' to 'gameState = '. As a final note, in case you were not aware, in line 34, 'round == playerCount*15' will have the number of rounds be 30 for two players, 45 for three players, etc. (I did not know if that is actually what you wanted or not).
ProfessionalNoob ProfessionalNoob

2015/3/9

#
I was aware of the playercount thing. I'm wondering, however, how I can make it so that only one player object can run in the gamestate.
danpost danpost

2015/3/9

#
Post your revised World subclass code. Play should be controlled by the world. The actual steps required during play, that the players may do, should be coded as methods in the Player class.
ProfessionalNoob ProfessionalNoob

2015/3/9

#
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
import greenfoot.*;
  
public class CardWorld extends World
{
    int playerCount = 2;
    int turn;
    int gameState;
    Player[] Player = new Player[playerCount];
  
    public CardWorld()
    {   
        super(845, 570, 1);
        SomeDice myDice = new SomeDice();
        for (int i=0; i<playerCount; i++)
        {
            Player[i] = new Player();
            addObject(Player[i], 436, 100+340*i);
        }
    }
  
    public void act()
    {
        addObject(Player[0], 436, 440);
        addObject(Player[1], 436, 100);
    }
  
    public void playGame()
    {
        int round = turn/playerCount; //check what round we are on
        int play = turn%playerCount; //whose turn is it?
        showText(""+round, getWidth()-20, 10);
        showText(""+play, getWidth()-20, 35);
        if (round == playerCount*15) {
            gameState = 0;
            }//gme over state gets reached here
         
    }
}
danpost danpost

2015/3/9

#
Remove lines 23 and 24. Your players are being added into the world at line 17, in the constructor. Add an 'else' block to the final 'if', lines 33 through 35, at line 36:
1
else gameState = 2;
I do not know how the value of 'gameState' is used during game play; but, I suggest this to keep things basically as they were in your original code. Also, remove line 13. 'someDice' is not being used in the class.
danpost danpost

2015/3/10

#
Let us now go to the Player class. Cleaning it up, I removed all unused fields and unnecessary statements, and simplified what code remained (again, my next post will discuss remaining issues):
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
import greenfoot.*;
  
public class Player extends Actor
{
    int position;
    Cards[] playerCards = {new Cards(),new Cards(),new Cards(),new Cards(),new Cards(),new Cards()};
 
    public void cardSelect()
    {
        if (getY() > 400 && Greenfoot.mouseClicked(this))
        {  
            int value = Greenfoot.getRandomNumber(6);
            getWorld().addObject(playerCards[value], 150 * (position+1)^2, 320);
            position++;
        }
        else if (getY() < 400 && Greenfoot.mouseClicked(this))
        {     
            int value = Greenfoot.getRandomNumber(6);
            getWorld().addObject(playerCards[value], 150 * (position+1)^2 , 220);
            position++;
        }
    }
}
danpost danpost

2015/3/10

#
Now, because the world is supposed to control the play of the game, it should determine if a player can take a turn or not and therefore check for clicks on the player whose turn it is. This means that the 'cardSelect' method should be called from the world and the 'if' conditions within it will have already been determined to be true when called. This will reduce your 'cardSelect' method to the following:
1
2
3
4
5
6
7
8
9
10
public void cardSelect()
{
    if (position == 6) return;
    int value = Greenfoot.getRandomNumber(6-position);
    Cards card = playerCards[value];
    getWorld().addObject(card, 150*(position+1)^2, (760-getX())%440);
    position++;
    playerCards[value] = playerCards[6-position];
    playerCards[6-position] = card;
}
As written here, if all cards are already selected, nothing will happen when the method is called. Also, no card will be randomly picked twice because of the way I swapped the chosen card with the last possible one that could have been chosen. That card will no be outside the next set of possible cards to choose from. Another thing is that with a little calculation, the location to place the card can be determined by the location of the player and the value of 'position' at the time it is placed.
ProfessionalNoob ProfessionalNoob

2015/3/10

#
Thank you so much for your help so far. So what I do is call the CardSelect method in the world, correct? Like this?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
public void act()
   {
       addObject(Player[0], 436, 440);
       addObject(Player[1], 436, 100);
        
       if(Greenfoot.mouseClicked(Player[0]))
       {
           Player[0].CardSelect();
       }
       if(Greenfoot.mouseClicked(Player[1]))
       {
           Player[1].CardSelect();
       }
   }
danpost danpost

2015/3/10

#
What are you STILL doing with lines 3 and 4 in the act method. Please remove them. The act method, at this point, should be something like this:
1
2
3
4
5
6
7
public void act()
{
    if (Greenfoot.mouseClicked(player[turn%playerCount]))
    {
        player[turn%playerCount].cardSelect();
    }
}
ProfessionalNoob ProfessionalNoob

2015/3/10

#
Thank you very much for the help. That works.
You need to login to post a reply.