前言
超级玛丽这款游戏是很多人童年经典的回忆,是一种简单的大众的游戏,自从计算机实现以来,深受广大电脑玩家的喜爱。并且随着社会的快速发展,人们的生活节奏越来越快,人们对于童年的美好已经不愿意仅仅停留在回忆阶段。
《超级玛丽升级版》游戏是用java语言实现,采用了swing技术进行了界面化处理,设计思路用了面向对象思想。
主要设计
功能主要设计
本系统主要是完成超级玛丽游戏的基本操作。本系统需要满足以下几点要求:
(1) 在开始界面按空格键进入游戏。
(2) 利用方向键来控制马里奥的运动。
(3) 碰撞检测:
A.马里奥在运动的过程中如果碰到障碍物则停止运动,在移动到悬崖上方是会掉下去,并失去一条生命。
B.对于有些敌人,如果马里奥跳到敌人头顶上,则敌人消失,否则马里奥失去一条生命。
(4)马里奥顶到金币会增加分数,当马里奥失去3条生命时游戏结束。
界面主要设计
-
选取和谐Q版的图片,使画面色彩和谐自然。
-
固定游戏界面大小与初始显示位置。
-
游戏采用900600像素显示,对于马里奥和障碍物选用6060像素
的正方图片,对于较大的障碍物分割成多个60*60的小正方形。
功能截图
游戏开始:
马里奥的控制移动
马里奥与障碍物进行碰撞
当马里奥失去所有的生命以后,游戏结束
关卡图
大悬崖场景:
场景借鉴了魂斗罗
为了提升游戏的可玩性,加了一个隐藏的过关要点
代码实现
马里奥类
public class Mario implements Runnable{
//坐标
private int x;
private int y;
//定义玛丽奥所在场景
private BackGround bg;
//加入线程
private Thread t = null;
//移动速度e
private int xmove = 0;
//跳跃速度
private int ymove = 0;
//状态
private String status;
//显示图片
private BufferedImage showImage;
//生命和分数
private int score;
private int life;
//当前移动中的图片
private int moving = 0;
//跳跃时间
private int upTime = 0;
//标记玛丽奥是否死亡
private boolean isDead = false;
//完成游戏,游戏结束
private boolean isClear = false;
//构造方法
public Mario(int x,int y){
this.x = x;
this.y = y;
//初始化玛丽奥图片
this.showImage = StaticValue.allMarioImage.get(0);
this.score = 0;
this.life = 3;
this.t = new Thread(this);
t.start();
this.status = "right-standing";
}
public void leftMove(){
//移动速度
xmove = -5;
//改变状态
//如果当前已经是跳跃,应该保持原有状态,不能再改变
if(this.status.indexOf("jumping") != -1){
this.status = "left-jumping";
}else{
this.status = "left-moving";
}
}
public void rightMove(){
xmove = 5;
if(this.status.indexOf("jumping") != -1){
this.status = "right-jumping";
}else{
this.status = "right-moving";
}
}
public void leftStop(){
this.xmove = 0;
if(this.status.indexOf("jumping") != -1){
this.status = "left-jumping";
}else{
this.status = "left-standing";
}
}
public void rightStop(){
this.xmove = 0;
if(this.status.indexOf("jumping") != -1){
this.status = "right-jumping";
}else{
this.status = "right-standing";
}
}
public void jump(){
if(this.status.indexOf("jumping") == -1){
if(this.status.indexOf("left") != -1){
this.status = "left-jumping";
}else{
this.status = "right-jumping";
}
ymove = -10;
upTime = 18;
}
}
//下落方法
public void down(){
if(this.status.indexOf("left") != -1){
this.status = "left-jumping";
}else{
this.status = "right-jumping";
}
ymove = 10;
}
//死亡方法
public void dead(){
this.life--;
if(this.life == 0){
this.isDead = true;
}else{
this.bg.reset();
this.x = 0;
this.y = 480;
}
}
public int getX() {
return x;
}
public int getY() {
return y;
}
public BufferedImage getShowImage() {
return showImage;
}
public void run() {
while(true){
//判断是否与障碍物碰撞
//定义标记
if(this.bg.isFlag() && this.x >= 520){
this.bg.setOver(true);
if(this.bg.isDown()){
//降旗后玛丽奥开始移
this.status = "right-moving";
if(this.x < 580){
//向右
this.x += 5;
}else{
if(this.y < 480){
//向下
this.y += 5;
}
this.x += 5;
if(this.x >= 780){
//游戏结束
this.setClear(true);
}
}
}else{
//如果为最后一个场景,同事Mario的x坐标到了550,游戏结束
//自动控制玛丽奥
if(this.y < 420){
this.y += 5;
}
if(this.y >= 420){
this.y = 420;
this.status = "right-standing";
}
}
}else{
boolean canLeft = true;
boolean canRight = true;
//能否跳跃标记
boolean onLand = false;
for(int i=0;i<this.bg.getAllObstruction().size();i++){
Obstruction ob = this.bg.getAllObstruction().get(i);
//不能向右移动
if(ob.getX()==this.x+60 && (ob.getY()+50>this.y && ob.getY()-50<this.y)){
if(ob.getType() != 3){
canRight = false;
}
}
//不能向左移动
if(ob.getX()==this.x-60 && (ob.getY()+50>this.y && ob.getY()-50<this.y)){
if(ob.getType() != 3){
canLeft = false;
}
}
//判断能否跳跃
if(ob.getY()==this.y+60 && (ob.getX()+60>this.x && ob.getX()-60<this.x)){
if(ob.getType() != 3){
onLand = true;
}
}
//判断玛丽奥跳跃时是否撞到障碍物
if(ob.getY()==this.y-60 && (ob.getX()+50>this.x && ob.getX()-50<this.x)){
//如果是砖块
if(ob.getType()==0){
//移除砖块
this.bg.getAllObstruction().remove(ob);
//保存到移除的障碍物中
this.bg.getRemoveObstruction().add(ob);
}
//如果是问号||隐藏的砖块
if((ob.getType()==4 || ob.getType()==3) && upTime > 0){
//增加分数
score += 10;
ob.setType(2);
ob.setImage();
}
upTime = 0;
}
}
//对敌人的判断
for(int i=0;i<this.bg.getAllEnemy().size();i++){
Enemy e = this.bg.getAllEnemy().get(i);
if((e.getX()+50>this.x && e.getX()-50<this.x) && (e.getY()+60>this.y && e.getY()-60<this.y)){
//玛丽奥死亡
this.dead();
}
if(e.getY()==this.y+60 && (e.getX()+60>this.x && e.getX()-60<this.x)){
if(e.getType() == 1){
e.dead();
this.upTime = 5;
this.ymove = -10;
//敌人死亡,增加分数
score += 10;
}else if(e.getType() == 2){
this.dead();
}
}
}
if(onLand && upTime == 0){
if(this.status.indexOf("left") != -1){
if(xmove != 0){
this.status = "left-moving";
}else{
this.status = "left-standing";
}
}else{
if(xmove != 0){
this.status = "right-moving";
}else{
this.status = "right-standing";
}
}
}else{
//上升状态
if(upTime != 0){
upTime--;
}else{
this.down();
}
y += ymove;
}
if(this.y>600){
this.dead();
}
if(canLeft && xmove<0 || canRight && xmove>0){
x += xmove;
if(x<0){
x = 0;
}
}
}
//默认向右
int temp = 0;
//向左状态
if(this.status.indexOf("left") != -1){
temp += 5;
}
//判断是否移动
if(this.status.indexOf("moving") != -1){
temp += this.moving;
moving++;
if(moving==4){
this.moving = 0;
}
}
if(this.status.indexOf("jumping") != -1){
temp += 4;
}
//改变显示图片
this.showImage = StaticValue.allMarioImage.get(temp);
try {
Thread.sleep(50);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
public void setBg(BackGround bg) {
this.bg = bg;
}
public void setX(int x) {
this.x = x;
}
public void setY(int y) {
this.y = y;
}
public boolean isDead() {
return isDead;
}
public int getScore() {
return score;
}
public void setScore(int score) {
this.score = score;
}
public int getLife() {
return life;
}
public void setLife(int life) {
this.life = life;
}
public boolean isClear() {
return isClear;
}
public void setClear(boolean isClear) {
this.isClear = isClear;
}
}
马里奥
小怪
public class Enemy implements Runnable{
//坐标
private int x;
private int y;
//初始坐标
private int startx;
private int starty;
//怪物类型
private int type;
//显示图片
private BufferedImage showImage;
//移动方向
private boolean isLeftOrUp = true;
//移动范围
private int upMax = 0;
private int downMax = 0;
//加入线程
private Thread t = null;
//定义图片变化
private int imageType = 0;
//定义所在场景
private BackGround bg ;
//蘑菇怪
public Enemy(int x,int y,boolean isLeft,int type,BackGround bg){
this.x = x;
this.y = y;
this.startx = x;
this.starty = y;
this.isLeftOrUp = isLeft;
this.type = type;
this.bg = bg;
if(type==1){
this.showImage = StaticValue.allTriangleImage.get(0);
}
this.t = new Thread(this);
t.start();
t.suspend();
}
//食人花
public Enemy(int x,int y,boolean isUp,int type,int upMax,int downMax,BackGround bg){
this.x = x;
this.y = y;
this.startx = x;
this.starty = y;
this.isLeftOrUp = isUp;
this.type = type;
this.upMax = upMax;
this.downMax = downMax;
this.bg = bg;
if(type==2){
this.showImage = StaticValue.allFlowerImage.get(0);
}
this.t = new Thread(this);
t.start();
t.suspend();
}
public void run() {
while(true){
//判断怪物类型
if(type==1){
if(this.isLeftOrUp){
this.x -= 5;
}else{
this.x += 5;
}
if(imageType==0){
imageType = 1;
}else{
imageType = 0;
}
//定义标记
boolean canLeft = true;
boolean canRight = true;
for(int i=0;i<this.bg.getAllObstruction().size();i++){
Obstruction ob = this.bg.getAllObstruction().get(i);
//不能向右移动
if(ob.getX()==this.x+60 && (ob.getY()+50>this.y && ob.getY()-50<this.y)){
canRight = false;
}
//不能向左移动
if(ob.getX()==this.x-60 && (ob.getY()+50>this.y && ob.getY()-50<this.y)){
canLeft = false;
}
}
if(!canLeft && this.isLeftOrUp || this.x == 0){
this.isLeftOrUp = false;
}else if(!canRight && !this.isLeftOrUp || this.x == 840){
this.isLeftOrUp = true;
}
this.showImage = StaticValue.allTriangleImage.get(imageType);
}
if(type==2){
if(this.isLeftOrUp){
this.y -=5;
}else{
this.y +=5;
}
if(imageType==0){
imageType = 1;
}else{
imageType = 0;
}
if(this.isLeftOrUp && this.y == this.upMax){
this.isLeftOrUp = false;
}
if(!this.isLeftOrUp && this.y == this.downMax){
this.isLeftOrUp = true;
}
this.showImage = StaticValue.allFlowerImage.get(imageType);
}
try {
Thread.sleep(100);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
public void reset(){
//还原坐标
this.x = this.startx;
this.y = this.starty;
//还原图片
if(this.type == 1){
this.showImage = StaticValue.allTriangleImage.get(0);
}else if(this.type == 2){
this.showImage = StaticValue.allFlowerImage.get(0);
}
}
public void dead(){
//死亡图片
this.showImage = StaticValue.allTriangleImage.get(2);
this.bg.getAllEnemy().remove(this);
this.bg.getRemoveEnemy().add(this);
}
public int getX() {
return x;
}
public int getY() {
return y;
}
public BufferedImage getShowImage() {
return showImage;
}
public void setBg(BackGround bg) {
this.bg = bg;
}
public int getType() {
return type;
}
public void startMove(){
t.resume();
}
}
总结
通过此次的《超级玛丽升级版》游戏实现,让我对JAVA的相关知识有了进一步的了解,对java这门语言也有了比以前更深刻的认识。
java的一些基本语法,比如数据类型、运算符、程序流程控制和数组等,理解更加透彻。java最核心的核心就是面向对象思想,对于这一个概念,终于悟到了一些。
源码获取
点赞,关注博主后,私聊博主免费获取
需要技术指导,写项目程序,等更多服务请联系博主
今天是持续写作的第 28 / 100 天。
可以关注我,点赞我、评论我、收藏我啦。