Unity Instantiate GameObject not working in iOS - ios

I have a level loading script that draws a level from an array representation loaded from file. This works fine in unity editor but when I build for ios those objects dynamically drawn do not display.
Here is the code that does the drawing:
void DrawNewLevel(int level) {
LevelEditor.Level lvl = new LevelEditor.Level (1, level);
for (int x = 0; x < 260; x++) {
for (int y = 0; y < 23; y++) {
GameObject gameObject;
if (lvl.LevelContents[x, y].BlockType != LevelEditor.BlockType.Empty) {
Debug.Log("drawing non-null");
if (lvl.LevelContents[x, y].BlockType == LevelEditor.BlockType.Floor) {
gameObject = Instantiate(Floor);
gameObject.transform.position = new Vector3(x, 23-y, 0);
} else if (lvl.LevelContents[x, y].BlockType == LevelEditor.BlockType.FloorBad) {
gameObject = Instantiate(FloorBad);
gameObject.transform.position = new Vector3(x, 23-y, 0);
} else if (lvl.LevelContents[x, y].BlockType == LevelEditor.BlockType.SmartRocketLauncher) {
gameObject = Instantiate(SmartRocketLauncher);
gameObject.transform.position = new Vector3(x, 23-y, 1);
}
}
}
}
}

Related

I can't find why memory isn't release using in SharpDX

I'm making on some Winform application, I noticed my program's memory issue.
This is my winform custom control code.
using System;
using System.Drawing;
using System.Windows.Forms;
using DX = SharpDX;
using D2D = SharpDX.Direct2D1;
using SharpDX.Mathematics.Interop;
using DW = SharpDX.DirectWrite;
namespace WinFormTest
{
public partial class BitmapSurface : Control
{
D2D.Factory d2dFactory;
DW.Factory dwFactory;
D2D.WindowRenderTarget wrt;
D2D.BitmapRenderTarget brt;
Rectangle clippingRect = new Rectangle(0, 0, 100, 100);
public BitmapSurface()
{
InitializeComponent();
InitializeRenderer();
}
DX.Size2 clientSize2;
DX.Size2F clientSize2f;
protected override void OnResize(EventArgs e)
{
base.OnResize(e);
if (clientSize2 == null)
clientSize2 = new DX.Size2();
if (clientSize2f == null)
clientSize2f = new DX.Size2F();
clientSize2.Width = ClientSize.Width;
clientSize2.Height = ClientSize.Height;
clientSize2f.Width = ClientSize.Width;
clientSize2f.Height = ClientSize.Height;
if (wrt != null)
{
wrt.Resize(clientSize2);
}
if (brt != null)
{
brt.Dispose();
brt = new D2D.BitmapRenderTarget(wrt, D2D.CompatibleRenderTargetOptions.None, clientSize2f, null, null);
brt.AntialiasMode = D2D.AntialiasMode.Aliased;
}
this.Invalidate();
}
private D2D.SolidColorBrush GetBrush(float r, float g, float b, float a = 255)
{
var brush = new D2D.SolidColorBrush(
wrt, new RawColor4(r / 255.0f, g / 255.0f, b / 255.0f, a / 255.0f));
return brush;
}
protected override void OnPaint(PaintEventArgs pe)
{
base.OnPaint(pe);
clippingRect = this.ClientRectangle;
var rect = clippingRect;
DrawBitmap();
}
public void InitializeRenderer()
{
int width = this.ClientSize.Width;
int height = this.ClientSize.Height;
D2D.HwndRenderTargetProperties hrtp = new D2D.HwndRenderTargetProperties();
hrtp.Hwnd = this.Handle;
hrtp.PixelSize = new DX.Size2(width, height);
// D2DFactory
if (d2dFactory == null)
d2dFactory = new D2D.Factory();
// DirectWrite
if (dwFactory == null)
dwFactory = new DW.Factory();
wrt = new D2D.WindowRenderTarget(d2dFactory, new D2D.RenderTargetProperties(), hrtp);
wrt.AntialiasMode = D2D.AntialiasMode.Aliased;
brt = new D2D.BitmapRenderTarget(wrt, D2D.CompatibleRenderTargetOptions.None, new DX.Size2F(width, height), null, null);
brt.AntialiasMode = D2D.AntialiasMode.Aliased;
}
public void DrawBitmap()
{
brt.BeginDraw();
brt.Clear(new RawColor4(0, 0, 0, 1));
// Draw Something
for (int i = 0; i < 1000; i++)
{
brt.DrawLine(
new RawVector2(0, i),
new RawVector2(90, 90 + i),
GetBrush(255, 255, 255));
}
for (int i = 0; i < 1000; i++)
{
brt.FillRectangle(
new RawRectangleF(90, 0 + i, 150, 10 + i),
GetBrush(255 - i, 255 - i, 255 - i));
}
brt.EndDraw();
wrt.BeginDraw();
wrt.DrawBitmap(brt.Bitmap, 1, D2D.BitmapInterpolationMode.NearestNeighbor);
wrt.EndDraw();
}
}
}
My program's mainform can have many childs, Child draw somethings with SharpDX.
Memory usage is increase When I open child forms, but after closing child form and GC.Collect memory usage is NOT decrease.
Is this bad usage for SharpDX?

Actionscript 3.0 Creating Boundaries with Arrays

Currently I'm working on a project recreating a mario level, my issue is that when I do not hard code the bottomLimit (the floor, currently set to 400) Mario will eventually just fall through.
Another thing I can't quite figure out is how I can move my invisible block that creates the floor boundary to accomodate the flooring. The level chosen is the Fortress level of Super Mario Brothers 3, if that helps picture what I'm trying to do with it.
There are a couple .as files to my code, I will put my troublesome file in along with my collision code.
package {
import flash.display.MovieClip;
import flash.events.Event;
import flash.ui.Keyboard;
import flash.events.KeyboardEvent;
import flash.media.Sound;
public class FortressMap extends MovieClip
{
private var _mario:SmallMario;
private var vx:Number = 0;
private var vy:Number = 0;
private var _ceiling:Array = new Array();
private var _floor:Array = new Array();
public const accy:Number = 0.20;
public const termv:Number = 15;
public var onGround:Boolean;
public var bottomLimit:Number;
public function FortressMap()
{
addEventListener(Event.ADDED_TO_STAGE, addedToStageHandler);
_mario = new SmallMario();
addChild(_mario);
_mario.x = 50;
_mario.y = 400;
//Creating the blocks for the floor
createFloor(16, 416);
//Creating the blocks for the ceiling
createCeiling(16, 352);
}
private function createFloor(xPos:Number, yPos:Number):void
{
var floor:Floor = new Floor();
addChild(floor);
floor.x = xPos;
floor.y = yPos;
floor.height = 16;
_floor.push(floor);
floor.visible = false;
}
private function createCeiling(xPos:Number, yPos:Number):void
{
var ceiling:Ceiling = new Ceiling();
addChild(ceiling);
ceiling.x = xPos;
ceiling.y = yPos;
ceiling.height = 16;
_ceiling.push(ceiling);
ceiling.visible = false;
}
private function addedToStageHandler(event:Event):void
{
removeEventListener(Event.ADDED_TO_STAGE, addedToStageHandler);
addEventListener(Event.ENTER_FRAME, frameHandler);
addEventListener(Event.REMOVED_FROM_STAGE, removeStageHandler);
stage.addEventListener(KeyboardEvent.KEY_DOWN, keyDownHandler);
stage.addEventListener(KeyboardEvent.KEY_UP, keyUpHandler);
}
private function frameHandler(event:Event):void
{
_mario.x += vx;
_mario.y += vy;
if (_mario.x < 16)
{
_mario.x = 16;
}
vy += accy;
for (var i:int = 0; i < _ceiling.length; ++i)
{
Collision.block(_mario, _ceiling[i]);
}
for (var j:int = 0; j < _floor.length; ++j)
{
Collision.block(_mario, _floor[j]);
}
bottomLimit = 400;
if(_mario.y >= bottomLimit)
{
_mario.y = bottomLimit;
vy = 0;
onGround = true;
}
else
{
onGround = false;
}
}
private function keyDownHandler(event:KeyboardEvent):void
{
if (event.keyCode == Keyboard.LEFT)
{
vx = -5;
return;
}
if (event.keyCode == Keyboard.RIGHT)
{
vx = 5;
return;
}
if (event.keyCode == Keyboard.UP)
{
if(onGround == true)
{
vy = -5;
trace("My people need me!");
}
return;
}
if (event.keyCode == Keyboard.DOWN)
{
//vy = 5;
return;
}
}
private function keyUpHandler(event:KeyboardEvent):void
{
if (event.keyCode == Keyboard.LEFT || event.keyCode == Keyboard.RIGHT)
{
vx = 0;
return;
}
if (event.keyCode == Keyboard.UP || event.keyCode == Keyboard.DOWN)
{
//vy = 0;
return;
}
}
private function removeStageHandler(event:Event):void
{
removeEventListener(Event.ENTER_FRAME, frameHandler);
removeEventListener(Event.REMOVED_FROM_STAGE, removeStageHandler);
stage.removeEventListener(KeyboardEvent.KEY_DOWN, keyDownHandler);
stage.removeEventListener(KeyboardEvent.KEY_UP, keyUpHandler);
}
}
package
{
import flash.display.Sprite;
public class Collision
{
static public var collisionSide:String = "";
public function Collision()
{
}
static public function block(r1:Sprite, r2:Sprite):Boolean
{
var isBlocked:Boolean;
//Calculate the distance vector
var vx:Number
= (r1.x + (r1.width / 2))
- (r2.x + (r2.width / 2));
var vy:Number
= (r1.y + (r1.height / 2))
- (r2.y + (r2.height / 2));
//Check whether vx
//is less than the combined half widths
if(Math.abs(vx) < r1.width / 2 + r2.width / 2)
{
//A collision might be occurring! Check
//whether vy is less than the combined half heights
if(Math.abs(vy) < r1.height / 2 + r2.height / 2)
{
//A collision has ocurred! This is good!
//Find out the size of the overlap on both the X and Y axes
var overlap_X:Number
= r1.width / 2
+ r2.width / 2
- Math.abs(vx);
var overlap_Y:Number
= r1.height / 2
+ r2.height / 2
- Math.abs(vy);
//The collision has occurred on the axis with the
//*smallest* amount of overlap. Let's figure out which
//axis that is
if(overlap_X >= overlap_Y)
{
//The collision is happening on the X axis
//But on which side? _v0's vy can tell us
if(vy > 0)
{
collisionSide = "Top";
//Move the rectangle out of the collision
r1.y = r1.y + overlap_Y;
//r1 is being blocked
isBlocked = true;
}
else
{
collisionSide = "Bottom";
//Move the rectangle out of the collision
r1.y = r1.y - overlap_Y;
//r1 is being blocked
isBlocked = true;
}
}
else
{
//The collision is happening on the Y axis
//But on which side? _v0's vx can tell us
if(vx > 0)
{
collisionSide = "Left";
//Move the rectangle out of the collision
r1.x = r1.x + overlap_X;
//r1 is being blocked
isBlocked = true;
}
else
{
collisionSide = "Right";
//Move the rectangle out of the collision
r1.x = r1.x - overlap_X;
//r1 is being blocked
isBlocked = true;
}
}
}
else
{
//No collision
collisionSide = "No collision";
//r1 is not being blocked
isBlocked = false;
}
}
else
{
//No collision
collisionSide = "No collision";
//r1 is not being blocked
isBlocked = false;
}
return isBlocked;
}
}
}
I think what you want to do is to set the bottomlimit, but not hardcode the number 400, correct?
I would do change your createFloor method:
private function createFloor(xPos:Number, yPos:Number):void
{
var floor:Floor = new Floor();
addChild(floor);
floor.x = xPos;
floor.y = yPos;
floor.height = 16;
_floor.push(floor);
floor.visible = false;
// set bottom limit here
bottomLimit = yPos;
}
... then you wouldnt need to set it to 400.
However, another option is to change your if statement:
if(_mario.y >= Floor(_floor[0]).y)
{
_mario.y = Floor(_floor[0]).y;
vy = 0;
onGround = true;
}
else
{
onGround = false;
}
... and then you can get rid of the bottomLimit variable completely
(assuming I understood your code, and that the floor tiles are always going to be at the bottomLimit)

Processing with tuio

hi i am new to processing and i'm trying to figure out how to make the sphere move from left to right using a marker instead of the mouse. can you help me please? i can use the marker to shoot but i cant move the sphere by shooting
import TUIO.*;
TuioProcessing tuioClient;
HashMap symbols=new HashMap();
PFont fontA;
int sphereDiameter = 50;
boolean shoot = false;
float obj_size = 60;
int randx()
{
return int(random(600));
}
int[] sphereXCoords = { randx(), randx(), randx(), randx(), randx() };
int[] sphereYCoords = { 0, 0, 0, 0, 0 };
void setup()
{
size(1000,700);
tuioClient = new TuioProcessing(this);
}
void draw()
{
Vector<TuioObject> tuioObjectList =tuioClient.getTuioObjects();
Collections.sort(tuioObjectList, comp);
for (TuioObject tobj:tuioObjectList) {
fill(50, 50, 100);
int id = tobj.getSymbolID();
int x = tobj.getScreenX(width);
int y = tobj.getScreenY(height);
rect(x, y, obj_size, obj_size);
String txt="?";
if (symbols.containsKey(id)) {// if it's one in symbols, then look it up
txt = (String)symbols.get(id);
}
fill(255);
text(txt, x, y);
}
int[] sphereXCoords = { randx(), randx(), randx(), randx(), randx() };
fill(100, 0, 0);
// draw the answer box
// ellipse(answerX, answerY, obj_size, obj_size);
fill(255);
// write the answer text
// text(""+answer, answerX, answerY);
background(1);
fill(color(255,255,0));
stroke(color(0,255,0));
triangle(mouseX-8, 580, mouseX+8, 580, mouseX, 565);
fill(color(255,0,0));
stroke(color(255,0,0));
if(shoot==true)
{
sphereKiller( mouseX);
shoot = false;
}
sphereDropper();
//gameEnder();
}
Comparator<TuioObject> comp = new Comparator<TuioObject>() {
// Comparator object to compare two TuioObjects on the basis of their x position
// Returns -1 if o1 left of o2; 0 if they have same x pos; 1 if o1 right of o2
public int compare(TuioObject o1, TuioObject o2) {
if (o1.getX()<o2.getX()) {
return -1;
}
else if (o1.getX()>o2.getX()) {
return 1;
}
else {
return 0;
}
}
};
void mousePressed()
{
shoot = true;
}
void sphereDropper()
{
stroke(255);
fill(255);
for (int i=0; i<5; i++)
{
ellipse(sphereXCoords[i], sphereYCoords[i]++,
sphereDiameter, sphereDiameter);
}
}
void sphereKiller(int shotX)
{
boolean hit = false;
for (int i = 0; i < 5; i++)
{
if((shotX >= (sphereXCoords[i]-sphereDiameter/2)) &&
(shotX <= (sphereXCoords[i]+sphereDiameter/2)))
{
hit = true;
line(mouseX, 565, mouseX, sphereYCoords[i]);
ellipse(sphereXCoords[i], sphereYCoords[i],
sphereDiameter+25, sphereDiameter+25);
sphereXCoords[i] = randx();
sphereYCoords[i] = 0;
}
}
if(hit == false)
{
line(mouseX, 565, mouseX, 0);
}
}
/* void gameEnder()
{
for (int i=0; i< 5; i++)
{
if(sphereYCoords[i]==600)
{
fill(color(255,0,0));
noLoop();
}
}
}*/
void addTuioObject(TuioObject tobj) {
}
// called when an object is removed from the scene
void removeTuioObject(TuioObject tobj) {
}
/ / called when an object is moved
void updateTuioObject (TuioObject tobj) {
if(tobj.getSymbolID() == 32)
{
shoot = true;
}
}
// called when a cursor is added to the scene
void addTuioCursor(TuioCursor tcur) {
}
// called when a cursor is moved
void updateTuioCursor (TuioCursor tcur) {
}
// called when a cursor is removed from the scene
void removeTuioCursor(TuioCursor tcur) {
}
// called after each message bundle
// representing the end of an image frame
void refresh(TuioTime bundleTime) {
//redraw();
}
What do you mean by "shooting" ?
So you have your tuioClient and you initialize it in setup(). Thats good, because then the callback methods (addTuioObject, removeTuioObject, updateTuioObject, addTuioCursor, updateTuioCursor, removeTuioCursor, refresh) will fire whenever your sketch receives a TUIO message.
Keep in mind that TUIO is based on OSC which is transported over UDP. That means the tracker (reactivision & co) will have to send to the IP and port your sketch is listening to. If both are on the same machine use 127.0.0.1 and port 3333 (default).
Have a look at the examples. You'll find them in the processing "IDE" click:
"File -> Examples"
and Navigate to
"Contributed Libraries -> TUIO"

Collision stops all characters moving in the list

I am making a game where characters come from opposite sides of the screen and collide and attack each other then they are removed when they die. I have managed to enable the lists to stop moving and do damage when they collide but my problem is when 2 of them collide all of them stop moving.
My code for the shortswordsman collisions is:
private void shortMoveCollisions(GameTime gameTime)
{
Rectangle shortRect;
int shortSpeed = 2;
int shortDamage = 20;
bool collided = false;
for (int i = 0; i < shortList.Count; i++)
{
List<Goblin> tempGoblinList = new List<Goblin>(goblinList);
shortRect = new Rectangle((int)shortList[i].position.X, (int)shortList[i].position.Y, ShortSwordsman.texture.Width / 4 - 20, ShortSwordsman.texture.Height);
foreach (Goblin goblin in tempGoblinList)
{
Rectangle goblinRect = new Rectangle((int)goblin.position.X, (int)goblin.position.Y, Goblin.texture.Width / 4 - 20, Goblin.texture.Height);
if (shortRect.Intersects(goblinRect))
{
collided = true;
shortList[i].AnimateAttack(gameTime);
shortTimer += (float)gameTime.ElapsedGameTime.TotalSeconds;
if (shortTimer >= shortDelay)
{
shortTimer -= shortDelay;
goblin.health -= shortDamage;
if (goblin.health <= 0)
{
goblinList.Remove(goblin);
}
}
}
}
if (shortRect.Intersects(background.badCastleRect))
{
collided = true;
shortList[i].AnimateAttack(gameTime);
shortTimer += (float)gameTime.ElapsedGameTime.TotalSeconds;
if (shortTimer >= shortDelay)
{
shortTimer -= shortDelay;
badCastleHealth -= shortDamage;
}
}
if (collided == false)
{
shortList[i].AnimateWalk(gameTime);
shortList[i].position.X += shortSpeed;
}
}
}
And my code for the goblins collisions is:
private void GoblinMoveCollisions(GameTime gameTime)
{
Rectangle goblinRect;
int goblinSpeed = 2;
int goblinDamage = 20;
bool collided = false;
for (int i = 0; i < goblinList.Count; i++)
{
List<ShortSwordsman> tempShortList = new List<ShortSwordsman>(shortList);
goblinRect = new Rectangle((int)goblinList[i].position.X, (int)goblinList[i].position.Y, Goblin.texture.Width / 4 - 20, Goblin.texture.Height);
foreach (ShortSwordsman shortSwordsman in tempShortList)
{
Rectangle shortRect = new Rectangle((int)shortSwordsman.position.X, (int)shortSwordsman.position.Y, ShortSwordsman.texture.Width / 4 - 20, ShortSwordsman.texture.Height);
if (goblinRect.Intersects(shortRect))
{
collided = true;
goblinList[i].AnimateAttack(gameTime);
goblinAttackTimer += (float)gameTime.ElapsedGameTime.TotalSeconds;
if (goblinAttackTimer >= goblinAttackDelay)
{
goblinAttackTimer -= goblinAttackDelay;
shortSwordsman.health -= goblinDamage;
if (shortSwordsman.health <= 0)
{
shortList.Remove(shortSwordsman);
}
}
}
}
if (goblinRect.Intersects(background.goodCastleRect))
{
collided = true;
goblinList[i].AnimateAttack(gameTime);
goblinAttackTimer += (float)gameTime.ElapsedGameTime.TotalSeconds;
if (goblinAttackTimer >= goblinAttackDelay)
{
goblinAttackTimer -= goblinAttackDelay;
goodCastleHealth -= goblinDamage;
}
}
if (collided == false)
{
goblinList[i].AnimateWalk(gameTime);
goblinList[i].position.X -= goblinSpeed;
}
}
}
Your collided bool shouldn't be a variable of those classes, as those classes seem to operate on the entire lists of all the entities. Instead the collision detection should happen on an entity by entity basis, basically: make the collided bool a property of goblins and swordsmen. This would mean that you'll have to check for intersections with other creatures of the same type as well, probably without an attack command.
This is the code I am using at the moment - shortswordsman and goblin are the same so i will only show one:
In the goblin class:
public Goblin(Vector2 position, float health, bool Collided, Rectangle goblinRect)
{
this.position = position;
this.health = health;
this.Collided = Collided;
this.goblinRect = goblinRect;
}
In the game1 class:
void CreateGoblin()
{
goblinList.Add(new Goblin(new Vector2(1900, 270), 100, false, new Rectangle()));
}
And then for the collisions i tried this - this includes the bit to try and stop them overlapping each other:
private void GoblinMoveCollisions(GameTime gameTime)
{
int goblinSpeed = 2;
int goblinDamage = 20;
for (int i = 0; i < goblinList.Count; i++)
{
goblinList[i].Collided = false;
goblinList[i].goblinRect = new Rectangle((int)goblinList[i].position.X, (int)goblinList[i].position.Y, Goblin.texture.Width / 4 - 20, Goblin.texture.Height);
List<ShortSwordsman> tempShortList = new List<ShortSwordsman>(shortList);
foreach (ShortSwordsman shortSwordsman in tempShortList)
{
Rectangle shortRect = new Rectangle((int)shortSwordsman.position.X, (int)shortSwordsman.position.Y, ShortSwordsman.texture.Width / 4 - 20, ShortSwordsman.texture.Height);
if (goblinList[i].goblinRect.Intersects(shortRect))
{
goblinList[i].Collided = true;
goblinList[i].AnimateAttack(gameTime);
goblinAttackTimer += (float)gameTime.ElapsedGameTime.TotalSeconds;
if (goblinAttackTimer >= goblinAttackDelay)
{
goblinAttackTimer -= goblinAttackDelay;
shortSwordsman.health -= goblinDamage;
if (shortSwordsman.health <= 0)
{
shortList.Remove(shortSwordsman);
}
}
}
}
if (goblinList[i].goblinRect.Intersects(background.goodCastleRect))
{
goblinList[i].Collided = true;
goblinList[i].AnimateAttack(gameTime);
goblinAttackTimer += (float)gameTime.ElapsedGameTime.TotalSeconds;
if (goblinAttackTimer >= goblinAttackDelay)
{
goblinAttackTimer -= goblinAttackDelay;
goodCastleHealth -= goblinDamage;
}
}
if (goblinList[i].goblinRect.Intersects(goblinList[i].goblinRect))
{
goblinList[i].Collided = true;
goblinList[i].AnimateStill(gameTime);
}
if (goblinList[i].Collided == false)
{
goblinList[i].AnimateWalk(gameTime);
goblinList[i].position.X -= goblinSpeed;
}
}
}

How to show more than one location in Blackberry MapField?

I can able to show one location using co ordinates or longtitude and latitude but i dont know how to show more than one location in the blackberry MapField.If is it possible pls share with me how to do this..
Same way as How to show our own icon in BlackBerry Map?.
Pass an array of Coordinates into custom MapField, define a bitmap for location point and paint it for each Coordinate in custom MapField paint() method.
Remember to zoom in/out CustomMapField for best fit of all location points.
Sample of implementation
Lets display Liverpool Sheffield and London with custom bitmap icons (yellow circle with black border). Code for custom MapField:
class MultyMapField extends MapField {
Coordinates[] mPoints = new Coordinates[0];
Bitmap mPoint;
Bitmap mPointsBitmap;
XYRect mDest;
XYRect[] mPointDest;
public void addCoordinates(Coordinates coordinates) {
Arrays.add(mPoints, coordinates);
zoomToFitPoints();
repaintPoints();
}
protected void zoomToFitPoints() {
// zoom to max
setZoom(getMaxZoom());
// get pixels of all points
int minLeft = getWidth();
int minUp = getHeight();
int maxRight = 0;
int maxDown = 0;
Coordinates minLeftCoordinates = null;
Coordinates minUpCoordinates = null;
Coordinates maxRightCoordinates = null;
Coordinates maxDownCoordinates = null;
for (int i = 0; i < mPoints.length; i++) {
XYPoint point = new XYPoint();
convertWorldToField(mPoints[i], point);
if (point.x <= minLeft) {
minLeft = point.x;
minLeftCoordinates = mPoints[i];
}
if (point.x >= maxRight) {
maxRight = point.x;
maxRightCoordinates = mPoints[i];
}
if (point.y <= minUp) {
minUp = point.y;
minUpCoordinates = mPoints[i];
}
if (point.y >= maxDown) {
maxDown = point.y;
maxDownCoordinates = mPoints[i];
}
}
double moveToLat = maxDownCoordinates.getLatitude()
+ (minUpCoordinates.getLatitude() - maxDownCoordinates
.getLatitude()) / 2;
double moveToLong = minLeftCoordinates.getLongitude()
+ (maxRightCoordinates.getLongitude() - minLeftCoordinates
.getLongitude()) / 2;
Coordinates moveTo = new Coordinates(moveToLat, moveToLong, 0);
moveTo(moveTo);
// zoom to min left up, max right down pixels + 1
int zoom = getZoom();
boolean outOfBounds = false;
while (!outOfBounds && zoom > getMinZoom()) {
zoom--;
setZoom(zoom);
XYPoint point = new XYPoint();
try {
convertWorldToField(minLeftCoordinates, point);
if (point.x < 0)
outOfBounds = true;
convertWorldToField(minUpCoordinates, point);
if (point.y < 0)
outOfBounds = true;
convertWorldToField(maxRightCoordinates, point);
if (point.x > getWidth())
outOfBounds = true;
convertWorldToField(maxDownCoordinates, point);
if (point.y > getHeight())
outOfBounds = true;
} catch (IllegalArgumentException ex) {
outOfBounds = true;
}
}
zoom++;
setZoom(zoom);
}
protected void repaintPoints() {
mPointsBitmap = new Bitmap(getWidth(), getHeight());
mPointsBitmap.createAlpha(Bitmap.ALPHA_BITDEPTH_8BPP);
mDest = new XYRect(0, 0, mPointsBitmap.getWidth(), mPointsBitmap
.getHeight());
Graphics g = new Graphics(mPointsBitmap);
if (null != mPoint) {
mPointDest = new XYRect[mPoints.length];
for (int i = 0; i < mPoints.length; i++) {
if (null == mPointDest[i]) {
XYPoint fieldOut = new XYPoint();
convertWorldToField(mPoints[i], fieldOut);
int imgW = mPoint.getWidth();
int imgH = mPoint.getHeight();
mPointDest[i] = new XYRect(fieldOut.x - imgW / 2,
fieldOut.y - imgH, imgW, imgH);
}
g.drawBitmap(mPointDest[i], mPoint, 0, 0);
}
}
}
protected void paint(Graphics graphics) {
super.paint(graphics);
if (null != mPointsBitmap) {
graphics.setGlobalAlpha(100);
graphics.drawBitmap(mDest, mPointsBitmap, 0, 0);
}
}
}
Sample of use:
class Scr extends MainScreen {
// test coordinates:
// London
// 51.507778, -0.128056
Coordinates mLondonC = new Coordinates(51.507778, -0.128056, 0);
// Liverpool
// 53.4, -2.983333
Coordinates mLiverpoolC = new Coordinates(53.4, -2.983333, 0);
// Sheffield
// 53.385833, -1.469444
Coordinates mSheffieldC = new Coordinates(53.385833, -1.469444, 0);
MultyMapField mMultyMapField;
public Scr() {
add(mMultyMapField = new MultyMapField());
mMultyMapField.mPoint = createPointBitmap();
}
protected void onUiEngineAttached(boolean attached) {
super.onUiEngineAttached(attached);
if (attached) {
mMultyMapField.addCoordinates(mLondonC);
mMultyMapField.addCoordinates(mLiverpoolC);
mMultyMapField.addCoordinates(mSheffieldC);
}
}
private Bitmap createPointBitmap() {
int r = 10;
Bitmap result = new Bitmap(2 * r, 2 * r);
result.createAlpha(Bitmap.ALPHA_BITDEPTH_8BPP);
Graphics g = new Graphics(result);
g.setColor(Color.BLACK);
g.fillEllipse(r, r, 2 * r, r, r, 2 * r, 0, 360);
g.setColor(Color.YELLOW);
g.fillEllipse(r, r, r + (r - 2), r, r, r + (r - 2), 0, 360);
return result;
}
}
A valid and probably simpler option would be to use this open source library by Monits https://github.com/Monits/blackberry-commons
It contains several common functionality found in BB applications and is compatible for BB 4.6.1+
Among other things, it provides a map field with the ability to add and display markers on top of it, with and without focus, and optionally "open" them. This makes for an API much more alike that found on other smart phones such as iPhone or Android.
The documentation is pretty good, and the wiki even has a tutorial on how to achieve it https://github.com/Monits/blackberry-commons/wiki/CustomMap

Resources