|
马上注册,结交更多好友,享用更多功能^_^
您需要 登录 才可以下载或查看,没有账号?立即注册
x
今天是第27天,对于之前的学习的整理
①扫雷
1.规则:用户点击第i个按钮,如果该位置没有雷,则显示该位置的周围(左右 上下 左上 右上 左下 右下)雷的个数
2.例如:21--->(2,3)
2=21/9 取整
3=21%9 取模
一般公式:m= i/N n= i%N i = m * N + n
3.如果某个数是(m,n)
上:(m-1,n)
下:(m+1,n)
左: (m,n-1)
右: (m,n+1)
右下 row<=N-2
4.代码
package SaoLeiFrame;
import java.awt.Color;
import java.awt.GridLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.util.Random;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JOptionPane;
//简单扫雷游戏
public class SaoleiFrame extends JFrame implements ActionListener {
final int N = 9;// 格子的行列数
final int M = 10;// 雷的个数
// 定义一个数组,用于存放N*N个按钮
JButton[] btns = new JButton[N * N];
// 定义一个数组,用于存放N*N个位置的状态,0-无雷,1-有雷
int[] pos = new int[N * N];
// 定义界面初始化方法
public void Ini() {
setSize(400, 400);
setTitle("我的山寨扫雷= =");
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
// 生成N*N个按钮,放到屏幕
// 设置屏幕布局为网格布局
setLayout(new GridLayout(N, N));
for (int i = 0; i < N * N; i++) {
// 创建第i个按钮
btns[i] = new JButton();
btns[i].setBackground(Color.green);
// 放置到屏幕上
add(btns[i]);
// 设置按钮的监视器
btns[i].addActionListener(this);
} // end for
// 随机生成10个雷
Random rd = new Random();
for (int i = 0; i < M; i++) {
while(true){
int x = rd.nextInt(N * N);// !!随机生成一个位置
//判断x 在前面的i-1次中是否出现过
//检测x在前面是否出现过
if(pos[x]==0)
{ pos[x] = 1;
break;
}
}
// 设置该位置的状态为 1
}
}
// 显示雷的分布情况
// showLeiPos();
// end Ini
// 显示雷的分布情况
public void showLeiPos() {
for (int i = 0; i < N * N; i++) {
if (pos[i] == 1) // 判断第i个位置是否有雷
btns[i].setBackground(Color.red);
}
}
// 编写main方法,作为程序运行入库
public static void main(String[] args) {
SaoleiFrame f1 = new SaoleiFrame();
f1.Ini();
f1.setVisible(true);
}
// 重写按钮点击事件的处理方法
@Override
public void actionPerformed(ActionEvent e) {
// 区分第几个按钮被点击
for (int i = 0; i < N * N; i++) {
if (e.getSource() == btns[i])// 第i个被点击
{
if (pos[i] == 1)// 判断第i个位置是否有雷
{
JOptionPane.showMessageDialog(null, "恭喜你被炸死了!哈哈哈");
showLeiPos();// 显示雷的位置
} else {
btns[i].setBackground(Color.white);
// 提示该位置雷的数量
showAroundLeiNumber(i);
checkWinner();//判断是否扫雷成功
}
} // end if
} // end for
}// end actionPerformed
// 定义显示第i个位置周围雷的个数
void showAroundLeiNumber(int i) {
// 1.计算出第i个按钮在屏幕上网格的行号和列号
int row = i / N;
int col = i % N;
// 定义雷的个数
int num = 0;
// 3.以该位置 ( row,col )为中心,判断周围8个位置雷的个数
// 3.1 判断上方位置
if (row > 0) {
//计算正上方的行列号
int m = row - 1;
int n = col;
// 计算在数组中的位置
int k =m*N+n;
//判断该位置是否有雷
if(pos[k]==1)
num++;
else btns[k].setBackground(Color.white);
}
//判断下方位置
if(row<N-1){
//计算正下方的行列号
int m = row +1;
int n = col;
// 计算在数组中的位置
int k =m*N+n;
//判断该位置是否有雷
if(pos[k]==1)
num++;
else btns[k].setBackground(Color.white);
}
//判断正左方位置
if(col>0){
//计算正左方的行列号
int m = row ;
int n = col-1;
// 计算在数组中的位置
int k =m*N+n;
//判断该位置是否有雷
if(pos[k]==1)
num++;
else btns[k].setBackground(Color.white);
}
//判断正右方位置
if(col<N-1){
//计算正右方的行列号
int m = row ;
int n = col+1;
// 计算在数组中的位置
int k =m*N+n;
//判断该位置是否有雷
if(pos[k]==1)
num++;
else btns[k].setBackground(Color.white);
}
//判断左上方位置
if(row>0&&col>0){
//计算左上方的行列号
int m = row-1 ;
int n = col-1;
// 计算在数组中的位置
int k =m*N+n;
//判断该位置是否有雷
if(pos[k]==1)
num++;
else btns[k].setBackground(Color.white);
}
//判断左下方位置
if(row<N-1&& col>0){
//计算左下方的行列号
int m = row+1 ;
int n = col-1;
// 计算在数组中的位置
int k =m*N+n;
//判断该位置是否有雷
if(pos[k]==1)
num++;
else btns[k].setBackground(Color.white);
}
//判断右上方位置
if(row>0&&col<N-1){
//计算右上方的行列号
int m = row -1;
int n = col+1;
// 计算在数组中的位置
int k =m*N+n;
//判断该位置是否有雷
if(pos[k]==1)
num++;
else btns[k].setBackground(Color.white);
}
//判断右下方位置
if(row<N-1&&col<N-1){
//计算右下方的行列号
int m = row +1;
int n = col+1;
// 计算在数组中的位置
int k =m*N+n;
//判断该位置是否有雷
if(pos[k]==1)
num++;
else btns[k].setBackground(Color.white);
}
if(num>0)
btns[i].setText(""+num);
}
//判断是否扫雷成功的方法checkWinner
public void checkWinner(){
//判断屏幕上,背景为白色的按钮的个数是否为N*N-m
int blankNum=0;
for(int i=0;i<N*N;i++){
if( btns[i].getBackground()==Color.white)
blankNum++;
}
if(blankNum==N*N-M){
JOptionPane.showMessageDialog(null,"恭喜您!扫雷成功哈哈哈哈哈哈");
showLeiPos();
}
}//end checkWinner
}
②简单打字测试程序
1.规则:在给定的时间内,界面上每隔特定的时间出现一个字符
用户在输入框中输入所看到的字符,如果输入正确,则分数+1
最后根据用户所得的分数,时间终止后,根据得分给予其评价
2.步骤:
a.创建工程
WorldExam
b.创建类
WorldExamFrame
c.排列: 边框布局 流式布局 网格布局(m X n)
复杂界面的排列---综合运用多种布局方法
整体采用一个布局,将屏幕分成若干个部分,在某个局部
则采用其他的布局
Java提供一个JPanel的容器组件,用于放置小的界面元素
d.创建线程任务类TaskOfCreateWord
3.代码import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Font;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.util.Random;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JOptionPane;
import javax.swing.JPanel;
import javax.swing.JTextField;
//打字工具界面类
public class WordExamFrame extends JFrame implements ActionListener {
// 定义随机产生的候选字符数组
final char[] rndChars = { 'h', 'i', 'j', 'k', 'l', 'm', 'n', 'o', 'p', 'q', 'r', 'a', 'b', 'c', 'd', 'e', 'f', 'g',
'!', '#', '@', 's', 't', 'v', 'u', 'w', 'x', 'y', 'z' };
// 定义存放用户的分数
int score = 0;
// 定义总时间
int totalTime = 60 * 2;
//定义是否为新产生的字符,控制重复输入累加的问题
boolean isNew=false;
// 定义界面上的各种界面元素
JButton btnBegin = new JButton("开始");
JButton btnClose = new JButton("关闭");
JLabel lblScore = new JLabel("得分:");
JLabel lblWord = new JLabel("等待产生字符..");
JLabel lblTime = new JLabel("倒计时:");
JTextField tfdWord = new JTextField(20);
// 定义界面初始化方法initial(init)
public void init() {
setTitle("打字测试工具---测试你 是否是打字高手!");
setSize(400, 300);
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
// 将上面定义的六个界面元素加入到窗口中
// 1.将整个窗口采用BorderLayout布局
setLayout(new BorderLayout());
// 2.顶部部分
// 2.1创建顶部托盘
JPanel pTop = new JPanel();
// 2.2将顶部的界面元素,放入到顶部托盘上
pTop.add(btnBegin);
pTop.add(btnClose);
pTop.add(lblScore);
pTop.setBackground(Color.pink);
// 2.3将顶部托盘,放置到界面的顶部(North)
add(pTop, BorderLayout.NORTH);
// 3.中间部分
add(lblWord, BorderLayout.CENTER);
// 4.底部部分
JPanel pBottom = new JPanel();
pBottom.add(lblTime);
pBottom.add(tfdWord);
pBottom.setBackground(Color.green);
add(pBottom, BorderLayout.SOUTH);
// 设置字体
lblWord.setFont(new Font(("楷体"), 1, 50));
// 设置文字水平居中
lblWord.setHorizontalAlignment(JLabel.CENTER);
}
// 定义一个构造方法 不能加返回值
public WordExamFrame() {
// 窗口初始化
init();
// 设置对各种事件的监听
// 2.1对输入框的回车事件实行监听
tfdWord.addActionListener(this);
//2.2 对开始按钮进行监听
btnBegin.addActionListener(this);
//2.3对关闭按钮进行监听
btnClose.addActionListener(this);
}
// 定义一个产生中间字符的线程类 TaskOfCreateWord
class TaskOfCreateWord extends Thread {
@Override
public void run() {
Random rd = new Random();
while (totalTime > 0) {
// 随机从候选数组中产生一个位置
int index = rd.nextInt(rndChars.length);
String x = "" + rndChars[index];// 取出该位置的字符
// String x=""+rd.nextInt(10);
lblWord.setText(x);// 显示在提示框中
isNew=true;//设置一个新产生的字符标志!!!!!
// 任务休眠一秒
try {
sleep(1000 * 2);
} catch (Exception e) {
e.printStackTrace();
}
}
}// end run
}// end class
// 定义一个倒计时任务线程TaskOfCountTime
class TaskOfCountTime extends Thread {
@Override
public void run() {
while (totalTime > 0) {
try {
sleep(1000 * 1);
} catch (Exception e) {}
totalTime--;// 时间倒计时计数器-1
lblTime.setText("倒计时:" + totalTime);
} // end while
JOptionPane.showMessageDialog(null, "本次测试结束!");
} // end run
}// end class
// 定义main
public static void main(String[] args) {
new WordExamFrame().setVisible(true);
}
// 重写事件处理方法
@Override
public void actionPerformed(ActionEvent e) {
// 区分发生事件的事件源
if (e.getSource() == tfdWord)// 用户在输入框里按回车
{
// 判断用户的输入和系统产生的字符是否一致
String s1 = tfdWord.getText();
String s2 = lblWord.getText();
if (s1.equals(s2)) {
//判断是否为新产生的字符
if(isNew==true){
score++;
lblScore.setText("得分:" + score);
isNew=false;//设置该字符已经处理过
}
}
// 清空输入框的内容
tfdWord.setText("");
}//end if
else if(e.getSource()==btnBegin){ //开始按钮被点击
totalTime=2*60;
score=0;
// 创建产生字符的线程任务并启动
TaskOfCreateWord t1 = new TaskOfCreateWord();
t1.start();
// 创建倒计时线程任务并启动
TaskOfCountTime t2 = new TaskOfCountTime();
t2.start();
//设置开始按钮不可用
btnBegin.setEnabled(false);
}
else if(e.getSource()==btnClose){ //停止按钮
totalTime=0;
//设置开始按钮可用
btnBegin.setEnabled(true);
}
}// end actionPerformed
}
|
|