السلام عليكم ورحمة الله وبركاته، اخوتي الكرام احتاج لمساعدتكم في اتمام اللعبة، لم اعتد بعد على البرمجة بجافا، ومطلوب مني إضافة توقيت(Timer) وكذلك امكانية حفظ (Save) للعبة مع العلم انه عندما يتم حفظها يمكن إتمامها في وقت لاحق.
وجزاكم الله عني خيرا.
السلام عليكم ورحمة الله وبركاته.
اريد من فضلكم حفظ قطع اللعبة وكذلك اماكنها على الشاشة حتى يتسنى فتحها تانية وفي نفس المواقع التي كانت تتواجد بها.
شكرا لكم.
// ### Should Pieces be implemented as BufferedImages backed by Rasters,
// rather than images backed by MemoryImageSources?
// ### Puzzle feature: time yourself!
// ### Classic piece edges are problematic. First of all, the corners are
// weird. Secondly, the edges are probably too close together. This is
// causing the bevels to overlap very slightly, so they don't look quite
// right.
/**
* A single piece of a jigsaw puzzle. Each piece knows the portion of the
* image it contains, how its edges are to be drawn, and what its
* neighboring pieces are.
*
* <p> When two or more Pieces are put together, the result is another
* Piece object, a MultiPiece.
*
* @see MultiPiece
*/
public class Piece
{
// Class constants ------------------------------------------------------
/** A Piece must be within this many pixels of "perfect" to be considered
* close. */
public static final int posClose = 7;
/** A Piece must be within this many degrees of rotation from another to
* be considered aligned to it. */
public static final int rotClose = 5;
// Constructor and fields -----------------------------------------------
/** Creates a new Piece. No initial rotation is done. (This is needed
* by MultiPiece, which needs to set its subpieces before rotating.)
* @param data image data
* @param imageX X position of image relative to entire puzzle
* @param imageY Y position of image relative to entire puzzle
* @param imageWidth width of original image
* @param imageHeight height of original image
* @param totalWidth the width of the entire picture
* @param totalHeight the height of the entire picture
*/
protected Piece(
int[] data,
int imageX, int imageY,
int imageWidth, int imageHeight,
int totalWidth, int totalHeight)
{
neighbors = new HashSet();
setImageData (data, imageWidth, imageHeight);
setImagePosition (imageX, imageY);
this.totalWidth = totalWidth;
this.totalHeight = totalHeight;
}
/** Creates a new Piece.
* @param data image data
* @param imageX X position of image relative to entire puzzle
* @param imageY Y position of image relative to entire puzzle
* @param imageWidth width of original image
* @param imageHeight height of original image
* @param totalWidth the width of the entire picture
* @param totalHeight the height of the entire picture
* @param rotation initial rotation
*/
public Piece(
int[] data,
int imageX, int imageY,
int imageWidth, int imageHeight,
int totalWidth, int totalHeight,
int rotation)
{
this (data, imageX, imageY, imageWidth, imageHeight,
totalWidth, totalHeight);
forceSetRotation (rotation);
}
// Location in the image.
int imageX, imageY;
// Size of the entire image.
int totalWidth, totalHeight;
// Location in the image adjusted by current rotation.
int rotatedX, rotatedY;
/** Pieces considered to be neighbors to this one. They are the only
* ones that can be fitted to it.
*/
protected Set neighbors;
/** Original image size and data. */
protected int origWidth, origHeight;
int[] origData;
/** Current size and data, taking rotation into account. */
protected int curWidth, curHeight;
int[] curData;
// Location in the puzzle panel.
int puzzleX, puzzleY;
// Image for this Piece. We're going to now try making this null for
// non-atomic pieces.
Image image;
// This is measured in integer degrees, 0-359. 0 is unrotated. 90 is 90
// degrees clockwise, etc.
int rotation;
// Accessors ------------------------------------------------------------
// ### This should be done in the constructor...
/** Sets this Piece's upper-left position relative to the upper-left
* position of the entire image. This position can be arbitrary, but for
* efficiency, it should be the upper-left corner of the smallest
* rectangle that contains all of this Piece's image data. This method
* should typically be called when the Piece is first created, and never
* again.
*/
protected void setImagePosition (int x, int y)
{
this.imageX = x;
this.imageY = y;
}
/** Returns this Piece's current rotation. The rotation is given in
* integer degrees clockwise, and will always be between 0 and 359
* inclusive.
*/
public int getRotation() { return rotation; }
/** Sets this Piece's current rotation. The rotation is given in integer
* degrees clockwise, and should always be between 0 and 359 inclusive.
* If the new rotation is different, this Piece's image data will be
* recomputed.
* @throws IllegalArgumentException if rotation is not in [0,359]
*/
public void setRotation (int rot)
{
if (rot == rotation) return;
forceSetRotation (rot);
}
/** Sets this Piece's current rotation. Unlike setRotation(), this
* method forces a recompute of the image.
* @throws IllegalArgumentException if rotation is not in [0,359]
*/
protected void forceSetRotation (int rot)
{
if ((rot < 0) || (rot > 359)) throw new IllegalArgumentException
("invalid rotation: "+rot);
// For now, allow only 0, 90, 180, 270.
if (rot % 90 != 0) {
int newRot = rot / 90;
JigsawFrame.verbose("unsupported rotation "+rot
+"; using "+newRot+" instead");
rot = newRot;
}
rotation = rot;
recomputeImageData();
if (image != null) image.flush();
image = Toolkit.getDefaultToolkit().createImage (
new MemoryImageSource (curWidth,curHeight, curData, 0, curWidth));
}
/** Sets this Piece's upper-left position relative to the upper-left
* position of the JigsawPuzzle.
*/
public void setPuzzlePosition (int x, int y)
{
this.puzzleX = x;
this.puzzleY = y;
}
/** Returns this Piece's current height in pixels. This is the height of
* the smallest rectangle containing all of this Piece's image data at
* its current rotation.
*/
public int getCurrentHeight() { return curHeight; }
/** Returns this Piece's current width in pixels. This is the width of
* the smallest rectangle containing all of this Piece's image data at
* its current rotation.
*/
public int getCurrentWidth() { return curWidth; }
/** Returns the width of the entire picture. */
public int getTotalWidth() { return totalWidth; }
/** Returns the height of the entire picture. */
public int getTotalHeight() { return totalHeight; }
/** Returns this Piece's image height in pixels. This is the height of
* the smallest rectangle containing all of this Piece's image data in
* its original orientation.
*/
public int getImageHeight() { return origHeight; }
/** Returns this Piece's image width in pixels. This is the width of the
* smallest rectangle containing all of this Piece's image data in its
* original orientation.
*/
public int getImageWidth() { return origWidth; }
/** Returns this Piece's X position in the original image. */
public int getImageX() { return imageX; }
/** Returns this Piece's Y position in the original image. */
public int getImageY() { return imageY; }
/** Returns this Piece's X position in the original image, modified by
* its current rotation. The origin is the center of rotation. */
public int getRotatedX() { return rotatedX; }
/** Returns this Piece's Y position in the original image, modified by
* its current rotation. The origin is the center of rotation. */
public int getRotatedY() { return rotatedY; }
/** Returns this Piece's X position in the original image, modified by
* the given rotation. */
public int getRotatedX(int rotation) { return rotatedX; }
/** Returns this Piece's Y position in the original image, modified by
* the given rotation. */
public int getRotatedY(int rotation) { return rotatedY; }
/** Returns this Piece's X position in the puzzle. */
public int getPuzzleX() { return puzzleX; }
/** Returns this Piece's Y position in the puzzle. */
public int getPuzzleY() { return puzzleY; }
/** Returns this Piece's current image. This will be the Piece's portion
* of the original image, rotated by this Piece's current rotation.
*/
public Image getImage () { return image; }
/** Adds a Piece to this Piece's set of neighbors.
* @throws NullPointerException if neighbor is null
*/
public void addNeighbor (Piece neighbor)
{
if (neighbor == null) throw new NullPointerException ("null neighbor");
neighbors.add (neighbor);
}
/** Removes the given Piece from this Piece's set of neighbors.
*/
public void removeNeighbor (Piece neighbor)
{ neighbors.remove (neighbor); }
/** Moves this Piece to the given location, relative to the puzzle
* panel's upper-left corner.
*/
public void moveTo (int x, int y)
{ setPuzzlePosition (x, y); }
public String toString()
{
return "Piece[iPos=("+imageX+","+imageY+"),"
+"iSiz="+origWidth+"x"+origHeight+","
+"rot="+rotation+","
+"rPos=("+rotatedX+","+rotatedY+"),"
+"pPos=("+puzzleX+","+puzzleY+")]";
}
/** Draws this Piece in the given Graphics object. The current image
* will be drawn, at this Piece's current puzzle position. */
protected void draw (Graphics g)
{
Image img = getImage();
if (img != null)
g.drawImage (img, getPuzzleX(), getPuzzleY(), null);
}
/** Returns whether this Piece currently contains the given point,
* relative to the puzzle panel's upper-left corner.
*/
public boolean contains (int x, int y)
{
int puzX = getPuzzleX();
int puzY = getPuzzleY();
int w = getCurrentWidth();
int h = getCurrentHeight();
return
(puzX <= x) && (x <= (puzX+w-1)) &&
(puzY <= y) && (y <= (puzY+h-1)) &&
(getAlpha(x-puzX, y-puzY) != 0);
}
/** Returns the alpha (transparency) value at the given coordinates in
* the current image data.
*/
protected int getAlpha (int x, int y)
{
int pixel = curData[y*curWidth + x];
return (pixel >> 24) & 0xff;
}
/** Returns whether this piece is located and oriented close enough to
* the given Piece to be fitted.
*/
public boolean isCloseTo (Piece piece)
{
// System.out.println ("isCloseTo this:"+this+" piece:"+piece);
// Don't even bother if they're not aligned.
int rot = getRotation();
int rotD = Math.abs (piece.getRotation() - getRotation());
rotD = Math.min (rotD, 360-rotD);
if (rotD > rotClose) return false;
JigsawFrame.verbose("aligned...");
int puzXD = getPuzzleX() - piece.getPuzzleX();
int puzYD = getPuzzleY() - piece.getPuzzleY();
int rotXD = getRotatedX() - piece.getRotatedX(rot);
int rotYD = getRotatedY() - piece.getRotatedY(rot);
JigsawFrame.verbose(puzXD + ":" + puzYD + ":" + rotXD + ":" + rotYD);
return
(Math.abs(puzXD-rotXD) <= posClose) &&
(Math.abs(puzYD-rotYD) <= posClose) ;
}
// ### This should be built into the constructor, I think.
/** Sets the image data and size for this Piece. */
protected void setImageData (int[] data, int width, int height)
{
this.curWidth = this.origWidth = width;
this.curHeight = this.origHeight = height;
origData = data;
// forceSetRotation (rotation);
}
// Joining pieces -------------------------------------------------------
/** Checks whether any of this Piece's neighbors are located and oriented
* close enough to be joined to this one.
* @return an array of Pieces, or null if no neighbors were close enough;
* if the array is non-null, the first Piece will be the new one;
* subsequent Pieces will be the ones it was built from
*/
public Piece[] join ()
{
ArrayList close = new ArrayList();
Iterator iter = neighbors.iterator();
while (iter.hasNext()) {
Piece piece = (Piece) iter.next();
if (piece.isCloseTo (this)) close.add (piece);
}
// System.out.println ("close: "+close.size());
// for (int i = 0; i < close.size(); i++)
// System.out.println (close.get(i));
if (close.size() == 0)
return null;
// We can't just return the new MultiPiece, because the JigsawPuzzle
// needs to know what pieces the new one was formed from that are
// currently in its list. These might include other MultiPieces, which
// wouldn't be in the new Piece's subpiece list.
Piece newPiece = MultiPiece.join (this, close);
Piece[] ret = new Piece[close.size()+2];
ret[0] = newPiece;
ret[1] = this;
this.image.flush();
for (int i = 0; i < close.size(); i++) {
Piece piece = (Piece) close.get(i);
ret[i+2] = piece;
piece.image.flush();
}
System.gc();
return ret;
}
// 4-way rotation -------------------------------------------------------
/**
* Sets this Piece's rotated position and size, based on its current
* rotation. The entire puzzle is rotated about the origin, and then
* translated so that its new upper left corner is at the origin. Each
* piece's rotated position is then defined by its new upper left corner
* in the rotated puzzle.
*/
protected void setRotatedPosition()
{
int rot = getRotation();
switch (rot) {
case 0: rotatedX = imageX; rotatedY = imageY;
curWidth = origWidth; curHeight = origHeight; break;
case 90:
rotatedX = totalHeight-imageY-origHeight;
rotatedY = imageX;
curWidth = origHeight; curHeight = origWidth; break;
case 180:
rotatedX = totalWidth -imageX-origWidth;
rotatedY = totalHeight-imageY-origHeight;
curWidth = origWidth; curHeight = origHeight; break;
case 270:
rotatedX = imageY;
rotatedY = totalWidth -imageX-origWidth;
curWidth = origHeight; curHeight = origWidth; break;
default:
JigsawFrame.verbose("sRotPos() can't handle rotation: "+rot);
}
}
/** Recomputes this Piece's current image data and size from its original
* image data and rotation.
*/
protected void recomputeImageData()
{
setRotatedPosition();
if (rotation == 0) {
curData = (int[]) origData.clone();
} else if (rotation == 90) {
curData = new int[origData.length];
for (int i = 0; i < curWidth; i++)
for (int j = 0; j < curHeight; j++)
try {
curData[j*curWidth+i] = origData[(origHeight-i-1)*origWidth + j];
} catch (ArrayIndexOutOfBoundsException ex) {
System.out.println ("ArrayIndexOutOfBoundsException");
System.out.println (" olen="+origData.length+" clen="+curData.length);
System.out.println (" i="+i+" j="+j);
System.out.println (" orgW="+origWidth+" orgH="+origHeight);
System.out.println (" curW="+ curWidth+" curH="+ curHeight);
System.out.println(
" cIdx="+ (j*curWidth+i)
+" oIdx="+ ((origWidth-j-1)*origHeight + i));
throw new NullPointerException();
}
} else if (rotation == 180) {
curData = new int[origData.length];
for (int i = 0; i < curWidth; i++)
for (int j = 0; j < curHeight; j++)
curData[j*curWidth+i] =
origData[(origHeight-j-1)*origWidth + (origWidth-i-1)];
} else if (rotation == 270) {
curData = new int[origData.length];
for (int i = 0; i < curWidth; i++)
for (int j = 0; j < curHeight; j++)
curData[j*curWidth+i] = origData[i*origWidth + (origWidth-j-1)];
}
bevel(curData, curWidth, curHeight);
image = Toolkit.getDefaultToolkit().createImage (
new MemoryImageSource (curWidth,curHeight, curData, 0, curWidth));
}هذا الموضوع مغلق.