The popular game Words with Friends draws letter tiles at the game board as a single entity -
You can see a yellow linear gradient applied to all letter tiles in the following screenshot and also an emboss effect on the edge:
In my word game I would like to have similar effects:
So I create a game board sized mBitmap
, then draw all tiles into it and finally draw the bitmap into my custom view -
Setup:
setLayerType(View.LAYER_TYPE_SOFTWARE, null);
// create yellow linear gradient
mGradStart = new Point(3 * mWidth / 4, mHeight / 3);
mGradEnd = new Point(mWidth / 4, 2 * mHeight / 3);
LinearGradient gradient = new LinearGradient(
mGradStart.x,
mGradStart.y,
mGradEnd.x,
mGradEnd.y,
new int[]{ 0xCCFFCC00, 0xCCFFCC99, 0xCCFFCC00 },
null,
TileMode.CLAMP);
// create the big bitmap holding all tiles
mBitmap = Bitmap.createBitmap(mWidth, mHeight, Bitmap.Config.ARGB_8888);
mCanvas = new Canvas(mBitmap);
mPaintGrad = new Paint();
mPaintGrad.setShader(gradient);
mPaintEmboss = new Paint();
mPaintEmboss.setShader(gradient);
EmbossMaskFilter filter = new EmbossMaskFilter(
new float[] { 0f, 1f, 0.5f }, 0.8f, 3f, 3f);
mPaintEmboss.setMaskFilter(filter);
Drawing:
@Override
protected void onDraw(Canvas canvas) {
mGameBoard.draw(canvas);
// draw all tiles as rectangles into big bitmap
// (this code will move to onTouchEvent later)
mBitmap.eraseColor(Color.TRANSPARENT);
for (SmallTile tile: mTiles) {
mCanvas.drawRect(
tile.left,
tile.top,
tile.left + tile.width,
tile.top + tile.height,
mPaintGrad);
tile.draw(mCanvas);
}
canvas.drawBitmap(mBitmap, 0, 0, mPaintEmboss); // emboss NOT displayed
canvas.drawText("TEXT WORKS OK", 400, 400, mPaintEmboss); // ebmoss OK
canvas.drawRect(300, 600, 800, 1200, mPaintEmboss); // emboss OK
}
The EmbossMaskFilter
effect works OK with drawText()
and drawRect()
calls, but it does NOT work for the drawBitmap()
:
My question: is it possible to use some combinations of PorterDuff.Mode (and extractAlpha
?) to draw an emboss around my big bitmap?
UPDATE:
By looking at HolographicOutlineHelper.java I have been able to add an outer shadow:
with the following code in MyView.java -
Setup:
public MyView(Context context, AttributeSet attrs) {
super(context, attrs);
mScale = getResources().getDisplayMetrics().density;
mGradStart = new Point(3 * mWidth / 4, mHeight / 3);
mGradEnd = new Point(mWidth / 4, 2 * mHeight / 3);
LinearGradient gradient = new LinearGradient(
mGradStart.x,
mGradStart.y,
mGradEnd.x,
mGradEnd.y,
new int[]{ 0xCCFFCC00, 0xCCFFCC99, 0xCCFFCC00 },
null,
TileMode.CLAMP);
mBitmap = Bitmap.createBitmap(mWidth, mHeight, Bitmap.Config.ARGB_8888);
mCanvas = new Canvas(mBitmap);
mPaintGrad = new Paint(Paint.ANTI_ALIAS_FLAG | Paint.FILTER_BITMAP_FLAG);
mPaintGrad.setShader(gradient);
mPaintBlur = new Paint();
mPaintBlur.setColor(Color.BLACK);
BlurMaskFilter blurFilter = new BlurMaskFilter(mScale * 1, Blur.OUTER);
mPaintBlur.setMaskFilter(blurFilter);
}
Drawing:
private void prepareBitmaps() {
mBitmap.eraseColor(Color.TRANSPARENT);
for (SmallTile tile: mTiles) {
mCanvas.drawRect(
tile.left,
tile.top,
tile.left + tile.width,
tile.top + tile.height,
mPaintGrad);
tile.draw(mCanvas);
}
mAlphaBitmap = mBitmap.extractAlpha(mPaintBlur, mOffset);
}
@Override
protected void onDraw(Canvas canvas) {
mGameBoard.draw(canvas);
canvas.drawBitmap(mAlphaBitmap, mOffset[0], mOffset[1], mPaintBlur);
canvas.drawBitmap(mBitmap, 0, 0, mPaintGrad);
}
but unfortunately the app is acting slow now - and I still don't know how to add an emboss effect around the bitmap.
mScale=getResources().getDisplayMetrics().density;
– Boyt