2

I'm making my first game using Java on Android. I need to draw a lot of pixels which together should create a line. My first approach was to make a large array of booleans, create a loop, and draw a pixel when the associated boolean was true.

It wasn't a good idea of course (the array is about 200x300). Now I remember only the position of the first pixel of the line, and every next pixel has to remember his follower. It works pretty well, but when the line gets longer (but still not very long), the efficiency is bad (<20 fps after 4000 frames).

This is the function that I use to draw a line (only one for now). Can anybody help me improve its efficiency?

public void drawLine(Canvas canvas, int beginx, int beginy) {
    Paint paint = new Paint(Paint.ANTI_ALIAS_FLAG);
    paint.setColor(Color.RED);
    paint.setStrokeWidth(3);

    int x = beginx;
    int y = beginy;
    while(C.mGrid[x][y].nx != -1) {
        //canvas.drawLine(x, y, C.mGrid[x][y].nx, C.mGrid[x][y].ny, paint);
        canvas.drawPoint(x, y, paint);
        Grid temp = C.mGrid[x][y];
        if ((C.mGrid[x][y].nx == x) && (C.mGrid[x][y].ny == y)) break;
        x = temp.nx;
        y = temp.ny;
    }
}

and Grid.java:

package com.qwak.achtung;

public float x = 0,y = 0;
public int px = -1, py = -1, nx = -1, ny = -1;

public Grid(float x, float y) {
    this.x = x;
    this.y = y;
}

public void set(int px, int py, int nx, int ny) {
    this.px = px;
    this.py = py;
    this.nx = nx;
    this.ny = ny;
}

public void setp(int px, int py) {
    this.px = px;
    this.py = py;
}

public void setn(int nx, int ny) {
    this.nx = nx;
    this.ny = ny;
}

PS: It looks like this http://c.wrzuta.pl/wi10559/11f7d10b00110e504e25ebd3/0/andek 14 is fps (on my phone (samsung Spica) it run better - 40 but after a while it decreases to 20 and even less) and 983 is number of frames at all.

Krzysztof Kaczor
  • 5,026
  • 7
  • 35
  • 47

2 Answers2

4

There is a drawLine method in the canvas object.

Use the example here: How to draw a line in android

canvas.drawLine(0, 0, 20, 20, paint);

If you want to draw a curve. Find the function of the curve. A Parabola for example is x=y^2. You can get points from the curve: 1 = 1, 2 = 4, 3 = 9, 4 = 16... etc.. If your drawing pixel by pixel you can plug in your x and get your y and draw it.

Paint paint = new Paint(Paint.ANTI_ALIAS_FLAG); paint.setColor(Color.RED); paint.setStrokeWidth(3);

for(int i = beginx; i < CanvasWidth; i++)
{
    int x = i;
    int y = i * i; //x=y^2
    canvas.drawPoint(x, y, paint);
}

To keep a record of points that were visited you could do the following:

class Point
{
    int x;
    int y;
}


List<Point> points = new List<Point>();

onMove(int newX, int newY)
{
    Point p = new Point();
    p.x = newX;
    p.y = newY;

    points.add(p);
}


onDraw()
{
    for(Point p : points)
    {
        canvas.drawPoint(p.x, p.y, paint);
    }
}
Community
  • 1
  • 1
Chris Lucian
  • 993
  • 5
  • 15
  • I know how to write line but its more like curve(? english is not my first language) it cant be described as a simple line between 2 points but between many of them. – Krzysztof Kaczor Jul 19 '11 at 18:13
  • You will need to find the function for the line. i.e. x=y^2 (a curve), then you can just plug in each point you want to draw. That will be more efficient than using the array. I will add to my original post. – Chris Lucian Jul 19 '11 at 18:40
  • It looks like this http://c.wrzuta.pl/wi10559/11f7d10b00110e504e25ebd3/0/andek 14 is fps (on my phone (samsung Spica) it run better - 40 but after a while it decreases to 20 and even less) and 983 is number of frames at all. – Krzysztof Kaczor Jul 19 '11 at 20:45
  • What are you trying to do? Is this someone drawing the line with their finger? If your just adding to the line, consider creating a bitmap, then changing the pixels on the bitmap and finally call draw on it. http://developer.android.com/reference/android/graphics/Bitmap.html Use the setPixel function – Chris Lucian Jul 19 '11 at 20:52
  • Yellow dot i current position of the player ;) using dpad you can turn left/right... – Krzysztof Kaczor Jul 19 '11 at 21:09
  • Keep a List of all each point moved to... Adding code to answer. – Chris Lucian Jul 19 '11 at 21:11
  • Ok, tomorrow i will read about bitmaps and i will draw only new points on the screen. Thank you! :) – Krzysztof Kaczor Jul 19 '11 at 21:36
0

You want to look into the bresenham algorithm. A bresenham algorithm is a method to draw or rasterize a line. It's a bit different from the subdivision of a grid in a certain angle for example a morton-curve. It's a bit like compute the scalar product for every angle like recall here Traversing a 2D array in an angle.

Community
  • 1
  • 1
Gigamegs
  • 12,342
  • 7
  • 31
  • 71
  • Yep, I used it to "check" pixels between 2 points created in 2 frames. ( i want to have it checked in the array ). It is currently turn off because i have efficietly problems ;/ – Krzysztof Kaczor Jul 19 '11 at 21:05