0

It's a bit hard to explain my problem so i'll show it with few pictures. I made this bitmap :

and I wanted to draw a circle of light inside it, using this code:

 Rect bounds1 = new Rect(x, y, x+bit.getWidth(), y+bit.getHeight());
        for (int i = bounds1.left; i < bounds1.right; i++) {
            for (int j = bounds1.top; j < bounds1.bottom; j++) {
                int result=(int) Math.sqrt((x2-i)*(x2-i)+(y2-j)*(y2-j));
                if(result<=120){
                      int pixel = (bit.getPixel(i-x,j-y));

                      int a,r, g, b;

                      int different=result/10;
                      //change the value of each component
                      a=Color.alpha(pixel);

                      r = Color.red(pixel) + rn;
                      g = Color.green(pixel) + gn;
                      b = Color.blue(pixel) + bn;

                      //r,g,b values which are out of the range 0 to 255 should set to 0 or 255
                      if (r >= 256) {
                          r = 255;
                      } else if (r < 0) {
                          r = 0;
                      }

                      if (g >= 256) {
                          g = 255;
                      } else if (g < 0) {
                          g = 0;
                      }

                      if (b >= 256) {
                          b = 255;
                      } else if (b < 0) {
                          b = 0;
                      }

                    bit.setPixel(i-x, j-y, Color.argb(a,r, g, b));
                }
            }

I managed to create this:

Now, I'm trying to make the light ball be smoother and not so rough so it wont look like a circle, anyone has any idea how can I do that? I tried many things but nothing worked out.

whole code of drawing:

public class CreatorView extends View

{

Context c;


boolean quickfix=false;
boolean bin_isEmpty=true;
boolean iftrue=false;
boolean stopnow=false;
boolean buttonpressed=false;
String arrowcheck="";
int screenw;
int screenh;
int pixelx;
int pixely;
int smallpixelx;
int smallpixely;
Point arrowsp;
Paint paintblock;
int currentColor=0;
int x2=120;
int y2=120;

int rn=60;
int gn=45;
int bn=30;

 Bitmap tileBitmap;
 Bitmap lightBitmap;
 RectF lightRect;
 Paint paint0 = new Paint(Paint.ANTI_ALIAS_FLAG);
 Paint paint1 = new Paint(Paint.ANTI_ALIAS_FLAG);   

Bitmap mountaintop;
Bitmap mountainbottom;


Bitmap grass;
Bitmap dirt;
Bitmap dirt2;
Bitmap dirt3;
Bitmap stonegrass;
Bitmap stone;
Bitmap stone2;
Bitmap stone3;
Bitmap stone4;
Bitmap cloud;
Bitmap bin_Empty;
Bitmap bin_Full;
Bitmap arrowno;
Bitmap arrown;
Bitmap arrowl;
Bitmap arrowr;
Bitmap arrowu;
Bitmap arrowd;
Bitmap arrowul;
Bitmap arrowur;
Bitmap save;
Bitmap fliph;
Bitmap flipv;
Bitmap Rotatef;
Bitmap Rotateb;
Bitmap arrowdl;
Bitmap arrowdr;
Bitmap grassSide;
Bitmap grassTop;
Bitmap orange;
Bitmap blue;
Bitmap smallpixel;
Bitmap PixelDetect;
Bitmap colorpick;
Bitmap brush;
Bitmap brushcolor;
Bitmap torch;

Map.Entry<CreatorBlock,Point>currentBlock;
Map.Entry<CreatorBlock,Point>lastBlock;
Map<CreatorBlock, Point> grassblock = new HashMap<CreatorBlock, Point>();
Map<CreatorBlock, Point> stonegrassblock = new HashMap<CreatorBlock, Point>();
Map<CreatorBlock, Point> dirtblock = new HashMap<CreatorBlock, Point>();
Map<CreatorBlock, Point> stoneblock = new HashMap<CreatorBlock, Point>();
Map<CreatorBlock, Point> grassSideBlock = new HashMap<CreatorBlock, Point>();
Map<CreatorBlock, Point> grassTopBlock = new HashMap<CreatorBlock, Point>();
Map<CreatorBlock, Point> orangeBlock = new HashMap<CreatorBlock, Point>();
Map<CreatorBlock, Point> blueBlock = new HashMap<CreatorBlock, Point>();

Map<BackBlock, Point> mountaintopBack = new HashMap<BackBlock, Point>();
Map<BackBlock, Point> mountainbottomBack = new HashMap<BackBlock, Point>();

Map<BackBlock, Point> torchBack = new HashMap<BackBlock, Point>();

Map<CreatorBlock, Point> levelMap = new HashMap<CreatorBlock, Point>();
List<MenuButton>menuButtonList=new ArrayList<MenuButton>();


public CreatorView(Context c) {
    super(c);
    this.c=c;


    WindowManager wm = (WindowManager) c.getSystemService(Context.WINDOW_SERVICE);
    Display display = wm.getDefaultDisplay();
    this.screenw= display.getWidth();
    this.screenh=display.getHeight();

    this.PixelDetect   = BitmapFactory.decodeResource(   getResources(),   R.drawable.custom_pixel);
    this.smallpixel   = Bitmap.createScaledBitmap(PixelDetect, 3, 3, false);


    this.grass=BitmapFactory.decodeResource(getResources(), R.drawable.block_grass);
    this.grassSide=BitmapFactory.decodeResource(getResources(), R.drawable.block_grassside);
    this.grassTop=BitmapFactory.decodeResource(getResources(), R.drawable.block_grasstop);
    this.orange=BitmapFactory.decodeResource(getResources(), R.drawable.block_cube1);
    this.blue=BitmapFactory.decodeResource(getResources(), R.drawable.block_bluecube);
    this.dirt=BitmapFactory.decodeResource(getResources(), R.drawable.block_dirt);
    this.dirt2=BitmapFactory.decodeResource(getResources(), R.drawable.block_dirt2);
    this.dirt3=BitmapFactory.decodeResource(getResources(), R.drawable.block_dirt3);
    this.stonegrass=BitmapFactory.decodeResource(getResources(), R.drawable.block_stonegrass);
    this.stone=BitmapFactory.decodeResource(getResources(), R.drawable.block_stone);
    this.stone2=BitmapFactory.decodeResource(getResources(), R.drawable.block_stone2);
    this.stone3=BitmapFactory.decodeResource(getResources(), R.drawable.block_stone3);
    this.stone4=BitmapFactory.decodeResource(getResources(), R.drawable.block_stone4);
    this.mountaintop=BitmapFactory.decodeResource(getResources(), R.drawable.back_mountaintop);
    this.mountainbottom=BitmapFactory.decodeResource(getResources(), R.drawable.back_mountainbottom);
    this.arrowno=BitmapFactory.decodeResource(getResources(), R.drawable.arrow_noclick);
    this.arrown=BitmapFactory.decodeResource(getResources(), R.drawable.arrow_normal);
    this.arrowl=BitmapFactory.decodeResource(getResources(), R.drawable.arrow_left);
    this.arrowr=BitmapFactory.decodeResource(getResources(), R.drawable.arrow_right);
    this.arrowu=BitmapFactory.decodeResource(getResources(), R.drawable.arrow_up);
    this.arrowd=BitmapFactory.decodeResource(getResources(), R.drawable.arrow_down);
    this.arrowul=BitmapFactory.decodeResource(getResources(), R.drawable.arrow_upperleft);
    this.arrowur=BitmapFactory.decodeResource(getResources(), R.drawable.arrow_upperright);
    this.arrowdl=BitmapFactory.decodeResource(getResources(), R.drawable.arrow_downleft);
    this.arrowdr=BitmapFactory.decodeResource(getResources(), R.drawable.arrow_downright);
    this.arrowno=Bitmap.createScaledBitmap(arrowno, arrowno.getWidth()*3, arrowno.getHeight()*3, false);
    this.save=BitmapFactory.decodeResource(getResources(), R.drawable.button_save);
    this.brush=BitmapFactory.decodeResource(getResources(), R.drawable.menu_brush);
    this.brushcolor=BitmapFactory.decodeResource(getResources(), R.drawable.menu_brush_color);
    this.colorpick=BitmapFactory.decodeResource(getResources(), R.drawable.menu_colorpicker);
    this.torch=BitmapFactory.decodeResource(getResources(), R.drawable.item_torch);
    this.save=BitmapFactory.decodeResource(getResources(), R.drawable.button_save);
    this.fliph=BitmapFactory.decodeResource(getResources(), R.drawable.menu_fliph);
    this.flipv=BitmapFactory.decodeResource(getResources(), R.drawable.menu_flipv);
    this.Rotatef=BitmapFactory.decodeResource(getResources(), R.drawable.menu_rotatef);
    this.Rotateb=BitmapFactory.decodeResource(getResources(), R.drawable.menu_rotateb);
    this.bin_Empty=BitmapFactory.decodeResource(getResources(), R.drawable.bin_empty);
    this.bin_Full=BitmapFactory.decodeResource(getResources(), R.drawable.bin_full);
    this.bin_Empty=Bitmap.createScaledBitmap(bin_Empty, bin_Empty.getWidth()*3, bin_Empty.getHeight()*3, false);
    this.bin_Full=Bitmap.createScaledBitmap(bin_Full, bin_Full.getWidth()*3, bin_Full.getHeight()*3, false);
    this.brush=Bitmap.createScaledBitmap(brush, brush.getWidth()*3, brush.getHeight()*3, false);
    this.brushcolor=Bitmap.createScaledBitmap(brushcolor, brushcolor.getWidth()*3, brushcolor.getHeight()*3, false);
    this.colorpick=Bitmap.createScaledBitmap(colorpick, colorpick.getWidth()*3, colorpick.getHeight()*3, false);
    this.fliph=Bitmap.createScaledBitmap(fliph, fliph.getWidth()*3, fliph.getHeight()*3, false);
    this.flipv=Bitmap.createScaledBitmap(flipv, flipv.getWidth()*3, flipv.getHeight()*3, false);
    this.Rotateb=Bitmap.createScaledBitmap(Rotateb, Rotateb.getWidth()*3, Rotateb.getHeight()*3, false);
    this.Rotatef=Bitmap.createScaledBitmap(Rotatef, Rotatef.getWidth()*3, Rotatef.getHeight()*3, false);
    this.arrown=Bitmap.createScaledBitmap(arrown, arrown.getWidth()*3, arrown.getHeight()*3, false);
    this.arrowl=Bitmap.createScaledBitmap(arrowl, arrowl.getWidth()*3, arrowl.getHeight()*3, false);
    this.arrowr=Bitmap.createScaledBitmap(arrowr, arrowr.getWidth()*3, arrowr.getHeight()*3, false);
    this.arrowu=Bitmap.createScaledBitmap(arrowu, arrowu.getWidth()*3, arrowu.getHeight()*3, false);
    this.arrowd=Bitmap.createScaledBitmap(arrowd, arrowd.getWidth()*3, arrowd.getHeight()*3, false);
    this.arrowul=Bitmap.createScaledBitmap(arrowul, arrowul.getWidth()*3, arrowul.getHeight()*3, false);
    this.arrowur=Bitmap.createScaledBitmap(arrowur, arrowur.getWidth()*3, arrowur.getHeight()*3, false);
    this.arrowdl=Bitmap.createScaledBitmap(arrowdl, arrowdl.getWidth()*3, arrowdl.getHeight()*3, false);
    this.arrowdr=Bitmap.createScaledBitmap(arrowdr, arrowdr.getWidth()*3, arrowdr.getHeight()*3, false);

    Menu_Add(arrowno,0,true,"arrows");
    Menu_Add(bin_Empty,1,false,"bin");
    Menu_Add(brush,2,false,"brush");
    Menu_Add(brushcolor,2,false,"brushcolor");
    Menu_Add(colorpick,3,false,"colorpick");
    Menu_Add(Rotateb,4,false,"rotateb");
    Menu_Add(Rotatef,5,false,"rotatef");
    Menu_Add(fliph,6,false,"fliph");
    Menu_Add(flipv,7,false,"flipv");
    Menu_Add(grassTop,1,true,"grasstop");
    Menu_Add(grassSide,2,true,"grassside");
    Menu_Add(grass,3,true,"grass");
    Menu_Add(dirt,4,true,"dirt");
    Menu_Add(stonegrass,5,true,"stonegrass");
    Menu_Add(stone,6,true,"stone");
    Menu_Add(orange,7,true,"orange");
    Menu_Add(blue,8,true,"blue");
    Menu_Add(mountaintop,9,true,"mountaintop");
    Menu_Add(mountainbottom,10,true,"mountainbottom");
    Menu_Add(torch,11,true,"torch");
    arrowsp=new Point();
    arrowsp.x=0;
    arrowsp.y=0;
      tileBitmap = grass;

}
private void Menu_Add(Bitmap b,int order,boolean vertical,String name)
{
    Point p=new Point();
    if(order==0){
        p.x=0;
        p.y=0;
        MenuButton m=new MenuButton(order,b , vertical, p,name);
        menuButtonList.add(m);
    }
    else{
        for (MenuButton m : menuButtonList) {
            if((m.isVertical()==vertical||order==1)&&m.getOrder()+1==order ){
                if(vertical){
                    p.x=0;
                    p.y=m.getP().y+m.getBit().getHeight()+2;
                }
                else{
                    p.x=m.getP().x+m.getBit().getWidth()+2;
                    p.y=0;
                }
                MenuButton m2=new MenuButton(order,b , vertical, p,name);
                menuButtonList.add(m2);
                return;
            }
        }
    }
}
public void drawLight(){
    lightBitmap = Bitmap.createBitmap(1500, 15000, Bitmap.Config.ARGB_8888);
    Canvas cc = new Canvas(lightBitmap);
    Paint pp = new Paint(Paint.ANTI_ALIAS_FLAG);
    pp.setMaskFilter(new BlurMaskFilter(20, BlurMaskFilter.Blur.NORMAL));
    for (Map.Entry<BackBlock, Point> entry : torchBack.entrySet()) {
         cc.drawCircle(entry.getValue().x+6, entry.getValue().y+55, 25, pp);
        }
    lightRect = new RectF(-256, -256, lightBitmap.getWidth(), lightBitmap.getHeight());
    lightRect.offset(200, 200);
    float[] array = {
            1.2f, 0, 0, 0, 1,
            0,1.2f, 0, 0, 1,
            0, 0, 1.2f, 0, 1,
            0, 0, 0, 1, 0,
    };
    ColorMatrix ccc=new ColorMatrix(array);
    ccc.setScale(2, 1.5f, 1f, 1f);
    ColorMatrixColorFilter c4=new ColorMatrixColorFilter(ccc);
    paint0.setColorFilter(c4);
    paint1.setXfermode(new PorterDuffXfermode(PorterDuff.Mode.DST_IN));

}
@Override
protected void onDraw(Canvas canvas) {
    super.onDraw(canvas);
    drawLight();
    Paint paintAlpha = new Paint();
    paintAlpha.setAlpha(200);
    canvas.drawARGB(255, 86, 194, 243);
      drawTiles(canvas, paint0);

      drawTiles(canvas, null);

        for(MenuButton m : menuButtonList){
            switch(m.getName()){
            case "bin":
                if(bin_isEmpty){
                    canvas.drawBitmap(bin_Empty, m.getP().x, m.getP().y,paintAlpha);
                    }
                    else{
                        canvas.drawBitmap(bin_Full, m.getP().x, m.getP().y,paintAlpha);
                    }
                break;
            case "brushcolor":
                canvas.drawBitmap(m.getBit(), m.getP().x,m.getP().y, changeBitmapColor(m.getBit(), currentColor));
            break;
            case "arrows":
                canvas.drawBitmap(m.getBit(),m.getP().x,m.getP().y,paintAlpha);
                switch (arrowcheck) {
                case "normal":
                    canvas.drawBitmap(arrown, arrowsp.x, arrowsp.y,paintAlpha);
                    break;
                case "left":
                    canvas.drawBitmap(arrowl, arrowsp.x, arrowsp.y,paintAlpha);
                    break;
                case "right":
                    canvas.drawBitmap(arrowr, arrowsp.x, arrowsp.y,paintAlpha);
                    break;
                case "down":
                    canvas.drawBitmap(arrowd, arrowsp.x, arrowsp.y,paintAlpha);
                    break;
                case "up":
                    canvas.drawBitmap(arrowu, arrowsp.x, arrowsp.y,paintAlpha);
                    break;
                case "upleft":
                    canvas.drawBitmap(arrowul, arrowsp.x, arrowsp.y,paintAlpha);
                    break;
                case "upright":
                    canvas.drawBitmap(arrowur, arrowsp.x, arrowsp.y,paintAlpha);
                    break;
                case "downleft":
                    canvas.drawBitmap(arrowdl, arrowsp.x, arrowsp.y,paintAlpha);
                    break;
                case "downright":
                    canvas.drawBitmap(arrowdr, arrowsp.x, arrowsp.y,paintAlpha);
                    break;
                }
                break;
            default:
                canvas.drawBitmap(m.getBit(),m.getP().x,m.getP().y,paintAlpha);
                break;

            }
            Paint paintRec = new Paint();
            paintRec.setColor(Color.RED);
            paintRec.setStyle(Style.STROKE);
            paintRec.setStrokeWidth(4);
            paintRec.setStrokeCap(Cap.ROUND);
            paintRec.setStrokeJoin(Join.ROUND);
            paintRec.setPathEffect(new DashPathEffect(new float[] {30,40}, 0));
            paintRec.setAlpha(5);
            if(currentBlock!=null)
            canvas.drawRect(currentBlock.getValue().x,currentBlock.getValue().y,currentBlock.getValue().x+currentBlock.getKey().getBit().getWidth(),currentBlock.getValue().y+currentBlock.getKey().getBit().getHeight(),paintRec);


        }
        canvas.saveLayer(lightRect, null, Canvas.HAS_ALPHA_LAYER_SAVE_FLAG);
        canvas.clipRect(lightRect);
        drawTiles(canvas, paint0);
        canvas.drawBitmap(lightBitmap, null, lightRect, paint1);
        canvas.restore();

}
  void drawTiles(Canvas canvas, Paint p) {
      for (Map.Entry<BackBlock, Point> entry : mountainbottomBack.entrySet()) {
            //Bitmap lighten=Bitmap.createScaledBitmap(entry.getKey().getBit(), entry.getKey().getBit().getWidth(), entry.getKey().getBit().getHeight(), false);
            canvas.drawBitmap(entry.getKey().getBit(), entry.getValue().x,entry.getValue().y, p);
            }
        for (Map.Entry<BackBlock, Point> entry : mountaintopBack.entrySet()) {
            canvas.drawBitmap(entry.getKey().getBit(), entry.getValue().x,entry.getValue().y, p);
            }
        for (Map.Entry<CreatorBlock, Point> entry : grassblock.entrySet()) {
            canvas.drawBitmap(entry.getKey().getBit(), entry.getValue().x,entry.getValue().y, p);
        }
        for (Map.Entry<CreatorBlock, Point> entry : stonegrassblock.entrySet()) {
            canvas.drawBitmap(entry.getKey().getBit(), entry.getValue().x,entry.getValue().y, p);
            }
        for (Map.Entry<CreatorBlock, Point> entry : dirtblock.entrySet()) {
            canvas.drawBitmap(entry.getKey().getBit(), entry.getValue().x,entry.getValue().y, p);
            }
        for (Map.Entry<CreatorBlock, Point> entry : stoneblock.entrySet()) {
            canvas.drawBitmap(entry.getKey().getBit(), entry.getValue().x,entry.getValue().y, p);
            }
        for (Map.Entry<CreatorBlock, Point> entry : grassSideBlock.entrySet()) {
            canvas.drawBitmap(entry.getKey().getBit(), entry.getValue().x,entry.getValue().y, p);
            }
        for (Map.Entry<CreatorBlock, Point> entry : grassTopBlock.entrySet()) {
            canvas.drawBitmap(entry.getKey().getBit(), entry.getValue().x,entry.getValue().y, p);
            }
        for (Map.Entry<CreatorBlock, Point> entry : orangeBlock.entrySet()) {
            canvas.drawBitmap(entry.getKey().getBit(), entry.getValue().x,entry.getValue().y, p);
            }
        for (Map.Entry<CreatorBlock, Point> entry : blueBlock.entrySet()) {
            canvas.drawBitmap(entry.getKey().getBit(), entry.getValue().x,entry.getValue().y, p);
            }
        for (Map.Entry<BackBlock, Point> entry : torchBack.entrySet()) {
            canvas.drawBitmap(entry.getKey().getBit(), entry.getValue().x,entry.getValue().y, p);
            }
    }
SpoocyCrep
  • 604
  • 7
  • 23
  • http://stackoverflow.com/questions/19428973/how-to-draw-a-circle-with-radial-gradient-in-a-canvas – weston Jan 16 '15 at 12:03
  • I'm not trying to create a bitmap with gradient in it, I only want the light to fade out using the pixels and code I provided, sort of like gradient. – SpoocyCrep Jan 16 '15 at 12:05
  • That's just down to what the bitmap looks like before plus select colours with alpha blends for your gradient and it will blend. – weston Jan 16 '15 at 12:06
  • You don't want to be manipulating large amounts of pixels yourself. It will be slow. Android has good graphics classes that uses your graphics hardware that will do this very efficiently. – weston Jan 16 '15 at 12:07
  • so you're saying draw two bitmaps ontop of eachother and decrease the alpha of the light bitmap? That's possible but I still wonder if there is a way to work only with the pixels, i got the center x,y and radius of how far i want the light to go, is there a way to make it fade out the more far it is using only pixel colors? – SpoocyCrep Jan 16 '15 at 12:08
  • the graphics in android doesn't fit my original need, the only solution i was able to find was to run on all the pixels. – SpoocyCrep Jan 16 '15 at 12:11
  • 2
    "the graphics in android doesn't fit my original need," You're wrong. – weston Jan 16 '15 at 12:11
  • you don't know what my needs are.. I'm trying to make a torch that will light every bitmap that is behind it, not just one. In order to do that the only solution I was able to find is to run on every pixel in bitmaps that are close to it and check if they are inside the light circle of the torch, if so light them up. – SpoocyCrep Jan 16 '15 at 12:13
  • 2
    @SpoocyCrep did you try various porter duff modes? – pskink Jan 16 '15 at 12:15
  • @pskink I don't know what are those, but I'm allowed to only use canvas because it's a school project – SpoocyCrep Jan 16 '15 at 12:17
  • @SpoocyCrep see Paint.setXfermode() – pskink Jan 16 '15 at 12:19
  • @pskink I don't want to use paint, why do you guys insist on changing the code, I already made a light source and I can place any amount of bitmaps around the circle or inside and it will count as one light source, all I asked for is how to smooth it using the pixels and code provided.. Here, I added a picture of what happens when I add many bitmaps, maybe it will help you understand. – SpoocyCrep Jan 16 '15 at 12:33
  • @SpoocyCrep because if you deal with raw pixels in 99.9% of cases you are stepping the wrong path – pskink Jan 16 '15 at 12:33
  • @pskink I don't care, I'm not going to sell this app, I just want it to be done this way. – SpoocyCrep Jan 16 '15 at 12:38
  • 1
    @SpoocyCrep so you mean you want to get something like this http://snag.gy/DEIfA.jpg ? the general solution takes 30 lines of code or so... – pskink Jan 16 '15 at 17:35
  • @pskink yeah! this is exactly what im trying to do, only what is missing is a bit of yellow tint that will make it looked like its real light – SpoocyCrep Jan 16 '15 at 17:46
  • @SpoocyCrep as i said i did it with ~30 lines of code and its a generic solution, the bad news is it uses Paint stuff, not raw pixels as you **require** – pskink Jan 16 '15 at 17:57
  • @pskink I gave up on the pixels because I can't find solution to it, I don't mind if it's 30 lines of code.. – SpoocyCrep Jan 16 '15 at 18:02
  • @pskink don't mind as in i'm okay with it, ill take any solution that works.. – SpoocyCrep Jan 16 '15 at 18:14
  • @SpoocyCrep if so, i posted the answer – pskink Jan 16 '15 at 18:28

2 Answers2

2

I agree with the other posters who say that using the built-in Android graphics functions is a better and more efficient way of tackling this problem, but if this is just for learning purposes I don't see the harm in manipulating the raw pixel values directly. I'll just give you some ideas rather than providing a complete solution.

At the moment, you are effectively doing an additive blend of your texture with a constant light color (rn, gn, bn). In order to do this more smoothly, introduce an alpha value, so that you are adding (rn * a, gn * a, bn * a) to your texture instead, and vary alpha based on the radial distance.

Be careful, this is not the alpha value you get from the texture with Color.alpha(pixel) but another one to represent the strength of the light.

Implicitly, your current alpha value is defined as one if result (your calculated distance from the light center) is <= 120, and zero otherwise: it's all-or-nothing.

You can define a function based on result to give alpha values in between these extremes. For example, you could make it so that the alpha value is one if the radius is less than 90, then fade it down from one to zero from radius = 90 to radius = 150, and then make it zero any further away than that.

You can also scale your alpha value to go from 0 (no light) to 256 (full light intensity) instead of 0 to 1, for coding convenience.

Calculate the alpha value function like this based on the above rules:

int result=(int) Math.sqrt((x2-i)*(x2-i)+(y2-j)*(y2-j));
int alpha = 0;
if(result <= 90)
    alpha = 256;
else if((result > 90) && (result < 150))
    alpha = ((60 - (result - 90)) * 256) / 60;

Obviously you can play around with the values to get an effect that you like.

Then, instead of testing against

if(result<=120)

Test against the alpha value like this

if(alpha > 0)

Lastly, inside your loop, add rn, gn and bn to the pixel color values, such that when alpha = 0 you add nothing, when alpha = 256 you add the whole amount, and you add partial amounts for every value in between. I'll let you figure out how to do this on your own.

samgak
  • 23,944
  • 4
  • 60
  • 82
  • Uhm theres a problem, the new color (brightness) has yellow tint to it so I cant reduce same alpha for all of them.. rn=130 gn=60 bn=3 – SpoocyCrep Jan 16 '15 at 15:33
  • uhm.. what kind of formula i can use? sorry its a bit confusing :( – SpoocyCrep Jan 16 '15 at 15:41
  • Multiply your light color by alpha and add to the bitmap pixel e.g. r = Color.red(pixel) + ((rn * alpha) / 256); – samgak Jan 16 '15 at 22:23
2

use this custom View, to make it more yellow see the comment in float[] array initialization:

class V extends View {
    Paint paint0;
    Paint paint1;

    public V(Context context) {
        super(context);
        setLayerType(View.LAYER_TYPE_SOFTWARE, null);
        paint0 = new Paint();
        Bitmap bitmap = BitmapFactory.decodeResource(getResources(), R.drawable.fykgf);
        Shader shader = new BitmapShader(bitmap, Shader.TileMode.REPEAT, Shader.TileMode.REPEAT);
        paint0.setShader(shader);

        paint1 = new Paint();
        paint1.setMaskFilter(new BlurMaskFilter(50, BlurMaskFilter.Blur.NORMAL));
        float[] array = {
                2, 0, 0, 0, 0,
                0, 2, 0, 0, 0,
                0, 0, 2, 0, 0, // change 2 to: something between [1..2] to get it more yellow
                0, 0, 0, 1, 0,
        };
        paint1.setColorFilter(new ColorMatrixColorFilter(array));
        paint1.setShader(shader);
    }

    @Override
    protected void onDraw(Canvas canvas) {
        canvas.drawRect(0, 0, getWidth(), getHeight(), paint0);
        canvas.drawCircle(300, 300, 150, paint1);
    }
}

EDIT

if you want several Bitmapts to be drawn use this:

class V extends View {
    Bitmap tileBitmap;
    Bitmap lightBitmap;
    RectF lightRect;
    Paint paint0 = new Paint(Paint.ANTI_ALIAS_FLAG);
    Paint paint1 = new Paint(Paint.ANTI_ALIAS_FLAG);

    public V(Context context) {
        super(context);
//        setLayerType(View.LAYER_TYPE_SOFTWARE, null);
        tileBitmap = BitmapFactory.decodeResource(getResources(), R.drawable.fykgf);
        lightBitmap = Bitmap.createBitmap(256, 256, Bitmap.Config.ARGB_8888);
        Canvas c = new Canvas(lightBitmap);
        Paint p = new Paint(Paint.ANTI_ALIAS_FLAG);
        p.setMaskFilter(new BlurMaskFilter(20, BlurMaskFilter.Blur.NORMAL));
        c.drawCircle(128, 128, 100, p);
        lightRect = new RectF(0, 0, lightBitmap.getWidth(), lightBitmap.getHeight());
        lightRect.offset(200, 200);

        float[] array = {
                4, 0, 0, 0, 0,
                0, 4, 0, 0, 0,
                0, 0, 0, 0, 0,
                0, 0, 0, 1, 0,
        };
        paint0.setColorFilter(new ColorMatrixColorFilter(array));
        paint1.setXfermode(new PorterDuffXfermode(PorterDuff.Mode.DST_IN));
    }

    @Override
    protected void onDraw(Canvas canvas) {
        drawTiles(canvas, null);

        canvas.saveLayer(lightRect, null, Canvas.HAS_ALPHA_LAYER_SAVE_FLAG);
        canvas.clipRect(lightRect);
        drawTiles(canvas, paint0);
        canvas.drawBitmap(lightBitmap, null, lightRect, paint1);
        canvas.restore();
    }

    void drawTiles(Canvas canvas, Paint p) {
        // draw your Bitmaps here...
    }
}
pskink
  • 23,874
  • 6
  • 66
  • 77
  • Nice! but its not exactly what I wanted to do, on my project the cobblestone blocks are moveable, i want the circle of light to stay still and i could move around the block and if it will be under the circle of light it will light up as a circle, your code draws many bitmaps and circle, how can I change it? – SpoocyCrep Jan 16 '15 at 18:28
  • I will be more specific : My project is a map creator, i can move around blocks, im trying to make a torch block that you can move around and place and wherever you place it it will create a small circle of light around it and light the blocks around it. – SpoocyCrep Jan 16 '15 at 18:35
  • You can do it by just changing the shader – pskink Jan 16 '15 at 18:43
  • so read this for example: http://www.curious-creature.com/2012/12/13/android-recipe-2-fun-with-shaders/ – pskink Jan 16 '15 at 19:05
  • But you apply one shader to one bitmap and then you just showed it multiplied, how will it work when it comes to different bitmaps and one shader\light circle that are not related to eachother? for example two different bitmaps, one cobblestone and one wood. How can I apply the same shader to both of them? And do I need to apply to all the bitmaps i got the shader? – SpoocyCrep Jan 16 '15 at 19:12
  • You have two ways: combine n small bitmaps into one large and call setShader/drawCircle once or call setShader/drawCircle n times – pskink Jan 16 '15 at 19:29
  • Or what i didn't try, you could use a ComposeShader, i will need to test it – pskink Jan 16 '15 at 19:31
  • Combining them all into one bitmap won't work because it is a map creator, the user constantly moves the blocks (the bitmaps) and re-positions them. I don't know what composeshader is, I could email you my map creator code if it helps. – SpoocyCrep Jan 16 '15 at 19:34
  • It will work, create a Bitmap of size of your view and draw your tiles there, then use it as a BitmapShader source – pskink Jan 16 '15 at 22:32
  • there is no "then", what if after i drew the bitmap shader the user would like to change the block and place it somewhere else, it will merge into one bitmap and he wont be able to move each bitmap like before.. – SpoocyCrep Jan 16 '15 at 23:19
  • Again: in onDraw method draw your tiles into the offscreen buffer and then use it as a input to the shader – pskink Jan 16 '15 at 23:24
  • offscreen buffer? I apologize, I'm a beginner to android, I don't really understand what you wrote or how to do that :(. – SpoocyCrep Jan 17 '15 at 10:36
  • ok maybe i dont understand your needs, do you want something like this: https://drive.google.com/open?id=0B_WcN_UEpuxmZE1FMmJGb1FpNzA&authuser=0 ? – pskink Jan 17 '15 at 10:50
  • Not exactly, here you move all the squares of stone together, i want to be able to move each one of them by their own, here my map creator with what I created using pixels - you were right, its laggy with pixels because its a lot to check. Download of apk: https://drive.google.com/file/d/0B4m6efvI6B3uMDBOLW91c2x3X0k/view?usp=sharing circle is at : http://puu.sh/eDyrd/88c40c23d1.png – SpoocyCrep Jan 17 '15 at 12:11
  • come in, its about the idea, not the concrete implementation, for example by overriding two or three methods you can have this: https://drive.google.com/open?id=0B_WcN_UEpuxmN0FVdEw2RHBWcm8&authuser=0 – pskink Jan 18 '15 at 10:11
  • the idea you gave before is make one bitmap that connects them all and move them all together (that's at least how it looked like for me), here you did each bitmap for it own, this is exactly what I need!, how did you do that? Also, if you add another bitmap of another picture, will it still work the same? – SpoocyCrep Jan 18 '15 at 10:26
  • yes you can draw different Bitmaps, updated the answer – pskink Jan 18 '15 at 10:34
  • I will try it now! thank you so much, by the way unrelated question : how did you do the onclick to move the blocks like that? the way I did it places the mouse on the corner of the block when you move and it does not place the block on top when you click on it. – SpoocyCrep Jan 18 '15 at 10:42
  • Use GestureDetector as i did, its the most simple way – pskink Jan 18 '15 at 10:44
  • GestureDetector? I never heared of it, ill look it up. – SpoocyCrep Jan 18 '15 at 10:46
  • Uhm, but in your code its tileBitmap = BitmapFactory.decodeResource(getResources(), R.drawable.fykgf); if I want to use two different pictures I need to write the whole code twice for the second picture? – SpoocyCrep Jan 18 '15 at 10:50
  • See drawTiles method, there you can draw dozen of different Bitmaps – pskink Jan 18 '15 at 10:52
  • I did that, but the result was odd: http://puu.sh/eGl7t/dbd3c5502d.png is all that showed up – SpoocyCrep Jan 18 '15 at 10:53
  • actually the blue square is my fault, i drew the background after the titles, but now i changed it and all it shows is the background, no other bitmaps are showing and no titles are showing. http://puu.sh/eGljf/8740702485.png – SpoocyCrep Jan 18 '15 at 10:55
  • Backgroud aftrr the tiles? It makes no sense, draw the background before everything else – pskink Jan 18 '15 at 10:58
  • I know, i did that it was my fault. – SpoocyCrep Jan 18 '15 at 10:59
  • puu.sh/eGlyl/b4b74a486a.png it cuts off and draws on the middle, it seems to draw everything inside small square – SpoocyCrep Jan 18 '15 at 11:00
  • i dont think so, you can draw the background and i dont see any small squere, see: https://drive.google.com/open?id=0B_WcN_UEpuxmN0FVdEw2RHBWcm8&authuser=0 – pskink Jan 18 '15 at 12:09
  • I don't understand why it doesnt work with my code.. few images doesnt show up and i dont see the light, can you please check my code, I can email it to you.. also ill edit the code here for you to see – SpoocyCrep Jan 18 '15 at 12:35
  • and? i never used paint to draw the tiles – SpoocyCrep Jan 18 '15 at 13:20
  • Its here for some purpose: for using with Canvas.drawBitmap – pskink Jan 18 '15 at 13:23
  • but you send it null, how does that matter? – SpoocyCrep Jan 18 '15 at 13:42
  • Nevermind I fixed it and it works! now last left is the color, i dont understand how to use the numbers for the color, i want it to be brighter and a little bit yellow, like i posted on the thread, how i can do that? – SpoocyCrep Jan 18 '15 at 14:08
  • you have to experiment as i did, but first read the docs http://developer.android.com/reference/android/graphics/ColorMatrix.html, you have some experience with raw pixel (r, g, b, a) so you should understand the ColorMatrix – pskink Jan 18 '15 at 14:10
  • cant I convert it from rgb to this? – SpoocyCrep Jan 18 '15 at 14:30
  • Convert? Convert what? – pskink Jan 18 '15 at 14:36
  • Nevermind that, it works perfectly! my last question is how do i change the circle size and reposition it, when i tried to change it to 33,33,33 it became a square http://puu.sh/eGJtZ/c90e6735c4.jpg and how do I create more circles like that? simply repeat c.drawCircle(128, 128, 100, p); at different positions? – SpoocyCrep Jan 18 '15 at 14:49
  • Okay I managed to do this, but there is a bug that its kind of hard to explain please check out the apk : http://puu.sh/eHNQH/978f433c76.apk spawn a torch and try move it on block, the light circle sometimes at right position but if u move it to the left or right its not at the right place anymore, ill update my code – SpoocyCrep Jan 18 '15 at 21:59
  • as i said before 1.1MB is to much to download as i'm on the mobile data plan, make your apk 100k or so, and i will download it – pskink Jan 18 '15 at 22:09
  • here you have my base code: add your changes and describe what went wrong: http://pastebin.com/0BFRmBeW – pskink Jan 18 '15 at 22:39
  • you don't have bluestacks? and all I did was to add a new bitmap that looks like a torch (http://puu.sh/eHZQx/3627972d4e.png) and I drew the circle of light at the x,y of this torch and made this torch draggable, the circle always changed position while dragging, if you move the torch to the right too much the circle goes outside far from the torch, and same about to the left.. ill edit it on your code tomorrow, sadly I need to go now. – SpoocyCrep Jan 18 '15 at 23:15
  • you're very good on android, I will be very happy if you could help me also solve this problem as well if you can: http://stackoverflow.com/questions/27815473/make-bitmap-size-and-position-the-same-on-every-device none was able to figure out what my problem is.. – SpoocyCrep Jan 19 '15 at 12:57
  • did you try to place your images in res/drawable-nodpi ? – pskink Jan 19 '15 at 13:01
  • They are in drawable-nodpi. – SpoocyCrep Jan 19 '15 at 13:01
  • so use absolute values for Canvas.drawBitmap for all of your devices and use different Canvas scaling – pskink Jan 19 '15 at 13:04
  • absolute values? I used DPI as they told me to, but it was weird (I posted few images) and what do you mean by canvas scaling? – SpoocyCrep Jan 19 '15 at 13:06
  • Use the same x/y in all devices and for small devices you can use canvas.scale() before drawing anything in onDraw – pskink Jan 19 '15 at 13:14
  • the problem is that I use emulator of tablet and scaling it to small devices now is not that simple.. – SpoocyCrep Jan 19 '15 at 13:17
  • Just call canvas.scale(.5f, .5f) for example – pskink Jan 19 '15 at 13:23
  • I don't think it will work out the best for me because I got a lot more calculations outside the drawing that uses the size and x,y maybe it will draw it correctly but everything else will stay the same.. – SpoocyCrep Jan 19 '15 at 13:26