作者簡介
作者名:編程界明世隱
簡介:CSDN博客專家,從事軟體開發多年,精通Java、JavaScript,博主也是從零開始一步步把學習成長、深知學習和積累的重要性,喜歡跟廣大ADC一起打野升級,歡迎您關注,期待與您一起學習、成長、起飛!
超級瑪麗
系列目錄
1. Java俄羅斯方塊
2. Java五子棋小游戲
3. 老Java程式員花一天時間寫了個飛機大戰
4. Java植物大戰僵尸
5. 老Java程式員花2天寫了個連連看
6. Java消消樂(天天愛消除)
7. Java貪吃蛇小游戲
8. Java掃雷小游戲
9. Java坦克大戰
10. Java迷宮小游戲
引言:
國慶前與群里的小伙伴們聊了一下,決定做一下超級瑪麗這個游戲,畢竟以前也經常玩,網上找了一下資源,然后國慶就整起來了,果然程式員不配有假期,我的假期就這樣泡湯了,超級瑪麗你給我發工資,
實作思路
- 創建視窗,
- 創建加載所有圖片的類,
- 創建場景,實體化場景,
- 創建障礙物,顯示障礙物,
- 創建敵人,創建主執行緒,讓敵人動起來,
- 創建馬里奧,顯示馬里奧,
- 創建鍵盤事件,
- 馬里奧的跳躍、左右移動、死亡等處理,
- 處理障礙物的消除,怪物的死亡等,
- 其他收尾處理(場景切換,背景音樂),
代碼實作
創建視窗
首先創建一個游戲表單類GameFrame,繼承至JFrame,用來顯示在螢屏上(window的物件),每個游戲都有一個視窗,設定好視窗標題、尺寸、布局等就可以,
package main;
import javax.swing.JFrame;
/**
*表單類
*/
public class GameFrame extends JFrame {
//構造方法
public GameFrame(){
setTitle("超級瑪麗");//設定標題
setSize(900, 600);//設定表單大小
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);//關閉后行程退出
setLocationRelativeTo(null);//居中
setResizable(false);//不允許變大
}
}
創建面板容器GamePanel繼承至JPanel
package main;
import javax.swing.JPanel;
/**
* 畫布類
*/
public class GamePanel extends JPanel {
private GameFrame mainFrame = null;
private GamePanel panel = null;
//構造里面初始化相關引數
public GamePanel(GameFrame frame){
this.setLayout(null);
this.setOpaque(false);
this.mainFrame=frame;
this.panel =this;
}
}
再創建一個Main類,來啟動這個視窗,用來啟動,
package main;
//Main類
public class Main {
public static void main(String[] args) {
GameFrame frame = new GameFrame();
GamePanel panel = new GamePanel(frame);
frame.add(panel);
frame.setVisible(true);
}
}
右鍵執行這個Main類,視窗建出來了

加載所有的圖片
創建StaticValue類,用來加載圖片,屬性全部定義為static 型別,其中 init 方法,只需呼叫一次,然后加載好所有的圖片,方便后面使用,
package main;
import java.awt.image.BufferedImage;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
import javax.imageio.ImageIO;
public class StaticValue {
//存盤馬里奧的圖片
public static List<BufferedImage> allMarioImage = new ArrayList<BufferedImage>();
//開始圖片
public static BufferedImage startImage = null;
//結束圖片
public static BufferedImage endImage = null;
//背景圖片
public static BufferedImage bgImage = null;
//食人花圖片
public static List<BufferedImage> allFlowerImage = new ArrayList<BufferedImage>();
//敵人圖片
public static List<BufferedImage> allTriangleImage = new ArrayList<BufferedImage>();
//烏龜圖片
public static List<BufferedImage> allTurtleImage = new ArrayList<BufferedImage>();
//障礙物圖片
public static List<BufferedImage> allObstructionImage = new ArrayList<BufferedImage>();
//馬里奧死亡圖片
public static BufferedImage mariDeadImage = null;
//定義檔案路徑
public static String ImagePath = "/image/";
//將圖片初始化
public static void init() {
String path = "";
//瑪麗奧圖片初始化
for (int i = 1; i <= 10; i++) {
try {
path = ImagePath + i + ".png";
allMarioImage.add(ImageIO.read(StaticValue.class.getResource(path)));
} catch (IOException e) {
e.printStackTrace();
}
}
//匯入背景圖片
try {
startImage = ImageIO.read(StaticValue.class.getResource(ImagePath + "start.jpg"));
bgImage = ImageIO.read(StaticValue.class.getResource(ImagePath + "firststage.jpg"));
endImage = ImageIO.read(StaticValue.class.getResource(ImagePath + "firststageend.jpg"));
} catch (IOException e) {
e.printStackTrace();
}
//匯入敵人圖片
for (int i = 1; i <= 5; i++) {
try {
if (i <= 2) {
allFlowerImage
.add(ImageIO.read(StaticValue.class.getResource(ImagePath + "flower" + i + ".png")));
}
if (i <= 3) {
allTriangleImage.add(
ImageIO.read(StaticValue.class.getResource(ImagePath + "triangle" + i + ".png")));
}
allTurtleImage
.add(ImageIO.read(StaticValue.class.getResource(ImagePath + "Turtle" + i + ".png")));
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
//匯入障礙物圖片
for (int i = 1; i <= 12; i++) {
try {
allObstructionImage
.add(ImageIO.read(StaticValue.class.getResource(ImagePath + "ob" + i + ".png")));
} catch (IOException e) {
e.printStackTrace();
}
}
//匯入瑪麗奧死亡圖片
try {
mariDeadImage = ImageIO.read(StaticValue.class.getResource(ImagePath + "over.png"));
} catch (IOException e) {
e.printStackTrace();
}
}
}
創建場景
創建場景的背景
有7個場景,前6個的背景圖如下:

第7個背景圖如下:

其實就是多了個旗桿和城堡,用來結束游戲的,這里在設定背景的時候有些區別,我們來定義BackGround類,
定義BackGround類
- sort代表場景的數字,比如第一個場景就是1,
- flag為true就是最后一個場景,所以最后一個場景的圖片有點不一樣,
package main;
import java.awt.image.BufferedImage;
public class BackGround {
//當前場景圖片
private BufferedImage bgImage = null;
//場景順序
private int sort;
//是否為最后的場景
private boolean flag;
//游戲結束標記
private boolean isOver = false;
//定義降旗結束
private boolean isDown = false;
//構造方法
public BackGround(int sort,boolean flag) {
this.sort = sort;
this.flag = flag;
if (flag) {//最后一個場景
bgImage = StaticValue.endImage;
} else {//1-6場景
bgImage = StaticValue.bgImage;
}
}
//繪制
public void draw(Graphics g) {
g.drawImage(bgImage,0,0,null);
}
}
實體化場景
- 在GamePanel類中加入相關成員
//存全部7個場景的集合
private List<BackGround> allBG = new ArrayList<BackGround>();
//存當前場景
private BackGround nowBG = null;
- 在GamePanel類中加入init方法,此方法用來做游戲的全部初始化操作,比如 初始化圖片、創建背景(包含障礙物、敵人等)、設定當前背景,
//初始化
private void init() {
//圖片初始化
StaticValue.init();
//創建全部場景
for (int i = 1; i <= 7; i++) {
//i==7?true:false 最后一個場景有點區別,有個結束的城堡
this.allBG.add(new BackGround(i, i == 7 ? true : false));
}
//將第一個場景設定為當前場景
this.nowBG = this.allBG.get(0);
}
在GamePanel中重寫paint方法,并在此方法中繪制背景,
@Override
public void paint(Graphics g) {
super.paint(g);
//繪制背景
this.nowBG.draw(g);
}
運行一下,背景被繪制到視窗上了,

創建障礙物類
package main;
import java.awt.Graphics;
import java.awt.image.BufferedImage;
public class Obstruction implements Runnable{
//坐標
private int x;
private int y;
//控制旗子
private Thread t = new Thread(this);
//型別
private int type;
//初始型別
private int starttype;
//顯示圖片
private BufferedImage showImage = null;
//取得場景
private BackGround bg;
//構造方法
public Obstruction(int x,int y,int type,BackGround bg){
this.x = x;
this.y = y;
this.type = type;
this.starttype = type;
this.bg = bg;
setImage();
if(this.type == 11){
t.start();
}
}
//繪制
public void draw(Graphics g) {
g.drawImage(showImage,x,y,null);
}
//重置方法
public void reset(){
this.type = starttype;
this.setImage();
}
//根據狀態改變顯示圖片
public void setImage(){
showImage = StaticValue.allObstructionImage.get(type);
}
public BufferedImage getShowImage() {
return showImage;
}
public int getX() {
return x;
}
public int getY() {
return y;
}
public int getType() {
return type;
}
public void setType(int type) {
this.type = type;
}
public void run() {
while(true){
if(this.bg.isOver()){
if(this.y < 420){
this.y += 5;
}else{
this.bg.setDown(true);
}
}
try {
Thread.sleep(50);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
}
障礙物介紹
總共有12種障礙物,圖片如下:



修改BackGround類
加入繪制障礙物的方法,比如第一個場景的 buildBackGround1()
注意點:
比如:this.allObstruction.add(new Obstruction(i * 60, 540, 9, this));
這里傳入的是9,但其實取得是第10個障礙物

因為我們在StaticValue存障礙物的集合allObstructionImage,集合是從0開始的,所以這里傳入9等于取到的是第10個障礙物,其他的一樣的意思,
package main;
import java.awt.Graphics;
import java.awt.image.BufferedImage;
import java.util.ArrayList;
import java.util.List;
public class BackGround {
//當前場景圖片
private BufferedImage bgImage = null;
//場景順序
private int sort;
//是否為最后的場景
private boolean flag;
//游戲結束標記
private boolean isOver = false;
//定義降旗結束
private boolean isDown = false;
//用集合保存障礙物
private List<Obstruction> allObstruction = new ArrayList<Obstruction>();
//被消滅的障礙物
private List<Obstruction> removeObstruction = new ArrayList<Obstruction>();
//構造方法
public BackGround(int sort,boolean flag) {
this.sort = sort;
this.flag = flag;
if (flag) {//最后一個場景
bgImage = StaticValue.endImage;
} else {//1-6場景
bgImage = StaticValue.bgImage;
}
//根據場景來配置對應的背景
switch (sort){
case 1:
buildBackGround1();
break;
case 2:
buildBackGround2();
break;
case 3:
buildBackGround3();
break;
case 4:
buildBackGround4();
break;
case 5:
buildBackGround5();
break;
case 6:
buildBackGround6();
break;
case 7:
buildBackGround7();
break;
}
}
//第1個場景
void buildBackGround1() {
//繪制地面
for (int i = 0; i < 15; i++) {
this.allObstruction.add(new Obstruction(i * 60, 540, 9, this));
}
//繪制磚塊和問號
this.allObstruction.add(new Obstruction(120, 360, 4, this));
this.allObstruction.add(new Obstruction(300, 360, 0, this));
this.allObstruction.add(new Obstruction(360, 360, 4, this));
this.allObstruction.add(new Obstruction(420, 360, 0, this));
this.allObstruction.add(new Obstruction(480, 360, 4, this));
this.allObstruction.add(new Obstruction(540, 360, 0, this));
this.allObstruction.add(new Obstruction(420, 180, 4, this));
//繪制水管
this.allObstruction.add(new Obstruction(660, 540, 6, this));
this.allObstruction.add(new Obstruction(720, 540, 5, this));
this.allObstruction.add(new Obstruction(660, 480, 8, this));
this.allObstruction.add(new Obstruction(720, 480, 7, this));
//隱藏磚塊
this.allObstruction.add(new Obstruction(660, 300, 3, this));
}
void buildBackGround2(){}
void buildBackGround3(){}
void buildBackGround4(){}
void buildBackGround5(){}
void buildBackGround6(){}
void buildBackGround7(){}
//繪制背景
public void draw(Graphics g) {
g.drawImage(bgImage,0,0,null);
}
public boolean isFlag() {
return flag;
}
public boolean isOver() {
return isOver;
}
public void setOver(boolean isOver) {
this.isOver = isOver;
}
public boolean isDown() {
return isDown;
}
public void setDown(boolean isDown) {
this.isDown = isDown;
}
public int getSort() {
return sort;
}
public List<Obstruction> getRemoveObstruction() {
return removeObstruction;
}
//回傳所有的障礙物
public List<Obstruction> getAllObstruction() {
return allObstruction;
}
}
繪制障礙物到視窗
//繪制障礙物
private void drawObstruction(Graphics g) {
//繪制障礙物
Obstruction ob = null;
Iterator<Obstruction> iter = this.nowBG.getAllObstruction().iterator();
while(iter.hasNext()){
ob = iter.next();
ob.draw(g);
}
}
在paint方法中呼叫它
@Override
public void paint(Graphics g) {
super.paint(g);
//繪制背景
this.nowBG.draw(g);
//繪制障礙物
drawObstruction(g);
}
運行一下,第一個場景的障礙物就繪制出來了, 
定義敵人類
- 因為這里的敵人有兩類,一類是蘑菇怪,一類是食人花,所以定義了2個構造,分別是創建不同型別的敵人,
- 執行緒先默認加好,因為敵人要運動的,待會在來具體寫run方法,
package main;
import java.awt.Graphics;
import java.awt.image.BufferedImage;
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 ;
//存活狀態
private boolean alive = false;
//蘑菇怪
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();
}
//食人花
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();
}
//繪制
public void draw(Graphics g){
g.drawImage(showImage,x,y,null);
}
//現場的run方法
public void run() {
while (true) {
if(alive){
}
try {
Thread.sleep(100);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
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(){
alive = true;
}
}
場景中初始化敵人,修改buildBackGround1 方法,加入以下代碼,
//繪制怪物
this.allEnemy.add(new Enemy(600, 480, true, 1,this));
//繪制食人花
this.allEnemy.add(new Enemy(690, 540, true, 2, 420, 540,this));
在GamePanel類中創建方法,并在paint中呼叫,繪制出敵人,
//繪制敵人
private void drawEnemy(Graphics g){
//繪制怪物敵人
Iterator<Enemy> iterEnemy = this.nowBG.getAllEnemy().iterator();
while(iterEnemy.hasNext()){
Enemy e = iterEnemy.next();
e.draw(g);
}
}
運行

讓敵人運動起來
一、蘑菇怪運動
- 先向左運動,讓其X坐標遞減就行,到最左邊后反過來向右運動,坐標依次遞增,碰到障礙物反過來繼續,
- 每次執行緒執行的時候,要切換圖片哦,
修改Enemy類的run方法(同時把alive先默認設定為true,測驗用)
if(alive){
//判斷怪物型別
if (type == 1) {
//左右移動
if (this.isLeftOrUp) {
this.x -= 5;
} else {
this.x += 5;
}
//imageType的切換來達到圖片的切換
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);
}
}
在GamePanel加入主執行緒代碼,
private class RefreshThread implements Runnable {
@Override
public void run() {
while (true) {
if (!"end".equals(gameFlag)) {
repaint();
}
try {
Thread.sleep(50);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}
建構式里面呼叫此執行緒

運行效果:

二、食人花運動
- 向上運動在遞減y坐標,向下運動遞增y坐標,
- 每次切換圖片
- 達到最高處,則反過來往下;達到最低處,反過來往上;
在Enemy類中的run方法加入以下代碼:
if (type == 2) {
if (this.isLeftOrUp) {//向上運動
this.y -= 5;
} else {//向下運動
this.y += 5;
}
//imageType的切換來達到圖片的切換
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);
}

加入馬里奧
創建類
package main;
import java.awt.Graphics;
import java.awt.image.BufferedImage;
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 int speed = 5;
//狀態
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 draw(Graphics g) {
g.drawImage(showImage, x, y, null);
}
public void run() {
while(true){
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;
}
}
修改init方法,加入馬里奧的初始化
//初始化
private void init() {
//圖片初始化
StaticValue.init();
//創建全部場景
for (int i = 1; i <= 7; i++) {
//i==7?true:false 最后一個場景有點區別,有個結束的城堡
this.allBG.add(new BackGround(i, i == 7 ? true : false));
}
//將第一個場景設定為當前場景
this.nowBG = this.allBG.get(0);
//初始化瑪麗奧
this.mario = new Mario(0, 480);
//將瑪麗奧放入場景中
this.mario.setBg(nowBG);
}
paint方法中繪制馬里奧

運動
移動代碼
public void leftMove(){
//移動速度
xmove = -speed;
//改變狀態
//如果當前已經是跳躍,應該保持原有狀態,不能再改變
if(this.status.indexOf("jumping") != -1){
this.status = "left-jumping";
}else{
this.status = "left-moving";
}
}
public void rightMove(){
xmove = speed;
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{
if(!isDead){
}
this.x = 0;
this.y = 480;
}
}
加入鍵盤事件
在GamePanel中加入鍵盤事件,并在構造方法在呼叫,
//添加鍵盤監聽
private void createKeyListener() {
KeyAdapter l = new KeyAdapter() {
//按下
@Override
public void keyPressed(KeyEvent e) {
int key = e.getKeyCode();
if("start".equals(gameFlag)){
switch (key) {
//向上
case KeyEvent.VK_UP:
case KeyEvent.VK_W:
mario.jump();
break;
//向右
case KeyEvent.VK_RIGHT:
case KeyEvent.VK_D:
mario.rightMove();
break;
//向左
case KeyEvent.VK_LEFT:
case KeyEvent.VK_A:
mario.leftMove();
break;
//空格
case KeyEvent.VK_SPACE:
//起跳
mario.jump();
break;
}
}else if("load".equals(gameFlag)||"end".equals(gameFlag)){
//游戲開始
//gameStart();
}
}
//松開
@Override
public void keyReleased(KeyEvent e) {
if("start".equals(gameFlag)){
int key = e.getKeyCode();
//控制瑪麗奧的停止
if(key==KeyEvent.VK_RIGHT||key==KeyEvent.VK_D){
mario.rightStop();
}
if(key==KeyEvent.VK_LEFT||key==KeyEvent.VK_A){
mario.leftStop();
}
}
}
};
//給主frame添加鍵盤監聽
mainFrame.addKeyListener(l);
}
修改馬里奧類的run方法
public void run() {
while(true){
//判斷是否與障礙物碰撞
//定義標記
if(this.bg.isFlag() && this.x >= 520){
if(!this.bg.isOver()){
}
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(this.status.indexOf("jumping") != -1){//在空中
//不能向右移動
if((ob.getX()<=this.x+60 && this.x <ob.getX() )&& (ob.getY()+50>this.y && ob.getY()-50<this.y)){
if(ob.getType() != 3){
canRight = false;
}
}
//不能向左移動
if((ob.getX()>=this.x-60 && this.x >ob.getX())&& (ob.getY()+50>this.y && ob.getY()-50<this.y)){
if(ob.getType() != 3){
canLeft = false;
}
}
}else{
//不能向右移動
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();
canLeft=false;
canRight=false;
}
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();
canLeft=false;
canRight=false;
}
}
}
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();
canLeft=false;
canRight=false;
}
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();
}
}
}

加入其他場景的代碼
//第2個場景
void buildBackGround2(){
for(int i=0;i<15;i++){
if(i != 9 && i != 10 && i != 11 ){
this.allObstruction.add(new Obstruction(i*60, 540, 9,this));
}
}
//繪制水管
this.allObstruction.add(new Obstruction(60, 540, 6,this));
this.allObstruction.add(new Obstruction(120, 540, 5,this));
this.allObstruction.add(new Obstruction(60, 480, 6,this));
this.allObstruction.add(new Obstruction(120, 480, 5,this));
this.allObstruction.add(new Obstruction(60, 420, 8,this));
this.allObstruction.add(new Obstruction(120, 420, 7,this));
this.allObstruction.add(new Obstruction(300, 540, 6,this));
this.allObstruction.add(new Obstruction(360, 540, 5,this));
this.allObstruction.add(new Obstruction(300, 480, 6,this));
this.allObstruction.add(new Obstruction(360, 480, 5,this));
this.allObstruction.add(new Obstruction(300, 420, 6,this));
this.allObstruction.add(new Obstruction(360, 420, 5,this));
this.allObstruction.add(new Obstruction(300, 360, 8,this));
this.allObstruction.add(new Obstruction(360, 360, 7,this));
//繪制怪物
this.allEnemy.add(new Enemy(330, 360, true, 2, 300, 420,this));
}
//第3個場景
void buildBackGround3(){
for(int i=0;i<15;i++){
this.allObstruction.add(new Obstruction(i*60, 540, 9,this));
}
//繪制磚塊和問號
this.allObstruction.add(new Obstruction(180, 360, 4,this));
this.allObstruction.add(new Obstruction(420, 360, 4,this));
this.allObstruction.add(new Obstruction(660, 360, 4,this));
this.allObstruction.add(new Obstruction(420, 180, 4,this));
}
//第4個場景
void buildBackGround4(){
for(int i=0;i<15;i++){
if(i<2||i>12){
this.allObstruction.add(new Obstruction(i*60, 540, 9,this));
}
}
this.allObstruction.add(new Obstruction(120, 360, 0,this));
this.allObstruction.add(new Obstruction(180, 360, 0,this));
this.allObstruction.add(new Obstruction(300, 180, 0,this));
this.allObstruction.add(new Obstruction(360, 180, 0,this));
this.allObstruction.add(new Obstruction(420, 180, 0,this));
this.allObstruction.add(new Obstruction(480, 180, 0,this));
this.allObstruction.add(new Obstruction(540, 180, 0,this));
this.allObstruction.add(new Obstruction(660, 360, 0,this));
this.allObstruction.add(new Obstruction(720, 360, 0,this));
}
//第5個場景
void buildBackGround5(){
int z = 2;
for(int i=0;i<15;i++){
if(i%2==0 && i<7){
this.allObstruction.add(new Obstruction(i*60, 540-(i*60), 9,this));
for(int x=i;x>0;x--){
this.allObstruction.add(new Obstruction(i*60, 540-(x*60)+60, 10,this));
}
}
if(i%2==0 && i>7){
this.allObstruction.add(new Obstruction(i*60, 540-((i-z)*60), 9,this));
for(int x=i-z;x>0;x--){
this.allObstruction.add(new Obstruction(i*60, 540-(x*60)+60, 10,this));
}
z+=4;
}
}
}
//第6個場景
void buildBackGround6(){
for(int i=0;i<15;i++){
this.allObstruction.add(new Obstruction(i*60, 540, 9,this));
}
this.allObstruction.add(new Obstruction(480, 480, 1,this));
this.allObstruction.add(new Obstruction(480, 420, 1,this));
this.allObstruction.add(new Obstruction(480, 360, 1,this));
this.allObstruction.add(new Obstruction(480, 300, 1,this));
this.allObstruction.add(new Obstruction(480, 240, 1,this));
this.allObstruction.add(new Obstruction(480, 180, 1,this));
this.allObstruction.add(new Obstruction(540, 240, 1,this));
this.allObstruction.add(new Obstruction(540, 300, 1,this));
this.allObstruction.add(new Obstruction(540, 360, 1,this));
this.allObstruction.add(new Obstruction(540, 420, 1,this));
this.allObstruction.add(new Obstruction(540, 480, 1,this));
this.allObstruction.add(new Obstruction(600, 300, 1,this));
this.allObstruction.add(new Obstruction(600, 360, 1,this));
this.allObstruction.add(new Obstruction(600, 420, 1,this));
this.allObstruction.add(new Obstruction(600, 480, 1,this));
this.allObstruction.add(new Obstruction(660, 360, 1,this));
this.allObstruction.add(new Obstruction(660, 420, 1,this));
this.allObstruction.add(new Obstruction(660, 480, 1,this));
this.allObstruction.add(new Obstruction(720, 420, 1,this));
this.allObstruction.add(new Obstruction(720, 480, 1,this));
this.allObstruction.add(new Obstruction(780, 480, 1,this));
//通關要點,隱形磚塊
this.allObstruction.add(new Obstruction(300, 360, 3,this));
}
//第7個場景
void buildBackGround7(){
for(int i=0;i<15;i++){
this.allObstruction.add(new Obstruction(i*60, 540, 9,this));
}
this.allObstruction.add(new Obstruction(490, 180, 11,this));
this.allObstruction.add(new Obstruction(520, 480, 2,this));
//地上障礙物
this.allObstruction.add(new Obstruction(240, 360, 1,this));
this.allObstruction.add(new Obstruction(240, 420, 1,this));
this.allObstruction.add(new Obstruction(240, 480, 1,this));
this.allObstruction.add(new Obstruction(180, 420, 1,this));
this.allObstruction.add(new Obstruction(180, 480, 1,this));
this.allObstruction.add(new Obstruction(120, 480, 1,this));
}
最后
加入積分、生命、場景切換、游戲結束、背景音樂等就完成了

看到這里的大佬,動動發財的小手 點贊 + 回復 + 收藏,能【 關注 】一波就更好了,
代碼獲取方式:
訂閱我的專欄《Java游戲大全》后,可以查看專欄內所有的文章,并且聯系博主免費獲取其中1-3份你心儀的源代碼,專欄的文章都是上過csdn熱榜的,值得信賴!專欄內目前有[ 13 + 1 ] 篇實體,未來2個月內專欄會更新到15篇以上,一般2周一更,了解一下我的專欄,
更多精彩
1. Java俄羅斯方塊
2. 老Java程式員花2天寫了個連連看
3. 老Java程式員花一天時間寫了個飛機大戰
4. Java五子棋人機版
5. Java植物大戰僵尸
6. Java消消樂(天天愛消除)
7. Java貪吃蛇小游戲
8. Java掃雷小游戲
9. Java坦克大戰
轉載請註明出處,本文鏈接:https://www.uj5u.com/ruanti/310620.html
標籤:其他
上一篇:如何快速學會別人的代碼和思維
