Newsletter sign-up
View all newsletters

Enterprise Java Newsletter
Stay up to date on the latest tutorials and Java community news posted on JavaWorld

Sponsored Links

Optimize with a SATA RAID Storage Solution
Range of capacities as low as $1250 per TB. Ideal if you currently rely on servers/disks/JBODs

Checker dragging

Drag a checker from square to square

  • Print
  • Feedback

Have you ever wanted to create a checkers game—perhaps one that involves two human players or a human player versus a computer player? Creating a checkers game presents many challenges. One of these challenges involves dragging a checker from one square to another square on a checkerboard. This Java Fun And Games installment presents a CheckerDrag applet that demonstrates checker dragging.

The CheckerDrag applet displays a checkerboard and a single checker. It lets you drag the checker to any area within the checkerboard's boundaries. CheckerDrag doesn't care where the checker ends up—on a square of the opposite color, between two squares, several squares away from the current square, and so on. The goal is to show you how to drag a checker. Listing 1 presents the applet's source code.

Listing 1. CheckerDrag.java

 // CheckerDrag.java

import java.awt.*; import java.awt.event.*;

public class CheckerDrag extends java.applet.Applet { // Dimension of checkerboard square.

final static int SQUAREDIM = 40;

// Dimension of checkerboard -- includes black outline.

final static int BOARDDIM = 8 * SQUAREDIM + 2;

// Dimension of checker -- 3/4 the dimension of a square.

final static int CHECKERDIM = 3 * SQUAREDIM / 4;

// Square colors are dark green or white.

final static Color darkGreen = new Color (0, 128, 0);

// Dragging flag -- set to true when user presses mouse button over checker // and cleared to false when user releases mouse button.

boolean inDrag = false;

// Left coordinate of checkerboard's upper-left corner.

int boardx;

// Top coordinate of checkerboard's upper-left corner.

int boardy;

// Left coordinate of checker rectangle origin (upper-left corner).

int ox;

// Top coordinate of checker rectangle origin (upper-left corner).

int oy;

// Left displacement between mouse coordinates at time of press and checker // rectangle origin.

int relx;

// Top displacement between mouse coordinates at time of press and checker // rectangle origin.

int rely;

// Width of applet drawing area.

int width;

// Height of applet drawing area.

int height;

// Image buffer.

Image imBuffer;

// Graphics context associated with image buffer.

Graphics imG;

public void init () { // Obtain the size of the applet's drawing area.

width = getSize ().width; height = getSize ().height;

// Create image buffer.

imBuffer = createImage (width, height);

// Retrieve graphics context associated with image buffer.

imG = imBuffer.getGraphics ();

// Initialize checkerboard's origin, so that board is centered.

boardx = (width - BOARDDIM) / 2 + 1; boardy = (height - BOARDDIM) / 2 + 1;

// Initialize checker's rectangle's starting origin so that checker is // centered in the square located in the top row and second column from // the left.

ox = boardx + SQUAREDIM + (SQUAREDIM - CHECKERDIM) / 2 + 1; oy = boardy + (SQUAREDIM - CHECKERDIM) / 2 + 1;

// Attach a mouse listener to the applet. That listener listens for // mouse-button press and mouse-button release events.

addMouseListener (new MouseAdapter () { public void mousePressed (MouseEvent e) { // Obtain mouse coordinates at time of press.

int x = e.getX (); int y = e.getY ();

// If mouse is over draggable checker at time // of press (i.e., contains (x, y) returns // true), save distance between current mouse // coordinates and draggable checker origin // (which will always be positive) and set drag // flag to true (to indicate drag in progress).

if (contains (x, y)) { relx = x - ox; rely = y - oy; inDrag = true; } }

boolean contains (int x, int y) { // Calculate center of draggable checker.

int cox = ox + CHECKERDIM / 2; int coy = oy + CHECKERDIM / 2;

// Return true if (x, y) locates with bounds // of draggable checker. CHECKERDIM / 2 is the // radius.

return (cox - x) * (cox - x) + (coy - y) * (coy - y) < CHECKERDIM / 2 * CHECKERDIM / 2; }

public void mouseReleased (MouseEvent e) { // When mouse is released, clear inDrag (to // indicate no drag in progress) if inDrag is // already set.

if (inDrag) inDrag = false; } });

// Attach a mouse motion listener to the applet. That listener listens // for mouse drag events.

addMouseMotionListener (new MouseMotionAdapter () { public void mouseDragged (MouseEvent e) { if (inDrag) { // Calculate draggable checker's new // origin (the upper-left corner of // the checker rectangle).

int tmpox = e.getX () - relx; int tmpoy = e.getY () - rely;

// If the checker is not being moved // (at least partly) off board, // assign the previously calculated // origin (tmpox, tmpoy) as the // permanent origin (ox, oy), and // redraw the display area (with the // draggable checker at the new // coordinates).

if (tmpox > boardx && tmpoy > boardy && tmpox + CHECKERDIM < boardx + BOARDDIM && tmpoy + CHECKERDIM < boardy + BOARDDIM) { ox = tmpox; oy = tmpoy; repaint (); } } } }); }

public void paint (Graphics g) { // Paint the checkerboard over which the checker will be dragged.

paintCheckerBoard (imG, boardx, boardy);

// Paint the checker that will be dragged.

paintChecker (imG, ox, oy);

// Draw contents of image buffer.

g.drawImage (imBuffer, 0, 0, this); }

void paintChecker (Graphics g, int x, int y) { // Set checker shadow color.

g.setColor (Color.black);

// Paint checker shadow.

g.fillOval (x, y, CHECKERDIM, CHECKERDIM);

// Set checker color.

g.setColor (Color.red);

// Paint checker.

g.fillOval (x, y, CHECKERDIM - CHECKERDIM / 13, CHECKERDIM - CHECKERDIM / 13); }

void paintCheckerBoard (Graphics g, int x, int y) { // Paint checkerboard outline.

g.setColor (Color.black); g.drawRect (x, y, 8 * SQUAREDIM + 1, 8 * SQUAREDIM + 1);

// Paint checkerboard.

for (int row = 0; row < 8; row++) { g.setColor (((row & 1) != 0) ? darkGreen : Color.white);

for (int col = 0; col < 8; col++) { g.fillRect (x + 1 + col * SQUAREDIM, y + 1 + row * SQUAREDIM, SQUAREDIM, SQUAREDIM);

g.setColor ((g.getColor () == darkGreen) ? Color.white : darkGreen); } } }

// The AWT invokes the update() method in response to the repaint() method // calls that are made as a checker is dragged. The default implementation // of this method, which is inherited from the Container class, clears the // applet's drawing area to the background color prior to calling paint(). // This clearing followed by drawing causes flicker. CheckerDrag overrides // update() to prevent the background from being cleared, which eliminates // the flicker.

public void update (Graphics g) { paint (g); } }


Listing 1's state variables and event handlers (responding to mouse-press, mouse-release, and mouse-drag events) collectively describe checker dragging. I won't delve into how those state variables and event handlers interact because a careful study of the source code and its many comments reveals how checker dragging works. However, there is one item that I want to discuss: flicker and its elimination.

  • Print
  • Feedback
What is Tech Briefcase?
TechBriefcase is a new, free service where IT Professionals can Search, Store and Share IT white papers and content like this. Learn more
Bookmark content
Speed up your research efforts with content across the web.
Search and Store
Find the white papers you need. Create folders for any topic.
View Anywhere
Open your briefcase on your iPhone, tablet or desktop. Share with colleagues.
Don't have an account yet?

Resources