2021-07-01

超级马里奥

窗体类

package ui;
import javax.swing.JFrame;
//窗体类
public class GameFrame extends 	JFrame{
	/**
	 * 构造方法:
	 * 根据提供的素材,去制作游戏窗体
	 */
	
	public GameFrame() {
		//设置标题
		setTitle("超级玛丽");
		//设置尺寸(大小)
		setSize(1920,600);
		//设置位置居中显示
		setLocationRelativeTo(null);
		//禁止改变界面大小
		setResizable(false);
		//设置默认的关闭选项
		//关闭窗体的时候退出程序
		setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
	}
	/**
	 * 
	 */
	public static void main(String[] args) {
		//使用模具 (构造方法)创建游戏面板
		GameFrame frame = new GameFrame();
		//使用模具 (构造方法)创建游戏面板
		GamePanel panel = new GamePanel();
		//将面板加入到窗体中
		frame.add(panel);
		//让窗体显示出来
		frame.setVisible(true);
		//让面板获取到焦点(一定要加,否则键盘监听器,使用不了)
		panel.requestFocus();
			
		
	}

}
package ui;
import java.awt.Color;
import java.awt.Graphics;
import java.awt.event.KeyAdapter;
import java.awt.event.KeyEvent;
import java.awt.image.BufferedImage;
import java.util.ArrayList;
import java.util.List;
import java.util.Timer;
import java.util.TimerTask;

import javax.swing.JPanel;
/**
 * 游戏的界面(面板)
 * @author Administrator
 *JPanel 面板的类
 */
public class GamePanel extends JPanel{
	
	//定义背景图
	BufferedImage bg = ImageUtil.getImg("/img/bac.png");
	//使用玛丽奥的模具(构造方法),制作出马里奥
	Mario mario = new Mario();
	//定义集合,用来存放游戏中所有的蘑菇
	List<Mushroom>ms =new ArrayList<Mushroom>();
	int index = 0;//计算器,记录方法执行的次数
	/**
	 * 出现蘑菇的方法
	 */
	protected void mushroomEnter() {
		//美执行一次计算器增加
		index ++;
		if(index%200==0) {
		
		//创建一个蘑菇出来
		Mushroom m= new Mushroom();
		//将蘑菇添加到集合中
		ms.add(m);
		}
	}
	/**
	 * 构造方法:模具
	 */
	public GamePanel() {	
		 new MusicThread("/img/imgw/mario.wav");
		//开始音乐播放
		//mp.start();
		//创建启动线程,让程序一直出现蘑菇
		new Thread() {
			public void run() {
				while(true) {
				//蘑菇入场
				mushroomEnter();
				//让蘑菇移动
				for(int i=0;i<ms.size();i++) {
					//获取一个蘑菇
					Mushroom m = ms.get(i);
					//如果蘑菇没有死亡
					if(!m.isDie) {
					//向左移动
					m.x -= 5;
				}
				}
				try {
					Thread.sleep(10);
				} catch (InterruptedException e) {
					// TODO Auto-generated catch block
					e.printStackTrace();
				}
				}
			}
		}.start();
		//创建并启动一个线程,控制马里奥垂直上抛运动
		new Thread() {
				public void run() {
				while(true) {
					mario.step();
					//检查马里奥是否踩到了蘑菇
					caimogu();
					//Thread.sleep(毫秒数),让线程休眠指定的毫秒数
					try {
						//刷新界面
						repaint();
						Thread.sleep(20);
					} catch (InterruptedException e) {
						// TODO Auto-generated catch block
						e.printStackTrace();
					}
					
				}
			}
		}.start();
		
		//设置背景
		setBackground(Color.black );
		//添加键盘监听器(用键盘控制马里奥的活动)(固定格式)
		//1.创建键盘适配器
		KeyAdapter adapter = new KeyAdapter() {
			//2.确定要监听的事件(编写对应的方法)
			//当按下键盘的按键时,会执行的方法
			//keyEvent e 事件记事本(会记录对键盘所有的操作)
			@Override
			public void keyPressed(KeyEvent e) {
				//获取键盘上对应的数字
				int code = e.getKeyCode();
			    //如果按的是A键
				if(code==KeyEvent.VK_A) {
					mario.dir = App.DIR_LEFT;
					//让马里奥向左移动
					mario.x -= mario.mvSpeed;
					//改变马里奥显示的图片
					mario.changeImg();
				}
				//如果按的是D键
				if(code==KeyEvent.VK_D) {
					mario.dir = App.DIR_RIGHT;
					//让马里奥向左移动
					mario.x += mario.mvSpeed;
					//改变马里奥显示的图片
					mario.changeImg();
				}
				//如果按的是空格键
				if(code==KeyEvent.VK_SPACE) {
					//重新设置马里奥上抛运动的初始速度
					mario.jump();
					
				}
				//刷新界面,让马里奥显示到新的位置上
				repaint();
			}
		};
		//3.将适配器加入到监听器中
		addKeyListener(adapter);
	}
	/**
	 * 检查马里奥采蘑菇的方法
	 */
	protected void caimogu() {
        //所有的蘑菇有可能被马里奥踩到
		for(int i=0;i<ms.size();i++) {
			//获取一个蘑菇
			Mushroom m = ms.get(i);
			if(m.caiBy(mario)) {
				//让马里奥挑一下
				mario.jump();
				//让蘑菇死亡
				m.goDie();
				//JAVA计时器
				Timer timer = new Timer();
				timer.schedule(new TimerTask(){				
					@Override
					public void run() {	
						ms.remove(m);
					}
				},1000);
				
			}
		}	
	}
	/**
	 * 画图专用方法
	 * 打paint 按键盘的 ALT+?  敲回车
	 * Graphics g 画笔
	 */
	@Override
	public void paint(Graphics g) {
		super.paint(g);
		//设置画笔颜色(在画笔之前设置)
		//g.setColor(Color.red);
		
		//画背景图
		//g.drawImage(图片,横坐标, 纵坐标,null);
		g.drawImage(bg, 0, 0,1920, 600, null);
		
		//画马里奥的图片
		g.drawImage(mario.img,mario.x, mario.y, mario.w,mario.h,null);
		
		//遍历所有的蘑菇,画蘑菇
		for(int i=0;i<ms.size();i++) {
			//获取一个蘑菇
			Mushroom m = ms.get(i);
			//画蘑菇
			g.drawImage(m.img, m.x, m.y, m.w, m.h, null);
			
		}
		
		
	}
	
}

package ui;
import java.awt.image.BufferedImage;
import java.io.IOException;
import javax.imageio.ImageIO;
public class ImageUtil{
	
	public static BufferedImage getImg(String path) {
		
		try {
			BufferedImage img = ImageIO.read(ImageUtil.class.getResource(path));
			return img;
		} catch (IOException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		return null;
	}
}
package ui;
import java.awt.image.BufferedImage;
import java.util.ArrayList;
import java.util.List;
/**
 * 玛丽奥 的类
 * @author Administrator
 *
 */
public class Mario {
	//玛丽奥当前显示的图片
	BufferedImage img;
	//横坐标
	int x;
	//纵坐标
	int y;
	//宽度
	int w;
	//高度
	int h;
	//定义一个集合,用来存放向右移动动画数组的图片
	List<BufferedImage> imgR = new ArrayList<BufferedImage>();
	//定义一个集合,用来存放向左移动动画数组的图片
	List<BufferedImage> imgL = new ArrayList<BufferedImage>();
	//定义向右跳跃的图片
	BufferedImage jumpR = ImageUtil.getImg("/img/marioR5.gif");
	//定义向左跳跃的图片
	BufferedImage jumpL = ImageUtil.getImg("/img/10.gif");
	int mvSpeed = 5;
	//马里奥移动的方向
	int dir = App.DIR_RIGHT;
	//
	double g = 8; //重力加速度
	double t = 0.25; //移动的时间
	double s; //t时间后位移
	double speed = 40; //初始速度
	int groundY;//马里奥在地面的纵坐标
	
	boolean isJump;//是否处于跳跃状态下的开关
	public void step() {
		//定义初始速度
		double v0 = speed;
		//t时间后位移
		s = v0*t - 1/2*g*t*t;
		//计算t时间后当前速度
		double vt = v0-g*t;
		speed = vt;
		//修改马里奥的纵坐标
		y -=(int)s;
		//如果马里奥下落到地面位置时
		if(y>=groundY) {
			//让马里奥停留在地面位置
			y = groundY;
			if(dir==App.DIR_RIGHT) {
				img = imgR.get(0);
			}else {
				img = imgL.get(0);
			}
		}
	}
	/**
	 * 构造方法:玛丽奥的模具
	 */
	public Mario() {
		for(int i=1;i<=4;i++) {
			//加载向右移动的动画图片,并加入到向右的集合中
			//imgR.add(ImageUtil.getImg("/img/marioL/"+i+".gif"));
			//加载向左移动的动画图片,并加入到向右的集合中
			//imgL.add(ImageUtil.getImg("/img/marioR/"+i+".gif"));
		}
		//确定玛丽奥显示的图片
		img = ImageUtil.getImg("/img/marioR1.gif");
		//确认玛丽奥的大小(用图片的大小,作为玛丽奥的大小)
		w = img.getWidth();
		h = img.getHeight();
		//确定玛丽奥游戏开始时显示的位置
		x = 400;
		//确认马里奥在地位置
		groundY = y = 600-h-50;
	}
	
	//下标:  0   1    2   3 
	//图片:{ 图1, 图2, 图3, 图4}
	//定义下标,用来从集合中选取显示的图片
	int index = 0;
	public void changeImg() {
		//下标增加
		index ++;//自加1
		if(index==imgR.size()) {
			//让下标归0,继续从第一张图片开始显示
			index = 0;
		}
		//如果方向向右
		if(dir==App.DIR_RIGHT) {
			//自加后,从集合中取出图片,替换马里奥当前显示的图片
			img = imgR.get(index);
		}else {
			//从向左的集合中取出图片
			img = imgL.get(index);
		}	
		
	}
	//马里奥跳跃
	public void jump() {
		isJump = true;//跳跃的开关打开
		speed = 40;
		if(dir==App.DIR_RIGHT) {
			img = jumpR;
		}else {
			img = jumpL;
		}
	}







}

package ui;
import java.awt.image.BufferedImage;
//蘑菇类
public class Mushroom {
	//蘑菇显示的图片
	BufferedImage img;
	int x;	
	int y;	
	int w;
	int h;
	
	//蘑菇死亡图片
	BufferedImage deadImg = ImageUtil.getImg("/img/dead.png");
	
	public Mushroom() {
		//确定游戏开始时蘑菇显示的图片
		img = ImageUtil.getImg("/img/0.png");
		//确认蘑菇的大小
		w = img.getWidth();
		h = img.getHeight();
		x = 1920-w;
	    y = 600-h-50;
	}
	public boolean caiBy(Mario m) {
		boolean hit = x<=m.x+m.w&&x>=m.x-w&&y<=m.y+m.h;
		return hit&&m.isJump;
	}
	boolean isDie;//蘑菇是否死亡开关
	/**
	 * 让蘑菇死亡
	 */
	public void goDie() {
		//修改蘑菇当前显示的图片为死亡图片
		img = deadImg;
		//判定蘑菇已经死亡
		isDie = true;
		//重新获取死亡图片的大小
		w = img.getWidth();
		h = img.getHeight();
		//重新设置蘑菇地面的位置
		y = 600-h-50;
		
		
		
	}
	

}
package ui;

import java.io.ByteArrayInputStream;
import java.io.DataInputStream;
import java.io.File;
import java.io.IOException;
import java.io.InputStream;
import javax.sound.sampled.AudioFormat;
import javax.sound.sampled.AudioInputStream;
import javax.sound.sampled.AudioSystem;
import javax.sound.sampled.DataLine;
import javax.sound.sampled.LineUnavailableException;
import javax.sound.sampled.SourceDataLine;
import javax.sound.sampled.UnsupportedAudioFileException;
//音频类
public class MusicThread extends Thread {
	//定义一个成员变量fileName
	private String fileName;
	//音频格式
	private AudioFormat format;
    //存放音频文件的内用
	private byte[] samples;
	public  MusicThread(String fileName){
		this.fileName = fileName;
		reverseMusic();
	}
	public void reverseMusic(){
		try {
			AudioInputStream stream =AudioSystem.getAudioInputStream(new File(fileName));
			format = stream.getFormat();
			samples = getSamples(stream);
		}
		catch (UnsupportedAudioFileException ex) {
			ex.printStackTrace();
		}
		catch (IOException ex) {
			ex.printStackTrace();
		}
	}

	public byte[] getSamples(AudioInputStream audioStream) {

		int length = (int)(audioStream.getFrameLength() * format.getFrameSize());

		byte[] samples = new byte[length];

		DataInputStream is = new DataInputStream(audioStream);

		try {

			is.readFully(samples);

		}catch (IOException ex) {
			ex.printStackTrace();
		}
		return samples;
	}

	public void play(InputStream source) {
	    //获得每秒中播放的文件大小
		int bufferSize = format.getFrameSize() *
				Math.round(format.getSampleRate());//具有此格式的声音每秒播放或录制的样本数
		byte[] buffer = new byte[bufferSize];
		
		SourceDataLine line;
		try {
			DataLine.Info info =
					new DataLine.Info(SourceDataLine.class, format);
			line = (SourceDataLine)AudioSystem.getLine(info);
			line.open(format, bufferSize);
		}
		catch (LineUnavailableException ex) {
			ex.printStackTrace();
			return;
		}
		
		line.start();
		
		try {
			int numBytesRead = 0;
			while (numBytesRead != -1) {		
				numBytesRead =source.read(buffer, 0, buffer.length);
				if (numBytesRead != -1) {
					line.write(buffer, 0, numBytesRead);
				}
			}		
		}
		catch (IOException ex) {
			ex.printStackTrace();
		}	
		line.drain();
		line.close();
	}
	public void run(){		
		InputStream stream =new ByteArrayInputStream(samples);			
		play(stream);

}

}
package ui;

public class App {
	/**
	 * 方向向左
	 */
	public static int DIR_LEFT =1;

	/**
	 * 方向向右
	 */
	public static int DIR_RIGHT =2;
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值