制作这款游戏​​的正确方法是什么?

时间:2013-07-24 19:37:33

标签: java

我想制作类似于http://www.i-am-bored.com/bored_link.cfm?link_id=24495的游戏,但到目前为止,我一直没有成功。我想我应该使用int []作为块的x和y位置...但我不确定如何轻松地做到这一点。

这是我的代码(我知道它有点乱)。 Panel是JPanel,Block是左右移动的块,DeadBlock是静止的块,已经放置。

游戏非常简单,但我很难放置DeadBlocks。

package com.valgriz.game;

import java.awt.Color;
import java.awt.Graphics;
import java.awt.Toolkit;
import java.awt.event.KeyEvent;
import java.awt.event.KeyListener;

import javax.swing.JPanel;

public class Panel extends JPanel implements Runnable, KeyListener {
    private Thread thread;

    private final int ARRAY_NUMS = 999;

    private int sleepTime = 200;
    private int rights = 5;
    private int lefts = 0;
    private int dbCurrent;
    private int drawThisMany;

    private boolean isSpaced;

    private Block block;
    private DeadBlock[] dBlock = new DeadBlock[ARRAY_NUMS];
    private int[] dbX = new int[ARRAY_NUMS];
    private int[] dbY = new int[ARRAY_NUMS];

    public Panel() {
        addKeyListener(this);
        setDoubleBuffered(true);
        setFocusable(true);
        setBackground(Color.black);
        block = new Block();
        drawThisMany = 0;
        drawThisMany += rights;
        for (int i = 0; i < dBlock.length; i++) {
            dBlock[i] = new DeadBlock();
        }

        dbCurrent = 0;

        // Thread
        thread = new Thread(this);
        thread.start();
    }

    @Override
    public void run() {
        while (true) {
            update();
            try {
                thread.sleep(sleepTime);
            } catch (Exception e) {

            }
        }
    }

    public void update() {
        block.update();
        repaint();
    }

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

        for (int i = lefts; i < rights; i++) {
            int bX = block.getX();
            if (bX == getWidth() - block.getDx() * rights) {
                block.setDx(block.getDx() * -1);
            }
            if (bX == 0) {
                block.setDx(block.getDx() * -1);
            }

            g.drawImage(block.getBlock(), i * block.getWidth() + block.getX(),
                    getHeight() - block.getDy() * block.getY(), this);

            dbPaint(g);
        }
        // Toolkit
        Toolkit.getDefaultToolkit().sync();
        g.dispose();

    }

    ////// This code is useless
    public void dbPaint(Graphics g) {
        for (int i = 0; i < drawThisMany; i++) {
            dbX[i] = block.getX() + i * block.getX();
            dbY[i] = getHeight() - block.getY() * block.getWidth();
            g.drawImage(dBlock[i].getImage(), dbX[i], dbY[i], this);
        }

    }

    public void spaced() {

    }

    @Override
    public void keyPressed(KeyEvent e) {
        int key = e.getKeyCode();
        if (key == KeyEvent.VK_SPACE) {
            spaced();
        }
    }

    @Override
    public void keyReleased(KeyEvent e) {

    }

    @Override
    public void keyTyped(KeyEvent e) {

    }
}

package com.valgriz.game;

import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.Image;
import java.net.URL;

import javax.swing.ImageIcon;

public class Block {
    private ImageIcon bii;
    private Image block;
    private int x;
    private int y;
    private int dX;
    private int dY;
    private int pos;
    private int width;

    public Block() {
        bii = new ImageIcon(this.getClass().getResource(
                "/raw/images/ss_block.png"));
        block = bii.getImage();

        dX = getBlock().getWidth(null);
        dY = getBlock().getHeight(null);
        width = getBlock().getWidth(null);

        x = 0;
        y = 1;
    }

    public void update() {
        x += dX;
    }

    public Image getBlock() {
        return block;
    }

    public int getDx() {
        return dX;
    }

    public void setDx(int dX) {
        this.dX = dX;
    }

    public int getDy() {
        return dY;
    }

    public int getX() {
        return x;
    }

    public int getY() {
        return y;
    }

    public int getWidth() {
        return width;
    }
 }

package com.valgriz.game;

import java.awt.Graphics;
import java.awt.Image;

import javax.swing.ImageIcon;

public class DeadBlock {
    private Block block;

    private ImageIcon bii;
    private Image dBlock;

    private int x;
    private int y;

    public DeadBlock() {
        bii = new ImageIcon(this.getClass().getResource(
                "/raw/images/ss_block.png"));
        dBlock = bii.getImage();
    }

    public void paint(Graphics g) {

    }

    public int getX() {
        return x;
    }

    public void setX(int x) {
        this.x = x;
    }

    public int getY() {
        return y;
    }

    public void setY(int y) {
        this.y = y;
    }

    public Image getImage() {
        return dBlock;
    }
}

正确的方向是什么?如何使此代码有效?

2 个答案:

答案 0 :(得分:2)

如果您想编写简单的Java / Swing / AWT游戏,我强烈建议 Developing Games in Java

本书解释了一切:如何编写干净的游戏循环,如何处理所有发生的Swing重绘问题,如何使其全屏,集成声音等等。我在你的代码中看到很多奇怪的小东西,可以通过一些研究来修复。

答案 1 :(得分:2)

一个工作示例

Give it a try!

它并不完美,但它可能是一个很好的参考:

package stackgame;

import java.awt.Color;
import java.awt.Dialog;
import java.awt.Dimension;
import java.awt.Graphics;
import java.awt.KeyEventDispatcher;
import java.awt.KeyboardFocusManager;
import java.awt.event.KeyEvent;

import javax.swing.JApplet;
import javax.swing.JFrame;
import javax.swing.JOptionPane;
import javax.swing.JPanel;

public class StackGame extends JApplet {
    private final static int BOX_SIZE = 15;
    private final static int ROWS = 30;
    private final static int COLS = 15;

    private static int currentRow = 1;
    private static int currentCount = 9;
    private static JFrame f = new JFrame();

    private static JPanel gamePanel = new JPanel() {
        @Override
        public void paintComponent(Graphics g) {
            g.setColor(Color.WHITE);
            g.fillRect(0, 0, COLS * BOX_SIZE, (ROWS + 1) * BOX_SIZE);

            g.setColor(Color.BLUE);
            for (int j = 0 ; j < ROWS ; j++) {
                for (int i = 0 ; i < COLS ; i++) {
                    if (boxes[i][j]) {
                        g.fillRect(
                                (i * BOX_SIZE) + 1,
                                (ROWS * BOX_SIZE) - (j * BOX_SIZE) + 1,
                                BOX_SIZE - 2,
                                BOX_SIZE - 2);
                    }
                }
            }
        }
    };

    private static long sleepTime = 500;

    private static Thread moveBoxesThread = new Thread() {
        @Override
        public void run() {
            while(true) {
                try {
                    Thread.sleep(sleepTime );
                }
                catch (InterruptedException e) {
                    break;
                }
                moveRow();
                gamePanel.repaint();
            }
        }
    };

    static boolean[][] boxes = new boolean[COLS][ROWS];
    static {
        for (int i = 0 ; i < COLS ; i++) {
            for (int j = 0 ; j < ROWS ; j++) {
                boxes[i][j] = false;
            }
        }
        moveBoxesThread.setDaemon(true);
    }

    private static boolean movingRight = true;

    private static void startGame() {
        for (int i = 3 ; i < 12 ; i++) {
            boxes[i][0] = true;
        }

        initRow();

        gamePanel.repaint();
        startKeyListenning();
        moveBoxesThread.start();
    }

    private static void initRow() {
        if (currentRow >= ROWS) {
            moveBoxesThread.interrupt();
            JOptionPane.showMessageDialog(f, "You win, StackOverFlow!");
            System.exit(0);
        }
        for (int i = 0 ; i < currentCount ; i++) {
            boxes[i][currentRow] = true;
        }
    }

    private static void startKeyListenning() {
        KeyboardFocusManager.getCurrentKeyboardFocusManager().addKeyEventDispatcher(
            new KeyEventDispatcher() {

                @Override
                public boolean dispatchKeyEvent(KeyEvent e) {
                    if (!f.isFocusOwner() || currentRow > ROWS - 1)
                        return false;
                    if (e.getID() == KeyEvent.KEY_PRESSED
                            && e.getKeyCode() == KeyEvent.VK_SPACE) {
                        checkRowAndProceed();
                    }
                    return false;
                }
        });
    }

    protected static synchronized void checkRowAndProceed() {
        int count = 0;
        for (int i = 0 ; i < COLS ; i++) {
            try {
                if (!boxes[i][currentRow - 1]) {
                    boxes[i][currentRow] = false;
                }
                if (boxes[i][currentRow]) {
                    count++;
                }
            }
            catch (Exception e) {
                e.printStackTrace();
            }
        }
        currentCount = count;
        if (currentCount == 0) {
            JOptionPane.showMessageDialog(f, "You loose!");
            System.exit(0);
        }
        currentRow++;
        movingRight  = true;
        initRow();
        sleepTime *= 95;
        sleepTime /= 100;
    }

    protected static synchronized void moveRow() {
        if (!movingRight) {
            for (int col = 0 ; col < COLS - 1 ; col++) {
                boxes[col][currentRow] = boxes[col + 1][currentRow];
            }
            boxes[COLS - 1][currentRow] = false;
        }
        else {
            for (int col = COLS - 1 ; col > 0 ; col--) {
                boxes[col][currentRow] = boxes[col - 1][currentRow];
            }
            boxes[0][currentRow] = false;
        }
        if ((movingRight && boxes[COLS - 1][currentRow])
                || (!movingRight && boxes[0][currentRow])) {
            movingRight = !movingRight;
        }
    }

    public static void main(String[] args) {
        try {
            gamePanel.setPreferredSize(new Dimension(COLS * BOX_SIZE, (ROWS + 1) * BOX_SIZE));
            f.getContentPane().add(gamePanel);
            f.pack();
            f.setResizable(false);
            f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
            f.setLocationRelativeTo(null);
            f.setVisible(true);

            startGame();
        }
        catch (Exception e) {
            e.printStackTrace();
        }
    }
}