首页 诗词 字典 板报 句子 名言 友答 励志 学校 网站地图
当前位置: 首页 > 教程频道 > JAVA > J2SE开发 >

小弟我写的一个小坦克程序

2014-01-13 
我写的一个小坦克程序我写的一个小坦克程序,但发现它运行起来比较慢,请各位给点建议。运行程序后,点击start

我写的一个小坦克程序
我写的一个小坦克程序,但发现它运行起来比较慢,请各位给点建议。运行程序后,点击start按钮,再用鼠标点击一下画面中间,然后按下上下左右箭头键就可以让坦克动起来。
程序名为Tank.java,只有一个文件。因为太长,无法一次贴完,所以分两次发出。
--------------------------------------
import java.util.*;
import java.applet.*;
import java.awt.event.*;
import java.awt.*;
import java.awt.image.*;
import javax.swing.*;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.geom.AffineTransform;
import java.awt.Color;
import java.io.*;
import java.lang.Math.*;
import java.text.DecimalFormat;


class OneTank {
//坦克的长度
double tank_length = 30;
// 坦克的宽度
double tank_width = 20;
//履带的宽度
double panel_width = 6;
// 坦克中心部分的宽度
double core_width = tank_width - panel_width;
// 坦克中心部分的长度
double core_length = tank_length * 0.75;
// 坦克炮管的长度
double canon_length = tank_length / 2;
//坦克炮管的宽度
double canon_width = 4;
//----------------
// 坦克所处的中心位置
    double[] center;
//坦克旋转的角度
double angle;
// 敌我双方的哪一方
String side;
//坦克颜色
Color color;
//坦克速度
double speed;
//坦克生命值
double value;
double[] pt1, pt2, pt3, pt4, pt5, pt6, pt7, pt8, pt9, pt10, pt11, pt12, pt13, pt14, pt15, pt16;
OneTank() {
}

    void draw(Graphics g, Color c) {

Graphics2D d2=(Graphics2D)g;
d2.setColor(c);
/*
AffineTransform at=new AffineTransform();
at.setToIdentity();
at.translate((int) center[0], (int)center[1]);
at.rotate(angle);
d2.setTransform(at);
*/
d2.drawLine((int) pt1[0], (int)pt1[1], (int) pt2[0], (int)pt2[1]);
d2.drawLine((int) pt2[0], (int)pt2[1], (int) pt4[0], (int)pt4[1]);
d2.drawLine((int) pt4[0], (int)pt4[1], (int) pt3[0], (int)pt3[1]);
d2.drawLine((int) pt3[0], (int)pt3[1], (int) pt1[0], (int)pt1[1]);

d2.drawLine((int) pt5[0], (int)pt5[1], (int) pt7[0], (int)pt7[1]);
d2.drawLine((int) pt7[0], (int)pt7[1], (int) pt8[0], (int)pt8[1]);
d2.drawLine((int) pt8[0], (int)pt8[1], (int) pt6[0], (int)pt6[1]);
d2.drawLine((int) pt6[0], (int)pt6[1], (int) pt5[0], (int)pt5[1]);

d2.drawLine((int) pt10[0], (int)pt10[1], (int) pt9[0], (int)pt9[1]);
d2.drawLine((int) pt9[0], (int)pt9[1], (int) pt11[0], (int)pt11[1]);
d2.drawLine((int) pt11[0], (int)pt11[1], (int) pt12[0], (int)pt12[1]);
d2.drawLine((int) pt12[0], (int)pt12[1], (int) pt10[0], (int)pt10[1]);

//炮管
d2.drawLine((int) pt13[0], (int)pt13[1], (int) pt14[0], (int)pt14[1]);
d2.drawLine((int) pt14[0], (int)pt14[1], (int) pt15[0], (int)pt15[1]);
d2.drawLine((int) pt15[0], (int)pt15[1], (int) pt16[0], (int)pt16[1]);
d2.drawLine((int) pt16[0], (int)pt16[1], (int) pt13[0], (int)pt13[1]);
    }
}

class TankSys extends JFrame implements ActionListener,  KeyListener{
    boolean firstTimeRunning = true;
    // 标志线程是否运行
    boolean ThreadRunning = false;
    // 目前哪一个星球是被聚焦的,默认是0号,即第一个
    int WhichPlanetFocus= 0;
double PI =Math.PI;
double PI20 = PI * 2.0;
double PI05 = PI / 2.0;
double[] original_pt = new double[] {0, 0};
double final_angle, temp_angle, temp;
    // 这是绘画所有运动星球图画的区域
    // 初始化记录所有星球类
    ArrayList<OneTank> tanks = new ArrayList<OneTank>();
    // 这是在cvs上面的图像,它用于在上面画星球的图像
    Image image;
    // 这是image的Graphics
    Graphics cvsimage, gimage;
    // 获取屏幕大小
    Toolkit kit = Toolkit.getDefaultToolkit();
    Dimension screenSize = kit.getScreenSize();
    //  屏幕宽度
    int swidth = screenSize.width;
    // 屏幕高度
    int sheight = screenSize.height;
    // 屏幕中心位置
    int ScreenCenterx = (int)(swidth / 2);
    int ScreenCentery = (int)(sheight / 2);
    // 这是用鼠标点击屏幕所获得的绘画中心的偏移量
    int CenterOffsetx = ScreenCenterx;
    int CenterOffsety = ScreenCentery;
    Canvas cvs;
    // 这是cvs的大小
    int cvsw = swidth;
    int cvsh = sheight - 100;


    // 这是按钮区
    JPanel btnpan;
    JButton btnstart;
    // 一旦按下这个开始键,程序开始运行太阳系
    boolean StartToRun = false;
    public TankSys() {
        // 这是整个图框的大小
        this.setSize(swidth, sheight);
        this.setVisible(true);
        btnpan = new JPanel();
        btnpan.setLayout(new FlowLayout());
        this.getContentPane().add(btnpan, BorderLayout.NORTH);
        // 开始游戏的按钮
        btnstart = new JButton("Start");
        btnpan.add(btnstart);
        btnstart.addActionListener(this);
        cvs = new Canvas();
        // 画图区的大小
        cvs.setSize(cvsw, cvsh);
        this.getContentPane().add(cvs, BorderLayout.CENTER);
        cvs.createBufferStrategy(2);
        // 用户必须点击CVS来获得聚焦点,这时候才能接受键盘输入
        cvs.addKeyListener(new KeyHandler());
        cvs.addMouseListener(new MouseHandler());
        cvsimage = cvs.getGraphics();
        cvs.setBackground(Color.BLACK);
        // 这是在cvs上面的图像,它用于在上面画星球的图像
        image = createImage(cvsw, cvsh);
        gimage = image.getGraphics();
        this.pack();
    }

    class MouseHandler implements MouseListener{
        public void mouseClicked(MouseEvent e) {

        }
        public void mousePressed(MouseEvent e){
        }
        public void mouseReleased(MouseEvent e){
        }
        public void mouseEntered(MouseEvent e){
        }
        public void mouseExited(MouseEvent e){
        }
    }

    public void keyReleased(KeyEvent e) {//键盘弹起事件
    }
    public void keyPressed(KeyEvent e) {
}

    public void keyTyped (KeyEvent e) {// 键盘按下事件
    }
    class KeyHandler extends KeyAdapter{
        public void keyPressed(KeyEvent e){
            int keyCode = e.getKeyCode();
            switch (keyCode) {
                case KeyEvent.VK_ADD://按下数字键盘上的+
                case KeyEvent.VK_PAGE_UP://按下PageUp键

                break;
                case KeyEvent.VK_SUBTRACT://按下数字键盘上的-
                case KeyEvent.VK_PAGE_DOWN://按下PageDown

                break;
                case KeyEvent.VK_SPACE://按下空格键

                case KeyEvent.VK_P://按下PauseBreak

                break;
                case KeyEvent.VK_UP://按下向上键
                // 提高星球的线速度
temp = tanks.get(0).center[0] + tanks.get(0).speed * Math.cos(tanks.get(0).angle - PI05);
tanks.get(0).center[0] = temp;
temp = tanks.get(0).center[1] + tanks.get(0).speed * Math.sin(tanks.get(0).angle - PI05);
tanks.get(0).center[1] = temp;
forward_tank(tanks.get(0));
                break;


                case KeyEvent.VK_DOWN://按下向下键
                // j降低星球的线速度
temp = tanks.get(0).center[0] + tanks.get(0).speed * Math.cos(tanks.get(0).angle + PI05);
tanks.get(0).center[0] = temp;
temp = tanks.get(0).center[1] + tanks.get(0).speed * Math.sin(tanks.get(0).angle + PI05);
tanks.get(0).center[1] = temp;
forward_tank(tanks.get(0));
                break;
                case KeyEvent.VK_LEFT://按下向左键
// 第一个坦克一定是我方坦克
temp_angle = tanks.get(0).angle - 5.0/180.0 * PI;
if (temp_angle > PI20) {
final_angle = temp_angle - PI20;
} else if (temp_angle < 0) {
final_angle = PI20 + temp_angle;
} else {
final_angle = temp_angle;
}
tanks.get(0).angle = final_angle;
forward_tank(tanks.get(0));
                // 降低vx方向的速度
                break;
                case KeyEvent.VK_RIGHT://按下向右键
temp_angle = tanks.get(0).angle + 5.0/180.0 * PI;
if (temp_angle > PI20) {
final_angle = temp_angle - PI20;
} else if (temp_angle < 0) {
final_angle = PI20 + temp_angle;
} else {
final_angle = temp_angle;
}
tanks.get(0).angle = final_angle;
forward_tank(tanks.get(0));
                break;
                default:
            }

        }
    }

    // 这是主程序
    void DrawTank() {
        if (firstTimeRunning) {
            firstTimeRunning = false;
// 创建我方坦克
double[] center_pos = new double[] {500, 500};
OneTank one = new OneTank();
one.center = center_pos;
one.angle = PI;
double[][] re= rotate_tank(center_pos, one.angle, one.tank_length, one.tank_width, one.panel_width, one.core_width, one.core_length, one.canon_length, one.canon_width);
one.pt1=re[0];
one.pt2=re[1];
one.pt3=re[2];
one.pt4=re[3];
one.pt5=re[4];
one.pt6=re[5];
one.pt7=re[6];
one.pt8=re[7];
one.pt9=re[8];
one.pt10=re[9];
one.pt11=re[10];
one.pt12=re[11];
one.pt13=re[12];
one.pt14=re[13];
one.pt15=re[14];
one.pt16=re[15];
one.side="2";
one.color=Color.white;
one.speed=4;
one.value=50;
            tanks.add(one);
        }
        while (ThreadRunning) {
                // 把图像以前在上面所画的所有图像用黑色抹掉
                    gimage.setColor(Color.black);
                    gimage.fillRect(0, 0, cvsw, cvsh);
                for (int i = 0; i < tanks.size(); i++) {
                            tanks.get(i).draw(gimage, tanks.get(i).color);

                }
                    cvsimage.drawImage(image, 0, 0, this);
                // 计算所有星球的速度和位置
                for (int i = 0; i < tanks.size(); i++) {
//forward_tank(tanks.get(i));
                }

        }
    }

// 由一点和角度方向和距离决定一点坐标
double[] point_and_angle (double[] pt0, double angle, double dist) {
double x = pt0[0]+ dist * Math.cos (angle);
double y = pt0[1] + dist * Math.sin (angle);


return new double[] {x, y};
}


[解决办法]
之所以会运行起来慢,是因为你把操作都放到键盘监听里了,正确的做法应该是:
创建一个全局变量:private static boolean keyDown[256];   //256个按键的状态
键盘监听:if key Down{
keyDown[keyCode] = true;
}
if key Release{
keyDown[keyCode] = false;
}

键盘的监听里只改变状态,不进行任何操作。
对于操作,在你的游戏线程里进行。
例如,你可以在游戏线程里再写这样一段代码:

.....
if(keyDwon[KeyEvent.VK_UP]){
...}
else if
...

保证不卡

热点排行