java实现俄罗斯方块游戏-程序员宅基地

技术标签: 程序员  python  java  游戏  

@Override

public void actionPerformed(ActionEvent e) {

int curLevel = getLevel();

if (!playing && curLevel > 1) {

setLevel(curLevel - 1);

}

}

});

// 退出按钮动作响应

miExit.addActionListener(new ActionListener() {

@Override

public void actionPerformed(ActionEvent e) {

System.exit(0);

}

});

}

3、添加事件监听

/*

  • 添加事件监听

*/

/*

  • 开始游戏

*/

btPlay.addActionListener(new ActionListener() {

@Override

public void actionPerformed(ActionEvent ae) {

// TODO Auto-generated method stub

game.playGame();

}

});

/*

  • 暂停游戏

*/

btPause.addActionListener(new ActionListener() {

@Override

public void actionPerformed(ActionEvent ae) {

// TODO Auto-generated method stub

if (btPause.getText().equals(“暂停”)) {

game.pauseGame();

} else {

game.resumeGame();

}

}

});

/*

  • 停止游戏

*/

btStop.addActionListener(new ActionListener() {

@Override

public void actionPerformed(ActionEvent ae) {

// TODO Auto-generated method stub

game.stopGame();

}

});

/*

  • 升高难度

*/

btTurnLevelUp.addActionListener(new ActionListener() {

@Override

public void actionPerformed(ActionEvent ae) {

// TODO Auto-generated method stub

try {

int level = Integer.parseInt(tfLevel.getText());

if (level < RussiaBlocksGame.MAX_LEVEL) {

tfLevel.setText(“” + (level + 1));

}

} catch (NumberFormatException e) {

// TODO: handle exception

requestFocus();

}

}

});

/*

  • 降低游戏难度

*/

btTurnLevelDown.addActionListener(new ActionListener() {

@Override

public void actionPerformed(ActionEvent ae) {

// TODO Auto-generated method stub

try {

int level = Integer.parseInt(tfLevel.getText());

if (level > 1) {

tfLevel.setText(“” + (level - 1));

}

} catch (NumberFormatException e) {

// TODO: handle exception

requestFocus();

}

}

});

/*

  • 主要用于解决Jframe窗口大小变化时,里面的组件的位置也会自适应的移动。

*/

addComponentListener(new ComponentAdapter() {

public void componentResized(ComponentEvent ce) {

plTipBlock.fanning();

}

});

4、创建方块

public class ErsBox implements Cloneable {

private boolean isColor;

private Dimension size = new Dimension(); // Dimension类封装单个对象中组件的宽度和高度(精确到整数)

/*

  • 方格类构造函数 isColor是不是用前景色为此方格着色,true前景色,false背景色

*/

public ErsBox(boolean isColor) {

// TODO Auto-generated constructor stub

this.isColor = isColor;

}

/*

  • 设置方格的颜色 true前景色,false背景色

*/

public void setColor(boolean isColor) {

// TODO Auto-generated method stub

this.isColor = isColor;

}

/*

  • 得到此方格的尺寸

*/

public Dimension getSize() {

return size;

}

/**

  • 设置方格的尺寸,

  • @param size Dimension ,方格的尺寸

*/

public void setSize(Dimension size) {

this.size = size;

}

/*

  • 覆盖object的object clone(),实现克隆

*/

public Object clone() {

Object cloned = null;

try {

cloned = super.clone();

} catch (Exception ex) {

// TODO: handle exception

ex.printStackTrace();

}

return cloned;

}

/**

  • 此方格是不是用前景色表现

  • @return boolean ,true用前景色表现,false 用背景色表现

*/

public boolean isColorBox() {

// TODO Auto-generated method stub

return isColor;

}

}

5、实现对方块操作

public class ErsBlock extends Thread {

// 一个块占得4行

public static final int BOXES_ROWS = 4;

// 一个块占4列

public static final int BOXES_COLS = 4;

/*

  • 让升级变化平滑的因子,避免最后几级之间的速度相差近一倍

*/

public final static int LEVEL_FLATNESS_GENE = 3;

// 相近的两级之间,块每下落一行的时间差别为多少(毫秒)

public final static int BETWEEN_LEVELS_DEGRESS_TIME = 50;

// 方块的样式数目为7

public final static int BLOCK_KIND_NUMBER = 7;

// 每一个样式的方块反转状态种类为4

public final static int BLOCK_STASTUS_NUMBER = 4;

/**

  • 分别对应7中模型的28中状态

*/

public final static int[][] STYLES = { // 共28种状态

{ 0x0f00, 0x4444, 0x0f00, 0x4444 }, // 长条型的四种状态

{ 0x04e0, 0x0464, 0x00e4, 0x04c4 }, // T型的四种状态

{ 0x4620, 0x6c00, 0x4620, 0x6c00 }, // 反Z型的四种状态

{ 0x2640, 0xc600, 0x2640, 0xc600 }, // Z型的四种状态

{ 0x6220, 0x1700, 0x2230, 0x0740 }, // 7型的四种状态

{ 0x6440, 0x0e20, 0x44c0, 0x8e00 }, // 反7型的四种状态

{ 0x0660, 0x0660, 0x0660, 0x0660 }, // 方块的四种状态

};

private GameCanvas canvas;

private ErsBox[][] boxes = new ErsBox[BOXES_ROWS][BOXES_COLS];

private int style, y, x, level;

private boolean pausing = false, moving = true;

/*

  • 构造一个函数,产生一个特定的块 style为块的样式,对应STYLES中的某一个 y起始位置,左上角在canvas中的坐标行

  • x起始位置,左上角在canvas中的坐标列 level游戏等级控制下降速度 canvas面板

*/

public ErsBlock(int style, int y, int x, int level, GameCanvas canvas) {

this.style = style;

this.y = y;

this.x = x;

this.level = level;

this.canvas = canvas;

int key = 0x8000;

for (int i = 0; i < boxes.length; i++) {

for (int j = 0; j < boxes[i].length; j++) {

boolean isColor = ((style & key) != 0);

boxes[i][j] = new ErsBox(isColor);

key >>= 1;

}

}

display();

}

/*

  • 线程类的run()函数覆盖,下落块,直到块不能再下落

*/

@Override

public void run() {

while (moving) {

try {

sleep(BETWEEN_LEVELS_DEGRESS_TIME * (RussiaBlocksGame.MAX_LEVEL - level + LEVEL_FLATNESS_GENE));

} catch (InterruptedException ie) {

ie.printStackTrace();

}

// 后边的moving是表示在等待的100毫秒间,moving没有被改变

if (!pausing) {

moving = (moveTo(y + 1, x) && moving);

}

}

}

/*

  • 块左移一格

*/

public void moveLeft() {

// TODO Auto-generated method stub

moveTo(y, x - 1);

}

/*

  • 块右移一格

*/

public void moveRight() {

// TODO Auto-generated method stub

moveTo(y, x + 1);

}

/**

  • 块下移一格

*/

public void moveDown() {

// TODO Auto-generated method stub

moveTo(y + 1, x);

}

/*

  • 块变形

*/

public void turnNext() {

for (int i = 0; i < BLOCK_KIND_NUMBER; i++) {

for (int j = 0; j < BLOCK_STASTUS_NUMBER; j++) {

if (STYLES[i][j] == style) {

int newStyle = STYLES[i][(j + 1) % BLOCK_STASTUS_NUMBER];

turnTo(newStyle);

return;

}

}

}

}

public void startMove() {

// TODO Auto-generated method stub

pausing = false;

moving = true;

}

/*

  • 暂定块的下落,对应暂停游戏

*/

public void pauseMove() {

// TODO Auto-generated method stub

pausing = true;

// moving = false;

}

/*

  • 继续块的下落,对应游戏的继续

*/

public void resumeMove() {

// TODO Auto-generated method stub

pausing = false;

moving = true;

}

/*

  • 停止块的下落,对应游戏的停止

*/

public void stopMove() {

// TODO Auto-generated method stub

pausing = false;

moving = false;

}

/*

  • 将当前块从画布的对应位置移除,要等到下次重画画布时才能反映出来

*/

private void erase() {

for (int i = 0; i < boxes.length; i++) {

for (int j = 0; j < boxes[i].length; j++) {

if (boxes[i][j].isColorBox()) {

ErsBox box = canvas.getBox(i + y, j + x);

if (box == null) {

continue;

}

box.setColor(false);

}

}

}

}

/*

  • 让当前块放置在画布的对应位置上,要等到下次重画画布时,才能看见

*/

private void display() {

for (int i = 0; i < boxes.length; i++) {

for (int j = 0; j < boxes[i].length; j++) {

if (boxes[i][j].isColorBox()) {

ErsBox box = canvas.getBox(i + y, j + x);

if (box == null) {

continue;

}

box.setColor(true);

}

}

}

}

/**

  • 当前块能否移动到newRow/newCol 所指定的位置

  • @param newRow int,目的地所在行

  • @param newCol int,目的地所在列

  • @return boolean,true-能移动,false-不能移动

*/

public boolean isMoveAble(int newRow, int newCol) {

erase();

for (int i = 0; i < boxes.length; i++) {

for (int j = 0; j < boxes[i].length; j++) {

if (boxes[i][j].isColorBox()) {

ErsBox box = canvas.getBox(i + newRow, j + newCol);

if (box == null || (box.isColorBox())) {

display();

return false;

}

}

}

}

display();

return true;

}

/*

  • 将当前块移动到newRow/newCol所指定位置 newRow 目的所在行 newCol 目的所在列 boolean, true 能移动,false

  • 不能移动

*/

private synchronized boolean moveTo(int newRow, int newCol) {

if (!isMoveAble(newRow, newCol) || !moving) {

return false;

}

erase();

y = newRow;

x = newCol;

display();

canvas.repaint();

return true;

}

/*

  • 当前块能否变成newStyle所指定的样式,主要考虑 边界,以及被其他块挡住不能移动的情况 newStyle,希望改变的样式 boolean true

  • 能改变,false不能改变

*/

private boolean isTurnAble(int newStyle) {

int key = 0x80000;

erase();

for (int i = 0; i < boxes.length; i++) {

for (int j = 0; j < boxes[i].length; j++) {

if ((newStyle & key) != 0) {

ErsBox box = canvas.getBox(i + y, j + x);

if (box == null || (box.isColorBox())) {

display();

return false;

}

}

key >>= 1;

}

}

display();

return true;

}

/*

  • 将当前块变成newStyle所指定的块样式 newStyle ,希望改变的样式,对应STYLES中的某一个 true 改变成功,false改变失败

*/

private boolean turnTo(int newStyle) {

// TODO Auto-generated method stub

if (!isTurnAble(newStyle) || !moving) {

return false;

}

erase();

int key = 0x8000;

for (int i = 0; i < boxes.length; i++) {

for (int j = 0; j < boxes[i].length; j++) {

boolean isColor = ((newStyle & key) != 0);

boxes[i][j].setColor(isColor);

key >>= 1;

}

}

style = newStyle;

display();

canvas.repaint();

return true;

}

}

6、游戏主类,实现游戏控制

public RussiaBlocksGame(String title) {

super(title); // 设置标题

setSize(500, 600); // 设置窗口大小

setLocationRelativeTo(null); // 设置窗口居中

creatMenu();

Container container = getContentPane(); // 创建菜单栏

container.setLayout(new BorderLayout(6, 0)); // 设置窗口的布局管理器

canvas = new GameCanvas(20, 15); // 新建游戏画布

ctrlPanel = new ControlPanel(this); // 新建控制面板

container.add(canvas, BorderLayout.CENTER); // 左边加上画布

container.add(ctrlPanel, BorderLayout.EAST); // 右边加上控制面板

// 注册窗口事件。当点击关闭按钮时,结束游戏,系统退出。

addWindowListener(new WindowAdapter() {

@Override

public void windowClosing(WindowEvent we) {

stopGame();

System.exit(0);

}

});

// 根据窗口大小,自动调节方格的尺寸

addComponentListener(new ComponentAdapter() {

@Override

public void componentResized(ComponentEvent ce) {

canvas.adjust();

}

});

setVisible(true);

canvas.adjust();

}

/**

  • 让游戏复位

*/

public void reset() { // 画布复位,控制面板复位

ctrlPanel.setPlayButtonEnable(true);

ctrlPanel.setPauseButtonEnable(false);

ctrlPanel.setPauseButtonLabel(true);

ctrlPanel.setStopButtonEnable(false);
自我介绍一下,小编13年上海交大毕业,曾经在小公司待过,也去过华为、OPPO等大厂,18年进入阿里一直到现在。

深知大多数Java工程师,想要提升技能,往往是自己摸索成长或者是报班学习,但对于培训机构动则几千的学费,着实压力不小。自己不成体系的自学效果低效又漫长,而且极易碰到天花板技术停滞不前!

因此收集整理了一份《2024年Java开发全套学习资料》,初衷也很简单,就是希望能够帮助到想自学提升又不知道该从何学起的朋友,同时减轻大家的负担。img

既有适合小白学习的零基础资料,也有适合3年以上经验的小伙伴深入学习提升的进阶课程,基本涵盖了95%以上Java开发知识点,真正体系化!

由于文件比较大,这里只是将部分目录截图出来,每个节点里面都包含大厂面经、学习笔记、源码讲义、实战项目、讲解视频,并且会持续更新!

如果你觉得这些内容对你有帮助,可以扫码获取!!(备注Java获取)

img

总结

对于面试,一定要有良好的心态,这位小伙伴面试美团的时候没有被前面阿里的面试影响到,发挥也很正常,也就能顺利拿下美团的offer。
小编还整理了大厂java程序员面试涉及到的绝大部分面试题及答案,希望能帮助到大家,

在这里插入图片描述

在这里插入图片描述

最后感谢大家的支持,希望小编整理的资料能够帮助到大家!也祝愿大家都能够升职加薪!
《一线大厂Java面试题解析+核心总结学习笔记+最新讲解视频+实战项目源码》点击传送门即可获取!
l(true);

ctrlPanel.setStopButtonEnable(false);
自我介绍一下,小编13年上海交大毕业,曾经在小公司待过,也去过华为、OPPO等大厂,18年进入阿里一直到现在。

深知大多数Java工程师,想要提升技能,往往是自己摸索成长或者是报班学习,但对于培训机构动则几千的学费,着实压力不小。自己不成体系的自学效果低效又漫长,而且极易碰到天花板技术停滞不前!

因此收集整理了一份《2024年Java开发全套学习资料》,初衷也很简单,就是希望能够帮助到想自学提升又不知道该从何学起的朋友,同时减轻大家的负担。[外链图片转存中…(img-FjTmo5Yi-1712025024246)]

[外链图片转存中…(img-bqFZpd07-1712025024247)]

[外链图片转存中…(img-2Ash5qNq-1712025024247)]

既有适合小白学习的零基础资料,也有适合3年以上经验的小伙伴深入学习提升的进阶课程,基本涵盖了95%以上Java开发知识点,真正体系化!

由于文件比较大,这里只是将部分目录截图出来,每个节点里面都包含大厂面经、学习笔记、源码讲义、实战项目、讲解视频,并且会持续更新!

如果你觉得这些内容对你有帮助,可以扫码获取!!(备注Java获取)

img

总结

对于面试,一定要有良好的心态,这位小伙伴面试美团的时候没有被前面阿里的面试影响到,发挥也很正常,也就能顺利拿下美团的offer。
小编还整理了大厂java程序员面试涉及到的绝大部分面试题及答案,希望能帮助到大家,

[外链图片转存中…(img-ct3VEz8w-1712025024248)]

[外链图片转存中…(img-OkLc8z6U-1712025024248)]

最后感谢大家的支持,希望小编整理的资料能够帮助到大家!也祝愿大家都能够升职加薪!
《一线大厂Java面试题解析+核心总结学习笔记+最新讲解视频+实战项目源码》点击传送门即可获取!

版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。
本文链接:https://blog.csdn.net/Tx1xQn9G4/article/details/137261424

智能推荐

JWT(Json Web Token)实现无状态登录_无状态token登录-程序员宅基地

文章浏览阅读685次。1.1.什么是有状态?有状态服务,即服务端需要记录每次会话的客户端信息,从而识别客户端身份,根据用户身份进行请求的处理,典型的设计如tomcat中的session。例如登录:用户登录后,我们把登录者的信息保存在服务端session中,并且给用户一个cookie值,记录对应的session。然后下次请求,用户携带cookie值来,我们就能识别到对应session,从而找到用户的信息。缺点是什么?服务端保存大量数据,增加服务端压力 服务端保存用户状态,无法进行水平扩展 客户端请求依赖服务.._无状态token登录

SDUT OJ逆置正整数-程序员宅基地

文章浏览阅读293次。SDUT OnlineJudge#include<iostream>using namespace std;int main(){int a,b,c,d;cin>>a;b=a%10;c=a/10%10;d=a/100%10;int key[3];key[0]=b;key[1]=c;key[2]=d;for(int i = 0;i<3;i++){ if(key[i]!=0) { cout<<key[i.

年终奖盲区_年终奖盲区表-程序员宅基地

文章浏览阅读2.2k次。年终奖采用的平均每月的收入来评定缴税级数的,速算扣除数也按照月份计算出来,但是最终减去的也是一个月的速算扣除数。为什么这么做呢,这样的收的税更多啊,年终也是一个月的收入,凭什么减去12*速算扣除数了?这个霸道(不要脸)的说法,我们只能合理避免的这些跨级的区域了,那具体是那些区域呢?可以参考下面的表格:年终奖一列标红的一对便是盲区的上下线,发放年终奖的数额一定一定要避免这个区域,不然公司多花了钱..._年终奖盲区表

matlab 提取struct结构体中某个字段所有变量的值_matlab读取struct类型数据中的值-程序员宅基地

文章浏览阅读7.5k次,点赞5次,收藏19次。matlab结构体struct字段变量值提取_matlab读取struct类型数据中的值

Android fragment的用法_android reader fragment-程序员宅基地

文章浏览阅读4.8k次。1,什么情况下使用fragment通常用来作为一个activity的用户界面的一部分例如, 一个新闻应用可以在屏幕左侧使用一个fragment来展示一个文章的列表,然后在屏幕右侧使用另一个fragment来展示一篇文章 – 2个fragment并排显示在相同的一个activity中,并且每一个fragment拥有它自己的一套生命周期回调方法,并且处理它们自己的用户输_android reader fragment

FFT of waveIn audio signals-程序员宅基地

文章浏览阅读2.8k次。FFT of waveIn audio signalsBy Aqiruse An article on using the Fast Fourier Transform on audio signals. IntroductionThe Fast Fourier Transform (FFT) allows users to view the spectrum content of _fft of wavein audio signals

随便推点

Awesome Mac:收集的非常全面好用的Mac应用程序、软件以及工具_awesomemac-程序员宅基地

文章浏览阅读5.9k次。https://jaywcjlove.github.io/awesome-mac/ 这个仓库主要是收集非常好用的Mac应用程序、软件以及工具,主要面向开发者和设计师。有这个想法是因为我最近发了一篇较为火爆的涨粉儿微信公众号文章《工具武装的前端开发工程师》,于是建了这么一个仓库,持续更新作为补充,搜集更多好用的软件工具。请Star、Pull Request或者使劲搓它 issu_awesomemac

java前端技术---jquery基础详解_简介java中jquery技术-程序员宅基地

文章浏览阅读616次。一.jquery简介 jQuery是一个快速的,简洁的javaScript库,使用户能更方便地处理HTML documents、events、实现动画效果,并且方便地为网站提供AJAX交互 jQuery 的功能概括1、html 的元素选取2、html的元素操作3、html dom遍历和修改4、js特效和动画效果5、css操作6、html事件操作7、ajax_简介java中jquery技术

Ant Design Table换滚动条的样式_ant design ::-webkit-scrollbar-corner-程序员宅基地

文章浏览阅读1.6w次,点赞5次,收藏19次。我修改的是表格的固定列滚动而产生的滚动条引用Table的组件的css文件中加入下面的样式:.ant-table-body{ &amp;amp;::-webkit-scrollbar { height: 5px; } &amp;amp;::-webkit-scrollbar-thumb { border-radius: 5px; -webkit-box..._ant design ::-webkit-scrollbar-corner

javaWeb毕设分享 健身俱乐部会员管理系统【源码+论文】-程序员宅基地

文章浏览阅读269次。基于JSP的健身俱乐部会员管理系统项目分享:见文末!

论文开题报告怎么写?_开题报告研究难点-程序员宅基地

文章浏览阅读1.8k次,点赞2次,收藏15次。同学们,是不是又到了一年一度写开题报告的时候呀?是不是还在为不知道论文的开题报告怎么写而苦恼?Take it easy!我带着倾尽我所有开题报告写作经验总结出来的最强保姆级开题报告解说来啦,一定让你脱胎换骨,顺利拿下开题报告这个高塔,你确定还不赶快点赞收藏学起来吗?_开题报告研究难点

原生JS 与 VUE获取父级、子级、兄弟节点的方法 及一些DOM对象的获取_获取子节点的路径 vue-程序员宅基地

文章浏览阅读6k次,点赞4次,收藏17次。原生先获取对象var a = document.getElementById("dom");vue先添加ref <div class="" ref="divBox">获取对象let a = this.$refs.divBox获取父、子、兄弟节点方法var b = a.childNodes; 获取a的全部子节点 var c = a.parentNode; 获取a的父节点var d = a.nextSbiling; 获取a的下一个兄弟节点 var e = a.previ_获取子节点的路径 vue