跟着教学视频来做,但是视频不完整的,还缺一部分,后面的是我自己独自完成的,嘿嘿嘿
这是初步的作品,也就三百多行代码
package myGame2048;
public class StartGame_2048 {
public static void main(String[] args) {
new GameFrame_2048();
}
}
package myGame2048;
import javax.swing.*;
public class GameFrame_2048 extends JFrame {
public GameFrame_2048() {
add(new GamePanel_2048());
setVisible(true);
setSize(360,500);
setTitle("2048小游戏");
setLocationRelativeTo(null); // 居中
setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);
}
}
package myGame2048;
import javax.swing.*;
import java.awt.*;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.KeyAdapter;
import java.awt.event.KeyEvent;
import java.util.Random;
public class GamePanel_2048 extends JPanel {
// 二维数组存储4*4的卡片,这只是创建数组,没有创建具体的对象
Card[][] allCards=new Card[4][4];
int score;
boolean isFail,isWin;
public GamePanel_2048() { // 生成对象必定调用构造器,且只执行一次
init();
setFocusable(true); // 设置聚焦
addKeyListener(new KeyAdapter() {
@Override
public void keyPressed(KeyEvent e) {
int keyCode=e.getKeyCode();
switch (keyCode){
case KeyEvent.VK_UP: moveUp(); createRN(); getScore(); break;
case KeyEvent.VK_DOWN: moveDown(); createRN(); getScore(); break;
case KeyEvent.VK_LEFT:moveLeft(); createRN(); getScore(); break;
case KeyEvent.VK_RIGHT:moveRight(); createRN(); getScore(); break;
case KeyEvent.VK_SPACE:if (isFail==true || isWin==true) init();break;
}
repaint();
}
});// 键盘监听器
// 为什么我的按钮有问题
JButton jButton = new JButton("重新开始游戏");
jButton.setVisible(true);
jButton.addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
init();
repaint();
}
});
add(jButton);
}
public void init(){
isFail=isWin=false;
score=0;
// 创建16个具体的Card对象,以及确定坐标
for (int i = 0; i < 4; i++) {
for (int j = 0; j < 4; j++) {
allCards[i][j]=new Card(i,j);
// 依次创建16个Card对象.当重置游戏的时候,这些对象都会重新变为空白,变成泉下的对象
}
}
createRN();
}
// 画笔
@Override
public void paint(Graphics g) {
// 画出上面的界面
g.setColor(Color.gray);
g.fillRect(0,0,670,110);
g.setColor(Color.cyan);
g.fillRect(0,110,670,1000);
g.setColor(Color.yellow);
g.setFont(new Font("微软雅黑",Font.BOLD,30));
g.drawString("2048",50,50);
g.setColor(Color.white);
g.setFont(new Font("微软雅黑",Font.BOLD,30));
g.drawString("分数:"+score,200,50);
g.setColor(Color.black);
g.setFont(new Font("宋体",Font.BOLD,15));
g.drawString("按下键盘的上下左右进行游戏",10,80);
// 画出16张卡片
for (int i = 0; i < 4; i++) {
for (int j = 0; j < 4; j++) {
// 卡片的位置
Card card=allCards[i][j];
g.setColor(setColor(card.num));
g.fillRect(card.x,card.y,80,80);
// 卡片上的数字,根据数字大小决定x的偏移量offset_x
int offset_x = 0;
if (card.num<10) {offset_x=25;}
if (card.num>=10 && card.num<100) {offset_x=5;}
if (card.num>=100 && card.num<1000) {offset_x=15;}
if (card.num>=1000 && card.num<10000) {offset_x=10;}
g.setColor(Color.black);
g.setFont(new Font("微软雅黑", Font.BOLD, 50));
if (card.num>0) g.drawString(""+card.num,card.x+offset_x,card.y+60);
}
}
if (isFail==true){
g.setColor(Color.red);
g.setFont(new Font("宋体",Font.BOLD,20));
g.drawString("游戏失败,按下空格重新开始游戏",10,100);
}
if (score==8){
isWin=true;
g.setColor(Color.pink);
g.setFont(new Font("宋体",Font.BOLD,20));
g.drawString("恭喜通关!按下空格重新开始游戏!",10,100);
}
}//画笔
// 在没有数字的卡片( card.num==0)中随机地选择一张卡片,生成2(3/5概率)或者4(2/5概率)两个随机数字
public void createRN(){
isFail();
if (isFail==false){
int rn=new Random().nextInt(5); // 随机数random number:0,1,2,3,4
if(rn==3 ||rn==3){
rn=4;
}else{rn=2;}
randomCard().num=rn;
}else System.out.println("游戏失败");
}
// 选出空的卡片
public Card randomCard() { // 这里应该用异常来处理,因为再也没有没有空的卡牌的时候,游戏失败.这里就陷入了死循环
Card card = allCards[new Random().nextInt(4)][new Random().nextInt(4)];
if (card.num == 0) {
return card;
} else
return randomCard(); // 递归,选出空的卡片}
}
// 根据卡片上的数字来决定卡片的颜色
public Color setColor(int num) {
Color color = null;
switch (num) {
case 0:
color = new Color(92, 151, 117);
break;
case 2:
color = Color.yellow;
break;
case 4:
color = Color.red;
break;
case 8:
color = Color.blue;
break;
case 16:
color = Color.gray;
break;
case 32:
color = Color.cyan;
break;
case 64:
color = Color.lightGray;
break;
case 128:
color = Color.pink;
break;
case 256:
color = Color.blue;
break;
case 512:
color = Color.orange;
break;
case 1024:
color = Color.white;
break;
case 2048:
color = Color.magenta;
break;
}
return color;
}
//---------------------------------------------------------------------------------------------------
// 键盘监听器,控制卡片的移动
public void moveUp(){
for (int i = 1; i < 4; i++) { // 最上层不需要移动,第二行最先开始移动
for (int j = 0; j < 4; j++) {
Card card=allCards[i][j]; // 当前的卡片
if (card.num!=0) {
card.moveUp(allCards);
}
}
}
}
public void moveDown(){
for (int i = 2; i >=0; i--) { // 第三行最先开始移动
for (int j = 0; j < 4; j++) {
Card card=allCards[i][j]; // 当前的卡片
if (card.num!=0) {
card.moveDown(allCards);
}
}
}
}
public void moveLeft(){ // 第二列最先开始移动
for (int i = 0; i < 4 ; i++) {
for (int j = 1; j < 4; j++) {
Card card=allCards[i][j]; // 当前的卡片
if (card.num!=0) {
card.moveLeft(allCards);
}
}
}
}
public void moveRight(){ // 第三列最先开始移动
for (int i = 0; i < 4; i++) {
for (int j = 2; j >=0; j--) {
Card card=allCards[i][j]; // 当前的卡片
if (card.num!=0) {
card.moveRight(allCards);
}
}
}
}
//---------------------------------------------------------------------------------------------------
// 游戏失败的判定
public void isFail(){
isFail=true;
for (int i = 0; i < 4; i++) {
for (int j = 0; j < 4; j++) {
Card card=allCards[i][j];
if (card.num==0){
isFail=false; // 只要有任意一个为空格子,那么游戏就没有失败
}
}
}
}
// 确定分数,在二维数组中得到最大值
public void getScore(){
for (int i = 0; i < 4; i++) {
for (int j = 0; j < 4; j++) {
if (allCards[i][j].num>score)
score=allCards[i][j].num;
}
}
}
}
package myGame2048;
public class Card {
int x,y; // 相对于面板的坐标
int i,j; // 在二维数组中的下标
int num; // 卡片的数字
public Card(int i, int j) {
this.i = i;
this.j = j;
// 确定每张卡片的坐标
this.x=5+80*j+5*j;
this.y=125+80*i+5*i; // 边距为5
}
// 卡片移动,实际上是数字赋值
public void moveUp(Card[][] allCards) {
if (this.i==0) return; // 递归结束的判定
Card precard=allCards[i-1][j]; // 获得上一张卡片
if (precard.num==0){
precard.num=this.num; // 为什么 precard变了,而那边的allCards[i-1][j] 也跟着改变
this.num=0;
precard.moveUp(allCards); // 递归
}
// 合并数字
if (precard.num==this.num && this.num!=0){
precard.num*=2;
this.num=0;
//不需要 precard.moveUp(allCards); // 递归
}
}
public void moveDown(Card[][] allCards) {
if (this.i==3) return; // 递归结束的判定
Card nextcard=allCards[i+1][j]; // 获得下一张卡片
if (nextcard.num==0){
nextcard.num=this.num; // 为什么 precard变了,而那边的allCards[i-1][j] 也跟着改变
this.num=0;
nextcard.moveDown(allCards); // 递归
}
if (nextcard.num==this.num && this.num!=0){
nextcard.num*=2;
this.num=0;
}
}
public void moveLeft(Card[][] allCards) {
if (this.j==0) return; // 递归结束的判定
Card leftcard=allCards[i][j-1]; // 获得下一张卡片
if (leftcard.num==0){
leftcard.num=this.num; // 为什么 precard变了,而那边的allCards[i-1][j] 也跟着改变
this.num=0;
leftcard.moveLeft(allCards); // 递归
}
if (leftcard.num==this.num && this.num!=0){
leftcard.num*=2;
this.num=0;
}
}
public void moveRight(Card[][] allCards) {
if (this.j==3) return; // 递归结束的判定
Card rightcard=allCards[i][j+1]; // 获得下一张卡片
if (rightcard.num==0){
rightcard.num=this.num; // 为什么 precard变了,而那边的allCards[i-1][j] 也跟着改变
this.num=0;
rightcard.moveRight(allCards); // 递归
}
if (rightcard.num==this.num && this.num!=0){
rightcard.num*=2;
this.num=0;
}
}
}
标签:21.2048,num,Card,int,小游戏,allCards,public,card
From: https://www.cnblogs.com/zhanjianhai/p/17656619.html