分享
 
 
 

Java游戏编程分析--棋子的拖动

王朝java/jsp·作者佚名  2008-05-31
窄屏简体版  字體: |||超大  

在棋盘的两个方格之间拖动棋子

摘要

编写一个跳棋游戏会碰到许多挑战,在棋盘上拖动棋子就是其中之一,本期的Java Fun and Games讨论了这个方面,并着重介绍了如何消除拖动棋子时产生的屏幕闪烁。

你有没有想过要编写一个跳棋游戏——可以是双人对战,也可以是人机对战?编写一个跳棋游戏会碰到许多挑战,在棋盘上把棋子从一个方格拖动到另外一个方格就是其中之一。本期的Java Fun and Games通过一个名为CheckerDrag的applet演示了棋子的拖动。

CheckerDrag applet在屏幕上显示了一个棋盘和一个棋子,你可以在棋盘的边界内任意拖动棋子。CheckerDrag不考虑棋子会落在哪里——也许是在不同颜色的格子上,在两个格子之间,或者是离开几个格子远。该程序的目的是演示如何拖动棋子。表1展示了applet的源代码:

表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.

// 棋子的尺寸 – 方格尺寸的3/4

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.

// 拖动标记 --当用户在棋子上按下鼠标按键时设为true,

// 释放鼠标按键时设为false

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.

// applet绘图区域的宽度

int width;

// Height of applet drawing area.

// applet绘图区域的高度

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.

// 获取applet绘图区域的尺寸

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.

// 向applet添加一个用来监听鼠标按键的按下和释放事件的鼠标监听器

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).

// 在按键时假如鼠标位于可拖动的棋子上方

// (也就是contains (x, y)返回true),则保存当前

// 鼠标坐标与棋子的原点之间的距离(始终为正值)并且

// 将拖动标志设为true(用来表明正处在拖动过程中)

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.

// 假如(x, y)仍处于棋子范围内则返回true

// CHECKERDIM / 2为半径

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.

// 当鼠标按键被释放时,假如inDrag已经为true,

// 则将其置为false(用来表明不在拖动过程中)

if (inDrag)

inDrag = false;

}

});

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

// for mouse drag events.

//向applet添加一个用来监听鼠标拖动事件的鼠标运动监听器

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).

// 假如棋子(至少是棋子的一部分)没有被

// 移出棋盘,则将之前计算的原点

// (tmpox, tmpoy)赋值给永久性的原点(ox, oy),

// 并且刷新显示区域(此时的棋子已经位于新坐标上)

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.

// AWT调用了update()方法来响应拖动棋子时所调用的repaint()方法。

 
 
 
免责声明:本文为网络用户发布,其观点仅代表作者个人观点,与本站无关,本站仅提供信息存储服务。文中陈述内容未经本站证实,其真实性、完整性、及时性本站不作任何保证或承诺,请读者仅作参考,并请自行核实相关内容。
2023年上半年GDP全球前十五强
 百态   2023-10-24
美众议院议长启动对拜登的弹劾调查
 百态   2023-09-13
上海、济南、武汉等多地出现不明坠落物
 探索   2023-09-06
印度或要将国名改为“巴拉特”
 百态   2023-09-06
男子为女友送行,买票不登机被捕
 百态   2023-08-20
手机地震预警功能怎么开?
 干货   2023-08-06
女子4年卖2套房花700多万做美容:不但没变美脸,面部还出现变形
 百态   2023-08-04
住户一楼被水淹 还冲来8头猪
 百态   2023-07-31
女子体内爬出大量瓜子状活虫
 百态   2023-07-25
地球连续35年收到神秘规律性信号,网友:不要回答!
 探索   2023-07-21
全球镓价格本周大涨27%
 探索   2023-07-09
钱都流向了那些不缺钱的人,苦都留给了能吃苦的人
 探索   2023-07-02
倩女手游刀客魅者强控制(强混乱强眩晕强睡眠)和对应控制抗性的关系
 百态   2020-08-20
美国5月9日最新疫情:美国确诊人数突破131万
 百态   2020-05-09
荷兰政府宣布将集体辞职
 干货   2020-04-30
倩女幽魂手游师徒任务情义春秋猜成语答案逍遥观:鹏程万里
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案神机营:射石饮羽
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案昆仑山:拔刀相助
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案天工阁:鬼斧神工
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案丝路古道:单枪匹马
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案镇郊荒野:与虎谋皮
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案镇郊荒野:李代桃僵
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案镇郊荒野:指鹿为马
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案金陵:小鸟依人
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案金陵:千金买邻
 干货   2019-11-12
 
推荐阅读
 
 
 
>>返回首頁<<
 
靜靜地坐在廢墟上,四周的荒凉一望無際,忽然覺得,淒涼也很美
© 2005- 王朝網路 版權所有