Adding Randomness With Generic Button Image
by David Taylor · in Torque Game Builder · 10/26/2007 (2:29 am) · 7 replies
I'm making a simple card game, and the cards all start face down. I'm using Generic Button Image to 'flip' the card over. But I want the new image to be randomised. How do I implement this into the Behavior scripting?
About the author
#2
I have nine cards, plus the back, so it's an image split into 10 cells. But I'm getting no random images. I think it has to do with the ClickFrame value. When I set it up in Torque, I have to give it a value. But even if I remove it from the top datablock which assigns the behaviors, it still only spits out the same image.
Here's the code I'm using:
Any ideas?
10/27/2007 (1:51 am)
Thanks, Phillip. That hasn't fixed my problem, but has certainly given me a new way to look at it. I wasn't using a single image with cells, but I now am.I have nine cards, plus the back, so it's an image split into 10 cells. But I'm getting no random images. I think it has to do with the ClickFrame value. When I set it up in Torque, I have to give it a value. But even if I remove it from the top datablock which assigns the behaviors, it still only spits out the same image.
Here's the code I'm using:
if (!isObject(GenericButtonBehaviorImageStayRandom))
{
%template = new BehaviorTemplate(GenericButtonBehaviorImageStayRandom);
%template.friendlyName = "Generic Button Image Stay Random";
%template.behaviorType = "GUI";
%template.description = "Executes a method when clicked. The method is called on the behavior's owner";
%template.addBehaviorField(hoverImage, "The image to display when mousing over the object", object, "", t2dImageMapDatablock);
%template.addBehaviorField(hoverFrame, "The frame of the hoverImage to display", int, 0);
%template.addBehaviorField(clickImage, "The image to display when clicking on the object", object, "", t2dImageMapDatablock);
%template.addBehaviorField(clickFrame, "The frame of the clickImage to display", int, 0);
%template.addBehaviorField(method, "The method to call on mouse up", string, "onClick");
}
function GenericButtonBehaviorImageStayRandom::onBehaviorAdd(%this)
{
%this.owner.setUseMouseEvents(true);
%this.startImage = %this.owner.getImageMap();
//Call the initiation function'
%this.initiateDeck();
}
//Initiate Deck
function GenericButtonBehaviorImageStayRandom::initiateDeck(%this)
{
for (%i = 0; %i < 10; %i++)
{
%this.cardTaken[%i] = 0;
}
}
function GenericButtonBehaviorImageStayRandom::onMouseDown(%this, %modifier, %worldPos)
{
if (!isObject(%this.clickImage))
return;
//Select random card
%this.currentCard = -1;
while %this.currentCard == -1)
{
%randomNumber = ceil(10 * getRandom());
if (!%cardTaken[%randomNumber])
{
%cardTaken[%randomNumber] = 1;
%this.currentCard = %randomNumber;
%this.clickFrame = %randomNumber;
}
}
%this.owner.setImageMap(%this.clickImage, %this.clickFrame);
}Any ideas?
#3
11/03/2007 (9:05 pm)
Just a bump to this thread. I'm still stuck on getting the Behaviour to go to a random frame. Does anyone have any suggestions that might further my efforts? The post above is still as far as I've got.
#4
In the end I wound up multiplying the getRandom() result with the object's X position multiplied with it's Y position and then just getting the last whole number digit. This gave me random numbers even when called almost back to back as long as the objects aren't directly on top of each other.
11/09/2007 (3:29 pm)
Hm, I ran into a similar problem where i was calling random multiple times in a row for different objects and it was so quick that the results of the getRandom() was the same for each call. In the end I wound up multiplying the getRandom() result with the object's X position multiplied with it's Y position and then just getting the last whole number digit. This gave me random numbers even when called almost back to back as long as the objects aren't directly on top of each other.
#5
11/12/2007 (9:50 pm)
Thanks! I've got it working on a basic level. There was a typo in my code - a missing bracket. It also didn't recognise the call to 'ceil', so now I have it working, and I just need it to round to a single digit, and I'll be good to go.function GenericButtonBehaviorImageStayRandom::onMouseDown(%this, %modifier, %worldPos)
{
if (!isObject(%this.clickImage))
return;
//Select random card
%this.currentCard = -1;
while(%this.currentCard == -1)
{
%randomNumber = (10 * getRandom());
if (!%cardTaken[%randomNumber])
{
%cardTaken[%randomNumber] = 1;
%this.currentCard = %randomNumber;
%this.clickFrame = %randomNumber;
}
}
%this.owner.setImageMap(%this.clickImage, %this.clickFrame);
}
#6
11/12/2007 (9:52 pm)
Thanks! I've got it working on a basic level. There was a typo in my code - a missing bracket. It also didn't recognise the call to 'ceil', so now I have it working, and I just need it to round to a single digit, and I'll be good to go.function GenericButtonBehaviorImageStayRandom::onMouseDown(%this, %modifier, %worldPos)
{
if (!isObject(%this.clickImage))
return;
//Select random card
%this.currentCard = -1;
while(%this.currentCard == -1)
{
%randomNumber = (10 * getRandom());
if (!%cardTaken[%randomNumber])
{
%cardTaken[%randomNumber] = 1;
%this.currentCard = %randomNumber;
%this.clickFrame = %randomNumber;
}
}
%this.owner.setImageMap(%this.clickImage, %this.clickFrame);
}
#7
11/12/2007 (9:52 pm)
Actually, that was a typo, too. It should be mCeil. Heh. Cool. :)function GenericButtonBehaviorImageStayRandom::onMouseDown(%this, %modifier, %worldPos)
{
if (!isObject(%this.clickImage))
return;
//Select random card
%this.currentCard = -1;
while(%this.currentCard == -1)
{
%randomNumber = mCeil(10 * getRandom());
if (!%cardTaken[%randomNumber])
{
%cardTaken[%randomNumber] = 1;
%this.currentCard = %randomNumber;
%this.clickFrame = %randomNumber;
}
}
%this.owner.setImageMap(%this.clickImage, %this.clickFrame);
}
Associate Phillip O'Shea
Violent Tulip
function GenericButtonBehavior::onBehaviorAdd(%this) { %this.owner.setUseMouseEvents(true); //This is the card's imagemap block, I'm assuming you have it in cells //so then all you have to do is change the frame which it comes from %this.startImage = %this.owner.getImageMap(); //Call the initiation function' %this.initiateDeck(); } //Initiate Deck function GenericButtonBehavior::initiateDeck(%this) { for (%i = 0; %i < 52; %i++) { %this.cardTaken[%i] = 0; } } function GenericButtonBehavior::onMouseDown(%this, %modifier, %worldPos) { if (!isObject(%this.clickImage)) return; //Select random card %this.currentCard = -1; while %this.currentCard == -1) { %randomNumber = ceil(52 * getRandom()); if (!%cardTaken[%randomNumber]) { %cardTaken[%randomNumber] = 1; %this.currentCard = %randomNumber; } } //This sets the image to CardImageMap %this.owner.setImageMap(%this.clickImage, %this.currentCard); }I've given you the basics with this. With this setup, I've assumed that all of your cards are in one image, which are divided up using cells. You'd probably want to have Frame 0 as the back of your card or something, so you can just set the frame of your imagemap to 0 when you want it flipped back over. To do that, you can easily mod the above.
Hope that helped ;)