Selasa, 05 Juni 2012

Program java permainan ular

import javax.swing.*;
import java.awt.*;

import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.MouseEvent;
import java.awt.event.MouseListener;
import java.util.Random;
import java.util.ArrayList;

public class Snake extends JFrame implements ActionListener {

    private static final long serialVersionUID = 123654L;   // just to avoid compile warning
    // number of squares in the grid, size of each of them
    private static final int SIZE = 25, WIDTH = 20;
    // the labels for displaying the snake and its foods
    private SnakeLabel[][] label = new SnakeLabel[SIZE][SIZE];
    // arrayList containing all of the snake position (Labels)
    private SnakeList snakeList = new SnakeList();
    // the label displaying if I am running or not and the size of the snake
    private JLabel statusLabel = new JLabel("Initializing");
    // random number generator to find a new spot for a new food when I eat one
    private Random random = new Random();
    // if I am in a pause state or not
    boolean pause = false;
    // the button to switch from pause to not pause
    private JButton pauseResume = new JButton("Pause");
    // which direction I am running and where is my head
    private int directionX = 0, directionY = -1, headX, headY;
    // the refresh rate
    private int refreshRate;
    // The Timer that moves the Snake
    private Timer timer;

    Snake() {
        super("Snake Game");
        // to hold all the labels with a gap of 1 pixel
        JPanel panel = new JPanel(new GridLayout(SIZE, SIZE, 1, 1));
        // the same color as the Snake so the back will show a continuos snake
        panel.setBackground(Color.BLUE);
        panel.setBorder(BorderFactory.createLineBorder(Color.BLUE));
        // create all the JLabels
        initLabels(panel);

        // add the 4 foods
        initFood();
        // init the snake the length of a quarter of our size
        initSnake(SIZE / 4);
        add(panel, BorderLayout.CENTER);

        // label if I am running well and size of the snake
        statusLabel.setHorizontalAlignment(SwingConstants.CENTER);
        statusLabel.setOpaque(true);
        statusLabel.setBackground(Color.YELLOW);
        add(statusLabel, BorderLayout.NORTH);
        // listener so the pause button will work
        pauseResume.setForeground(Color.RED);
        pauseResume.addActionListener(this);
        add(pauseResume, BorderLayout.SOUTH);
        // general JFrame stuff its size and visible
        setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);
        setSize(SIZE * WIDTH - 5, SIZE * WIDTH - 5);
        setVisible(true);
        // start the thread that move the snakes
        refreshRate = 5000 / (snakeList.size() / 2);
        timer = new Timer(refreshRate, this);
        timer.start();
    }

    // to initialize the labels filling the grid
    // this method is called only once
    private void initLabels(JPanel p) {
        for(int j = 0; j < SIZE; j++) {
            for(int i = 0; i < SIZE; i++) {
                label[i][j] = new SnakeLabel(i, j);
                p.add(label[i][j]);
            }
        }

    }
    // to put the initial 4 food labels in 1/4 of the grid
    // this method will be called only once
    private void initFood() {
        // north/west at 1/4 of the grid
        int x = SIZE / 4;
        int y = x;
        label[x][y].setFood(true);
        // north east so x is the same delta from the end
        x = SIZE - x;
        label[x][y].setFood(true);
        // south/west
        y = x;
        x = SIZE / 4;
        label[x][y].setFood(true);
        // south east
        x = y;
        label[x][y].setFood(true);       
    }

    // to position the snake at the beginning of game
    private void initSnake(int length) {
        // the snake in the middle of everything initial size of length
        headX = SIZE / 2;
        headY = (SIZE / 2) - (length / 2);
        // declare these label as holding the snake
        // registering them in the arrayList
        for(int i = headY; i < headY + length; i++)
            snakeList.addLabel(label[headX][i]);
        // set the color for the first time
        snakeList.updateColor();
    }

    // run
    public void runSnake() {

        // wait according to snake length... determine an empiric way
        int oldRefreshRate = refreshRate;
        refreshRate = 5000 / (snakeList.size() / 2);
        // manage to have at least a minimum refresh rate
        if(refreshRate < 10)
            refreshRate = 10;
        // if refresh rate changed, update Timer delay
        if(oldRefreshRate != refreshRate)
            timer.setDelay(refreshRate);
       
        // if the "Pause" button was pushed go to next turn
        if(pause)
            return;
        // update snake head position
        headX += directionX;
        headY += directionY;
        // check if we are going out of bound
        if(headX < 0 || headX >= SIZE || headY < 0 || headY >= SIZE) {
            statusLabel.setText("Out of bound... length: " + snakeList.size());
            timer.stop();
            pauseResume.setEnabled(false);
            return;
        }
        // check if we are eating ourself
        if(label[headX][headY].isSnake) {
            statusLabel.setText("You eat yourself... length: " + snakeList.size());
            timer.stop();
            pauseResume.setEnabled(false);
            return;
        }
        // if we hit food
        if(label[headX][headY].isFood) {
            snakeList.updateHead();     // without updating tail
            // found new place for food
            for(;;) {
                int x = random.nextInt(SIZE);
                int y = random.nextInt(SIZE);
                // start again if new random place is already in the snake or is already food
                if(label[x][y].isFood)
                    continue;
                if(label[x][y].isSnake)
                    continue;
                // ok good dpot not used yet/// declare it as food
                label[x][y].setFood(true);
                break;
            }
        }
        else {
            snakeList.updateTail();     // first if I pass on my back
            snakeList.updateHead();
        }
        statusLabel.setText("Running... snake length: " + snakeList.size()
                + "    Refresh Rate: " + refreshRate + "/1000 sec");

    }
    // called when the pause/resume button is hit
    public void actionPerformed(ActionEvent e) {
        Object o = e.getSource();
        if(o == pauseResume) {
            // change the state
            pause = !pause;
            // update button text accordingly
            if(pause) {
                pauseResume.setText("Resume");
                timer.stop();
            }
            else {
                pauseResume.setText("Pause");
                timer.restart();
            }
            return;
        }
        else {    // it is the Timer if it is not the pauseResume button
            runSnake();
        }
    }
    // to run the whole damned thing
    public static void main(String[] args) {

        SwingUtilities.invokeLater(new Runnable() {
            public void run() {
                new Snake();
            }
        });
    }
    // array list that contains the position taken by the snake
    private class SnakeList extends ArrayList<SnakeLabel> {
        private static final long serialVersionUID = 654321L;  // to avoid compile warning
        // the 2 colours of the snake
        private Color[] snakeColor = {new Color(0, 0, 255), new Color(75, 75, 255)};
        // for initial build when we install the snake first positions
        private boolean addLabel(SnakeLabel sl) {
            // flag the SnakeLabel as being part of the Snake
            sl.setSnake(true);
            // call father's method to add an object into the arrayList
            return add(sl);
        }
        // remove (make free) the tail of the snake
        private void updateTail() {
            SnakeLabel sl = remove(size() - 1);
            sl.setSnake(false);
        }
        // to update the head to new position
        private void updateHead() {
            // declare it as part of the snake
            label[headX][headY].setSnake(true);
            // add it to the head of the snake
            add(0, label[headX][headY]);
            // switch colors
            updateColor();
        }

        // to put 2 colours in the snake
        private void updateColor() {
            int len = size();
            // the head in black
            get(0).setBackground(Color.BLACK);
            // variation of blue for the others
            for(int i = 1; i < len; i++) {
                get(i).setBackground(snakeColor[i % snakeColor.length]);
            }
        }
    } // end of inner class SnakeList

    // specialized JLabel to keep coordinate X and Y and have a mouseListener if cliked
    private class SnakeLabel extends JLabel implements MouseListener{
        private static final long serialVersionUID = 123456L;   // to avoid compile warning
        // my coordinates on the Grid so the mouseListener can know where I am situate
        private int x, y;
        // init not food and not snake
        boolean isFood = false;         // not a food case
        boolean isSnake = false;        // not part of the snake
        // constructor
        SnakeLabel(int x, int y) {
            super("");
            // save my coordinates
            this.x = x; this.y = y;
            // opaque because I use background to represent myself
            setOpaque(true);
            // so I will react if I am cleicked
            addMouseListener(this);
            // default color
            setBackground(Color.WHITE);
        }
        // declares me as a food case or not
        private void setFood(boolean state) {
            isFood = state;
            // change color accordingly
            if(state)
                setBackground(Color.RED);       // food color
            else
                setBackground(Color.WHITE);     // regular color
        }
        // declares me as part of the snake or not
        private void setSnake(boolean state) {
            isSnake = state;
            // change my color accordingly
            if(state) {
                setFood(false);      // make it available again as food slot
                setBackground(Color.BLUE);
            }
            else {
                setBackground(Color.WHITE);
            }
        }

        // ok click on me I just chek for the Pressed event to react faster
        // (important when the snake goes very fast)
        public void mousePressed(MouseEvent e) {
            // so am I going vertically or horitonaly
            if(directionX == 0) {
                // if clicked on my same X nothing to do
                if(x == headX)
                    return;
                directionY = 0;                // stop updating Y
                // if clicked to my left
                if(x < headX) {
                    // update the way I am going
                    directionX = -1;
                }   
                else  {   // so to my rioght
                    directionX = +1;               
                }
            }
            else {                  // OK I am moving horizontaly
                if(y == headY)
                    return;
                directionX = 0;
                if(y < headY) {     // to my left
                    directionY = -1;
                }
                else {     // to my right
                    directionY = +1;
                }               
            }
        }
        // do not react to those but as I implement MouseListener have have to implement these
        public void mouseEntered(MouseEvent arg0) {}
        public void mouseExited(MouseEvent arg0) {}
        public void mouseClicked(MouseEvent arg0) {}
        public void mouseReleased(MouseEvent arg0) {}

    }  // end inner class SnakeLabel
}

0 komentar:

Posting Komentar

resep donat empuk ala dunkin donut resep kue cubit coklat enak dan sederhana resep donat kentang empuk lembut dan enak resep es krim goreng coklat kriuk mudah dan sederhana resep es krim coklat lembut resep bolu karamel panggang sarang semut

Copyright © Deja Area | Powered by Blogger

Design by Anders Noren | Blogger Theme by NewBloggerThemes.com | BTheme.net      Up ↑