Java版简单版马里奥游戏
马里奥类
import java.awt.image.BufferedImage;
public class Mario implements Runnable { // implements Runnable
// Runnable
// 定义MyRunnable类实现Runnable接口。
// 实现run()方法,编写线程执行体。
// 创建线程对象,调用start()方法启动线程。
// 提示:推荐使用Runnable对象,因为Java单继承的局限性
private int x; // 用于表示坐标
private int y;
private String status; // 用于表示当前状态
private BufferedImage show = null; // 用于显示当前状态对应的图像
private BackGround backGround = new BackGround(); // 用于获取当前障碍物的信息
private Thread thread = null; // 用来实现马里奥的动作
private int xSpeed; // 马里奥的移动速度
private int ySpeed; // 马里奥的跳跃速度
private int index; // 索引
private int upTime = 0; // 表示马里奥的上跳时间
private boolean isOK; // 用于判断马里奥是否走到了城堡的门口
private boolean isDeath = false; // 用于判断马里奥是否死亡
private int score = 0; // 表示分数
public Mario() {
}
public Mario(int x, int y) {
this.x = x;
this.y = y;
show = StaticValue.stand_r; // 初始化马里奥图片一开始是向右站着的
this.status = "stand--right";
thread = new Thread(this); // 初始化线程
thread.start(); // 开始线程
}
public void death() {
isDeath = true;
}
public void leftMove() { // 马里奥向左移动的方法
xSpeed = -5; // 改变速度
if (backGround.isReach()) {// 判断马里奥是否碰到旗子
xSpeed = 0;
}
if (status.indexOf("jump") != -1) { // 判断是不是处于空中 //-1为地面
status = "jump--left"; // 处于空中
} else {
status = "move--left"; // 向左移动
}
}
public void rightMove() { // 马里奥向右移动的方法
xSpeed = 5;
if (backGround.isReach()) { // 判断马里奥是否碰到旗子
xSpeed = 0;
}
if (status.indexOf("jump") != -1) {
status = "jump--right";
} else {
status = "move--right";
}
}
public void leftStop() { // 马里奥向左停止的方法
xSpeed = 0;
if (status.indexOf("jump") != -1) {
status = "jump--left";
} else {
status = "stop--left";
}
}
public void rightStop() { // 马里奥向右停止的方法
xSpeed = 0;
if (status.indexOf("jump") != -1) {
status = "jump--right";
} else {
status = "stop--right";
}
}
public void jump() { // 马里奥跳跃的方法
if (status.indexOf("jump") == -1) { // 如果为-1这个时候不是跳跃状态
if (status.indexOf("left") != -1) { // !=-1这个时候是向左
status = "jump--left";
} else {
status = "jump--right";
}
ySpeed = -10; // 向上跳速度减少
upTime = 7; // 跳跃高度为70
}
if (backGround.isReach()) { // 判断马里奥是否碰到旗子
ySpeed = 0;
}
}
public void fall() { // 下落的方法
// 马里奥下落不一定是跳起来下落,也有可能是从障碍物上落下,所以不用判断当前是否为跳跃状态
if (status.indexOf("left") != -1) { // 所以判断方向就好
status = "jump--left";
} else {
status = "jump--right";
}
ySpeed = 10;
}
@Override // 创建线程方式二:实现Runnable接口,重写run方法,执行线程需要丢入Runnable接口实现类,调用start方法
public void run() { // 用于线程
while (true) {
boolean onObstacle = false; // 判断是否处于障碍物上
boolean canRight = true; // 判断是否可以往右走
boolean canLeft = true; // 判断是否可以往左走
if (backGround.isFlag() && this.x >= 500) { // 判断马里奥是否到达旗杆的位置
this.backGround.setReach(true);
if (this.backGround.isBase()) { // 判断旗子是否下落完成
status = "move--right";
if (x < 690) { // 是否移动到城堡那里
x += 5; // 没有每次加速5
} else {
isOK = true;
}
} else {
if (y < 395) { // 判断马里奥是否空中
xSpeed = 0;
this.y += 5; // 下落的速度
status = "jump--right"; // 改变状态
}
if (y > 395) { // 到达地面不能再下落
this.y = 395;
status = "stop--right"; // 改变状态
}
}
} else {
for (int i = 0; i < backGround.getObstacleList().size(); i++) {// 遍历当前场景的里所有的障碍物
Obstacle ob = backGround.getObstacleList().get(i);
// 这是人物位于障碍物上方的情况
if (ob.getY() == this.y + 25 && (ob.getX() > this.x - 30 && ob.getX() < this.x + 25)) { // 判断马里奥是否在障碍物上,这个是给出的临界值
onObstacle = true;
}
// 这是人物位于障碍物下方的情况
if ((ob.getY() >= this.y - 30 && ob.getY() <= this.y - 20)
&& (ob.getX() > this.x - 30 && ob.getX() < this.x + 25)) { // 判断是否跳起来顶到砖块
if (ob.getType() == 0) { // 如果是普通砖块被顶到,移除
backGround.getObstacleList().remove(ob);
score += 1; // 碰到就加分
}
upTime = 0; // 为了实现顶到砖块后立刻下落
}
// 这是人物位于障碍物左方的情况
if (ob.getX() == this.x + 25 && (ob.getY() > this.y - 30 && ob.getY() < this.y + 25)) {
canRight = false; // 不能向右走
}
// 这是人物位于障碍物右方的情况 //判断是否可以往左走
if (ob.getX() == this.x - 30 && (ob.getY() > this.y - 30 && ob.getY() < this.y + 25)) {
canLeft = false; // 不能向左走
}
}
for (int i = 0; i < backGround.getEmemyList().size(); i++) { // 判断马里奥是否碰到敌人死亡或者踩死蘑菇敌人
Enemy e = backGround.getEmemyList().get(i);
if (e.getY() == this.y + 20 && (e.getX() - 25 <= this.x && e.getX() + 35 >= this.x)) {
if (e.getType() == 1) {
e.death(); // 踩到就死
score += 2;
upTime = 3; // 马里奥上升一段时间
ySpeed = -10;
} else if (e.getType() == 2) { // 碰到食人花,马里奥死亡
death();
}
}
if ((e.getX() + 35 > this.x && e.getX() - 25 < this.x)
&& (e.getY() + 35 > this.y && e.getY() - 20 < this.y)) { // 判断是否碰到了敌人
death();
}
}
if (onObstacle && upTime == 0) { // 进行马里奥跳跃的操作
if (status.indexOf("left") != -1) { // 判断马里奥现在面向的方向是哪里
if (xSpeed != 0) {
status = "move--left";
} else {
status = "stop--left";
}
} else {
if (xSpeed != 0) {
status = "move--right";
} else {
status = "stop--right";
}
}
} else {// 处于上升状态
if (upTime != 0) {
upTime--; // 不断的减,为0就停止下落
} else {
fall();
}
y += ySpeed;
}
}
// 可以向左向右走,并且要速度大于0才行
if ((canLeft && xSpeed < 0) || (canRight && xSpeed > 0)) { // 判断马里奥是否在运动
x += xSpeed; // 运动
if (x < 0) { // 判断马里奥是否到了左边
x = 0; // 坐标变为0
}
}
if (status.contains("move")) { // 判断当前是否是移动状态 //包含就是移动
index = index == 0 ? 1 : 0; // 这里是改变图片的索引
}
// 判断是否向左移动
if ("move--left".equals(status)) {
show = StaticValue.run_l.get(index); // 显示这个方向的图片
}
// 判断是否向右移动
if ("move--right".equals(status)) {
show = StaticValue.run_r.get(index);
}
// 判断是否向左停止
if ("stop--left".equals(status)) {
show = StaticValue.stand_l;
}
// 判断是否向右停止
if ("stop--right".equals(status)) {
show = StaticValue.stand_r;
}
// 判断是否向左跳跃
if ("jump--left".equals(status)) {
show = StaticValue.jump_L;
}
// 判断是否向右跳跃
if ("jump--right".equals(status)) {
show = StaticValue.jump_R;
}
try {
thread.sleep(50); // 休眠50毫秒
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
public int getX() {
return x;
}
public void setX(int x) {
this.x = x;
}
public int getY() {
return y;
}
public void setY(int y) {
this.y = y;
}
public BufferedImage getShow() {
return show;
}
public void setShow(BufferedImage show) {
this.show = show;
}
public void setBackGround(BackGround backGround) {
this.backGround = backGround;
}
public boolean isOK() {
return isOK;
}
public boolean isDeath() {
return isDeath;
}
public int getScore() {
return score;
}
}
敌人类
import java.awt.image.BufferedImage;
public class Enemy implements Runnable {
private int x, y; // 敌人的坐标
private int type; // 敌人的类型
private boolean face_to = true; // 判断敌人的移动方向
private BufferedImage show; // 图像
private BackGround bg; // 背景
private int max_up = 0; // 食人花的运动范围 //最高
private int max_down = 0; // 最低
private Thread thread = new Thread(this);
private int image_type = 0; // 定义当前图片的状态
public Enemy(int x, int y, boolean face_to, int type, BackGround bg) { // 蘑菇敌人的构造函数
this.x = x;
this.y = y;
this.face_to = face_to;
this.type = type;
this.bg = bg;
show = StaticValue.mogu.get(0); // 初始化蘑菇敌人为第一个
thread.start();
}
public Enemy(int x, int y, boolean face_to, int type, int max_up, int max_down, BackGround bg) { // 花敌人的构造函数
this.x = x; // 构造函数的顺序不能写乱要不然会出错
this.y = y;
this.face_to = face_to;
this.type = type;
this.max_up = max_up;
this.max_down = max_down;
this.bg = bg;
show = StaticValue.flower.get(0); // 初始化花敌人为第一个
thread.start();
}
public void death() { // 死亡方法
show = StaticValue.mogu.get(2); // 死亡的图片
this.bg.getEmemyList().remove(this); // 死了就移除
}
public int getX() {
return x;
}
public int getY() {
return y;
}
public BufferedImage getShow() {
return show;
}
public int getType() {
return type;
}
@Override
public void run() {
while (true) {
if (type == 1) { // 判断是否是蘑菇敌人
if (face_to) {
this.x -= 2; // 向左移动
} else {
this.x += 2; // 向右移动
}
image_type = image_type == 1 ? 0 : 1; // 来回切换两张图片达到行走的效果
show = StaticValue.mogu.get(image_type); // 获取图片
}
boolean canLeft = true; // 用来判断能否向左向右走
boolean canRight = true;
for (int i = 0; i < bg.getObstacleList().size(); i++) { // 遍历当前场景的里所有的障碍物
Obstacle ob1 = bg.getObstacleList().get(i);
// 判断是否可以向右走
if (ob1.getX() == this.x + 36 && (ob1.getY() + 65 > this.y && ob1.getY() - 35 < this.y)) {
canRight = false;
}
// 判断是否可以向左走
if (ob1.getX() == this.x - 36 && (ob1.getY() + 65 > this.y && ob1.getY() - 35 < this.y)) {
canLeft = false;
}
}
if (face_to && !canLeft || this.x == 0) { // 0位屏幕的最左处
face_to = false;
} else if ((!face_to) && (!canRight) || this.x == 764) { // 764为右边的边界处
face_to = true;
}
if (type == 2) { // 判断是不是食人花敌人
if (face_to) { // 为true向上移动
this.y -= 2;
} else {
this.y += 2; // 向下移动
}
image_type = image_type == 1 ? 0 : 1; // 来回切换两张图片达到行走的效果
if (face_to && (this.y == max_up)) { // 判断食人花是否移动到了上极限的位置,移动到了后就要向下移动
face_to = false;
}
if ((!face_to) && (this.y == max_down)) { // 判断食人花是否移动到了下极限的位置,移动到了后就要向上移动
face_to = true;
}
show = StaticValue.flower.get(image_type); // 获取图片
}
try {
thread.sleep(50);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}
旗杆类
import java.awt.image.BufferedImage;
public class Obstacle implements Runnable {
private int x; // 坐标
private int y;
private int type; // 障碍物类型
private BufferedImage show = null; // 用于显示图像
private BackGround bg = null; // 定义当前背景的对象
private Thread thread = new Thread(this); // 定义线程对象
public Obstacle(int x, int y, int type, BackGround bg) {
this.x = x;
this.y = y;
this.type = type;
this.bg = bg;
show = StaticValue.obstacle.get(type); // 初始化为障碍物的图片
if (type == 8) { // 判断类型是不是8,其实就是判断是不是旗子在第三关,是就启动线程
thread.start();
}
}
public int getX() {
return x;
}
public int getY() {
return y;
}
public int getType() {
return type;
}
public BufferedImage getShow() {
return show;
}
@Override
public void run() {
while (true) {
if (this.bg.isReach()) { // 判断是否到达旗杆的位置
if (this.y < 374) {
this.y += 5; // 让旗子降落
} else {
this.bg.setBase(true); // 表示旗子已经下落到下面
}
}
try {
thread.sleep(50); // 同步休眠
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}
需要完整源码以及完整图片请点赞留言博主