java基础 小游戏 飞机大战(上)

    科技2025-08-13  7

    文章目录

    1 建立游戏主窗口2 图形,文本绘制3 图片对象的加载4 多线程和内部类实现动画效果5 GameObject类设计6 面向对象思想重构飞机类设计

    1 建立游戏主窗口

    建立窗口代码:

    /** * @author coisini1999 * @飞机游戏的主窗口 */ package cn.coisini.game; import javax.swing.JFrame; //导入JFrame包 public class MyGameFrame extends JFrame { public void launchFrame() { this.setTitle("coisini"); //设置窗口名字 this.setVisible(true); //窗口可视化 this.setSize(500, 500); //设置窗口大小 this.setLocation(400,200); //设置窗口显示位置 } public static void main(String[] args) { //主方法创建窗口入口 MyGameFrame f = new MyGameFrame(); //由MyGameFrame类新建对象 f.launchFrame(); //调用lanuchFrame()方法 } }

    2 图形,文本绘制

    paint 方法:如果要在窗口中画或者显示什么内容,需要重写paint(Graphics g)方法,这个方法的作用是:画出整个窗口及其内部内容,它会被系统自动调用,不需要自己去调用这个方法

    /** * @author coisini1999 * @飞机游戏的主窗口 */ package cn.coisini.game; import java.awt.Color; import java.awt.Font; import java.awt.Graphics; import javax.swing.JFrame; //导入JFrame包 public class MyGameFrame extends JFrame { public void paint(Graphics g) { //自动被调用,g 相当于一支笔 Color c = g.getColor(); //保存默认的颜色 Font f = g.getFont(); //保存默认的字体 g.setColor(Color.BLUE); //更改颜色 g.drawLine(100, 100, 300, 300); //画线 g.drawRect(100, 100, 300, 300); //画矩形 g.drawOval(100, 100, 300, 300); //画圆 g.fillRect(100, 100, 40, 40); //填充矩形 g.setColor(Color.RED); g.setFont(new Font("宋体",Font.BOLD,50)); //更改字体 g.drawString("coisini", 200, 200); //画字符串 g.setColor(c); //恢复默认颜色 g.setFont(f); //恢复默认字体 } public void launchFrame() { this.setTitle("coisini"); //设置窗口名字 this.setSize(500, 500); //设置窗口大小 this.setLocation(300,300); //设置窗口显示位置 this.setVisible(true); //窗口可视化 } public static void main(String[] args) { //主方法创建窗口入口 MyGameFrame f = new MyGameFrame(); //由MyGameFrame类新建对象 f.launchFrame(); //调用lanuchFrame()方法 } }

    3 图片对象的加载

    使用ImageIO类实现图片加载,为了实现代码复用,将图片加载的方法封装到GameUtil的工具类中,便于以后调用

    GameUtile类的代码:

    package cn.coisini.game; import java.awt.Image; import java.awt.image.BufferedImage; import java.io.IOException; import java.net.URL; import javax.imageio.ImageIO; public class GameUtil { //工具类最好将构造器私有化 private GameUtil() { } /** * 返回指定路径文件的图片对象 * @param path * @return */ public static Image getImage(String path) { BufferedImage bi = null; try { URL u = GameUtil.class.getClassLoader().getResource(path); bi = ImageIO.read(u); } catch(IOException e) { e.printStackTrace(); } return bi; } }

    先将项目用到的图片拷贝到项目的src下,可以建立新的包images来保存所有的图片

    加载图形对象:

    /** * @author coisini1999 * @飞机游戏的主窗口 */ package cn.coisini.game; import java.awt.Color; import java.awt.Font; import java.awt.Graphics; import java.awt.Image; import javax.swing.JFrame; //导入JFrame包 public class MyGameFrame extends JFrame { Image ball = GameUtil.getImage("images/ball.png"); //加载图片对象,指定路径 public void paint(Graphics g) { //自动被调用,g 相当于一支笔 Color c = g.getColor(); //保存默认的颜色 Font f = g.getFont(); //保存默认的字体 g.setColor(Color.BLUE); //更改颜色 g.drawLine(100, 100, 300, 300); //画线 g.drawRect(100, 100, 300, 300); //画矩形 g.drawOval(100, 100, 300, 300); //画圆 g.fillRect(100, 100, 40, 40); //填充矩形 g.setColor(Color.RED); g.setFont(new Font("宋体",Font.BOLD,50)); //更改字体 g.drawString("coisini", 200, 200); //画字符串 g.drawImage(ball, 250, 250, null); //画出图片 g.setColor(c); //恢复默认颜色 g.setFont(f); //恢复默认字体 } public void launchFrame() { this.setTitle("coisini"); //设置窗口名字 this.setSize(500, 500); //设置窗口大小 this.setLocation(300,300); //设置窗口显示位置 this.setVisible(true); //窗口可视化 } public static void main(String[] args) { //主方法创建窗口入口 MyGameFrame f = new MyGameFrame(); //由MyGameFrame类新建对象 f.launchFrame(); //调用lanuchFrame()方法 } }

    4 多线程和内部类实现动画效果

    为了实现动态的效果,使用多线程实现动态效果,在MyGameFrame类中定义 重画窗口线程PaintThread类,为了方便使用MyGameFrame类的属性和方法,将PaintThread类定义为内部类

    /** * @author coisini1999 * @飞机游戏的主窗口 */ package cn.coisini.game; import java.awt.Color; import java.awt.Font; import java.awt.Graphics; import java.awt.Image; import java.awt.event.WindowAdapter; import java.awt.event.WindowEvent; import java.awt.event.WindowListener; import javax.swing.JFrame; //导入JFrame包 public class MyGameFrame extends JFrame { Image bg = GameUtil.getImage("images/bg.jpg"); //加载图片对象,指定路径 Image plane = GameUtil.getImage("images/plane.png"); //加载图片对象,指定路径 int planeX = 250, planeY = 250; public void paint(Graphics g) { //自动被调用,g 相当于一支笔 g.drawImage(bg, 0, 0, null); g.drawImage(plane, planeX , planeY, null); x++; } //帮助我们反复重画的方法 class PaintThread extends Thread { //内部类,使用此类的所有属性和方法 Thread是线程 @Override public void run() { while(true) { System.out.println("窗口重画了一次"); repaint(); //重画 try { Thread.sleep(40); //40ms } catch (InterruptedException e) { e.printStackTrace(); } } } } public void launchFrame() { this.setTitle("coisini"); //设置窗口名字 this.setSize(500, 500); //设置窗口大小 this.setLocation(300,300); //设置窗口显示位置 this.setVisible(true); //窗口可视化 //实际关闭窗口 this.addWindowListener(new WindowAdapter() { public void windowClosing(WindowEvent e) { System.exit(0); } }); new PaintThread().start(); //启动重画窗口的线程 } public static void main(String[] args) { //主方法创建窗口入口 MyGameFrame f = new MyGameFrame(); //由MyGameFrame类新建对象 f.launchFrame(); //调用lanuchFrame()方法 } }

    通过定义变量planeX和planeY可以在每次重画时,x++来改变飞机的位置

    5 GameObject类设计

    对于窗口中的所有对象(飞机,炮弹等等)都有很多共性,图片对象,坐标位置,运行速度,宽度和高度,为了方便使用,需要设计一个GameObject类,它可以作为所有游戏物体的父类,方便我们使用

    GameObject类:

    package cn.coisini.game; import java.awt.Graphics; import java.awt.Image; /** * 游戏物体的父类 * @author coisini1999 * */ public class GameObject { //游戏物体的属性 Image img; double x,y; int speed; int width,height; //画出自己的方法 public void drawSelf(Graphics g) { g.drawImage(img, (int)x, (int)y, null); } //构造器1 public GameObject(Image img, double x, double y, int speed, int width, int height) { super(); this.img = img; this.x = x; this.y = y; this.speed = speed; this.width = width; this.height = height; } //构造器2 public GameObject(Image img, double x, double y) { super(); this.img = img; this.x = x; this.y = y; } //无参构造 public GameObject() { } }

    6 面向对象思想重构飞机类设计

    通过GameObject类,可以再构建新的Plane类:

    package cn.coisini.game; import java.awt.Graphics; import java.awt.Image; public class Plane extends GameObject { public void drawSelf(Graphics g) { g.drawImage(img, (int)x, (int)y, null); x++; } public Plane(Image img, double x, double y) { this.img = img; this.x = x; this.y = y; } }

    这样Plane类就继承了GameObject类的所有属性和方法,在MyGameFrame类中就可以直接new若干个plane直接使用

    /** * @author coisini1999 * @飞机游戏的主窗口 */ package cn.coisini.game; import java.awt.Color; import java.awt.Font; import java.awt.Graphics; import java.awt.Image; import java.awt.event.WindowAdapter; import java.awt.event.WindowEvent; import java.awt.event.WindowListener; import javax.swing.JFrame; //导入JFrame包 public class MyGameFrame extends JFrame { Image bg = GameUtil.getImage("images/bg.jpg"); //加载图片对象,指定路径 Image planeImg = GameUtil.getImage("images/plane.png"); //加载图片对象,指定路径 Plane plane = new Plane(planeImg, 250 ,250); //创建飞机对象 Plane plane2 = new Plane(planeImg, 350 ,250); //创建飞机对象 Plane plane3 = new Plane(planeImg, 450 ,250); //创建飞机对象 public void paint(Graphics g) { //自动被调用,g 相当于一支笔 g.drawImage(bg, 0, 0, null); plane.drawSelf(g); //画飞机 plane2.drawSelf(g); //画飞机 plane3.drawSelf(g); //画飞机 } //帮助我们反复重画方法 class PaintThread extends Thread { //内部类,使用此类的所有属性和方法 Thread是线程 @Override public void run() { while(true) { System.out.println("窗口重画了一次"); repaint(); //重画 try { Thread.sleep(40); //40ms } catch (InterruptedException e) { e.printStackTrace(); } } } } public void launchFrame() { this.setTitle("coisini"); //设置窗口名字 this.setSize(500, 500); //设置窗口大小 this.setLocation(300,300); //设置窗口显示位置 this.setVisible(true); //窗口可视化 //实际关闭窗口 this.addWindowListener(new WindowAdapter() { public void windowClosing(WindowEvent e) { System.exit(0); } }); new PaintThread().start(); //启动重画窗口的线程 } public static void main(String[] args) { //主方法创建窗口入口 MyGameFrame f = new MyGameFrame(); //由MyGameFrame类新建对象 f.launchFrame(); //调用lanuchFrame()方法 } }

    Processed: 0.015, SQL: 8