我的第一個Java遊戲——2048

[img]http://dl2.iteye.com/upload/attachment/0102/1806/88eb01e5-291a-31e2-a1fe-d1c586760e0e.jpg[/img]

這兩天寫了個Java的2048遊戲,找了兩天bug,找完bug感覺自己萌萌噠。啥也不說了,來代碼,來圖吧!
首先,我們得創建一個界面:
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 {
public static void main(String[] args) {
UI ui = new UI();
ui.InUI();
}

// 創建數組,存儲數據
private int[][] numbers = new int[4][4];

// 創建界面
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);//空佈局的大小位置設置要用setBounds………………………………
jl.setForeground(new Color(3, 82, 212));
this.add(jl);
this.setDefaultCloseOperation(3);
this.setResizable(false);//界面大小動一個試試 :twisted:

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|| numbers[i][j] == 8) {
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);
}
}
}
}

}
}//實現了數字在矩形框上顯示的位置(居中),設置了數字所對應的框的顏色

接下來就是各方向算法的分析咯~

import java.applet.Applet;
import java.applet.AudioClip;
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;//又是導包 :x

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());
}

// 鍵盤按下的方法
這個地方最好用pressed 不要用released不然後面會有bug。。。如果用release的話,彈出的失敗或勝利框,是不能用回車鍵確定的~pressd則不會出現這種情況

public void keyPressed(KeyEvent e) {
// System.out.println("66666"+e.getKeyCode());
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) {
//向左移動時,當其顯示2048時,出現“你贏了!” JOptionPane.showMessageDialog(null, "你贏了!");
}
}
}
}
相加之後如果後面還有空 就再移動一次~
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個格子都有值,且相鄰格子上的值不能相等,注意遍歷時候越界問題,以及計數器所計的值到底是表示什麼,(這個困擾了小編兩個下午,真鬧心,不過想通了~~~)
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, "思密達,你輸了~~~");
}
}
下面是測試結果:
[img]http://dl2.iteye.com/upload/attachment/0102/1808/4db07157-6990-3ae1-862d-cd7ebf50c9f0.jpg[/img]

[img]http://dl2.iteye.com/upload/attachment/0102/1810/18ae1db9-499d-3e70-8b76-4c2639bf2fde.jpg[/img]

當然,數字可以換成圖片,這時就可以用drawimage 或者直接添加Jbutton,然後在jbutton上添加圖片,這個小編還沒做,不過目前來說簡單的2048就算完成咯~~
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章