一、 坦克大战游戏演示
1 游戏演示

2.为什么写这个项目

3.写项目前的提醒

二、java 绘图坐标体系
1 坐标体系-介绍
2 坐标体系-像素

3 介绍-快速入门

package com.hspedu.draw;import javax.swing.*;
import java.awt.*;/*** @author 林然* @version 1.0* 演示如何在面板画圆*/
@SuppressWarnings("all")
public class DrawCircle extends JFrame{//JFrame 对应窗口,可以理解成是一个画框//定义一个面板private MyPanel mp=null;public static void main(String[] args) {new DrawCircle();}public DrawCircle(){//构造器//初始化面板mp=new MyPanel();//把面板加入到窗口(画框)this.add(mp);//设置窗口的大小this.setSize(400,300);//当点击窗口的小×,程序完全退出.this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);this.setVisible(true);//可以显示}
}
//1、先定义一个面板 MyPanel,继承JPanel类,画图形,就在面板上
class MyPanel extends JPanel{//1. MyPanel 对象就是一个画板//2. Graphics g 把 g 理解成一支画笔//3. Graphics 提供了很多绘图的方法//Graphics g@Overridepublic void paint(Graphics g) {//绘图方法super.paint(g);//调用父类的方法完成初始化//画出一个圆形.System.out.println("paint 方法被调用了~");g.drawOval(20,20,100,100);}
}
4 绘图原理

5 Graphics 类

package com.hspedu.draw;import javax.swing.*;
import java.awt.*;/*** @author 林然* @version 1.0* 演示如何在面板画圆*/
@SuppressWarnings("all")
public class DrawCircle extends JFrame{//JFrame 对应窗口,可以理解成是一个画框//定义一个面板private MyPanel mp=null;public static void main(String[] args) {new DrawCircle();}public DrawCircle(){//构造器//初始化面板mp=new MyPanel();//把面板加入到窗口(画框)this.add(mp);//设置窗口的大小this.setSize(400,300);//当点击窗口的小×,程序完全退出.this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);this.setVisible(true);//可以显示}
}
//1、先定义一个面板 MyPanel,继承JPanel类,画图形,就在面板上
class MyPanel extends JPanel{//1. MyPanel 对象就是一个画板//2. Graphics g 把 g 理解成一支画笔//3. Graphics 提供了很多绘图的方法//Graphics g@Overridepublic void paint(Graphics g) {//绘图方法super.paint(g);//调用父类的方法完成初始化//画出一个圆形.System.out.println("paint 方法被调用了~");//g.drawOval(20,20,100,100);//演示绘制不同的图形..//画直线 drawLine(int x1,int y1,int x2,int y2)//g.drawLine(10, 10, 10, 100);//画矩形边框 drawRect(int x, int y, int width, int height)//g.drawRect(10, 10, 100, 200);//画椭圆边框 drawOval(int x, int y, int width, int height)//填充矩形 fillRect(int x, int y, int width, int height)//设置画笔的颜色//g.setColor(Color.blue);//g.fillRect(10, 10, 10, 10);//填充椭圆 fillOval(int x, int y, int width, int height)
// g.setColor(Color.red);
// g.fillOval(10, 10, 100, 100);//画图片 drawImage(Image img, int x, int y, ..)//1. 获取图片资源, /bg.png 表示在该项目的根目录去获取 bg.png 图片资源Image image = Toolkit.getDefaultToolkit().getImage(MyPanel.class.getResource("/bg.png"));g.drawImage(image, 10, 10, 175, 221, this);//画字符串 drawString(String str, int x, int y)//写字//给画笔设置颜色和字体g.setColor(Color.red);g.setFont(new Font("隶书", Font.BOLD, 50));//这里设置的 100, 100, 是 "北京你好"左下角g.drawString("北京你好", 100, 100);//左下角//设置画笔的字体 setFont(Font font)//设置画笔的颜色 setColor(Color c)}
}
6 绘出坦克


package com.hspedu.tankgame;/*** @author 林然* @version 1.0* 初试坦克*/
public class Tank {private int x;//坦克横坐标private int y;//坦克纵坐标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;}
}
package com.hspedu.tankgame;/*** @author 林然* @version 1.0* 我的坦克*/
public class Hero extends Tank {public Hero(int x, int y) {super(x, y);}
}
package com.hspedu.tankgame;import javax.swing.*;
import java.awt.*;/*** @author 林然* @version 1.0* 坦克大战的绘图区域*/
public class MyPanel extends JPanel {//定义我的坦克Hero hero = null;public MyPanel(){hero = new Hero(100,100);//初始化自己的坦克}@Overridepublic void paint(Graphics g) {super.paint(g);g.fillRect(0,0,1000,750);//填充矩形。默认黑色//画出坦克-封装方法drawtank(hero.getX(),hero.getY(),g,0,1);//画出坦克-封装方法drawtank(hero.getX()+60,hero.getY(),g,0,0);}/*** @param x 坦克的左上方x坐标* @param y 坦克的左上方y坐标* @param g 画笔* @param direct 坦克方向(上下左右)* @param type 坦克类型*/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);break;}//根据坦克方向,来绘制坦克switch (direct){case 0://向上g.fill3DRect(x,y,10,60,false);//画出坦克左边的轮子g.fill3DRect(x+30,y,10,60,false);//画出坦克右边的轮子g.fill3DRect(x+10,y+10,20,40,false);//画出坦克盖子g.fillOval(x+10,y+20,20,20);//画出圆形盖子g.drawLine(x+20,y+30,x+20,y);break;default://其他方向暂时不处理System.out.println("其他方向暂时不处理");}}
}
package com.hspedu.tankgame;import javax.swing.*;/*** @author 林然* @version 1.0*/
public class HspTankGame01 extends JFrame {//定义一个PanelMyPanel mp=null;public static void main(String[] args) {HspTankGame01 hspTankGame01 =new HspTankGame01();}public HspTankGame01(){mp=new MyPanel();this.add(mp);//把面板就是游戏绘图区域this.setSize(1000,750);this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);this.setVisible(true);}
}
三、java 事件处理机制
1 事件处理机制-看个问题

package com.hspedu.event_;import javax.swing.*;
import java.awt.*;
import java.awt.event.KeyEvent;
import java.awt.event.KeyListener;/*** @author 林然* @version 1.0* 演示小球通过键盘控制上下左右的移动-> 讲解 Java 的事件控制*/
public class BallMove extends JFrame {MyPanel mp=null;public static void main(String[] args) {BallMove ballMove =new BallMove();}public BallMove(){mp=new MyPanel();this.add(mp);this.setSize(400,300);//窗口 JFrame 对象可以监听键盘事件, 即可以监听到面板发生的键盘事件this.addKeyListener(mp);this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);this.setVisible(true);}
}
//面板 可以画小球
class MyPanel extends JPanel implements KeyListener{//为了让小球可以移动, 把他的左上角的坐标(x,y)设置变量int x = 10;int y = 10;@Overridepublic void paint(Graphics g) {super.paint(g);g.fillOval(x,y,20,20);//默认黑色}//有字符输出时,该方法就会触发@Overridepublic void keyTyped(KeyEvent e) {}//当某个键按下,就会触发@Overridepublic void keyPressed(KeyEvent e) {//System.out.println((char)e.getKeyCode()+"被按下");//根据用户按下的不同键,来处理小球的移动 (上下左右的键)//在 java 中,会给每一个键,分配一个值(int)int step=5;if(e.getKeyCode()==KeyEvent.VK_DOWN){y+=step;}else if(e.getKeyCode() == KeyEvent.VK_UP) {y-=step;} else if(e.getKeyCode() == KeyEvent.VK_LEFT) {x-=step;} else if(e.getKeyCode() == KeyEvent.VK_RIGHT) {x+=step;}//让面板重绘this.repaint();}//当某个键释放,就会触发@Overridepublic void keyReleased(KeyEvent e) {}
}
2 基本说明

3 请大家看一个示意图

4 机制分析

5 事件处理机制深入理解


四、坦克大战游戏
1 让你的坦克动起来


package com.hspedu.tankgame2;/*** @author 林然* @version 1.0* 初试坦克*/
public class Tank {private int x;//坦克横坐标private int y;//坦克纵坐标private int direction;//坦克方向0 1 2 3[上右下左]private int speed = 1;//坦克速度public int getSpeed() {return speed;}public void setSpeed(int speed) {this.speed = speed;}public int getDirection() {return direction;}public void setDirection(int direction) {this.direction = direction;}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;}public void moveUp(){y=y-speed;}public void moveRight(){x=x+speed;}public void moveDown(){y=y+speed;}public void moveLeft(){x=x-speed;}}
package com.hspedu.tankgame2;/*** @author 林然* @version 1.0* 我的坦克*/
public class Hero extends Tank {public Hero(int x, int y) {super(x, y);}
}
package com.hspedu.tankgame2;import javax.swing.*;
import java.awt.*;
import java.awt.event.KeyEvent;
import java.awt.event.KeyListener;/*** @author 林然* @version 1.0* 坦克大战的绘图区域*/
//为了监听 键盘事件, 实现KeyListener
public class MyPanel extends JPanel implements KeyListener {//定义我的坦克Hero hero = null;public MyPanel(){hero = new Hero(100,100);//初始化自己的坦克hero.setSpeed(5);}@Overridepublic void paint(Graphics g) {super.paint(g);g.fillRect(0,0,1000,750);//填充矩形。默认黑色//画出坦克-封装方法drawtank(hero.getX(),hero.getY(),g,hero.getDirection(),1);}/*** @param x 坦克的左上方x坐标* @param y 坦克的左上方y坐标* @param g 画笔* @param direct 坦克方向(上下左右)* @param type 坦克类型*/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);break;}//根据坦克方向,来绘制坦克//根据坦克方向,来绘制对应形状坦克//direct 表示方向(0: 向上 1 向右 2 向下 3 向左 )//switch (direct){case 0://向上g.fill3DRect(x,y,10,60,false);//画出坦克左边的轮子g.fill3DRect(x+30,y,10,60,false);//画出坦克右边的轮子g.fill3DRect(x+10,y+10,20,40,false);//画出坦克盖子g.fillOval(x+10,y+20,20,20);//画出圆形盖子g.drawLine(x+20,y+30,x+20,y);break;case 1://向右g.fill3DRect(x,y,60,10,false);//画出坦克左边的轮子g.fill3DRect(x,y+30,60,10,false);//画出坦克右边的轮子g.fill3DRect(x+10,y+10,40,20,false);//画出坦克盖子g.fillOval(x+20,y+10,20,20);//画出圆形盖子g.drawLine(x+30,y+20,x+60,y+20);break;case 2://向下g.fill3DRect(x,y,10,60,false);//画出坦克左边的轮子g.fill3DRect(x+30,y,10,60,false);//画出坦克右边的轮子g.fill3DRect(x+10,y+10,20,40,false);//画出坦克盖子g.fillOval(x+10,y+20,20,20);//画出圆形盖子g.drawLine(x+20,y+30,x+20,y+60);break;case 3://向右g.fill3DRect(x,y,60,10,false);//画出坦克左边的轮子g.fill3DRect(x,y+30,60,10,false);//画出坦克右边的轮子g.fill3DRect(x+10,y+10,40,20,false);//画出坦克盖子g.fillOval(x+20,y+10,20,20);//画出圆形盖子g.drawLine(x+30,y+20,x,y+20);break;default://其他方向暂时不处理System.out.println("其他方向暂时不处理");}}@Overridepublic void keyTyped(KeyEvent e) {}//处理 上右下左键按下的情况@Overridepublic void keyPressed(KeyEvent e) {if(e.getKeyCode()==KeyEvent.VK_UP){hero.setDirection(0);hero.moveUp();}else if(e.getKeyCode()==KeyEvent.VK_RIGHT){hero.setDirection(1);hero.moveRight();}else if(e.getKeyCode()==KeyEvent.VK_DOWN){hero.setDirection(2);hero.moveDown();}else if(e.getKeyCode()==KeyEvent.VK_LEFT){hero.setDirection(3);hero.moveLeft();}this.repaint();}@Overridepublic void keyReleased(KeyEvent e) {}
}
package com.hspedu.tankgame2;import javax.swing.*;/*** @author 林然* @version 1.0*/
public class HspTankGame02 extends JFrame {//定义一个PanelMyPanel mp=null;public static void main(String[] args) {HspTankGame02 hspTankGame01 =new HspTankGame02();}public HspTankGame02(){mp=new MyPanel();this.add(mp);//把面板就是游戏绘图区域this.setSize(1000,750);this.addKeyListener(mp);//监听键盘事件this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);this.setVisible(true);}
}
五、作业

package com.hspedu.tankgame2;/*** @author 林然* @version 1.0*/
public class EnemyTank extends Tank {public EnemyTank(int x,int y) {super(x,y);}
}
package com.hspedu.tankgame2;import javax.swing.*;
import java.awt.*;
import java.awt.event.KeyEvent;
import java.awt.event.KeyListener;
import java.util.Vector;/*** @author 林然* @version 1.0* 坦克大战的绘图区域*/
//为了监听 键盘事件, 实现KeyListener
public class MyPanel extends JPanel implements KeyListener {int enemyTankSize =3;//定义我的坦克Hero hero = null;//定义敌人坦克Vector<EnemyTank> enemyTanks =new Vector<>();public MyPanel(){hero = new Hero(100,100);//初始化自己的坦克hero.setSpeed(5);//初始化敌人坦克for (int i=0;i<enemyTankSize;i++){enemyTanks.add(new EnemyTank(100*(i+1),0));}}@Overridepublic void paint(Graphics g) {super.paint(g);g.fillRect(0,0,1000,750);//填充矩形。默认黑色//画出坦克-封装方法drawtank(hero.getX(),hero.getY(),g,hero.getDirection(),1);for (int i=0;i<enemyTankSize;i++){EnemyTank enemyTank = enemyTanks.get(i);enemyTank.setDirection(2);drawtank(enemyTank.getX(),enemyTank.getY(),g,enemyTank.getDirection(),0);}}/*** @param x 坦克的左上方x坐标* @param y 坦克的左上方y坐标* @param g 画笔* @param direct 坦克方向(上下左右)* @param type 坦克类型*/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);break;}//根据坦克方向,来绘制坦克//根据坦克方向,来绘制对应形状坦克//direct 表示方向(0: 向上 1 向右 2 向下 3 向左 )//switch (direct){case 0://向上g.fill3DRect(x,y,10,60,false);//画出坦克左边的轮子g.fill3DRect(x+30,y,10,60,false);//画出坦克右边的轮子g.fill3DRect(x+10,y+10,20,40,false);//画出坦克盖子g.fillOval(x+10,y+20,20,20);//画出圆形盖子g.drawLine(x+20,y+30,x+20,y);break;case 1://向右g.fill3DRect(x,y,60,10,false);//画出坦克左边的轮子g.fill3DRect(x,y+30,60,10,false);//画出坦克右边的轮子g.fill3DRect(x+10,y+10,40,20,false);//画出坦克盖子g.fillOval(x+20,y+10,20,20);//画出圆形盖子g.drawLine(x+30,y+20,x+60,y+20);break;case 2://向下g.fill3DRect(x,y,10,60,false);//画出坦克左边的轮子g.fill3DRect(x+30,y,10,60,false);//画出坦克右边的轮子g.fill3DRect(x+10,y+10,20,40,false);//画出坦克盖子g.fillOval(x+10,y+20,20,20);//画出圆形盖子g.drawLine(x+20,y+30,x+20,y+60);break;case 3://向右g.fill3DRect(x,y,60,10,false);//画出坦克左边的轮子g.fill3DRect(x,y+30,60,10,false);//画出坦克右边的轮子g.fill3DRect(x+10,y+10,40,20,false);//画出坦克盖子g.fillOval(x+20,y+10,20,20);//画出圆形盖子g.drawLine(x+30,y+20,x,y+20);break;default://其他方向暂时不处理System.out.println("其他方向暂时不处理");}}@Overridepublic void keyTyped(KeyEvent e) {}//处理 上右下左键按下的情况@Overridepublic void keyPressed(KeyEvent e) {if(e.getKeyCode()==KeyEvent.VK_UP){hero.setDirection(0);hero.moveUp();}else if(e.getKeyCode()==KeyEvent.VK_RIGHT){hero.setDirection(1);hero.moveRight();}else if(e.getKeyCode()==KeyEvent.VK_DOWN){hero.setDirection(2);hero.moveDown();}else if(e.getKeyCode()==KeyEvent.VK_LEFT){hero.setDirection(3);hero.moveLeft();}this.repaint();}@Overridepublic void keyReleased(KeyEvent e) {}
}