java版超级玛丽游戏

news/2024/10/23 5:42:09/

技术选型

平台:Windows开发工具:Intelij IDEA

JDK环境:Java 8

UI界面:基于Swing的桌面编程技术。

绘图技术:Graphics

集合框架

IO流

多线程等

地图配置

地图map.txt文件

0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0
0,1,0,0,0,1,1,1,1,0,0,2,2,0,0,0,0,0,0,3
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0

 

读取地图

package cn.tx.util;import org.junit.Test;import java.io.BufferedReader;
import java.io.FileInputStream;
import java.io.InputStreamReader;
import java.util.ArrayList;
import java.util.List;/*** 地图配置类* @author 任亮* @company 拓薪教育* @QQ:206229531*/
public class GameMap {//数据容器public List<String> list = new ArrayList<>();// 二维数组元素又是一个一维数组:行列矩阵public int[][] map = null;// 单元测试:验证Map类的readMap()方法确实把地图配置文件map.txt// 加载成了二维数组@Testpublic void testResult() throws Exception {int[][] result = readMap();// 二维数组的内容输出,看一下是否是地图的配置信息for(int i = 0 ; i < result.length ; i++ ){for(int j = 0 ; j < result[i].length ; j++) {System.out.print(result[i][j]+" ");}System.out.println();}}public int[][] readMap() throws Exception {// 构造文件输入流FileInputStream fis = new FileInputStream("map.txt");InputStreamReader isr = new InputStreamReader(fis);BufferedReader br = new BufferedReader(isr);//直接读取一行数据String value = br.readLine();while (value != null) {//将读取到的一行数据加入到容器中list.add(value);value = br.readLine();}br.close();//得到多少行多少列int row = list.size();int cloum = 0;for (int i = 0; i < 1; i++) {String str = list.get(i);String[] values = str.split(",");cloum = values.length;}map = new int[row][cloum];//将读到的字符创转换成整数,并赋值给二位数组mapfor (int i = 0; i < list.size(); i++) {String str = list.get(i);String[] values = str.split(",");for (int j = 0; j < values.length; j++) {map[i][j] = Integer.parseInt(values[j]);}}return map;}}

定义角色

超级玛丽中的角色包括了,水管,怪物,砖头等。并显示到主界面。

障碍物抽象父类Enemy

package cn.tx.role;import java.awt.Image;
/**敌人抽象类* @author 任亮* @company 拓薪教育* @QQ:206229531*/
public abstract class Enemy {//坐标位置public int x,y;//宽高public int width,height;//图片public Image img;public Enemy(int x, int y, int width, int height, Image img) {this.x = x;this.y = y;this.width = width;this.height = height;this.img=img;}
}

水管类

package cn.tx.role;
import java.awt.Image;/*** 水管类* @author 任亮* @company 拓薪教育* @QQ:206229531*/
public class Pipe extends Enemy {public Pipe(int x, int y, int width, int height, Image img) {super(x, y, width, height, img);}
}

砖头类

package cn.tx.role;import java.awt.Image;/*** 砖** @author 任亮* @company 拓薪教育* @QQ:206229531*/
public class Brick extends Enemy {public Brick(int x, int y, int width, int height, Image img) {super(x, y, width, height, img);}
}

金币类

package cn.tx.role;import java.awt.Image;/**金币类* @author 任亮* @company 拓薪教育* @QQ:206229531*/
public class Coin extends Enemy {public Coin(int x, int y, int width, int height, Image img) {super(x, y, width, height, img);}
}

子弹类

package cn.tx.role;
/**子弹类* @author 任亮* @company 拓薪教育* @QQ:206229531*/
public class Boom {//子弹的坐标,大小,速度public int x,y;public int width;public int speed=1;public Boom(int x, int y, int width) {super();this.x = x;this.y = y;this.width = width;}
}

马里奥类

package cn.tx.mario;import java.awt.Image;
import java.awt.Rectangle;
import javax.swing.ImageIcon;import cn.tx.ui.GameFrame;
import cn.tx.role.Enemy;/*** 玛丽** @author 任亮* @company 拓薪教育* @QQ:206229531*/
public class Mario extends Thread {//窗体对象public GameFrame gf;//是否跳起public boolean jumpFlag = true;//马里奥的坐标,原点为左上角,所以y周越小玛丽越高public int x = 50, y = 358;//马里奥的速度public int xspeed = 5, yspeed = 1;//马里奥的宽高public int width = 30, height = 32;//马里奥的图片public Image img = new ImageIcon("image/mari1.png").getImage();//键盘上的上下左右是否被按下public boolean left = false, right = false, down = false, up = false;public String Dir_Up = "Up", Dir_Left = "Left", Dir_Right = "Right", Dir_Down = "Down";public Mario(GameFrame gf) {this.gf = gf;this.Gravity();}// 玛丽飞翔的逻辑 ;移动的逻辑都在这里。public void run() {while (true) {//向左走if (left) {//碰撞到了if (hit(Dir_Left)) {this.xspeed = 0;}//没有撞击到障碍物if (this.x >= 0) {//马里奥的位置的更新this.x -= this.xspeed;//改变马里奥的图片this.img = new ImageIcon("image/mari_left.gif").getImage();}this.xspeed = 5;}//向右走if (right) {// 右边碰撞物检测应该是往右走的时候检测// 进行碰撞检测:至少主角(玛丽,碰撞物)if (hit(Dir_Right)) {this.xspeed = 0;}//任人物向右移动if (this.x < 400) {this.x += this.xspeed;this.img = new ImageIcon("image/mari_right.gif").getImage();}//玛丽奥x轴的坐标大于400的时候发生什么if (this.x >= 400) {//背景向左移动gf.bg.x -= this.xspeed;//障碍物项左移动for (int i = 0; i < gf.eneryList.size(); i++) {Enemy enery = gf.eneryList.get(i);enery.x -= this.xspeed;}//图标的变化this.img = new ImageIcon("image/mari_right.gif").getImage();}this.xspeed = 5;}//向上跳if (up) {if (jumpFlag && !isGravity) {jumpFlag = false;new Thread() {public void run() {jump();jumpFlag = true;}}.start();}}try {this.sleep(20);} catch (InterruptedException e) {e.printStackTrace();}}}//向上跳的函数public void jump() {//定义高度值int jumpHeigh = 0;for (int i = 0; i < 150; i++) {//玛丽的y轴位置减去玛丽的y轴速度gf.mario.y -= this.yspeed;//玛丽的高度递增jumpHeigh++;//如果撞到障碍物跳出if (hit(Dir_Up)) {break;}try {Thread.sleep(5);} catch (InterruptedException e) {e.printStackTrace();}}//玛丽跳起来后下落for (int i = 0; i < jumpHeigh; i++) {//玛丽的y轴高度加上y轴速度gf.mario.y += this.yspeed;//如果撞到下面障碍则停止if (hit(Dir_Down)) {this.yspeed = 0;}try {Thread.sleep(5);} catch (InterruptedException e) {e.printStackTrace();}}this.yspeed = 1;//还原速度}//检测碰撞public boolean hit(String dir) {// Swing技术中,人家已经提供了!!Rectangle myrect = new Rectangle(this.x, this.y, this.width, this.height);Rectangle rect = null;for (int i = 0; i < gf.eneryList.size(); i++) {Enemy enery = gf.eneryList.get(i);if (dir.equals("Left")) {rect = new Rectangle(enery.x + 2, enery.y, enery.width, enery.height);} else if (dir.equals("Right")) {// 右侧碰撞物检测。rect = new Rectangle(enery.x - 2, enery.y, enery.width, enery.height);} else if (dir.equals("Up")) {rect = new Rectangle(enery.x, enery.y + 1, enery.width, enery.height);} else if (dir.equals("Down")) {rect = new Rectangle(enery.x, enery.y - 2, enery.width, enery.height);}//碰撞检测if (myrect.intersects(rect)) {return true;}}return false;}//检查是否贴地public boolean isGravity = false;// 重力线程!public void Gravity() {new Thread() {public void run() {while (true) {try {sleep(10);} catch (InterruptedException e) {e.printStackTrace();}while (true) {//如果没有跳起退出if (!jumpFlag) {break;}//如果撞到下面障碍跳出if (hit(Dir_Down)) {break;}//大于385 在地面之下if (y >= 358) {isGravity = false;} else {//在地面上isGravity = true;//y是马里奥的纵向的位置y += yspeed;}try {sleep(10);} catch (InterruptedException e) {e.printStackTrace();}}}}}.start();}
}

窗体

package cn.tx.ui;import java.awt.Color;
import java.awt.Graphics;
import java.awt.image.BufferedImage;
import java.util.ArrayList;
import javax.swing.ImageIcon;
import javax.swing.JFrame;import cn.tx.mario.Mario;
import cn.tx.role.*;
import cn.tx.util.GameMap;
import cn.tx.util.MusicUtil;
/**主体窗口界面:展示角色。*/
public class GameFrame extends JFrame{// 超级玛丽:界面需要一个超级玛丽的。public Mario mario;// 分别定义:水管,金币和砖块public Enemy pipe ,coin , brick;//背景图片public BackgroundImage bg ;//定义一个集合容器装敌人对象public ArrayList<Enemy> eneryList = new ArrayList<Enemy>();//定义一个集合容器装子弹public ArrayList<Boom> boomList = new ArrayList<Boom>();//子弹的速度public int bspeed=0;//地图数据,制定规则,是1画砖头,是2画金币,是3画水管public int[][] map = null;//对象代码块: 当前类的创建的时候执行{// 实例代码块中初始化地图资源的数据GameMap mp = new GameMap();map = mp.readMap();}//构造函数里面初始化背景图片和马里奥对象public GameFrame() throws Exception {// 创建背景图片bg = new BackgroundImage();//初始化窗体相关属性信息数据// this代表了当前主界面对象。this.setSize(800,450);this.setTitle("超级玛丽");this.setResizable(true);// 居中展示窗口this.setLocationRelativeTo(null);this.setDefaultCloseOperation(EXIT_ON_CLOSE);this.setVisible(true);// 创建玛丽对象mario = new Mario(this);// 读取地图,并配置地图for (int i = 0; i < map.length; i++) {for (int j = 0; j < map[0].length; j++) {//读取到的是1,画砖头if(map[i][j]==1){// xbrick = new Brick(j*30,i*30,30,30,new ImageIcon("image/brick.png").getImage());eneryList.add(brick);}//读到2画金币if(map[i][j]==2){coin = new Coin(j*30,i*30,30,30,new ImageIcon("image/coin_brick.png").getImage());eneryList.add(coin);}//读到3画水管if(map[i][j]==3){pipe = new Pipe(j*30,i*30,60,120,new ImageIcon("image/pipe.png").getImage());eneryList.add(pipe);}}}mario.start();//开启一个线程负责界面的窗体重绘线程new Thread(){public void run(){while(true){//重绘窗体repaint(); // 自动触发当前窗口中的paint方法//检查子弹是否出界//checkBoom();try {Thread.sleep(10);} catch (InterruptedException e) {e.printStackTrace();}}}}.start();//设置背景音乐new Thread(new Runnable() {@Overridepublic void run() {MusicUtil.playBackground();}}).start();}/*** 画窗体* @param g*/@Overridepublic void paint(Graphics g) {//利用双缓冲画背景图片和马里奥BufferedImage bi =(BufferedImage)this.createImage(this.getSize().width,this.getSize().height);//创建画图对象Graphics big = bi.getGraphics();//画背景big.drawImage(bg.img, bg.x, bg.y, null);// 开始绘制界面上的敌人。for (int i = 0; i < eneryList.size(); i++) {Enemy e = eneryList.get(i);//绘制敌人big.drawImage(e.img, e.x, e.y, e.width, e.height,null);}//画子弹for (int i = 0; i < boomList.size(); i++) {Boom b =boomList.get(i);Color c =big.getColor();big.setColor(Color.red);big.fillOval(b.x+=b.speed, b.y, b.width, b.width);big.setColor(c);}//画人物 玛丽自己big.drawImage(mario.img, mario.x, mario.y, mario.width, mario.height,null);g.drawImage(bi,0,0,null);}//检查子弹是否出界,出界则从容器中移除,不移除的话,内存会泄漏public void checkBoom(){for (int i = 0; i < boomList.size(); i++) {Boom b = boomList.get(i);if(b.x<0 || b.x>800){boomList.remove(i);}}}
}

 键盘事件监听

package cn.tx.util;import cn.tx.role.Boom;
import cn.tx.ui.GameFrame;import java.awt.event.KeyAdapter;
import java.awt.event.KeyEvent;import javax.swing.ImageIcon;//键盘按下监听类
public class KeyListener extends KeyAdapter {// 接收到了当前主界面:游戏界面public GameFrame gf;public KeyListener(GameFrame gf) {this.gf = gf;}//键盘监听@Overridepublic void keyPressed(KeyEvent e) {//code是按下键盘的键对应的值int code = e.getKeyCode();switch (code) {//向右走case 39:gf.mario.right = true; // 信号位break;//向左走case 37:gf.mario.left = true;break;case 66:addBoom();break;//向上跳case 38:gf.mario.up = true;break;}}//添加子弹public void addBoom() {Boom b = new Boom(gf.mario.x, gf.mario.y + 5, 10);if (gf.mario.left) b.speed = -2;if (gf.mario.right) b.speed = 2;gf.boomList.add(b);}//键盘释放监听@Overridepublic void keyReleased(KeyEvent e) {int code = e.getKeyCode();//释放右键if (code == 39) {gf.mario.right = false;gf.mario.img = new ImageIcon("image/mari1.png").getImage();}//释放左键if (code == 37) {gf.mario.left = false;gf.mario.img = new ImageIcon("image/mari_left1.png").getImage();}//释放上键if (code == 38) {gf.mario.up = false;}}
}

 

主方法和事件绑定

import cn.tx.ui.GameFrame;
import cn.tx.util.KeyListener;
/**超级玛丽启动类。*/
public class Run {//主函数,程序入口public static void main(String[] args) throws Exception {GameFrame gf = new GameFrame();// 创建监听器对象KeyListener kl = new KeyListener(gf);// 给窗体添加键盘监听器gf.addKeyListener(kl);}
}

完整源码和讲解QQ加群:685168267


http://www.ppmy.cn/news/889245.html

相关文章

1751 - 快乐的马里奥

马里奥是一个快乐的油漆工人&#xff0c;这天他接到了一个油漆任务&#xff0c;要求马里奥把一个 nn 行 mm 列的矩阵每一格都用油漆标记一个数字&#xff0c;标记的顺序按照广度优先搜索的方式进行&#xff0c;也就是他会按照如下方式标记&#xff1a; 1、首先标记第 11 行第 …

FZU 2234 牧场物语(dp 好题)

Problem 2234 牧场物语 Accept: 95 Submit: 434 Time Limit: 1000 mSec Memory Limit : 32768 KB Problem Description 小茗同学正在玩牧场物语。该游戏的地图可看成一个边长为n的正方形。 小茗同学突然心血来潮要去砍树&#xff0c;然而&#xff0c;斧头在小茗的右下方。…

计算机游戏155,MAME0.155经典1430款游戏合集

MAME0.155经典1430款游戏合集本合集收录了MAME自1984至2008年间已模拟的几乎所有经典游戏&#xff0c;共1430款&#xff0c;而且基本只收录了游戏的一个版本&#xff0c;也就是剔除了克隆&#xff0c;以达到最大的精简(当然一些必要的克隆还是会保留的&#xff0c;一般都是和原…

《巧克甜恋》官方中文版全解锁存档分享

因为之前修复更新英文版后补丁失效的问题一不小心把存档删了&#xff0c;遂意识到了存档的重要性&#xff0c;也特此分享给需要的朋友。 全解锁存档下载

二次元页游《幻想物语》全套源码+资源+工具(可转H5手游)

二次元页游《幻想物语》全套源码资源工具&#xff08;可转H5手游&#xff09; 代码非常齐全&#xff0c;包含前后端源码和合服工具、管理后台 包含全部资源和SQL 前端AS&#xff0c;后端C GM工具PHP 源码下载 二次元页游《幻想物语》全套源码资源工具&#xff08;可转H5手游&a…

JAVA 实现《超级玛丽升级版》游戏

前言 超级玛丽这款游戏是很多人童年经典的回忆&#xff0c;是一种简单的大众的游戏&#xff0c;自从计算机实现以来&#xff0c;深受广大电脑玩家的喜爱。并且随着社会的快速发展&#xff0c;人们的生活节奏越来越快&#xff0c;人们对于童年的美好已经不愿意仅仅停留在回忆阶…

发现一个优秀的Java版国人仿曹操传游戏

终于又看见有国人用Java写J2ME以外的游戏了,先让偶们一起为作者的开创精神而叫声好吧! 该作者博客如下:http://www.cnblogs.com/egria ,http://salin.javaeye.com/ 以下为引用作者原文: ————————————————————————————————————…

HTML <menu> 标签

实例 带有两个菜单按钮 ("File" 和 "Edit") 的工具栏,每个按钮都包含带有一系列选项的下拉列表: <menu type="toolbar"><li><menu label="File"><button type="button" οnclick="file_new…