1、初步学习 JavaSwing GUI 编写小游戏

AWT和Swing
Swing是对AWT的提高和扩展。在写GUI程序时,Swing和AWT都要作用。他们共存于 Java基础类(JFC)中。

AWT依赖于主平台绘制用户界面组件;
而Swing有自己的机制,在主平台提供的窗口中绘制和管理界面组件。
Swing和AWT之间的最明显的区别是界面组件的外观,AWT在不同平台上运行相同的程序,界面的外观和风格可能会有些差异。然而一个基于Swing的应用程序可能在任何平台上都会有相同的外观和风格。

Swing中的类是从AWT继承的,有些Swing类直接扩展AWT中对应的类。如JApplet JDialog JFrame JWindow

使用Swing设计图形界面,主要引入两个包
javax.swing包和java.awt.event包
组件和容器
组件是图形界面的基本元素,用户可以直接操作,如按钮。
容器是图形界面的复合元素。容器可以包含组件。

Java语言为每种组件都预定义类,程序通过它们或者它们的子类各种组件对象。如Swing中预定义的按钮类JButton是一种类,程序创建的JButton对象,或JButton子类的对象就是按钮。
Java也为每种容器预定义类,程序通过它们或它们的子类创建各种容器对象。例如,Swing中预定义的窗口类JFrame是一种容器类,程序创建的JFrame或JFrame子类的对象就是窗口。

为了统一管理组件和容器,为所有组件类定义超类,把组件的共有操作都定义在Component类中。同样,为所有容器类定义超类Container类,把容器的共有操作都定义在Container类中。例如,Container类中定义了add()方法,大多数容器都可以用add()方法向容器添加组件。

Component Container和Graphics类是AWT库中的关键类。为能层次地构造复杂的图形界面,容器被当做特殊的组件,可以把容器放入另一个容器中。这种层次地构造界面的方法,都以增量的方式构造复杂的用户界面。

事件驱动程序设计基础
1.事件/监视器/监视器注册
图形界面上的事件是指在某个组件上发生用户操作。例如,用户单机了界面上的某个按钮,就说在这个按钮上发生了事件,这个按钮对象就是事件的击发者。对事件作监视的对象成为监视器,监视器提供响应事件的处理方法。为了让监视器与事件对象关联起来,需要对事件对象作监视器注册,告诉系统事件对象的监视器。

以程序相应按钮事件为例,程序要创建按钮对象,把它添加到界面中,要为按钮监视器注册,程序要有响应按钮事件的方法。当”单机按钮”事件发生时,系统就调用已为这个按钮注册的事件处理方法,完成处理按钮事件的工作。

2.实现事件处理的途径
Java语言编写事件处理程序主要有两种方案,一个是程序重设handleEvent,采用这个方法的程序工作量稍大一些。另一个方法是程序实现一些系统设定的接口。java按事件类型提供多种接口,作为监视器对象的类穾实现相应的接口,即实现响应事件的方法。当事件发生时,系统内设的handleEvent方法就自动调用监视器的类实现的响应事件的方法。

java.awt.event包中用来检测并对事件做出反应的模型包括以下三个组成元素
1、源对象
2、监视器对象
3、事件对象

一个事件驱动程序要做的工作除了创建源对象和监视器对象之外,还必须安排监视器了解源对象,或者向源对象注册监视器。每个源对象有一个已经注册的监视器列表,提供一个方法能向该列表添加监视器对象。只有在源对象注册了监视器之后,系统才会将源对象上发生的时间通知监视器对象。

3.事件类型和监视器接口
在Java语言中,为了便于系统管理事件,也为了便于程序作监视器注册,系统将时间分类,称为事件类型。系统为每个事件类型提供一个接口。要作为监视器对象的类必须实现相应的接口,提供接口规定的响应时间的方法。

再以程序相应按钮事件为例,JButton类对象button可以是一个事件的击发者。当用户点击界面中与button对应的按钮时,button对象就会产生一个ActionEvent类型的时间。如果监视器对象时obj,对象obj的类是Obj,则类Obj必须实现addActionListener方法注册它的监视器obj。

程序运行时,当用户点击button对象对应的按钮时,系统就讲一个ActionEvent对象从事件传递到监视器。ActionEvent对象包含的信息包括事件发生在哪一个按钮,以及有关该事件的其他信息。

实际事件发生时,通常会产生一系列的时间,例如,用户点击按钮,会产生ChangeEvent事件提示光标到了按钮上,接着又是一个ChangeEvent事件表示鼠标被按下,然后是ActionEvent事件表示鼠标已松开,但光标依旧在按钮上,最后是ChangeEvent事件,表示光标已经离开按钮,但是应用程序通常只处理按下按钮的完整动作的单个ActionEvent事件。

每个事件类型都有一个相应的监视器接口,实现监视器接口的类必须实现所有定义在接口中的方法。

笔者第一次写,不太会写请见谅。接下来就是游戏的编写了。
1、项目工程,由于用SpringBoot整合了一些技术,又不想单独分开所有就写在了一起。主要文件在games目录下

2、编写GameFrame程序布局和启动都写在里面具体代码如下

    package com.java.games.role.game;import java.awt.Color;import java.awt.Font;import java.awt.Graphics;import java.awt.Image;import java.util.ArrayList;import javax.swing.JFrame;import com.java.games.role.BaseRole;import com.java.games.role.Boss;import com.java.games.role.Bullet;import com.java.games.role.Girl;import com.java.games.role.util.CreatEnemy;public class GameFrame extends JFrame implements Runnable {//@Fields serialVersionUID :  private static final long serialVersionUID = 1L;// 程序运行的标志private static boolean isRun = true;private Image memoryimage;private Graphics memorygraphics;Boss boss=new Boss();public static Girl girl=new Girl();Bullet bullet=new Bullet(girl.getX(),girl.getY());/**角色集合*/public static ArrayList<BaseRole> rolelist=new ArrayList<BaseRole>();/**玩家的得分*/public static int point;public GameFrame() {this.setSize(1000, 700);this.setVisible(true);this.setDefaultCloseOperation(3);this.setLocationRelativeTo(null);// 创建大小为1000*700的内存画布memoryimage = this.createImage(1000, 700);// 从内存画布中得到内存画笔,内存画笔绘制的内容就在内存画布上this.memorygraphics = this.memoryimage.getGraphics();new InitImage(this);rolelist.add(girl);Thread th = new Thread(this);th.start();this.addKeyListener(new PressKey());}public static void main(String[] args) {new GameFrame();}@Overridepublic void run() {while (isRun) {this.drawFrame(this.getGraphics());try {Thread.sleep(20);} catch (InterruptedException e) {e.printStackTrace();}}}// 绘制图片public void drawFrame(Graphics g) {GameMap.drawMyself(memorygraphics);CreatEnemy.creatEnemy();for(int i=0;i<rolelist.size();i++){rolelist.get(i).drawMyself(memorygraphics);}this.drawInfo();g.drawImage(memoryimage, 0, 0, this);}/**绘制游戏得分等信息*/public void drawInfo(){memorygraphics.setColor(Color.BLUE);memorygraphics.setFont(new Font("宋体",Font.BOLD,30));memorygraphics.drawString("得分:"+point, 50, 80);}}

2、编写工具处理类主要处理图片切图等信息

package com.java.games.role.util;import java.awt.Image;public class ChangeImg {private int speed;private int index;private int count;private Image[] img;public ChangeImg(int speed){this.speed=speed;
}
public Image change(Image[] img){count++;if(count>speed){count=0;index++;if(index>img.length-1){index=0;}}return img[index];
}
}
package com.java.games.role.util;import com.java.games.role.LightEnemy;
import com.java.games.role.RedEnemy;
import com.java.games.role.game.GameFrame;public class CreatEnemy {/** 产生红怪的计数器 */private static int redcount;/** 产生灯怪的计数器 */private static int lightcount;/** 产生红怪的方法 */public static void creatEnemy(){CreatRedEnemy();CreatLightEnemy();}public static void CreatRedEnemy() {redcount++;if (redcount > 80) {redcount=0;GameFrame.rolelist.add(new RedEnemy());}}/** 产生灯怪的方法 */public static void CreatLightEnemy() {lightcount++;if (lightcount > 80) {lightcount=0;GameFrame.rolelist.add(new LightEnemy());}}
}
package com.java.games.role.util;import java.awt.Image;
import java.awt.MediaTracker;
import java.awt.image.CropImageFilter;
import java.awt.image.FilteredImageSource;
import java.awt.image.ImageProducer;import javax.swing.ImageIcon;
import javax.swing.JFrame;
/*** 图像切割类* @Title: CutImage.java * @Package com.java.games.role.util * @Description: TODO(用一句话描述该文件做什么) * @author lys* @date 2019年6月13日 下午5:08:10 * Copyright (c) ©1994-2019 Scjydz.com All Rights Reserved.*/
public class CutImage {/***  切割多行图片* * @param filePath            原始图片路径* @param row                 图片切割行数* @param col                 图片切割列数* @param track               媒体追踪器* @param groupId              分组ID* @return Image[][]          切割完成后的图像数组*/public static  Image[][] cutManyImage(String filePath, int row, int col,MediaTracker track,int groupId) {Image[][] img = new Image[row][col];ImageIcon imIcon = new ImageIcon(filePath);// 创建图像数组对象Image imgTemp = imIcon.getImage();// 创建源图像int imageWidth = imgTemp.getWidth(null)/col;int imageHight = imgTemp.getHeight(null)/row;// 为源 图象获取ImageProducer源ImageProducer sourceProducer = imgTemp.getSource();for (int i = 0; i < row; i++) {for (int j = 0; j < col; j++) {// 创建图片分割图像对象,第一、二个参数为分割图像起始坐标。后两个参数为图像大小CropImageFilter cropImg = new CropImageFilter(j * imageWidth, i * imageHight,imageWidth, imageHight);/* 获得图像生成器 */ImageProducer imgProducer = new FilteredImageSource(sourceProducer, cropImg);/* 获图像对象 */img[i][j] = new JFrame().createImage(imgProducer);track.addImage(img[i][j], groupId);}}return img;}/*** 切割单行图片* @param filePath 文件路径* @param col 列数* @param track 媒体追踪器* @param groupId 分组ID* @return 切割完成后的图像数组*/public static  Image[] cutOneImage(String filePath,int col,MediaTracker track,int groupId) {Image[] img = new Image[col];ImageIcon imIcon = new ImageIcon(filePath);// 创建图像数组对象Image imgTemp = imIcon.getImage();// 创建源图像int imageWidth = imgTemp.getWidth(null)/col;int imageHight = imgTemp.getHeight(null);// 为源 图象获取ImageProducer源ImageProducer sourceProducer = imgTemp.getSource();for (int j = 0; j < col; j++) {// 创建图片分割图像对象,第一、二个参数为分割图像起始坐标。后两个参数为图像大小CropImageFilter cropImg = new CropImageFilter(j * imageWidth, 0,imageWidth, imageHight);/* 获得图像生成器 */ImageProducer imgProducer = new FilteredImageSource(sourceProducer, cropImg);/* 获图像对象 */img[j] = new JFrame().createImage(imgProducer);track.addImage(img[j], groupId);}return img;}/*** 得到单个图像* @param filePath 文件路径* @param track 媒体追踪器* @param groupId 分组ID* @return 图像对象*/public static  Image getSingleImage(String filePath,MediaTracker track,int groupId){Image img = new ImageIcon(filePath).getImage();track.addImage(img, groupId);return img;}
}

3、编写BaseRole写成抽象类,到时候人物和Boos等都可以继承此类

package com.java.games.role;import java.awt.Graphics;
import java.awt.Image;
import java.awt.Rectangle;import com.java.games.role.game.GameFrame;
/*** * @Title: BaseRole.java * @Package com.java.games.role * @Description: TODO(角色抽象类) * @author lys* @date 2019年6月13日 下午5:02:41 * Copyright (c) ©1994-2019 Scjydz.com All Rights Reserved.*/
public abstract class BaseRole {/** 角色的x坐标 */protected int x;/** 角色的y坐标 */protected int y;/** 角色的宽度 */protected int width;/** 角色的高度 */protected int height;/** 角色需要绘制的图片 */protected Image img;/** 角色的碰撞区域 */protected Rectangle rect;public int getX() {return x;}public int getY() {return y;}public BaseRole(int x, int y, int width, int height) {this.x = x;this.y = y;this.width = width;this.height = height;this.rect = new Rectangle(x,y,width,height);}/** 将碰撞区域和角色重合 */public void setRect() {rect.x = this.x;rect.y = this.y;rect.width = this.width;rect.height = this.height;}/** 角色的绘制方法 */public void drawMyself(Graphics memorygraphics) {memorygraphics.drawImage(img, x, y, width, height, null);this.move();this.setRect();this.removeMyself();}/** 角色移除方法 角色到达屏幕以外 自动移除 */public void removeMyself() {if (this.x < -200 || this.x > 1200 || this.y < -200 || this.y > 900) {GameFrame.rolelist.remove(this);}}/** 角色的移动方法 */protected abstract void move();
}

4、图片改变

package com.java.games.role;import java.awt.Image;import com.java.games.role.game.GameFrame;
import com.java.games.role.util.ChangeImg;public class Boom extends BaseRole{
public static Image[] boomimg;
private int count;
private ChangeImg a=new ChangeImg(3);public Boom(int x,int y) {super(x, y,100, 100);}@Overrideprotected void move() {this.img=a.change(boomimg);count++;if(count>30){GameFrame.rolelist.remove(this);}}}

5、设置Boos

package com.java.games.role;import java.awt.Image;import com.java.games.role.util.ChangeImg;public class Boss extends BaseRole{/** 获取boss图片组*/public static  Image[] bossimg;/**图片切换对象*/private ChangeImg a=new ChangeImg(3);public Boss(){super(300,300,150,150);}@Overrideprotected void move() {this.img=a.change(bossimg);}
}

6、编写子弹类,具体子弹图片大家按照喜好自己选择子弹图片

package com.java.games.role;import java.awt.Image;import com.java.games.role.game.GameFrame;public class Bullet extends BaseRole{public static Image bulletimg;
public Bullet(int x,int y){super(x,y,50,30);this.img=bulletimg;
}
@Override
protected void move() {this.x+=15;for(int i=0;i<GameFrame.rolelist.size();i++){BaseRole b=GameFrame.rolelist.get(i);if(this.rect.intersects(b.rect)&&b instanceof EnemyRole){EnemyRole a=(EnemyRole) b;a.Hit(100);GameFrame.rolelist.remove(this);}}}
}

7、编写敌人类,把它设置成抽象类所有敌人都可以继承

package com.java.games.role;import com.java.games.role.game.GameFrame;public abstract class EnemyRole extends BaseRole{
private int exp;
private int hp;public EnemyRole(int x, int y, int width, int height,int exp,int hp) {super(x, y, width, height);this.exp=exp;this.hp=hp;}
public void Hit(int a){this.hp-=a;if(this.hp<0){GameFrame.point+=this.exp;GameFrame.rolelist.remove(this);GameFrame.rolelist.add(new Boom(this.x,this.y));}
}
}

8、编写英雄类,就是角色吧

package com.java.games.role;import java.awt.Image;import com.java.games.role.game.PressKey;
import com.java.games.role.util.ChangeImg;public class Girl extends BaseRole {public static Image[] girlimage;/** 图片切换对象 */private ChangeImg a = new ChangeImg(3);public Girl() {super(100, 100, 70, 70);}@Overrideprotected void move() {if (PressKey.isUp == true) {y -= 20;}if (PressKey.isDown == true) {y += 20;}if (PressKey.isLeft == true) {x -= 20;}if (PressKey.isRight == true) {x += 20;}this.img = a.change(girlimage);}}

9、编写灯怪敌人

package com.java.games.role;import java.awt.Image;import com.java.games.role.util.ChangeImg;public class LightEnemy extends EnemyRole{
private ChangeImg a=new ChangeImg(3);public static Image[] lightenemy;
public LightEnemy() {super((int)(Math.random()*1001),700, 100, 100,100,200);}@Overrideprotected void move() {this.img=a.change(lightenemy);this.y-=5;}}

10、编写红怪敌人

package com.java.games.role;import java.awt.Image;import com.java.games.role.util.ChangeImg;public class RedEnemy extends EnemyRole{
public static Image[] redenemy;
private ChangeImg a=new ChangeImg(3);public RedEnemy() {super((int)(Math.random()*200+1000),(int)(Math.random()*400+100), 100,100,100,200);}public void move(){this.img=a.change(redenemy);this.x-=5;}
}

11、设置背景图片

package com.java.games.role.game;import java.awt.Graphics;
import java.awt.Image;import javax.swing.ImageIcon;public class GameMap {// 获取背景图片public static Image mapimage = new ImageIcon("image/map.jpg").getImage();// 背景图片x值public static int mapX;public static void drawMyself(Graphics memorygraphics) {if (mapX <= -17000) {mapX = -17000;}mapX -= 5;memorygraphics.drawImage(mapimage, mapX, 0, null);}}

12、图片初始化类,所有的图标、怪物、子弹、角色、都可以进行按照大家的图片修改。个人喜欢吧

package com.java.games.role.game;import java.awt.MediaTracker;
import javax.swing.JFrame;import com.java.games.role.Boom;
import com.java.games.role.Boss;
import com.java.games.role.Bullet;
import com.java.games.role.Girl;
import com.java.games.role.LightEnemy;
import com.java.games.role.RedEnemy;
import com.java.games.role.util.CutImage;public class InitImage {public InitImage(JFrame jf) {MediaTracker tracker = new MediaTracker(jf);tracker.addImage(GameMap.mapimage, 1);// 切割背景图片Boss.bossimg = CutImage.cutOneImage("image/boss/playSpear.png", 18, tracker, 1);// 切割女孩主角图片Girl.girlimage = CutImage.cutOneImage("image/girl/forward.png", 4, tracker, 1);//子弹图片初始化Bullet.bulletimg=CutImage.getSingleImage("image/jbullet/dart.png",  tracker, 1);//红怪图片初始化RedEnemy.redenemy=CutImage.cutOneImage("image/enemy/redEnemy.png", 3, tracker,1);//灯怪图片初始化LightEnemy.lightenemy=CutImage.cutOneImage("image/enemy/lightEnemy.png", 2, tracker, 1);//爆炸图片初始化Boom.boomimg=CutImage.cutOneImage("image/bomb/detonate.png", 5, tracker, 1);try {tracker.waitForID(1);} catch (InterruptedException e) {e.printStackTrace();}}
}

13、最后最主要的一步,我们给自己角色编写键盘事件,键盘按键可以自己修改。这边就用ASDW了吧!

package com.java.games.role.game;import java.awt.event.KeyEvent;
import java.awt.event.KeyListener;import com.java.games.role.Bullet;public class PressKey implements KeyListener {/** 玩家是否按下了上键 */public static boolean isUp;/** 玩家是否按下了下键 */public static boolean isDown;/** 玩家是否按下了左键 */public static boolean isLeft;/** 玩家是否按下了右键 */public static boolean isRight;// 键盘按下事件@Overridepublic void keyPressed(KeyEvent arg0) {int code = arg0.getKeyCode();if (code == KeyEvent.VK_W) {isUp = true;}if (code == KeyEvent.VK_S) {isDown = true;}if (code == KeyEvent.VK_A) {isLeft = true;}if (code == KeyEvent.VK_D) {isRight = true;}}// 键盘释放事件@Overridepublic void keyReleased(KeyEvent arg0) {int code = arg0.getKeyCode();if (code == KeyEvent.VK_W) {isUp = false;}if (code == KeyEvent.VK_S) {isDown = false;}if (code == KeyEvent.VK_A) {isLeft = false;}if (code == KeyEvent.VK_D) {isRight = false;}if (code == KeyEvent.VK_J) {GameFrame.rolelist.add(new Bullet(GameFrame.girl.getX(), GameFrame.girl.getY()));}}@Overridepublic void keyTyped(KeyEvent arg0) {// TODO Auto-generated method stub}}

这里是我自己的Image图片包:https://pan.baidu.com/s/1Nkx_oIhOC-XL9D4fgqDiFg
提取码:ycml
到这里就差不写完了
点击运行看看效果吧
找到我们写的GameFrame,运行main方法启动 如下:



项目地址:https://download.csdn.net/download/weixin_44598993/11239968

JavaSwing GUI 编写射击小游戏相关推荐

  1. gui实现2048小游戏

    gui实现2048小游戏 1.登录模块 public class LoginJFrame extends JFrame implements MouseListener{ //登录按钮 JButton ...

  2. 基于pygame的射击小游戏制作(一)让飞船动起来

    基于pygame的射击小游戏制作(一)让飞船动起来 一.文件结构 alien_invasion.py 是整个系统的主文件,用来创建游戏中的一系列对象,ai_settings存储设置.screen存储显 ...

  3. html游戏技术文档编写,HTML5编写的小游戏

    HTML5编写的小游戏 HTML5 是什么东西?而 HTML5 的优势又在哪里?大家可以回顾之前一篇相关文章了解下 HTML5 知识:<深入分析:Flash VS HTML5到底谁统江山> ...

  4. 用python编写乒乓球小游戏--Turtle功能的应用

    用python编写乒乓球小游戏–Turtle功能的应用 python有很多功能强大的代码库,Turtle是一款用于游戏开发的代码库.通过编写乒乓球小游戏可以了解这个库的基本的代码的使用 先创建游戏的背 ...

  5. Unity3D 2D射击小游戏瞄准线的实现

    Unity3D 2D射击小游戏瞄准线的实现 0. 前言 本片文章是对 https://www.bilibili.com/video/bv1sY411V7tx 视频中瞄准线是如何实现的一个讲解教程,欢迎 ...

  6. matlab GUI制作拼图小游戏

    matlab GUI制作拼图小游戏 最近帮同学的忙制作一个拼图贴上代码和效果图,以后再详细说明.之前一般找到的拼图游戏都是"推格子"形式的,由于具体的要求,不能应用这种模板. 本人 ...

  7. c语言编写数据存储的游戏,c语言经典小程序和c语言编写的小游戏带注释(自动保存的).doc...

    c语言经典小程序和c语言编写的小游戏带注释(自动保存的) 1.写一个定时?关机的小程?序,可以立即关?闭计算机,也可以一段?时间后关闭?计算机. #inclu?de #inclu?de #inclu? ...

  8. 基于html+JavaScript+css的飞机射击小游戏网页设计与实现

    资源下载地址:https://download.csdn.net/download/sheziqiong/86954471 资源下载地址:https://download.csdn.net/downl ...

  9. 用javascript编写的小游戏-打砖块

    用javascript编写的小游戏-打砖块 前言 启发 下载链接 游戏功能说明 代码效果演示 代码 后记 前言 这是我在CSDN发表的第一篇文章.是我在初学javascript后, 忽然来了兴致, 编 ...

最新文章

  1. 短序列拼接软件velvet简介
  2. 接上一篇Ansible和celery的结合,在celery的tasks.py文件里为了实现并发不阻塞的需求,用到了多进程
  3. 结合zuul网关的鉴权流程
  4. 远程办公第五天,你还在扩容吗?
  5. 如何在web api中使用SignalR
  6. 前端学习(3345):设计模式之工厂模式2
  7. CISC与RISC的区别?
  8. 算法可以申请专利么_Ta 在假笑么?这个识别算法可以鉴定
  9. ORACLE小错误和小技巧
  10. php 中 的含义
  11. 应用程序中主键ID生成与UUID
  12. 大数据爬虫的一些小目标
  13. 史上最通俗易懂的并查集算法详解
  14. OFDM-训练序列与导频
  15. 如何合并两个excel表格数据
  16. gpu cpu交互_CPU和GPU如何交互以渲染计算机图形?
  17. TMS320F28379D创建工程
  18. 什么是软件EV代码签名证书
  19. react-shopping-cart尺码筛选
  20. ORB匹配--基于OpenCV

热门文章

  1. Jumpserver入门介绍
  2. jumpserver 节点部署_Jumpserver安装部署
  3. 数据总结(刀哥情绪数据)
  4. 玩好大数据:1.数据清洗
  5. 深度学习笔记目录大全(吴恩达)--终于有翻译版本了
  6. 奔驰C260L(W206)升级柏林之声音响系统,体验不一样的感觉
  7. 兆欧表电压档位选择_过路老熊_新浪博客
  8. Java选择题(二十七)
  9. 论述常见轻量级数据库
  10. Android空格符对比