I would like to get the Bitmap of the content of a webpage as it is displayed in the BrowserField. Therefore I'd need the Graphic-object of the browser field. But the paint-method is protected unfortunately.
Is there a way to get this?
Thank's
Normally, if you want to do some custom drawing with a field ie. draw into the field's graphics context, you'd subclass Field and override the paint method. However, when it comes to BrowserField, you can't do that because it's declared final.
There is a workaround for this, though. You can subclass a Manager and add your BrowserField to an instance of that manager. So, for example, if you want to add your BrowserField instance to a VerticalFieldManager, you can use the following code to get access to the Graphics object the browser will be drawn into. In this sample code, you'll see that I use the graphics object and manager's superclass implementation to draw into a bitmap. Then, that bitmap is drawn to the screen.
VerticalFieldManager vfm = new VerticalFieldManager() {
// Override to gain access to Field's drawing surface
//
protected void paint(Graphics graphics) {
// Create a bitmap to draw into
//
Bitmap b = new Bitmap(vfm.getVirtualWidth(), vfm.getVirtualHeight());
// Create a graphics context to draw into the bitmap
//
Graphics g = Graphics.create(b);
// Give this graphics context to the superclass implementation
// so it will draw into the bitmap instead of the screen
//
super.paint(g);
// Now, draw the bitmap
//
graphics.drawBitmap(0,
0,
vfm.getVirtualWidth(),
vfm.getVirtualHeight(),
b,
0,
0);
}
};
And, there you have a Bitmap containing the contents of the manager. Should note, though, that this has the potential to consume a lot of memory.
Related
In my first LibGdx Project,I want to draw some rectangles.
I am not looking for shape rendering purpose.I am aiming to implement a function like what fillRect() in j2me do.I have to draw filled rectangles and need to manipulate it(changing size,rotating.. etc).
When I google about it, always getting shapeRenderer related things only.
Please mention how can I draw and manipulate my own images.
Draw Rectangle by using Pixmap.
Texture texture=getPixmapTexture(Color.WHITE);
Sprite sprite=new Sprite(texture); //Used for drawing 2D sprites.
//or
Image image=new Image(texture); //2D scene graph node.
public static Texture getPixmapTexture(Color color){
return new Texture(PixmapBuilder.getPixmapRectangle(1, 1, color));
}
public static Pixmap getPixmapRectangle(int width, int height, Color color){
Pixmap pixmap=new Pixmap(width, height, Pixmap.Format.RGBA8888);
pixmap.setColor(color);
pixmap.fillRectangle(0,0, pixmap.getWidth(), pixmap.getHeight());
return pixmap;
}
The answer by Abhishek is correct.
However, if you have just started game developement with LibGDX, I would check whether you need at all to perform such operation (draw a rectangle).
In libGDX you can use Scene2D which allow you to create a Stage, Actors and direct them on your stage.
So instead of drawing a rectangle, you create an actor, such as an image, to which you can associate a texture, a button or a TextBox and place it on your screen.
Scene2D allows you to then use things like Action or rotation, scaling..
There are some good visual demos about that on Libgdx.info
I am mentioning this because moving to Scene2D later may be more complicated than if you make that decision early on.
I am making an 2d rpg game with box2d. So, I've got a problem. When one of my bodies(the character) collides with another(a door) the map needs to change, should I just create new screens for maps and change them? Or is there a more simple solution?
You can change your current map on the same screen only. What you have to do is, Let's say your map variable name is testMap. Now let's say your player just collided with a door. Now let's say you will call a method called changeMap(). Here is what you will put inside changeMap() method. (Assuming you are using tiled maps, you can change logic accordingly here)
void changeMap() {
Gdx.app.postRunnable(() -> { //Post runnable posts the below task in opengl thread
testMap = new TmxMapLoader().load("someMap.tmx"); //load the new map
renderer.getMap().dispose(); //dispose the old map
renderer.setMap(testMap); //set the map in your renderer
});
}
I'm just getting started with Flash/ActionScript and it seems to be the general consensus to create Sprites, Bitmaps, MovieClips, etc for various objects in order to represent pictures and other graphics.
However, the way I'm used to writing games and whatnot in other languages is to just loop repeatedly and each frame use something similar to the Graphics object to redraw the scene on the main Sprite. Is this how it's also done in Flash, and is it good practice? I can do it this way, but I'm wondering if there's some Flash ecosystem standard instead.
Here's an example of the way I'm used to:
public class MyApp extends Sprite
{
public function MyApp()
{
var t:Timer = new Timer(20);
t.addEventListener(TimerEvent.TIMER, update);
t.start();
}
public function update(e:TimerEvent)
{
this.graphics.clear();
//Rendering code and updating of objects.
}
}
Is this acceptable?
Well, it depends.
In Flash, you have the option of relying on the Flash Player's vector rasterizer and rendering system, which will figure out all the redrawing for you. For instance, you can draw once to a Sprite then simply apply transforms to the sprite (set x, y, width, height, rotation, scaleX, scaleY, transform.matrix, transform.colorTransform, etc). Any of these objects could be a vector shape or a bitmap, and you can also use cacheAsBitmap and cacheAsBitmapMatrix for even more redraw optimization. The Flash Player will only redraw areas that change, on the frame that they change. I would consider this the traditional "Flash way".
Using the Graphics API is just a programmatic way to create vector shape data. Think of it as a code alternative to drawing in the Flash IDE. You could draw using Graphics once when the object is created, or if you needed to change the actual shape (ie not just the transform) you are correct that you would clear() and redraw it. However, ideally you would not be doing that a lot. If you find yourself redrawing the shape a lot, you might want to move to a pre-rendered sprite-sheet approach. In that case you use BitmapData to more quickly copy pre-drawn pixel data to a Bitmap object. This is generally faster than relying on the vector rasterizer to render your Graphics commands, as long as you use the fast pixel methods like copyPixels(). This is probably closer to the sort of rendering systems you are used to in other platforms that don't have a vector rasterizer built in.
Lastly, it's worth noting that the newest (and fastest) way to render objects in Flash is completely different than all that. It's called Stage3D and it uses a completely different rendering pipeline than the vector rasterizer. It's powered by GPU rendering APIs, so it's blazing fast (great for games) but has no vector rasterizing abilities. It can be used for both 3D and 2D. It's a bit more involved to work with, but there are some useful frameworks to make it easier, most notably the Starling 2D framework.
Hope that helps.
The "Flash way" is to use EnterFrame event instead of using timer to draw. You must make your calculation whenever you want but let flash draw you scene.
It works the same way in actionscript.
public class App extends Sprite // adding "my" to identifier names doesn't add any information, so there's no real point in doing it
{
public function App()
{
addEventListener(Event.ENTER_FRAME, update); // "each frame"
}
private function update(e:Event):void //not just parameters of functions have a type, but also their return value
{
graphics.clear(); // no need for "this" here
//Rendering code and updating of objects.
}
}
Keep in mind that the Graphics API is vector based and as such will only draw so many things before dropping performance.
Sprite is a general purpose container, not to be confused with what the term "sprite" stands for in a sprite sheet.
What you are probably referring to when saying "main Sprite" is some rectangular region of pixels that you can manipulate.In this case, a BitmapData is what you want, which is displayed with a Bitmap object.
BitmapData does not offer a graphics property. Essentially, drawing vectors and manipulating pixels are treated separately in As3. If you want to draw a line in a BitmapData object, you'd have to first draw the line as a vector into a Sprite (or better Shape, if all you want to do is draw on it) using its graphics property, then use draw() of BitmapData to set its pixels according to the drawn line.
As of right now. I have 3 objects. One BitMap that acts as my canvas. And 2 bitmapDatas. One is my buffer and another is my tiles. I am creating a tiling effect for a game. I would like to take my tile:BitMapData, and turn it into a custom object. reason being is I want each tile to be interactive. So I can click on each one. Is it possible to turn my bitMapData that represents a tile, into a custom object that has properties and methods. Sort of like a movie clip. and draw it into my buffer ?? Could I create a new class that extends bitMapData ?? Or would I have to get rid of the buffer and draw the tile objects directly into the BitMap ??
In other words, what is the best way to put Sprite or a tile into a BitMapData object or even a Bitmap.
First of all, BitmapData and Bitmap are not interchangeable. They are two very different things. The BitmapData class contains bitmap pixel data, and allows you to manipulate that pixel data, e.g. draw to it, change the color of particular pixels, et c. There is no way of displaying a BitmapData directly, i.e. by adding it to the display list.
The Bitmap class, on the other hand, is a DisplayObject, like MovieClips and Sprites, which you can add to the display list. It's single purpose is to render a BitmapData in the display list. In fact, it is not even interactive, so you cannot detect clicks directly on a Bitmap instance, for example.
On to your question: If you have a bitmap data that contains a tile sprite, and you want to draw that tile in another bitmapdata, you can use the BitmapData.draw() method, or the BitmapData.copyPixels() method. The latter is one of the fastest methods you can use on any BitmapData, so I would highly recommend it.
Depending on your particular application, it might not be beneficial to draw everything in a bitmap at all. It sounds as if you want to be able to detect click events on all the tiles, which makes me think that you would probably benefit from having them be separate DisplayObjects, e.g. Sprites.
If you want to, you can create a Tile class that extends Sprite, and draws a BitmapData using a bitmap fill. That way, you can have any properties you want, and also detect mouse events on the tile instances.
package
{
/* ... imports ... */
public class Tile extends Sprite
{
private var _solid : Boolean;
public function Tile(bmp : BitmapData, solid : Boolean)
{
this.graphics.beginBitmapFill(bmp, null, false, true);
this.graphics.drawRect(0, 0, bmp.width, bmp.height);
_solid = solid;
}
/**
* Sample custom property. Could be used to define whether a tile
* is solid, e.g. the player cannot pass it.
*/
public function get isSolid() : Boolean
{
return _solid;
}
}
}
This class could simply be instantiated for every tile in your game, passing in the bitmap data that should be drawn in the tile. You could also listen for events on such a tile instance.
var tile : Tile;
tile = new Tile(myBitmapData, false);
tile.x = 200;
tile.y = 200;
tile.addEventListener(MouseEvent.CLICK, handleTileClick);
addChild(tile);
This way, you don't have to use the Bitmap class at all to render the tiles. They can be added directly to the display list.
I figure a better solution for when you want to select certain parts of the tile without effecting the position of the sprite itself
theMatrix.translate(30,0);
this.graphics.beginBitmapFill(tileImage,theMatrix);
//this.graphics.drawRect(0, 0,tWidth ,tHeight );
this.graphics.endFill();
Your right, leave drawRect at 0, 0. using Matrix.Translate, allows you to move the positioning of what part of the tile you want, without affecting the sprite position itself.
We have Bitmap and Bitmapdata objects now. And when using the webcam, we can get raw-pixeldata output from it. But, can we get raw-pixeldata from the "stage" or "swf" object somehow?
I would like to use this to make "small thumbnails" of certain parts of Actionscript applications and these could be complex compositions of dynamic text, bitmap graphics and movieclips at the same time. So it would be nice to make a "quick snap" and just get the current combined pixels into one bitmap and then be able to "save that for later use".
Is that possible? is it too easy? am I just looking the wrong place in the Adobe Docs?
We have images, vectors etc at the same time on stage, so I need to grab the "stage" objects bitmapdata???
Create a BitmapData and call its draw() method with the corresponding DisplayObject
var bmpData:BitmapData = new BitmapData(sprite.width, sprite.height, true);
bmpData.draw(sprite);
If you want to make thumbnails smaller, create a Matrix and call its createBox method with required scaling parameters and pass it to the draw method.
var bmpData:BitmapData = new BitmapData(thumbW, thumbH, true);
var mat:Matrix = new Matrix();
mat.createBox(thumbW / sprite.width, thumbH / sprite.height);
bmpData.draw(sprite, mat);