本篇文章目的
- 画出坦克的实心圆
- 让坦克圆动起来
- 双缓冲解决闪烁问题
一、画出代表坦克的实心圆
我们需要画出一个圆,那么可以使用fillOval方法
fillOval(int x,int y ,int width ,int height)
参数的X 和 Y是矩形框的左上角的坐标,width和height是宽和高。
而我们重写paint方法进行画出坦克的圆
@Override
public void paint(Graphics g) {
//获取默认的颜色Color
Color c = g.getColor();
//将坦克颜色为红色
g.setColor(Color.red);
//画一个圆
g.fillOval(50,50,30,30);
//将原颜色填充回
g.setColor(c);
}
当然也可以在lauchFrame方法里添加背景填充色,显得更外显眼一些
//添加设置背景颜色
this.setBackground(Color.GREEN);
二、让坦克动起来
我们使用fillOval方法画出了圆的实现,那么怎么让这个圆改变位置?
//画一个圆
g.fillOval(50,50,30,30);
我们发现x和y的做标都是50,他们是固定的!
若改变成变量的方式?是不是也是一样可以呢?
int x = 50;//坦克的x坐标
int y = 50;//坦克的y坐标
@Override
public void paint(Graphics g) {
//获取默认的颜色Color
Color c = g.getColor();
//将坦克颜色为红色
g.setColor(Color.red);
//画一个圆
g.fillOval(x,y,30,30);
//将原颜色填充回
g.setColor(c);
}
若我们每次原有的基础上进行改动,是不是就动起来了?
我们采用repaint重绘方法,每隔多少毫秒刷新最新的圆点信息坐标
private class PaintThread implements Runnable {
@Override
public void run() {
while (true) {
repaint();//重绘方法
try {
Thread.sleep(100);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}
//定义窗口方法
public void lauchFrame() {
//省略其他关键性代码.....
//添加设置背景颜色
this.setBackground(Color.GREEN);
//使用线程重绘最新圆点信息坐标
new Thread(new PaintThread()).start();
}
@Override
public void paint(Graphics g) {
//省略其他关键性代码.....
//刷新圆点位置
x += 5;//x坐标
y += 5;//y坐标
}
这时我们在main方法运行起来就发现每个100毫秒就会移动圆点位置了
为什么使用线程重面,而不是每按下一个键进行一次重画?
- 线程重画更均匀,更能控制重画的速度。
- 按键重画不能解决子弹自动飞行的问题。
三、双缓冲解决闪烁问题
我们的显示器一般都是多少hz、多少hz的刷新率,而刷新速度太快,paint方法还没完成,没跟上导致会出现闪烁的问题
那么怎么解决呢?
1.逐条显示
2.将所有东西画在虚拟图片上,一次性显示出来
Image offScreenImage = null;//虚拟图片
@Override
public void update(Graphics g){
if(offScreenImage == null){
//若为null,则创建一张图片
offScreenImage = this.createImage(800,600);
}
//获取到虚拟图片的画笔
Graphics gOffScreen = offScreenImage.getGraphics();
//使用虚拟图片的画笔画圆
paint(gOffScreen);
//将虚拟图片画下来
g.drawImage(offScreenImage,0,0,null);
}
但是运行起来会发现,圆动起来后慢慢变成了一条线
这是怎么回事呢?
因为当我们不重写update方法时,它会自己用背景颜色刷一遍,刷完再画
而为什么会一条线呢,因为背景没刷,之前画出来的圆还在那
所以我们用虚拟图片的画笔画出一个方框出来代替之前的背景
@Override
public void update(Graphics g){
if(offScreenImage == null){
//若为null,则创建一张图片
offScreenImage = this.createImage(800,600);
}
//获取到虚拟图片的画笔
Graphics gOffScreen = offScreenImage.getGraphics();
//默认黑色,所以需要与效果背景一致获取原色
Color c = gOffScreen.getColor();
gOffScreen.setColor(Color.green);//与原背景色一致
//使用画笔画出一个实现的方框代替原画的背景效果
gOffScreen.fillRect(0,0,800,600);
gOffScreen.setColor(c);//设置原回来
//使用虚拟图片的画笔画圆
paint(gOffScreen);
//将虚拟图片画下来
g.drawImage(offScreenImage,0,0,null);
}
这时再运行就即可
参考资料
尚学堂:坦克大战(马士兵老师)