AndEngine visible rectangle - entity

I'm trying to create an additional visibility rectangle on a main Scene.
So I'v a main Camera 480x800 that is showing me a scene as it is and i'd like to attach an aditional entity or a scene that will have a rectangle of visibility.
So if I'll drag items inside it they will not dissapier in a single moment they will dissapier gradually.

As described in my previous comment you could stamp out a square alpha hole in your background Sprite. You could do this simply with an image editor, adding alpha pixels or you could do it dynamically as follows,
//set the background to white - so we can see our square alpha
//cut out later
mScene.setBackground(new ColorBackground(1.0f, 1.0f, 1.0f));
//Create and load bitmap texture atlas
BitmapTextureAtlas mBitmapBGTextureAtlas = new BitmapTextureAtlas(1024, 1024, TextureOptions.BILINEAR_PREMULTIPLYALPHA);
mActivity.getEngine().getTextureManager().loadTextures(mBitmapBGTextureAtlas);
//Get image in assets and decode into bitmap
InputStream ims;
try {
ims = mActivity.getAssets().open("gfx/my_backgound.jpg");
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
return;
}
Bitmap Bitmap_bg = BitmapFactory.decodeStream(ims);
//In my case the image is different than the height and width of the camera
//so store the ratio of size and height that the image will be resized to
float XScale = Bitmap_bg.getWidth()/mCamera.getWidth();
float YScale = Bitmap_bg.getHeight()/mCamera.getHeight();
//Cut out the alpha square, if our camera is 480x800, the square will appear
//at (40,200) and will be size 400x400
Bitmap_bg = cutSquareOutOfBitmap(Bitmap_bg, 40 * XScale, 200 * YScale, 400 * XScale , 400 * YScale);
//Get our edited bitmap into a region of the texture atlas
BitmapTextureAtlasSource source = new BitmapTextureAtlasSource(Bitmap_bg);
mBackground = BitmapTextureAtlasTextureRegionFactory.createFromSource(mBitmapBGTextureAtlas, source, 0, 0);
Bitmap_bg.recycle();
//Finally, create our background sprite with this new texture region
Sprite mBackgroundSprite = new Sprite(0, 0, mCamera.getWidth(), mCamera.getHeight(), mBackground);
mBackgroundSprite.setZIndex(1);
mScene.attachChild(mBackgroundSprite);
And the function cutSquareOutOfBitmap()
public static Bitmap cutSquareOutOfBitmap(Bitmap MyImage, float Xpos, float Ypos, float Width, float Height) {
Bitmap mBitmap = MyImage.copy(Bitmap.Config.ARGB_8888, true);
Paint mPaint = new Paint();
Canvas mCanvas = new Canvas(mBitmap );
mPaint = new Paint(Paint.ANTI_ALIAS_FLAG);
mPaint .setXfermode(new PorterDuffXfermode(Mode.SRC_OUT));
mPaint .setColor(Color.TRANSPARENT);
mCanvas.drawBitmap(mBitmap , 0, 0, null);
mCanvas.drawRect(Xpos, Ypos, Xpos + Width, Ypos + Height, mPaint );
return mBitmap ;
}
If you run this - not a lot to look at but a big white square, however, this is a transparent region, the square is actually the background we set earlier.
To demonstrate how the contents will be obscured, you could create a scrollable area, as mentioned in my previous comment I wrote a small container class you are welcome to use,
Custom ScrollView in andengine
Underneath the first code block in this answer, after,
mScene.attachChild(mBackgroundSprite);
You could now add,
//Now we can use the ShapeScrollContainer just as an example so the user can
//scroll our container shapes around
//Create it around the same area as the cut out
ShapeScrollContainer mShapeScrollContainer = new ShapeScrollContainer(40, 200, 400, 400, new IShapeScrollContainerTouchListener() {
#Override
public void OnContentClicked(Shape pShape) {
// TODO Auto-generated method stub
//Add code here for content click event
}
});
//Disable the ShapeScrollContainer ability to change the visibility
//of contents - we no longer require this as the background will
//cover them outside of the bounds of the ShapeScrollContainer itself
mShapeScrollContainer.SetContentVisiblitiyControl(false);
//Disable alpha
mShapeScrollContainer.SetAlphaVisiblitiyControl(false);
//Allow user to scroll both horizontally and vertically
mShapeScrollContainer.SetScrollableDirections(true, true);
//Don't allow the user to scroll to no where
mShapeScrollContainer.SetScrollLock(true);
//Allow use to scroll half the container over in either direction
mShapeScrollContainer.SetScrollLockPadding(50.0f,50.0f);
//Attach the container to the scene and register the event listener
mScene.registerTouchArea(mShapeScrollContainer);
mScene.attachChild(mShapeScrollContainer);
//Finally add some content to the container, what ever extends Shape,
//Sprite, Animated Sprite, Text, ChangeableText e.t.c.
Rectangle mRectangle = new Rectangle(200, 360, 80, 80);
mRectangle.setColor(0.0f, 1.0f, 0.0f);
mRectangle.setZIndex(0);
//Attach to the scene and the ShapeScrollContainer
mScene.attachChild(mRectangle);
mShapeScrollContainer.Add(mRectangle);
Rectangle mRectangle2 = new Rectangle(40, 360, 80, 80);
mRectangle2.setColor(0.0f, 0.0f, 1.0f);
mRectangle2.setZIndex(0);
mScene.attachChild(mRectangle2);
mShapeScrollContainer.Add(mRectangle2);
Rectangle mRectangle3 = new Rectangle(360, 360, 80, 80);
mRectangle3.setColor(1.0f, 1.0f, 0.0f);
mRectangle3.setZIndex(0);
mScene.attachChild(mRectangle3);
mShapeScrollContainer.Add(mRectangle3);
//And sort the order in which shapes are rendered
mScene.sortChildren();
Now you should get something like the following after scrolling,
As another alternative if you are going for a simpler background you could forgo the bitmap manipulation and simply make the square with four surrounding rectangles making up the sides to the edge of the screen.
Or you could physically split your background into 4 surrounding rectangles and a central square with an image editor. Then create 5 sprites, set the z order of the four rectangles to 2, the square to 0 and any content sprites to 1.
Hope this is of use.

Related

How does the viewport work in libgdx and how to set it up correctly?

I am learning the use of libgdx and I got confused by the viewport and how objects are arranged on the screen. Let's assume my 2D world is 2x2 units wide and high. Now I create a camera which viewport is 1x1. So I should see 25% of my world. Usually displays are not square shaped. So I would expect libgdx to squish and stretch this square to fit the display.
For a side scroller you would set the viewport height the same as the world height and adjust the viewport width according to the aspect ratio. Independent of the aspect ratio of your display you always see the full height of the world but different expansions on the x-axis. Somebody with a wider than high display could look further on the x-axis than somebody with a square shaped display. But proportions will be maintained and there is no distortion. So far I thought I mastered how the viewport logic works.
I am working with the book "Learning LibGDX Game Development" in which you develop the game "canyon bunny". The source code can be found here:
Canyon Bunny - GitHub
In the WorldRenderer Class you find the initilization of the camera:
private void init() {
batch = new SpriteBatch();
camera = new OrthographicCamera(Constants.VIEWPORT_WIDTH, Constants.VIEWPORT_HEIGHT);
camera.position.set(0, 0, 0);
camera.update();
}
The viewport constants are saved in a separate Constants-Class:
public class Constants {
// Visible game world is 5 meters wide
public static final float VIEWPORT_WIDTH = 5.0f;
// Visible game world is 5 meters tall
public static final float VIEWPORT_HEIGHT = 5.0f;
}
As you can see the viewport is 5x5. But the game objects have the right proportion on my phone (16:9) and even on a desktop when you change the windows size the game maintains the correct proportions. I don't understand why. I would expect that the game tries to paint a square shaped cutout of the world onto a rectangle shaped display which would lead to distortion. Why is that not the case? And why don't you need the adaption of width or height of the viewport to the aspect ratio?
The line:
cameraGUI.setToOrtho(true);
Overrides the values you gave when you called:
cameraGUI = new OrthographicCamera(Constants.VIEWPORT_GUI_WIDTH, Constants.VIEWPORT_GUI_HEIGHT);
Here's the LibGDX code that shows why/how the viewport sizes you set were ignored:
/** Sets this camera to an orthographic projection using a viewport fitting the screen resolution, centered at
* (Gdx.graphics.getWidth()/2, Gdx.graphics.getHeight()/2), with the y-axis pointing up or down.
* #param yDown whether y should be pointing down */
public void setToOrtho (boolean yDown) {
setToOrtho(yDown, Gdx.graphics.getWidth(), Gdx.graphics.getHeight());
}
/** Sets this camera to an orthographic projection, centered at (viewportWidth/2, viewportHeight/2), with the y-axis pointing up
* or down.
* #param yDown whether y should be pointing down.
* #param viewportWidth
* #param viewportHeight */
public void setToOrtho (boolean yDown, float viewportWidth, float viewportHeight) {
if (yDown) {
up.set(0, -1, 0);
direction.set(0, 0, 1);
} else {
up.set(0, 1, 0);
direction.set(0, 0, -1);
}
position.set(zoom * viewportWidth / 2.0f, zoom * viewportHeight / 2.0f, 0);
this.viewportWidth = viewportWidth;
this.viewportHeight = viewportHeight;
update();
}
So you would need to do this instead:
cameraGUI.setToOrtho(true, Constants.VIEWPORT_GUI_WIDTH, Constants.VIEWPORT_GUI_HEIGHT);
Also don't forget to call update() right after wherever you change the position or viewport dimensions of your camera (Or other properties)
I found the reason. If you take a look on the worldRenderer class there is a method resize(). In this method the viewport is adapted to the aspect ratio. I am just wondering because until now I thought the resize method is only called when resizing the window. Apparently it's also called at start up. Can anybody clarify?

UWP MapControl issue anchoring xaml children

I'm new to UWP MapControl currently. I have a simple problem when adding XAML children to map (instead of the regular map elements).
this is my code:
private void MapRightTapped(MapControl sender, MapRightTappedEventArgs args)
{
Ellipse circle = new Ellipse() { Height = 20, Width = 20, Fill = new SolidColorBrush(Colors.Black)};
sender.Children.Add(circle);
Geopoint position = new Geopoint(new BasicGeoposition()
{
Latitude = args.Location.Position.Latitude,
Longitude = args.Location.Position.Longitude,
Altitude = 5000,
});
MapControl.SetLocation(circle, position);
MapControl.SetNormalizedAnchorPoint(circle, new Point(0.5, 0.5));
}
At first the point displayed correctly on the map.
but after zooming or tilting the map,
the circle appeared to be anchored at the surface altitude and NOT at altitude of 5000
You need to set an altitude reference system. Leaving it set to the default of unspecified will cause the altitude value to be ignored.

EaselJS line draw with unnecessary multiple dots issues

While drawing a line on canvas, it creates multiple dots within the line. I am using easelJS for canvas drawing. Please refer the attached screenshot.
Code for line draw is as below.
Line with multiple dots
scope.init = function(){
stage = new createjs.Stage(element[0].id);
stage.enableDOMEvents(true);
createjs.Touch.enable(stage);
shellWrapper = new createjs.Container();
shellWrapper.id = mainContainerId;
shellWrapper.hitArea = new createjs.Shape(new createjs.Graphics().f('#000').dr(0,0,cacheWidth,cacheHeight));
shellWrapper.cache(0,0,cacheWidth,cacheHeight); // Cache it.
stage.addChild(shellWrapper);
drawing = new createjs.Shape();
shellWrapper.addChild(drawing);
stage.update();
}
scope.mouseDown = function(event) {
oldX = event.stageX;
oldY = event.stageY;
shellWrapper.addEventListener('pressmove', function(evt){
drawing.graphics.beginStroke(color)
.setStrokeStyle(size, 'round')
.moveTo(oldX, oldY)
.lineTo(evt.stageX, evt.stageY);
oldX = evt.stageX;
oldY = evt.stageY;
shellWrapper.updateCache(erase?'destination-out':'source-over');
drawing.graphics.clear();
stage.update();
});
};
This happens because a single line has its limits rounded, so it actually look like this:
The rounded edge goes a little bit (depending on stroke width) out of the line boundary so it gets over the past line drawn. This line overlay causes your drawing to look like it has small circles, but it does not, and thats because you're using a semi transparent color on the stroke.
To solve the issue, make the stroke color opaque and add transparency to the whole drawing by using myDisplayObj.alpha = 0.5;
This way individual lines will be fully opaque in relation to each other but they will be semi transparent relative to other display objects in the scene.

libgdx generate texture at runtime

Hi i need to create a texture that is made up of other textures overlayed. I've tried using pixmap however it is noticably slow. The idea is to create a "snapshot" of a dialog so that it can be animated as it shows up and when it is dismissed. Please help
This is the code that I am using:
texture_dialog.getTextureData().prepare();
Pixmap pm1 = texture_dialog.getTextureData().consumePixmap();
btn_ok.getTexture().getTextureData().prepare();
Pixmap pm = btn_ok.getTexture().getTextureData().consumePixmap();
pm1.drawPixmap(pm, pm1.getWidth()/2 - pm.getWidth()/2, pm1.getHeight() - pm.getHeight() - 52);
textureSnapShot = new Texture(pm1, true);
pm1.dispose();
pm.dispose();
textureSnapShot.setFilter(TextureFilter.MipMapLinearLinear, TextureFilter.MipMapLinearLinear);
spriteSnapShot = new Sprite(textureSnapShot);
I've tried using a FrameBuffer as follows:
SpriteBatch sb = new SpriteBatch();
sb.setProjectionMatrix(camera.combined);
FrameBuffer fbo = new FrameBuffer(Format.RGBA8888, texture_dialog.getWidth(), texture_dialog.getHeight(), false);
fbo.begin();
sb.begin();
sb.draw(texture_dialog, 0, 0);
sb.draw(btn_ok.getTexture(), texture_dialog.getWidth()/2 - btn_ok.getWidth()/2, 52);
sb.end();
fbo.end();
sb.dispose();
textureSnapShot = fbo.getColorBufferTexture();
//textureSnapShot.setFilter(TextureFilter.MipMapLinearLinear, TextureFilter.MipMapLinearLinear);
spriteSnapShot = new Sprite(textureSnapShot);
The results are as follows:
http://medialinestudio.co.za/screens.png
Left: Pixmap Right: FrameBuffer
Pixmap has the correct result but too slow. FrameBuffer is faster but incorrect result
FBO is definitely what you should use for your need.
read this post : libgdx SpriteBatch render to texture
what you missing is :
create a camera with correct width/height and position to fit your drawing inside the FBO viewport (0,0,Width,Height)
flip the output texture (m_fboRegion.flip(false, true))

Drawing control with transparent background

I've been trying to display an image which has a transparent border as the background to a control.
Unfortunately, the transparent area creates a hole in the parent form as follows:
In the above image, the form has a red background which I'd hoped to see behind my control in the transparent areas.
The code I used is as follows:
protected override void OnPaint(System.Windows.Forms.PaintEventArgs e)
{
if (this.Image != null)
{
Graphics g = Graphics.FromImage(this.Image);
ImageAttributes attr = new ImageAttributes();
//set the transparency based on the top left pixel
attr.SetColorKey((this.Image as Bitmap).GetPixel(0, 0), (this.Image as Bitmap).GetPixel(0, 0));
//draw the image using the image attributes.
Rectangle dstRect = new Rectangle(0, 0, this.Image.Width, this.Image.Height);
e.Graphics.DrawImage(this.Image, dstRect, 0, 0, this.Image.Width, this.Image.Height,
GraphicsUnit.Pixel, attr);
}
else
{
base.OnPaint(e);
}
}
protected override void OnPaintBackground(System.Windows.Forms.PaintEventArgs e)
{
//base.OnPaintBackground(e);
}
This class is inherited from a PictureBox because I needed a control which implements OnMouseMove and OnMouseUp Events.
I've been researching most of the day without success testing out different ideas but unfortunately most only work on the full framework and not .Net CF.
Any ideas would be much appreciated.
Ah the joys of CF transparency. I could go on and on about it (and have in my blog and the Project Resistance code I did ages ago).
The gist is this. The child control has to paint it's areas, but first it has to call back up to it's parent (the Form in your case) and tell it to redraw it's background image everywhere except in the child's clipping region and then draw itself on top of that. If that sounds a bit confusing it's because it is.
For example, if you look at Project Resistance, a View (which is just a Control) draws a resistor and bands. It lies in a Form that has an image background, and that background needs to "show through" the transparent areas of the resistor:
So in the drawing code of the resistor it does this:
protected override void OnPaint(PaintEventArgs e)
{
base.OnPaint(e);
try
{
RECT rect = new RECT(this.Bounds);
// draw the blank
Infrastructure.GraphicTools.DrawTransparentBitmap(e.Graphics, m_blankImage, Bounds,
new Rectangle(0, 0, m_blankImage.Width, m_blankImage.Height));
if (m_bandsImage != null)
{
// draw the bands
Infrastructure.GraphicTools.DrawTransparentBitmap(e.Graphics, m_bandsImage, Bounds,
new Rectangle(0, 0, m_bandsImage.Width, m_bandsImage.Height));
}
}
finally
{
}
if (!Controller.TouchMode)
{
// TODO: draw in the selection arrow
// Controller.SelectedBand
}
}
Which is simple enough. The key is that it calls to it's base OnPaint, which does this:
protected override void OnPaint(System.Windows.Forms.PaintEventArgs e)
{
// this assumes we're in a workspace, on MainForm (the whole Parent.Parent thing)
IBackgroundPaintProvider bgPaintProvider = Parent.Parent as IBackgroundPaintProvider;
if (bgPaintProvider != null)
{
Rectangle rcPaint = e.ClipRectangle;
// use the parent, since it's the workspace position in the Form we want,
// not our position in the workspace
rcPaint.Offset(Parent.Left, Parent.Top);
bgPaintProvider.PaintBackground(e.Graphics, e.ClipRectangle, rcPaint);
}
}
You can see it's calling PaintBackground of the containing Form (it's Parent.Parent in this case becuse the Control is actually in a container called a Workspace - you wouldn't need to walk up twice in your case). That draws in the background image in the area you're currently seeing as the "hole"
public void PaintBackground(Graphics g, Rectangle targetRect, Rectangle sourceRect)
{
g.DrawImage(m_bmBuffer, targetRect, sourceRect, GraphicsUnit.Pixel);
}