Knowladge Is Free

Catatan Kuliah Teknik Informatika dan lain-lain

Source Code Java Game Testis 2D

http://zetcode.com/img/gfx/java2d/tetrominoes.png
Tetris game adalah satu [menyangkut] game komputer [yang] yang paling populer pernah menciptakan. game Yang asli dirancang dan diprogramkan oleh seorang orang Rusia Programmer Alexey Pajitnov di (dalam) 1985. Sejak itu, Tetris ada tersedia pada [atas] hampir tiap-tiap platform komputer di (dalam) kelompok variasi. Bahkan telepon [yang] gesit ku mempunyai suatu versi modifikasi [menyangkut] Tetris game.

 Tetris disebut suatu jatuh blok membingungkan game. Di (dalam) game ini, kita mempunyai tujuh bentuk berbeda [memanggil/hubungi] tetrominoes. S-Shape, Z-Shape, T-Shape, L-Shape, Line-Shape, Mirroredl-Shape dan suatu Square-Shape. Masing-Masing bentuk ini dibentuk dengan empat penyiku. Bentuk  sedang gagal/jatuh papan [itu]. Obyek dari  Tetris game akan pindah;gerakkan dan berputar bentuk, sedemikian sehingga mereka cocok [sedapat/ sebanyak] mungkin. Jika kita mengatur untuk membentuk suatu baris, baris dibinasakan dan kita mencetak (prestasi). Kita main Tetris game sampai kita puncak ke luar.

The development

Kita tidak mempunyai gambaran untuk [kita/kami] Tetris game, kita [menggambar/menarik] tetrominoes menggunakan Ayunan yang menggambar;menarik API. Di belakang tiap-tiap game komputer, ada suatu model matematika. Maka itu ada di Tetris.

 Beberapa gagasan di belakang game:
  •  Kita menggunakan suatu pengatur waktu Kelas untuk menciptakan suatu siklus game
  • Tetrominoes digambar/ditarik
  •  Bentuk berjalan terus suatu penyiku oleh basis bujur sangkar ( [yang] bukan pixel [oleh/dengan] pixel)
  • Mathematically suatu papan adalah suatu daftar sederhana angka-angka

Saya sudah menyederhanakan game sedikit, sedemikian sehingga adalah lebih mudah untuk memahami. Game start dengan seketika, setelah [itu] diluncurkan. Kita dapat berhenti game [oleh/dengan] menekan [itu] p menyetem. [ruang;spasi] Kunci akan menetes jatuh Tetris menambah dengan seketika kepada alas/pantat [itu]. D kunci akan menetes jatuh potongan satu garis menurun/jatuh. ( [Itu] dapat digunakan untuk mempercepat jatuh sedikit.) Game pergi pada kecepatan tetap, tidak (ada) akselerasi diterapkan. Score menjadi banyaknya bentuk, yang [itu] kita sudah memindahkan.
Tetris.java

package com.zetcode;

import java.awt.BorderLayout;

import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.SwingUtilities;


public class Tetris extends JFrame {

    private JLabel statusbar;

    public Tetris() {
        
        initUI();
   }
    
   private void initUI() {

        statusbar = new JLabel(" 0");
        add(statusbar, BorderLayout.SOUTH);
        Board board = new Board(this);
        add(board);
        board.start();

        setSize(200, 400);
        setTitle("Tetris");
        setDefaultCloseOperation(EXIT_ON_CLOSE);
        setLocationRelativeTo(null);       
   }

   public JLabel getStatusBar() {
       
       return statusbar;
   }

    public static void main(String[] args) {

        SwingUtilities.invokeLater(new Runnable() {
            
            @Override
            public void run() {
                
                Tetris game = new Tetris();
                game.setVisible(true);
            }
        });                
    } 
}
Dalam file Tetris.java, kami mendirikan permainan. Kami membuat papan di mana kita bermain game. Kami menciptakan sebuah statusbar.
board.start();
Method Start() Tetris game. dengan seketika setelah jendela nampak pada [atas] layar dekstop.

Shape.java

package com.zetcode;

import java.util.Random;

public class Shape {

    protected enum Tetrominoes { NoShape, ZShape, SShape, LineShape, 
               TShape, SquareShape, LShape, MirroredLShape };

    private Tetrominoes pieceShape;
    private int coords[][];
    private int[][][] coordsTable;


    public Shape() {

        coords = new int[4][2];
        setShape(Tetrominoes.NoShape);
    }

    public void setShape(Tetrominoes shape) {

         coordsTable = new int[][][] {
            { { 0, 0 },   { 0, 0 },   { 0, 0 },   { 0, 0 } },
            { { 0, -1 },  { 0, 0 },   { -1, 0 },  { -1, 1 } },
            { { 0, -1 },  { 0, 0 },   { 1, 0 },   { 1, 1 } },
            { { 0, -1 },  { 0, 0 },   { 0, 1 },   { 0, 2 } },
            { { -1, 0 },  { 0, 0 },   { 1, 0 },   { 0, 1 } },
            { { 0, 0 },   { 1, 0 },   { 0, 1 },   { 1, 1 } },
            { { -1, -1 }, { 0, -1 },  { 0, 0 },   { 0, 1 } },
            { { 1, -1 },  { 0, -1 },  { 0, 0 },   { 0, 1 } }
        };

        for (int i = 0; i < 4 ; i++) {
            
            for (int j = 0; j < 2; ++j) {
                
                coords[i][j] = coordsTable[shape.ordinal()][i][j];
            }
        }
        
        pieceShape = shape;
    }

    private void setX(int index, int x) { coords[index][0] = x; }
    private void setY(int index, int y) { coords[index][1] = y; }
    public int x(int index) { return coords[index][0]; }
    public int y(int index) { return coords[index][1]; }
    public Tetrominoes getShape()  { return pieceShape; }

    public void setRandomShape() {
        
        Random r = new Random();
        int x = Math.abs(r.nextInt()) % 7 + 1;
        Tetrominoes[] values = Tetrominoes.values(); 
        setShape(values[x]);
    }

    public int minX() {
        
      int m = coords[0][0];
      
      for (int i=0; i < 4; i++) {
          
          m = Math.min(m, coords[i][0]);
      }
      
      return m;
    }


    public int minY() {
        
      int m = coords[0][1];
      
      for (int i=0; i < 4; i++) {
          
          m = Math.min(m, coords[i][1]);
      }
      
      return m;
    }

    public Shape rotateLeft() {
        
        if (pieceShape == Tetrominoes.SquareShape)
            return this;

        Shape result = new Shape();
        result.pieceShape = pieceShape;

        for (int i = 0; i < 4; ++i) {
            
            result.setX(i, y(i));
            result.setY(i, -x(i));
        }
        
        return result;
    }

    public Shape rotateRight() {
        
        if (pieceShape == Tetrominoes.SquareShape)
            return this;

        Shape result = new Shape();
        result.pieceShape = pieceShape;

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

            result.setX(i, -y(i));
            result.setY(i, x(i));
        }
        
        return result;
    }
}

bentuk Kelas menyediakan informasi tentang suatu Tetris potongan.
protected enum Tetrominoes { NoShape, ZShape, SShape, LineShape, 
            TShape, SquareShape, LShape, MirroredLShape };

Tetrominoes enum menjaga semua tujuh Tetris bentuk. lebih bentuk Yang kosong disebut di sini Noshape.
public Shape() {

    coords = new int[4][2];
    setShape(Tetrominoes.NoShape);
}
Ini menjadi pembangun dari  bentuk Kelas. Coords array [memegang/menjaga] yang nyata mengkoordinir suatu Tetris potongan.
coordsTable = new int[][][] {
   { { 0, 0 },   { 0, 0 },   { 0, 0 },   { 0, 0 } },
   { { 0, -1 },  { 0, 0 },   { -1, 0 },  { -1, 1 } },
   { { 0, -1 },  { 0, 0 },   { 1, 0 },   { 1, 1 } },
   { { 0, -1 },  { 0, 0 },   { 0, 1 },   { 0, 2 } },
   { { -1, 0 },  { 0, 0 },   { 1, 0 },   { 0, 1 } },
   { { 0, 0 },   { 1, 0 },   { 0, 1 },   { 1, 1 } },
   { { -1, -1 }, { 0, -1 },  { 0, 0 },   { 0, 1 } },
   { { 1, -1 },  { 0, -1 },  { 0, 0 },   { 0, 1 } }
};
array Yang coordsTable [memegang/menjaga] semua mungkin mengkoordinir nilai-nilai [dari;ttg] [kita/kami] Tetris potongan. Ini adalah suatu template dari yang (mana)  semua potongan mengambil mereka mengkoordinir nilai-nilai.
for (int i = 0; i < 4 ; i++) {
    
    for (int j = 0; j < 2; ++j) {
        
        coords[i][j] = coordsTable[shape.ordinal()][i][j];
    }
}
Di sini kita meletakkan [satu/ orang] baris [menyangkut] mengkoordinir nilai-nilai dari yang coordsTable [bagi/kepada] suatu coords array suatu Tetris potongan. Catat[lah penggunaan dari  nomor urut() metoda. Di (dalam) C++, suatu enum jenis esencially suatu bilangan bulat. Tidak sama dengan di (dalam) C++, Pulau Jawa enums adalah kelas penuh. Dan nomor urut() metoda kembali[kan posisi sekarang dari  enum mengetik di (dalam) enum menolak.

 Gambaran berikut  akan membantu memahami mengkoordinir nilai-nilai sedikit lebih []. Coords array [menyelamatkan;menabung] mengkoordinir dari  Tetris potongan. Sebagai contoh, angka-angka{ 0, - 1},{ 0, 0},{ - 1, 0},{ - 1, - 1}, menghadirkan suatu S-Shape diputar. Diagram berikut  menggambarkan bentuk [itu].
Coordinates
Figure: Coordinates
public Shape rotateLeft() {
    
    if (pieceShape == Tetrominoes.SquareShape)
        return this;

    Shape result = new Shape();
    result.pieceShape = pieceShape;

    for (int i = 0; i < 4; ++i) {
        
        result.setX(i, y(i));
        result.setY(i, -x(i));
    }
    
    return result;
}
Kode ini berputar potongan kepada yang ditinggalkan. Penyiku tidaklah harus diputar. Itu adalah mengapa kita sederhananya kembali[kan acuan kepada obyek yang sekarang [itu]. Pemandangan di gambaran yang sebelumnya akan membantu ke arah memahami perputaran [itu].
Board.java

package com.zetcode;

import java.awt.Color;
import java.awt.Dimension;
import java.awt.Graphics;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.KeyAdapter;
import java.awt.event.KeyEvent;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.Timer;

import com.zetcode.Shape.Tetrominoes;

public class Board extends JPanel 
        implements ActionListener {

    private final int BoardWidth = 10;
    private final int BoardHeight = 22;

    private Timer timer;
    private boolean isFallingFinished = false;
    private boolean isStarted = false;
    private boolean isPaused = false;
    private int numLinesRemoved = 0;
    private int curX = 0;
    private int curY = 0;
    private JLabel statusbar;
    private Shape curPiece;
    private Tetrominoes[] board;

    public Board(Tetris parent) {

        initBoard(parent);
    }
    
    private void initBoard(Tetris parent) {
        
       setFocusable(true);
       curPiece = new Shape();
       timer = new Timer(400, this);
       timer.start(); 

       statusbar =  parent.getStatusBar();
       board = new Tetrominoes[BoardWidth * BoardHeight];
       addKeyListener(new TAdapter());
       clearBoard();          
    }

    @Override
    public void actionPerformed(ActionEvent e) {
        
        if (isFallingFinished) {
            
            isFallingFinished = false;
            newPiece();
        } else {
            
            oneLineDown();
        }
    }

    private int squareWidth() { return (int) getSize().getWidth() / BoardWidth; }
    private int squareHeight() { return (int) getSize().getHeight() / BoardHeight; }
    private Tetrominoes shapeAt(int x, int y) { return board[(y * BoardWidth) + x]; }


    public void start()  {
        
        if (isPaused)
            return;

        isStarted = true;
        isFallingFinished = false;
        numLinesRemoved = 0;
        clearBoard();

        newPiece();
        timer.start();
    }

    private void pause()  {
        
        if (!isStarted)
            return;

        isPaused = !isPaused;
        
        if (isPaused) {
            
            timer.stop();
            statusbar.setText("paused");
        } else {
            
            timer.start();
            statusbar.setText(String.valueOf(numLinesRemoved));
        }
        
        repaint();
    }
    
    private void doDrawing(Graphics g) {
        
        Dimension size = getSize();
        int boardTop = (int) size.getHeight() - BoardHeight * squareHeight();

        for (int i = 0; i < BoardHeight; ++i) {
            
            for (int j = 0; j < BoardWidth; ++j) {
                
                Tetrominoes shape = shapeAt(j, BoardHeight - i - 1);
                
                if (shape != Tetrominoes.NoShape)
                    drawSquare(g, 0 + j * squareWidth(),
                               boardTop + i * squareHeight(), shape);
            }
        }

        if (curPiece.getShape() != Tetrominoes.NoShape) {
            
            for (int i = 0; i < 4; ++i) {
                
                int x = curX + curPiece.x(i);
                int y = curY - curPiece.y(i);
                drawSquare(g, 0 + x * squareWidth(),
                           boardTop + (BoardHeight - y - 1) * squareHeight(),
                           curPiece.getShape());
            }
        }        
    }

    @Override
    public void paintComponent(Graphics g) { 

        super.paintComponent(g);
        doDrawing(g);
    }

    private void dropDown() {
        
        int newY = curY;
        
        while (newY > 0) {
            
            if (!tryMove(curPiece, curX, newY - 1))
                break;
            --newY;
        }
        
        pieceDropped();
    }

    private void oneLineDown()  {
        
        if (!tryMove(curPiece, curX, curY - 1))
            pieceDropped();
    }


    private void clearBoard() {
        
        for (int i = 0; i < BoardHeight * BoardWidth; ++i)
            board[i] = Tetrominoes.NoShape;
    }

    private void pieceDropped() {
        
        for (int i = 0; i < 4; ++i) {
            
            int x = curX + curPiece.x(i);
            int y = curY - curPiece.y(i);
            board[(y * BoardWidth) + x] = curPiece.getShape();
        }

        removeFullLines();

        if (!isFallingFinished)
            newPiece();
    }

    private void newPiece()  {
        
        curPiece.setRandomShape();
        curX = BoardWidth / 2 + 1;
        curY = BoardHeight - 1 + curPiece.minY();

        if (!tryMove(curPiece, curX, curY)) {
            
            curPiece.setShape(Tetrominoes.NoShape);
            timer.stop();
            isStarted = false;
            statusbar.setText("game over");
        }
    }

    private boolean tryMove(Shape newPiece, int newX, int newY) {
        
        for (int i = 0; i < 4; ++i) {
            
            int x = newX + newPiece.x(i);
            int y = newY - newPiece.y(i);
            
            if (x < 0 || x >= BoardWidth || y < 0 || y >= BoardHeight)
                return false;
            
            if (shapeAt(x, y) != Tetrominoes.NoShape)
                return false;
        }

        curPiece = newPiece;
        curX = newX;
        curY = newY;

        repaint();

        return true;
    }

    private void removeFullLines() {
        
        int numFullLines = 0;

        for (int i = BoardHeight - 1; i >= 0; --i) {
            boolean lineIsFull = true;

            for (int j = 0; j < BoardWidth; ++j) {
                if (shapeAt(j, i) == Tetrominoes.NoShape) {
                    lineIsFull = false;
                    break;
                }
            }

            if (lineIsFull) {
                ++numFullLines;
                for (int k = i; k < BoardHeight - 1; ++k) {
                    for (int j = 0; j < BoardWidth; ++j)
                         board[(k * BoardWidth) + j] = shapeAt(j, k + 1);
                }
            }
        }

        if (numFullLines > 0) {
            
            numLinesRemoved += numFullLines;
            statusbar.setText(String.valueOf(numLinesRemoved));
            isFallingFinished = true;
            curPiece.setShape(Tetrominoes.NoShape);
            repaint();
        }
     }

    private void drawSquare(Graphics g, int x, int y, Tetrominoes shape)  {
        
        Color colors[] = { new Color(0, 0, 0), new Color(204, 102, 102), 
            new Color(102, 204, 102), new Color(102, 102, 204), 
            new Color(204, 204, 102), new Color(204, 102, 204), 
            new Color(102, 204, 204), new Color(218, 170, 0)
        };

        Color color = colors[shape.ordinal()];

        g.setColor(color);
        g.fillRect(x + 1, y + 1, squareWidth() - 2, squareHeight() - 2);

        g.setColor(color.brighter());
        g.drawLine(x, y + squareHeight() - 1, x, y);
        g.drawLine(x, y, x + squareWidth() - 1, y);

        g.setColor(color.darker());
        g.drawLine(x + 1, y + squareHeight() - 1,
                         x + squareWidth() - 1, y + squareHeight() - 1);
        g.drawLine(x + squareWidth() - 1, y + squareHeight() - 1,
                         x + squareWidth() - 1, y + 1);

    }

    class TAdapter extends KeyAdapter {
        
         @Override
         public void keyPressed(KeyEvent e) {

             if (!isStarted || curPiece.getShape() == Tetrominoes.NoShape) {  
                 return;
             }

             int keycode = e.getKeyCode();

             if (keycode == 'p' || keycode == 'P') {
                 pause();
                 return;
             }

             if (isPaused)
                 return;

             switch (keycode) {
                 
             case KeyEvent.VK_LEFT:
                 tryMove(curPiece, curX - 1, curY);
                 break;
                 
             case KeyEvent.VK_RIGHT:
                 tryMove(curPiece, curX + 1, curY);
                 break;
                 
             case KeyEvent.VK_DOWN:
                 tryMove(curPiece.rotateRight(), curX, curY);
                 break;
                 
             case KeyEvent.VK_UP:
                 tryMove(curPiece.rotateLeft(), curX, curY);
                 break;
                 
             case KeyEvent.VK_SPACE:
                 dropDown();
                 break;
                 
             case 'd':
                 oneLineDown();
                 break;
                 
             case 'D':
                 oneLineDown();
                 break;
             }
         }
     }
}
Akhirnya, kita mempunyai Board.Java file. Inilah di mana logika game ditempatkan; terletak.
...
private boolean isFallingFinished = false;
private boolean isStarted = false;
private boolean isPaused = false;
private int numLinesRemoved = 0;
private int curX = 0;
private int curY = 0;
...
Kita initialize beberapa variabel penting. variabel Yang isFallingFinished menentukan, jika Tetris bentuk telah menyelesaikan jatuh dan kita kemudian harus menciptakan suatu bentuk baru. gelar ningrat Yang numLinesRemoved banyaknya bentuk, kita sudah memindahkan sejauh ini. Curx dan curY variabel menentukan posisi nyata dari  [yang] jatuh Tetris bentuk.
setFocusable(true);
Method Trymove() adalah method untuk pindah;gerakkan [itu] Tetris potongan. Metoda kembali[kan sumbang/palsu, jika [itu] telah mencapai batasan-batasan papan atau adalah bersebelahan kepada telah jatuh Tetris potongan.
int numFullLines = 0;

for (int i = BoardHeight - 1; i >= 0; --i) {
    boolean lineIsFull = true;

    for (int j = 0; j < BoardWidth; ++j) {
        if (shapeAt(j, i) == Tetrominoes.NoShape) {
            lineIsFull = false;
            break;
        }
    }

    if (lineIsFull) {
        ++numFullLines;
        for (int k = i; k < BoardHeight - 1; ++k) {
            for (int j = 0; j < BoardWidth; ++j)
                    board[(k * BoardWidth) + j] = shapeAt(j, k + 1);
        }
    }
}
Kita mengendalikan game dengan suatu papan tombol. kendali Mekanisme diterapkan dengan suatu Keyadapter. Ini adalah suatu kelas bagian dalam yang mengesampingkan yang keyPressed() method.
case KeyEvent.VK_LEFT:
    tryMove(curPiece, curX - 1, curY);
    break;
Jika kita tekan kunci panah yang ditinggalkan, kita mencoba untuk pindah;gerakkan jatuh potongan satu penyiku kepada [yang] yang ditinggalkan [itu].

Tetris




Share this article :
+
Previous
Next Post »
0 Komentar untuk "Source Code Java Game Testis 2D"

 
Copyright © 2014 Knowladge Is Free - All Rights Reserved - DMCA
Template By Kunci Dunia