2 weixin 36010292 weixin_36010292 于 2016.09.08 15:10 提问

基于java ee 的吹泡泡游戏

源代码如下(其中其他窗体代码我已省略):
import java.awt.*;
import java.awt.event.*;
import java.awt.event.KeyAdapter;
import java.awt.event.KeyEvent;
import javax.swing.*;

import java.awt.*;
import java.lang.reflect.Field;

import javax.swing.JLabel;
/**展示面板*/
@SuppressWarnings("serial")
public class BallFrame extends JFrame {
private JPanel Pane ;// 背景面板
private Ball ball = null;// 窗体提供一个小球
//测试方法:
public static void main(String[] args) {
SwingUtilities.invokeLater(new Runnable() {
public void run() {
BallFrame thisClass = new BallFrame();
thisClass
.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
thisClass.setVisible(true);
}
});
}

/**
 * 构造方法
 */
public BallFrame() {
    super();
    initialize();// 初始程序界面
}

/**
 * 初始化程序界面
 */
private void initialize() {
    this.setSize(400, 400);// 设置窗体大小
    this.setResizable(false);// 禁止调整窗体大小
    this.setContentPane(getJContentPane());// 添加内容面板
    // 设置窗体标题文本
    this.setTitle("开始游戏");
}

/**
 * 背景面板
 * 
 * @return javax.swing.JPanel
 */

private JPanel getJContentPane() {
    int x1=-10;
    if (Pane == null) {
        ball = new Ball();// 创建第一个小球
        // 设置小球位置与大小
        ball.setBounds(new Rectangle(10, 300, 20, 20));
        // 创建背景面板
       Pane = new JPanel();
        // 背景面板使用null布局
        Pane.setLayout(null);
        Pane.add(ball, null);// 添加第一个小球到背景面板
        // 为背景面板添加鼠标事件监听器
        Icon icon=new ImageIcon("c:/point90.png");  //添加吸管到面板
        JLabel jlb=new JLabel(icon);
        jlb.setBounds(x1,340, 51, 51);
        Pane.add(jlb); 
        jlb.addKeyListener(new KeyListener() {
       public void keyPressed(KeyEvent e){
            int x;
            x=x1;
            if(e.getKeyCode()==KeyEvent.VK_LEFT){
                if(x>-10){
                    x=x-10;
                }
            }
            if(e.getKeyCode()==KeyEvent.VK_RIGHT){
                if(x<341){
                    x=x+10;

                }
            }
            jlb.setBounds(x,340,51,51);
        }

    @Override
    public void keyTyped(KeyEvent e) {
        // TODO 自动生成的方法存根

    }

    @Override
    public void keyReleased(KeyEvent e) {
        // TODO 自动生成的方法存根

    }

        });
       Pane.addMouseListener(new MouseAdapter() {
            public void mousePressed(MouseEvent e) {
                // 获取面板中控件的数量
                int count = Pane.getComponentCount();
                double t=0;
                // 十分钟的游戏时间

                while (t==10) {
                    if (count <= 400) {// 限制小球数量为400
                        Ball ball = new Ball();// 创建新的小球对象
                        Point icon= e.getPoint();// 获取鼠标当前位置
                        ball.setLocation(icon);// 设置小球为鼠标位置
                       Pane.add(ball);// 添加小球到面板
                    } else {// 否则
                        // 提示小球太多
                        JOptionPane.showMessageDialog(null,
                                "球太多啦");
                    }
                }/* else {// 如果单击鼠标右键
                    if (count < 1) {// 如果面板中没有控件
                        // 对话框提示信息
                        JOptionPane.showMessageDialog(null,
                                "没有球啦");
                        return;
                    }
                    // 移除面板中的第一个控件
                   Pane.remove(0);
                    // 重新绘制面板
                    Pane.repaint();
                }*/
            }
        });
    }
    return Pane;
}

}

//小球一个内部类:
class Ball extends JLabel implements Runnable {
private int r = 10;// 小球半径
private int width = r * 2;// 球宽度
private int height = r * 2;// 球高度s
private Color ballColor = Color.BLACK;// 默认颜色

/**
 * 构造方法
 */
public Ball() {
    // 初始化大小
    setSize(new Dimension(width, height));
    setPreferredSize(new Dimension(width, height));
    // 反射获取Color类的所有成员变量数组
    Field[] fields = Color.class.getFields();
    // 随机生成数组下标索引
    int index = (int) (Math.random() * fields.length);
    try {
        // 获取指定下标索引的成员变量
        Object object = fields[index].get(null);
        // 判断是否Color类的实例对象
        if (object instanceof Color) {
            // 改变默认颜色
            ballColor = (Color) object;
        }
    } catch (IllegalArgumentException e) {
        e.printStackTrace();
    } catch (IllegalAccessException e) {
        e.printStackTrace();
    }
    // 启动小球跳跃线程
    new Thread(this).start();
}

@Override
protected void paintComponent(Graphics g) {
    super.paintComponent(g);
    g.setColor(ballColor);// 设置默认颜色
    g.fillOval(0, 0, width, height);// 绘制球体
}

@Override
public void run() {
    // 获取父容器对象
    Container parent = getParent();
    Point myPoint = getLocation();// 获取初始位置
    while (true) {// 循环读取父容器对象
        if (parent == null) {
            try {
                Thread.sleep(50);// 线程休眠
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            myPoint = getLocation();// 获取初始位置
            parent = getParent();
        } else {// 如果已经获取到父容器
            break;// 跳出循环
        }
    }
    int sx = myPoint.x;// X坐标
    int sy = myPoint.y;// y坐标
    int step = 10;// 移动步进
    int t=0;
    step = 1;// 移动步进
    int dy =1;// 垂直步进值
    // 随机移动速度
    int stime = 10;
    while (parent.isVisible()) {
        int parentWidth = parent.getWidth();// 容器宽度
        int parentHeight = parent.getHeight();// 容器高度
        setLocation(sx, sy);
        try {
            Thread.sleep(stime);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }

        sy = sy + dy;// 垂直坐标偏移1个像素
        // 检测垂直边界
        if (sy > parentHeight - height - 35 || sy - 20 < 0)
        { dy = -dy;// 防止坐标超出垂直边界
          t++;
        }
        if(t==2)
        {   sy=0;
            dy=0;
        }

    }
}

}

要求:我想实现图片的键盘左右移动,而且泡泡垂直上升碰到其他泡泡如果是三个不同颜色的则消掉这三个不是则停止上升,泡泡碰到图片就停止,如果有泡泡龙JAVA EE的源代码发来参考的话感激不尽

3个回答

qq_36093700
qq_36093700   2016.09.09 12:20
已采纳

你可以参考这个(转载自网络):
import java.awt.*;
import java.util.Vector;
import java.util.Random;

//代表一个泡泡对象
public class BubbleSprite extends Sprite
{
private static double FALL_SPEED = 1.;
private static double MAX_BUBBLE_SPEED = 8.;
private static double MINIMUM_DISTANCE = 841.;

private Image bubbleFace;
private Image bubbleBlindFace;
private Image frozenFace;
private Image bubbleBlink;
private Image[] bubbleFixed;
private FrozenGame frozen;//游戏主屏幕
private BubbleManager bubbleManager;//泡泡管理器
private double moveX, moveY;//相对位移
private double realX, realY;//绝对位移

private boolean fixed;
private boolean blink;
private boolean released;

//保证每个泡泡只被检查一次
private boolean checkJump;
private boolean checkFall;

private int fixedAnim;

private SoundManager soundManager;

//构造一个移动的泡泡
public BubbleSprite(Rectangle area, int direction, Image bubbleFace, Image bubbleBlindFace, Image frozenFace, Image[] bubbleFixed, Image bubbleBlink, BubbleManager bubbleManager, SoundManager soundManager, FrozenGame frozen)
{
    super(area);

    this.bubbleFace = bubbleFace;
    this.bubbleBlindFace = bubbleBlindFace;
    this.frozenFace = frozenFace;
    this.bubbleFixed = bubbleFixed;
    this.bubbleBlink = bubbleBlink;
    this.bubbleManager = bubbleManager;
    this.soundManager = soundManager;
    this.frozen = frozen;

    this.moveX = MAX_BUBBLE_SPEED * -Math.cos(direction * Math.PI / 40.);
    this.moveY = MAX_BUBBLE_SPEED * -Math.sin(direction * Math.PI / 40.);
    this.realX = area.x;
    this.realY = area.y;

    fixed = false;
    fixedAnim = -1;
}

//构造一个固定的泡泡
public BubbleSprite(Rectangle area, Image bubbleFace, Image bubbleBlindFace, Image frozenFace, Image bubbleBlink, BubbleManager bubbleManager, SoundManager soundManager, FrozenGame frozen)
{
    super(area);

    this.bubbleFace = bubbleFace;
    this.bubbleBlindFace = bubbleBlindFace;
    this.frozenFace = frozenFace;
    this.bubbleBlink = bubbleBlink;
    this.bubbleManager = bubbleManager;
    this.soundManager = soundManager;
    this.frozen = frozen;

    this.realX = area.x;
    this.realY = area.y;

    fixed = true;
    fixedAnim = -1;
    bubbleManager.addBubble(bubbleFace);
}

//得到当前位置所对应二维数组中的下标
Point currentPosition()
{
    int posY = (int)Math.floor((realY-28.-frozen.getMoveDown())/28.);
    int posX = (int)Math.floor((realX-174.)/32. + 0.5*(posY%2));//190-16=174

    if (posX>7) 
    {
        posX = 7;
    }

    if (posX<0) 
    {
        posX = 0;
    }

    if (posY<0)
    {
        posY = 0;
    }

    return new Point(posX, posY);
}

public void removeFromManager()
{
    bubbleManager.removeBubble(bubbleFace);
}

public boolean fixed()
{
    return fixed;
}

public boolean checked()
{
    return checkFall;
}

public boolean released()
{
    return released;
}

//绝对向下移动
public void moveDown()
{
    if (fixed)
    {
        realY += 28.;
    }

    super.absoluteMove(new Point((int)realX, (int)realY));
}

//向上移动泡泡
public void move()
{
    //先移动
    realX += moveX;

    if (realX>=414.)//到右后,反向左
    {
        moveX = -moveX;
        realX += (414. - realX);
        soundManager.playSound(FrozenBubble.SOUND_REBOUND);
    }
    else if (realX<=190.)//到左后,反向右
    {
        moveX = -moveX;
        realX += (190. - realX);
        soundManager.playSound(FrozenBubble.SOUND_REBOUND);
    }

    realY += moveY;

    //得到泡泡当前的位置
    Point currentPosition = currentPosition();
    //得到此泡泡四周的泡泡
    Vector neighbors = getNeighbors(currentPosition);

    if (checkCollision(neighbors) || realY < 44.+frozen.getMoveDown())
    {
        realX = 190.+currentPosition.x*32-(currentPosition.y%2)*16;
        realY = 44.+currentPosition.y*28+frozen.getMoveDown();

        fixed = true;

        Vector checkJump = new Vector();
        this.checkJump(checkJump, neighbors);

        BubbleSprite[][] grid = frozen.getGrid();

        //每碰撞到的同色泡泡弹起
        if (checkJump.size() >= 3)
        {   
            released = true;

            for (int i=0 ; i<checkJump.size() ; i++)
            {
                BubbleSprite current = (BubbleSprite)checkJump.elementAt(i);
                Point currentPoint = current.currentPosition();

                frozen.addJumpingBubble(current);
                if (i>0)
                {
                    current.removeFromManager();
                }
                grid[currentPoint.x][currentPoint.y] = null;
            }

            //依附的泡泡直接掉下
            for (int i=0 ; i<8 ; i++)
            {
                if (grid[i][0] != null)
                {
                    grid[i][0].checkFall();
                }
            }

            for (int i=0 ; i<8 ; i++)
            {
                for (int j=0 ; j<12 ; j++)
                {
                    if (grid[i][j] != null)
                    {
                        if (!grid[i][j].checked())//没有检查到的,都是没有依附的
                        {
                            frozen.addFallingBubble(grid[i][j]);
                            grid[i][j].removeFromManager();
                            grid[i][j] = null;
                        }
                    }
                }
            }

            soundManager.playSound(FrozenBubble.SOUND_DESTROY);
        }
        else
        {
            bubbleManager.addBubble(bubbleFace);
            grid[currentPosition.x][currentPosition.y] = this;
            moveX = 0.;
            moveY = 0.;
            fixedAnim = 0;
            soundManager.playSound(FrozenBubble.SOUND_STICK);
        }
    }    

    super.absoluteMove(new Point((int)realX, (int)realY));
}

Vector getNeighbors(Point p)
{
    BubbleSprite[][] grid = frozen.getGrid();

    Vector list = new Vector();

    if ((p.y % 2) == 0)//奇数行
    {
        if (p.x > 0)
        {
            list.addElement(grid[p.x-1][p.y]);//左边的
        }

        if (p.x < 7)
        {
            list.addElement(grid[p.x+1][p.y]);//右边的

            if (p.y > 0)//上边的两个
            {
                list.addElement(grid[p.x][p.y-1]);
                list.addElement(grid[p.x+1][p.y-1]);
            }

            if (p.y < 12)//下边的两个
            {
                list.addElement(grid[p.x][p.y+1]);
                list.addElement(grid[p.x+1][p.y+1]);
            }
        }
        else
        {
            if (p.y > 0)
            {
                list.addElement(grid[p.x][p.y-1]);
            }

            if (p.y < 12)
            {
                list.addElement(grid[p.x][p.y+1]);
            }               
        }
    }
    else//偶数行
    {
        if (p.x < 7)
        {
            list.addElement(grid[p.x+1][p.y]);
        }

        if (p.x > 0)
        {
            list.addElement(grid[p.x-1][p.y]);

            if (p.y > 0)
            {
                list.addElement(grid[p.x][p.y-1]);
                list.addElement(grid[p.x-1][p.y-1]);
            }

            if (p.y < 12)
            {
                list.addElement(grid[p.x][p.y+1]);
                list.addElement(grid[p.x-1][p.y+1]);
            }
        }
        else
        {
            if (p.y > 0)
            {
                list.addElement(grid[p.x][p.y-1]);
            }

            if (p.y < 12)
            {
                list.addElement(grid[p.x][p.y+1]);
            }               
        }           
    }

    return list;
}

//这两个函数构成递归调用,查找被碰撞同色的泡泡
void checkJump(Vector jump, Image compare)
{
    if (checkJump)
    {
        return;
    }
    checkJump = true;

    if (this.bubbleFace == compare)
    {
        checkJump(jump, this.getNeighbors(this.currentPosition())); 
    }
}

void checkJump(Vector jump, Vector neighbors)
{
    jump.addElement(this);

    for (int i=0 ; i<neighbors.size() ; i++)
    {
        BubbleSprite current = (BubbleSprite)neighbors.elementAt(i);

        if (current != null)
        {
            current.checkJump(jump, this.bubbleFace);
        }
    }       
}

//将与第一行有关联的泡泡都标示出来,则没有标示的都为要下掉的泡泡
public void checkFall()
{
    if (checkFall)
    {
        return;
    }
    checkFall = true;

    Vector v = this.getNeighbors(this.currentPosition());

    for (int i=0 ; i<v.size() ; i++)
    {
        BubbleSprite current = (BubbleSprite)v.elementAt(i);

        if (current != null)
        {
            current.checkFall();
        }
    }
}

//检查两个泡泡之间是否碰撞,求两点间的距离
boolean checkCollision(Vector neighbors)
{
    for (int i=0 ; i<neighbors.size() ; i++)
    {
        BubbleSprite current = (BubbleSprite)neighbors.elementAt(i);

        if (current != null)
        {
            if (checkCollision(current))
            {
                return true;
            }
        }
    }

    return false;
}

boolean checkCollision(BubbleSprite sprite)
{
    double value = (sprite.getSpriteArea().x - this.realX) * (sprite.getSpriteArea().x - this.realX)
                   + (sprite.getSpriteArea().y - this.realY) * (sprite.getSpriteArea().y - this.realY);

    return (value < MINIMUM_DISTANCE);
}

public void jump()
{
    if (fixed)
    {
        moveX = -6. + frozen.getRandom().nextDouble() * 12.;
        moveY = -5. - frozen.getRandom().nextDouble() * 10. ;

        fixed = false;
    }

    moveY += FALL_SPEED;//由负的慢慢增加到正的
    realY += moveY;
    realX += moveX;

    super.absoluteMove(new Point((int)realX, (int)realY));

    if (realY >= 680.)
    {
        frozen.deleteJumpingBubble(this);
    }
}

//直接下掉
public void fall()
{
    //第一次计算出一个随机数,作为下掉的增量
    if (fixed)
    {
        moveY = frozen.getRandom().nextDouble()* 5.;
    }

    fixed = false;

    moveY += FALL_SPEED;
    realY += moveY;

    super.absoluteMove(new Point((int)realX, (int)realY));

    if (realY >= 680.)
    {
        frozen.deleteFallingBubble(this);
    }
}

public void blink()
{
    blink = true;
}

public void frozenify()
{
    changeSpriteArea(new Rectangle(getSpritePosition().x-1, getSpritePosition().y-1, 34, 42));
    bubbleFace = frozenFace;
}

public final void paint(Graphics g, GameApplet applet)
{
    checkJump = false;
    checkFall = false;

    Point p = getSpritePosition();

    if (blink && bubbleFace != frozenFace)
    {
        blink = false;
        g.drawImage(bubbleBlink, p.x, p.y, applet);
    }
    else
    {
        if (FrozenBubble.getMode() == FrozenBubble.GAME_NORMAL || bubbleFace == frozenFace) {
            g.drawImage(bubbleFace, p.x, p.y, applet);
        }
        else {
            g.drawImage(bubbleBlindFace, p.x, p.y, applet);
        }
    }

    if (fixedAnim != -1)
    {
        g.drawImage(bubbleFixed[fixedAnim], p.x, p.y, applet);
        fixedAnim++;
        if (fixedAnim == 6)
        {
            fixedAnim = -1;
        }
    }
}   

}

u012216727
u012216727   Ds   Rxr 2016.09.08 16:03

在网上可以搜到手机键盘码的,手机上的每一个键有一个数字码,然后你判断一下:
如果你按A(这个数字你自己选):
if(e.keycode==58)花括号//这里的A的数字码可能不是58,我只是随便找了个数字代替一下的
获取你的图片在屏幕上的位置,然后用++,--,或者你需要进行位置的距离来进行计算就可以了
花括号
而泡泡上升碰到其他的泡泡,这个就是碰撞检测了,碰撞检测我只知道一点点,你可以查查资料看看,网上可以搜到的。
然后根据泡泡的颜色来进行相应的操作就可以了。
泡泡的上升则不断的增加泡泡的竖直方向上的位置就可以了。
对于泡泡上升位置的停止,你可以定义一个常量,如果三个泡泡颜色不一样,就给这个常量一个新值,然后在一个判断里break一下就可以了。
泡泡的上升最好用for,范围在屏幕底层的原点到屏幕竖直方向上的最高点。
你可以根据这个思路,然后自己调整修改。

qq_29594393
qq_29594393   Ds   Rxr 2016.09.08 17:41

感觉进入了一个误区,就是用图片进行判断,
其实在底层用的还是一个数组表示,或者用其他数据存储泡泡对象,判断大小,颜色,这些都是对象的属性,
每一次一个泡泡的运动到最后能影响的范围,做一个遍历的判断,那就是规则,

Csdn user default icon
上传中...
上传图片
插入图片