博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
java实现的俄罗斯方块游戏--powered by dustin
阅读量:4090 次
发布时间:2019-05-25

本文共 9962 字,大约阅读时间需要 33 分钟。

学习java时间不长,跟着学习视频敲过一个贪吃蛇的游戏代码,遂产生了仿写一个俄罗斯方游戏的想法。用了六天时间终于实现了最基本的功能,然而bug仍然很多,不过运行成功玩几局仍然很开森哇!期间遇到了很多难题,很伤脑筋,不过还是一个个地解决掉了,真心希望自己在学习java的路上能一直保持热情,keep fighting!!
新手程序员--java实现的俄罗斯方块游戏 - duslish - duslish的博客
在游戏中我使用了两个类(貌似不是最优的面向对象思维),一个是游戏的窗体Yard类,另一个是方块Brick类。算法的思想主要有:1.使用二维数组保存方块的形状。2.起一个线程用于方块的刷新和重绘。3.在方块未触底时(即isReachDown()返回FALSE)方块对象调用向下自动运动的方法。4.当方块触底,新new一个方块的形状。5.采用一个巨大的二维数组保存落地的方块,这是方块对象和落地方块用不同的数组进行保存。6.有了这个背景数组之后,消行和下行就很好实现了。
import java.awt.Color; import java.awt.Graphics; import java.awt.event.KeyEvent; import java.util.Random; public class Brick {
boolean reachdown = false; private static Random r = new Random(); public boolean[][] s = new boolean[4][4]; boolean[][] s1 = new boolean[4][4]; final boolean[][] b1 = {
{false,false,false,false},{false,false,false,false},{false,false,false,false},{true,true,true,true} };//任意位置 final boolean[][] b2 = {
{false,false,false,false},{false,false,false,false},{true,false,false,false},{true,true,true,false} };//靠左 final boolean[][] b3 = {
{false,false,false,true},{false,false,false,true},{false,false,false,true},{false,true,true,true} };//靠右 final boolean[][] b4 = {
{false,false,false,false},{false,false,false,false},{true,true,false,false},{true,true,false,false} };//靠左 final boolean[][] b5 = {
{false,false,false,false},{false,false,false,false},{false,false,true,false},{false,true,true,true} };//靠右 final boolean[][] b6 = {
{false,false,false,false},{false,false,false,false},{false,true,false,false},{false,true,false,false} }; boolean[][] background={
{false,false,false,false,false,false,false,false,false,false,false,false,false,false,false}, {false,false,false,false,false,false,false,false,false,false,false,false,false,false,false}, {false,false,false,false,false,false,false,false,false,false,false,false,false,false,false}, {false,false,false,false,false,false,false,false,false,false,false,false,false,false,false}, {false,false,false,false,false,false,false,false,false,false,false,false,false,false,false}, {false,false,false,false,false,false,false,false,false,false,false,false,false,false,false}, {false,false,false,false,false,false,false,false,false,false,false,false,false,false,false}, {false,false,false,false,false,false,false,false,false,false,false,false,false,false,false}}; S_node[][] background_str = new S_node[8][15]; S_node[][] str = new S_node[4][4]; int[] downside = new int[15]; int[] upside = new int[4]; int begin_r = 1; int begin_c = 11; private class S_node{
final int node_w = Yard.NODE_SIZE; final int node_h = Yard.NODE_SIZE; int row,col; S_node(int row,int col){
this.row =row ; this.col = col; } void draw(Graphics g){
Color c = g.getColor(); g.setColor(Color.WHITE); g.fillRect(col *node_w, row *node_h, node_w, node_h); g.setColor(c); } } public void getCode(){
switch((r.nextInt(6))){
case 0 : for(int i =0;i<4;i++){
for(int j=0;j<4;j++){
s[i][j] = b1[i][j]; } } break; case 1: for(int i =0;i<4;i++){
for(int j=0;j<4;j++){
s[i][j] = b2[i][j]; } } break; case 2 : for(int i =0;i<4;i++){
for(int j=0;j<4;j++){
s[i][j] = b3[i][j]; } } break; case 3: for(int i =0;i<4;i++){
for(int j=0;j<4;j++){
s[i][j] = b4[i][j]; } } break; case 4 : for(int i =0;i<4;i++){
for(int j=0;j<4;j++){
s[i][j] = b5[i][j]; } } break; case 5 : for(int i =0;i<4;i++){
for(int j=0;j<4;j++){
s[i][j] = b6[i][j]; } } break; } } public void getStr(){
for(int i =0;i<4;i++){
for(int j=0;j<4;j++){
if(s[i][j]==true){
str[i][j] = new S_node(begin_r+i,begin_c+j); //绝对坐标 } } } } public void draw(Graphics g){
this.getStr(); for(int i=0; i<4; i++){
upside[i] = 0; } for(int i=0; i<15; i++){
downside[i] = 0; } for(int i =0;i<4;i++){
for(int j=0;j<4;j++){
if(str[i][j]!=null){
str[i][j].draw(g); } } } for(int i=0;i<8;i++){
for(int j=0;j<15;j++){
if(background[i][j]==true){
background_str[i][j] = new S_node(16+i,j+5); } if(background[i][j]==false){
background_str[i][j] = null; } if(background_str[i][j]!=null){
background_str[i][j].draw(g); } } //************ 让满行的消掉********************// if((background[i][0]==true)&&(background[i][1]==true)&&(background[i][2]==true)&&(background[i][4]==true)&& (background[i][5]==true)&&(background[i][6]==true)&&(background[i][7]==true)&&(background[i][8]==true)&& (background[i][9]==true)&&(background[i][10]==true)&&(background[i][11]==true)&&(background[i][12]==true)&& (background[i][13]==true)&&(background[i][14]==true)&&(background[i][3]==true)){
for(int k= 0;k<15;k++){
background[i][k]=false; } //******************** 下行一行*****************// for(int l=i;l>0;l--){
for(int m=0;m<15;m++){
background[l][m]=background[l-1][m]; } } for(int n=0;n<15;n++){
background[0][n]=false; } } // *************************************************// } //****************** 用以记录上下目标位置的数组赋值***************// for(int j=7; j>=0; j--){
for(int i=0; i<15; i++){
if(background[j][i]==true){
downside[i] = 8-j; continue; } } } for(int i=0; i<4; i++){
for(int j=3; j>=0; j--){
if(str[j][i]!=null){
upside[i]=3-j; //离最下一行的空缺数 break; } else upside[i]=4; } } //***************************************************// if(!isReachDown()){
this.moveDown(); } else{
for(int i =0;i<4;i++){
for(int j=0;j<4;j++){
if(str[i][j]!=null){
background[this.begin_r+ i - 16][this.begin_c + j - 5 ]=true; } } } reachdown=false; this.begin_r=1; this.begin_c=10; for(int i =0;i<4;i++){
for(int j=0;j<4;j++){
str[i][j]=null; s[i][j]=false; } } this.getCode(); } } public void moveDown(){
for(int i =0;i<4;i++){
for(int j=0;j<4;j++){
if(str[i][j]!=null){
str[i][j]=new S_node(begin_r+i,begin_c+j); } } } begin_r++; } public void moveLeft(){
for(int i =0;i<4;i++){
for(int j=0;j<4;j++){
if(str[i][j]!=null){
str[i][j]=new S_node(begin_r+i,begin_c+j); } } } begin_c--; } public void moveRight(){
for(int i =0;i<4;i++){
for(int j=0;j<4;j++){
if(str[i][j]!=null){
str[i][j]=new S_node(begin_r+i,begin_c+j); } } } begin_c++; } public boolean isReachDown(){
//************************ 碰撞式触底*************// 解决当str[i]==null的情况 if((str[3][1].row<=(22+upside[0]-downside[str[3][1].col-6]))&&(str[3][1].row<=(22+upside[1]-downside[str[3][1].col-5]))&&(str[3][1].row<=(22+upside[2]-downside[str[3][1].col-4]))&&(str[3][1].row<=(22+upside[3]-downside[str[3][1].col-3]))) return reachdown; //*********************************************// reachdown=true; return reachdown; } public void keyPressed(KeyEvent e){
int Key = e.getKeyCode(); switch(Key){
case KeyEvent.VK_LEFT : this.moveLeft(); break; case KeyEvent.VK_RIGHT: this.moveRight(); break; } } }
                                                                                   
 Brick类
 
import java.awt.Color; import java.awt.Frame; import java.awt.Graphics; import java.awt.event.KeyAdapter; import java.awt.event.KeyEvent; import java.awt.event.WindowAdapter; import java.awt.event.WindowEvent; public class Yard extends Frame {
public static final int ROW = 25 ; public static final int COL = 25 ; public static final int NODE_SIZE = 20 ; public boolean flag = true; public Brick b = new Brick(); public void launch(){
this.setLocation(200, 200); this.setSize(COL * NODE_SIZE, ROW *NODE_SIZE); this.setVisible(true) ; this.addWindowListener(new WindowAdapter(){
public void windowClosing(WindowEvent e){
System.exit(0); } } ); b.getCode(); this.addKeyListener(new KeyMonitor()); new Thread(new Spaint()).start(); } public void paint(Graphics g){
Color c = g.getColor(); g.setColor(new Color(0,0,128)); g.fillRect(0, 0, COL * NODE_SIZE, ROW * NODE_SIZE); g.setColor(new Color(50,205,50)); g.fillRect(0,0,COL * NODE_SIZE,NODE_SIZE*2); //将边框刷白 g.fillRect(0,0,NODE_SIZE*5,NODE_SIZE*ROW); g.fillRect(0,NODE_SIZE*(ROW - 1),COL * NODE_SIZE,NODE_SIZE*2); g.fillRect(NODE_SIZE*(ROW - 5),0 , NODE_SIZE*6, NODE_SIZE*ROW); g.setColor(new Color(255,255,255)); g.drawString("Designed ", 420, 200); g.drawString("By ", 420, 250); g.drawString("Dustin ", 420, 300); g.setColor(c); b.draw(g); } private class Spaint implements Runnable{
public void run(){
while(flag){
repaint(); for(int i=0; i<15; i++){
System.out.print(b.downside[i]); } System.out.println(); for(int i=0; i<4; i++){
System.out.print(b.upside[i]); } System.out.println(); try{
Thread.sleep(400); }catch(InterruptedException e){
e.printStackTrace(); } } } } private class KeyMonitor extends KeyAdapter{
public void keyPressed(KeyEvent e){
b.keyPressed(e); } } public static void main(String[] args) {
new Yard().launch(); } }
  
                                                                            Yard类
代码如上所示,总共用了400余行,游戏还存在着两个主要的问题,一是有些情况会出现数组越界的异常,这是由于方块的二维数组中为空的地方超出了背景数组的范围,我认为可以通过增加背景数组的宽度解决。第二是我还没有添加变形的功能,也希望喜欢编程的朋友能完善它,一起交流学习!共同提高!

转载地址:http://sfdii.baihongyu.com/

你可能感兴趣的文章
MyBatis常见面试题
查看>>
Qt——pro文件的使用&Qt调用dll
查看>>
Object源码阅读笔记
查看>>
Object、String的hashCode()和equals()对比
查看>>
Object的clone()方法的使用
查看>>
java.lang.Object.clone()解读
查看>>
instanceof运算符初探
查看>>
Java中package(包)的总结(一)
查看>>
Java的JAVA_HOME、Path、CLASSPATH环境变量小结
查看>>
Java中package(包)的总结(二)
查看>>
Java的编译、运行
查看>>
【线性表】线性表
查看>>
【非线性结构】树
查看>>
【线性表】栈
查看>>
【线性表】队列
查看>>
【动态规划】三种背包问题(01背包、完全背包、多重背包)
查看>>
【贪心策略】背包问题
查看>>
【贪心策略】硬币问题
查看>>
【分治】归并排序
查看>>
算法导论——第二章习题
查看>>