folder Tahribat.com Forumları
linefolder Java
linefolder Java İle Tetris Projesi (+Kaynak Kodlar)



Java İle Tetris Projesi (+Kaynak Kodlar)

  1. KısayolKısayol reportŞikayet pmÖzel Mesaj
    wasd
    wasd's avatar
    Kayıt Tarihi: 14/Haziran/2006
    Erkek

    Geçen dönem c# ile puzzle ödevinden sonra bu dönem java ile tetris ödevi hazırladım. Aslında proje zetcode.com adlı siteden çalıntı ama değişken ve fonksiyon isimlerini falan Türkçeleştirdim, birkaç yeni özellik ve bu özelliklerle birlikte birkaç bug ekledim :D Gönül isterdi ki sıfırdan yapayım ama ödev grup ödevi ve tek uğraşanda ben olunca mecbur böyle birşey yaptım...

    Neyse, buyrun kodlar;

    -------------------------Tetris.java-------------------------------------------------------------------

    package tetris;
    
    import java.awt.BorderLayout;
    import javax.swing.JFrame;
    import javax.swing.JLabel;
    public class Tetris extends JFrame
    {
        JLabel statusbar;
    
        public Tetris() 
        {
            statusbar = new JLabel("Puan: 0");
            add(statusbar, BorderLayout.SOUTH);
            Board board = new Board(this);
            add(board);
            board.basla();
            setSize(250, 570);
            setResizable(false);
            setTitle("NDAT - Tetris - 2012");
            setDefaultCloseOperation(EXIT_ON_CLOSE);
       }
    
       public JLabel getStatusBar() 
       {
           return statusbar;
       }
    
        public static void main(String[] args) 
        {
            Tetris oyun = new Tetris();
            oyun.setLocationRelativeTo(null);
            oyun.setVisible(true);
        } 
    }

    --------------------------------------------Sekil.java-----------------------------------------------------------------

    package tetris;

    import java.util.Random;

    public class Sekil
    {
        enum parcalar { Bos, ZSekli, SSekli, CizgiSekli, TSekli, KareSekli, LSekli, TersLSekli };

        private parcalar pSekil;
        private int koordinatlar[][];
        private int[][][] koordinatTablosu;

        public Sekil()
        {
            koordinatlar = new int[4][2];
            setSekil(parcalar.Bos);
        }

        public void setSekil(parcalar sekil)
        {
             koordinatTablosu = 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)
                {
                    koordinatlar[i][j] = koordinatTablosu[sekil.ordinal()][i][j];
                }
            }
            pSekil = sekil;
        }

        private void setX(int index, int x)
        {
            koordinatlar[index][0] = x;
        }
        
        private void setY(int index, int y)
        {
            koordinatlar[index][1] = y;
        }
        
        public int x(int index)
        {
            return koordinatlar[index][0];
        }
        
        public int y(int index)
        {
            return koordinatlar[index][1];
        }
        
        public parcalar getSekil()  
        {
            return pSekil;
        }

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

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


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

        public Sekil solaCevir()
        {
            if (pSekil == parcalar.KareSekli)
                return this;

            Sekil result = new Sekil();
            result.pSekil = pSekil;

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

        public Sekil sagaCevir()
        {
            if (pSekil == parcalar.KareSekli)
                return this;

            Sekil result = new Sekil();
            result.pSekil = pSekil;

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

    ---------------------Board.java------------------------------------------------------------------------

    package tetris;

    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 tetris.Sekil.parcalar;


    public class Board extends JPanel implements ActionListener
    {
        final int BoardEn = 10;
        final int BoardBoy = 22;
        Timer timer;
        boolean dususFlag = false;
        boolean baslamaFlag = false;
        boolean duraklamaFlag = false;
        int silinenSatir = 0;
        int curX = 0;
        int curY = 0;
        JLabel statusbar;
        Sekil curParca;
        parcalar[] board;

        public Board(Tetris parent)
        {
           setFocusable(true);
           curParca = new Sekil();
           timer = new Timer(300, this);
           timer.start();
           statusbar =  parent.getStatusBar();
           board = new parcalar[BoardEn * BoardBoy];
           addKeyListener(new TAdapter());
           temizle();  
        }

        @Override
        public void actionPerformed(ActionEvent e)
        {
            if (dususFlag)
            {
                dususFlag = false;
                yeniParca();
            }
            else
            {
                birSatirAsagi();
            }
        }

        int kareEn()
        {
            return (int) getSize().getWidth() / BoardEn;
        }
        
        int kareBoy()
        {
            return (int) getSize().getHeight() / BoardBoy;
        }
        
        parcalar shapeAt(int x, int y)
        {
            return board[(y * BoardEn) + x];
        }


        public void basla()
        {
            if (duraklamaFlag)
                return;

            baslamaFlag = true;
            dususFlag = false;
            silinenSatir = 0;
            temizle();

            yeniParca();
            timer.start();
        }

        private void duraklat()
        {
            if (!baslamaFlag)
                return;

            duraklamaFlag = !duraklamaFlag;
            if (duraklamaFlag)
            {
                timer.stop();
                statusbar.setText("Duraklatıldı");
            }
            else
            {
                timer.start();
                statusbar.setText("Puan: " + String.valueOf(silinenSatir*100));
            }
            repaint();
        }

        public void paint(Graphics g)
        {
            super.paint(g);

            Dimension size = getSize();
            int boardTop = (int) size.getHeight() - BoardBoy * kareBoy();


            for (int i = 0; i < BoardBoy; ++i)
            {
                for (int j = 0; j < BoardEn; ++j)
                {
                    parcalar sekil = shapeAt(j, BoardBoy - i - 1);
                    if (sekil != parcalar.Bos)
                        kareCiz(g, 0 + j * kareEn(),boardTop + i * kareBoy(), sekil);
                }
            }

            if (curParca.getSekil() != parcalar.Bos)
            {
                for (int i = 0; i < 4; ++i)
                {
                    int x = curX + curParca.x(i);
                    int y = curY - curParca.y(i);
                    kareCiz(g, 0 + x * kareEn(),
                               boardTop + (BoardBoy - y - 1) * kareBoy(),
                               curParca.getSekil());
                }
            }
        }

        private void enDibe()
        {
            int newY = curY;
            while (newY > 0)
            {
                if (!hareketDene(curParca, curX, newY - 1))
                    break;
                --newY;
            }
            pieceDropped();
        }

        private void birSatirAsagi()
        {
            if (!hareketDene(curParca, curX, curY - 1))
                pieceDropped();
        }


        private void temizle()
        {
            for (int i = 0; i < BoardBoy * BoardEn; ++i)
                board[i] = parcalar.Bos;
        }

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

            satirSil();

            if (!dususFlag)
                yeniParca();
        }

        private void yeniParca()
        {
            curParca.setRandomSekil();
            curX = BoardEn / 2;
            curY = BoardBoy - 1 + curParca.minY();

            if (!hareketDene(curParca, curX, curY))
            {
                timer.stop();
                statusbar.setText("Oyun Bitti!");
            }
        }

        private boolean hareketDene(Sekil yeniParca, int yeniX, int yeniY)
        {
            //Parçaların form dışına çıkmasını engelleme kontrolü
            //True döndürülürse istenilen hareketin gerçekleştirilmesi
            for (int i = 0; i < 4; ++i)
            {
                int x = yeniX + yeniParca.x(i);
                int y = yeniY - yeniParca.y(i);
                if (x < 0 || x >= BoardEn || y < 0 || y >= BoardBoy)
                    return false;
                if (shapeAt(x, y) != parcalar.Bos)
                    return false;
            }

            curParca = yeniParca;
            curX = yeniX;
            curY = yeniY;
            repaint();
            return true;
        }

        private void satirSil()
        {
            //Tam dolan satırların silinmesi ve silinen satırın üstündeki parçaların
            //aşağıya kaydırılması.
            //Kazanılan puanın label üstünde görüntülenmesi.
            int silinenStrSayisi = 0;
            
            for (int i = BoardBoy - 1; i >= 0; --i)
            {
                boolean satirDolu = true;

                for (int j = 0; j < BoardEn; ++j)
                {
                    if (shapeAt(j, i) == parcalar.Bos)
                    {
                        satirDolu = false;
                        break;
                    }
                }

                if (satirDolu)
                {
                    ++silinenStrSayisi;
                    for (int k = i; k < BoardBoy - 1; ++k)
                    {
                        for (int j = 0; j < BoardEn; ++j)
                             board[(k * BoardEn) + j] = shapeAt(j, k + 1);
                    }
                }
            }

            if (silinenStrSayisi > 0)
            {
                silinenSatir += silinenStrSayisi;
                if(silinenSatir<10)
                    statusbar.setText("Puan: " + String.valueOf(silinenSatir*100));
                else if(silinenSatir>10 || silinenSatir<20)
                    statusbar.setText("Puan: " + String.valueOf(silinenSatir*110));
                else if(silinenSatir <30 ||silinenSatir>20)
                    statusbar.setText("Puan: " + String.valueOf(silinenSatir*120));
                else if(silinenSatir>30 || silinenSatir<40)
                    statusbar.setText("Puan: " + String.valueOf(silinenSatir*130));
                else if(silinenSatir>40)
                    statusbar.setText("Puan: " + String.valueOf(silinenSatir*140));
                dususFlag = true;
                curParca.setSekil(parcalar.Bos);
                repaint();
            }
         }

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


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

            g.setColor(color);
            g.fillRect(x + 1, y + 1, kareEn() - 2, kareBoy() - 2);
        }

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

                 if (!baslamaFlag || curParca.getSekil() == parcalar.Bos)
                 {  
                     return;
                 }

                 int keycode = e.getKeyCode();

                 if (keycode == 'p' || keycode == 'P')
                 {
                     duraklat();
                     return;
                 }
                 
                 if (keycode == 'e' || keycode == 'E')
                 {
                     System.exit(0);
                 }
                 
                 if (keycode == 'r' || keycode == 'R')
                 {
                     baslamaFlag = true;
                     dususFlag = false;
                     silinenSatir = 0;
                     statusbar.setText("Puan: 0");
                     temizle();
                     yeniParca();
                     timer.start();
                 }
                 
                 if (keycode == '.')
                 {
                     enDibe();
                 }

                 if (duraklamaFlag)
                     return;

                 switch (keycode)
                 {
                 case KeyEvent.VK_LEFT:
                     hareketDene(curParca, curX - 1, curY);
                     break;
                 case KeyEvent.VK_RIGHT:
                     hareketDene(curParca, curX + 1, curY);
                     break;
                 case KeyEvent.VK_DOWN:
                     hareketDene(curParca.sagaCevir(), curX, curY);
                     break;
                 case KeyEvent.VK_UP:
                     hareketDene(curParca.solaCevir(), curX, curY);
                     break;
                 case KeyEvent.VK_SPACE:
                     birSatirAsagi();
                     break;
                 }
             }
         }
    }

    ------------------------------------------------------------------------------

     

    Kodları Belirtilen isimlerdeki dosyaları oluşturup içlerine c/p yapın. Sonra 3 kaynak kod dosyasınıda tetris adında bi klasör oluşturup onun içine atın. Package kullanıldığı için bu şekilde yapmanız gerekiyor ama yinede komut satırında derleyemeyebilirsiniz eğer benim gibi javada yeniyseniz :) o yüzden tavsiyem netbeans ya da eclipse kullanmanız.

    Proje çalıntı ama açıklayamayacağım biyeri yok diyebilirim, her satırını tek tek okuyup çalıştım herşeyini açıklayabilirim eğer anlamadığınız yeri olursa.

    Gelelim eklemelerime ve buglara:

    -Oyunda puanlama yoktu, 5dakikada yaptım oldu. Hızı arttırma yapacaktım zorluk seviyesi için bununla birlikte ama alelacele eklediğim bişey oldu bu :p

    -Oyun bittikten sonra kapat aç yapmak gerekiyodu, R tuşuna bikaç bişey ekledim yeni oyun ve reset olayını yaptırdım. Tabi buglarda bununla birlikte geldi(son parçanın iç içe geçmesi) duraklatma olayıyla falan karıştı, flaglarla oynayarak düzeltilebilir.

    Başkada bişey aklıma gelmiyor şu an, oyunu başlattıktan sonra oynayabilmeniz için önce şu en sondaki switch-case yapısını incelemenizi tavsiye ederim :)

     

    Oyunun Mantığı-Algoritması:

    Tetris oyununda her parça 4 kutucuktan oluşur.(Latince Tetra kelimesi 4 anlamındadır) Burda yapılan koordinat düzlemini oluşturmak ve kutucukları koordinat düzleminde çizdirmek ve hareketleri içinde repaint yapmak. Bütün sıkıntısı çizim kısmı,hareketler tamamen koordinat düzlemi bilgisi ve 4 işlemden ibaret.

     

    Anlamadığınız yerleri sorabilirsiniz hadi kolay gelsin :)


    :)
  2. KısayolKısayol reportŞikayet pmÖzel Mesaj
    Holyzone
    Holyzone's avatar
    Üstün Hizmet Madalyası
    Kayıt Tarihi: 13/Ekim/2008
    Erkek

    Çok güzelmiş hocam eline sağlık :)

  3. KısayolKısayol reportŞikayet pmÖzel Mesaj
    mungabunga
    mungabunga's avatar
    Kayıt Tarihi: 09/Nisan/2011
    Erkek

    derleyip bir yere upload edebilecek bir friendo var mı?


    ve bu konuda başka bir şey söylemeyeceğim...
  4. KısayolKısayol reportŞikayet pmÖzel Mesaj
    ulaslaslas
    ulaslaslas's avatar
    Kayıt Tarihi: 19/Kasım/2011
    Erkek

    çiz


    Trilyon da olsan harcanacaksın!!!
  5. KısayolKısayol reportŞikayet pmÖzel Mesaj
    wasd
    wasd's avatar
    Kayıt Tarihi: 14/Haziran/2006
    Erkek

    http://s2.dosya.tc/server14/Kinpnv/tetris.jar.html

     

    Bu derlenmiş hali. Dün ben güzelce bi cevap yazmıştım ama şu "ipdeğişti" muhabbeti yüzünden yalan olmuş sanırım :/ oyun olarak saracağını sanmıyorum, direk başlıyor,gram görsellik yok,hızlanma yok,puanlama dandirik vs vs(85 aldım bu ödevle ama oynanmaz yani :D)... Olayı ufaktan java ve algoritma konularında birşeyler öğrenme & öğretme.


    :)
  6. KısayolKısayol reportŞikayet pmÖzel Mesaj
    SyspioniC
    SyspioniC's avatar
    Kayıt Tarihi: 26/Eylül/2007
    Erkek

    oyunu denedim. güzel olmuş :P


    "Derviş Yunus bu sözü eğri büğrü söyleme, Seni sorguya çeker bir Molla Kasım gelir."
  7. KısayolKısayol reportŞikayet pmÖzel Mesaj
    Amd-x
    Amd-x's avatar
    Kayıt Tarihi: 29/Eylül/2009
    Erkek

    deniyeceğim.

    teşekkürler hocam.

Toplam Hit: 6795 Toplam Mesaj: 7