0

I am developing game using canvas. I have drawn grid of circles using loop. I want to get x,y coordinates of circles. For that I have to make those circles clickable so that whenever player click on a circle it should return its coordinates. I will pass those coordinates to lineDraw() method for drawing line between those circles. This loop is defining grid of circles:

for (int y=0;y<rows;y++)
        {
            for (int x=0;x<cols;x++)
            {
               canvas.drawCircle((x + 1) * dw, (y + 1) *(3* dh), 20, pDot);
}
}

Here dw is (displayWidth) and dh is (displayHeight). Please suggest how I should make these circles clickable?

Blo
  • 11,903
  • 5
  • 45
  • 99
Umar Farooq
  • 127
  • 1
  • 2
  • 19
  • hope this link give you some idea http://stackoverflow.com/a/20588487/3110609 – Harshal Benake Apr 04 '14 at 13:14
  • If I am not wrong this method will detect motion event, and return x,y. While I have already drawn circles with fix x and y and I want to make those circles clickable. I don't want to move those circles the only thing I want is there x and y coordinates. I will pass these coordinates to line draw method for drawing line between two circles. – Umar Farooq Apr 04 '14 at 13:20

2 Answers2

1

I had played with this project a little after your previous questions. I'm sure this isn't the most optimized way to do this, but without knowing how you plan to implement the game logic, I think this is flexible enough to adapt. The following is your custom View class, which I've renamed Board, in keeping with Java naming conventions.

public class Board extends View
{
    Paint pBack = new Paint();
    Paint pDot = new Paint();
    Paint pLine = new Paint();

    int cols = 5; 
    int rows = 6;

    // Default initialization = false
    boolean[][] dots = new boolean[cols][rows];     

    int canWidth = 0;
    int canHeight = 0;

    float xStep = 0;
    float yStep = 0;

    float[] xCoords = new float[cols];
    float[] yCoords = new float[rows];

    public Board(Context context)
    {
        super(context); 
        pBack.setARGB(255, 255, 102, 0);
        pDot.setARGB(255, 255, 255, 255);

        pLine.setStrokeWidth(5);
        pLine.setARGB(255, 90, 10, 0);
    }

    public void setDots(boolean[][] dotSelected)
    {
        this.dots = dotSelected;
    }

    public boolean[][] getDots()
    {
        return dots;
    }

    protected void onSizeChanged(int w, int h, int oldw, int oldh)
    {
        canWidth = w;
        canHeight = h;

        xStep = canWidth / (cols + 1);
        yStep = canHeight / (rows + 1);

        for (int y = 0; y < rows; y++)
        {
            yCoords[y] = (y + 1) * yStep;
        }

        for (int x = 0; x < cols; x++)
        {
            xCoords[x] = (x + 1) * xStep;
        }           
    }

    protected void onDraw(Canvas canvas) 
    {
        super.onDraw(canvas);
        canvas.drawPaint(pBack);

        // Grid, lines and box markings
        for (int y = 0; y < rows; y++)
        {
            canvas.drawLine(xStep, yCoords[y], cols * xStep, yCoords[y], pDot);

            for (int x = 0; x < cols; x++)
            {
                if (y == 0)
                {
                    canvas.drawLine(xCoords[x], yStep, xCoords[x], rows * yStep, pDot);
                }

                if (dots[x][y])
                {
                    boolean left = x > 0 && dots[x - 1][y];
                    boolean up = y > 0 && dots[x][y - 1];

                    if (left)
                    {
                        canvas.drawLine(xCoords[x], yCoords[y], xCoords[x - 1], yCoords[y], pLine);
                    }

                    if (up)
                    {
                        canvas.drawLine(xCoords[x], yCoords[y], xCoords[x], yCoords[y - 1], pLine);
                    }

                    if (left && up && dots[x - 1][y - 1])
                    {
                        canvas.drawCircle(xCoords[x] - xStep / 2, yCoords[y] - yStep / 2, 10, pLine);
                    }
                }
            }
        }

        // Dots
        for (int y = 0; y < rows; y++)
        {
            for (int x = 0; x < cols; x++)
            {
                canvas.drawCircle(xCoords[x], yCoords[y], 20, pDot);                    
                if (dots[x][y])
                {
                    canvas.drawCircle(xCoords[x], yCoords[y], 15, pBack);                       
                }                                       
            }
        }
    }

    public boolean onTouchEvent(MotionEvent event)
    {
        super.onTouchEvent(event);

        if (event.getAction() != MotionEvent.ACTION_DOWN)
            return true;

        int xNear = 0;
        int yNear = 0;

        float xMin = canWidth;
        float yMin = canHeight;

        for (int x = 0; x < cols; x++)
        {
            if (Math.abs(xCoords[x] - event.getX()) < xMin)
            {
                xMin = Math.abs(xCoords[x] - event.getX());
                xNear = x;
            }
        }

        for (int y = 0; y < rows; y++)
        {
            if (Math.abs(yCoords[y] - event.getY()) < yMin)
            {
                yMin = Math.abs(yCoords[y] - event.getY());
                yNear = y;
            }
        }

        dots[xNear][yNear] = !dots[xNear][yNear];
        invalidate();

        return true;
    }
}
Mike M.
  • 38,532
  • 8
  • 99
  • 95
  • Can you please download this game from play store. https://play.google.com/store/apps/details?id=com.ruslana.dotsandboxes it will make you clear about my game idea. – Umar Farooq Apr 05 '14 at 08:13
  • I am copying this idea as it is. – Umar Farooq Apr 05 '14 at 08:14
  • I tested you code. It allows diagonal selection. Which is not allowed. It should allow only two circle at a time for drawing line. – Umar Farooq Apr 05 '14 at 08:14
  • One more thing it allows user to selection and deselection both. Which is not allowed, instead it should allow a player to select two circle in one turn. after selecting one circle he can only select the circle which is right next to its upper or left or right or lower side. – Umar Farooq Apr 05 '14 at 08:23
  • How to restrict diagonal selection? – Umar Farooq Apr 06 '14 at 07:55
  • This would be two player game so it will allow player to select 2 adjacent circles in one turn, When he complete box he will be given one more chance to draw line between two circles. – Umar Farooq Apr 06 '14 at 07:59
  • Q1) Does the player really need to select two dots? It is developer's choice, whatever way you feel easy apply that, The only thing we have to ensure is that in one turn a player is allowed to connect only "two" dots with one "line". unless he succeeded to complete box, in this scenario the player will be allowed one more turn as reward. – Umar Farooq Apr 06 '14 at 10:54
  • This is above mentioned game's screen shot. In this shot you can see there "3" are blue lines which are drawn by me and "4" red lines which are drawn by my opponent, why he has drawn 4 it is because he completed a box you can see in picture, and in reward he is allowed to draw one more line. Link http://postimg.org/image/7a5097wn3/ – Umar Farooq Apr 06 '14 at 11:02
  • One more thing, it is not necessary to draw line sequentially, it is on player's will, wherever he find safe he can draw line there. And by safe it means that wherever he finds that opponent can't complete box or if there is no safe place remaining than he will make sure that opponent will be given minimum number of boxes by him. – Umar Farooq Apr 06 '14 at 11:11
  • Because winner will be the person who have maximum boxes, like this http://postimg.org/image/gchoqxqc5/ – Umar Farooq Apr 06 '14 at 11:21
  • How to restrict circles selection? It should allow first circle selection randomly but second circle selection should be right next to first circles's surroundings. By surrounding mean its upper or lower or left or right side. – Umar Farooq Apr 07 '14 at 11:25
  • Yes this approach can work, please guide me I want to implement this "hacky" :) – Umar Farooq Apr 08 '14 at 04:01
  • I have made three classes, "Selector", "MainActivity" and "BoarView". MainActivity contains interface from where I click "Two Player" option, When I click a message appears "Unfortunately, Game has Stopped." – Umar Farooq Apr 08 '14 at 10:41
  • I am calling BoardView in Selector class, while MainActivity contains the starting interface like this http://postimg.org/image/ny3cqw45r/. – Umar Farooq Apr 08 '14 at 10:47
  • public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); gameBoard=new BoardView(this); setContentView(gameBoard); gameBoard.requestFocus(); } – Umar Farooq Apr 08 '14 at 11:24
  • I have called my previous project in this way and that worked fine – Umar Farooq Apr 08 '14 at 11:24
  • In my previous project there were two activity classes and one view. – Umar Farooq Apr 08 '14 at 11:25
  • Which one is better approach, TextView or ImageView? – Umar Farooq Apr 08 '14 at 11:26
  • I have asked a question here. http://stackoverflow.com/questions/22979939/type-mismatch-exception – Umar Farooq Apr 10 '14 at 07:17
0

Store the data of your circles (for instance the position and the radius) in a list and check each of them for mouse collision(register a mouseeventlistener).

public class Circle
{
private int radius;
private int positionX;
private int positionY;

public Circle(int positionX, int positionY, int radius)
{
this.radius = radius;
this.positionX = positionX;
this.positionY = positionY;
}

public int getPositionX()
{
return this.positionX;
}

public int getPositionY()
{
return this.positionY;
}


public boolean contains(int posX, int posY)
{
int distanceX = this.positionX - posX;
int distanceY = this.positionY - posY;

return Math.sqrt((distanceX * distanceX) + (distanceY * distanceY)) <= this.radius;
}
Shadow3097
  • 28
  • 7
  • I have asked such question before, For better insight of code you can check this link. http://stackoverflow.com/questions/22854225/passing-x-y-coordinates-of-drawcircle-to-drawline – Umar Farooq Apr 04 '14 at 13:46