[java]代码库
1.主类
package s1230坦克大战;
import java.awt.Color;
import java.awt.Graphics;
import java.awt.event.KeyEvent;
import java.awt.event.KeyListener;
import java.util.Vector;
import javax.swing.ImageIcon;
import javax.swing.JFrame;
import javax.swing.JPanel;
import 工具类.ThreadSleep;
public class Tank1 extends JFrame {
static int panelXLength=700;
static int panelYlength=700;
static int gameXLength=500;
static int gameYLength=500;
static int zidanNum=0;
MyPanel mp=null;
public static void main(String[] args)
{
Tank1 t1=new Tank1();
}
public Tank1()
{ mp=new MyPanel();
this.add(mp);
this.setTitle("坦克大战"); //设置窗体的标题
this.setLocationRelativeTo(null); //设置窗体出现位置居中
this.setDefaultCloseOperation(3); //设置窗体的关闭操作
this.setResizable(true); //设置禁止调整窗体的大小
this.setIconImage((new ImageIcon("E:/Michael/javaImage/扫雷图片/bomb.png").getImage())); //设置标题栏图标
this.setSize(panelXLength,panelYlength); //设置窗体的大小
this.setLocationRelativeTo(null); //设置窗体出现在屏幕中间
this.addKeyListener(mp);
this.setVisible(true);
Thread o=new Thread(mp); //添加线程很重要 不然子弹不会动
o.start(); //这个线程的作用是不断执行MyPanel
}
class MyPanel extends JPanel implements KeyListener,Runnable
{
MyTank mt=null; //有什么作用?
Vector<EnemyTank> dtk=new Vector<EnemyTank>(); //new 出一个新的vector对象,vector多线程
int tankNum=3;
public MyPanel()
{
mt=new MyTank(250,400); //创建我方坦克
for(int i=0;i<tankNum;i++) //批量创建敌方坦克,要用到vector
{ EnemyTank dt=new EnemyTank((i)*180+5,10);
dtk.add(dt);
Thread r=new Thread(dt); //让坦克动起来的线程
r.start();
}
}
public void paint(Graphics g)
{
super.paint(g);
g.fillRect(0,0,gameXLength,gameYLength);
this.drawTank(mt.getX(),mt.getY(),g,mt.leixing,mt.fangxiang); //在界面上绘制我方坦克,x(坐标),y(坐标),画笔g,类型,方向
for(int i=0;i<tankNum;i++) //在界面上批量绘制敌方坦克
{ if(dtk.get(i).life==true)
{this.drawTank(dtk.get(i).getX(),dtk.get(i).getY(),g,0,dtk.get(i).fangxiang); //x(坐标),y(坐标),画笔g,类型,方向
for(int j=0;j<dtk.get(i).dzd.size();j++)
{
Zidan zd=dtk.get(i).dzd.get(j);
dtk.get(i).shoot();
if(zd!=null&&zd.life==true) //mt.zd.life==true 控制子弹的范围
{
g.setColor(Color.RED); //设置子弹颜色
g.fill3DRect(zd.x, zd.y, 3,3, false); //绘制子弹,如何让子弹动起来
}
if(zd.life==false) //除去Vector中的zd对象,目的是为了实现子弹数量限制
dtk.get(i).dzd.remove(zd);
}
}
}
for(int i=0;i<mt.aa.size();i++) //绘制我方坦克子弹
{ Zidan zd=mt.aa.get(i);
if(zd!=null&&mt.zd.life==true) //mt.zd.life==true 控制子弹的范围
{
g.setColor(Color.RED); //设置子弹颜色
g.fill3DRect(zd.x, zd.y, 3, 3, false); //绘制子弹,如何让子弹动起来
}
if(zd.life==false) //除去Vector中的zd对象,目的是为了实现子弹数量限制
mt.aa.remove(zd);
}
}
//子弹是否击中tank的判断方法*************************************
public void jizhong(Zidan zd,EnemyTank dt)
{ switch(dt.fangxiang)
{
case 0:
case 1:
if(zd.x>dt.x&&zd.x<dt.x+20&&zd.y>dt.y&&zd.y<dt.y+30)
{ zd.life=false; dt.life=false;}
break;
case 2:
case 3:
if(zd.x>dt.x&&zd.x<dt.x+30&&zd.y>dt.y&&zd.y<dt.y+20)
{ zd.life=false; dt.life=false;}
break;
}
}
//子弹是否击中tank的判断方法*************************************
private void drawTank(int x, int y, Graphics g, int leixing, int fangxiang) //绘制坦克的方法
{
switch(leixing) //设置坦克颜色,0为黄色,1为绿色
{
case 0: g.setColor(Color.YELLOW);break;
case 1: g.setColor(Color.GREEN);break;
}
switch(fangxiang) //坦克方向,case0表示面朝上方的坦克,1表示面朝右方,2表示面朝下方,3表示面朝左方
{
case 0: g.fill3DRect(x, y, 5, 30, false); //履带
g.fill3DRect(x+15, y, 5, 30, false); //履带
g.fill3DRect(x+5, y+5, 10, 20, false); //中间正方形车体
g.fillOval(x+5, y+10, 10, 10); //椭圆炮台
g.drawLine(x+10, y+15, x+10, y-3); //炮管:绝对长度为18
break;
case 1: g.fill3DRect(x, y, 30, 5, false); //履带
g.fill3DRect(x, y+15, 30, 5, false); //履带
g.fill3DRect(x+5, y+5, 20, 10, false); //中间正方形车体
g.fillOval(x+10, y+5, 10, 10); //椭圆炮台
g.drawLine(x+15, y+10, x-3, y+10); //炮管:绝对长度为18
break;
case 2: g.fill3DRect(x, y, 5, 30, false); //履带
g.fill3DRect(x+15, y, 5, 30, false); //履带
g.fill3DRect(x+5, y+5, 10, 20, false); //中间正方形车体
g.fillOval(x+5, y+10, 10, 10); //椭圆炮台
g.drawLine(x+10, y+15, x+10, y+33); //炮管:绝对长度为18
break;
case 3: g.fill3DRect(x, y, 30, 5, false); //履带
g.fill3DRect(x, y+15, 30, 5, false); //履带
g.fill3DRect(x+5, y+5, 20, 10, false); //中间正方形车体
g.fillOval(x+5, y+5, 10, 10); //椭圆炮台
g.drawLine(x+10, y+10, x+28, y+10); //炮管:绝对长度为18
break;
}
}
public void keyTyped(KeyEvent e) {}
public void keyReleased(KeyEvent e) {}
public void keyPressed(KeyEvent e)
{ //坦克的方向控制,依次是上下左右,对应按键是w s a d。
if(e.getKeyCode()==KeyEvent.VK_W)
{
this.mt.setFangxiang(0);
this.mt.upMove();
}
if(e.getKeyCode()==KeyEvent.VK_S)
{ this.mt.setFangxiang(2);
this.mt.downMove();
}
if(e.getKeyCode()==KeyEvent.VK_A)
{ this.mt.setFangxiang(1);
this.mt.leftMove();
}
if(e.getKeyCode()==KeyEvent.VK_D)
{ this.mt.setFangxiang(3);
this.mt.rightMove();
}
if(e.getKeyCode()==KeyEvent.VK_J) //监听发射子弹的按钮
{ if(mt.aa.size()<8) //限制子弹发射的数量为8颗
this.mt.shoot();
}
this.repaint(); //还没搞懂这个是干嘛的?
}
public void run()
{
while(true)
{
ThreadSleep.threadSleep(100);
for(int i=0;i<mt.aa.size();i++) //2层循环的作用是,让每一颗子弹和每一辆坦克的坐标对比,来确定被打中的坦克
{ Zidan zd=mt.aa.get(i); //取出子弹
if(zd.life) //如果子弹有效
{
for(int j=0;j<dtk.size();j++)
{EnemyTank dt=dtk.get(j); //取出坦克对象
if(dt.life) this.jizhong(zd,dt);//判断子弹是否击中tank
}
}
}
this.repaint(); //还没搞懂这个是干嘛的?
}
}
}
}
2.sucai类
package s1230坦克大战;
import java.util.Random;
import java.util.Vector;
class Tank {
int x=0,y=0; //横纵坐标
int speed=9;
int fangxiang=0;
int leixing=1;
int time=0;
boolean life=true;
public Tank(int x,int y) //构造方法
{this.x=x;
this.y=y;
}
public int getSpeed() {return speed;}
public void setSpeed(int speed) {this.speed = speed;}
public int getX() {return x;}
public void setX(int x) {this.x = x;}
public int getY() {return y;}
public void setY(int y) {this.y = y;}
public void upMove() {if(y>5) y-=speed;} //向上移动
public void downMove() {if(y<460)y+=speed;} //向下移动
public void leftMove() {if(x>5) x-=speed;} //向左移动
public void rightMove() {if(x<460)x+=speed;} //向右移动
public int getFangxiang() {return fangxiang;}
public void setFangxiang(int fangxiang) {this.fangxiang = fangxiang;}
public int getLeixing() {return leixing;}
public void setLeixing(int leixing) {this.leixing = leixing;}
}
class MyTank extends Tank
{ Vector<Zidan> aa=new Vector<Zidan>(); //专门存放子弹,来解决一按发射键子弹消失的问题
Zidan zd=null;
public MyTank(int x,int y)
{super(x,y);} //调用父类的构造方法
public void shoot()
{ switch(this.fangxiang)
{ case 0: zd=new Zidan(x+10,y,0); aa.add(zd);break; //每发射一颗子弹都加入到容器Vector中
case 1: zd=new Zidan(x,y+10,1); aa.add(zd);break;
case 2: zd=new Zidan(x+10,y+30,2); aa.add(zd);break;
case 3: zd=new Zidan(x+30,y+10,3); aa.add(zd);break;
}
Thread t=new Thread(zd); //这个线程是为了让子弹动起来
t.start();
}
}
class EnemyTank extends Tank implements Runnable
{ int speed=1; //每次线程调用,坦克前进一次的距离
Zidan zd=null;
Vector<Zidan> dzd=new Vector<Zidan>(); //专门存放子弹,来解决一按发射键子弹消失的问题
public EnemyTank(int x,int y)
{super(x,y);} //调用父类的构造方法
public void shoot()
{ switch(this.fangxiang)
{ case 0: zd=new Zidan(x+10,y,0); dzd.add(zd);break; //每发射一颗子弹都加入到容器Vector中
case 1: zd=new Zidan(x,y+10,1); dzd.add(zd);break;
case 2: zd=new Zidan(x+10,y+30,2); dzd.add(zd);break;
case 3: zd=new Zidan(x+30,y+10,3); dzd.add(zd);break;
}
Thread t=new Thread(zd); //这个线程是为了让子弹动起来
t.start();
}
public void run()
{
while(true)
{
int length;
Random a=new Random();
this.fangxiang=(int)(Math.random()*4); //随机产生方向
switch(this.fangxiang)
{ case 0:
length=a.nextInt(59)+13; //每次随机方向,坦克前进的距离为 次数*speed,就是每次随机方向前进的总距离
for(int i=0;i<length;i++)
{
if(y>5)y-=speed;
else break;
try {Thread.sleep(50);} //通过线程挂起的时间,控制地方坦克移动的频率,0.2秒前进一次
catch (Exception e) {}
}
break;
case 1:
length=a.nextInt(59)+13; //每次随机方向,坦克前进的次数 次数*speed,就是每次随机方向前进的总距离
for(int i=0;i<length;i++)
{
if(x>5)x-=speed;
else break;
try {Thread.sleep(50);} //通过线程挂起的时间,控制地方坦克移动的频率,0.2秒前进一次
catch (Exception e) {}
}
break;
case 2:
length=a.nextInt(59)+13; //每次随机方向,坦克前进的次数 次数*speed,就是每次随机方向前进的总距离
for(int i=0;i<length;i++)
{
if(y<480)y+=speed;
else break;
try {Thread.sleep(50);} //通过线程挂起的时间,控制地方坦克移动的频率,0.2秒前进一次
catch (Exception e) {}
}
break;
case 3:
length=a.nextInt(59)+13; //每次随机方向,坦克前进的次数 次数*speed,就是每次随机方向前进的总距离
for(int i=0;i<length;i++)
{
if(x<470)x+=speed;
else break;
try {Thread.sleep(50);} //通过线程挂起的时间,控制地方坦克移动的频率,0.2秒前进一次
catch (Exception e) {}
}
break;
}
if(this.life==false) break; //如果坦克被子弹击中,那么就退出循环
Vector<Zidan> dzd=new Vector<Zidan>();
//坦克发子弹的代码
time++;
if(time%2==0)
{ if(life)
{
if(dzd.size()<5)
{ Zidan zd=null;
switch(fangxiang)
{
case 0: zd=new Zidan(x+10,y,0);
dzd.add(zd);
break;
case 1: zd=new Zidan(x+10,y,1);
dzd.add(zd);
break;
case 2: zd=new Zidan(x+10,y,2);
dzd.add(zd);
break;
case 3: zd=new Zidan(x+10,y,3);
dzd.add(zd);
break;
}
Thread t5=new Thread(zd);
t5.start();
}
}
}
}
}
}
class Zidan implements Runnable
{ int x,y;
int fangxiang;
int speed=9;
boolean life=true;
public Zidan(int x,int y,int fangxiang)
{this.x=x;
this.y=y;
this.fangxiang=fangxiang;
}
public void run()
{
while(true) //线程下面有死循环都要有休眠时间
{
try {Thread.sleep(50);}
catch (Exception e) {}
switch(fangxiang)
{ case 0: y-=speed;break;
case 1: x-=speed;break;
case 2: y+=speed;break;
case 3: x+=speed;break;
}
if(x<0||x>500||y<0||y>500) //子弹出了游戏边界就自动就将生命值设为false
{this.life=false; break;}
}
}
}
[源代码打包下载]
初级程序员
by: 一梦三生 发表于:2015-12-28 10:33:26 顶(0) | 踩(0) 回复
import 工具类.ThreadSleep;
提示有错误。。
网友回复
回复尜尜 : 把ThreadSleep().threadsleep(100);方法换成Thread.sleep(100);就好
顶(0) 踩(0) 2015-12-30 17:55:54
永夜极光 : 把ThreadSleep().threadsleep(100);方法换成Thread.sleep(100);就好
顶(0) 踩(0) 2017-06-03 02:29:06
回复评论