I need to traverse a Tree Field in Blackberry .
I need to know how to check from the existing node whether it is a parent node or child node ?
Since I need a different row color for Child rows and Parent rows
I have referred a previous question of Customising TreeField as seen in link below
Customising Blackberry Treefield
It looks like you're already using the TreeFieldCallback to customize painting of your tree field. You can detect parent vs. child nodes here in drawTreeItem().
However, we need to be clear about what you consider "parent" and "child", because technically, it's possible for a row to be both a parent and a child, if the tree has more than 2 levels (in addition to the root level).
If "Child" == "Leaf" Node
Use:
public void drawTreeItem(TreeField treeField, Graphics graphics, int node, int y, int width, int indent) {
boolean isChild = treeField.getFirstChild(node) == -1;
if (isChild) {
// draw child row color
} else {
// draw parent row color
}
}
assuming that what you mean by "child" is a row that has no more children of its own (also called a "leaf" node).
If "Child" == "Non-Root Parent"
If you consider a node that has both a non-root parent of its own and a child of its own to be a "child" row, then use this logic:
public void drawTreeItem(TreeField treeField, Graphics graphics, int node, int y, int width, int indent) {
boolean isParent = treeField.getParent(node) == 0;
if (isParent) {
// draw parent row color
} else {
// draw child row color
}
}
this second implementation will only color rows that are directly under the root node as "parents".
Related
I have a 2048-type game where the gameboard grid is made up of a list of 4 other lists (each of which contain 4 Tiles).
Each time a move is made, the newGameboardGrid is saved in yet another list (so that removeLast can be called when a player wants to undo a move).
When a player swipes, I need to compare the newGameboardGrid grid with the previous one to see if any actual movement took place or if the tile values are still the same (as would happen if a player swiped in a direction where no movement was possible).
I tried this code:
if (newGameboardGrid == listOfGameboardGrids.last) {
// do something
}
It almost works in that it is comparing the <List<List< Tile>> from the new move with the <List<List< Tile>> of the last move, but the problem is that it never results in the two <List<List< Tile>> as being equal, even when all the tile values are identical. I believe it's because it is comparing hashcodes and/or other things.
The Tile class has lots of stuff in it, but the thing I would like to compare is that int named "value". Is it possible to compare only the "value" variable for these two <List<List< Tile>>?
Thanks in advance for any help! (And apologies if any of my terms are imprecise.)
Dart list implementations do not override the operator== of Object, so they are only ever equal to themselves. The elements are not checked.
IF you want to compare the elements (and here, the elements of the list elements), you can use the Equality classes from package:collection:
const boardEquality = ListEquality(ListEquality(DefaultEquality()));
This creates a ListEquality object which compares two lists of lists of elements by checking that they contain the same number of lists, which again contains the same number of equal elements. (I assume that Tile implements operator==).
You can the use it as: if (boardEquality.equals(newGameboardGrid, listOfGameboardGrids.last)) { ... }.
You could do an extension method on your particular list type and make an isEqual method for that compares each Tile:
extension TileListComp on List<List<Tile>> {
bool isEqual(List<List<Tile>> other) {
if(this.length != other.length || this[0]?.length != other[0]?.length) {
return false;
}
for(int x = 0; x < this.length; x++) {
for(int y = 0; y < this[0].length; y++) {
if(this[x][y] != other[x][y]) {
return false;
}
}
}
return true;
}
}
If you have not implemented any kind of comparison for your Tile class, you will need to do so. I can advise if necessary.
The task at hand is to add a band selection tool to a Dart WebGL application.
The tool will be used to draw a rectangle over multiple objects by dragging the mouse.
Thus multiple objects can be selected/picked in a single user action.
I'm currently using gl.readPixels() to read colors from an off-screen renderbuffer.
Problem is, when a large area is band-selected, gl.readPixels() issues millions of pixels.
Scanning such a big amount of colors wastes precious seconds just to locate few objects.
Please anyone point possibly faster methods for band-selecting multiple objects with Dart+WebGL.
For reference, I show below the current main portion of the band selection tool.
Uint8List _color = new Uint8List(4);
void bandSelection(int x, y, width, height, PickerShader picker, RenderingContext gl, bool shift) {
if (picker == null) {
err("bandSelection: picker not available");
return;
}
int size = 4 * width * height;
if (size > _color.length) {
_color = new Uint8List(size);
}
gl.bindFramebuffer(RenderingContext.FRAMEBUFFER, picker.framebuffer);
gl.readPixels(x, y, width, height, RenderingContext.RGBA, RenderingContext.UNSIGNED_BYTE, _color);
if (!shift) {
// shift is released
_selection.clear();
}
for (int i = 0; i < size; i += 4) {
if (_selection.length >= picker.numberOfInstances) {
// selected all available objects, no need to keep searching
break;
}
PickerInstance pi = picker.findInstanceByColor(_color[i], _color[i+1], _color[i+2]);
if (pi == null) {
continue;
}
_selection.add(pi);
}
debug("bandSelection: $_selection");
}
// findInstanceByColor is method from PickerShader
PickerInstance findInstanceByColor(int r, g, b) {
return colorHit(_instanceList, r, g, b);
}
PickerInstance colorHit(Iterable<Instance> list, int r,g,b) {
bool match(Instance i) {
Float32List f = i.pickColor;
return (255.0*f[0] - r.toDouble()).abs() < 1.0 &&
(255.0*f[1] - g.toDouble()).abs() < 1.0 &&
(255.0*f[2] - b.toDouble()).abs() < 1.0;
}
Instance pi;
try {
pi = list.firstWhere(match);
} catch (e) {
return null;
}
return pi as PickerInstance;
}
Right now I can see small solutions that might speed up your algorithm to limit as much as possible iterating over all of your elements,
The first thing you can do is have a default colour. When you see that colour, you know you don't need to iterate all over your array of elements.
It will accelerate large poorly populated areas.
It's very easy to implement, just adding a if.
For more dense areas you can implement some kind of colour caching. That means you store an array of colour you encountered. When you check a pixel, you first check the cache and then go over the entire list of elements, and if you find the element, add it to the cache.
It should accelerate cases with few big elements but will be bad if you have lots of small elements, which is very unlikely if you have picking...
You can accelerate your cache buy sorting your cached elements by last hit or/and by number of hits, it's very likely to find the same element in a continuous raw of pixels.
It's more work but stays relatively easy and short to implement.
Last optimisation would be to implement a space partitioning algorithm to filter the elements you want to check.
That would be more work but will pay better of on the long run.
edit :
I'm not a dart guy but this is how it would look like to implement in a basic way the first two optimisations:
var cache = new Map<UInt32, PickerInstance>();
for (int i = 0; i < size; i += 4) {
UInt32 colour = _color[i] << 24 | _color[i+1] << 16 | _color[i+2] << 8 | 0; // I guess we can just skip transparency.
if (_selection.length >= picker.numberOfInstances) {
// selected all available objects, no need to keep searching
break;
}
// black is a good default colour.
if(colour == 0) {
// if the pixel is black we didn't hit any element :(
continue;
}
// check the cache
if(cache[colour] != null) {
_selection.add(cache[colour]);
continue;
}
// valid colour and cache miss, we can't avoid iterating the list.
PickerInstance pi = picker.findInstanceByColor(_color[i], _color[i+1], _color[i+2]);
if (pi == null) {
continue;
}
_selection.add(pi);
// update cache
cache[colour] = pi;
}
I want to make a game where the player can place objects in an existing gamemap like a wall or different kind of turrets.
The gamemap consist 2 things:
So basicaly the main gamemap where the player can walk around in, that exist of trees, walls and water that is already there.
And the objects (with their specific heights and widths) that the player can place (when he gots wood, gold (when the player slays monsters etc) in that main gamemap.
How should I approach this? Any tips, class structures with methods would be nice to have.
The main gamemap could be a grid of tiles. Your turrets could then have width and height as multiples of the tile sizes and occupy a certain number of them.
For example, a 2x2 turret would occupy four tiles. Limiting turrets/walls to tiles rather than giving them arbitrary positions and lengths is limiting, but it allows you faster collision detection.
You could then have:
class Tile
{
public Building WhatIsConstructedHereIfAnything;
}
and
class Building
{
public List<Tile> TilesOccupiedByThisBuilding;
}
You could then update the building by going over the list of buildings and handle collisions only by looking at nearby tiles.
Add a Rectangle to your object class, and use its Width and Height properties.
class YourObject
{
public Rectangle Rectangle;
public YourObject(Vector2 position, int width, int height)
{
Rectangle = new Rectangle((int)position.X, (int)position.Y, width, height);
}
public void Draw()
{
spritebatch.Draw(Texture, Rectangle, Color);
}
}
I have a property called FitToPlay and it contains a list of Players that are not injured. What I want to do is make a drop down box for each position in a team and only fill the drop down box with the players in the fit to play list that have the position in question as either their primary or secondary position.
What I want to know is how can I just display specific objects using html drop down box helper.
Many thanks in advance.
J
I think you would want to loop through each position and inside the loop go through all the currently FitToPlay players and if either his first or secondary position is the currently looped through position then insert him into it.. in the end if someone was inserted create a dropdownlist
So something like..
//Loop through all the positions
foreach (var position in Model.positions)
{
//Create a list for each position
List<SelectListItem> playersInPosition = new List<SelectListItem>();
//Only loop through players with the current position as either primary or secondary
foreach(var player in Model.FitToPlay.Where(pl => pl.primary == position || pl.secondary == position))
{
//Put this player into the list
playersInPosition.add(new SelectListItem { Text = player.name, Value = player.id});
}
//If at least one fits the criteria make a drop down list from it
if(playersInPosition != null && playersInPosition.Count > 0)
{
#Html.DropDownList(position.name, playersInPosition);
}
}
In DirectX it is possible to set the D3DXSPRITE parameters to be a combination of both:
D3DXSPRITE_SORT_DEPTH_BACKTOFRONT
and
D3DXSPRITE_SORT_TEXTURE
Meaning that sprites are sorted first by their layer depth and then secondly by the texture that they are on. I'm trying to do the same in XNA and i'm having some problems. I've tried:
SpriteBtch.Begin(SpriteBlendMode.AlphaBlend, SpriteSortMode.BackToFront & SpriteSortMode.Texture, SaveStateMode.None);
But it doesn't work and just seems to do them in Texture ordering, ignoring the textures layer depth. Am I doing something wrong!? Or is it not even possible?
SpriteSortMode is an enum and should be combined using the | operator:
SpriteSortMode.BackToFront | SpriteSortMode.Texture
Update: as this article mentions, your scenario is not possible in XNA:
sorting by depth and sorting by
texture are mutually exclusive
A possible solution :
Define a new object representing a sprite to draw
class Sprite
{
public float Priority { get; set; } // [0..1]
public String TextureName { get; set; }
public void Draw(SpriteBatch spriteBatch)
{
spriteBatch.Draw(TextureName, ..., Priority); // here Priority is useless because of the sort mode.
}
}
Then add a "sprites to draw" list that you:
Sort by drawing priority, reverse order so Priority == 1 is first
Sort by texture when a.Priority == b.Priority (this is the tricky part but not THAT hard)
So in your Main class for example, you'll have :
private List<Sprite> spritesToDrawThisTick = new List<Sprite>();
And every tick, you :
Add sprites to draw
Do the sorting logic
Call your SpriteBatch.Begin using SpriteSortMode.Immediate
Do a foreach on your list to call every Sprite's Draw method
important: empty your spritesToDrawThisTick list