您的位置:首页 > 其它

坦克大战(版本0.1-版本0.9)

2016-05-17 21:41 295 查看
版本0.1

功能: 产生一个窗口

掌握: 通过Eclipse建立新的项目 为新的项目指定不同的源代码和输出目录 指定项目所用的JDK版本 通过Eclipse建立新的类

注意: 类名和方法名的命名能够见名知意,类名首字母大写,方法名、变量名首字母小写,应用驼峰标识(多个单词组成第一个单词小写,其他单词首字母大写)

具体代码实现:

import java.awt.Frame;

public class TankClient extends Frame{

public static void main(String[] args) {
TankClient tc=new TankClient();
tc.launchFrame();
}
public void launchFrame(){
this.setLocation(400,300);
this.setSize(800, 600);
setVisible(true);
}
}


版本0.2

功能: 添加关闭窗口的事件处理,不允许窗口的大小改动

掌握: 匿名类的用法 思考:匿名类的应用场合? 类短小、不涉及将来的扩展、不涉及重要的业务逻辑 通过Eclipse重写父类的方法

注意: 没掌握匿名类的先照抄,不写也行 不影响最后的运行效果

具体代码实现:

import java.awt.Frame;
import java.awt.event.WindowAdapter;
import java.awt.event.WindowEvent;

public class TankClient extends Frame{

public static void main(String[] args) {
TankClient tc=new TankClient();
tc.launchFrame();
}
public void launchFrame(){
this.setLocation(400,300);
this.setSize(800, 600);
this.addWindowListener(new WindowAdapter() {

@Override
public void windowClosing(WindowEvent e) {

System.exit(0);
}

});
setResizable(false);
setVisible(true);
}
}


版本0.3

功能: 画出代表坦克的实心圆

掌握: 如何重写paint方法

注意: 不要改变原来的前景色

回顾: paint(Graphics g)方法,窗口重画时自动调用 x轴、y轴的方向(X向右递增、Y向下递增)

具体代码实现:

import java.awt.Color;
import java.awt.Frame;
import java.awt.Graphics;
import java.awt.event.WindowAdapter;
import java.awt.event.WindowEvent;

public class TankClient extends Frame{

//重写paint方法
@Override
public void paint(Graphics g) {
System.out.println(g.getColor());
//不要改变原来的前景色,先拿出来,使用以后再改回去
//getClolor返回的是this graphics context's current color
Color c=g.getColor();
g.setColor(Color.RED);
//四个参数分别代表Frame的左上角的x、y坐标,实心圆的宽width和高height
g.fillOval(50,50,30,30);
g.setColor(c);

}
public static void main(String[] args) {
TankClient tc=new TankClient();
tc.launchFrame();
}
public void launchFrame(){
this.setLocation(400,300);
this.setSize(800, 600);
this.addWindowListener(new WindowAdapter() {

@Override
public void windowClosing(WindowEvent e) {

System.exit(0);
}

});
setResizable(false);
//设置背景色
this.setBackground(Color.GREEN);
setVisible(true);
}
}


版本0.4

功能: 让坦克运动起来

步骤: 将位置改变为变量 启动线程不断重画

思考:为什么使用线程重画,而不是每按下一个键进行一次重画?

因为线程重画更均匀,更能控制重画的速度。 按键重画不能解决子弹自动飞行的问题。 每次重画改变Tank位置

掌握: 内部类的使用 思考:内部类有哪些好处?什么时候使用内部类? 可以方便的访问包装类的方法。不方便公开的,只为包装类服务的类应当定义为内部类。

注意: x, y值得含义,指的是小方块的左上角点

具体代码实现:

import java.awt.Color;
import java.awt.Frame;
import java.awt.Graphics;
import java.awt.event.WindowAdapter;
import java.awt.event.WindowEvent;

public class TankClient extends Frame{
//将坦克的位置设置为变量
int x=50;
int y=50;

//重写paint方法
@Override
public void paint(Graphics g) {
//不要改变原来的前景色,先拿出来,使用以后再改回去
//getClolor返回的是this graphics context's current color
Color c=g.getColor();
g.setColor(Color.RED);
//四个参数分别代表Frame的左上角的x、y坐标,实心圆的宽width和高
g.fillOval(x,y,30,30);
g.setColor(c);
y+=5;
}
public static void main(String[] args) {
TankClient tc=new TankClient();
tc.launchFrame();
}
public void launchFrame(){
//窗体位置
this.setLocation(400,300);
//窗体尺寸大小
this.setSize(800, 600);
//窗体title名称
this.setTitle("TankWar");
this.addWindowListener(new WindowAdapter() {

@Override
public void windowClosing(WindowEvent e) {

System.exit(0);
}

});
setResizable(false);
//设置背景色
this.setBackground(Color.GREEN);
setVisible(true);
new Thread(new PaintThread()).start();
}
//使用内部类,只为包装类复位
private class PaintThread implements Runnable{

@Override
public void run() {
//重画,内部会自动调用paint(Graphics g)方法
repaint();
try {
Thread.sleep(100);
} catch (InterruptedException e) {
e.printStackTrace();
}
}

}
}


版本0.4.1

功能:使用双缓冲消除闪烁现象

原因:刷新重画频率太快,paint方法还没有完成 逐条显示

解决办法:将所有东西画在虚拟图片上,一次性显示出来

注意:如果不能理解透彻就照抄本版本代码,不影响对J2SE的练习功效

具体代码实现:

import java.awt.Color;
import java.awt.Frame;
import java.awt.Graphics;
import java.awt.Image;
import java.awt.event.WindowAdapter;
import java.awt.event.WindowEvent;

public class TankClient extends Frame {
// 将坦克的位置设置为变量
int x = 50;
int y = 50;
Image offScreenImage = null;

// 重写paint方法
@Override
public void paint(Graphics g) {
// 不要改变原来的前景色,先拿出来,使用以后再改回去
// getClolor返回的是this graphics context's current color
Color c = g.getColor();
g.setColor(Color.RED);
// 四个参数分别代表Frame的左上角的x、y坐标,实心圆的宽width和高
g.fillOval(x, y, 30, 30);
g.setColor(c);
y += 50;
}

@Override
public void update(Graphics g) {
if (offScreenImage == 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);
}

public static void main(String[] args) {
TankClient tc = new TankClient();
tc.launchFrame();
}

public void launchFrame() {
// 窗体位置
this.setLocation(400, 300);
// 窗体尺寸大小
this.setSize(800, 600);
// 窗体title名称
this.setTitle("TankWar");
this.addWindowListener(new WindowAdapter() {

@Override
public void windowClosing(WindowEvent e) {

System.exit(0);
}

});
setResizable(false);
// 设置背景色
this.setBackground(Color.GREEN);
setVisible(true);
new Thread(new PaintThread()).start();
}

// 使用内部类,只为包装类复位
private class PaintThread implements Runnable {

@Override
public void run() {
// 重画,内部会自动调用paint(Graphics g)方法
repaint();
try {
Thread.sleep(50);
} catch (InterruptedException e) {
e.printStackTrace();
}
}

}
}


版本0.5

功能: 代码重构,将以后可能需要多处改变的量定义为常量,Frame的宽度和高度(常量名一般大写)

注意: 常量一般是public static final的。

具体代码实现:

import java.awt.*;
import java.awt.event.*;

public class TankClient extends Frame {
// 设置成常量,方便以后的改动
public static final int GAME_WIDTH = 800;
public static final int GAME_HEIGHT = 600;
Tank myTank = new Tank(50, 50);

// 定义虚拟图片,方便后期的一次性显示
Image offScreenImage = null;

public void paint(Graphics g) {
// 不改变前景色
myTank.draw(g);
}

// 刷新操作
public void update(Graphics g) {
if (offScreenImage == null) {
offScreenImage = this.createImage(GAME_WIDTH, GAME_HEIGHT);
}
Graphics gOffScreen = offScreenImage.getGraphics();
Color c = gOffScreen.getColor();
gOffScreen.setColor(Color.GREEN);
gOffScreen.fillRect(0, 0, GAME_WIDTH, GAME_HEIGHT);
gOffScreen.setColor(c);
paint(gOffScreen);
g.drawImage(offScreenImage, 0, 0, null);
}

public void lauchFrame() {
this.setLocation(400, 300);
this.setSize(GAME_WIDTH, GAME_HEIGHT);
this.setTitle("TankWar");
this.addWindowListener(new WindowAdapter() {
public void windowClosing(WindowEvent e) {
System.exit(0);
}
});
this.setResizable(false);
this.setBackground(Color.GREEN);

this.addKeyListener(new KeyMonitor());

setVisible(true);

new Thread(new PaintThread()).start();
}

public static void main(String[] args) {
TankClient tc = new TankClient();
tc.lauchFrame();
}

private class PaintThread implements Runnable {

public void run() {
while (true) {
repaint();
try {
Thread.sleep(50);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}

// 创建键盘时间监听
private class KeyMonitor extends KeyAdapter {

// 直接调用myTank自己的方法根据相应的按键信息进行移动
public void keyPressed(KeyEvent e) {
myTank.KeyPressed(e);
// 添加了处理键抬起的事件,可以控制坦克起步以后的状态
// 而不是一直按照一个方向走下去
myTank.keyReleased(e);
}

}
}


View Code
未完待续。。。。。。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: