Brick Breaker in Unity w json data input - json

I'm making a brick breaker game in Unity2D, but was told to make the bricks dynamic instead of dragging in cubes from the UI. The idea is to make the brick patterns dynamic, and receive brick data (i.e. positions) from a .json file. I've taken the approach of populating using Instantiate and a prefab, although I'm not sure how to incorporate that with data from .json or if I'm on the right track. Newbie here please help! Even just directing me to concepts would be fantastic.
using System.Collections.Generic;
using UnityEngine;
public class BrickGrid : MonoBehaviour
{
public Transform brickPrefab;
private Vector3[] BrickCoords;
private int totalBricks;
void Start()
{
totalBricks = 4;
BrickCoords = new Vector3[totalBricks];
BrickCoords[0] = new Vector3(-2.2f, 2f, 0f);
BrickCoords[1] = new Vector3(-0.75f, 2f, 0f);
BrickCoords[2] = new Vector3(0.75f, 2f, 0f);
BrickCoords[3] = new Vector3(2.2f, 2f, 0f);
for (int x = 0; x < totalBricks; x++)
{
Instantiate(brickPrefab, BrickCoords[x], Quaternion.identity);
}
}
public static void initGrid(){
}
}
[System.Serializable]
public class BrickCoordinate
{
public Vector3 brickPos;
}

It depends on how your JsonString looks. But something along these lines might be what you need:
Make a class containing a list of blocks.
[System.Serializable]
public class Bricks
{
public List<BrickCoordinate> BrickCoordinates;
}
Then load in your json from wherever you have it, and pass it into Unity's JsonUtility class.
var listOfBlocks = JsonUtility.FromJson<Bricks>(yourJsonStringHere);
And then you can iterate over your list and instantiate each item.
You can view more info here
Edit:
An easy way to get a correct Json string, is to do the exact opposite.
Use the Json function in your code to test and serialize a list of blocks.
(Also i changed the name of the list, because it was misleading)
var test = new Bricks
{
BrickCoordinates = new List<BrickCoordinate>
{
new BrickCoordinate
{
brickpos = new Vector3{ x = 1, y = 2, z = 3};
},
new BrickCoordinate
{
brickpos = new Vector3{ x = 2, y = 2, z = 3};
},
new BrickCoordinate
{
brickpos = new Vector3{ x = 1, y = 4, z = 3};
},
}
};
var jsonString = JsonUtility.ToJson(test);
Debug.Log(jsonString);

Related

How to use LSTM with a 2d array with DeepLearning4j

i am trying to learn how to use LSTM with deeplearning4j lib.
I created a dummy scenario where i want to get an output (3 classes) based on data that i collected.
I got the data from here (http://www.osservatoriodioropa.it/meteoropa/NOAAMO.TXT) if someone is curious :)
Back to the scenario.
I created 2 matrix, one with features, other with classes that i want to output, just as a test.
When i try the classifier i got
Exception in thread "main" java.lang.IllegalStateException: 3D input expected to RNN layer expected, got 2
i think because the RnnOutputLayer expect a 3d matrix, but i am not able to understand how to populate it. How can i convert a 2d matrix into a 3d matrix correlating the previous event with the new one? The data are a time serie, and i want to relate the classification of the new day based on previous days as well. (I know that probably the data won't fit this scenario and that there are better way to do that, but that's just to learning how to use LSTM, not how to classify this specific dataset)
this is the code so far
public class Test {
public static void main(String args[]) {
int events = 5;
int features = 6;
int classes = 3;
double[][] featureMatrix = new double[events][features];
double[][] labelMatrix = new double[events][classes];
for (int i = 0; i < events; i++) {
for (int f = 0; f < features; f++) {
featureMatrix[i][f] = getFeature(i, f);
}
for (int c = 0; c < classes; c++) {
labelMatrix[i][c] = getResult(i, c);
}
}
INDArray trainingIn = Nd4j.create(featureMatrix);
INDArray trainingOut = Nd4j.create(labelMatrix);
DataSet myData = new DataSet(trainingIn, trainingOut);
MultiLayerNetwork multiLayerNetwork = createModel(features,classes);
multiLayerNetwork.init();
multiLayerNetwork.fit(myData);
}
private static double getFeature(int i, int f) {
//dummy
return 1.;
}
private static double getResult(int i, int c) {
//dummy
return 1.;
}
public static MultiLayerNetwork createModel(int inputNum, int outputNum) {
MultiLayerConfiguration conf = new NeuralNetConfiguration.Builder()
.trainingWorkspaceMode(ENABLED).inferenceWorkspaceMode(ENABLED)
.seed(123456)
.optimizationAlgo(OptimizationAlgorithm.STOCHASTIC_GRADIENT_DESCENT)
.updater(new RmsProp.Builder().learningRate(0.05).rmsDecay(0.002).build())
.l2(0.0005)
.weightInit(WeightInit.XAVIER)
.activation(Activation.TANH)
.list()
.layer(new LSTM.Builder().name("1").nIn(inputNum).nOut(inputNum).build())
.layer(new LSTM.Builder().name("2").nIn(inputNum).nOut(inputNum).build())
.layer(new RnnOutputLayer.Builder().name("output").nIn(inputNum).nOut(outputNum)
.activation(Activation.IDENTITY).lossFunction(LossFunctions.LossFunction.MSE).build())
.build();
MultiLayerNetwork net = new MultiLayerNetwork(conf);
net.init();
return net;
}
}

Outputting data to JSON file csharp (unity)

I can't figure out how to output a complex data type to JSON.
I constructed a data type which basically holds smaller data types, I have also assigned the data types to new data types so they all seem to have a reference. I have looked into outputting complex data but don't seem to be able to find a problem similar to mine. I will consider appending data but this method will be much simpler if I can output the data type successfully.
Save Data Code
[System.Serializable]
public class SaveData
{
public MapData mapData;
}
[System.Serializable]
public class TileData
{
public List<BlockData> blockData;
}
[System.Serializable]
public class BlockData
{
public Vector3 blockPosition;
public string blockName;
public float blockOrientation;
public int blockLayer;
}
[System.Serializable]
public class MapData
{
public List<TileData> tileData;
}
Get Map Data Method
SaveData GetMapData()
{
mapHeight += mapStartY;
maplength += mapStartX;
int tileCounter = 0;
MapData mapData = new MapData();
SaveData saveData = new SaveData();
List<TileData> tileList = new List<TileData>();
for (float r = mapStartY; r < mapHeight; r++)
{
for(float c = mapStartX; c < maplength; c++)
{
Vector2 currentPosition = new Vector2(c * (blocksize)-(blocksize/2), blocksize * r -(blocksize/2));
GameObject[] currentTile = getObjectID.RayDetectAll(currentPosition);
if (currentTile!= null)
{
//adds a tiledata list here if the tile is occupied.
TileData tileData = new TileData();
//adds a list of blocks here.
List<BlockData> blocks = new List<BlockData>();
for (int i = 0; i < currentTile.Length; i++)
{
BlockData blockData = new BlockData();
GameObject currentBlock = currentTile[i];
blockData.blockPosition = currentBlock.transform.position;
blockData.blockName = currentBlock.name;
blockData.blockOrientation = currentBlock.transform.eulerAngles.z;
blockData.blockLayer = currentBlock.GetComponent<SpriteRenderer>().sortingOrder;
//adds a blockdata to the blocks list
blocks.Add(blockData);
Debug.LogWarning(blockData.blockName);
}
//need to assign tile data and add a new one to the list
tileList.Add(tileData);
//assins the blocks to tile data block data list
tileData.blockData = blocks;
}
else
{
//Debug.LogWarning("warning! no objects found on tile: " + currentPosition);
}
tileCounter++;
}
}
'''
I want the file to output all the data so that i can read the data and reassign it. Right now it outputs the data wrong.
Generally I think this is something that would be commented, but I can't comment yet.
If all you want is to convert an object to Json, could you use JsonUtility.ToJson() as described here?
just to let people know I devised a new method which counted an array of all tiles and assigned it to a data type with an array in it. It managed to load from this format.

BarabasiAlbertGenerator implementation

I wanted to implement BarabasiAlbertGenerator to generate graph. After creating all Factory objects in main method and changing the Objects (V, E) to (Integer, String) in the generator class, two errors worried me after making all possible modification.
1. index_vertex.put(v, i); type mismatch
2. index_vertex.put(newVertex, new Integer(vertex_index.size() - 1));// an Object of Integer cannot be instantiated. I made several casting the errors still appear. Please any help on how to correct the errors.
public class BarabasiAlbertGenerator<Integer, String> implements EvolvingGraphGenerator<Integer, String> {
mGraph = graphFactory.create();
vertex_index = new ArrayList<Integer>(2*init_vertices);
index_vertex = new HashMap<Integer, Integer>(2*init_vertices);
for (int i = 0; i < init_vertices; i++) {
Integer v = vertexFactory.create();
mGraph.addVertex(v);
vertex_index.add(v);
index_vertex.put(v, i);
seedVertices.add(v);
}
mElapsedTimeSteps = 0;
}
for (Pair<Integer> pair : added_pairs)
{
Integer v1 = pair.getFirst();
Integer v2 = pair.getSecond();
if (mGraph.getDefaultEdgeType() != EdgeType.UNDIRECTED ||
!mGraph.isNeighbor(v1, v2))
mGraph.addEdge(edgeFactory.create(), pair);
}
// now that we're done attaching edges to this new vertex,
// add it to the index
vertex_index.add(newVertex);
index_vertex.put(newVertex, new Integer(vertex_index.size() - 1));
}
public static void main(String[] args) {
SparseGraph<Integer, String> sir = new SparseGraph<Integer, String>();
ConstantFactory<Graph<Integer, String>> graphFactory = new ConstantFactory<Graph<Integer, String>>(sir);
InstantiateFactory<Integer> vertexFactory = new InstantiateFactory<Integer>(Integer.class);
InstantiateFactory<String> edgeFactory = new InstantiateFactory<String>(String.class);
HashSet<Integer> seedVertices = new HashSet<Integer>();
int evolve = 1;
int node = 10;
int agents = 100;
BarabasiAlbertGenerator<Integer, String> bbr = new BarabasiAlbertGenerator<Integer, String>(graphFactory, vertexFactory, edgeFactory, agents, node, seedVertices);
bbr.evolveGraph(evolve);
Layout<Integer, String> layout = new CircleLayout(sir);
layout.setSize(new Dimension(300,300));
BasicVisualizationServer<Integer,String> vv =
new BasicVisualizationServer<Integer,String>(layout);
vv.setPreferredSize(new Dimension(350,350));
// Setup up a new vertex to paint transformer...
Transformer<Integer,Paint> vertexPaint = new Transformer<Integer,Paint>() {
public Paint transform(Integer i) {
return Color.GREEN;
}
};
// Set up a new stroke Transformer for the edges
float dash[] = {10.0f};
final Stroke edgeStroke = new BasicStroke(1.0f, BasicStroke.CAP_BUTT,
BasicStroke.JOIN_MITER, 10.0f, dash, 0.0f);
Transformer<String, Stroke> edgeStrokeTransformer =
new Transformer<String, Stroke>() {
public Stroke transform(String s) {
return edgeStroke;
}
};
vv.getRenderContext().setVertexFillPaintTransformer(vertexPaint);
vv.getRenderContext().setEdgeStrokeTransformer(edgeStrokeTransformer);
vv.getRenderContext().setVertexLabelTransformer(new ToStringLabeller());
//vv.getRenderContext().setEdgeLabelTransformer(new ToStringLabeller());
vv.getRenderer().getVertexLabelRenderer().setPosition(Position.CNTR);
JFrame frame = new JFrame("Undirected Graph ");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.getContentPane().add(vv);
frame.pack();
frame.setVisible(true);
}
I don't think you want to use InstantiateFactory.
I was able to run your program after changing it to look like this (mostly the vertex and edge factories):
public static void main(String[] args) {
SparseGraph<Integer, String> sir = new SparseGraph<Integer, String>();
ConstantFactory<Graph<Integer, String>> graphFactory = new ConstantFactory<Graph<Integer, String>>(sir);
Factory<Integer> vertexFactory = new Factory<Integer>() {
int i = 0;
public Integer create() {
return i++;
}
};
Factory<String> edgeFactory = new Factory<String>() {
int i = 0;
public String create() {
return "" + i++;
}
};
HashSet<Integer> seedVertices = new HashSet<Integer>();
int evolve = 1;
int node = 10;
int agents = 100;
BarabasiAlbertGenerator<Integer, String> bbr = new BarabasiAlbertGenerator<Integer, String>(graphFactory, vertexFactory, edgeFactory, agents, node, seedVertices);
bbr.evolveGraph(evolve);
Layout<Integer, String> layout = new CircleLayout(sir);
layout.setSize(new Dimension(300, 300));
BasicVisualizationServer<Integer, String> vv =
new BasicVisualizationServer<Integer, String>(layout);
vv.setPreferredSize(new Dimension(350, 350));
// Setup up a new vertex to paint transformer...
Transformer<Integer, Paint> vertexPaint = new Transformer<Integer, Paint>() {
public Paint transform(Integer i) {
return Color.GREEN;
}
};
// Set up a new stroke Transformer for the edges
float dash[] = {10.0f};
final Stroke edgeStroke = new BasicStroke(1.0f, BasicStroke.CAP_BUTT,
BasicStroke.JOIN_MITER, 10.0f, dash, 0.0f);
Transformer<String, Stroke> edgeStrokeTransformer =
new Transformer<String, Stroke>() {
public Stroke transform(String s) {
return edgeStroke;
}
};
vv.getRenderContext().setVertexFillPaintTransformer(vertexPaint);
vv.getRenderContext().setEdgeStrokeTransformer(edgeStrokeTransformer);
vv.getRenderContext().setVertexLabelTransformer(new ToStringLabeller());
//vv.getRenderContext().setEdgeLabelTransformer(new ToStringLabeller());
vv.getRenderer().getVertexLabelRenderer().setPosition(Renderer.VertexLabel.Position.CNTR);
JFrame frame = new JFrame("Undirected Graph ");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.getContentPane().add(vv);
frame.pack();
frame.setVisible(true);
}
Make sure your imports are correct. I used these:
import edu.uci.ics.jung.algorithms.generators.random.BarabasiAlbertGenerator;
import edu.uci.ics.jung.algorithms.layout.CircleLayout;
import edu.uci.ics.jung.algorithms.layout.Layout;
import edu.uci.ics.jung.graph.Graph;
import edu.uci.ics.jung.graph.SparseGraph;
import edu.uci.ics.jung.visualization.BasicVisualizationServer;
import edu.uci.ics.jung.visualization.decorators.ToStringLabeller;
import edu.uci.ics.jung.visualization.renderers.Renderer;
import org.apache.commons.collections15.Factory;
import org.apache.commons.collections15.Transformer;
import org.apache.commons.collections15.functors.ConstantFactory;
import javax.swing.*;
import java.awt.*;
import java.util.HashSet;

Nonfunctioning "for loop" for addressing each variable of class

I'm learning AS3 but have some antiquated background in programming (TP and Atari Basic). On this forum I learned to use a loop such as the one below to address each variable in an object class, in order to make a clone of the object (deep or shallow) or in my case to build the text for a tooltip. However mine doesn't work. Here's the loop, following is an explanation, any help you can give I'd appreciate greatly!
var tooltipText:String;
var i:String;
for (i in bsm) {
if (!(bsm[i] is String)) {
if (bsm[i] != 0) {
tooltipText = i + ": " + bsm[i];
tooltip.extendTooltip(tooltipText, 0xFFFFFF);
}
}
}
Please forgive the horrible variable names. 'i' is a String. 'bsm' is a non-null instance of class StatMod, which begins with
public class StatMod extends Object {
public static const ENCHANTMENTMODIFIER:String = "enchantmentModifier";
public var enchantmentType:String = "None";
public var enchantmentDescriptor:String = "None";
public var minDamage:Number = 0;
public var maxDamage:Number = 0;
public var attackSpeed:Number = 0.2;
The intended behavior is to go through each of the variables of StatMod (I'm not showing them all and I will add more later), and if the variable is a non-zero number, make a string ("attackSpeed: 0.2" for instance) and then add that string to the tooltip. The tooltip.extendTooltip function is working properly.
The observed behavior is basically the computer believing that there are no variables in bsm.
What can I say or do to convince the computer that there actually are variabels in bsm?
The behavior you're expecting is only the case when iterating over dynamically attached properties. For example, if you marked your class dynamic:
public dynamic class StatMod { }
Then added some values to it at runtime:
bsm.test = 5;
Your loop will find the property test with the value 5.
Some options you have to achieve what you want are:
Extend the Proxy class to define what properties are iterable via nextName and nextNameIndex.
Use describeType to generate a list of all the public properties.
Though a simpler method is to expose a list of the properties you want to iterate over and use that in your loop instead, something like:
public class StatMod {
// Existing properties etc.
private _properties:Vector.<String>;
public function get properties():Vector.<String> {
if (_properties === null) {
_properties = new <String>[
'enchantmentType',
'enchantmentDescription',
'minDamage',
'maxDamage',
'attackSpeed'
];
}
return _properties;
}
}
Then:
for (var i:int = 0; i < bsm.properties.length; i++) {
var prop:String = bsm.properties[i];
trace(prop, bsm[prop]);
}

how to pass argument to Marionette.CompositeView

how to pass a values dynamically to an Marionette.CompositeView during run time? like in java we create a method like the following
package com.test.poc;
public class SampleMethod {
public int add(int a, int b) {
return a + b;
}
public static void main(String[] args) {
SampleMethod method = new SampleMethod();
int firstValue = 90, secondValue = 90;
System.out.println("add : " + method.add(firstValue, secondValue));
}
}
the above is the simple java code anybody can understand like the above how to create and pass arguments to Marionette.CompositeView and work on them?
Best Regards
at the moment you instanciate a view, you can pass whatever arguments you want. normally you pass the model and the collection to be rendered in the compositeView, but you can pass more data if you need.
var MyCompositeView = Backbone.Mationette.CompositeView.extend({
initialize : function (options){
this.dataValue = options.dataValue1;
this.helperObject = options.helperObject;
this.useValues();
},
useValues: function () {
console.log(this.dataValue);
}
});
var helperObject = {
value3 : "I have a value",
value4 : "I dont!"
}; /// a js object literal
var myModel = new MyModel();
var myCollection = new MyCollection();
var myCompositeView = new MyCompositeView({model:myModel,
collection:myCollection,
helperObject:helperObject,
dataValue1:"Hi there"});
notice that Im passing 4 values in the at the time to intanciate the view, and Im reading just two of them, the model and the collection will be handled by marionette, but the other two you can read them in your initialize function.
hope that helps.