import java.applet.Applet;
import java.applet.AudioClip;
import java.awt.Component;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.KeyAdapter;
import java.awt.event.KeyEvent;
import java.util.Random;
import javax.swing.JLabel;
import javax.swing.JOptionPane;//又是导包
public class NewListener extends KeyAdapter implements ActionListener{
private UI ui;// 界面类的对象
private int[][] numbers;// 存数数据的数组
private Random rand=new Random();
private JLabel jl;
private int score=0;
AudioClip audio;
AudioClip audio1;
public NewListener(UI ui, int[][] numbers, JLabel jl) {
this.ui=ui;
this.numbers=numbers;
this.jl=jl;
audio=Applet.newAudioClip(getClass().getResource("click_01.wav"));
audio1=Applet.newAudioClip(getClass().getResource("T-Ara - Number 9.wav"));//2048也是有声音滴~~~~~~这个地方不用new 而是Applet
}
@Override
public void actionPerformed(ActionEvent e) {
// TODO Auto-generated method stub
for (int i=0;i <4;i++) {
for (int j=0;j <4;j++) {
numbers[i][j]=0;
}
}
score=0;// 初始化,保证每次按开始后都能重新计分
audio1.loop();//有背景音乐的2048,你玩过么。。。
int r1=rand.nextInt(4);
int r2=rand.nextInt(4);
int c1=rand.nextInt(4);
int c2=rand.nextInt(4);
while (r1 == r2 &&c1 == c2) {
r2=rand.nextInt(4);
c2=rand.nextInt(4);
}
// 生成2 或 4
int value1=rand.nextInt(2) * 2 + 2;
int value2=rand.nextInt(2) * 2 + 2;
// 把数组存入对应的数组
numbers[r1][c1]=value1;
numbers[r2][c2]=value2;
ui.paint(ui.getGraphics());
}//WAY
// 键盘按下的方法
//这个地方最好用pressed 不要用released不然后面会有bug。。。如果用release的话,弹出的失败或胜利框,是不能用回车键确定的~pressd则不会出现这种情况
public void keyPressed(KeyEvent e) {
int count=0;// 计数器
int numberCount=0;//用来统计整个界面上的格子是否已占满
int numberCount2=0;//用来统计相邻格子上的数字是否相同
switch (e.getKeyCode()) {
//37是指键盘上的向左键对应到keyCode上是37;
case 37:// 左
for (int i=0;i <4;i++) {
for (int j=0;j <4;j++) {
if (numbers[i][j] != 0) {
int temp=numbers[i][j];
int c=j - 1;
while (c >= 0 &&numbers[i][c] == 0) {
numbers[i][c]=temp;
numbers[i][c + 1]=0;
c--;
count++;
}
}
}
}
for (int i=0;i <4;i++) {
for (int j=0;j <4;j++) {
/*当相邻两个相等的时候,加一次,并且数组的值不能为零:bug之二!!*/
if (j + 1 <4 &&numbers[i][j] == numbers[i][j + 1]&&(numbers[i][j] != 0 || numbers[i][j + 1] != 0)) {
numbers[i][j]=numbers[i][j] + numbers[i][j + 1];
numbers[i][j + 1]=0;
count++;
score += numbers[i][j];//计分~~
if (numbers[i][j] == 2048) {
}
}
}
}
//相加之后如果后面还有空 就再移动一次~
for (int i=0;i <4;i++) {
for (int j=0;j <4;j++) {
if (numbers[i][j] != 0) {
int temp=numbers[i][j];
int c=j - 1;
while (c >= 0 &&numbers[i][c] == 0) {
numbers[i][c]=temp;
numbers[i][c + 1]=0;
c--;
count++;
}
}
}
}
audio.play();//移动时会发出声音
break;
}
/*………………………向上、下、右的方法与向左类似,注意数组不能越界,
case38: case39: case40:………………………………
游戏失败的判断~~~当16个格子都有值,且相邻格子上的值不能相等,注意遍历时候越界问题,以及计数器所计的值到底是表示什么,(这个困扰了小编两个下午,真闹心,不过想通了~~~) */
case38:
case39:
case40:
for (int i=0;i <3;i++) {
for (int j=0;j <3;j++) {
if (numbers[i][j] == numbers[i][j + 1] &&numbers[i][j] != 0) {
numberCount2++;
}
if (numbers[i][j] == numbers[i + 1][j] &&numbers[i][j] != 0) {
numberCount2++;
}
if (numbers[3][j] == numbers[3][j + 1] &&numbers[3][j] != 0) {
numberCount2++;
}
if (numbers[i][3] == numbers[i + 1][3] &&numbers[i][3] != 0) {
numberCount2++;
}
}
}
for (int i=0;i <4;i++) {
for (int j=0;j <4;j++) {
if (numbers[i][j] != 0) {
numberCount++;
}
}
}
//进入循环的条件!
if (count >0) {
jl.setText("score:" + score);
int r1=rand.nextInt(4);
int c1=rand.nextInt(4);
while (numbers[r1][c1] != 0) {
r1=rand.nextInt(4);
c1=rand.nextInt(4);
}
// if(numbers[r1][c1]!=0){
int value1=rand.nextInt(2) * 2 + 2;
numbers[r1][c1]=value1;
ui.paint(( ui).getGraphics());
}
//失败的输出语句:
if (numberCount == 16 &&numberCount2 == 0) {
JOptionPane.showMessageDialog(ui, "思密达,你输了~~~");
}
}
}
这里是UI类
package Game2048;
import java.awt.Color;
import java.awt.Dimension;
import java.awt.Font;
import java.awt.Graphics;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JLabel;
public class UI extends JFrame{
int[][] numbers=new int[4][4];
public static void main(String[] args){
UI ui=new UI();
ui.InUI();
}
public void InUI() {
this.setTitle("2048");
this.setLocation(200,200);
this.setSize(270, 340);
this.setLayout(null);
JButton jb=new JButton();
jb.setText("开始游戏");
jb.setFocusable(false);
jb.setBounds(10,10,100,30);
jb.setForeground(new Color(3,82,212));
jb.setFont(new Font("宋体",Font.BOLD,15));
this.add(jb);
JLabel jl=new JLabel("score");
jl.setBounds(160,10,100,30);
jl.setForeground(new Color(3,82,212));
this.add(jl);
this.setDefaultCloseOperation(3);
this.setResizable(false);
this.setVisible(true);
NewListener nl=new NewListener(this,numbers,jl);
jb.addActionListener(nl);//动作监听器
this.addKeyListener(nl);//键盘监听器
}
/*重写方法体*/
public void paint(Graphics g){
super.paint(g);
g.setColor(new Color(255,170,37));
g.fillRoundRect(10, 80, 250,250, 15, 15);//绘制大矩形框
g.setColor(new Color(234,223,223));
for (int i=0;i<4;i++){
for(int j=0;j<4;j++){
g.fillRoundRect(20 +i*60,90+j*60,50,50,15,15);
}
}
// 调整数字的位置,注意横纵坐标~~~~~~是反的哦!!!bug之一!!!
for (int i=0;i <4;i++) {
for (int j=0;j <4;j++) {
if (numbers[i][j] != 0) {
if (numbers[i][j] == 2 || numbers[i][j] == 4) {
g.setColor(Color.red);
g.fillRoundRect(20 + j * 60, 90 + i * 60, 50, 50, 15,15);
g.setColor(Color.black);
g.setFont(new Font("宋体", Font.BOLD, 30));
g.drawString(numbers[i][j] + "", 20 + j * 60 + 17,90 + i * 60 + 33);
}
else if (numbers[i][j] == 16 || numbers[i][j] == 32|| numbers[i][j] == 64) {
g.setColor(Color.CYAN);
g.fillRoundRect(20 + j * 60, 90 + i * 60, 50, 50, 15,15);
g.setColor(Color.BLUE);
g.setFont(new Font("宋体", Font.BOLD, 30));
g.drawString(numbers[i][j] + "", 20 + j * 60 + 8,90 + i * 60 + 33);
}
else if (numbers[i][j] == 128 || numbers[i][j] == 256|| numbers[i][j] == 512) {
g.setColor(Color.white);
g.fillRoundRect(20 + j * 60, 90 + i * 60, 50, 50, 15,15);
g.setColor(Color.red);
g.setFont(new Font("宋体", Font.BOLD, 20));
g.drawString(numbers[i][j] + "", 20 + j * 60 + 10,90 + i * 60 + 33);
}
else if (numbers[i][j] == 1024 || numbers[i][j] == 2048|| numbers[i][j] == 4096) {
g.setColor(Color.blue);
g.fillRoundRect(20 + j * 60, 90 + i * 60, 50, 50, 15,15);
g.setColor(Color.green);
g.setFont(new Font("宋体", Font.BOLD, 20));
g.drawString(numbers[i][j] + "", 20 + j * 60 + 5,90 + i * 60 + 33);
}
}//if
}//for
}//for
}//way
//实现了数字在矩形框上显示的位置(居中),设置了数字所对应的框的颜色
}//class
可以贴错误提示出来吗.
就是 左右键不能控制 只能向上移动