Share data between scripts? - scripting

I want to create a scoring system. I have 4 buttons with 4 different but similar scripts and want to share 1 GUI Text for the scores. Example Code:
var something : Sprite;
var SpriteRenderer : SpriteRenderer;
var score : int = 0;
var guiScore : GUIText;
function OnMouseDown () {
if(SpriteRenderer.sprite == something) {
score += 1;
guiScore.text = "Score: " = score;
}
}
Right now, if I pressed a button and got a point then I pressed a different button the score would start from 0 again. How can I share data something like static variables but different scripts? I know this sounds a bit noobie but any help would be much appreciated. Thanks in advance

Static variables won't appear in the inspector so you can't assign the GUIText in the inspector (thanks for making me find out). So try using GetComponent instead:
// make a variable of type GUIText
var guiScore: GUIText;
// assign the gameobject in the inspector
var staticObject: GameObject;
// Again I don't know the name of your script, so I'll name it StaticScript
// get the script
StaticScript scr = staticObject.GetComponent(StaticScript);
// assign local GUIText with the one from above
guiScore = scr.guiScore;
This way you have already shared 1 GUIText for all other scripts.
However you said:
Right now, if I pressed a button and got a point then I pressed a
different button the score would start from 0 again
Doesn't that mean something is wrong with the score, not the GUIText?

Related

How to give an dynamicly loaded TreeViewItem an EventHandler?

at the moment i programm a database based Chat System.
The friendlist of every User gets loadet in a TreeView after the login.
means:
After the login I request the names of the useres friends by the following Funktion,
String namesSt[] = get.getUserFriendNameByUserID(currentUserID);
To use the given Names to load them as TreeItem into my Friendlist / TreeRootItem "rootItem"
for (int counter = 0; counter < namesSt.length; counter++) {
System.out.println(namesSt[counter]);
TreeItem<String> item = new TreeItem<String> (namesSt[counter]);
item.addEventHandler(MouseEvent.MOUSE_CLICKED,handler);
rootItem.getChildren().add(item);
}
When I now add my rootItem, I see the Names in the TreeView.
But if I click on a name, the given MouseEventHandler doesn´t get called.
Further I just want to request the text of the Element which trigger the MouseEvent, so that i can submit these name to a spezial funktion.
How can i realice such an MouseEvent?
How is it possible to call it from the dynamicly created TreeItem?
Thank you for any help :)
cheerse
Tobi
TreeItems represent the data, not the UI component. So they don't generate mouse events. You need to register the mouse listener on the TreeCell. To do this, set a cell factory on the TreeView. The cell factory is a function that creates TreeCells as they are needed. Thus this will work for dynamically added tree items too.
You will need something like this:
TreeView<String> treeView ;
// ...
treeView.setCellFactory( tv -> {
TreeCell<String> cell = new TreeCell<>();
cell.textProperty().bind(cell.itemProperty());
cell.addEventHandler(MouseEvent.MOUSE_CLICKED, event -> {
if (! cell.isEmpty()) {
String value = cell.getItem();
TreeItem<String> treeItem = cell.getTreeItem(); // if needed
// process ...
}
});
return cell ;
}

Titanium: click on element(View, Label e.t.c.) should increase its top by 1

I've binded the same function to all elements that I want(let's say View and Label).
In this onClick handler function I want to get the element which was clicked and increase its 'top' by 1.
Please tell me if you know how to do that, I can't find an answer yet.
My global click handler function:
function increaseElementTop(e) {
// Here we should increase element's top position.
Ti.API.info(JSON.stringify(e));
}
Thanks, any help is appreciated.
Get the e.source attribute from the Event e. Then use the setTop() method.
if (e.source == $.yourLabel) {
$.yourLabel.setTop($.yourLabel.getTop() + 1)
}
UPDATE: Regarding your comment: I thought it would only be used for two elements. A universal approach would be something like this:
e.source.setTop(e.source.getTop() + 1);
Unfortunately I have no machine available to test the code but I will do so later (Tuesday I guess). Just try it and let your programm print the e.source variable. If this does not work you can also try to use e.source.getId().
function increaseElementTop(e) {
var theUIElement = e.source;
theUIElement.top = theUIElement.top + 1;
}
Add the event listener to each of your UIElements, and this will get the element you click on & modify the top.

DevExpress ExtraEditors checkedcombobox doesn't synchronize?

I'm trying to use two devExpress checkedComboBoxes (boxes) to maintain a list and its antilist (i.e, same items in both comboboxes, and they must be checked in only one of the lists).
I'm using C++/CLI, so for each box I handle
EditValueChanged += gcnew System::EventHandler(this, &SelectionControl::exclBox_EditValueChanged);
which calls through to
void
box_ToggleAntibox(
DevExpress::XtraEditors::CheckedComboBoxEdit^ box,
DevExpress::XtraEditors::CheckedComboBoxEdit^ antibox )
{
using namespace DevExpress::XtraEditors::Controls ;
cli::array<String ^> ^ sAnti = gcnew cli::array<String ^>(2*box->Properties->Items->Count) ;
int ii = 0;
String ^ delim = ", ";
for each (CheckedListBoxItem^ i in box->Properties->GetItems()) {
if (i->CheckState==Windows::Forms::CheckState::Unchecked)
{
sAnti[ii] = i->Value->ToString();
++ii;
sAnti[ii] = delim;
++ii;
}
}
String ^ result = String::Concat(sAnti);
antibox->EditValue = result;
}
As the devExpress documentation seems to say to set the edit value, rather than simply iterating through the box list and setting the anti-list to !Checked.
However, it doesn't seem to be working (the correct items are added to the text window, but nothing is checked). Moreover, if I look at my box after the event has finished, I find that the string value in the text window is correct (reflects what I'd selected), but if I open it up, then all items are selected.
Does anyone have any suggestions I might try?
Is it better to set each item's CheckState::Checked instead?
Thanks!
I spent some time talking to DevExpress support. The short answer is that this should work - but doesn't for us. Your mileage may vary, but our solution was to put the two comboboxes on to separate controls on the form.

Problems in my AS2 Game

Hey guys, I'm trying to make a 2D Platform style game similar to this game below:
http://www.gameshed.com/Puzzle-Games/Blockdude/play.html
I have finished making most of the graphic, and areas, and collision, but our character is still not able to carry things. I'm confused as to what code to use so that my character can carry the blocks. I need help as to how to make our character carry blocks that are in front of him, provided that the blocks that don't have anything on top of it. This has been confusing me for a week now, and any help would be highly appreciated. :D
I fondly remember my first AS2 game. The best approach is probably an object oriented approach, as I will explain.
In AS2, there is a hittest method automatically built into objects. There is a good tutorial on Kirupa here:
http://www.kirupa.com/developer/actionscript/hittest.htm
also
http://help.adobe.com/en_US/AS2LCR/Flash_10.0/help.html?content=00001314.html
First you'll want to generate your boxes using a Box class. Your class would need to look something like the following:
//Box.as pseudo-code
class Box {
var x_pos:Number;
var y_pos:Number;
var attachedToPlayer:Boolean;
function Box(_x:Number, _y:Number) {
this.x_pos = _x;
this.y_pos = _y;
}
//other code here
}
See this tutorial on how to attach a class to an object in the library:
http://www.articlesbase.com/videos/5min/86620312
To create a new Box, you'd then use something like
box1 = new Box(100,200);
// creates a box at position 100x,200y
However, you'll also want to store the blocks you want to pickup into some sort of array so you can loop through them. See http://www.tech-recipes.com/rx/1383/flash-actionscript-create-an-array-of-objects-from-a-unique-class/
Example:
//somewhere near the top of your main method, or whereever your main game loop is running from - note Box.as would need to be in the same folder
import Box;
//...then, somewhere before your game loop
//create an array to hold the objects
var boxArray:Array = new Array();
//create loop with i as the counter
for (var i=0; i<4; i++)
{
var _x:Number = 100 + i;
var _y:Number = 100 + i;
//create Box object
var box:Box = new Box();
//assign text to the first variable.
//push the object into the array
boxArray.push(box);
}
Similarly, you would need a class for your player, and to create a new Player object at the start of your game, e.g.
var player = new Player(0,0);
You could then run a hittest method for your player against the blocks in your array for the main game loop (i.e. the loop that updates your player's position and other game properties). There are probably more efficient ways of doing this, e.g. only looping for the blocks that are currently on the screen.
Once your array has been created, use a foreach loop to run a hittest against your player in your game's main loop, e.g.
//assuming you have an array called 'boxArray' and player object called 'player'
for(var box in boxArray){
if (player.hittest(box)) {
player.attachObjectMethod(box);
}
}
This is basically pseudo-code for "for every box that we have entered into the array, check if the player is touching the box. If the box is touching, use the box as the argument for a method in the player class (which I have arbitrarily called attachObjectMethod)".
In attachObjectMethod, you could then define some sort of behavior for attaching the box to the player. For example, you could create a get and set method(s) for the x and y position of your boxes inside the box class, along with a boolean called something useful like attachedToPlayer. When attachObjectMethod was called, it would set the box's boolean, e.g. in the Player class
//include Box.as at the top of the file
import Box;
//other methods, e.g. constructor
//somewhere is the Player.as class/file
public function attachObjectMethod (box:Box) {
box.setattachedToPlayer(true);
//you could also update fields on the player, but for now this is all we need
}
Now the attachedToPlayer boolean of the box the player has collided with would be true. Back in our game loop, we would then modify our loop to update the position of the boxes:
//assuming you have an array called 'boxArray' and player object called 'player'
for(var box in boxArray){
if (player.hittest(box)) {
player.attachObjectMethod(box);
}
box.updatePosition(player.get_Xpos, player.get_Ypos);
}
In our Box class, we now need to define 'updatePosition':
//Box.as pseudo-code
class Box {
var x_pos:Number;
var y_pos:Number;
var attachedToPlayer:Boolean;
function Box(box_x:Number, box_y:Number) {
this.x_pos = box_x;
this.y_pos = box_y;
}
public function updatePosition(_x:Number, _y:Number) {
if (this.attachedToPlayer) {
this.x_pos = _x;
this.y_pos = _y;
}
}
//other code here
}
As you can see we can pass the player's position, and update the box's position if the attachedToPlayer boolean has been set. Finally, we add a move method to the box:
public function move() {
if (this.attachedToPlayer) {
this._x = x_pos;
this._y = y_pos;
}
}
Examples of updating position:
http://www.swinburne.edu.au/design/tutorials/P-flash/T-How-to-smoothly-slide-objects-around-in-Flash/ID-17/
Finally, to make it all work we need to call the move method in the game loop:
//assuming you have an array called 'boxArray' and player object called 'player'
for(var box in boxArray){
if (player.hittest(box)) {
player.attachObjectMethod(box);
}
box.updatePosition(player.get_Xpos, player.get_Ypos);
box.move();
}
You have also specified that the blocks should only move with the player if they have nothing on top of them. When you call your attachedToPlayer method, you would also need to run a foreach loop inside the method between the box and the objects that might sit on top of the box. You should now have a fair idea from the above code how to do this.
I appreciate that this is quite a lengthy answer, and I haven't had an opportunity to test all the code (in fact I'm fairly positive I made a mistake somewhere) - don't hesitate to ask questions. My other advice is to understand the concepts thoroughly, and then write your own code one bit at a time.
Good luck!
The way I would do this is to design an individual hit test for each block he will be picking up, then code for the hit test to play a frame within the sprite's timeline of him carrying a block, and to play a frame within the block to be picked up's timeline of the block no longer at rest (disappeared?).
Good Luck if you're confused about what I've said just ask a little more about it and I'll try to help you if I can.

Problems with adding/removing ContentPanes in AccordionContainer

I'm a complete newbie at Dojo, and Adobe AIR, which is my target. I'm
trying to put some panes into an AccordionContainer like so:
var mainview = dijit.byId("mainview");
var rand = randomString();
var widg = gtd_create_entry_widget(rand)
air.trace(mainview);
air.trace(widg);
mainview.addChild(widg);
"mainview" is my AccordionContainer, and gtd_create_entry_widget() is:
function gtd_create_entry_widget(id) {
var entry = new dijit.layout.ContentPane();
entry.attr("id",id);
entry.attr("title","title "+id);
return entry;
}
The pane shows up in the container, with the correct id and title, and
no errors, however, if I try to add another pane, the next one shows
up too, but I get the error:
TypeError: Result of expression '_7' [undefined] is not an object.
I get the same error if I run
var mainview = dijit.byId("mainview");
mainview.destroyDescendants();
and also, only one pane is destroyed at a time, and I understand this
method should destroy all the children.
I can include full project code if required.
Thanks a lot
Garry
I'm not exactly sure if this is going to fix your problem, but you're supposed to use dijit.layout.AccordianPane (http://www.dojotoolkit.org/api/dijit/layout/AccordionPane.html) with the AccordianContainer.