📄 ballapplet.java
字号:
import java.awt.*;
import java.awt.event.*;
import java.applet.Applet;
public class ballApplet extends Applet implements Runnable {
Dimension d;
Font bFont = new Font("Helvetica", Font.BOLD, 24);
Font sFont = new Font("Helvetica", Font.BOLD, 14);
FontMetrics fmSmall, fmBig;
Graphics goff;
Image img;
Thread mThread;
boolean ingame = false;
int ballx, bally; //球的坐标
int batpos; //球拍的位置x坐标
int batdpos = 0; //球拍的便宜量
int balldx = 0, balldy = 0,dxval;
int iScroe,ballNum; //分数和球的数量
boolean[] showbrick;
int brickNumOfLine; //每行的砖块数
final int bWidth = 5; //border宽度
final int batW = 20; //球拍的宽度
final int ballsize = 5; //球拍的大小
final int batH = 5; //球拍的高度
final int scoreH = 25; //显示分数的相对高度
final int brickW = 15; //砖块的宽度
final int brickH = 8; //砖块的高度
final int space = 1; //砖块间的间隔
final int backcol = 0x102010;//背景色
final int line = 4; //砖块总行数
final int startline = 32;
public void init() {
Graphics g;
d = size();
setBackground(new Color(backcol));
brickNumOfLine = (d.width - 2 * bWidth) / (brickW + space);
d.width = brickNumOfLine * (brickW + space) + (2 * bWidth);
g = getGraphics();
g.setFont(sFont);
fmSmall = g.getFontMetrics();
g.setFont(bFont);
fmBig = g.getFontMetrics();
showbrick = new boolean[brickNumOfLine * line];
GameInit();
}
public void GameInit() {
batpos = (d.width - batW) / 2;
ballx = (d.width - ballsize) / 2;
bally = (d.height - ballsize - scoreH - 2 * bWidth);
iScroe = 0;
ballNum = 3;
dxval = 2;
if (Math.random() < 0.5)
balldx = dxval;
else
balldx = -dxval;
balldy = -dxval;
batdpos = 0;
InitBricks();
}
public void InitBricks() {
int i;
for (i = 0; i < line * brickNumOfLine; i++)
showbrick[i] = true;
}
public boolean keyDown(Event e, int key) {
if (ingame) {
if (key == Event.LEFT)
batdpos = -4;
if (key == Event.RIGHT)
batdpos = 4;
if (key == Event.ESCAPE)
ingame = false;
}
else {
if (key == 's' || key == 'S') {
ingame = true;
GameInit();
}
}
return true;
}
public boolean keyUp(Event e, int key) {
if (key == Event.LEFT || key == Event.RIGHT)
batdpos = 0;
return true;
}
public void paint(Graphics g) {
if (goff == null && d.width > 0 && d.height > 0) {
img = createImage(d.width, d.height);
goff = img.getGraphics();
}
if (goff == null || img == null)
return;
goff.setColor(new Color(backcol));
goff.fillRect(0, 0, d.width, d.height);
if (ingame)
PlayGame();
else
ShowIntroScreen();
g.drawImage(img, 0, 0, this);
}
public void PlayGame() {
MoveBall();
CheckBat();
CheckBricks();
DrawPlayField();
DrawBricks();
ShowScore();
}
public void ShowIntroScreen() {
MoveBall();
CheckBat();
CheckBricks();
BatDummyMove();
DrawPlayField();
DrawBricks();
ShowScore();
goff.setFont(bFont);
goff.setColor(new Color(96, 128, 255));
String s = "弹球游戏";
goff.drawString(s, (d.width - fmBig.stringWidth(s)) / 2,
(d.height - scoreH - bWidth) / 2 - 20);
goff.setFont(sFont);
goff.setColor(new Color(128, 255, 32));
s = "请按下'S'键开始游戏!";
goff.drawString(s, (d.width - fmSmall.stringWidth(s)) / 2,
(d.height - scoreH - bWidth) / 2 + 30);
goff.setColor(new Color(255, 160, 64));
s = "请使用方向键来控制球拍的运动";
goff.drawString(s, (d.width - fmSmall.stringWidth(s)) / 2,
(d.height - scoreH - bWidth) / 2 + 50);
}
public void DrawBricks() {
int i, j;
boolean nobricks = true;
int colorDelta = 255 / (line - 1);
for (j = 0; j < line; j++) {
for (i = 0; i < brickNumOfLine; i++) {
if (showbrick[j * brickNumOfLine + i]) {
nobricks = false;
goff.setColor(new Color(255, j * colorDelta, 255 - j * colorDelta));
goff.fillRect(bWidth + i * (brickW + space),
startline + j * (brickH + space),brickW, brickH);
}
}
}
if (nobricks) {
InitBricks();
if (ingame)
iScroe += 100;
}
}
public void DrawPlayField() {
goff.setColor(Color.white);
goff.fillRect(0, 0, d.width, bWidth);
goff.fillRect(0, 0, bWidth, d.height);
goff.fillRect(d.width - bWidth, 0, bWidth, d.height);
goff.fillRect(0,d.height - bWidth, d.width, bWidth);
goff.fillRect(batpos, d.height - 2 * bWidth - scoreH, batW,batH); // 球拍
goff.fillRect(ballx, bally, ballsize, ballsize); // 球
}
public void ShowScore() {
goff.setFont(sFont);
goff.setColor(Color.white);
goff.drawString("得分: " + iScroe, 40, d.height - 10);
String s = "生命数量: " + ballNum;
goff.drawString(s, d.width - 40 - fmSmall.stringWidth(s), d.height - 10);
}
public void MoveBall() {
ballx += balldx;
bally += balldy;
if (bally <= bWidth) {
balldy = -balldy;
bally = bWidth;
}
if (bally >= (d.height - ballsize - scoreH)) {
if (ingame) {
ballNum--;
if (ballNum <= 0)
ingame = false; //游戏结束
}
ballx = batpos + (batW - ballsize) / 2;
bally = startline + line * (brickH + space);
balldy = dxval;
balldx = 0;
}
if (ballx >= (d.width - bWidth - ballsize)) {
balldx = -balldx;
ballx = d.width - bWidth - ballsize;
}
if (ballx <= bWidth) {
balldx = -balldx;
ballx = bWidth;
}
}
public void BatDummyMove() {
if (ballx < (batpos + 2))
batpos -= 3;
else if (ballx > (batpos + batW - 3))
batpos += 3;
}
public void CheckBat() {
batpos += batdpos;
if (batpos < bWidth)
batpos = bWidth;
else if (batpos > (d.width - bWidth - batW))
batpos = (d.width - bWidth - batW);
if (bally >= (d.height - scoreH - 2 * bWidth - ballsize) &&
bally < (d.height - scoreH - 2 * bWidth) &&
(ballx + ballsize) >= batpos && ballx <= (batpos + batW)) {
bally = d.height - scoreH - ballsize - bWidth * 2;
balldy = -dxval;
balldx = CheckBatBounce(balldx, ballx - batpos);
}
}
public int CheckBatBounce(int dy, int delta) {
int sign;
int stepsize, i = -ballsize, j = 0;
stepsize = (ballsize + batW) / 8;
if (dy > 0)
sign = 1;
else
sign = -1;
while (i < batW && delta > i) {
i += stepsize;
j++;
}
switch (j) {
case 0:
case 1:
return -4;
case 2:
return -3;
case 7:
return 3;
case 3:
case 6:
return sign * 2;
case 4:
case 5:
return sign * 1;
default:
return 4;
}
}
public void CheckBricks() {
int i, j, x, y;
int xspeed = balldx;
if (xspeed < 0)
xspeed = -xspeed;
int ydir = balldy;
if (bally < (startline - ballsize) ||
bally > (startline + line * (space + brickH)))
return;
for (j = 0; j < line; j++) {
for (i = 0; i < brickNumOfLine; i++) {
if (showbrick[j * brickNumOfLine + i]) {
y = startline + j * (space + brickH);
x = bWidth + i * (space + brickW);
if (bally >= (y - ballsize) && bally < (y + brickH) &&
ballx >= (x - ballsize) && ballx < (x + brickW)) {
showbrick[j * brickNumOfLine + i] = false;
if (ingame)
iScroe += (line - j);
// 敲击砖块的地点
if (ballx >= (x - ballsize) && ballx <= (x - ballsize + 3)){
balldx = -xspeed;
}
else if (ballx <= (x + brickW - 1) && ballx >= (x + brickW - 4)){
balldx = xspeed;
}
balldy = -ydir;
}
}
}
}
}
public void run() {
long starttime;
Graphics g = getGraphics();
Thread.currentThread().setPriority(Thread.MAX_PRIORITY);
while (true) {
starttime = System.currentTimeMillis();
try {
paint(g);
starttime += 20;
Thread.sleep(Math.max(0, starttime - System.currentTimeMillis()));
}
catch (InterruptedException e) {
break;
}
}
}
public void start() {
if (mThread == null) {
mThread = new Thread(this);
mThread.start();
}
}
public void stop() {
if (mThread != null) {
mThread.stop();
mThread = null;
}
}
public static void main(String[] args) {
Frame frame = new Frame("弹球游戏");
ballApplet app = new ballApplet();
frame.add("Center", app);
frame.setSize(270, 350);
frame.validate();
frame.setVisible(true);
frame.addWindowListener(new WindowControl(app));
app.init();
app.start();
}
}
class WindowControl extends WindowAdapter {
Applet app;
public WindowControl(Applet app) {
this.app = app;
}
public void windowClosing(WindowEvent e) {
app.stop();
app.destroy();
System.exit(0);
}
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -