(心得一)java俄罗斯方块小游戏编写心得
? ? 首先,對游戲進行分析,俄羅斯方塊由七種方塊及游戲界面組成,再進行細(xì)分,七種方塊可拆分成四個最基本小方塊,而游戲界面可分為窗體上嵌入一塊游戲面板。所以,首先對游戲的最基本元素最基本小方塊進行構(gòu)造,編寫一個Cell類
對Cell類進行分析,最基本小方塊所具有的屬性為行row,列col,圖片Image;所具有的行為為左移,右移,下落(七種方塊的左移、右移、下落實質(zhì)上為最基本小方塊的左移、右移、下落)。
注:在編寫代碼時,需要遵守JavaBean規(guī)范,即程序員在定義類時,默認(rèn)遵守的一種規(guī)范。
代碼如下:
package com.tetris;
import java.awt.image.BufferedImage;
public class Cell {
?? ?private int row;
?? ?private int col;
?? ?private BufferedImage image;
?? ?public Cell() {}
?? ?public Cell(int row, int col, BufferedImage image) {
?? ??? ?super();
?? ??? ?this.row = row;
?? ??? ?this.col = col;
?? ??? ?this.image = image;
?? ?}
?? ?public int getRow() {
?? ??? ?return row;
?? ?}
?? ?public void setRow(int row) {
?? ??? ?this.row = row;
?? ?}
?? ?public int getCol() {
?? ??? ?return col;
?? ?}
?? ?public void setCol(int col) {
?? ??? ?this.col = col;
?? ?}
?? ?public BufferedImage getImage() {
?? ??? ?return image;
?? ?}
?? ?public void setImage(BufferedImage image) {
?? ??? ?this.image = image;
?? ?}
?? ?@Override
?? ?public String toString() {
?? ??? ?return "Cell [row=" + row + ", col=" + col + ", image=" + image + "]";
?? ?}
?? ?//向左移動
?? ?public void left() {
?? ??? ?col--;
?? ?}
?? ?//向右移動
?? ?public void right() {
?? ??? ?col++;
?? ?}
?? ?public void drop() {
?? ??? ?row++;
?? ?}
}
游戲最基本小方塊類已經(jīng)寫完,接下來的第二步,就是需要用最基本小方塊組合出來七種方塊,而七種方塊統(tǒng)一是由四個最基本小方塊組成,所以我們可以先編寫一個四格方塊類,即取出四個最基本小方塊放入二維數(shù)組中,構(gòu)成一個四格方塊,但是此時方塊還未組成七種基本圖形,只是在定義其行為及屬性,為接下來的七種圖形的構(gòu)造提供方便。最終的七種方塊的形狀,由各個類繼承本類來進行構(gòu)造。對該類進行分析,四格方塊所具有的屬性為四個最基本小方塊,方法同最基本小方塊方法相同,即左移、右移、下落
代碼如下:
package com.tetris;
public class Tetromino {
?? ?protected Cell[] cells=new Cell[4];
?? ?public void moveLefr() {
?? ??? ?for(int i=0;i<cells.length;i++) {
?? ??? ??? ?cells[i].left();
?? ??? ?}
?? ?}
?? ?public void moveRight() {
?? ??? ?for(int i=0;i<cells.length;i++) {
?? ??? ??? ?cells[i].right();;
?? ??? ?}
?? ?}
?? ?public void softDrop() {
?? ??? ?for(int i=0;i<cells.length;i++) {
?? ??? ??? ?cells[i].drop();
?? ??? ?}
?? ?}
}
七種方塊可抽象為字母I,S,T,Z,L,O,J,如圖所示,若想將最基本小方塊組合成七種方塊,需要將最基本方塊放在一個二維數(shù)組中,行列號圖中已經(jīng)給出,所以可編寫出I,S,T,Z,L,O,J類,分別代表七種方塊。
七種小方塊圖片為:I:??J:? L:? O:? S:? T:? Z:?,在使用圖片時,需要將圖片放入到同一包下。
?
代碼如下:
I:
package com.tetris;
public class I extends Tetromino {
?? ?public I() {
?? ??? ?cells[0]=new Cell(0,4,Tetris.I);
?? ??? ?cells[1]=new Cell(0,3,Tetris.I);
?? ??? ?cells[2]=new Cell(0,5,Tetris.I);
?? ??? ?cells[3]=new Cell(0,6,Tetris.I);
?? ?}
}
J:
package com.tetris;
public class J extends Tetromino {
?? ?public J() {
?? ??? ?cells[0]=new Cell(0,4,Tetris.J);
?? ??? ?cells[1]=new Cell(0,3,Tetris.J);
?? ??? ?cells[2]=new Cell(0,5,Tetris.J);
?? ??? ?cells[3]=new Cell(1,5,Tetris.J);
?? ?}
}
L:
package com.tetris;
public class L extends Tetromino {
?? ?public L() {
?? ??? ?cells[0]=new Cell(0,4,Tetris.L);
?? ??? ?cells[1]=new Cell(0,3,Tetris.L);
?? ??? ?cells[2]=new Cell(0,5,Tetris.L);
?? ??? ?cells[3]=new Cell(1,3,Tetris.L);
?? ?}
}
O:
package com.tetris;
public class O extends Tetromino {
?? ?public O() {
?? ??? ?cells[0]=new Cell(0,4,Tetris.O);
?? ??? ?cells[1]=new Cell(0,5,Tetris.O);
?? ??? ?cells[2]=new Cell(1,4,Tetris.O);
?? ??? ?cells[3]=new Cell(1,5,Tetris.O);
?? ?}
}
S:
package com.tetris;
public class S extends Tetromino {
?? ?public S() {
?? ??? ?cells[0]=new Cell(0,4,Tetris.S);
?? ??? ?cells[1]=new Cell(0,5,Tetris.S);
?? ??? ?cells[2]=new Cell(1,3,Tetris.S);
?? ??? ?cells[3]=new Cell(1,4,Tetris.S);
?? ?}
}
T:
package com.tetris;
public class T extends Tetromino{
?? ?//提供構(gòu)造器,進行初始化T形的四格方塊的位置
?? ?public T() {
?? ??? ?cells[0]=new Cell(0,4,Tetris.T);
?? ??? ?cells[1]=new Cell(0,3,Tetris.T);
?? ??? ?cells[2]=new Cell(0,5,Tetris.T);
?? ??? ?cells[3]=new Cell(1,4,Tetris.T);
?? ?}
}
Z:
package com.tetris;
public class Z extends Tetromino{
?? ?public Z(){
?? ??? ?cells[0]=new Cell(1,4,Tetris.Z);
?? ??? ?cells[1]=new Cell(0,3,Tetris.Z);
?? ??? ?cells[2]=new Cell(0,4,Tetris.Z);
?? ??? ?cells[3]=new Cell(1,5,Tetris.Z);
?? ?}
}
代碼到了這,七種方塊已經(jīng)構(gòu)造完成,但是代碼到了這會出錯,因為我們在使用圖片時只是將圖片引到了同一包下,并沒有將圖片讀進來,如果我們在這七種方塊類中加入圖片讀取,那么就會出現(xiàn)一個問題,在最終寫完后,圖片會是使用一次加載一次,會造成不必要的浪費,所以我們現(xiàn)在需要一個主類,來將圖片在程序運行最初就將圖片加載進來,在以后的使用中只對其進行調(diào)用即可,不需要重新加載。
代碼如下:
package com.tetris;?
import java.awt.image.BufferedImage;
import javax.imageio.ImageIO;
?? ?public class Tetris{
?? ??? ?public static BufferedImage T;
?? ??? ?public static BufferedImage I;
?? ??? ?public static BufferedImage O;
?? ??? ?public static BufferedImage J;
?? ??? ?public static BufferedImage L;
?? ??? ?public static BufferedImage S;
?? ??? ?public static BufferedImage Z;
?? ??? ?public static BufferedImage background;
?? ??? ?static {
?? ??? ??? ?try {
?? ??? ??? ??? ??? ?T=ImageIO.read(Tetris.class.getResource("T.png"));
?? ??? ??? ??? ??? ?I=ImageIO.read(Tetris.class.getResource("I.png"));
?? ??? ??? ??? ??? ?O=ImageIO.read(Tetris.class.getResource("O.png"));
?? ??? ??? ??? ??? ?J=ImageIO.read(Tetris.class.getResource("J.png"));
?? ??? ??? ??? ??? ?L=ImageIO.read(Tetris.class.getResource("L.png"));
?? ??? ??? ??? ??? ?S=ImageIO.read(Tetris.class.getResource("S.png"));
?? ??? ??? ??? ??? ?Z=ImageIO.read(Tetris.class.getResource("Z.png"));
?? ??? ??? ??? ??? ?background=ImageIO.read(Tetris.class.getResource("tetris.png"));
?? ??? ??? ??? ?}catch(Exception e) {
?? ??? ??? ??? ??? ?e.printStackTrace();
?? ??? ??? ??? ?}
?? ??? ?}
?? ?}
代碼到了這里,根據(jù)之前的分析,七種方塊的構(gòu)造已經(jīng)完成,還需要一個游戲面板,而游戲面板是一進游戲首先出現(xiàn)的就是這個面板,所以也可以說它是游戲的入口,也就是整個程序的開始的地方,所以需要寫在主類的main方法中,因為主類即游戲界面,所以可以使主類繼承JPanel,那么在創(chuàng)建主類對象時,就是創(chuàng)建了一個游戲面板。
代碼如下:
package com.tetris;?
import java.awt.image.BufferedImage;
import javax.imageio.ImageIO;
import javax.swing.JFrame;
import javax.swing.JPanel;
public class Tetris extends JPanel{
?? ?public static void main(String[] args) {
?? ??? ?//創(chuàng)建一個窗口對象
?? ??? ?JFrame jf=new JFrame("火拼俄羅斯");
?? ??? ?//創(chuàng)建游戲界面,即面板
?? ??? ?Tetris panle=new Tetris();
?? ??? ?//將面板嵌入窗口
?? ??? ?jf.add(panle);
?? ??? ?//設(shè)置窗口可見
?? ??? ?jf.setVisible(true);
?? ??? ?//設(shè)置窗口的尺寸
?? ??? ?jf.setSize(535, 595);
?? ??? ?//設(shè)置窗口位置
?? ??? ?jf.setLocationRelativeTo(null);
?? ??? ?//設(shè)置窗口關(guān)閉,即程序終止
?? ??? ?jf.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
?? ?}
}
此時如果運行的話只會出現(xiàn)一個游戲界面,而游戲界面上什么都沒有,因為并沒有在面板上繪制任何東西,接下來我們需要分析一下面板上都要繪制什么,首先,有游戲背景,其次,在游戲開始時我們會有一個正在下落的方塊,在右邊還會有一個位置顯示下一個將要下落的方塊,這是面板上可見的元素,再分析,如果想要讓方塊顯示在游戲界面上,那便需要給方塊一個初始位置,而位置如何表示,我們可以衍生出一個抽象的墻的概念,即方塊是在墻上的,這便是面板上可見與不可見的元素。我們需要將這些屬性封裝在JPanel的自動調(diào)用方法paint()方法中,但是我們需要對paint()方法進行重寫。
代碼如下:
package com.tetris;?
import java.awt.Graphics;
import java.awt.image.BufferedImage;
import javax.imageio.ImageIO;
import javax.swing.JFrame;
import javax.swing.JPanel;
public class Tetris extends JPanel{
?? ?public void paint(Graphics g) {
?? ??? ?//繪制背景
?? ??? ?g.drawImage(background, 0, 0, null);
?? ??? ?//繪制墻
?? ??? ?paintWall(g);
?? ??? ?//繪制正在下落的四格方塊
?? ??? ?paintCurrentOne(g);
?? ??? ?//繪制下一個將要下落的四格方塊
?? ??? ?paintNextOne(g);
?? ?}
}
此時我們需要對paintWall()、paintCurrentOne()、paintNextOne()方法進行定義,對paintWall()(繪制墻)方法進行分析,如果想要使方塊顯示在墻上,那就需要給方塊位置,位置用什么來表示,我們可以將墻定義為一個10列20行的二維數(shù)組,而墻的二維數(shù)組內(nèi)的元素為與最基本小方塊長寬相同的小方格,如上圖。
代碼如下:
package com.tetris;?
import java.awt.Graphics;
import java.awt.image.BufferedImage;
import javax.imageio.ImageIO;
import javax.swing.JFrame;
import javax.swing.JPanel;
public class Tetris extends JPanel{
?? ?public void paintWall(Graphics g) {
?? ??? ?//外層循環(huán)控制行數(shù)
?? ??? ?for(int i=0;i<20;i++) {
?? ??? ?//內(nèi)層循環(huán)控制列數(shù)
?? ??? ??? ?for(int j=0;j<10;j++) {
?? ??? ??? ??? ?int x=j*CELL_SIZE;
?? ??? ??? ??? ?int y=i*CELL_SIZE;
?? ??? ??? ??? ?Cell cell=wall[i][j];
?? ??? ??? ??? ?if(cell==null) {
?? ??? ??? ??? ??? ?//增加難度本句可加注釋
?? ??? ??? ??? ??? ?g.drawRect(x, y, CELL_SIZE, CELL_SIZE);
?? ??? ??? ??? ?}else {
?? ??? ??? ??? ??? ?g.drawImage(cell.getImage(), x, y, null);
?? ??? ??? ??? ?}
?? ??? ??? ?}
?? ??? ?}
?? ?}
}
然后分析即將下落方塊與正在下落方塊,之前已經(jīng)定義過七種圖形方塊,可以在主類中首先定義兩個Tetromino類型變量currentOne和nextOne,然后給兩個變量賦值,因為在游戲中方塊都是隨機出現(xiàn),所以需要一個隨機生成方塊的方法,在Tetromino類中定義此方法
代碼如下:
package com.tetris;
public class Tetromino {
?? ?protected Cell[] cells=new Cell[4];
?? ?public static Tetromino randomeOne() {
?? ?Tetromino t=null;
?? ?int num=(int)(Math.random()*7);
?? ?switch(num) {
?? ??? ?case 0:t=new T();break;
?? ??? ?case 1:t=new O();break;
?? ??? ?case 2:t=new I();break;
?? ??? ?case 3:t=new J();break;
?? ??? ?case 4:t=new L();break;
?? ??? ?case 5:t=new S();break;
?? ??? ?case 6:t=new Z();break;
?? ?}
?? ??? ?return t;
?? ?}
}
有了隨機生成方法后,就可以給currentOne與nextOne賦值,接下來就可以重新定義方法paintCurrentOne()方法
代碼如下:
package com.tetris;?
import java.awt.Graphics;
import java.awt.image.BufferedImage;
import javax.imageio.ImageIO;
import javax.swing.JFrame;
import javax.swing.JPanel;
public class Tetris extends JPanel{
?? ?public void paintCurrentOne(Graphics g){
?? ??? ?Cell[] cells=currentOne.cells;
?? ??? ?for(Cell c:cells) {
?? ??? ??? ?int x=c.getCol()*CELL_SIZE;
?? ??? ??? ?int y=c.getRow()*CELL_SIZE;?
?? ??? ??? ?g.drawImage(c.getImage(), x, y, null);
?? ??? ?}
?? ?}
}
接下來繼續(xù)分析nextOne,即將下落方塊因為要顯示在右上角,所以他的橫坐標(biāo)至少大于260像素,縱坐標(biāo)至少大于26.。
代碼如下:
package com.tetris;?
import java.awt.Graphics;
import java.awt.image.BufferedImage;
import javax.imageio.ImageIO;
import javax.swing.JFrame;
import javax.swing.JPanel;
public class Tetris extends JPanel{
?? ?public void paintNextOne(Graphics g) {
?? ??? ?//獲取nextOne對象的四個元素
?? ??? ?Cell[] cells=nextOne.cells;
?? ??? ?for(Cell c:cells) {
?? ??? ??? ?//獲取每一個元素的行號和列號
?? ??? ??? ?int row=c.getRow();
?? ??? ??? ?int col=c.getCol();
?? ??? ??? ?//橫坐標(biāo)、縱坐標(biāo)
?? ??? ??? ?int x=col*CELL_SIZE+260;
?? ??? ??? ?int y=row*CELL_SIZE+26;
?? ??? ??? ?g.drawImage(c.getImage(), x, y, null);
?? ??? ?}
?? ?}
}
現(xiàn)在運行代碼,可以看到游戲界面已經(jīng)完美,游戲的第一步已經(jīng)完成
總結(jié)
以上是生活随笔為你收集整理的(心得一)java俄罗斯方块小游戏编写心得的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 贵州计算机学业水平考试基础知识,贵州省高
- 下一篇: 2015年计算机技术应用大赛,2015年