>  기사  >  Java  >  Java로 Tetris 게임을 구현하는 코드를 작성하는 방법

Java로 Tetris 게임을 구현하는 코드를 작성하는 방법

王林
王林앞으로
2023-05-03 20:55:053033검색

Renderings

여기 인터페이스는 별로 좋아보이지는 않지만 기능만 있으면 큰 문제는 아니라고 생각합니다!

Java로 Tetris 게임을 구현하는 코드를 작성하는 방법

구현 아이디어

두 개의 캔버스:

캔버스 1: 게임 영역 테두리, 그리드, 점수 영역 상자, 다음 영역 상자, 버튼 등과 같이 정적인 부분을 그릴 필요가 없는 부분을 그리는 데 사용됩니다. 상쾌해지다.

Canvas 2: 그리드 모델, 그리드 이동, 회전 변형, 제거, 포인트 표시, 다음 그래픽 표시 등과 같은 게임의 동적 부분을 그리는 데 사용됩니다.

코드 구현

창 만들기

먼저 게임 형식 클래스인 GameFrame을 만들고 이를 JFrame에서 상속하여 화면(창 개체)에 표시하는 데 사용합니다. 각 게임에는 창 제목, 크기, 크기를 설정합니다. 레이아웃을 기다리세요.

/*
 * 游戏窗体类
 */
public class GameFrame extends JFrame {
	
	public GameFrame() {
		setTitle("俄罗斯方块");//设置标题
		setSize(488, 476);//设定尺寸
		setLayout(new BorderLayout());
		setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);//点击关闭按钮是关闭程序
        setLocationRelativeTo(null);   //设置居中
    	setResizable(false); //不允许修改界面大小
	}
}

Canvas 1

패널 컨테이너 BackPanel을 만들고 JPanel에서 상속합니다.

/*
 * 背景画布类
 */
public class BackPanel extends JPanel{
	BackPanel panel=this;
	private JFrame mainFrame=null;
	//构造里面初始化相关参数
	public BackPanel(JFrame frame){
		this.setLayout(null);
		this.setOpaque(false);
		this.mainFrame = frame;
		mainFrame.setVisible(true);
	}
}

이 창을 시작하려면 Main 클래스를 만듭니다.

public class Main {
	//主类
	public static void main(String[] args) {
		GameFrame frame = new GameFrame();
		BackPanel panel = new BackPanel(frame);
		frame.add(panel);
		frame.setVisible(true);//设定显示
	}
}

마우스 오른쪽 버튼을 클릭하여 Main 클래스를 실행하면 창이 생성됩니다

Java로 Tetris 게임을 구현하는 코드를 작성하는 방법

메뉴 및 메뉴 옵션 생성

메뉴 생성

private void  initMenu(){
		// 创建菜单及菜单选项
		jmb = new JMenuBar();
		JMenu jm1 = new JMenu("游戏");
		jm1.setFont(new Font("仿宋", Font.BOLD, 15));// 设置菜单显示的字体
		JMenu jm2 = new JMenu("帮助");
		jm2.setFont(new Font("仿宋", Font.BOLD, 15));// 设置菜单显示的字体
		
		JMenuItem jmi1 = new JMenuItem("开始新游戏");
		JMenuItem jmi2 = new JMenuItem("退出");
		jmi1.setFont(new Font("仿宋", Font.BOLD, 15));
		jmi2.setFont(new Font("仿宋", Font.BOLD, 15));
		
		JMenuItem jmi3 = new JMenuItem("操作说明");
		jmi3.setFont(new Font("仿宋", Font.BOLD, 15));
		JMenuItem jmi4 = new JMenuItem("失败判定");
		jmi4.setFont(new Font("仿宋", Font.BOLD, 15));
		
		jm1.add(jmi1);
		jm1.add(jmi2);
		
		jm2.add(jmi3);
		jm2.add(jmi4);
		
		jmb.add(jm1);
		jmb.add(jm2);
		mainFrame.setJMenuBar(jmb);// 菜单Bar放到JFrame上
		jmi1.addActionListener(this);
		jmi1.setActionCommand("Restart");
		jmi2.addActionListener(this);
		jmi2.setActionCommand("Exit");
		
		jmi3.addActionListener(this);
		jmi3.setActionCommand("help");
		jmi4.addActionListener(this);
		jmi4.setActionCommand("lost");
	}

ActionListener 구현 및 actionPerformed 메소드 재정의

Java로 Tetris 게임을 구현하는 코드를 작성하는 방법

actionPerformed 메소드 구현

Java로 Tetris 게임을 구현하는 코드를 작성하는 방법

Java로 Tetris 게임을 구현하는 코드를 작성하는 방법

게임 영역 그리기

게임 영역 테두리 그리기

//绘制边框
private void drawBorder(Graphics g) {
	BasicStroke bs_2=new BasicStroke(12L,BasicStroke.CAP_ROUND,BasicStroke.JOIN_MITER);
	Graphics2D g_2d=(Graphics2D)g;
	g_2d.setColor(new Color(128,128,128));
	g_2d.setStroke(bs_2);

	RoundRectangle2D.Double rect = new RoundRectangle2D.Double(6, 6, 313 - 1, 413 - 1, 2, 2);
	g_2d.draw(rect);
}

올바른 보조 영역(포인트, 다음, 버튼 등) 그리기

//绘制右边区域边框
private void drawBorderRight(Graphics g) {
	BasicStroke bs_2=new BasicStroke(12L,BasicStroke.CAP_ROUND,BasicStroke.JOIN_MITER);
	Graphics2D g_2d=(Graphics2D)g;
	g_2d.setColor(new Color(128,128,128));
	g_2d.setStroke(bs_2);
	
	RoundRectangle2D.Double rect = new RoundRectangle2D.Double(336, 6, 140 - 1, 413 - 1, 2, 2);
	g_2d.draw(rect);
	//g_2d.drawRect(336, 6, 140, 413);
}

BackPanel의 페인트 방법을 재정의하고 두 가지를 호출 지금 막 영역 그리기 방법을 살펴보겠습니다.

Java로 Tetris 게임을 구현하는 코드를 작성하는 방법

Java로 Tetris 게임을 구현하는 코드를 작성하는 방법

점수 영역과 다음 영역 그리기

//绘制积分区域
private void drawCount(Graphics g) {
	BasicStroke bs_2=new BasicStroke(2L,BasicStroke.CAP_ROUND,BasicStroke.JOIN_MITER);
	Graphics2D g_2d=(Graphics2D)g;
	g_2d.setColor(new Color(0,0,0));
	g_2d.setStroke(bs_2);
	g_2d.drawRect(350, 17, 110, 80);
	
	//得分
	g.setFont(new Font("宋体", Font.BOLD, 20));
	g.drawString("得分:",380, 40);
}

//绘制下一个区域
private void drawNext(Graphics g) {
	BasicStroke bs_2=new BasicStroke(2L,BasicStroke.CAP_ROUND,BasicStroke.JOIN_MITER);
	Graphics2D g_2d=(Graphics2D)g;
	g_2d.setColor(new Color(0,0,0));
	g_2d.setStroke(bs_2);
	g_2d.drawRect(350, 120, 110, 120);
	
	//得分
	g.setFont(new Font("宋体", Font.BOLD, 20));
	g.drawString("下一个:",360, 140);
}

그리드 그리기(15열, 20행)

//绘制网格
private void drawGrid(Graphics g) {
	Graphics2D g_2d=(Graphics2D)g;
	g_2d.setColor(new Color(255,255,255,150));
	int x1=12;
	int y1=20;
	int x2=312;
	int y2=20;
	for (int i = 0; i <= ROWS; i++) {
		y1 = 12 + 20*i;
		y2 = 12 + 20*i;
		g_2d.drawLine(x1, y1, x2, y2);		
	}
	
	y1=12;
	y2=412;
	for (int i = 0; i <= COLS; i++) {
		x1 = 12 + 20*i;
		x2 = 12 + 20*i;
		g_2d.drawLine(x1, y1, x2, y2);		
	}
}

페인트 방법 호출

Java로 Tetris 게임을 구현하는 코드를 작성하는 방법

오른쪽 영역에 일시 정지 버튼 만들기 of ​​the game

//初始化
private void init() {
	// 开始/停止按钮
	btnStart = new JButton();
	btnStart.setFont(new Font("黑体", Font.PLAIN, 18));
	btnStart.setFocusPainted(false);
	btnStart.setText("暂停");
	btnStart.setBounds(360, 300, 80, 43);
	btnStart.setBorder(BorderFactory.createRaisedBevelBorder());
	this.add(btnStart);
	btnStart.addActionListener(this);
	btnStart.setActionCommand("start");
}

Java로 Tetris 게임을 구현하는 코드를 작성하는 방법

이제 기본 레이아웃이 완성되었습니다.

Canvas 2

GamePanel은 JPanel에서 상속하고 페인트 메서드를 재정의합니다.

Main 클래스를 수정하고 Canvas 2를 창에 넣습니다.

public class Main {
	//主类
	public static void main(String[] args) {
		GameFrame frame = new GameFrame();
		BackPanel panel = new BackPanel(frame);
		frame.add(panel);
		GamePanel gamePanel = new GamePanel(frame);
		panel.setGamePanel(gamePanel);
		frame.add(gamePanel);
		frame.setVisible(true);//设定显示
	}
}

Canvas 2는 작은 사각형을 그립니다.

게임 영역이 작은 영역으로 나누어져 있기 때문에 Grid, 각각의 작은 그리드는 하나의 단위이고 전체 그리드는 15, 20의 2차원 배열입니다.

그래서 배열 첨자로 표현된 첫 번째 행의 첫 번째 요소는 0,0이고 첫 번째 행의 두 번째 요소는 0,1입니다.

이것은 쉽습니다. Block 클래스를 만들고 좌표를 설정하고 너비와 높이를 사용하여 사각형을 그릴 수 있습니다(너비와 높이는 그리드에 해당하는 20으로 고정됩니다).

package main;
import java.awt.Graphics;
public class Block {
	private int x=0;//x坐标
	private int y=0;//y坐标
	private GamePanel panel=null;
	
	public Block(int x,int y,int mX,int mY,GamePanel panel){
		this.x=x;
		this.y=y;
		this.panel=panel;
	}
	//绘制
	void draw(Graphics g){
		g.fillRect(12+x*20, 12+y*20, 20, 20);
	}
	
	public int getX() {
		return x;
	}
	public void setX(int x) {
		this.x = x;
	}
	public int getY() {
		return y;
	}
	public void setY(int y) {
		this.y = y;
	}
}

이 클래스를 인스턴스화하고 페인트 메서드에서 그리기 메서드를 호출합니다.

private void init() {
	x=0;
	y=0;
	curBlock = new Block(x, y,this);
}
@Override
public void paint(Graphics g) {
	super.paint(g);
	
	if(curBlock!=null){
		curBlock.draw(g);	
	}
}

Java로 Tetris 게임을 구현하는 코드를 작성하는 방법

Block 클래스에 이동 메서드를 추가합니다.

두 개의 매개변수 boolean xDir, int step

xDir 부울 값: true는 수평 이동을 의미하고 false를 의미합니다.

step은 단계 수입니다. xDir이 true인 경우 이를 1과 -1로 설정합니다. 수평 이동 1은 오른쪽으로 이동하는 것을 의미하고, -1은 xDir이 true인 경우 왼쪽으로 이동하는 것을 의미합니다. 1(위로 이동할 수 없기 때문에) 아래로 이동합니다.

//移动
	void move(boolean xDir, int step){
		if(xDir){//X方向的移动,step 正数向右 负数向左
			x += step;
		}else{//向下运动
			y += step;
		}
		panel.repaint();
	}

GamePanel에 키보드 이벤트 추가

//添加键盘监听
private void createKeyListener() {
	KeyAdapter l = new KeyAdapter() {
		//按下
		@Override
		public void keyPressed(KeyEvent e) {
			int key = e.getKeyCode();
			switch (key) {
				//空格
				case KeyEvent.VK_SPACE:
					break;
					
				//向上
				case KeyEvent.VK_UP:
				case KeyEvent.VK_W:
					break;
					
				//向右	
				case KeyEvent.VK_RIGHT:
				case KeyEvent.VK_D:
					if(curBlock!=null) curBlock.move(true, 1);
					break;
					
				//向下
				case KeyEvent.VK_DOWN:
				case KeyEvent.VK_S:
					if(curBlock!=null) curBlock.move(false, 1);
					break;
					
				//向左
				case KeyEvent.VK_LEFT:
				case KeyEvent.VK_A:
					if(curBlock!=null) curBlock.move(true, -1);
					break;
			}
		
		}
		//松开
		@Override
		public void keyReleased(KeyEvent e) {
		}
		
	};
	//给主frame添加键盘监听
	mainFrame.addKeyListener(l);
}

그래서 일련의 작업을 했습니다

Java로 Tetris 게임을 구현하는 코드를 작성하는 방법

그래픽 생성

Seven 그래픽

Java로 Tetris 게임을 구현하는 코드를 작성하는 방법

위 그림과 같이 작은 빨간색 사각형을 원점으로 삼으면 (0,0) 그런 다음 그래픽에서 다른 사각형의 위치를 ​​분석해 보겠습니다.

Java로 Tetris 게임을 구현하는 코드를 작성하는 방법

예를 들어 위 그림에서 빨간색 상자가 (0,0)이면 앞에 있는 상자는 (-1,0)입니다. x가 하나 이동하는 한 y와 둘은 동일하기 때문입니다. 위치는 왼쪽으로.

유추하자면 세 번째는 (1,0), 네 번째는 (2,0)이 되어야 합니다.

Java로 Tetris 게임을 구현하는 코드를 작성하는 방법

此图形呢,标红的为(0,0),它正下方的那个应该是(0,1),它右边那个是(1,0),它右下角的那个应该是(1,1)
于是我们可以设计一个Data类,专门存储7种图形的位置信息,分别对应前面图的7种模型

public class Data {
	public static List datas = new ArrayList(); 
	static void init(){
		int[][] data1 = {{-1,0},{0,0},{1,0},{1,1}}; 
		datas.add(data1);
		
		int[][] data2 = {{-1,0},{0,0},{1,0},{2,0}}; 
		datas.add(data2);
		
		int[][] data3 = {{-1,0},{-1,1},{0,0},{1,0}}; 
		datas.add(data3);
		
		int[][] data4 = {{-1,0},{0,0},{0,1},{1,1}}; 
		datas.add(data4);
		
		int[][] data5 = {{0,0},{0,1},{1,0},{1,1}}; 
		datas.add(data5);
		
		int[][] data6 = {{-1,1},{0,0},{0,1},{1,0}}; 
		datas.add(data6);
		
		int[][] data7 = {{-1,0},{0,0},{0,1},{1,0}}; 
		datas.add(data7);
	}
}

创建模型类

其中创建的时候,随机从Data类里面7个数据里面取到一个,生成一个图形,根据对应二维数组作为下标来创建小方块。

public class Model {

	private int x=0;
	private int y=0;
	private GamePanel panel=null;
	private List blocks = new ArrayList();
	boolean moveFlag=false;

	public Model(int x,int y,GamePanel panel){
		this.x=x;
		this.y=y;
		this.panel=panel;
		
		createModel();
	}
	
	private void createModel() {
		Random random = new Random();
		int type = random.nextInt(7);//1-7种模型
		int[][] data= (int[][])Data.datas.get(type);
		
		Block block=null;
		int mX=0;
		int mY=0;
		for (int i = 0; i < 4; i++) {
			mX = data[i][0];
			mY = data[i][1];
			block = new Block(x, y, mX , mY, panel);
			blocks.add(block);
		}
	}
}

Block也要稍微做些变动

需要加入偏移坐标值,来设定4个小方块的相对位置

Java로 Tetris 게임을 구현하는 코드를 작성하는 방법

GamePanel类中实例化的就是Model类了,同时绘制的也是

curModel = new Model(x,y,this);
@Override
public void paint(Graphics g) {
	super.paint(g);
	
	//当前模型
	if(curModel!=null){
		List blocks = curModel.getBlocks();
		Block block=null;
		for (int i = 0; i < blocks.size(); i++) {
			block = (Block)blocks.get(i);
			block.draw(g);
		}
	}
}

我这里设定创建Model的时候x为7,y为3,于是:

Java로 Tetris 게임을 구현하는 코드를 작성하는 방법

图形创建好了,怎么去移动这个图形呢

很简单就是键盘移动的时候,改成调用Model类的move方法了,此方法里面就是循环模型的4个Block实例,每个小块调用自己的move方法即可:

Java로 Tetris 게임을 구현하는 코드를 작성하는 방법

效果如下:

Java로 Tetris 게임을 구현하는 코드를 작성하는 방법

模型旋转变形

旋转万能公式 x=-y y=x 这里的x、y指的是Data类里面二维数组的值,也就是 Block中的偏移值

在Block中添加变形方法

	//变形
	public void rotate() {
		//旋转万能公式 x=-y y=x
		int x = mX;
		mX = -mY;
		mY = x;
	}

Model中添加变形方法,就是循环4个Block实例

这里加入了预变形方法,就是要先判断能否变形,比如变形会出边界,会碰到别的方块,则不让变形。

//旋转
void rotate(){
	boolean flag = true;//允许变形
	Block block=null;
	for (int i = 0; i < blocks.size(); i++) {
		block = (Block)blocks.get(i);
		if(!block.preRotate()){ //有一个不让变形就不能变形
			flag = false;//不能变形
			break;
		}
	}
	if(flag){
		for (int i = 0; i < blocks.size(); i++) {
			block = (Block)blocks.get(i);
			block.rotate();
		}
	}
	panel.repaint();
}

Java로 Tetris 게임을 구현하는 코드를 작성하는 방법

方块累计

当图形触底或者接触往下接触到其他方块时,会累计在下面,并且创建新的图形出来。

public Block[][] blockStack = new Block[15][20];

这个二维数组用来存储累计的方块

图形触底后,会根据每个小block实例的位置一一对应插入到blockStack这个二维数组中。

Java로 Tetris 게임을 구현하는 코드를 작성하는 방법

在paint方法中加入累积块的绘制

	//累计块
		Block bott = null;
		for (int i = 0; i < 15; i++) {
			for (int j = 0; j < 20; j++) {
				bott = (Block)blockStack[i][j];
				if(bott!=null ){
					bott.draw(g);
				}
			}
		}

方块消除和积分

1.从当前撞击的模型中取出y坐标(注意去重)。

2.将y进行排序,让位置小的排在前面,也就是如果消除两行的话要先消上面的那行。

3.消除当前行采用的是数据替换,从当前行开始,上一行的数据往下一行赋值,当前行就等于被消除了。

4.积分处理。

//消除处理
private void clear() {
	Block block = null ;
	int num=0;
	int y=0;
	List hasDoList=new ArrayList(); 
	List clearList=new ArrayList();
	for (int i = 0; i < blocks.size(); i++) {
		block = (Block)blocks.get(i);
		y = block.getY() + block.getmY();
		if(y<0 || y>19) continue;
		
		if(!hasDoList.contains(y)){
			hasDoList.add(y);
			if(block.clear()){
				clearList.add(y);
				num++;
			}
		}
	}
	if(num==1){
		panel.curCount+=100;
	}else if(num==2){
		panel.curCount+=300;
	}else if(num==3){
		panel.curCount+=600;
	}else if(num==4){
		panel.curCount+=1000;
	}
	//执行格子的消除动作
	if(num>0){
		Collections.sort(clearList);
		doClear(clearList);
	}
}
//执行消除
void doClear(List l){
	int y=0;
	for (int i = 0; i < l.size(); i++) {
		y = Integer.parseInt(String.valueOf(l.get(i)));
		clearClock(y);
	}
}

void clearClock(int y){
	Block[][] stack = panel.blockStack;
	Block block=null;
	for (int i = 0; i < 15; i++) {
		for (int j = 19; j >= 0; j--) {//从最下面往上
			if(y>=j&&j>0){//消除行和上方的行,全部往下移动,即这行等于上一行的数据
				block = stack[i][j-1];
				if(block!=null){
					block.setY(block.getY()+1);
				}
				stack[i][j]=block;
			}else if(j==0){//第一行,清空
				stack[i][j]=null;
			}
		}
	}
}

积分规则:1行100分、2行300分、3行600分、4行1000分

Java로 Tetris 게임을 구현하는 코드를 작성하는 방법

显示下一个

这个其实不难:

1.创建好当前模型的时候,同时创建好下一个模型,并绘制出来;

2.当前模型触底累计后,把下一个模型设置为当前模型。

3.同时创建一个新模型做为下一个模型。

//创建模型
	public void createModel(int type) {
		if(type==0){//游戏刚开始时
			curModel = new Model(x,y,this);
			nextModel = new Model(x,y,this);
		}else{//游戏运行中
			curModel = nextModel;
			nextModel = new Model(x,y,this);
		}
	}

在paint方法中绘制‘下一个’,在右边的下一个区域显示

		//下一个模型
		if(nextModel!=null){
			List blocks = nextModel.getBlocks();
			Block block=null;
			for (int i = 0; i < blocks.size(); i++) {
				block = (Block)blocks.get(i);
				block.drawNext(g);
			}
		}

加入自动向下线程,并启动

//游戏线程,用来自动下移
private class GameThread implements Runnable {
	@Override
	public void run() {
		while (true) {
			if("start".equals(gameFlag)){
				curModel.move(false, 1);
			}
			try {
				Thread.sleep(300);
			} catch (InterruptedException e) {
				e.printStackTrace();
			}
		}
	}
}

Java로 Tetris 게임을 구현하는 코드를 작성하는 방법

最后加入积分、按键控制、游戏结束、重新开始等就完成了

위 내용은 Java로 Tetris 게임을 구현하는 코드를 작성하는 방법의 상세 내용입니다. 자세한 내용은 PHP 중국어 웹사이트의 기타 관련 기사를 참조하세요!

성명:
이 기사는 yisu.com에서 복제됩니다. 침해가 있는 경우 admin@php.cn으로 문의하시기 바랍니다. 삭제