解决组件闪动问题
在前面的代码中,由于组件不停的分别绘制,会出现明显闪动问题,若将所有组件绘制到同一个画布里,重新绘制时绘制整个画布,就可以有效解决闪动问题。
在窗体中定义一个画布
Image offScreenImage;//定义画布
在绘制函数中将所有的组件都绘制到画布中,并绘制整个画布
public void paint(Graphics g) {//调用绘制函数
offScreenImage=this.createImage(768,1000);
Graphics gImage=offScreenImage.getGraphics();
bg.paintSelf(gImage);
line.paintSelf(gImage);
gold.paintSelf(gImage);
g.drawImage(offScreenImage,0,0,null);
}
由于前期创建背景类时使用了bg,为避免混淆,今天把它改为了Bg,修改类名时不小心把绘制部分中调用的Bg类中的变量bg也改掉了,导致背景中绘制自己的函数出错。调用时要使用前面定义的变量。还有就是,如果重新写了程序,请一定要记得把外部的图片等素材复制进去,,,
金块抓取收回
为金块添加一个状态3,抓取收回,当线的endx和endy在金块的坐标内时状态为3
//状态 0 摇摆 1 向下抓取 2 收回 3抓取返回
int state;
GameWin frame;//使线类可以接收到主窗口中的元素
Line(GameWin frame){this.frame=frame;}
void logic(){
if (endx>this.frame.gold.x && endx<this.frame.gold.x+this.frame.gold.width
&& endy>this.frame.gold.y && endy<this.frame.gold.y+this.frame.gold.height){
state=3;
}
void paintSelf(Graphics g){
logic();
switch (state){
//状态0,1,2省略
case 3:
if (length>100) {
length = length - 10;
lines(g);
this.frame.gold.x=endx-26;
this.frame.gold.y=endy;
}else {
this.frame.gold.x=-150;
this.frame.gold.y=-150;
state=0;
}
break;
}
多个金块
public class GameWin extends JFrame { //创建窗口
List<Object> objectList = new ArrayList<>();//存储金块,石块
Bg bg=new Bg();
Line line=new Line(this);
{//不能直接在类中使用for循环,可以构造无参构造或代码块
for (int i = 0; i < 3; i++) {
objectList.add(new Gold());
}
}
Image offScreenImage;//定义画布
void launch(){
this.setVisible(true); //设置窗口是否可见
this.setSize(768,700); //直接输入数字即可
this.setLocationRelativeTo(null); //窗口居中
this.setTitle("黄金矿工"); //窗口名称
setDefaultCloseOperation(EXIT_ON_CLOSE);//关闭窗口
addMouseListener(new MouseAdapter() {
@Override
public void mouseClicked(MouseEvent e) {
super.mouseClicked(e);
if(e.getButton()==1);//左轮为e
{line.state=1;}
}
});
while(true){//死循环
repaint();//使线段不停的重新绘制,即使线可以进行摇摆
try {
Thread.sleep(10);//设置时延
} catch (InterruptedException e) {
e.printStackTrace();//编写时会发生异常,直接选择try catch解决
}
}
}
@Override
public void paint(Graphics g) {//调用绘制函数
offScreenImage=this.createImage(768,700);
Graphics gImage=offScreenImage.getGraphics();
bg.paintSelf(gImage);
line.paintSelf(gImage);
for (Object obj:objectList){//增强for循环
obj.paintSelf(gImage);
}
g.drawImage(offScreenImage,0,0,null);
}
public static void main(String[] args) { //输入psvm直接声明主函数
GameWin gameWin=new GameWin();
gameWin.launch(); //new一个类后才能调用这个类
}
}
线类中
Line(GameWin frame){this.frame=frame;}
void logic(){
for (Object obj:this.frame.objectList){//增强for循环
if (endx>obj.x && endx<obj.x+obj.width
&& endy>obj.y && endy<obj.y+obj.height){
state=3;
}
}
}
//前后不再写,直接写case 3
case 3:
if (length>100) {
length = length - 10;
lines(g);
for (Object obj:this.frame.objectList) {//增强for循环
obj.x=endx-26;
obj.y=endy;
if (length<=100){
obj.x=-150;
obj.y=-150;
state=0;
}
}
}
break;
多次使用循环增强,感觉冗余度有点高,使用无参构造应该好一点。
金块类
public class Gold extends Object{
Gold(){//金块生成位置,因此要设置为变量,使用随机数
this.x=(int) (Math.random()*700);//窗体大小为768,设置为700防止金块生成在窗体外
this.y=(int) (Math.random()*400+210);//防止金块生成在天上
this.width=52;
this.height=52;
this.img= Toolkit.getDefaultToolkit().getImage("imgs/gold1.gif");
}
}