教你用JAVA写个小游戏[通俗易懂]

教你用JAVA写个小游戏[通俗易懂]上周上课的时候老师让用Java写个小程序,我本想写一个经典的飞机大战游戏来着,可以后来突发奇想就写成了这个一、整体思路继承窗体类,复写窗体刷新 添加按键监听 游戏结束界面 王思聪类和热狗类移动轨迹计算 判断碰撞音乐播放 不断刷新窗体处理细节二、编码1.图片首先你要找到图片,可以百度一张,然后用ps切开,再找一张背景图片就搞定了你还需要一个加载图片的…

大家好,又见面了,我是你们的朋友全栈君。

 上周上课的时候老师让用Java写个小程序,我本想写一个经典的飞机大战游戏来着,可以后来突发奇想就写成了这个

教你用JAVA写个小游戏[通俗易懂]

一、整体思路

  1. 继承窗体类,复写窗体刷新
  2. 添加按键监听
  3. 游戏结束界面
  4. 王思聪类和热狗类 移动轨迹计算
  5. 判断碰撞 音乐播放
  6. 不断刷新窗体 处理细节

二、编码

1.图片

首先你要找到图片,可以百度一张,然后用ps切开,再找一张背景图片就搞定了

教你用JAVA写个小游戏[通俗易懂]教你用JAVA写个小游戏[通俗易懂]

 你还需要一个加载图片的工具类,可以使用getResource得到图片的URL路径,然后使用java自带的工具类ImageIO来读取图片

public class GameUtil {

	public static Image getImage(String path){
		URL url=GameUtil.class.getClassLoader().getResource(path);
		BufferedImage img=null;
		try {
			img = ImageIO.read(url);
		} catch (IOException e) {
			e.printStackTrace();
		}	
		return img;
	}
}

2.窗体

写一个类来继承窗体,为其设置宽高,位置,关闭设置,可否缩放大小

复写它的更新和绘画方法,以后要在里面写绘画思聪和热狗和碰撞判断逻辑

为其添加按键监听事件,在这里处理按键的点击和释放,以此来实现思聪的移动

		
	public void launchFrame(){
		setSize(width,height);
		setResizable(false);
		setLocation(200,20);
		setVisible(true);
		addKeyListener(new KeyMoniter());
		addWindowListener(new WindowAdapter(){
			@Override
			public void windowClosing(WindowEvent e) {
				System.exit(0);
			}
		});
	}

        @Override
	public void paint(Graphics graphics) {}
	@Override
	public void update(Graphics g){}

	class KeyMoniter extends KeyAdapter{
		@Override
		public void keyPressed(KeyEvent e) {
	            //按键按下
		}
		@Override
		public void keyReleased(KeyEvent e) {
		    //按键抬起
		}	
	}

3.思聪和热狗

首先要有一个位置,还要能移动,其实也就是不断的计算位置和把图片画上去的过程

定义一些思聪的属性,并在构造方法中初始化这些属性

	boolean left,right,down,up;
	
	public int x,y,width,height;
	
	Image img ;

	public Plane(String img_path,int x, int y){
		this.img = GameUtil.getImage(img_path);
		this.x = x;
		this.y = y;
		width = img.getWidth(null);
		height = img.getWidth(null);
		live = true;
	}

把思聪画上去

	public void draw(Graphics g){
		if(live){
			g.drawImage(img, x, y, null);
			move();
		}
	}

接下来最重要的就是计算思聪的位置了,为什么要把位置计算写到画思聪的方法里呢?主要是考虑这样的一种情况,如果你把方法计算写到按键按下或者释放里面,那么你想移动思聪的位置就得疯狂按键盘,要想长按按键来控制移动就要吧移动方法写到画思聪的方法里面,然后用按键的按下和释放来控制是否移动。

移动的时候还要考虑到边界的情况

	public void move(){
		if(left&&x>=10){
			x -= 10;
		}		
		if(up&&y>=30){
			y -= 10;
		}
		if(right&&x<=FeiJiGame.width-60){
			x += 10;
		}
		if(down&&y<=FeiJiGame.height -60){
			y += 10;
		}
	}

	public void KeyPressedControlDirection(KeyEvent e){
		int key_code = e.getKeyCode();
		if(key_code == 37){
			left = true;
		}
		if(key_code == 38){
			up = true;
		}
		if(key_code == 39){
			right = true;
		}
		if(key_code == 40){
			down = true;
		}
	}

	public void KeyRelasedControlDirection(KeyEvent e){
		int key_code = e.getKeyCode();
		if(key_code == 37){
			left = false;
		}
		if(key_code == 38){
			up =false;
		}
		if(key_code == 39){
			right = false;
		}
		if(key_code == 40){
			down = false;
		}
	}

最后提供两个方法来改写思聪的生存

对于热狗类就简单多了,就是让它不断的跑,不需要响应按键事件

定义一些属性和在构造方法中初始化

	double speed=15;
	double degree;

	public double x,y;
	public int width,height;
	Image img;

	public Bullet(String img_path){
		img=GameUtil.getImage(img_path);
		degree = Math.random()*Math.PI*2;
		x=FeiJiGame.width/2;
		y=FeiJiGame.height/2;
		width = 10;
		height = 10;
	}

随机的degree的用途是让它们的初始方向不同,使用sin和cos函数来控制热狗的移动,同时也要注意边界

	public void draw(Graphics g){
		g.drawImage(img, (int)x, (int)y, null);
		x += speed*Math.cos(degree);
		y += speed*Math.sin(degree);

		if(x>FeiJiGame.width-width||x<width){
			degree=Math.PI-degree;
		}
		if(y>FeiJiGame.height-height||y<height){
			degree=-degree;
		}
	}

4.碰撞检测和音乐播放

在java的awt里面有一个矩形类可以判断两个矩形是否有重叠部分,有重叠说明就碰撞上了

Rectangle bulletRectangle = new Rectangle((int)bullet.x,(int)bullet.y,bullet.width,bullet.height);
Rectangle planeRectangle = new Rectangle(plane.x,plane.y,plane.width,plane.height);
boolean collide= bulletRectangle.intersects(planeRectangle);

音乐播放可以使用第三方的库,jl-1.0.1.jar,因为可能连续吃到热狗,所以需要多线程播放音乐

	class MusicPlayer implements Runnable{
		@Override
		public void run() {
			try {
				new Player(new FileInputStream(FeiJiGame.class.getClassLoader().getResource("raw/music.mp3").getPath().substring(1))).play();
			} catch (Exception e) {
				e.printStackTrace();
			}
		}
	}

5.完成

剩下的就是窗体的刷新,这个可以开一个线程来做

	class PaintThread extends Thread {
		@Override
		public void run() {
			while(!Thread.currentThread().isInterrupted()){
				repaint();
				try {
					Thread.sleep(40);
				} catch (InterruptedException e) {
					Thread.currentThread().interrupt();
				}
			}
		}	
	}

游戏右上方要显示现在的游戏时间,结束也要显示一些文字信息,写了一个工具类

使用font控制字体,graphics.setFont设置字体,drawString画上去

	public void printInfo(Graphics g,String message,int size,int x,int y){
		g.setColor(Color.white);
		Font f = new Font("宋体",Font.BOLD,size);
		g.setFont(f);
		g.drawString(message, x,y);
	}

游戏结束时显示一些信息,根据时间判断给出等级

	private void gameOver(Graphics graphics) {
		printInfo(graphics,"GAME OVER",80,270,300);
		int survivalTime = (int)(endTime.getTime()-starTime.getTime())/1000;
		printInfo(graphics,"吃热狗时间:"+survivalTime+"秒",40,300,400);

		switch(survivalTime/10){
			case 1:
				printInfo(graphics,"独孤求败",50,350,500);
				break;
			case 2:
				printInfo(graphics,"登堂入室",50,350,500);
				break;
			case 3:
				printInfo(graphics,"小有成就",50,350,500);
				break;
			default:
				printInfo(graphics,"初入江湖",50,350,500);
				break;
		}
		paintThread.interrupt();
	}

在初始化窗体时要添加热狗和开始重绘线程,开始计时

		for(int i=0;i<15;i++){
			Bullet bullet = new Bullet("images/hotdog.png");
			bulletList.add(bullet);
 		}
		starTime = new Date();
		endTime = new Date();
		paintThread=new PaintThread();
		paintThread.start();

复写绘画和更新

        @Override
	public void paint(Graphics graphics) {
		graphics.drawImage(bg, 0, 0, null);
		plane.draw(graphics);
		endTime = new Date();
		if(gameState){
			for(int i=0;i<bulletList.size();i++){
				Bullet bullet=bulletList.get(i);
				bullet.draw(graphics);

				Rectangle bulletRectangle = new Rectangle((int)bullet.x,(int)bullet.y,bullet.width,bullet.height);
				Rectangle planeRectangle = new Rectangle(plane.x,plane.y,plane.width,plane.height);
				boolean collide= bulletRectangle.intersects(planeRectangle);

				if(collide){
					if (bulletList.size()!=0){
						executorService.execute(musicPlayer);
						bulletList.remove(i);
						if (bulletList.size()==0){
							gameState = false;
						}
					}
				}
			}
		}else {
			endTime = new Date();
			gameOver(graphics);
			paintThread.interrupt();
		}

		int count_time = (int)(endTime.getTime()-starTime.getTime())/1000;
		printInfo(graphics,"你已经吃了"+count_time+"秒",20,750,50);
	}

	Image ImageBuffer = null;  
	Graphics GraImage = null;
	@Override
	public void update(Graphics g){
	    ImageBuffer = createImage(this.getWidth(), this.getHeight());
	    GraImage = ImageBuffer.getGraphics();
	    paint(GraImage);
	    GraImage.dispose();
	    g.drawImage(ImageBuffer, 0, 0, this);
	}  

在按键监听里面调用思聪的按键按下和释放方法

	class KeyMoniter extends KeyAdapter{
		@Override
		public void keyPressed(KeyEvent e) {
			plane.KeyPressedControlDirection(e);
		}
		@Override
		public void keyReleased(KeyEvent e) {
			plane.KeyRelasedControlDirection(e);
		}	
	}

最后启动游戏

	public static void main(String[] args) {
		FeiJiGame game = new FeiJiGame();
		game.loadGame();
	}

教你用JAVA写个小游戏[通俗易懂]

github:https://github.com/s15603333319/SiCongEatHotDog

csdn:https://download.csdn.net/download/qq_37482202/11084561

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请联系我们举报,一经查实,本站将立刻删除。

发布者:全栈程序员-站长,转载请注明出处:https://javaforall.net/158956.html原文链接:https://javaforall.net

(0)
上一篇 2022年7月14日 下午6:46
下一篇 2022年7月14日 下午7:00


相关推荐

  • BP神经网络预测matlab代码讲解与实现步骤

    BP神经网络预测matlab代码讲解与实现步骤文章目录1.BP神经网络的简介和结构参数1.1BP神经网络的结构组成1.2BP神经网络训练界面的参数解读2.实现BP网络的步骤3.matlab代码编写4.BP代码运行结果4.1预测值和真实值的误差计算(MAE、MSE、MRSE)4.2BP网络训练的性能分析图像5.结语6.MATLAB代码1.BP神经网络的简介和结构参数神经网络是机器学习中一种常见的数学模型,通过构建类似于大脑神经突触联接的结构,来进行信息处理。在应用神经网络的过程中,处理信息的单元一般分为三类:输入单元、输出单元和

    2022年6月20日
    62
  • linux安装、卸载jdk及配置环境变量

    linux安装、卸载jdk及配置环境变量一、查看Jdk的安装路径:whereisjavawhichjava(java执行路径)echo$JAVA_HOMEecho$PATH二、卸载旧版本的JDK:1.确定JDK的版本:rpm-qa|grepjdkrpm-qa|grepgcj结果:copy-jdk-configs-2.2-5.el7_4.noarchjava-1.8.0-openjdk-headless-de…

    2022年6月25日
    27
  • 机械键盘各种设定(品牌:黑爵等)

    机械键盘各种设定(品牌:黑爵等)游戏机械键盘自带设定呼吸灯 asdf 重设 宏命令设置 但有时候不小心按到了会让人误解是键盘坏了 呼吸灯设置 ASDF 颠倒键盘的上下左右四个键位和 ASDW 四个键位转换 方法 如果键盘的上下左右变成了 ASDW 可以按快捷键 Fn W 切换回来 此种方法适用于大多数品牌 如果键盘的上下左右变成了 ASDW 可以按快捷键 Fn 空格切换回来 此种方法适用于达尔优等少数品牌 如果键盘的上下左右变成了 ASDW 可以按快捷键 Fn Win 切换回来 此种切换方式适用于苹果键盘等少数品牌 说明 其实 w a

    2026年3月19日
    1
  • 常见的几种矩阵分解方式

    常见的几种矩阵分解方式1.三角分解(LU分解)矩阵的LU分解是将一个矩阵分解为一个下三角矩阵与上三角矩阵的乘积。本质上,LU分解是高斯消元的一种表达方式。首先,对矩阵A通过初等行变换将其变为一个上三角矩阵。对于学习过线性代数的同学来说,这个过程应该很熟悉,线性代数考试中求行列式求逆一般都是通过这种方式来求解。然后,将原始矩阵A变为上三角矩阵的过程,对应的变换矩阵为一个下三角矩阵。这中间的过程,就是Doolittleal

    2022年5月30日
    45
  • Windows 全局钩子 Hook 详解

    Windows 全局钩子 Hook 详解监控程序的实现 nbsp nbsp nbsp nbsp nbsp 我们发现一些木马或其他病毒程序常常会将我们的键盘或鼠标的操作消息记录下来然后再将它发到他们指定的地方以实现监听 这种功能其他是利用了全局钩子将鼠标或键盘消息进行了截取 从而获得了操作的消息 要得到鼠标和键盘的控制权 我们要用 SetWindowsHo 这个函数 nbsp HHOOKSetWind nbsp nbsp nbsp intidHook nbsp nbsp nbsp nbsp nbsp nbsp nbsp

    2026年3月26日
    2
  • Android如何下抓取tcp数据包[通俗易懂]

    如果要抓TCP数据包,我们可以使用TCPdump工具,具体方法是: 下载tcpdump,  还有个地址是http://www.strazzere.com/android/tcpdump,不知道具体版本。  详细使用请参考http://www.tcpdump.org/里

    2022年4月14日
    219

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注

关注全栈程序员社区公众号