java 300行代码 冒险闯关小游戏(代码+讲解)

article/2025/10/12 17:07:16

         作为一个男孩子,从小就喜欢晚一些游戏。今天就用java写一个类似马里奥的冒险闯关小游戏,但这也不是一两天能完成的事情,我将会持续更新这个游戏(有什么好的介意也非常欢迎大家提出来,也能在我的基础上自己接着写)。目前完成的功能有:人物的流畅运动、跳跃以及自由下落,障碍物(地面)的添加,怪物的添加、移动以及死亡。(代码基本上是完整的,直接粘贴复制就能用)


游戏介绍

和马里奥差不太多,左右键控制移动,空格跳,碰到怪物死亡,可以踩死怪物。目前也就这些功能,也会不断添加新的功能。

代码讲解

目录结构

view里面是创建页面,handle里写控制方法,pic里存一些需要的图片。

创建Frame

没啥好讲的。

import javax.swing.*;public class GameFrame {public static void main(String[] args) {JFrame jf = new JFrame("冒险闯关小游戏");jf.add(new GamePanel());jf.setSize(806,600);jf.setLocationRelativeTo(null);     //居中jf.setResizable(false);jf.setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);jf.setVisible(true);}
}

 JPanel

这里定义了玩家、怪物、障碍物的一些属性,然后将他们画出来。其实更好的方法是定义三个类,用的时候实例化一下就行,这里后面我也会改。

import game2.handle.MonsterMove;
import game2.handle.MoveHandle;import javax.swing.*;
import java.awt.*;
import java.util.Vector;public class GamePanel extends JPanel {ImageIcon b = new ImageIcon("src\\game2\\pic\\b.jpg");ImageIcon xyq = new ImageIcon("src\\game2\\pic\\xyq.png");public boolean up = false;public boolean down = false;public boolean left = false;public boolean right = false;public int hero_x;public int hero_y;
//    public int hero_width = xyq.getIconWidth();
//    public int hero_height = xyq.getIconHeight();public int hero_width = 30;public int hero_height = 60;public Vector<int[]> v = new Vector<>();int[] f0 = {0,500,800,10};int[] f1 = {300,500-80,200,10};int[] f2 = {500,500-40,50,40};int[] f3 = {100,500-150,80,30};int[] f4 = {200,500-250,340,10};{v.add(f0);v.add(f1);v.add(f2);v.add(f3);v.add(f4);}public Vector<int[]> ms = new Vector<>();    //怪物列表public int[] m0 = {600,500-40,40,40,600,750,1}; //x,y,w,h,起点,终点,速度public int[] m1 = {0,500-40,40,40,0,100,1};{ms.add(m0);ms.add(m1);}public boolean mIsDie = false;public GamePanel() {setFocusable(true);MoveHandle moveHandle = new MoveHandle(this);addKeyListener(moveHandle);Thread thread = new Thread(moveHandle);thread.start();MonsterMove monsterMove = new MonsterMove(this);Thread thread2 = new Thread(monsterMove);thread2.start();init();}public void init() {hero_x = 200;hero_y = 500-hero_height;}@Overridepublic void paint(Graphics g) {super.paintComponent(g);b.paintIcon(this,g,0,0);g.setColor(Color.blue);g.fillRect(hero_x, hero_y, hero_width, hero_height);
//        xyq.paintIcon(this,g,hero_x,hero_y);g.setColor(Color.red);for(int i=0;i<ms.size();i++){g.fillRect(ms.get(i)[0],ms.get(i)[1],ms.get(i)[2],ms.get(i)[3]);}paintRect(g,v);}private void paintRect(Graphics g,Vector<int[]> v){g.setColor(Color.black);for(int i = 0; i<v.size(); i++){int[] f = v.get(i);g.fillRect(f[0],f[1],f[2],f[3]);}}
}

MoveHandle

我觉得我这里最好的一点代码就在这里面,其实从学写swing时候,就发现如果用键盘控制人物移动的时候它的移动并不顺畅。我这里是用线程的方法做成了顺畅移动。

简单讲,就是创建一个进程,一直让他循环执行,每当按下右(左)键,就会一直循环执行向右(左)走的方法,每次运行方法中间间隔几毫秒(不然移动的太快根本看不到)。

然后中间再添加一些其他判断,如是否碰到障碍物,是否碰到怪物等。

import game2.view.GamePanel;import java.awt.event.KeyEvent;
import java.awt.event.KeyListener;public class MoveHandle implements KeyListener, Runnable {GamePanel gamePanel;JumpHandle jump;public MoveHandle(GamePanel gamePanel) {this.gamePanel = gamePanel;jump = new JumpHandle(gamePanel);Thread thread1 = new Thread(jump);thread1.start();}@Overridepublic void keyTyped(KeyEvent e) {}@Overridepublic void keyPressed(KeyEvent e) {int code = e.getKeyCode();switch (code) {case KeyEvent.VK_LEFT:gamePanel.left = true;break;case KeyEvent.VK_RIGHT:gamePanel.right = true;break;case KeyEvent.VK_SPACE:jump.isSky = true;if (jump.c < 2) {jump.isJump = true;}break;default:break;}gamePanel.repaint();}@Overridepublic void keyReleased(KeyEvent e) {int code = e.getKeyCode();switch (code) {case KeyEvent.VK_LEFT:gamePanel.left = false;break;case KeyEvent.VK_RIGHT:gamePanel.right = false;break;default:break;}}@Overridepublic void run() {while (true) {move();if (!jump.isSky) {loop:while (true) {for (int i = 0; i < gamePanel.v.size(); i++) {if (gamePanel.hero_x + gamePanel.hero_width > gamePanel.v.get(i)[0]&& gamePanel.hero_x < gamePanel.v.get(i)[0] + gamePanel.v.get(i)[2]) {if (gamePanel.hero_y == gamePanel.v.get(i)[1] - gamePanel.hero_height) {break loop;}}}gamePanel.hero_y += 1;for(int i=0;i<gamePanel.ms.size();i++) {if (gamePanel.hero_y + gamePanel.hero_height == gamePanel.ms.get(i)[1]&& gamePanel.hero_x + gamePanel.hero_width > gamePanel.ms.get(i)[0]&& gamePanel.hero_x < gamePanel.ms.get(i)[0] + gamePanel.ms.get(i)[2]) {gamePanel.ms.remove(i);break ;}}gamePanel.repaint();try {Thread.sleep(3);} catch (InterruptedException e) {throw new RuntimeException(e);}move();}}gamePanel.repaint();try {Thread.sleep(3);} catch (InterruptedException e) {throw new RuntimeException(e);}}}private void move() {if (gamePanel.right) {if (gamePanel.hero_x + gamePanel.hero_width < 800 && isMoveRight()) {gamePanel.hero_x += 1;}} else if (gamePanel.left) {if (gamePanel.hero_x > 0 && isMoveLeft()) {gamePanel.hero_x -= 1;}}isDie();}private boolean isMoveRight() {for (int i = 0; i < gamePanel.v.size(); i++) {if (gamePanel.hero_x + gamePanel.hero_width == gamePanel.v.get(i)[0]&& gamePanel.hero_y + gamePanel.hero_height > gamePanel.v.get(i)[1]&& gamePanel.hero_y < gamePanel.v.get(i)[1] + gamePanel.v.get(i)[3]) {return false;}}return true;}private boolean isMoveLeft() {for (int i = 0; i < gamePanel.v.size(); i++) {if (gamePanel.hero_x == gamePanel.v.get(i)[0] + gamePanel.v.get(i)[2]&& gamePanel.hero_y + gamePanel.hero_height > gamePanel.v.get(i)[1]&& gamePanel.hero_y < gamePanel.v.get(i)[1] + gamePanel.v.get(i)[3]) {return false;}}return true;}private void isDie() {for(int i=0;i<gamePanel.ms.size();i++) {int[] m = gamePanel.ms.get(i);if ((gamePanel.hero_x + gamePanel.hero_width == m[0] || gamePanel.hero_x == m[0] + m[2])&& gamePanel.hero_y + gamePanel.hero_height > m[1]&& gamePanel.hero_y < m[1] + m[3]) {gamePanel.init();;}}}
}

JumpHandle

这段是用来实现跳跃的功能,我这里设置的上下跳跃是匀速的,可以自己改一下,让它符合真实物理情况。

这里我设置了最多跳两次。

并且在下降的时候增加了两个判断:1是是否落到实体障碍物上,2是是否踩到怪物,踩到怪物就被判断死亡。

import game2.view.GamePanel;import java.util.Arrays;public class JumpHandle implements Runnable {GamePanel gamePanel;boolean isJump = false;boolean isSky = false;int c;public JumpHandle(GamePanel gamePanel) {this.gamePanel = gamePanel;}@Overridepublic void run() {while (true) {c = 0;if (isJump) {isJump = false;jumpUp();jumpDown();}try {Thread.sleep(3);} catch (InterruptedException e) {throw new RuntimeException(e);}}}private void jumpDown() {loop:while (true) {for (int i = 0; i < gamePanel.v.size(); i++) {if (gamePanel.hero_x  + gamePanel.hero_width> gamePanel.v.get(i)[0]&& gamePanel.hero_x < gamePanel.v.get(i)[0] + gamePanel.v.get(i)[2]) {if (gamePanel.hero_y == gamePanel.v.get(i)[1] - gamePanel.hero_height) {isSky = false;break loop;}}}if (isJump && c < 2) {isJump = false;jumpUp();}gamePanel.hero_y += 1;for(int i=0;i<gamePanel.ms.size();i++) {if (gamePanel.hero_y + gamePanel.hero_height == gamePanel.ms.get(i)[1]&& gamePanel.hero_x + gamePanel.hero_width > gamePanel.ms.get(i)[0]&& gamePanel.hero_x < gamePanel.ms.get(i)[0] + gamePanel.ms.get(i)[2]) {gamePanel.ms.remove(i);break ;}}try {Thread.sleep(3);} catch (InterruptedException e) {throw new RuntimeException(e);}}}private void jumpUp() {c++;for (int i = 0; i < 80; i++) {if (isJump && c < 2) {isJump = false;jumpUp();break;}if(!isJumpD()){break;}gamePanel.hero_y -= 1;try {Thread.sleep(3);} catch (InterruptedException e) {throw new RuntimeException(e);}}}private boolean isJumpD() {for (int i = 0; i < gamePanel.v.size(); i++) {if (gamePanel.hero_y == gamePanel.v.get(i)[1] + gamePanel.v.get(i)[3]&& gamePanel.hero_x  + gamePanel.hero_width> gamePanel.v.get(i)[0]&& gamePanel.hero_x < gamePanel.v.get(i)[0] + gamePanel.v.get(i)[2]) {return false;}}return true;}
}

MonsterMove

这里是实现怪物的移动。

import game2.view.GamePanel;public class MonsterMove implements Runnable {GamePanel gamePanel;public MonsterMove(GamePanel gamePanel) {this.gamePanel = gamePanel;}@Overridepublic void run() {while(true) {for (int i = 0; i < gamePanel.ms.size(); i++) {gamePanel.ms.get(i)[0]+=gamePanel.ms.get(i)[6];if(gamePanel.ms.get(i)[0]==gamePanel.ms.get(i)[4]||gamePanel.ms.get(i)[0]+gamePanel.ms.get(i)[2]==gamePanel.ms.get(i)[5]){gamePanel.ms.get(i)[6] = -gamePanel.ms.get(i)[6];}}try {Thread.sleep(5);} catch (InterruptedException e) {throw new RuntimeException(e);}}}
}


http://chatgpt.dhexx.cn/article/TyhsNRnZ.shtml

相关文章

宝塔php防盗链,[宝塔面板]如何开启防盗链?

为了节省建站成本&#xff0c;大多数站长都会选择一些小服务器&#xff0c;在另加CDN、云存储之类的来减轻服务器的压力&#xff0c;但是这类功能大多收费。 如果自己网站的图片都让别人复制图片链接地址&#xff0c;那么自己CDN流量就跑得贼快&#xff0c;花了钱得不到好处。 …

HTTP防盗链(Referer)

HTTP请求防盗链&#xff1a;只允许某些域名请求来源才可以访问。比如A网站有一张图片或音频等资源被B网站直接通过img等标签属性引入使用&#xff0c;这样就是B网站盗用了A网站的资源。那么对于A网站来说&#xff0c;流量怎么被消耗的都不知道。 解决思路&#xff1a; 判断http…

Nginx防盗链的配置

Nginx防盗链的配置 通常站点&#xff0c;都会想让自己网站的视频和图片&#xff0c;免被盗用&#xff0c;毕竟视频流量&#xff0c;花的都是白花花银子   首先我们没有配置防盗链的情况下&#xff0c;放开静态资源你的访问。我们来看看效果 location ~* .*\.(gif|jpg|ico|pn…

python爬虫的防盗链

文章目录 前言一、防盗链是什么&#xff1f;二、 防盗链如何实现三、分析四、 对有防盗链的网站进行爬取对有视频连接的网站发出请求并且获取源码信息提取出我们的视频网站对我们提取的网址进行修改&#xff0c;和拼凑下载视频结束爬取 完整代码 前言 随着python的发展网页的反…

Nginx静态资源防盗链

1.什么是资源盗链 简单地说&#xff0c;就是将别人的资源用到自己的页面展示给用户。 2.效果演示 1&#xff09;准备图片 这两张图片直接在浏览器中访问都是可以打开的。 github图片地址&#xff1a;https://github.githubassets.com/images/modules/site/home-campaign/her…

取消文件服务器防盗链,如何取消防盗链保护

http标准协议中有专门的字段记录referer 一来可以追溯上一个入站地址是什么 二来对于资源文件&#xff0c;可以跟踪到包含显示他的网页地址是什么。 因此所有防盗链方法都是基于这个Referer字段 网上比较多的2种 一种是使用apache文件FileMatch限制&#xff0c;在httpd.conf中增…

视频防盗链

解析器链接&#xff1a; https://www.administratorw.com/index/qqvod.php?url 清晰度高url后面支持mp4、m3u8地址 https://z1.m1907.cn?jx 清晰度底&#xff0c;链接后面只支持电影名 此接口解析出来的m3u8地址为&#xff1a;&#xff08;雄狮少年&#xff09; https…

html 图片防盗链,【反防盗链】介绍一个对付图片防盗链的方法

悲催的声明: 由于腾讯也采用了防盗链技术,本文方法已经失效了! 当我们想在文章里引用某张图片时,如果对方设置了防盗链,我们看到的将是404或forbidden或其他图片,而不是想要的那张图片,为此,我们有无方法进行“反防盗链”呢?答案是有的,本文将介绍一个对付图片防盗链…

简单的视频防盗链

1.使用hls.js播放视频&#xff0c;页面中无法获得视频的src hls.js是视频播放的工具文件&#xff0c;在官网上有播放方式&#xff0c;可以产生如上图所示的效果&#xff0c;没有source标签&#xff0c;也就是说&#xff0c;在页面上隐藏掉了视频的url hls.js文件地址&#xff…

html设置referer防盗链,referer与防盗链

referer是什么 referer 中文意思是:参照页面,引用页。 下图直观感受,(づ ̄ 3 ̄)づ image 直接在浏览器中输入url地址来直接访问图片/js/css等资源时是没有referer的, 如果有referer说明是引用过来的,要么是从HTML页面,要么是通过css @import,再或则通过background(url)引用…

防盗链使用

现在很多网站启用了防盗链反爬&#xff0c;防止服务器上的资源被人恶意盗取。什么是防盗链呢&#xff1f; 以图片为例&#xff0c;访问图片要从他的网站访问才可以&#xff0c;否则直接访问图片地址得不到图片 练习&#xff1a;抓取微博图片&#xff1a;http://blog.sina.com…

nginx配置防盗链

现在流行前后端分离开发的情况下&#xff0c;一般我们都会将静态资源放在nginx的html目录下。这种情况下&#xff0c;我们就无法通过Java代码写拦截器来防盗链了。所以这里我们来说明一下如何使用nginx来配置防盗链。 1.我们先修改本地hosts文件&#xff0c;将 www.czx.com 映…

java防盗链_javaWeb防止恶意登陆或防盗链的使用

使用场景:明明引用了一个正确的图片地址,但显示出来的却是一个红叉或写有“此图片仅限于***网站用户交流沟通使用”之类的“假图片”。用嗅探软件找到了多媒体资源的真实地址用下载软件仍然不能下载。下载一些资源时总是出错,如果确认地址没错的话,大多数情况都是遇上防盗链…

防盗链机制

防盗链机制的几种实现 通常防盗链是为了防止图片&#xff0c;视频被盗用。下面简单介绍几种防盗链的机制&#xff1a; 1. 利用HTTP Referer字段 HTTP请求中会包含来自哪个url的点击来源&#xff0c;通过这个referer字段可以检测是否别的网站发送的请求。 2.利用登录验证信息 有…

网络中的防盗链是指什么?

什么是盗链&#xff1f; 比如,别人上传的东西,你直接拿了LINK去,贴到别的论坛或者网站,宣称"有好东西,快来下载",又或者告诉你的朋友"你要这个文件?俺有连接,快下",然后在那里接受别人的滔滔不绝的景仰之情。 “盗链” 的定义是&#xff1a; 此内容不在…

Nginx防盗链

Nginx防盗链的实现原理&#xff1a; 了解防盗链的原理之前&#xff0c;我们得先学习一个HTTP的头信息Referer,当浏览器向web服务器发送请求的时候&#xff0c;一般都会带上Referer,来告诉浏览器该网页是从哪个页面链接过来的。 后台服务器可以根据获取到的这个Referer信息来判…

Nginx-防盗链

目录 一、什么是盗链 如何区分哪些是不正常的用户&#xff1f; Referer理解 二、Nginx配置防盗链 三、使用 curl 测试防盗链 四、企业实战 1.设置返回错误页面 2.整合 rewrite 返回报错图片 一、什么是盗链 在实际生产过程中&#xff0c;我们线上的图片等静态资源&#…

Nginx:防盗链原理和配置

目录 一、防盗链概念 二、Nginx防盗链的具体实现 配置&#xff1a; 三、验证和验证时的问题 真正的验证&#xff1a; 没有none的验证 加上none参数的验证 让报错返回的是一张图片 注意事项&#xff1a; 一、防盗链概念 防盗链简单来说就是存在我们服务中的一些资源&#xff…

Java:eclipse下开发webservice教程

1 环境准备 下载wtp-all-in-one-sdk-R-1.5.4-win32&#xff0c;这个是eclipse的web开发插件 下载jakarta-tomcat-5.0.30 下载axis-src-1_4.zip 2 环境配置 配置tomcat关联到你的eclipse中 将axis-1_4\webapps\axis\WEB-INF\lib中的文件复制到$TOMCATHOME$\…

webservice 教程学习系列(九)——使用cxf框架开发webservice

首先下载两个包&#xff1a;apache-cxf-3.2.7.zip和apache-cxf-3.2.7-src.zip 解压两个包&#xff0c;进入apache-cxf-3.2.7的bin目录 可以看到wsdl2java.bat&#xff0c;这个相当于jdk自带的wsimport.exe的功能&#xff0c;可以将wsdl文件转换成java文件。 这里我的目录是&a…