基于java2048小游戏简单程序设计

上学期学习了一些java设计方法和模式,做个2048练练手再熟悉一下。

项目主要分为element、game、manager三个包。

element:与游戏有关的元素类,包括基本矩形RectObject和用来表示坐标的Point类。

game:与游戏运行主体有关的,包括三个界面的Jpanel,JFrame,以及整个游戏线程控制GameRunThread和游戏主类。

manager:元素管理类,管理所有element,单例模式。

if(MyJFrame.change==true){
			ElementManager.getElementManager().getARandomRect();
			//saveTheStep();
		}
package game;

import java.awt.Color;
import java.awt.Font;
import java.awt.FontMetrics;
import java.awt.Graphics;
import java.awt.Toolkit;

import javax.swing.JPanel;

public class GameoverJPanel extends JPanel {
	public GameoverJPanel(int w,int h){
		setSize(w,h);
		//setOpaque(false);
	}
	public void paintComponent(Graphics g){
		super.paintComponent(g);
		Font font=new Font("TimesRoman",Font.BOLD,80);
		g.setFont(font);
		FontMetrics fm=Toolkit.getDefaultToolkit().getFontMetrics(font);
		int width=fm.stringWidth("Game Over");
		int height=fm.getHeight();
		g.setColor(new Color(255,0,0));
		g.drawString("Game Over!", getWidth()/2-width/2, getHeight()/2-height/2);
	}
}


package game;

import java.awt.Font;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.RandomAccessFile;
import java.util.ArrayList;

import javax.swing.JButton;
import javax.swing.JPanel;

import element.RectObject;
import manager.ElementManager;

public class GameRunThread extends Thread{

	@Override
	public void run() {
		// TODO Auto-generated method stub
		while(true) {
			rectMove();
			System.out.println("ok");
			isReset();
			isGoBack();
			isGameOver();
			isGameSuccess();
		}
	}

	public void isGameSuccess() {
		if(MyJFrame.successFlag)
			gameSuccess();
	}
	public void isReset() {
		if(MyJFrame.isReset) {
			refreshBest();
			for(int i=0;i<4;i++){
				for(int j=0;j<4;j++){
					ElementManager.getElementManager().rectObj[i][j]=null;
				}
			}
			MyJFrame.scoreLabel.setText("0");
			MyJFrame.isReset = false;
			ElementManager.getElementManager().getARandomRect();
			ElementManager.getElementManager().getARandomRect();
			
		}
		
	}
	
	public void isGoBack() {
		if(MyJFrame.isGoBack)
		{
		// 第0位存分数,后面存数字
					ArrayList arr=(ArrayList)MyJFrame.saveList.getLast();
					MyJFrame.scoreLabel.setText(""+arr.get(0));
					for(int i=0;i<4;i++){
						for(int j=0;j<4;j++){
							int num=(int)arr.get(4*i+j+1);
							if(num!=0){
								ElementManager.getElementManager().rectObj[i][j]=new RectObject();
								ElementManager.getElementManager().rectObj[i][j].value=num;
							}else{
								ElementManager.getElementManager().rectObj[i][j]=null;
							}
						}
					}
					MyJFrame.saveList.removeLast();
					MyJFrame.isGoBack = false;
		}
	}
	
	
	public void isGameOver() {
		if( !aMoveAble()){
			gameOver();
			return;
		}
	}
	
	public void gameOver() {
		MyJFrame.gameOverFlag=true;
		JPanel jl=new GameoverJPanel(MyJFrame.myp.getWidth(),MyJFrame.myp.getHeight());
		jl.setBounds(0, 0, 700, 700);
		JButton jb1=new JButton("Again");
		Font font=new Font("TimesRoman",Font.BOLD,30);
		jb1.setOpaque(false);
		jb1.setFont(font);
		JButton jb2=new JButton("Close");
		jb2.setSize(jb1.getSize());
		jb2.setOpaque(false);
		jb2.setFont(font);
		jb1.addActionListener(new ActionListener(){
			public void actionPerformed(ActionEvent e){
				MyJFrame.scoreLabel.setText("0");
				MyJFrame.myp.remove(jl);
				clearList(ElementManager.getElementManager().rectObj);
				MyJFrame.myp.validate();
				ElementManager.getElementManager().getARandomRect();
				ElementManager.getElementManager().getARandomRect();
				MyJFrame.myp.repaint();
				MyJFrame.gameOverFlag=false;
				refreshBest();
			}
		});
		jb2.addActionListener(new ActionListener(){
			public void actionPerformed(ActionEvent e){
				refreshBest();
				File f=new File("LASTRECORD");
				if(f.exists()){
					f.delete();
				}
				System.exit(0);
			}
		});
		jl.add(jb1);
		jl.add(jb2);
		MyJFrame.myp.add(jl);
		jl.validate();
	}
	
	public void gameSuccess() {
		JPanel jl=new GameSuccessJPanel(MyJFrame.myp.getWidth(),MyJFrame.myp.getHeight());
		jl.setOpaque(false);
		jl.setBounds(0, 0, 700, 700);
		JButton jb1=new JButton("Continue");
		Font font=new Font("TimesRoman",Font.BOLD,30);
		jb1.setOpaque(false);
		jb1.setFont(font);
		JButton jb2=new JButton("Close");
		jb2.setSize(jb1.getSize());
		jb2.setOpaque(false);
		jb2.setFont(font);
		jb1.addActionListener(new ActionListener(){
			public void actionPerformed(ActionEvent e){
				MyJFrame.myp.remove(jl);
				MyJFrame.myp.validate();
							}
		});
		jb2.addActionListener(new ActionListener(){
			public void actionPerformed(ActionEvent e){
				refreshBest();
				System.exit(0);
			}
		});
		jl.add(jb1);
		jl.add(jb2);
		MyJFrame.myp.add(jl);
		jl.validate();
	}
	
	public boolean aMoveAble() {
		MyJFrame.CheckMode=true;
		MyJFrame.change=false;
		moveLeft(true);
		moveRight(true);
		moveDown(true);
		moveUp(true);
		MyJFrame.CheckMode=false;
		if(MyJFrame.change==true){
			return true;
		}else{
			return false;
		}
	}
	
	private void rectMove() {
		// TODO Auto-generated method stub
		if(MyJFrame.isUp)
		{
			moveUp(true);
			if(MyJFrame.change==true){
				ElementManager.getElementManager().getARandomRect();
				//saveTheStep();
			}
			MyJFrame.isUp = false;
		}
		else if(MyJFrame.isDown) {
			moveDown(true);
			if(MyJFrame.change==true){
				ElementManager.getElementManager().getARandomRect();
				//saveTheStep();
			}
			MyJFrame.isDown = false;
		}
		else if(MyJFrame.isLeft) {
			moveLeft(true);
			if(MyJFrame.change==true){
				ElementManager.getElementManager().getARandomRect();
				//saveTheStep();
			}
			MyJFrame.isLeft = false;
		}
		else if(MyJFrame.isRight) {
			moveRight(true);
			if(MyJFrame.change==true){
				ElementManager.getElementManager().getARandomRect();
				//saveTheStep();
			}
			MyJFrame.isRight = false;
		}
	}

	public void moveRight(boolean flag) {
		// TODO Auto-generated method stub
		clearList(ElementManager.getElementManager().rectNext);
		for(int i=0;i<4;i++){
			int k=3;
			for(int j=3;j>-1;j--){
				if(ElementManager.getElementManager().rectObj[i][j]!=null){
					ElementManager.getElementManager().rectNext[i][k--]=new RectObject(ElementManager.getElementManager().rectObj[i][j]);
				}
			}
		}
		for(int i=0;i<4 && flag;i++){
			for(int j=3;j>0;j--){
				if(ElementManager.getElementManager().rectNext[i][j]!=null && ElementManager.getElementManager().rectNext[i][j-1]!=null && ElementManager.getElementManager().rectNext[i][j].value==ElementManager.getElementManager().rectNext[i][j-1].value){
					ElementManager.getElementManager().rectNext[i][j].value*=2;
					if(MyJFrame.CheckMode==false){
						int sum=Integer.parseInt(MyJFrame.scoreLabel.getText());
						sum+=ElementManager.getElementManager().rectNext[i][j].value;
						MyJFrame.scoreLabel.setText(""+sum);
					}
					ElementManager.getElementManager().rectNext[i][j-1]=null;
					j--;
				}
			}
		}
		
		if(isChange()){
			if(MyJFrame.CheckMode==false){
				copySet(ElementManager.getElementManager().rectObj,ElementManager.getElementManager().rectNext);
				moveRight(false);
			}
			MyJFrame.change=true;
		}else{
			
		}
		
	}

	public void moveLeft(boolean flag) {
		// TODO Auto-generated method stub
		clearList(ElementManager.getElementManager().rectNext);
		for(int i=0;i<4;i++){
			int k=0;
			for(int j=0;j<4;j++){
				if(ElementManager.getElementManager().rectObj[i][j]!=null){
					ElementManager.getElementManager().rectNext[i][k++]=new RectObject(ElementManager.getElementManager().rectObj[i][j]);
				}
			}
		}
		for(int i=0;i<4 && flag;i++){
			for(int j=0;j<3;j++){
				if(ElementManager.getElementManager().rectNext[i][j]!=null && ElementManager.getElementManager().rectNext[i][j+1]!=null && ElementManager.getElementManager().rectNext[i][j].value==ElementManager.getElementManager().rectNext[i][j+1].value){
					ElementManager.getElementManager().rectNext[i][j].value*=2;
					if(MyJFrame.CheckMode==false){
						int sum=Integer.parseInt(MyJFrame.scoreLabel.getText());
						sum+=ElementManager.getElementManager().rectNext[i][j].value;
						MyJFrame.scoreLabel.setText(""+sum);
					}
					ElementManager.getElementManager().rectNext[i][j+1]=null;
					j++;
				}
			}
		}
		
		if(isChange()){
			if(MyJFrame.CheckMode==false){
				copySet(ElementManager.getElementManager().rectObj,ElementManager.getElementManager().rectNext);
				moveLeft(false);
			}

			MyJFrame.change=true;
		}else{
			
		}
		
	}


	public void moveDown(boolean flag) {
		// TODO Auto-generated method stub
		clearList(ElementManager.getElementManager().rectNext);
		for(int j=0;j<4;j++){
			int k=3;
			for(int i=3;i>-1;i--){
				if(ElementManager.getElementManager().rectObj[i][j]!=null){
					ElementManager.getElementManager().rectNext[k--][j]=new RectObject(ElementManager.getElementManager().rectObj[i][j]);
				}
			}
		}
		for(int j=0;j<4 && flag;j++){
			for(int i=3;i>0;i--){
				if(ElementManager.getElementManager().rectNext[i][j]!=null && ElementManager.getElementManager().rectNext[i-1][j]!=null && ElementManager.getElementManager().rectNext[i][j].value==ElementManager.getElementManager().rectNext[i-1][j].value){
					ElementManager.getElementManager().rectNext[i][j].value*=2;
					if(MyJFrame.CheckMode==false){
						int sum=Integer.parseInt(MyJFrame.scoreLabel.getText());
						sum+=ElementManager.getElementManager().rectNext[i][j].value;
						MyJFrame.scoreLabel.setText(""+sum);
					}
					ElementManager.getElementManager().rectNext[i-1][j]=null;
					i--;
				}
			}
		}
		
		if(isChange()){
			if(MyJFrame.CheckMode==false){
				copySet(ElementManager.getElementManager().rectObj,ElementManager.getElementManager().rectNext);
				moveDown(false);
			}

			MyJFrame.change=true;
		}else{
		
		}
		
	}

	public void moveUp(boolean flag) {
		// TODO Auto-generated method stub
		clearList(ElementManager.getElementManager().rectNext);
		for(int j=0;j<4;j++){
			int k=0;
			for(int i=0;i<4;i++){
				if(ElementManager.getElementManager().rectObj[i][j]!=null){
					ElementManager.getElementManager().rectNext[k++][j]=new RectObject(ElementManager.getElementManager().rectObj[i][j]);
				}
			}
		}
		for(int j=0;j<4 && flag;j++){
			for(int i=0;i<3;i++){
				if(ElementManager.getElementManager().rectNext[i][j]!=null && ElementManager.getElementManager().rectNext[i+1][j]!=null && ElementManager.getElementManager().rectNext[i][j].value==ElementManager.getElementManager().rectNext[i+1][j].value){
					ElementManager.getElementManager().rectNext[i][j].value*=2;
					if(MyJFrame.CheckMode==false){
						int sum=Integer.parseInt(MyJFrame.scoreLabel.getText());
						sum+=ElementManager.getElementManager().rectNext[i][j].value;
						MyJFrame.scoreLabel.setText(""+sum);
					}
					ElementManager.getElementManager().rectNext[i+1][j]=null;
					i++;
				}
			}
		}
		
		if(isChange()){
			if(MyJFrame.CheckMode==false){
				copySet(ElementManager.getElementManager().rectObj,ElementManager.getElementManager().rectNext);
				
				moveUp(false);
			}

			MyJFrame.change=true;
		}else{
			
		}
		
	}
	
	public boolean isChange() {
		for(int i=0;i<4;i++){
			for(int j=0;j<4;j++){
				if(ElementManager.getElementManager().rectObj[i][j]!=null && ElementManager.getElementManager().rectNext[i][j]!=null && !ElementManager.getElementManager().rectObj[i][j].equals(ElementManager.getElementManager().rectNext[i][j])){
					return true;
				}
				if(ElementManager.getElementManager().rectObj[i][j]!=null && ElementManager.getElementManager().rectNext[i][j]==null){
					return true;
				}
				if(ElementManager.getElementManager().rectObj[i][j]==null && ElementManager.getElementManager().rectNext[i][j]!=null){
					return true;
				}
			}
		}
		return false;
	}
	
	public void copySet(RectObject[][] dst, RectObject[][] src) {
		// TODO Auto-generated method stub
		for(int i=0;i<4;i++){
			for(int j=0;j<4;j++){
				dst[i][j]=src[i][j];
			}
		}
	}
	
	public void clearList(RectObject[][] s){
		for(int i=0;ibest){
				file.writeInt(cur);
			}
			file.close();
		} catch (FileNotFoundException e1) {
			e1.printStackTrace();
		}catch(IOException e2){
			e2.printStackTrace();
		}
	}

	public static void saveRecord(){
		try{
			RandomAccessFile file=new RandomAccessFile(new File("LASTRECORD"),"rw");
			int score=Integer.parseInt(MyJFrame.scoreLabel.getText());
			file.writeInt(score);
			for(int i=0;i<4;i++){
				for(int j=0;j<4;j++){
					if(ElementManager.getElementManager().rectObj[i][j]!=null){
						file.writeInt(ElementManager.getElementManager().rectObj[i][j].value);
					}else{
						file.writeInt(0);
					}
				}
			}
		}catch(FileNotFoundException e){
			e.printStackTrace();
		}catch(IOException e){
			e.printStackTrace();
		}
	}
	
}

package game;

import java.awt.Color;
import java.awt.Font;
import java.awt.FontMetrics;
import java.awt.Graphics;
import java.awt.Toolkit;

import javax.swing.JPanel;

public class GameSuccessJPanel extends JPanel {
	public GameSuccessJPanel(int w,int h){
		setSize(w,h);
		//setOpaque(false);
	}
	public void paintComponent(Graphics g){
		super.paintComponent(g);
		Font font=new Font("TimesRoman",Font.BOLD,80);
		g.setFont(font);
		FontMetrics fm=Toolkit.getDefaultToolkit().getFontMetrics(font);
		int width=fm.stringWidth("Success!");
		int height=fm.getHeight();
		g.setColor(new Color(255,0,0));
		g.drawString("Success!", getWidth()/2-width/2, getHeight()/2-height/2);
	}
}

package game;

import java.awt.Color;
import java.awt.Font;
import java.awt.FontMetrics;
import java.awt.Graphics;
import java.awt.Toolkit;

import javax.swing.JPanel;

import manager.ElementManager;

public class My2048JPanel extends JPanel implements Runnable{
	
	public static final int WID=150,SP=10;
	private int[] xindex={SP,2*SP+WID,3*SP+2*WID,4*SP+3*WID};
	private int[] yindex={SP,2*SP+WID,3*SP+2*WID,4*SP+3*WID};
	
	public void paintComponent(Graphics g){
		//background
		super.paintComponent(g);
		for(int i=0;i

package game;

import java.awt.Color;
import java.awt.Container;
import java.awt.Font;
import java.awt.GridLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.KeyEvent;
import java.awt.event.KeyListener;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.RandomAccessFile;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.LinkedList;
import java.util.Map;

import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JLabel;

import element.RectObject;
import manager.ElementManager;


public class MyJFrame extends JFrame {
	public static final int UP=0,DOWN=1,LEFT=2,RIGHT=3;
	public static boolean isLeft = false;
	public static boolean isRight = false;
	public static boolean isUp = false;
	public static boolean isDown = false;
	public static boolean isReset = false;
	public static boolean isGoBack = false;
	
	
	public static final int WID=150,SP=10;
	public int scores=0;
	public static JLabel scoreLabel;
	public static boolean change,CheckMode=false,gameOverFlag=false,successFlag=false;
	public int[] label={2,4,8,16,32,64,128};
	public Color[] clo={
			new Color(200,200,200),new Color(228,228,160),new Color(214,163,92),
			new Color(234,124,72),new Color(240,84,77),new Color(255,68,53),new Color(200,200,64)
	};
	public static Map cmap=new HashMap();
	
	public static My2048JPanel myp;
	public static LinkedList saveList=new LinkedList();
	private JButton goBackButton;
	
	
	public MyJFrame() {
		//saveTheStep();
				for(int i=0;i<7;i++){
					cmap.put(label[i], clo[i]);
				}
				init();
	}
	
	KeyListener kl=new KeyListener(){
		public void keyPressed(KeyEvent e){
			saveTheStep();
			goBackButton.setVisible(true);
			if(gameOverFlag==true){
				return;
			}
			int key=e.getKeyCode();
			switch(key){
			case KeyEvent.VK_UP:
				change=false;
				isUp = true;
				
				break;
			case KeyEvent.VK_DOWN:
				change=false;
				isDown = true;
				
				break;
			case KeyEvent.VK_LEFT:
				change=false;
				isLeft = true;

				break;
			case KeyEvent.VK_RIGHT:
				change=false;
				isRight = true;
				
				break;
			}
			//saveTheStep();
		}
		public void keyTyped(KeyEvent e){}
		public void keyReleased(KeyEvent e){}
	};
	
	
	
	public class goBackListener implements ActionListener{
		public void actionPerformed(ActionEvent e){
			if(saveList.size()==0){
				goBackButton.setVisible(false);
				return;
			}
			isGoBack = true;
			repaint();
		}
	}
	
	public class resetListener implements ActionListener{
		public void actionPerformed(ActionEvent e){
			isReset = true;
			repaint();
		}
	}
	
	public void saveTheStep(){
		if(saveList.size()<20){
			ArrayList arr=new ArrayList();
			int score=Integer.parseInt(scoreLabel.getText());
			arr.add(score);
			for(int i=0;i<4;i++){
				for(int j=0;j<4;j++){
					if(ElementManager.getElementManager().rectObj[i][j]!=null){
						arr.add(ElementManager.getElementManager().rectObj[i][j].value);
					}else{
						arr.add(0);
					}
				}
			}
			saveList.addLast(arr);
		}else{
			saveList.removeFirst();
			saveTheStep();
		}
	}
	
	public void init() {
		// TODO Auto-generated method stub
		Container cp=getContentPane();
		cp.setLayout(null);
		cp.setFocusable(true);
		cp.addKeyListener(kl);
		
		Font font=new Font("TimesNewman",Font.BOLD,30);
		JLabel sl=new JLabel();
		sl.setLayout(new GridLayout(2,1));
		JLabel sllb=new JLabel("Scores");
		sllb.setFont(font);
		scoreLabel=new JLabel("0");
		scoreLabel.setFont(font);
		sl.add(sllb);
		sl.add(scoreLabel);
		
		int best=0;
		try{
			File file=new File("BestRecord");
			if(file.exists()){
				RandomAccessFile f=new RandomAccessFile(file,"rw");
				best=f.readInt();
				f.close();
			}
		}catch(FileNotFoundException e){
			best=0;
			e.printStackTrace();
		}catch(IOException e){
			best=0;
			e.printStackTrace();
		}
		JLabel bsl=new JLabel();
		bsl.setLayout(new GridLayout(2,1));
		JLabel jl=new JLabel("Best");
		jl.setFont(font);
		JLabel jl1=new JLabel(""+best);
		jl1.setFont(font);
		bsl.add(jl);
		bsl.add(jl1);
		
		myp=new My2048JPanel();

		
		goBackButton=new JButton("UNDO");
		goBackButton.setFont(font);
		goBackButton.addActionListener(new goBackListener());
		goBackButton.addKeyListener(kl);
		
		JButton jb=new JButton("RESET");
		jb.setFont(font);
		jb.addActionListener(new resetListener());
		jb.addKeyListener(kl);
		
		sl.setBounds(500,20,200,80);
		bsl.setBounds(300,20,200,80);

		myp.setBounds(0,90,700,700);
		goBackButton.setBounds(700,250,150,60);
		jb.setBounds(700,450,150,60);
		
		cp.add(sl);
		cp.add(bsl);

		cp.add(myp);
		cp.add(goBackButton);
		cp.add(jb);
		
		
		
		File f=new File("LASTRECORD");
		if(f.exists()){
			try{
				RandomAccessFile file=new RandomAccessFile(f,"rw");
				int num=file.readInt();
				scoreLabel.setText(""+num);
				for(int i=0;i<4;i++){
					for(int j=0;j<4;j++){
						num=file.readInt();
						if(num!=0){
							ElementManager.getElementManager().rectObj[i][j]=new RectObject();
							ElementManager.getElementManager().rectObj[i][j].value=num;
						}
					}
				}
				file.close();
			}catch(FileNotFoundException e){
				e.printStackTrace();
			}catch(IOException e){
				e.printStackTrace();
			}
		}else{
			ElementManager.getElementManager().getARandomRect();
			ElementManager.getElementManager().getARandomRect();
		}
	}

	
	public void gameShow() {
		this.setVisible(true);
		new Thread((Runnable)myp).start();
		new GameRunThread().start();
	}
	
	
}

package game;

public class TzfeStart {
	public static MyJFrame jf;
	public static void main(String[] args) {
		jf = new MyJFrame();
		jf.gameShow();
	
	}
}

package manager;

import java.util.ArrayList;
import java.util.Random;

import element.Point;
import element.RectObject;

//单例模式
public class ElementManager {
	private static ElementManager elementManager = null;
	public static RectObject rectObj[][] = null;
	public RectObject rectNext[][] = null;
	
	private ElementManager() {
		rectObj = new RectObject[4][4];
		rectNext = new RectObject[4][4];
	}
	
	public static synchronized ElementManager getElementManager() {
		if(elementManager==null) {
			elementManager = new ElementManager();
		}
		return elementManager;	
	}
	
	public void getARandomRect() {
		ArrayList list = new ArrayList();
		for(int i = 0;i<4;i++) {
			for(int j = 0;j<4;j++)
			{
				if(rectObj[i][j]==null)
				{
					list.add(new Point(i,j));
					//System.out.println(list.get(0));
				}
			}
		}
		Random rand=new Random();
		int index=rand.nextInt(list.size());

		Point loc=(Point) list.get(index);
		index=rand.nextInt(2);
		ElementManager.getElementManager().rectObj[loc.x][loc.y]=new RectObject();
		if(index==1){
			ElementManager.getElementManager().rectObj[loc.x][loc.y].value=4;
		}else{
			ElementManager.getElementManager().rectObj[loc.x][loc.y].value=2;
		}
	}

}
package element;

public class Point {
	public int x;
	public int y;
	public Point(int x, int y) {
		this.x = x;
		this.y = y;
	}
	
}


package element;

public class RectObject {
	public int value;
	public RectObject() {
		value = 0;
	}
	public RectObject(RectObject obj) {
		this.value = obj.value;
	}
	@Override
	public boolean equals(Object iobj) {
		// TODO Auto-generated method stub
		RectObject obj = (RectObject)iobj;
		if(this.value == obj.value)
		{
			return true;
		}
			return false;
	}
}

这种游戏可能不适合用这种方式编程,还要继续学习。



你可能感兴趣的:(基于java2048小游戏简单程序设计)