📄 bubblesprite.java
字号:
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;
}
}
}
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -