BCE0024: ... does not have a visible constructor that matches the argument

Hi all,

I have tried nutting this issue out, and failed multiple times.
I tried searching existing posts, and understand why this is occuring.

However still being new to Unity (Particularly scripting) I am unable to find a solution to my issue.
I am learning from a book "Unity 3.x Game Development by example"by Ryan Creighton. (Excellent book btw)

Specific Error:
Assets/Scripts/GameScript.js(97,36): BCE0024: The type ‘Card’ does not have a visible constructor that matches the argument list ‘(String)’.

Entire Code from Script:
I believe the issue will be found in the last function “BuildDeck” but could be wrong.

var cols:int = 4; // the number of columns in the card grid
var rows:int = 4; // the number of rows in the card grid
var totalCards:int = 16;
var matchesNeededToWin:int = totalCards * 0.5; //If there are 16 cards the player needs to find 8 matches to clear the board
var matchesMade:int = 0; //At the outset, the player has not made any matches
var cardW:int = 100; //Each card's width and height is 100 pixels
var cardH:int = 100;
var aCards:Array; //We'll store all the cards we create int this array
var aGrid:Array; //This array will keep track of the shuffled, dealt cards
var aCardsFlipped:ArrayList; //This array will store the two cards that the player flips over
var playerCanClick:boolean; // We'll use this to flag to prevent the player from clicking buttons when we don't want him to
var playerHasWon:boolean=false; //Store whether or not the player has won. This should probably stat out false.

class Card extends System.Object 
{
	var isFaceUp:boolean = false;
	var isMatched:boolean = false;
	var img:String;
	
	function Card()
	{
		this.img = img;
	}
}

function Start () {
	playerCanClick = true; //Lets the player play.
	
	//Initialise the arrays as empty lists:
	aCards = new Array();
	aGrid = new Array();
	aCardsFlipped = new ArrayList();
	
	//Calls the Build Deck Function
	BuildDeck();
	
	for (i=0; i<rows; i++)
	{
		aGrid[i] = new Array(); //Create a new, empty array at index i
		
		for (j=0; j < cols; j++)
		{
			var someNum:int = Random.Range(0,aCards.length);
			aGrid[i][j] = aCards[someNum];
			aCards.RemoveAt(someNum);
		}
	}
}

function OnGUI(){
	GUILayout.BeginArea (Rect(0,0,Screen.width,Screen.height));
	BuildGrid();
	GUILayout.EndArea();
	print("building grid!");
}

function BuildGrid(){
	GUILayout.BeginVertical();
	GUILayout.FlexibleSpace();
	for (i=0; i<rows; i++)
	{
		GUILayout.BeginHorizontal();
		GUILayout.FlexibleSpace();
		for (j=0; j<cols; j++)
		{
			var card:Object = aGrid[i][j];
			if(GUILayout.Button(Resources.Load(card.img),
				GUILayout.Width(cardW)))
			{
				Debug.Log(card.img);
			}
		}
		GUILayout.FlexibleSpace();
		GUILayout.EndHorizontal();
	}
	GUILayout.FlexibleSpace();
	GUILayout.EndVertical();
}

function BuildDeck()
{
	var totalRobots:int = 4; //we've got four robots to work with
	//this stores a reference to a card
	
	for (i=0; i<totalRobots;i++)
	{
		var aRobotParts:Array = ["Head", "Arm", "leg"];
		for (j=0; j<2; j++)
		{
			var someNum:int = Random.Range(0, aRobotParts.Length);
			var theMissingPart:String = aRobotParts[someNum];
			
			aRobotParts.RemoveAt(someNum);
			
			var card:Object;
			
			card = new Card ("robot" + "Missing" + theMissingPart);
			aCards.Add(card);
			
			//card = new Card ("robot" +  (i + 1) + theMissingPart);
			//aCards.Add(card);
		}
	}
	
}

Thankyou in advance if anybody is able to assist or point me in the correct direction.

You are trying to use a constructor for the Card class that takes a string as a parameter but you only have one constructor defined with no parameters so you need a constructor like this:

function Card (string img)
{
     this.img = img;
}

Cheers markpdolby,

Upon review I had missed that, and makes sense to add the string as a parameter.
Thankyou for your prompt reply :slight_smile:

I have the same problem but your answer didn’t work for me. I’m a little further on in the chapter so my code looks like this:

	function Card (img, id:int)
	{
		this.img = img;
		this.id = id;
	}

but if I add “string” I get the error:

Assets/Scripts/GameScript2.js(51,31): BCE0043: Unexpected token: img.

I’m using Unity 4 Pro if that makes any difference?

Thanks for any suggestions,

B

Here’s my whole script in case I did anything stupid:

//#pragma strict
var cols:int = 4; // the number of columns in the card grid
var rows:int = 4; // the number of rows in the card grid
var totalCards:int = 16;
var matchesNeededToWin:int = totalCards * 0.5; // If there are 16 cards, the player needs to find 8 matches to clear the board
var matchesMade:int = 0; // At the outset, the player has not made any matches
var cardW:int = 100; // Each card's width and height is 100 pixels
var cardH:int = 100;
var aCards:Array; // We'll store all the cards we create in this array
var aGrid:Array; // This array will keep track of the shuffled, dealt cards
var aCardsFlipped:ArrayList; // This array will store the two cards that the player flips over
var playerCanClick:boolean; // We'll use this flag to prevent the player from clicking buttons when we don't want him to
var playerHasWon:boolean = false; // Store whether or not the player has won. This should probably start out false :)

function Start () 
	{
	playerCanClick = true; // We should let the player play, don't you think?
	// Initialize the arrays as empty lists:
	aCards = new Array();
	aGrid = new Array();
	aCardsFlipped = new ArrayList();

	BuildDeck();
	
	for(var i=0; i<rows; i++)
		{
			aGrid[i] = new Array(); // Create a new, empty array at index i
			for(var j=0; j<cols; j++)
				{
					var someNum:int = Random.Range(0,aCards.length);
					aGrid[i][j] = aCards[someNum];
					aCards.RemoveAt(someNum);
				}
		}
	}

function OnGUI () 
{
	GUILayout.BeginArea (Rect (0,0,Screen.width,Screen.height));
	BuildGrid();
	GUILayout.EndArea();
//	print("building grid with ");
}

class Card extends System.Object
{
	var isFaceUp:boolean = false;
	var isMatched:boolean = false;
	var img:String;
	var id:int;
	function Card (img, id:int)
	{
		this.img = img;
		this.id = id;
	}
}

function BuildGrid()
{
	GUILayout.BeginVertical();
	GUILayout.FlexibleSpace();
	for(var i=0; i<rows; i++)
	{
		GUILayout.BeginHorizontal();
		GUILayout.FlexibleSpace();
		for(var j=0; j<cols; j++)
		{
			var card:Object = aGrid[i][j];
			var img;
			if(card.isMatched)
			{
				img = "blank";
			}
			else
			{
				if (card.isFaceUp)
				{
					img = card.img;
				}
				else
				{
					img = "wrench";
				}
			}
			
			GUI.enabled = !card.isMatched;
			if(GUILayout.Button(Resources.Load(img), GUILayout.Width(cardW)))
			
			{
				if(playerCanClick)
				{
					FlipCardFaceUp(card);
				}
				Debug.Log(card.img);
			}
		}
	GUILayout.FlexibleSpace();
	GUILayout.EndHorizontal();
	}
	GUILayout.FlexibleSpace();
	GUILayout.EndVertical();
}

function BuildDeck()
{
	var totalRobots:int = 4; //we have four robots in total
	var card:Object; //this stores a reference to a card
	var id:int = 0;
	
	for(var i=0;i<totalRobots; i++)
	{
		var aRobotParts:Array = ["Head", "Arm", "Leg"];
		for(var j=0;j<2; j++)
		{
			var someNum:int = Random.Range(0, aRobotParts.length);
			var theMissingPart = aRobotParts[someNum];
			
			aRobotParts.RemoveAt(someNum);
			
			card = new Card("robot" + (i+1) + "Missing" + theMissingPart, id);
			aCards.Add(card);
			//this one causes problems
			card = new Card("robot" + (i+1) + theMissingPart);
			aCards.Add(card);
			id++;
		}
	}
}

function FlipCardFaceUp(card:Card)
{
	card.isFaceUp = true;
	if(aCardsFlipped.IndexOf(card) < 0)
	{
		aCardsFlipped.Add(card);
	
		if(aCardsFlipped.Count == 2)
		{
			playerCanClick = false;
		
			yield WaitForSeconds(1);
			
			if(aCardsFlipped[0].id == aCardsFlipped[1].id)
			{
				//match!
				aCardsFlipped[0].isMatched = true;
				aCardsFlipped[1].isMatched = true;
			}
			else
			{		
				aCardsFlipped[0].isFaceUp = false;
				aCardsFlipped[1].isFaceUp = false;
			}
			aCardsFlipped = new ArrayList();
		
			playerCanClick = true;
		}
	}
}

line 123
card = new Card(“robot” + (i+1) + theMissingPart); //

you have to conform to your own rules :wink: add the id param too, or create a constructor that only takes one parameter.

Eureka!

The problem is the id attribute. Once added, the

card = new Card("robot" + (i+1) + theMissingPart);

line expects it, so you need to add it in:

card = new Card("robot" + (i+1) + theMissingPart,id);

All is well with Robot Repair now.

Haha! I didn’t see your post Niklas when I posted :smile:

Tak,

B

Still one tiny problem… Everything is working fine now, but when the game has been won it puts a box on the screen with a button to play again. I tried making sure the player can click but the button is still ghosted. If I artificially set the Player has Won status to true I can click the button, otherwise no.

function BuildWinPrompt()
{
	var winPromptW:int = 100;
	var winPromptH:int = 90;
	
	var halfScreenW:int = Screen.width/2;
	var halfScreenH:int = Screen.height/2;
	
	var halfPromptW:int = winPromptW/2;
	var halfPromptH:int = winPromptH/2;

	playerCanClick = true;

//	GUI.BeginGroup(Rect(halfScreenW-halfPromptW, halfScreenH-halfPromptH, winPromptW, winPromptH));
	GUI.BeginGroup(Rect(0, 100, winPromptW, winPromptH));
		playerCanClick = true;
		GUI.Box (Rect (0, 0, winPromptW, winPromptH), winner);
//		GUI.skin = customSkin;
		if(GUI.Button(Rect(10,40,80,20),"Play again?"))
		{
			Application.LoadLevel("Title");
		}
		GUI.EndGroup();
}

B

Added a Debug.Log line in below the if and the game jumps straight to the title screen, comment it out and the button is ghosted and I can’t get anywhere…

:shock:

Tough this Unity mularky,

B