超级马里奥游戏开发(障碍物和敌人的设置)
目录
实现功能:
加入敌人和障碍物对象,敌人可以移动。
1.敌人类Enemy
- 同样在界面类MFrame的run方法里面绘制敌人的图片,因此我们的敌人也像之前的马里奥一样,需要被封装成一个类。
- 敌人类对外必须能提供自己此刻的图像、位置、大小。
- 敌人有自己的运动轨迹,因此需要实现Runnable接口,使用线程。
package Mario_7_12;
import java.awt.image.BufferedImage;
import java.util.ArrayList;
import java.util.List;
public class Enemy implements Runnable{
private Thread tr;
private List <BufferedImage> imagesL = new ArrayList<>();//图像集合
private List <BufferedImage> imagesR = new ArrayList<>();//图像集合
private volatile int index;//当前显示的图片索引
private volatile int posx,posy,dx,dy;//位置和水平速度,竖直方向速度
private int width,height;//大小
private int l,r,up,down;//运动范围
private volatile boolean diretL,directUp;//运动方向
private int switchN;
/*
* 构造函数
* */
public Enemy(int posx, int posy,int dx, int dy, List <BufferedImage> imagesL,List <BufferedImage> imagesR,
int width, int height,int l,int r,int up, int down){
this.posx = posx;
this.posy = posy;
this.imagesL = imagesL;
this.imagesR = imagesR;
this.width = width;
this.height = height;
this.l = l;
this.r = r;
this.up = up;
this.down = down;
diretL = false;
directUp = false;
this.dx = dx;
this.dy = dy;
index = 0;
switchN = 5;
tr = new Thread(this);
tr.start();//启动线程
}
/*
* 在线程中运动
* */
@Override
public void run(){
while(true){
posy += dy;
posx += dx;
//判断边界
if(posx<l) {posx = l;dx = -dx; diretL = false;}
if(posx+width>r) {posx = r-width;dx = -dx; diretL = true;}
if(posy<up){posy = up; dy = -dy; directUp = false;}
if(posy+height>down){posy = down - height; dy = -dy; directUp = true;}
switchN--;
if(switchN == 0){
index = (index+1)%2;//切换图片
switchN = 5;
}
try {
Thread.sleep(50);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
/*
* 得到当前的图片
* */
public BufferedImage getImage(){
if(diretL)
return imagesL.get(index);
else
return imagesR.get(index);
}
/*
* 得到x坐标
* */
public int getX(){
return posx;
}
/*
* 得到y坐标
* */
public int getY(){
return posy;
}
/*
* 得到宽
* */
public int getWidth(){
return width;
}
/*
* 得到高
* */
public int getHeight(){
return height;
}
}
2. 障碍物类Object
障碍物的信息比较简单,只需要知道它的位置和大小。
package Mario_7_12;
import java.awt.image.BufferedImage;
public class Object {
private int l,r,up,down;//边界
private BufferedImage image;//图像
public Object(int l, int r, int up, int down, BufferedImage image){
this.l = l;
this.r = r;
this.up = up;
this.down = down;
this.image = image;
}
public int getL(){
return l;
}
public int getR(){
return r;
}
public int getUp(){
return up;
}
public int getDown(){
return down;
}
public BufferedImage getImage(){
return image;
}
}
3.背景类Background
- 随着我们的移动我们的背景也要随之改变
- 一个背景中有独有的背景图片、障碍物、敌人
- 因此我们把背景包装成一个类
package Mario_7_12;
import java.awt.image.BufferedImage;
import java.util.ArrayList;
import java.util.List;
public class Background {
private BufferedImage bgImage = null;//背景图片
private int sort;//第几个场景
private List<Enemy> allEnemies = new ArrayList<Enemy>();//敌人
private List<Object> allConstructions = new ArrayList<Object>();//障碍物
/*
* 构造函数,根据创建的是第几个场景来初始化障碍物和敌人
* */
public Background(int sort){
switch(sort){
case 1:
setBg1();break;
}
}
/*
* 第一个场景
* */
public void setBg1(){
bgImage = StaticValue.bgImg1;//背景
List <BufferedImage> mushL = StaticValue.mushroomImgsL;//蘑菇怪
List <BufferedImage> mushR = StaticValue.mushroomImgsR;//蘑菇怪
List <BufferedImage> turtleL = StaticValue.turtleImgsL;//乌龟怪
List <BufferedImage> turtleR = StaticValue.turtleImgsR;//乌龟怪
List <BufferedImage> flowerUp = StaticValue.flowerImgs;//花怪
List <BufferedImage> flowerDown = StaticValue.flowerImgs;//花怪
Enemy enemy1 = new Enemy(800,445,4,0,mushL,mushR,30,50,400,900,0,600);
Enemy enemy2 = new Enemy(0,445,2,0,turtleL,turtleR,40,60,0,300,0,600);
Enemy enemy3 = new Enemy(330,415,0,1,flowerUp,flowerDown,55,80,0,900,270,430);
allEnemies.add(enemy1);
allEnemies.add(enemy2);
allEnemies.add(enemy3);
//柱子
Object object1 = new Object(300,400,360,500,StaticValue.constructionsImgs.get(6));
Object object2 = new Object(290,350,330,360,StaticValue.constructionsImgs.get(8));
Object object3 = new Object(350,420,330,360,StaticValue.constructionsImgs.get(7));
allConstructions.add(object1);
allConstructions.add(object2);
allConstructions.add(object3);
//砖块
Object object4 = new Object(600,650,300,350,StaticValue.constructionsImgs.get(0));
Object object5 = new Object(650,700,300,350,StaticValue.constructionsImgs.get(4));
Object object6 = new Object(700,750,300,350,StaticValue.constructionsImgs.get(0));
allConstructions.add(object4);
allConstructions.add(object5);
allConstructions.add(object6);
}
//得到背景图片
public BufferedImage getBgImage(){
return bgImage;
}
/*
* 得到敌人
* */
public List <Enemy> getEnemies(){
return allEnemies;
}
/*
* 得到障碍物
* */
public List<Object> getObjects(){
return allConstructions;
}
}
4.界面类中的run方法
因为在MFrame里面绘制图片,因此背景信息需要在这里画出来
增加的属性:
private Background bg;//背景
private int bgIndex;//第几个背景
run方法:
/*
* 在线程里面绘制图片
* */
@Override
public void run() {
// TODO Auto-generated method stub
List <Enemy> enemies = bg.getEnemies();
List<Object> objects = bg.getObjects();
while(true){
try {
Thread.sleep(10);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
Image bgimg = new ImageIcon(bg.getBgImage()).getImage();//背景图片
buffg.drawImage(bgimg, 0,0, null);
buffg.drawImage(mario.getImage(), mario.posx, mario.posy, 50, 100, null);//马里奥
//敌人
for(int i=0; i<enemies.size(); i++){
Enemy enemy = enemies.get(i);
BufferedImage enemyImg = enemy.getImage();
buffg.drawImage(new ImageIcon(enemyImg).getImage(),
enemy.getX(),enemy.getY(),enemy.getWidth(),enemy.getHeight(),null );
}
//障碍物
for(int i=0; i<objects.size(); i++){
Object object = objects.get(i);
BufferedImage objectImg = object.getImage();
buffg.drawImage(new ImageIcon(objectImg).getImage(),
object.getL(),object.getUp(),object.getR()- object.getL(),object.getDown() - object.getUp(),null );
}
g.drawImage(buffimg, 0, 0, null);
}
}