坦克大战1.0——让我的坦克动起来并能够发射子弹

在文章最后有源代码,需要的小伙cai伴niao自取——参考文献 韩顺平《java从入门到精通》

public class Tankwar extends JFrame{
	MyPanel mp=new MyPanel();
	public static void main(String args[])
	{		
		Tankwar T=new Tankwar();
	}
	public Tankwar()
	{
		this.add(mp);
		//注册键盘监听
		this.addKeyListener(mp);
		this.setSize(400,300);
		this.setVisible(true);	
	}
}

接下来我要写的是tank类,作为坦克,我首先考虑的就是他一定要有一个横坐标以及纵坐标,另外,他还得有方向。在坦克大战里,坦克分两种,一种是我方坦克,一种是敌方坦克,不管是那种坦克,他都有横纵坐标,以及方向,以及移动和开火功能,所以我将其封装在一个类里面。

class Tank {
	int x;//坦克横坐标 
	int y;
	int direct;
	//设置方向
	public void setdirect(int direct){
		this.direct =direct;
	}
	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 Tank(int x,int y)
	{
		this.x=x;
		this.y=y;
	}
	void moveup(){	//向y的上移动(实际上在我们的电脑上看是向下)
		if(y<300)
			y++;
	}
	void movedown(){	//屏幕上显示向上移动
		if(y>0)	
		y--;
	}
	void moveright(){	屏幕上显示右移动
		if(x<400)
		x++;
	}
	void moveleft(){	屏幕上显示左移动
		if(x>0)
		x--;
	}	
}

那有了坦克类,现在就要区分敌人的坦克和我的坦克了。

//敌人的坦克,敌人的坦克将在接下来的文章中解释,水平暂时不够哈哈哈
class Army extends Tank{
	public Army(int x,int y){
		super(x,y);
	}
}
//我的坦克
class Hero extends Tank{
	//定义一颗子弹
	shot s=null;
	
	public Hero(int x,int y)
	{
		super(x,y);	
	}
	
	//开火
	//因为子弹要时刻判断是否撞到障碍物,所以我觉得应该把子弹做成一个线程
	public void ShotTarget(){
		//System.out.println(x);
		//System.out.println(y);
		//首先判断开火方向
		switch(this.direct)
		{
		case 0:{
			s=new shot(x+8,y+30,direct);break;
		}
		case 1:{
			s=new shot(x+8,y,direct);break;
		}
		case 2:{
			s=new shot(x+30,y+8,direct);break;
		}
		case 3:{
			s=new shot(x,y+8,direct);break;
		}
		}
		//启动线程
		Thread S1=new Thread(s);
		S1.start();

	}
}

然后是我的子弹


//子弹
class shot implements Runnable{
	int x,y;//子弹的坐标
	int direct;//子弹的方向
	int speed=4;//子弹的速度
	boolean islive=true;//子弹是否还存在
	public shot(int x,int y,int direct){
		this.x=x;
		this.y=y;
		this.direct=direct;
	}
	@Override
	public void run() {
		// TODO Auto-generated method stub
		while(true)
		{
			try {
				Thread.sleep(50);//让其休眠一会,如果一直在循环内存开销太大
				//即可能我按下开火键,但每隔50ms判断一次我是否该开火了
			} catch (InterruptedException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			}
			//通过开火的方向判断坐标
			switch(direct)
			{
				case 0:y+=speed;break;
				case 1:y-=speed;break;
				case 2:x+=speed;break;
				case 3:x-=speed;break;
			}
			//判断子弹何时死亡,如果飞出了面板,则其死亡
			if(x<0||x>400||y<0||y>300)
			{
				this.islive=false;
				break;
			}
			//判断子弹是否碰到敌人坦克
		}
	}
}

MyPanel是我定义的一个画板,为了做一个简单的页面。自己看java的时候一直搞不太懂this的用法,包括考试时也是一知半解的,这次总算理解透了,this即可看作此类的对象,为了方便我们调用。
接下来是我的MyPanel类,我的所有目的基本都要通过画板表现出来:
首先继承了JPanel,那么时一定要重写Paint()函数的。作为新手,其实还是不太理解super.paint(g)这句话的目的。

//主要有KeyListener,MouseListener,ActionListener
//KeyListener是用来监听键盘,MouseListener是用来监听鼠标,ActionListener监听按钮等
class MyPanel extends JPanel implements KeyListener,Runnable{
	//定义我的tank
	Hero hero=new Hero(10,10);
	//敌人的tank
	Army army=new Army(100,10);
	//static int direct=1;
	public void paint(Graphics g)
	{
		super.paint(g);
		g.fillRect(0, 0, 400, 300);
		//this.paint_tank(hero.getX(),hero.getY(),0,1,g);
		//画出我的tank
		this.paint_tank(hero.x,hero.y,hero.direct,1,g);
		//画敌人的坦克
		this.paint_tank(army.x,army.y,army.direct,0,g);
	}

然后就是画出坦克了

	void paint_tank(int x,int y,int direct,int type,Graphics g)
	{
		//判断敌我坦克
		switch(type)
		{ 
		//敌人的tank画成蓝色
		case 0:{
			g.setColor(Color.CYAN);
			break;
		}
		//我的tank画成黄色
		case 1:{
			g.setColor(Color.yellow);
			break;
		}
		}
		//判断方向,画出tank的不同形态
		switch(direct){
		case 0:{
			g.fill3DRect(x, y, 5, 30,false);
			g.drawOval(x+5, y+10,10, 10);
			g.fill3DRect(x+5, y+5, 10, 20,false);
			g.fill3DRect(x+15, y, 5, 30,false);
			g.drawLine(x+9, y+15, x+9, y+30);
			break;
		}
		case 1:{
			g.fill3DRect(x, y, 5, 30,false);
			g.drawOval(x+5, y+10,10, 10);
			g.fill3DRect(x+5, y+5, 10, 20,false);
			g.fill3DRect(x+15, y, 5, 30,false);
			g.drawLine(x+9, y, x+9, y+15);
			break;
		}
		case 2:{
			g.fill3DRect(x, y, 30, 5,false);
			g.drawOval(x+5, y+5,10, 10);
			g.fill3DRect(x+5, y+5, 20, 10,false);
			g.fill3DRect(x, y+15, 30, 5,false);
			g.drawLine(x+15, y+9, x+30, y+9);
			break;
		}
		case 3:{
			g.fill3DRect(x, y, 30, 5,false);
			g.drawOval(x+5, y+5,10, 10);
			g.fill3DRect(x+5, y+5, 20, 10,false);
			g.fill3DRect(x, y+15, 30, 5,false);
			g.drawLine(x, y+9, x+15, y+9);
			break;
		}
		}
		//画我的子弹
		if(hero.s!=null&&hero.s.islive==true)
		{
			g.setColor(Color.gray);
			g.drawOval(hero.s.x, hero.s.y, 2, 2);
		}
		this.repaint();//一定要重绘!因为他是动态的图形

	}
	public void keyTyped(KeyEvent e) {
		// TODO Auto-generated method stub
		
	}
	

接下来就是对于键盘的监听了

	public void keyPressed(KeyEvent e) {
		// TODO Auto-generated method stub
		//按下上键
			if(e.getKeyCode()==KeyEvent.VK_DOWN)
			{		
				hero.setdirect(0); //则将方向设置成0
				hero.moveup();//调用向上移动的函数
			}
			//以下同上
			if(e.getKeyCode()==KeyEvent.VK_UP)
			{	
				hero.setdirect(1); 
				hero.movedown();
			}
			if(e.getKeyCode()==KeyEvent.VK_RIGHT)
			{
				hero.setdirect(2);
				hero.moveright();
			}
			if(e.getKeyCode()==KeyEvent.VK_LEFT)
			{
				hero.setdirect(3); 
				hero.moveleft();
			}
			//开火
		if(e.getKeyCode()==KeyEvent.VK_J)
		{
			this.hero.ShotTarget();			
		}
		
		//重绘
		this.repaint();
	}
	
	public void keyReleased(KeyEvent e) {
		// TODO Auto-generated method stub
		
	}
	@Override
	public void run() {
		// TODO Auto-generated method stub
		try {
			Thread.sleep(100);
		} catch (InterruptedException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		this.repaint();
	}
	
}

以上就是我的坦克大战1.0版,只是单纯实现了移动以及开火,对于让敌人的坦克动起来并且也可以开火还有待我的学习。
以下是源代码:

package tank_war;
import java.util.*;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.KeyEvent;
import java.awt.event.KeyListener;
import javax.swing.*;
import java.awt.*;
import java.awt.event.KeyEvent;


public class Tankwar extends JFrame{
	MyPanel mp=new MyPanel();
	
	public static void main(String args[])
	{		
		Tankwar T=new Tankwar();
	}
	public Tankwar()
	{
		this.add(mp);
		//注册键盘监听
		this.addKeyListener(mp);
		this.setSize(400,300);
		this.setVisible(true);	
	}
}

//主要有KeyListener,MouseListener,ActionListener
class MyPanel extends JPanel implements KeyListener,Runnable{
	//定义我的tank
	Hero hero=new Hero(10,10);
	Army army=new Army(100,10);
	//static int direct=1;
	public void paint(Graphics g)
	{
		super.paint(g);
		g.fillRect(0, 0, 400, 300);
		//this.paint_tank(hero.getX(),hero.getY(),0,1,g);
		//画出我的tank
		this.paint_tank(hero.x,hero.y,hero.direct,1,g);
		//画敌人的坦克
		this.paint_tank(army.x,army.y,army.direct,0,g);

	
	}
	void paint_tank(int x,int y,int direct,int type,Graphics g)
	{
		//判断敌我坦克
		switch(type)
		{ 
		case 0:{
			g.setColor(Color.CYAN);
			break;
		}
		case 1:{
			g.setColor(Color.yellow);
			break;
		}
		}
		//判断方向
		switch(direct){
		case 0:{
			g.fill3DRect(x, y, 5, 30,false);
			g.drawOval(x+5, y+10,10, 10);
			g.fill3DRect(x+5, y+5, 10, 20,false);
			g.fill3DRect(x+15, y, 5, 30,false);
			g.drawLine(x+9, y+15, x+9, y+30);
			break;
		}
		case 1:{
			g.fill3DRect(x, y, 5, 30,false);
			g.drawOval(x+5, y+10,10, 10);
			g.fill3DRect(x+5, y+5, 10, 20,false);
			g.fill3DRect(x+15, y, 5, 30,false);
			g.drawLine(x+9, y, x+9, y+15);
			break;
		}
		case 2:{
			g.fill3DRect(x, y, 30, 5,false);
			g.drawOval(x+5, y+5,10, 10);
			g.fill3DRect(x+5, y+5, 20, 10,false);
			g.fill3DRect(x, y+15, 30, 5,false);
			g.drawLine(x+15, y+9, x+30, y+9);
			break;
		}
		case 3:{
			g.fill3DRect(x, y, 30, 5,false);
			g.drawOval(x+5, y+5,10, 10);
			g.fill3DRect(x+5, y+5, 20, 10,false);
			g.fill3DRect(x, y+15, 30, 5,false);
			g.drawLine(x, y+9, x+15, y+9);
			break;
		}
		}
		//画我的子弹
		if(hero.s!=null&&hero.s.islive==true)
		{
			g.setColor(Color.gray);
			//System.out.print(hero.s.x);
			
			g.drawOval(hero.s.x, hero.s.y, 2, 2);
		}
		this.repaint();
	

	
	}
	public void keyTyped(KeyEvent e) {
		// TODO Auto-generated method stub
		
	}
	
	public void keyPressed(KeyEvent e) {
		// TODO Auto-generated method stub
		
			if(e.getKeyCode()==KeyEvent.VK_DOWN)
			{		
				hero.setdirect(0); 
				hero.moveup();
			}
			if(e.getKeyCode()==KeyEvent.VK_UP)
			{	
				hero.setdirect(1); 
				hero.movedown();
			}
			if(e.getKeyCode()==KeyEvent.VK_RIGHT)
			{
				hero.setdirect(2);
				hero.moveright();
			}
			if(e.getKeyCode()==KeyEvent.VK_LEFT)
			{
				hero.setdirect(3); 
				hero.moveleft();
			}
		if(e.getKeyCode()==KeyEvent.VK_J)
		{
			this.hero.ShotTarget();
			
		}
		
		//重绘
		this.repaint();
	}
	
	public void keyReleased(KeyEvent e) {
		// TODO Auto-generated method stub
		
	}
	@Override
	public void run() {
		// TODO Auto-generated method stub
		try {
			Thread.sleep(100);
		} catch (InterruptedException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		this.repaint();
	}
	
}
class Tank {
	int x;//坦克横坐标 
	int y;
	int direct;
	Tank(int direct){
		this.direct=direct;
	}
	public void setdirect(int direct){
		this.direct =direct;
	}
	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 Tank(int x,int y)
	{
		this.x=x;
		this.y=y;
	}
	void moveup(){	
		if(y<300)
			y++;
	}
	void movedown(){	
		if(y>0)	
		y--;
	}
	void moveright(){	
		if(x<400)
		x++;
	}
	void moveleft(){	
		if(x>0)
		x--;
	}
		
	
}
class Army extends Tank{
	public Army(int x,int y){
		super(x,y);
	}
}
class Hero extends Tank{
	shot s=null;
	//int direct;

	public Hero(int x,int y)
	{
		super(x,y);	
		//System.out.println(x);
	}
	
	//开火
	public void ShotTarget(){
		//System.out.println(x);
		//System.out.println(y);
		Thread S=new Thread();
		switch(this.direct)
		{
		case 0:{
			s=new shot(x+8,y+30,direct);break;
		}
		case 1:{
			s=new shot(x+8,y,direct);break;
		}
		case 2:{
			s=new shot(x+30,y+8,direct);break;
		}
		case 3:{
			s=new shot(x,y+8,direct);break;
		}
		}
		Thread S1=new Thread(s);
		S1.start();

	}
	
}
//子弹
class shot implements Runnable{
	int x,y;
	int direct;
	int speed=4;
	boolean islive=true;
	public shot(int x,int y,int direct){
		this.x=x;
		this.y=y;
		this.direct=direct;
	}
	@Override
	public void run() {
		// TODO Auto-generated method stub
		while(true)
		{
			try {
				Thread.sleep(50);
			} catch (InterruptedException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			}
			switch(direct)
			{
				case 0:y+=speed;break;
				case 1:y-=speed;break;
				case 2:x+=speed;break;
				case 3:x-=speed;break;
			}
			//判断子弹何时死亡
			
			//判断子弹是否碰到敌人坦克
			if(x<0||x>400||y<0||y>300)
			{
				this.islive=false;
				break;
			}
		}
	}
}
  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值