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
Related
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?
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);
}
}
}
}
}
This program is about driving fast and dodging the obstacles. I followed a couple of tutorials and managed to create an explosion class. Whenever a collision occurs, the explosion is meant to appear, but it doesn't.
There is no error, but I think the problem is in the Game1.cs. I created the following functions in the Game1.cs:
//list
List <Explosion> explosionList = new List<Explosion>();
//This is in the update method
foreach (Explosion ex in explosionList)
{
ex.Update(gameTime);
}
//This is a method called manage explosions
public void ManageExplosions()
{
for (int i = 0; i < explosionList.Count; i++)
{
if (explosionList[i].isVisible)
{
explosionList.RemoveAt(i);
i--;
}
}
}
//This is placed in the CheckCollision method
explosionList.Add(new Explosion(Content.Load<Texture2D>("Images/explosion3"), new Vector2(theHazard.Position.X, theHazard.Position.Y)));
Game1.cs
using System;
using System.Collections.Generic;
using System.Linq;
using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Audio;
using Microsoft.Xna.Framework.Content;
using Microsoft.Xna.Framework.GamerServices;
using Microsoft.Xna.Framework.Graphics;
using Microsoft.Xna.Framework.Input;
using Microsoft.Xna.Framework.Media;
namespace DriveFast
{
public class Game1 : Microsoft.Xna.Framework.Game
{
GraphicsDeviceManager graphics;
SpriteBatch spriteBatch;
private Texture2D mCar;
private Texture2D mBackground;
private Texture2D mRoad;
private Texture2D mHazard;
private Texture2D hazardCrash;
private KeyboardState mPreviousKeyboardState;
private Vector2 mCarPosition = new Vector2(280, 440);
private int mMoveCarX = 160;
private int mVelocityY;
private double mNextHazardAppearsIn;
private int mCarsRemaining;
private int mHazardsPassed;
private int mIncreaseVelocity;
private double mExitCountDown = 10;
private int[] mRoadY = new int[2];
private List<Hazard> mHazards = new List<Hazard>();
private Random mRandom = new Random();
private SpriteFont mFont;
//video
List <Explosion> explosionList = new List<Explosion>();
private enum State
{
TitleScreen,
Running,
Crash,
GameOver,
Success
}
private State mCurrentState = State.TitleScreen;
public Game1()
{
graphics = new GraphicsDeviceManager(this);
Content.RootDirectory = "Content";
graphics.PreferredBackBufferHeight = 600;
graphics.PreferredBackBufferWidth = 800;
}
protected override void Initialize()
{
base.Initialize();
}
protected override void LoadContent()
{
// Create a new SpriteBatch, which can be used to draw textures.
spriteBatch = new SpriteBatch(GraphicsDevice);
mCar = Content.Load<Texture2D>("Images/Car");
mBackground = Content.Load<Texture2D>("Images/Background");
mRoad = Content.Load<Texture2D>("Images/Road");
mHazard = Content.Load<Texture2D>("Images/Hazard");
hazardCrash = Content.Load<Texture2D>("Images/hazardCrash");
mFont = Content.Load<SpriteFont>("MyFont");
}
protected override void UnloadContent()
{
}
protected void StartGame()
{
mRoadY[0] = 0;
mRoadY[1] = -1 * mRoad.Height;
mHazardsPassed = 0;
mCarsRemaining = 3;
mVelocityY = 3;
mNextHazardAppearsIn = 1.5;
mIncreaseVelocity = 5;
mHazards.Clear();
mCurrentState = State.Running;
}
protected override void Update(GameTime gameTime)
{
KeyboardState aCurrentKeyboardState = Keyboard.GetState();
//Allows the game to exit
if (GamePad.GetState(PlayerIndex.One).Buttons.Back == ButtonState.Pressed ||
aCurrentKeyboardState.IsKeyDown(Keys.Escape) == true)
{
this.Exit();
}
switch (mCurrentState)
{
case State.TitleScreen:
case State.Success:
case State.GameOver:
{
ExitCountdown(gameTime);
if (aCurrentKeyboardState.IsKeyDown(Keys.Space) == true && mPreviousKeyboardState.IsKeyDown(Keys.Space) == false)
{
StartGame();
}
break;
}
case State.Running:
{
//If the user has pressed the Spacebar, then make the car switch lanes
if (aCurrentKeyboardState.IsKeyDown(Keys.Space) == true && mPreviousKeyboardState.IsKeyDown(Keys.Space) == false)
{
mCarPosition.X += mMoveCarX;
mMoveCarX *= -1;
}
ScrollRoad();
foreach (Hazard aHazard in mHazards)
{
if (CheckCollision(aHazard) == true)
{
//video
explosionList.Add(new Explosion(Content.Load<Texture2D>("Images/explosion3"), new Vector2(aHazard.Position.X, aHazard.Position.Y)));
break;
}
MoveHazard(aHazard);
}
UpdateHazards(gameTime);
break;
}
case State.Crash:
{
//If the user has pressed the Space key, then resume driving
if (aCurrentKeyboardState.IsKeyDown(Keys.Space) == true && mPreviousKeyboardState.IsKeyDown(Keys.Space) == false)
{
mHazards.Clear();
mCurrentState = State.Running;
}
break;
}
}
mPreviousKeyboardState = aCurrentKeyboardState;
//video
ManageExplosions();
//
base.Update(gameTime);
//video
foreach (Explosion ex in explosionList)
{
ex.Update(gameTime);
}
}
private void ScrollRoad()
{
//Move the scrolling Road
for (int aIndex = 0; aIndex < mRoadY.Length; aIndex++)
{
if (mRoadY[aIndex] >= this.window.ClientBounds.Height)
{
int aLastRoadIndex = aIndex;
for (int aCounter = 0; aCounter < mRoadY.Length; aCounter++)
{
if (mRoadY[aCounter] < mRoadY[aLastRoadIndex])
{
aLastRoadIndex = aCounter;
}
}
mRoadY[aIndex] = mRoadY[aLastRoadIndex] - mRoad.Height;
}
}
for (int aIndex = 0; aIndex < mRoadY.Length; aIndex++)
{
mRoadY[aIndex] += mVelocityY;
}
}
private void MoveHazard(Hazard theHazard)
{
theHazard.Position.Y += mVelocityY;
if (theHazard.Position.Y > graphics.GraphicsDevice.Viewport.Height && theHazard.Visible == true)
{
theHazard.Visible = false;
mHazardsPassed += 1;
if (mHazardsPassed >= 100)
{
mCurrentState = State.Success;
mExitCountDown = 10;
}
mIncreaseVelocity -= 1;
if (mIncreaseVelocity < 0)
{
mIncreaseVelocity = 5;
mVelocityY += 1;
}
}
}
private void UpdateHazards(GameTime theGameTime)
{
mNextHazardAppearsIn -= theGameTime.ElapsedGameTime.TotalSeconds;
if (mNextHazardAppearsIn < 0)
{
int aLowerBound = 24 - (mVelocityY * 2);
int aUpperBound = 30 - (mVelocityY * 2);
if (mVelocityY > 10)
{
aLowerBound = 6;
aUpperBound = 8;
}
mNextHazardAppearsIn = (double)mRandom.Next(aLowerBound, aUpperBound) / 10;
AddHazard();
}
}
private void AddHazard()
{
int aRoadPosition = mRandom.Next(1, 3);
int aPosition = 275;
if (aRoadPosition == 2)
{
aPosition = 440;
}
bool aAddNewHazard = true;
foreach (Hazard aHazard in mHazards)
{
if (aHazard.Visible == false)
{
aAddNewHazard = false;
aHazard.Visible = true;
aHazard.Position = new Vector2(aPosition, -mHazard.Height);
break;
}
}
if (aAddNewHazard == true)
{
//Add a hazard to the left side of the Road
Hazard aHazard = new Hazard();
aHazard.Position = new Vector2(aPosition, -mHazard.Height);
mHazards.Add(aHazard);
}
}
private bool CheckCollision(Hazard theHazard)
{
BoundingBox aHazardBox = new BoundingBox(new Vector3(theHazard.Position.X, theHazard.Position.Y, 0), new Vector3(theHazard.Position.X + (mHazard.Width * .4f), theHazard.Position.Y + ((mHazard.Height - 50) * .4f), 0));
BoundingBox aCarBox = new BoundingBox(new Vector3(mCarPosition.X, mCarPosition.Y, 0), new Vector3(mCarPosition.X + (mCar.Width * .2f), mCarPosition.Y + (mCar.Height * .2f), 0));
if (aHazardBox.Intersects(aCarBox) == true)
{
//video
explosionList.Add(new Explosion(Content.Load<Texture2D>("Images/explosion3"), new Vector2(theHazard.Position.X, theHazard.Position.Y)));
mCurrentState = State.Crash;
mCarsRemaining -= 1;
if (mCarsRemaining < 0)
{
mCurrentState = State.GameOver;
mExitCountDown = 10;
}
return true;
}
return false;
}
private void ExitCountdown(GameTime theGameTime)
{
mExitCountDown -= theGameTime.ElapsedGameTime.TotalSeconds;
if (mExitCountDown < 0)
{
this.Exit();
}
}
protected override void Draw(GameTime gameTime)
{
graphics.GraphicsDevice.Clear(Color.CornflowerBlue);
spriteBatch.Begin();
spriteBatch.Draw(mBackground, new Rectangle(graphics.GraphicsDevice.Viewport.X, graphics.GraphicsDevice.Viewport.Y, graphics.GraphicsDevice.Viewport.Width, graphics.GraphicsDevice.Viewport.Height), Color.White);
foreach (Explosion ex in explosionList)
{
ex.Draw(spriteBatch);
}
switch (mCurrentState)
{
case State.TitleScreen:
{
//Draw the display text for the Title screen
DrawTextCentered("Drive and avoid the hazards!", 200);
DrawTextCentered("Press 'Space' to start", 260);
DrawTextCentered("Exit in " + ((int)mExitCountDown).ToString(), 475);
break;
}
default:
{
DrawRoad();
DrawHazards();
spriteBatch.Draw(mCar, mCarPosition, new Rectangle(0, 0, mCar.Width, mCar.Height), Color.White, 0, new Vector2(0, 0), 0.2f, SpriteEffects.None, 0);
spriteBatch.DrawString(mFont, "Cars:", new Vector2(28, 520), Color.Brown, 0, new Vector2(0, 0), 1.0f, SpriteEffects.None, 0);
for (int aCounter = 0; aCounter < mCarsRemaining; aCounter++)
{
spriteBatch.Draw(mCar, new Vector2(25 + (30 * aCounter), 550), new Rectangle(0, 0, mCar.Width, mCar.Height), Color.White, 0, new Vector2(0, 0), 0.05f, SpriteEffects.None, 0);
}
spriteBatch.DrawString(mFont, "Hazards: " + mHazardsPassed.ToString(), new Vector2(5, 25), Color.Brown, 0, new Vector2(0, 0), 1.0f, SpriteEffects.None, 0);
if (mCurrentState == State.Crash)
{
DrawTextDisplayArea();
DrawTextCentered("Crash!", 200);
DrawTextCentered("Press 'Space' to continue driving.", 260);
}
else if (mCurrentState == State.GameOver)
{
DrawTextDisplayArea();
DrawTextCentered("Game Over.", 200);
DrawTextCentered("Press 'Space' to re-try.", 260);
DrawTextCentered("Exit in " + ((int)mExitCountDown).ToString(), 400);
}
else if (mCurrentState == State.Success)
{
DrawTextDisplayArea();
DrawTextCentered("Well Done!", 200);
DrawTextCentered("Press 'Space' to play again.", 260);
DrawTextCentered("Exit in " + ((int)mExitCountDown).ToString(), 400);
}
break;
}
}
spriteBatch.End();
base.Draw(gameTime);
}
private void DrawRoad()
{
for (int aIndex = 0; aIndex < mRoadY.Length; aIndex++)
{
if (mRoadY[aIndex] > mRoad.Height * -1 && mRoadY[aIndex] <= this.window.ClientBounds.Height)
{
spriteBatch.Draw(mRoad, new Rectangle((int)((this.window.ClientBounds.Width - mRoad.Width) / 2 - 18), mRoadY[aIndex], mRoad.Width, mRoad.Height + 5), Color.White);
}
}
}
private void DrawHazards()
{
foreach (Hazard aHazard in mHazards)
{
if (aHazard.Visible == true)
{
spriteBatch.Draw(mHazard, aHazard.Position, new Rectangle(0, 0, mHazard.Width, mHazard.Height), Color.White, 0, new Vector2(0, 0), 0.4f, SpriteEffects.None, 0);
}
}
}
private void DrawTextDisplayArea()
{
int aPositionX = (int)((graphics.GraphicsDevice.Viewport.Width / 2) - (450 / 2));
spriteBatch.Draw(mBackground, new Rectangle(aPositionX, 75, 450, 400), Color.White);
}
private void DrawTextCentered(string theDisplayText, int thePositionY)
{
Vector2 aSize = mFont.MeasureString(theDisplayText);
int aPositionX = (int)((graphics.GraphicsDevice.Viewport.Width / 2) - (aSize.X / 2));
spriteBatch.DrawString(mFont, theDisplayText, new Vector2(aPositionX, thePositionY), Color.Beige, 0, new Vector2(0, 0), 1.0f, SpriteEffects.None, 0);
spriteBatch.DrawString(mFont, theDisplayText, new Vector2(aPositionX + 1, thePositionY + 1), Color.Brown, 0, new Vector2(0, 0), 1.0f, SpriteEffects.None, 0);
}
//video
//manage explosions
public void ManageExplosions()
{
for (int i = 0; i < explosionList.Count; i++)
{
if (explosionList[i].isVisible)
{
explosionList.RemoveAt(i);
i--;
}
}
}
}
}
Explosion.cs
using System;
using System.Collections.Generic;
using System.Linq;
using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Audio;
using Microsoft.Xna.Framework.Content;
using Microsoft.Xna.Framework.GamerServices;
using Microsoft.Xna.Framework.Graphics;
using Microsoft.Xna.Framework.Input;
using Microsoft.Xna.Framework.Media;
namespace DriveFast
{
public class Explosion
{
public Texture2D texture;
public Vector2 position;
public float timer;
public float interval;
public Vector2 origin;
public int currentFrame, spriteWidth, spriteHeight;
public Rectangle sourceRect;
public bool isVisible;
//Constructor
public Explosion(Texture2D newTexture, Vector2 newPosition)
{
position = newPosition;
texture = newTexture;
timer = 0;
interval = 20f;
currentFrame = 1;
spriteWidth = 128;
spriteHeight = 128;
isVisible = true;
}
//load content
public void LoadContent(ContentManager Content)
{
}
//update
public void Update(GameTime gameTime)
{
//increase
timer += (float)gameTime.ElapsedGameTime.TotalMilliseconds;
if (timer > interval)
{
currentFrame++;
timer = 0f;
}
if (currentFrame == 17)
{
isVisible = false;
currentFrame = 0;
}
sourceRect = new Rectangle(currentFrame * spriteWidth, 0, spriteWidth, spriteHeight);
origin = new Vector2(sourceRect.Width / 2, sourceRect.Height / 2);
}
//draw
public void Draw(SpriteBatch spriteBatch)
{
if (isVisible == true)
{
spriteBatch.Draw(texture, position, sourceRect, Color.White, 0f, origin, 1.0f, SpriteEffects.None, 0);
}
}
}
}
Hazard.cs
using System;
using System.Collections.Generic;
using System.Text;
using Microsoft.Xna.Framework;
namespace DriveFast
{
class Hazard
{
public Vector2 Position;
public bool Visible = true;
public Hazard()
{
}
}
}
First of all you need to draw your Explosions after road, car, hazards etc. Replace next code as shown below:
DrawRoad();
DrawHazards();
spriteBatch.Draw(mCar, mCarPosition, new Rectangle(0, 0, mCar.Width, mCar.Height), Color.White, 0, new Vector2(0, 0), 0.2f, SpriteEffects.None, 0);
// place code here
foreach (Explosion ex in explosionList)
{
ex.Draw(spriteBatch);
}
//
Into manage explosion method make !isVisible instead of isVisible:
public void ManageExplosions()
{
for (int i = 0; i < explosionList.Count; i++)
{
if (!explosionList[i].isVisible)
{
explosionList.RemoveAt(i);
i--;
}
}
}
Remove line:
foreach (Hazard aHazard in mHazards)
{
if (CheckCollision(aHazard) == true)
{
//remove next line because it is duplicate of adding Explosion which is already added inside CheckCollision(Hazard) method
//explosionList.Add(new Explosion(Content.Load<Texture2D>("Images/explosion3"), new Vector2(aHazard.Position.X, aHazard.Position.Y)));
break;
}
MoveHazard(aHazard);
}
Change next variables:
spriteWidth = 71;//128;
spriteHeight = 100;//128;
sourceRect = new Rectangle(currentFrame * spriteWidth, 0, spriteWidth, spriteHeight);
//origin = new Vector2(sourceRect.Width / 2, sourceRect.Height / 2);
origin = new Vector2(-(sourceRect.Width / 4), 0);
Comment next code for testing:
if (mCurrentState == State.Crash)
{
//DrawTextDisplayArea();
//DrawTextCentered("Crash!", 200);
//DrawTextCentered("Press 'Space' to continue driving.", 260);
}
I'm trying to draw a line from the player to a targets asteroid as a "Grapple" hook, i've found some examples for doing this in 2D in xna but my "Position" and "origin" vector2 seems to change depending on who and when they are used. In the case of the lines they appear to draw up and right of the position (roughly 100 pixels) in the opposite direction of the target and rotate about an origin somewhere to the left of the target as the player moves.
here is the player code including the grapple code and target assignment
namespace Sparatius.Sprites
{
public class PlayerSprite : BaseSprite
{
ControlInput controlInput;
Texture2D Grapple;
SpriteFont font;
bool LeftGrapple = false, RightGrapple = false;
int GrappleRange = 300;
Sprites.AsteroidSprite LeftTarget, RightTarget;
public BoundingSphere grappleHitBox
{
get { return new BoundingSphere(new Vector3(Position.X + Origin.X, Position.Y + Origin.Y, 0), GrappleRange); }
}
public float speed
{
get { return Speed; }
}
public PlayerSprite(Vector2 spriteLocal)
:base(spriteLocal)
{
this.Rotation = 0;
this.Speed = 0;
this.FrameCount = new Point(4, 2);
this.ColorTint = Color.White;
this.controlInput = new ControlInput();
}
public void LoadContent(ContentManager content)
{
Texture = content.Load<Texture2D>("Sprites/PinballSpin");
font = content.Load<SpriteFont>("Fonts/Font1");
Grapple = content.Load<Texture2D>("Sprites/Grapple");
FrameSize = new Point((int)Texture.Width / FrameCount.X, (int)Texture.Height / FrameCount.Y);
Origin = new Vector2(FrameSize.X / 2, FrameSize.Y / 2);
Animation = new Animation(Texture, FrameSize);
}
public override void Update(GameTime gameTime)
{
base.Update(gameTime);
controlInput.GetControlStates();
if (controlInput.JustPressed(Keys.W))
Speed += 2;
else if (controlInput.JustPressed(Keys.S))
Speed -= 2;
if (controlInput.IsHeld(Keys.A))
Rotation -= 0.05f;
if (controlInput.IsHeld(Keys.D))
Rotation += 0.05f;
if (LeftTarget != null)
{
LeftTarget.Distance = Vector2.Distance(Position, LeftTarget.Position);
if (LeftTarget.Distance > GrappleRange)
{
LeftTarget.isTarget = false;
LeftTarget = null;
}
if (controlInput.IsHeld(Keys.Q))
{
LeftGrapple = true;
}
else
LeftGrapple = false;
}
if (RightTarget != null)
{
RightTarget.Distance = Vector2.Distance(Position, RightTarget.Position);
if (RightTarget.Distance > GrappleRange)
{
RightTarget.isTarget = false;
RightTarget = null;
}
if (controlInput.IsHeld(Keys.E))
{
RightGrapple = true;
}
else
RightGrapple = false;
}
}
public override void Draw(SpriteBatch spriteBatch)
{
base.Draw(spriteBatch);
if (LeftGrapple)
{
float leftRotation = (float)Math.Atan2(LeftTarget.Position.Y - Position.Y, LeftTarget.Position.X - Position.X);
//spriteBatch.Draw(Texture, Position, null, ColorTint, leftRotation, Position, 1f, SpriteEffects.None, 0f);
spriteBatch.Draw(Grapple,
new Rectangle((int)Position.X, (int)Position.Y, 2, (int)LeftTarget.Distance),
null, Color.Blue, leftRotation, Position, SpriteEffects.None, 0f);
}
if (RightGrapple)
{
float rightRotation = (float)Math.Atan2(RightTarget.Position.Y - Position.Y, RightTarget.Position.X - Position.X);
//spriteBatch.Draw(Texture, Position, null, ColorTint, rightRotation, Position, 1f, SpriteEffects.None, 0f);
spriteBatch.Draw(Grapple,
new Rectangle((int)Position.X, (int)Position.Y, 2, (int)RightTarget.Distance),
null, Color.Blue, rightRotation, Position, SpriteEffects.None, 0f);
}
spriteBatch.DrawString(font, "Player Rotation: " + Rotation, Position, Color.Red);
spriteBatch.DrawString(font, "Player RoationDegree: " + (int)MathHelper.ToDegrees(Rotation), origin, Color.Blue);
}
public void GrappleCheck(AsteroidSprite target)
{
float targetTragectory = (float)Math.Atan2(Position.Y - target.Position.Y, Position.X - target.Position.X);
if ((targetTragectory < (rotation - (float)MathHelper.PiOver4)) && ((targetTragectory > (rotation - (float)MathHelper.Pi + (float)MathHelper.PiOver4))))
{
target.Distance = Vector2.Distance(Position, target.Position);
if (LeftTarget != null)
{
if (LeftTarget.Distance > target.Distance)
{
LeftTarget.isTarget = false;
LeftTarget = target;
LeftTarget.isTarget = true;
}
}
else
{
LeftTarget = target;
LeftTarget.isTarget = true;
}
}
if ((targetTragectory > (rotation + (float)MathHelper.PiOver4)) && ((targetTragectory < (rotation + (float)MathHelper.Pi - (float)MathHelper.PiOver4))))
{
target.Distance = Vector2.Distance(Position, target.Position);
if (RightTarget != null)
{
if (RightTarget.Distance > target.Distance)
{
RightTarget.isTarget = false;
RightTarget = target;
RightTarget.isTarget = true;
}
}
else
{
RightTarget = target;
RightTarget.isTarget = true;
}
}
}
}
}
any idea whats going wrong? cheers
public static void DrawLine(SpriteBatch spriteBatch, Vector2 begin, Vector2 end, Color color, int width = 1)
{
Rectangle r = new Rectangle((int)begin.X, (int)begin.Y, (int)(end - begin).Length()+width, width);
Vector2 v = Vector2.Normalize(begin - end);
float angle = (float)Math.Acos(Vector2.Dot(v, -Vector2.UnitX));
if (begin.Y > end.Y) angle = MathHelper.TwoPi - angle;
spriteBatch.Draw(Pixel, r, null, color, angle, Vector2.Zero, SpriteEffects.None, 0);
}
Pixel is just a 1x1 sprite
You can also use the this keyword to make a handy extension method.
I want to make an Analog Clock In blackberry, and I want the hands of the clock to be custom images.
I gone through this thread Help with analog clock code but didnt get it worked. Can any body help me to make an analog clock
Update
The code i am getting is from the supports forum
// How to use it
ClockBitmapField clock = new ClockBitmapField(face, Field.NON_FOCUSABLE | Field.FIELD_HCENTER,
hrPng, minPng, secPng);
I can i use this to make an analog clock
How Can i use this
add(clock);
// Clock Face
class ClockBitmapField extends BitmapField {
Bitmap _face = null;
UpdateClockThread _updateClockThread = null;
Bitmap [] _hourBitmaps = null;
Bitmap [] _minBitmaps = null;
Bitmap [] _secBitmaps = null;
public ClockBitmapField(Bitmap face, long style, String [] hourPngs, String [] minPngs, String [] secPngs) {
super(face, style);
_face = face;
_ourBitmap = new Bitmap(_face.getWidth(), _face.getHeight());
this.setBitmap(_ourBitmap); // Swap to using work area
_hourBitmaps = new Bitmap [hourPngs.length];
for ( int i = 0; i < hourPngs.length; i++ ) {
_hourBitmaps[i] = Bitmap.getBitmapResource(hourPngs[i]);
}
_minBitmaps = new Bitmap [minPngs.length];
for ( int i = 0; i < minPngs.length; i++ ) {
_minBitmaps[i] = Bitmap.getBitmapResource(minPngs[i]);
}
_secBitmaps = new Bitmap [secPngs.length];
for ( int i = 0; i < secPngs.length; i++ ) {
_secBitmaps[i] = Bitmap.getBitmapResource(secPngs[i]);
}
}
protected void onDisplay() {
onExposed();
}
protected void onUnDisplay() {
onObscured();
}
protected void onExposed() {
if ( _updateClockThread == null || !_updateClockThread.isAlive() ) {
_updateClockThread = new UpdateClockThread(_ourBitmap, _face, this, _hourBitmaps, _minBitmaps, _secBitmaps);
_updateClockThread.start();
}
}
protected void onObscured() {
if ( _updateClockThread != null ) {
_updateClockThread.stop();
_updateClockThread = null;
}
}
public void invalidate() {
super.invalidate();
}
class UpdateClockThread extends Thread {
private Calendar _cal = null;
int _curHr = 0;
int _curMin = 0;
int _curSec = 0;
Bitmap _face = null;
int _faceWidth = 0;
int _faceHeight = 0;
_ourBitmap = null;
Graphics _g = null;
ClockBitmapField _ourField = null;
long LONG_ONE_THOUSAND = 1000;
boolean _stopped = false;
Bitmap [] _hourBitmaps = null;
Bitmap [] _minBitmaps = null;
Bitmap [] _secBitmaps = null;
public UpdateClockThread(Bitmap ourBitmap, Bitmap face, ClockBitmapField fieldToInvalidate,
Bitmap [] hourBitmaps, Bitmap [] minBitmaps, Bitmap [] secBitmaps) {
super();
_cal = Calendar.getInstance();
_face = face;
_faceWidth = _face.getWidth();
_faceHeight = _face.getHeight();
_ourBitmap = ourBitmap;
_g = new Graphics(_ourBitmap);
_ourField = fieldToInvalidate;
}
public void run() {
long timeToSleep = 0;
while (!_stopped) {
_g.setBackgroundColor(0x00191919);
_g.clear();
_g.drawBitmap(0, 0, _faceWidth, _faceHeight, _face, 0, 0);
_cal.setTime(new Date(System.currentTimeMillis()));
_curHr = cal.get(Calendar.HOUR);
_curMin = cal.get(Calendar.MINUTE);
_curHr = (_curHr * 5) + (5 * _curMin / 60);
if (_curHr > 60) _curHr = _curHr - 60;
_curSec = cal.get(Calendar.SECOND);
_g.drawBitmap(0, 0, _faceWidth, _faceHeight, _secBitmaps[_curSec], 0, 0);
_g.drawBitmap(0, 0, _faceWidth, _faceHeight, _minBitmaps[_curMin], 0, 0);
_g.drawBitmap(0, 0, _faceWidth, _faceHeight, _hourBitmaps[_curHr], 0, 0);
_ourField.invalidate();
timeToSleep = LONG_ONE_THOUSAND - ( System.currentTimeMillis() % LONG_ONE_THOUSAND );
if ( timeToSleep > 20 ) {
try {
Thread.sleep(timeToSleep);
} catch (Exception e) {
}
}
}
}
public void stop() {
_stopped = true;
}
}
}
and make minutes as second
thanks and regards
Just by looking at the code, it appears that the inputs:
String [] hourPngs, String [] minPngs, String [] secPngs are each a list of filenames of images which represent the clock hands at each position.
In this snippet, he builds an array of 60 Bitmaps from the strings:
_secBitmaps = new Bitmap [secPngs.length];
for ( int i = 0; i < secPngs.length; i++ ) {
_secBitmaps[i] = Bitmap.getBitmapResource(secPngs[i]);
}
Then, in this snippet you can see he gets the Bitmap object from a array by passing in the current "second" as the index:
_g.drawBitmap(0, 0, _faceWidth, _faceHeight, _secBitmaps[_curSec], 0, 0);
There doesn't appear to be any code where he rotates the images or anything.
So I guess that means you need 60 images for each clock hand. (180 images in total, plus the clock face).