I wanted to Create a Grid Dynamically into Page. I am using this Code:
Grid grd = new Grid();
for (int i = 0; i <MAX_X; i++)
{
grd.RowDefinitions.Add(new RowDefinition());
}
for (int i = 0; i <MAX_Y; i++)
{
grd.ColumnDefinitions.Add(new ColumnDefinition());
}
for (int x = 0; x <= MAX_X; x++)
{
for (int y = 0; y <= MAX_Y; y++)
{
TextBlock t = new TextBlock();
t.SetValue(Grid.RowProperty, x);
t.SetValue(Grid.ColumnProperty, y);
t.text = "Hello";
grd.Children.Add(t);
}
}
It is created but not displaying anything. When i do Debug, Its Working fine but its not displaying in my Page. am i missing Something ?
Your Grid doesnt have any parent that resides into Page. You needed to add Your Grid to the Page. It is created but not been added to Page so its not Displaying anything.
Try this:
ContentPanel.Children.Add(grd);
Related
Here I'm trying to write a code that can write and create a JSON File for me with the data I provide like row, column and depth.
For example, I need to spawn a 10 x 10 x 10 cube. And I give this data in unity Inspector also in the code when I'm serializing it.
I tried achieving this in a for loop and writing the JSON file. But I'm not getting the output I wanted. I am expecting output where the cube locations are different and in place what happens instead is all the data or cube position in my data is the one before the number I give. that is if I gave my row, column, and depth to be 10. So my data is like x: 9, y: 9, z:9 for the whole 1000 elements.Better explained in image down below.I know I'm doing a mistake at some point just not able to figure out where. Thanks for the help in Advance
public class JSONWriter : MonoBehaviour
{
[SerializeField] int rows , columns, depth = 10;
[SerializeField] float padding;
public enum CubeType
{
white,
yellow,
blue,
red,
green
}
private readonly IReadOnlyDictionary<CubeType, Color> colors = new Dictionary<CubeType, Color>
{
{CubeType.white, Color.white},
{CubeType.yellow, Color.yellow},
{CubeType.blue, Color.blue},
{CubeType.red, Color.red},
{CubeType.green, Color.green}
};
[System.Serializable]
public class CubeData
{
public Vector3 cubePosition;
public CubeType Cube;
}
[System.Serializable]
public class CubeDataList
{
public CubeData[] cubeDatas;
}
public void outputJSON()
{
string strOutput = JsonUtility.ToJson(myCubeDataList);
File.WriteAllText(Application.dataPath + "/Resources/10x10x10.txt", strOutput);
}
//CubeData myCubeData = new CubeData();
public CubeDataList myCubeDataList = new CubeDataList();
void Start()
{
for (int x = 0; x < myCubeDataList.cubeDatas.Length; x++)
{
//Debug.Log(myCubeDataList.cubeDatas.Length);
for (int i = 0; i < depth; i++)
{
for (int j = 0; j < columns; j++)
{
for (int k = 0; k < rows; k++)
{
myCubeDataList.cubeDatas[x].cubePosition = new Vector3(i, j, k) * padding;
//myCubeDataList.cubeDatas[x].Cube = Random.Range(CubeType, 3f);
}
}
}
}
}
}
You do not want to go through all i, j, k for each and every element x!
What you are doing is basically overwriting each and every element with the values for i=9, j=9, k=9.
Instead of an array I would rather simply use a dynamic List like
[Serializable]
public class CubeDataList
{
public List<CubeData> cubeDatas;
}
and then dynamically add them via
myCubeDataList.cubeDatas = new List<CubeData>(i * j * k);
for (int i = 0; i < depth; i++)
{
for (int j = 0; j < columns; j++)
{
for (int k = 0; k < rows; k++)
{
var data = new CubeData();
data.cubePosition = new Vector3(i, j, k) * padding;
data.Cube = Random.Range(CubeType, 3f);
myCubeDataList.cubeDatas.Add(data);
}
}
}
Or if you really want to go with an array
for (int i = 0; i < depth; i++)
{
for (int j = 0; j < columns; j++)
{
for (int k = 0; k < rows; k++)
{
var data = new CubeData();
myCubeDataList.cubeDatas[x].cubePosition = new Vector3(i, j, k) * padding;
myCubeDataList.cubeDatas[x].Cube = Random.Range(CubeType, 3f);
x++;
}
}
}
Though, from your previous question I know you actually do not want to fill the cube completely!
You actually only want the external shape (like a wall) and leave the cube empty on the inside.
So what you actually want would probably rather be
myCubeDataList.cubeDatas = new List<CubeData>(i * j * k);
for (int i = 0; i < depth; i++)
{
for (int j = 0; j < columns; j++)
{
for (int k = 0; k < rows; k++)
{
if(i == 0 || i == depth - 1
|| j == 0 || j == depth - 1
|| k == 0 || k == depth - 1)
{
var data = new CubeData();
data.cubePosition = new Vector3(i, j, k) * padding;
// TODO random enum (see below)
myCubeDataList.cubeDatas.Add(data);
}
}
}
}
For the random enum vlaue see e.g. this answer and do
private Random random = new Random();
and then where it says // TODO insert
var values = Enum.GetValues(typeof(Bar));
data.Cube = (CubeType)values.GetValue(random.Next(values.Length));
I have a datagrid with 5 columns and I want to manipulate its dataprovider. I'm trying to change dp's first column dynamically. I tried this:
for (var i:uint = 0; i < dp.length; i++) {
var tempArr:Array = new Array(dp.getItemAt(i));
tempArr[0] = String(i);
dp.replaceItemAt(tempArr, i);
}
However this empties all cells in datagrid. How can I fix this?
Anyway, I fixed this.
for (var i:uint = 0; i < dp.length; i++) {
dataGrid.editField(i, "noCol", String(i + 1));
}
If I don't cache the container of tiles after creating the map, I can see them rendered to the canvas:
function createWorld() {
background = new createjs.Container();
for (var y = 0; y < mapWidth; y++) {
for (var x = 0; x < mapHeight; x++) {
var tile = new createjs.Bitmap('images/tile.png');
tile.x = x * 28;
tile.y = y * 30;
background.addChild(tile);
}
}
//background.cache(0, 0, mapWidth, mapHeight);
stage.addChild(background);
}
If I do cache the background container of tile children, it won't render
function createWorld() {
background = new createjs.Container();
for (var y = 0; y < mapWidth; y++) {
for (var x = 0; x < mapHeight; x++) {
var tile = new createjs.Bitmap('images/tile.png');
tile.x = x * 28;
tile.y = y * 30;
background.addChild(tile);
}
}
background.cache(0, 0, mapWidth, mapHeight);
stage.addChild(background);
}
Why?
This is probably because that even when preloaded, images may not be available synchronously if you use a path to create them. If you aren't caching them, then they wouldn't show up immediately when the stage is updated -- but if you ticked the stage, they might appear to load instantly (they just take a frame or so).
I recommend you preload them, either internally, or using something like PreloadJS. Then pass the loaded instance to the bitmaps instead.
var img = document.createElement("img");
img.onload = draw;
img.src = "images/tile.png";
function draw() {
// loop
var bmp = new createjs.Bitmap(img); // Use a reference instead of a path
}
Note that this also reduces overhead, since only one image is created, and all the Bitmaps share a reference to it.
If all your tiles are the same, you might want to look at the Graphics.beginBitmapFill() method. http://www.createjs.com/Docs/EaselJS/classes/Graphics.html#method_beginBitmapFill
i want to make my box animation come up from left to right direction, right now my box appear from top to buttom, how can i change my move direction of the box from left to right, i have nine box and three each other line, like picture below
here is my current code
function random_item()
{
var listItem:Array = new Array();
for (var i:uint=0; i<15; i++)
{
listItem.push(i);
}
ItemLeft = 0;
for (var x:uint=0; x<boardWidth; x++)
{
for (var y:uint=0; y<boardHeight; y++)
{
var thisItem:FirstBox = new FirstBox();
thisItem.stop();
thisItem.x = x * IcardHorizontalSpacing + IboardOffsetX;
thisItem.y = y * IcardVerticalSpacing + IboardOffsetY;
var r:uint = Math.floor(Math.random() * listItem.length);
thisItem.cardface = listItem[r];
listItem.splice(r,1);
thisItem.addEventListener(MouseEvent.CLICK,clickItem);
thisItem.buttonMode = true;
addChild(thisItem);
ItemLeft++;
}
}
}
how do i make the animation from left to right, thanks before
Since your nested for loop has the y-position nested inside the x-position, three y positions (top, middle, bottom) will appear for each x-position.
You might be able to fix the behavior you are seeing by structuring your for loop like below, switching the order of the variables:
for (var y:uint=0; y<boardHeight; y++)
{
for (var x:uint=0; x<boardWidth; x++)
{
//Inner code remains the same
}
}
This way, three x-positions will be displayed for each y-position, hopefully creating the left-to-right behavior you're looking for.
//change
for (var y:uint=0; y<boardHeight; y++)
//to
for (var y:uint=boardHeight; y>0; y--)
Although, in your code you are nesting the y loop inside the x loop.
This means that for every iteration of the X loop the box will go from bottom to top
I don't know if this is the what you are looking for.
Please be more specific in your description of what you want.
You are looping first over x and then over y. This means that it will add 3 items for every column. Invert the loops to get it to add 3 items for every row.
function random_item()
{
var listItem:Array = new Array();
for (var i:uint=0; i<15; i++)
{
listItem.push(i);
}
ItemLeft = 0;
for (var y:uint=0; y<boardHeight; y++)
{
for (var x:uint=0; x<boardWidth; x++)
{
var thisItem:FirstBox = new FirstBox();
thisItem.stop();
thisItem.x = x * IcardHorizontalSpacing + IboardOffsetX;
thisItem.y = y * IcardVerticalSpacing + IboardOffsetY;
var r:uint = Math.floor(Math.random() * listItem.length);
thisItem.cardface = listItem[r];
listItem.splice(r,1);
thisItem.addEventListener(MouseEvent.CLICK,clickItem);
thisItem.buttonMode = true;
addChild(thisItem);
ItemLeft++;
}
}
}
I'm making an image gallery and I want to have a bunch of thumbnails on the bottom of the screen that smoothly slide from side to side when the mouse moves.
I'm working with a custom class for the container (Tiles) and a custom class for the thumbnails (ImageIcon).
I have a ComboBox which allows users to to choose a gallery. When the user chooses a gallery, the following code is run and the thumbnails should reload. The problem here is that the icons appear on top of each other instead of side by side, also switching categories should remove the old one (see the first for loop), but it does not. Also, the Icons are not animating properly. The animation code is below as well. Right now, only one of the icons will move. The icons should move in order from side to side, stopping when the last few icons hit the edge of the screen, so that they don't get "lost" somewhere off to the side.
Gallery Loader Code:
public function loadCategory(xml:XML = null) {
if (xml != null) {
dp = new DataProvider(xml);
for (var k:int = 0; k < this.numChildren; k++) {
this.removeChild(this.getChildAt(k));
}
var black:DropShadowFilter = new DropShadowFilter(0, 45, 0x000000, 1, 3, 3, 1, 1);
var white:DropShadowFilter = new DropShadowFilter(0, 45, 0xFFFFFF, 1, 2, 2, 1, 1);
for (var i:int = 0; i < dp.length; i++) {
var imgicon:ImageIcon = new ImageIcon();
imgicon.addEventListener(MouseEvent.CLICK, showImage);
imgicon.width = 100;
imgicon.x = (i * (imgicon.width + 20));
imgicon.path = dp.getItemAt(i).data;
imgicon.loadIcon();
imgicon.filters = [black, white];
stage.addEventListener(Event.ENTER_FRAME, moveIcon);
this.addChild(imgicon);
}
} else {
//Failed to load XML
}
}
Icon Animation Code:
public function moveIcon(e:Event){
var speed = 0;
speed = Math.floor(Math.abs(this.mouseX/20));
var image = this.getChildAt(k);
var imagebox = image.width + 20;
var edge:Number = (800/2);
if (this.mouseX > 0) {
for (var k:int = 0; k < this.numChildren; k++) {
if (image.x - (imagebox/2) + speed < -edge + (k * imagebox)) {
speed = 0;
}
image.rotationY = Math.floor(image.x/20);
image.x -= Math.floor(speed);
}
} else {
for (var j = this.numChildren; j >= 0; j--) {
if (image.x + speed > edge - ((imagebox * j) )) {
speed = 0;
}
image.rotationY = Math.floor(image.x/20);
image.x += Math.floor(speed);
}
}
}
As I see it, you have three questions (You should have put these at the end of your question instead of "What is wrong with my code?"). One of the main principles of programming is breaking problems into smaller parts.
How do I line up the ImageIcon beside each other?
How do I remove the old ImageIcon, when switching categories?
How do I animate ALL the ImageIcons together, based on the mouse position, with constraints on either side?
Question 1
I can't see anything wrong, but just check that when you are setting imgicon.x, that imgicon.width is actually set.
Question 2
Instead of relying on numChildren and getChildAt(), I would create a currentIcons array member variable, and when you create a new ImageIcon, just push it onto the array. Then when you want to remove them, you can just loop through the array like this:
for each (var cIcon:ImageIcon in currentIcons)
{
cIcon.removeEventListener(MouseEvent.CLICK, showImage);
removeChild(cIcon);
}
currentIcons = [];
As you can see, I am also removing any listeners that I have added. This is best practice. Then clearing the array when I have removed all the icons.
Question 3
I can see a few things wrong with your code. First, in the line where image is set, k is not set yet!
Here you can also use the currentIcons array, but you probably can't use a for each in loop, because that gives you the items out of order. Just a normal for loop will be better.
I haven't tested this code for the moveIcon method, but the idea should work. You may have to tweek it though:
public function moveIcon(e:Event):void
{
var speed:Number = Math.floor(this.mouseX / 20); // Removed "abs".
var imageBox:Number = currentIcons[0].width;
var edge:Number = 800 / 2;
for (var i:int = 0; i < currentIcons.length; i++)
{
var image:ImageIcon = currentIcons[i] as ImageIcon;
image.x += speed;
image.rotationY = Math.floor(image.x / 20);
var min:int = -edge + (i * imagebox);
if (image.x < min) image.x = min;
var max:int = edge - (imagebox * i);
if (image.x > max) image.x = max;
}
}
EDIT* Sorry, it was supposed to be a greater than in the last if statement, but I had a less than by accident.