说明 :学习Se感觉快无聊死了 写个项目来整合一下知识,也提高一下兴趣;
版本 1:实现画出窗口,设置好背景和一个坦克;
版本 2:在版本1的基础上 实现坦克的移动(使用线程呗)
我们在线程里调用repaint(){它里面会发调用paint};
版本 2.1:在版本2的基础上 实现坦克的移动(使用线程呗)
* 我们在线程里调用repaint(){它里面会发调用paint}
* 我们在加上双缓冲来消除闪烁
* 说明:闪烁的原因是我们的刷新率比较快 我们的paint()方法还没有画完就刷新了
* 就会出现闪烁现象
* 在我们电脑上其实并没有出现 我们就是说明一下这个知识点
* 原理:就是我们的 repaint 方法在调用 paint 方法之前会调用 update 方法
* 我们在 update 方法这里 设置一个虚拟的图片作为背景 我们在这里调用一下paint就可以把我们
* 原本设置画的东西给画上去 我们把化之后的图片直接呈现给你就不会出现闪烁的问题了
* 但是我们还要每次画了之后把原来的那个圆给擦除掉
* 解决这个问题的方法就是我们在这之前画一个跟背景一样的图片;
代码如下:
版本 1 :
package TankWarOne;
import java.awt.event.WindowAdapter;
import java.awt.event.WindowEvent;
import javax.swing.JFrame;
/**
*
* 游戏的主窗口
* 版本 1:实现画出窗口,设置好背景和一个坦克
* @author Wang
*
*/
/**
* 我们创建窗口的方法有两种一种是继承这个类
* 另一个是直接用这个类 new 一个对象
*/
public class Window extends JFrame{
/**
* 发动窗口和对窗口进行初始化
*/
public void LaunchFrame(){
this.setTitle("Wang_TankWar");//注意参数是字符串要加双引号呀(你老是忘)
this.setVisible(true);
this.setSize(1000,800);
this.setLocation(500,200);
this.setResizable(false);//设置为用户不能设置游戏窗口的大小 为了防止定位的错乱
this.addWindowListener(new WindowAdapter(){//增加窗口监听 以便于退出程序
public void windowClosing(WindowEvent e){//这里应该应WindowClosing
//不能用windowClosed 那个飞机大战的程序我们这个地方错了
System.exit(0);
}
});
}
public static void main(String[] args){
Window w = new Window();
w.LaunchFrame();
}
}
版本 2 :
package TankWarTwo;
import java.awt.*;
import java.awt.Graphics;
import java.awt.event.WindowAdapter;
import java.awt.event.WindowEvent;
/**
*
* 游戏的主窗口
* 版本 2:在版本1的基础上 实现坦克的移动(使用线程呗)
* 我们在线程里调用repaint(){它里面会发调用paint}
* @author Wang
*
*/
/**
* 我们创建窗口的方法有两种一种是继承这个类
* 另一个是直接用这个类 new 一个对象
*/
public class MainWindow extends Frame{
/**
* 使用这个类来画出坦克
* @param args
*/
private int x = 50; //这个是坦克的表变量
private int y = 50; //注意坦克的坐标是相对于你的主窗口来定的
public void paint(Graphics g){
//super.paint(g);
Color c = g.getColor();
g.setColor(Color.red);
g.fillOval(x, y, 30, 30);
g.setColor(c);
y+=3;
}
/**
* 发动窗口和对窗口进行初始化
*/
public void LaunchFrame(){
this.setTitle("Wang_TankWar");//注意参数是字符串要加双引号呀(你老是忘)
this.setSize(1000,800);
this.setLocation(500,200);
this.setResizable(false);//设置为用户不能设置游戏窗口的大小 为了防止定位的错乱
this.setBackground(Color.green);//如果继承的是JFrame这一句就是指不了背景
setVisible(true);
this.addWindowListener(new WindowAdapter(){//增加窗口监听 以便于退出程序
public void windowClosing(WindowEvent e){//这里应该应WindowClosing
//不能用windowClosed 那个飞机大战的程序我们这个地方错了
System.exit(0);
}
});
new Thread(new PaintThread()).start();
}
public static void main(String[] args){
MainWindow w = new MainWindow();
w.LaunchFrame();
}
/**
* 要不断的调用repaint 那么就会不断的重画;
* 我们的线程在这里使用内部类
* 因为我们要服务的方法就只有paint
* 然后我们在启动窗口的方法里 启动线程就好了
*/
private class PaintThread implements Runnable{//注意类与方法的区别 类后面不家小括号的
@Override
public void run() {
while(true){
repaint(); //这个是调用外部类的方法(Frame中的方法)
try {
Thread.sleep(10);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
}
}
版本 2 .1:
package TankWarTwo;
import java.awt.*;
import java.awt.event.WindowAdapter;
import java.awt.event.WindowEvent;
/**
*
* 游戏的主窗口
* 版本 2.1:在版本2的基础上 实现坦克的移动(使用线程呗)
* 我们在线程里调用repaint(){它里面会发调用paint}
* 我们在加上双缓冲来消除闪烁
* 说明:闪烁的原因是我们的刷新率比较快 我们的paint()方法还没有画完就刷新了
* 就会出现闪烁现象
* 在我们电脑上其实并没有出现 我们就是说明一下这个知识点
* 原理:就是我们的 repaint 方法在调用 paint 方法之前会调用 update 方法
* 我们在 update 方法这里 设置一个虚拟的图片作为背景 我们在这里调用一下paint就可以把我们
* 原本设置画的东西给画上去 我们把化之后的图片直接呈现给你就不会出现闪烁的问题了
* 但是我们还要每次画了之后把原来的那个圆给擦除掉
* 解决这个问题的方法就是我们在这之前画一个跟背景一样的图片
*
*
* @author Wang
*
*/
/**
* 我们创建窗口的方法有两种一种是继承这个类
* 另一个是直接用这个类 new 一个对象
*/
public class MainWindow2 extends Frame{
private int x = 50; //这个是坦克的表变量
private int y = 50; //注意坦克的坐标是相对于你的主窗口来定的
Image vBackground = null; //设置双缓冲中需要的那个虚拟的画布
/**
* 使用这个类来画出坦克
* @param args
*/
public void paint(Graphics g){
//super.paint(g);
Color c = g.getColor();
g.setColor(Color.red);
g.fillOval(x, y, 30, 30);
g.setColor(c);
y+=3;
}
/**
* 我们重写update
*/
/*@Override
public void update(Graphics g) {
if(vBackground == null){
//我们生成这个虚拟背景图片必须与你真实的背景相同
vBackground = this.createImage(1000, 800);
}
Graphics vg = vBackground.getGraphics();//得到虚拟背景的画笔
paint(vg);
g.drawImage(vBackground, 0, 0, null);//把我们画好的那个虚拟背景用g这个画笔画出来
//那不就是把我们做好的虚拟背景给一下呈现出来了 就不会闪烁
//但这个时候因为没擦除虚拟背景上每次生成那个圆球就会形成的一条线
}*/
@Override
public void update(Graphics g) {
if(vBackground == null){
//我们生成这个虚拟背景图片必须与你真实的背景相同
vBackground = this.createImage(1000, 800);
}
Graphics vg = vBackground.getGraphics();//得到虚拟背景的画笔
Color vc = vg.getColor();//得到虚拟画笔的颜色
vg.setColor(Color.green);//设置为绿色
vg.fillRect(0, 0, 1000, 800);//每次都画一个虚拟的背景 然后在画那个球
paint(vg);
g.drawImage(vBackground, 0, 0, null);//把我们画好的那个虚拟背景用g这个画笔画出来
//那不就是把我们做好的虚拟背景给一下呈现出来了 就不会闪烁
//但这个时候因为没擦除虚拟背景上每次生成那个圆球就会形成的一条线
}
/**
* 发动窗口和对窗口进行初始化
*/
public void LaunchFrame(){
this.setTitle("Wang_TankWar");//注意参数是字符串要加双引号呀(你老是忘)
this.setSize(1000,800);
this.setLocation(500,200);
this.setResizable(false);//设置为用户不能设置游戏窗口的大小 为了防止定位的错乱
this.setBackground(Color.green);//如果继承的是JFrame这一句就是指不了背景
setVisible(true);
this.addWindowListener(new WindowAdapter(){//增加窗口监听 以便于退出程序
public void windowClosing(WindowEvent e){//这里应该应WindowClosing
//不能用windowClosed 那个飞机大战的程序我们这个地方错了
System.exit(0);
}
});
new Thread(new PaintThread()).start();
}
public static void main(String[] args){
MainWindow2 w = new MainWindow2();
w.LaunchFrame();
}
/**
* 要不断的调用repaint 那么就会不断的重画;
* 我们的线程在这里使用内部类
* 因为我们要服务的方法就只有paint
* 然后我们在启动窗口的方法里 启动线程就好了
*/
private class PaintThread implements Runnable{//注意类与方法的区别 类后面不家小括号的
@Override
public void run() {
while(true){
repaint(); //这个是调用外部类的方法(Frame中的方法)
try {
Thread.sleep(50);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
}
}