Java小程序之山寨版超级玛丽
一、游戏基本功能
1、能够向左向右行走(键盘监听)
2、能够跳跃
3、能够发射子弹
4、能够检测和障碍物之间的碰撞
5、背景图片的移动
二、游戏运行界面
三、游戏大致实现思路:
1.窗体
2.自己角色的添加
3.背景图片的添加
4.背景图片的移动
5.人物的移动和跳跃
6.砖头、水管等等障碍物的添加
7.任务和障碍物的碰撞
难点分析:
1.人物的多键控制
1)给人物设定方向boolean变量:向左、向右、向上、向下
2)通过键盘监听来修改方向的变量值
      按下某个键的时候,我们把相应方向改为true,释放的时候改false

2.地图配置
自定义文件读取方式实现:文件流的使用和字符串String类的方法调用

3.碰撞检测
封装一个Rectangle类的对象

4.子弹添加
1)先定义一个容器,这个用于封装所有的子弹对象
2)按下某个键的时候,创建一个子弹对象(以角色的坐标为基准初始化)
3)把子弹对象添加到容器当中
4)在paint方法中,遍历容器,取出子弹对象并进行绘制

5)检测子弹如果超出了窗体边界,则需要把当前子弹从容器当中移除掉
四、程序源代码:
代码结构图:分了三个包、敌人类包、游戏界面类包、游戏地图配置包
com.huaxin.mario包:
package com.huaxin.mario;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 com.huaxin.enery.Enery;
import com.huaxin.enery.Pipe;import Util.Map;public class GameFrame extends JFrame{public Mario mario;public Enery pipe,cion,brick;//背景图片public BackgroundImage bg ;//容器装敌人public ArrayList<Enery> eneryList = new ArrayList<Enery>();//子弹容器public ArrayList<Boom> boomList = new ArrayList<Boom>();//子弹的速度public int bspeed=0;//画地图,制定规则,是1画砖头,是2画金币,是3画水管public int [][] map =null;//构造函数里面初始化背景图片和马里奥对象public GameFrame() throws Exception {mario = new Mario(this);mario.start();Map mp= new Map();bg = new BackgroundImage();//窗体重绘线程new Thread(){public void run(){while(true){//重绘窗体repaint();//检查子弹是否出界checkBoom();try {Thread.sleep(10);} catch (InterruptedException e) {e.printStackTrace();}}}}.start();map=mp.readMap();//读取地图,并配置地图for (int i = 0; i < map.length; i++) {for (int j = 0; j < map[0].length; j++) {//读取到的是1,画砖头if(map[i][j]==1){brick = new Pipe(j*30,i*30,30,30,new ImageIcon("image/brick.png").getImage());eneryList.add(brick);}//读到2画金币if(map[i][j]==2){cion = new Pipe(j*30,i*30,30,30,new ImageIcon("image/coin_brick.png").getImage());eneryList.add(cion);}//读到3画水管if(map[i][j]==3){pipe = new Pipe(j*30,i*30,60,120,new ImageIcon("image/pipe.png").getImage());eneryList.add(pipe);}}}//设置背景音乐com.huaxin.music.Util.startMusic("music/bg1.wav");}public void initFrame(){//设置窗体相关属性this.setSize(800,450);this.setTitle("山寨版超级玛丽");this.setResizable(false);this.setLocationRelativeTo(null);this.setDefaultCloseOperation(3);this.setVisible(true);//该窗体添加键盘监听KeyListener kl = new KeyListener(this);this.addKeyListener(kl);}public 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++) {Enery 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 com.huaxin.mario;import java.awt.Image;
import java.awt.Rectangle;import javax.swing.ImageIcon;import com.huaxin.enery.Enery;//自己的角色类
public class Mario extends Thread{public GameFrame gf;public boolean jumpFlag=true;//马里奥的坐标public int x=0,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();}if(this.x>=400){//背景向左移动gf.bg.x-=this.xspeed;//障碍物项左移动for (int i = 0; i <gf.eneryList.size(); i++) {Enery 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++) {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++) {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){Rectangle myrect = new Rectangle(this.x,this.y,this.width,this.height);Rectangle rect =null;for (int i = 0; i < gf.eneryList.size(); i++) {Enery 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();}if(!jumpFlag){}while(true){if(!jumpFlag){break;}if(hit(Dir_Down)){break;}if(y>=358){isGravity=false;}else{isGravity=true;y+=yspeed;}try {sleep(10);} catch (InterruptedException e) {e.printStackTrace();}}}}}.start();}
}
package com.huaxin.mario;import java.awt.event.KeyAdapter;
import java.awt.event.KeyEvent;import javax.swing.ImageIcon;//键盘按下监听类
public class KeyListener extends KeyAdapter{public GameFrame gf;public boolean jumpFlag=true;public KeyListener(GameFrame gf) {this.gf=gf;}//键盘监听public void keyPressed(KeyEvent e) {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 74: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);}//键盘释放监听public 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==74){gf.mario.up=false;}}}
package com.huaxin.mario;import java.awt.Image;import javax.swing.ImageIcon;public class BackgroundImage {public int x=0,y=0;public int ox=0,oy=0;public Image img=new ImageIcon("image/startBack.jpg").getImage();}
package com.huaxin.mario;//子弹类
public class Boom {//子弹的坐标,大小,速度int x,y;int width;int speed=1;public Boom(int x, int y, int width) {super();this.x = x;this.y = y;this.width = width;}}
主函数类,作为整个程序的入口
package com.huaxin.mario;public class Test {//主函数,程序入口public static void main(String[] args) throws Exception {GameFrame gf = new GameFrame();gf.initFrame();}
}
com.huaxin.enery包:
package com.huaxin.enery;import java.awt.Image;//障碍物的抽象父类
public abstract class Enery {public int x,y;public int width,height;public Image img;public Enery(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 com.huaxin.enery;import java.awt.Image;//金币类
public class Coin extends Enery{public Coin(int x, int y, int width, int height, Image img) {super(x, y, width, height, img);}}
package com.huaxin.enery;import java.awt.Image;//砖头类
public class Brick extends Enery {public Brick(int x, int y, int width, int height, Image img) {super(x, y, width, height, img);}
}
package com.huaxin.enery;import java.awt.Image;//水管类
public class Pipe extends Enery {public Pipe(int x, int y, int width, int height, Image img) {super(x, y, width, height, img);}
}
com.huaxin.util包:
package Util;import java.io.BufferedReader;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.InputStreamReader;
import java.util.ArrayList;//地图配置类
public class Map {//数据容器public ArrayList<String> list = new ArrayList<String>();public int [][] map=null;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;}}
五、项目总结:
这个小项目看起来挺简单的,其实里面也有很多功能需要仔细去思考的,以前觉得游戏人物在窗体走的时候,觉得一直是人在走,其实,人物走到中间或者走到某一位置的时候,人物已经是在原地踏步了,取而代之的是背后那张长度很长的背景的图片在移动,任务的左右移动相对而言比较简答实现,跳跃功能就不是那么简单了,需要永达线程,跟后面障碍物碰撞检测又有关系,当没有碰到的时候,人物要往下掉,一不注意就会出现各种bug,比如,可以一直跳,在跳的同时还能再跳,还有就是下降可能不会落地面的同一高度,可能会高于地面的高度,可能会低于地面的高度;障碍物的添加,我们是通过配置地图的方式,配置地图有时通过读入文件的操作,大致的原理是将后面的那张的背景图片划分成很多的小格子,将这些小格子用代码转换为二位数组,二维数组可以存入不同数字,代表不同的障碍物,通过操作文件就可以轻易配置地图;首先通过文件输入流将文件数据读入,将字符转换为数字,并存储在二维数组中,后面,通过遍历二维数组的不同位置的值,在相应的格子填充相应的障碍物;地图就这样配置好了;
觉得配地图很炫酷,因为以前有位学长在演示的时候,觉得好难,现在自己掌握了觉得也不是很难了,当然了,这里离不开老师的指导;碰撞检测类似之前小球的碰撞检测,这里主要需要处理碰撞之后的一些逻辑,如何避免一直碰撞(人物贴着障碍物不能动)等;发射子弹的话,也比较简单了,利用容器装子弹,不过需要注意的是要及时将容器中子弹移除,不然内存会很快被吃完的;
写程序,一定要按照思路一步一步来,一点一点来实现!不要太过急于求成!以前老想着自己做一个小东西出来,可是自己总是很急,希望很快做出来,结果,思路没有理清,写起来一团糟!前车之鉴!
好了,就先写到这吧!共勉!
最近很多人问我要源代码:于是乎就把源代码上传到了CSDN的资源中,下面是下载链接;不需要积分;
希望可以帮到想要学习这个游戏的朋友;
山寨版超级玛丽源代码下载

Java小程序之山寨版超级玛丽相关推荐

  1. java 获取文件所在的文件夹_带你0基础编写一个Java小程序,领略Java程序从编写到编译再到运行的全流程...

    在学习Java之前我们需要先认识下什么是计算机语言?计算机语言又有哪些分类?在了解这些后对我们理解学习帮助是很大的. 要知道计算机语言是人与计算机之间进行信息交流沟通的一种特殊语言,又分为机械语言.汇 ...

  2. java小程序之学生信息_java小程序之学生信息录入界面

    小程序我的项目下载链接:点击打开链接 因为这学期比赛太多,蓝桥杯,团体程序设计大赛,ACM省赛等原因基本这学期的课程都没上,比赛完后开始去上课,java老师让用java写一个学生信息录入界面,把界面中 ...

  3. 【开发日常】【Java】Java小程序汽车租赁

    <Java小程序--汽车租赁> 1.描述:刚学Java写的小程序,用到类的继承,多态,abstract抽象方法. 2.工具:eclipse.exe 3.功能:选择子类(轿车 / 客车) 选 ...

  4. Wifi热点java_用笔记本电脑开启热点Java小程序

    用笔记本电脑开启热点Java小程序是一条命令设置笔记本成无线热点, 制作"开启无线热点工具,这个小工具实际上是用java来执行cmd命令来完成操作,当然也可以反射jar里边的字节码文件. 使 ...

  5. 简单Java小程序----有界面ATM机

    继<简单Java小程序---无界面ATM机>以后,尝试对有界面ATM机改写,对面向对象的了解又深了一层! 桌面的创建过程       由于使用的NetBean软件没有提供专用的控件拖拽使用 ...

  6. java小程序_Java小程序

    java小程序 An applet is a special kind of Java program that runs in a Java enabled browser. This is the ...

  7. 3.每天一个java小程序之累加累乘

    3.每天一个java小程序之累加累乘 java小练习之数的累加累乘,在于锻炼数学计算思维. 每天一个小程序,每天进步一点点. 代码如下: package com.zou; import java.ut ...

  8. 基于Bluemix快速构建部署一款Java小程序——微博影响力分析器

    一.前言 近年来IT界风云际会,各种新概念如大数据.云平台.虚拟化等,如雨后春笋般层出不穷.而云平台,可以说是近些年来引领时代新潮的边缘概念之一,各大厂商竞相推出各种云产品,抢占云市场高地.近期,IT ...

  9. dw网页插入java小程序_DW网页设计100例35:构建Java插入模块

    Java 是一种程序设计语言, Java applet ( Java 小程序)是在 Java 的基础上演变而成的.能够嵌入在网页中的.可以执行一定小任务的应用程序. 20060407140110aa1 ...

  10. dw网页插入java小程序_DW网页设计35:构建Java插入模块

    Java 是一种程序设计语言, Java applet ( Java 小程序)是在 Java 的基础上演变而成的.能够嵌入在网页中的.可以执行一定小任务的应用程序. 效果说明建立文件,以 Java 计 ...

最新文章

  1. 在Blender中制作火箭发射烟雾和火焰模拟的动画
  2. AI 学习之路——轻松初探 Python 篇(一)
  3. 快乐数(双指针,哈希表)
  4. python文件运行哪一个_如何使一个python文件运行另一个?
  5. hive 中某个字段等于0_快速了解hive
  6. X-Frame-Options 配置
  7. idea构建spring源码环境
  8. mysql8.0.11创建用户报错_mysql8.0.11修改root密码,其他创建用户和删除用户
  9. 跑了10千米,再一次伤了膝盖
  10. git commit规范工具
  11. 怎样打开android设备,在app中打开android设备的存储
  12. 2014行业软件最新列表整理展示
  13. 我用Python写了一个做题软件控制台版。(支持Mod)
  14. 2020 年前端技术发展盘点
  15. 微信小程序获取服务器当前时间,微信小程序服务器日期格式化问题
  16. 教你联想一体机win7系统安装教程
  17. 计算机出现假桌面怎么解决办法,win10桌面因为AppHangXProcB1一直出现假死的有效修复技巧...
  18. 王者战力接口(免费),附接口文档+小程序源码
  19. c语言课程成绩分析报告范文,c语言课程分析报告题目.doc
  20. SpringBoot官方开发工具,热部署和远程调试真带劲

热门文章

  1. Linux面试题,浅析常见Linux命令面试题及答案
  2. LeetCode答案大全题(java版)
  3. 关于软件实施经验分享
  4. 飞信2016 5.6.8820.0超级精简版
  5. SaaSBase:什么是数云麒麟CRM?
  6. bcc语料库下载_CCL语料库与BCC语料库各自的特点是什么?
  7. 西南科技大学OJ题 顺序栈基本操作的实现1044
  8. ArcMAP栅格数据裁剪小技巧
  9. 多元统计分析主成分分析何晓群版课后作业
  10. matlab只加盐噪声,我用matlab中的imnoise函数给图像加椒盐噪声为什么产生的噪声不是黑白的?...