【Java_项目篇<1>】--JAVA实现坦克大战游戏--坦克移动+添加敌方坦克(二)

前期文章:

【Java_项目篇<1>】--JAVA实现坦克大战游戏--画出坦克(一)



控制小球移动



1.外部类 实现KeyListener监听接口写法

package com.test3;

import java.awt.Graphics;
import java.awt.event.KeyEvent;
import java.awt.event.KeyListener;

import javax.swing.JFrame;
import javax.swing.JPanel;

@SuppressWarnings("serial")
public class Demo9_4 extends JFrame{

	MyPanel p1 = new MyPanel();
	public Demo9_4(){
		
		add(p1);
		
		addKeyListener(p1);//写法
		
		setSize(400, 300);
		setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
		setLocationRelativeTo(null);
		setVisible(true);
		
	}
	public static void main(String[] args) {
		new Demo9_4();
	}
}

@SuppressWarnings("serial")
class MyPanel extends JPanel implements KeyListener{//必须实现keylistener中的所有方法
	
	int x = 5;
    int y = 5;


	protected void paintComponent(Graphics g){
		super.paintComponent(g);
		g.fillOval(this.x, this.y, 10, 10);
	}
	@Override
	public void keyTyped(KeyEvent e) {
	}
	@Override
	public void keyPressed(KeyEvent e) {
		if(e.getKeyCode()==KeyEvent.VK_DOWN){
			y+=5;
			repaint();
		}
	}
	@Override
	public void keyReleased(KeyEvent e) {
	}
}


2.匿名内部类写法

package com.test3;

import java.awt.Graphics;
import java.awt.event.KeyAdapter;
import java.awt.event.KeyEvent;

import javax.swing.JFrame;
import javax.swing.JPanel;

@SuppressWarnings("serial")
public class Demo9_4 extends JFrame{

	MyPanel p1 = new MyPanel();
	public Demo9_4(){
		
		add(p1);
		/**
		 * 匿名内部类    
		 * 不能是p1.addKeyListener(new keyListner)
		 * 如果是监听按钮就可以这样写
		 * p1是面板,所以不能这样写?   p1面板没有对应的出发时间类型? 不对啊 JPanel是Component的子类,可以触发事件类型啊?
		 */
		addKeyListener(new KeyAdapter() {

			public void keyPressed(KeyEvent e) {
				if(e.getKeyCode()==KeyEvent.VK_DOWN){
					p1.setY(p1.getY()+5);
					repaint();
				}
			}
		});
		
		setSize(400, 300);
		setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
		setLocationRelativeTo(null);
		setVisible(true);
		
	}
	public static void main(String[] args) {
		new Demo9_4();
	}
}

@SuppressWarnings("serial")
class MyPanel extends JPanel {
	
	int x = 5;
	int y = 5;
    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;
	}

	protected void paintComponent(Graphics g){
		super.paintComponent(g);
		g.fillOval(this.x, this.y, 10, 10);
	}

}





好,现在进入正式的程序编写

坦克2.0

1.画出坦克,颜色可控

2.实现坦克移动 并且速度可控




MyTankGame2.Java


[java]  view plain  copy
 print ? 在CODE上查看代码片 派生到我的代码片
  1. /** 
  2.  * 功能:坦克游戏的2.0 
  3.  * 1.画出坦克 
  4.  * 2.坦克的移动 
  5.  */  
  6.   
  7. package Tank_02;  
  8.   
  9. import java.awt.Color;  
  10. import java.awt.Graphics;  
  11.   
  12.   
  13. import java.awt.event.KeyEvent;  
  14. import java.awt.event.KeyListener;  
  15.   
  16. import javax.swing.JFrame;  
  17. import javax.swing.JPanel;  
  18.   
  19. @SuppressWarnings("serial")  
  20. public class MyTankGame2 extends JFrame{  
  21.       
  22.     MyPanel p1 = new MyPanel();  
  23.       
  24.     public MyTankGame2(){  
  25.         add(p1);  
  26.         setSize(400300);  
  27.         setVisible(true);  
  28.         setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);  
  29.           
  30.         addKeyListener(p1);//注册监听  
  31.           
  32.     }  
  33.       
  34.     public static void main(String[] args) {  
  35.          new MyTankGame2();  
  36.     }  
  37. }  
  38.   
  39. //画图  
  40. @SuppressWarnings("serial")  
  41. class MyPanel extends JPanel implements KeyListener{  
  42.       
  43.     Hero hero = null;  
  44.       
  45.     public MyPanel(){  
  46.         hero = new Hero(50,10);//设置坦克出现的位置(10,10)  
  47.     }  
  48.       
  49.     protected void paintComponent(Graphics g){  
  50.         super.paintComponent(g);  
  51.           
  52.         g.fillRect(00400300);//背景填充  
  53.           
  54.           
  55.         drawTank(hero.getX(),hero.getY(),g,0,1);//一定要传入画笔g  
  56.         g.setColor(Color.yellow);  
  57.           
  58.     }  
  59.       
  60.     /* 
  61.      * drawTank (坦克坐标x,y,画笔g,方向,坦克类型) 
  62.      * 方法介绍: 
  63.      *      可以设置-->坦克的颜色(类型:敌方坦克,我方坦克),方向,出现的坐标 
  64.      *  
  65.      * 如果type是default 则默认颜色为画出黑色坦克 
  66.      *  
  67.      * 封装性:将坦克封装到方法中。 
  68.      *  
  69.      */  
  70.       
  71.     public void drawTank(int x,int y,Graphics g,int direct,int type){  
  72.         switch (type) {  
  73.         case 0:  
  74.             g.setColor(Color.cyan);  
  75.             break;  
  76.         case 1:  
  77.             g.setColor(Color.yellow);  
  78.         default:  
  79.             break;  
  80.         }  
  81.         switch (direct) {  
  82.         case 0:  
  83.             //向上  
  84.             g.fill3DRect(x   , y    , 5 , 30false);  
  85.             g.fill3DRect(x+15, y    , 5 , 30false);  
  86.             g.fill3DRect(x+5 , y+5  , 1020false);  
  87.             g.fillOval(x+4, y+1010 , 10);  
  88.             g.drawLine(x+9, y+15, x+9, y );  
  89.             break;  
  90.   
  91.         default:  
  92.             break;  
  93.         }  
  94.     }  
  95.   
  96.     @Override  
  97.     public void keyTyped(KeyEvent e) {  
  98.     }  
  99.   
  100.     @Override  
  101.     public void keyPressed(KeyEvent e) {//实现接口 根据按键上下左右移动 可以控制速度和移动  
  102.         if(e.getKeyCode()==KeyEvent.VK_W){  
  103.             hero.setDirect(0);  
  104.             hero.moveUp();  
  105.         }else if(e.getKeyCode()==KeyEvent.VK_S){  
  106.             hero.setDirect(1);  
  107.             hero.moveDown();  
  108.         }else if(e.getKeyCode()==KeyEvent.VK_A){  
  109.             hero.setDirect(2);  
  110.             hero.moveLeft();  
  111.         }else if(e.getKeyCode()==KeyEvent.VK_D){  
  112.             hero.setDirect(3);  
  113.             hero.moveRight();  
  114.         }  
  115.         repaint();  
  116.     }  
  117.   
  118.     @Override  
  119.     public void keyReleased(KeyEvent e) {  
  120.     }  
  121. }  



members.java




[java]  view plain  copy
 print ? 在CODE上查看代码片 派生到我的代码片
  1. package Tank_02;  
  2.   
  3.   
  4.   
  5. //坦克父类  可以设置坦克出现位置(x,y)  
  6. class Tank {  
  7.     int x = 0;  
  8.     int y = 0;  
  9.     int speed = 10;//移动速度  
  10.     int Direct = 0;//移动方向  
  11.     public int getDirect() {  
  12.         return Direct;  
  13.     }  
  14.     public void setDirect(int direct) {  
  15.         Direct = direct;  
  16.     }  
  17.     public int getSpeed() {  
  18.         return speed;  
  19.     }  
  20.     public void setSpeed(int speed) {  
  21.         this.speed = speed;  
  22.     }  
  23.     public Tank (int x,int y){  
  24.         this.x = x;  
  25.         this.y = y;  
  26.     }  
  27.     public int getX() {  
  28.         return x;  
  29.     }  
  30.     public void setX(int x) {  
  31.         this.x = x;  
  32.     }  
  33.     public int getY() {  
  34.         return y;  
  35.     }  
  36.     public void setY(int y) {  
  37.         this.y = y;  
  38.     }  
  39.       
  40.       
  41.     //移动  
  42.     public void moveUp(){  
  43.         y-=speed;  
  44.     }  
  45.     public void moveDown(){  
  46.         y+=speed;  
  47.     }  
  48.     public void moveLeft(){  
  49.         x-=speed;  
  50.     }  
  51.     public void moveRight(){  
  52.         x+=speed;  
  53.     }  
  54. }  
  55. //我的英雄坦克  
  56. class Hero extends Tank{  
  57.       
  58.     public Hero(int x,int y){  
  59.         super(x, y);  
  60.     }  
  61. }  

实现效果




显然:坦克的方向并没有改变,他只是僵硬的移动

所以我们需要用画笔画出坦克不同方向的样子

更新 第96-130行   

67行的倒数第二个参数,需要改成灵活的方式 用鼠标可以控制方向

drawTank(hero.getX(),hero.getY(),g,hero.Direct,1);




另外 我们需要添加敌方坦克

//敌方坦克
class EnemyTank extends Tank{
	public EnemyTank(int x, int y) {
		super(x, y);
	}
}

显然:坦克的方向并没有改变,他只是僵硬的移动

所以我们需要用画笔画出坦克不同方向的样子

更新 第82-116行   

55行的倒数第二个参数,需要改成灵活的方式 用鼠标可以控制方向

drawTank(hero.getX(),hero.getY(),g,hero.Direct,1);

/**
 * 功能:坦克游戏的2.0
 * 1.画出坦克
 * 2.坦克的移动
 */

package Tank_02;

import java.awt.Color;
import java.awt.Graphics;


import java.awt.event.KeyEvent;
import java.awt.event.KeyListener;

import javax.swing.JFrame;
import javax.swing.JPanel;

@SuppressWarnings("serial")
public class MyTankGame2 extends JFrame{
	
	MyPanel p1 = new MyPanel();
	
	public MyTankGame2(){
		add(p1);
		setSize(400, 300);
		setVisible(true);
		setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
		
		addKeyListener(p1);//注册监听
		
	}
	
	public static void main(String[] args) {
		 new MyTankGame2();
	}
}

//画图
@SuppressWarnings("serial")
class MyPanel extends JPanel implements KeyListener{
	
	Hero hero = null;
	
	public MyPanel(){
		hero = new Hero(50,10);//设置坦克出现的位置(10,10)
	}
	
	protected void paintComponent(Graphics g){
		super.paintComponent(g);
		
		g.fillRect(0, 0, 400, 300);//背景填充
		
		
		drawTank(hero.getX(),hero.getY(),g,hero.Direct,1);//一定要传入画笔g
		g.setColor(Color.yellow);
		
	}
	
	/*
	 * drawTank (坦克坐标x,y,画笔g,方向,坦克类型)
	 * 方法介绍:
	 * 		可以设置-->坦克的颜色(类型:敌方坦克,我方坦克),方向,出现的坐标
	 * 
	 * 如果type是default 则默认颜色为画出黑色坦克
	 * 
	 * 封装性:将坦克封装到方法中。
	 * 
	 */
	
	public void drawTank(int x,int y,Graphics g,int direct,int type){
		switch (type) {
		case 0:
			g.setColor(Color.cyan);
			break;
		case 1:
			g.setColor(Color.yellow);
		default:
			break;
		}
		switch (direct) {
		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+4, y+10, 10 , 10);
			g.drawLine(x+9, y+15, x+9, y );
			break;
		case 1:
			//向下w
			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+4, y+10, 10 , 10);
			g.drawLine(x+9, y+15, x+9, y+30 );
			break;
		case 2:
			//向左
			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+9 , y+4, 10  , 10 );
			g.drawLine(x+5, y+9, x-4, y+9);
			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+9 , y+4, 10  , 10 );
			g.drawLine(x+15, y+9, x+30, y+9);
			break;
		default:
			break;
		}
		//repaint();  因为监听器里面有repaint()  所以不用在加repaint()了
	}

	@Override
	public void keyTyped(KeyEvent e) {
	}

	@Override
	public void keyPressed(KeyEvent e) {//实现接口 根据按键上下左右移动 可以控制速度和移动
		if(e.getKeyCode()==KeyEvent.VK_W){
			hero.setDirect(0);
			hero.moveUp();
		}else if(e.getKeyCode()==KeyEvent.VK_S){
			hero.setDirect(1);
			hero.moveDown();
		}else if(e.getKeyCode()==KeyEvent.VK_A){
			hero.setDirect(2);
			hero.moveLeft();
		}else if(e.getKeyCode()==KeyEvent.VK_D){
			hero.setDirect(3);
			hero.moveRight();
		}
		repaint();
	}

	@Override
	public void keyReleased(KeyEvent e) {
	}
}




画出敌方三辆坦克 我方一辆坦克

考虑用数组 还是集合?
如果击毁一辆坦克,那么怎么添加新的坦克? 所以数组不行,采用集合。
用ArrayList还是Vector?
ArrayList(多线程不安全)会出现各种奇怪的现象。
比如:发出的子弹变成破甲弹,击穿坦克子弹还在飞,并且击毁另一个坦克。
发出子弹自爆了。。
Vector(多线程安全)
所以采用Vector

最终的代码

MyTankGame2.java

/**
 * 功能:坦克游戏的2.0
 * 1.画出坦克
 * 2.坦克的移动
 */

package Tank_02;

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.JFrame;
import javax.swing.JPanel;

@SuppressWarnings("serial")
public class MyTankGame2 extends JFrame{
	
	MyPanel p1 = new MyPanel();
	
	public MyTankGame2(){
		add(p1);
		setSize(1200, 800);
		setVisible(true);
		setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
		
		addKeyListener(p1);//注册监听
		
	}
	
	public static void main(String[] args) {
		 new MyTankGame2();
	}
}

//画图
@SuppressWarnings("serial")
class MyPanel extends JPanel implements KeyListener{
	
	Hero hero = null;
	Vector<EnemyTank> ets = new Vector<EnemyTank>();
	int enSize = 20;
	
	public MyPanel(){
		hero = new Hero(50,10);//设置坦克出现的位置(10,10)
		// 初始化敌人的坦克
		for(int i=0;i<enSize;i++){
			//创建敌方坦克对象
			EnemyTank et =new EnemyTank((i+1)*30,0);
			et.setColor(1);
			et.setDirect(1);
			ets.add(et);
		}
	}
	
	protected void paintComponent(Graphics g){
		
		super.paintComponent(g);
		
		g.fillRect(0, 0, 1200, 800);//背景填充
		
		//画出我方坦克
		drawTank(hero.getX()+500,hero.getY()+500,g,hero.Direct,0);//一定要传入画笔g
		//画出敌方坦克
		for(int i=0;i<ets.size();i++){
			drawTank(ets.get(i).getX(), ets.get(i).getY(), g, ets.get(i).getDirect(), ets.get(i).getColor());
		}
	}
	
	/*
	 * drawTank (坦克坐标x,y,画笔g,方向,坦克类型(颜色))
	 * 方法介绍:
	 * 		可以设置-->坦克的颜色(类型:敌方坦克,我方坦克),方向,出现的坐标
	 * 
	 * 如果type是default 则默认颜色为画出黑色坦克
	 * 
	 * 封装性:将坦克封装到方法中。
	 * 
	 */
	
	public void drawTank(int x,int y,Graphics g,int direct,int type){
		switch (type) {
		case 0:
			g.setColor(Color.cyan);
			break;
		case 1:
			g.setColor(Color.yellow);
		default:
			break;
		}
		switch (direct) {
		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+4, y+10, 10 , 10);
			g.drawLine(x+9, y+15, x+9, y );
			break;
		case 1:
			//向下w
			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+4, y+10, 10 , 10);
			g.drawLine(x+9, y+15, x+9, y+30 );
			break;
		case 2:
			//向左
			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+9 , y+4, 10  , 10 );
			g.drawLine(x+5, y+9, x-4, y+9);
			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+9 , y+4, 10  , 10 );
			g.drawLine(x+15, y+9, x+30, y+9);
			break;
		default:
			break;
		}
		//repaint();  因为监听器里面有repaint()  所以不用在加repaint()了
	}

	@Override
	public void keyTyped(KeyEvent e) {
	}

	@Override
	public void keyPressed(KeyEvent e) {//实现接口 根据按键上下左右移动 可以控制速度和移动
		if(e.getKeyCode()==KeyEvent.VK_W){
			hero.setDirect(0);
			hero.moveUp();
		}else if(e.getKeyCode()==KeyEvent.VK_S){
			hero.setDirect(1);
			hero.moveDown();
		}else if(e.getKeyCode()==KeyEvent.VK_A){
			hero.setDirect(2);
			hero.moveLeft();
		}else if(e.getKeyCode()==KeyEvent.VK_D){
			hero.setDirect(3);
			hero.moveRight();
		}
		repaint();
	}

	@Override
	public void keyReleased(KeyEvent e) {
	}
}





members.java

package Tank_02;

//坦克父类  可以设置坦克出现位置(x,y)
class Tank {
	int x = 0;
	int y = 0;
	int speed = 10;
	int Direct = 0;
	int color;
	public int getColor() {
		return color;
	}
	public void setColor(int color) {
		this.color = color;
	}
	public int getDirect() {
		return Direct;
	}
	public void setDirect(int direct) {
		Direct = direct;
	}
	public int getSpeed() {
		return speed;
	}
	public void setSpeed(int speed) {
		this.speed = speed;
	}
	public Tank (int x,int y){
		this.x = x;
		this.y = y;
	}
	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;
	}
	
	
	//视频中是把移动放在hero类中
	public void moveUp(){
		y-=speed;
	}
	public void moveDown(){
		y+=speed;
	}
	public void moveLeft(){
		x-=speed;
	}
	public void moveRight(){
		x+=speed;
	}
}
//敌方坦克
class EnemyTank extends Tank{

	public EnemyTank(int x, int y) {
		super(x, y);
	}
}
//我的英雄坦克
class Hero extends Tank{
	
	public Hero(int x,int y){
		super(x, y);
	}
}




  • 9
    点赞
  • 55
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值