Java学习笔记_17 项目实战之天天酷跑(四):游戏主界面

项目源码及相关图片资源,已上传至GitHub,有需要的朋友自取吧。

https://github.com/HueyM/Projects

接上文,本文将实现游戏主界面,功能如下:

移动的背景图片、动态的玩家、玩家的移动功能、
五种障碍物持续出现、玩家和障碍物的碰撞、
暂停、继续功能。

首先,看一下整体效果:

动图实在太大,几秒钟的 Gif 就十几兆了。无奈,图片展示效果。

跳跃、得分、下落、障碍物:
在这里插入图片描述
碰到障碍物后,玩家被推着走。
在这里插入图片描述

下面,分别解释一下每个功能的逻辑:

一、创建一个显示窗体,承载游戏的主面板类。

GameFrame.java

package cn.sqc.runday.view;

import javax.swing.ImageIcon;
import javax.swing.JFrame;

import cn.sqc.runday.controller.GamePanel;

/**
 * @author Huey
 *2020-11-27  下午12:40:22
 * 游戏主界面:显示窗体,承载游戏的主面板类
 */

public class GameFrame extends JFrame {
    
    
	//设置窗体宽高属性
	public static final int WIDTH=1500;
	public static final int HEIGHT=900;
	public GameFrame() {
    
    
		//2.4创建游戏面板对象,并添加到窗体上去
		GamePanel panel = new GamePanel();
		panel.action();//程序启动的方法
		this.addKeyListener(panel);//谁实现就监听谁
		this.add(panel);
		
		/**1.设置窗体基本属性*/
		this.setSize(WIDTH,HEIGHT);
		this.setLocationRelativeTo(null);
		this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
		this.setIconImage(new ImageIcon("Image/115.png").getImage());
		this.setUndecorated(true);
		this.setVisible(true);	
	}
	
	public static void main(String[] args) {
    
    
		new GameFrame();
	}
}

二、游戏主面板类(核心逻辑类):

1、背景图片滚动效果

使用两张背景图片,实现背景图片滚动效果的逻辑如下:
在这里插入图片描述
下面用动图演示一下:
在这里插入图片描述

2、玩家动态效果

我国早期很有名的一部动画片《大闹天宫》,由于当时没有电脑,所以需要一帧一帧的画,随后快速播放图片,形成动态的画面(我愿称之:真·动画),并为之配音,短短10分钟的动画却要画7000到10000张原画!

而此处,我们的玩家的奔跑姿态,同理是由九张图片构成。
在这里插入图片描述
下面动图演示:
在这里插入图片描述
下面是实现玩家的(生成、移动、绘制)的基本代码,后面的障碍物的实现,也都遵循这一编写逻辑。

为更方便读懂代码,已尽力注释,若仍有不清楚的地方,欢迎留言交流。

Person.java

package cn.sqc.runday.model;

import java.awt.Graphics;
import java.awt.Image;
import java.io.File;
import java.io.IOException;

import javax.imageio.ImageIO;

import cn.sqc.runday.view.GameFrame;

/**
 * @author Huey
 * @date 2020-11-23
 * 玩家的实体类
 */
public class Person {
    
    //1.声明属性
	private Image image;//1.1 玩家当前显示图片
	private Image[] images;//1.2 玩家所有图片
	
	public static final int WIDTH = 120;//1.3玩家宽高
	public static final int HEIGHT = 120;
	
	//1.4玩家初始位置坐标
	private int x,y;
	int index;//下面用作切换图片
	//玩家得分
	private int score;
	//玩家跑酷距离
	private int distance;
	
	public Person() {
    
    //2.赋值
		//给图片数组images赋值
		init();//2.1	先写,会提示要不要实现!自动生成方法
		//默认当前显示图片位第一张图片 2.6
		image = images[0];
		
		x = 90;//2.7
		y = 580;//脚踩地板
		index = 0;
		score = 0;
		distance = 0;
	}
	//玩家自由下落方法5.1
	public void drop() {
    
    
		y += 5;
		if(y>=580){
    
    // 下落归下落,也得温柔点,不能让小人儿踩破了地板
			y = 580;
		}
	}
	//玩家移动的方法
	public void step(){
    
    
		//玩家图片的切换
		image = images[index ++ /3%images.length];
		//玩家坐标改变(玩家坐标通过键盘控制,此次不做处理)
	}
	//绘制玩家的方法
	public void paintPerson(Graphics g){
    
    
		g.drawImage(image, x, y, WIDTH, HEIGHT, null);
	}

	//判断玩家是否越界的方法
	public boolean outOfBounds(){
    
    
		return this.x >= GameFrame.WIDTH || this.x <= -WIDTH;
	}
	private void init() {
    
    //2.2
		images = new Image[9];
		for(int i = 0; i<images.length; i++){
    
    //2.3
			try {
    
    //2.5
				images[i] = ImageIO.read(new File("Image/"+(i+1) + ".png"));//2.4
			} catch (IOException e) {
    
    //2.5
				// TODO Auto-generated catch block
				e.printStackTrace();
			}
		}
	}
//2.8  右键,Source,GGAS
	public Image getImage() {
    
    
		return image;
	}

	public void setImage(Image image) {
    
    
		this.image = image;
	}

	public Image[] getImages() {
    
    
		return images;
	}

	public void setImages(Image[] images) {
    
    
		this.images = images;
	}

	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 static int getWidth() {
    
    
		return WIDTH;
	}

	public static int getHeight() {
    
    
		return HEIGHT;
	}
	public int getIndex() {
    
    
		return index;
	}
	public void setIndex(int index) {
    
    
		this.index = index;
	}
	public int getScore() {
    
    
		return score;
	}
	public void setScore(int score) {
    
    
		this.score = score;
	}
	public int getDistance() {
    
    
		return distance;
	}
	public void setDistance(int distance) {
    
    
		this.distance = distance;
	}
	
}

3、几种障碍物的出现

障碍物一:螃蟹

在这里插入图片描述

package cn.sqc.runday.model;

import java.awt.Graphics;
import java.awt.Image;
import java.awt.Paint;
import java.io.File;

import javax.imageio.ImageIO;

import cn.sqc.runday.view.GameFrame;

public class Barrs_1 {
    
    
	private Image image;
	private Image [] images;
	public static final int WIDTH=100;
	public static final int HEIGHT=110;
	private int x,y;
	int  index;
	private int speed;
	
	public Barrs_1() {
    
    //		螃蟹!
		images = new Image[2];
		try {
    
    
			images[0]=ImageIO.read(new File("image/a2.png"));
			images[1]=ImageIO.read(new File("image/a4.png"));		
		} catch (Exception e) {
    
    
			// TODO: handle exception
		}		
		image = images[0];
		x=GameFrame.WIDTH+100;
		y=580;
		speed =30;
		index = 0;
	}
	
	public  void step() {
    
    //切换图片
		image =images[index++/5%images.length];
		x-=speed;//切换图片实现螃蟹爪子张合的动态效果的同时,使其向左移动
	}
  public void paintBarrs(Graphics g) {
    
    
	g.drawImage(image, x,y,WIDTH,HEIGHT, null);
}
  public boolean outofBounds(){
    
    
		return this.x <=-WIDTH;
	}
public Image getImage() {
    
    
	return image;
}
public void setImage(Image image) {
    
    
	this.image = image;
}
public Image[] getImages() {
    
    
	return images;
}
public void setImages(Image[] images) {
    
    
	this.images = images;
}
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 int getIndex() {
    
    
	return index;
}
public void setIndex(int index) {
    
    
	this.index = index;
}
public int getSpeed() {
    
    
	return speed;
}
public void setSpeed(int speed) {
    
    
	this.speed = speed;
}
public static int getWidth() {
    
    
	return WIDTH;
}
public static int getHeight() {
    
    
	return HEIGHT;
}
  
}

需要注意的是,在创建后,记得添加set、get方法。以便在面板类中对其障碍物进行操作。

障碍物二:宠物

与其称之障碍物,不如说它是个跟着玩家的小跟班。

在这里插入图片描述
在这里插入图片描述

package cn.sqc.runday.model;

import java.awt.Graphics;
import java.awt.Image;
import java.awt.event.KeyListener;
import java.io.File;
import java.io.IOException;

import javax.imageio.ImageIO;

import cn.sqc.runday.view.GameFrame;

public class Barrs_2{
    
      //  宠物!
	private Image image;
	private Image images [] ;
	public static final int WIDTH= 70;
	public static final int HEIGHT = 60;
	private int x,y;
	int index;
	public Barrs_2() {
    
    
		init();
		image = images[0];
		x=300;
		y=460;
	}
	public void drop() {
    
    
		y ++;
		if(y>=460){
    
    
			y = 460;
		}
	}
	public void step(){
    
    
		image = images[index++/2%images.length];
	}
	 public void paintBarrs(Graphics g) {
    
    
			g.drawImage(image, x,y,WIDTH,HEIGHT, null);
		}
	public boolean outofBounds() {
    
    
		return this.x<=-WIDTH;
	}
public void init(){
    
    
	images = new Image[6];
	for( int i=0;i<6;i++){
    
    
		try {
    
    
			images[i]=ImageIO.read(new File ("Image/"+"d"+(i+1)+".png"));
		} catch (IOException e) {
    
    
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
	}
}
public Image getImage() {
    
    
	return image;
}
public void setImage(Image image) {
    
    
	this.image = image;
}
public Image[] getImages() {
    
    
	return images;
}
public void setImages(Image[] images) {
    
    
	this.images = images;
}
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 int getIndex() {
    
    
	return index;
}
public void setIndex(int index) {
    
    
	this.index = index;
}
public static int getWidht() {
    
    
	return WIDTH;
}
public static int getHeight() {
    
    
	return HEIGHT;
}

}

障碍物三、导弹

在这里插入图片描述

package cn.sqc.runday.model;

import java.awt.Graphics;
import java.awt.Image;
import java.io.File;

import javax.imageio.ImageIO;

import cn.sqc.runday.view.GameFrame;

public class Barrs_3 {
    
    // 		导弹!
	private Image image;
	private int x,y;
	public static final int WIDTH = 150;
	public static final int HEIGHT=70;
	private int speed;
	public Barrs_3() {
    
    
		try {
    
    
			image = ImageIO.read(new File("image/daodan.png"));
		} catch (Exception e) {
    
    
			// TODO: handle exception
		}
		x=GameFrame.WIDTH+1000;
		y=450;
		speed = 25 ;
	}
	public void step(){
    
    
		x-=speed;
	}
	public void paintBarrs(Graphics g) {
    
    
		g.drawImage(image, x, y, WIDTH, HEIGHT, null);

	}
	public boolean outofBounds(){
    
    
		return this.x<=-WIDTH;
	}
	public Image getImage() {
    
    
		return image;
	}
	public void setImage(Image image) {
    
    
		this.image = image;
	}
	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 int getSpeed() {
    
    
		return speed;
	}
	public void setSpeed(int speed) {
    
    
		this.speed = speed;
	}
	public static int getWidth() {
    
    
		return WIDTH;
	}
	public static int getHeight() {
    
    
		return HEIGHT;
	}
	

}

障碍物四:鱼叉等障碍物

在这里插入图片描述

package cn.sqc.runday.model;

import java.awt.Graphics;
import java.awt.Image;
import java.io.File;
import java.util.Random;

import javax.imageio.ImageIO;

import cn.sqc.runday.view.GameFrame;

public class Barrs_4 {
    
    //		鱼叉障碍物!
	private Image image;
	private Image images[];
	public static final int WIDTH =150;
	public static final int HEIGHT =350;
	private int x,y;
	
	public Barrs_4() {
    
    //构造方法
		Random random = new Random();
		images = new Image[4] ;
	try {
    
    
		images[0] = ImageIO.read(new File("image/11.png"));
		images[1]= ImageIO.read(new File("image/12.png"));
		images[2]= ImageIO.read(new File("image/13.png"));
		images[3]= ImageIO.read(new File("image/14.png"));
	} catch (Exception e) {
    
    
		// TODO: handle exception
	}
		image= images[random.nextInt(4)];
		x=GameFrame.WIDTH+1500;
		y=0;
	}
	public void step(){
    
    
		x-=20;
	}
	public void paintBarrs(Graphics g){
    
    
		g.drawImage(image, x, y, WIDTH, HEIGHT, null);
	}
	public boolean outofBounds(){
    
    
		return this.x<=-WIDTH;
	}
	public Image getImage() {
    
    
		return image;
	}
	public void setImage(Image image) {
    
    
		this.image = image;
	}
	public Image[] getImages() {
    
    
		return images;
	}
	public void setImages(Image[] images) {
    
    
		this.images = images;
	}
	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 static int getWidth() {
    
    
		return WIDTH;
	}
	public static int getHeight() {
    
    
		return HEIGHT;
	}
	
}
	

障碍物五、金币

在这里插入图片描述
在此,暂且先不写金币的动态效果。

package cn.sqc.runday.model;

import java.awt.Graphics;
import java.awt.Image;
import java.io.File;
import java.io.IOException;
import java.util.Random;

import javax.imageio.ImageIO;

import cn.sqc.runday.view.GameFrame;

/**
 * @author Huey
 *2020-11-30  下午03:44:51
 *金币障碍物类
 * 
 */
public class Barrs_5 {
    
    
		private Image image;//当前显示图片
		public static final int WIDTH = 30;
		public static final int HEIGHT = 30;
		private int x,y;
		private int speed;
		Random random = new Random();
		public Barrs_5() {
    
    
			try {
    
    
				image = ImageIO.read(new File("Image/"+(random.nextInt(6) + 21) + ".png"));
			} catch (IOException e) {
    
    
				// TODO Auto-generated catch block
				e.printStackTrace();
			}
			x = GameFrame.WIDTH + 10;
			y = random.nextInt(600);
			speed = 20;
		}
		
		public void step(){
    
    
			x -= speed;
		}
		
		public void paintBarrs(Graphics g){
    
    
			g.drawImage(image, x, y, WIDTH, HEIGHT, null);
		}
		public boolean outofBounds() {
    
    
			return this.x<=-WIDTH;
		}

		public Image getImage() {
    
    
			return image;
		}

		public void setImage(Image image) {
    
    
			this.image = image;
		}

		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 int getSpeed() {
    
    
			return speed;
		}

		public void setSpeed(int speed) {
    
    
			this.speed = speed;
		}

		public Random getRandom() {
    
    
			return random;
		}

		public void setRandom(Random random) {
    
    
			this.random = random;
		}

		public static int getWidth() {
    
    
			return WIDTH;
		}

		public static int getHeight() {
    
    
			return HEIGHT;
		}

}

4、玩家和障碍物的碰撞逻辑

以玩家与导弹的碰撞举例:

for(int i = 0;i<barrs3.length;i++){
    
    
		if(person.getX() + Person.WIDTH >= barrs3[i].getX() &&
		person.getX() <= barrs3[i].getX()	 + Barrs_3.WIDTH  &&
		person .getY() +Person.getHeight() >= barrs3[i].getY() &&
		person.getY()	<= barrs3[i].getY () + Barrs_3.HEIGHT){
    
    
			if(person.getX() + Person.WIDTH <= barrs3[i].getX() + Barrs_3.WIDTH){
    
    //玩家的宽度(120px)是比障碍物小的
				//左碰撞
				person.setX(barrs3[i].getX()  - Barrs_3.WIDTH);
			}else{
    
    
				//右碰撞
				person.setX(barrs3[i].getX()+ Barrs_3.WIDTH	);
			}	
		}
	}

以下动图演示了玩家从右边与障碍物b发生碰撞和从左边碰撞的逻辑,上下碰撞同理。

上下左右碰撞的逻辑代码,在动图下方:
在这里插入图片描述

5、暂停、继续逻辑

在监听键盘按键的方法中。
在这里插入图片描述
代码如下:
在这里插入图片描述
此处的 flag 来源于上面程序启动的方法中,不难看出只要按了空格键,就能实现生成、移动、绘制方法的暂停,也就相当于画面的静止、游戏的暂停!
在这里插入图片描述

6、结束逻辑

后面再实现。

游戏主界面代码如下:

package cn.sqc.runday.controller;

import java.awt.Color;
import java.awt.Font;
import java.awt.Graphics;
import java.awt.Image;
import java.awt.event.KeyEvent;
import java.awt.event.KeyListener;
import java.io.File;
import java.io.IOException;
import java.util.Arrays;

import javax.imageio.ImageIO;
import javax.swing.JPanel;

import cn.sqc.runday.model.Barrs_1;
import cn.sqc.runday.model.Barrs_2;
import cn.sqc.runday.model.Barrs_3;
import cn.sqc.runday.model.Barrs_4;
import cn.sqc.runday.model.Barrs_5;
import cn.sqc.runday.model.Person;
import cn.sqc.runday.view.EndFrame;
import cn.sqc.runday.view.GameFrame;

/**
 * @author Huey
 *2020-11-27  下午12:28:44
 * 游戏主面板类,核心逻辑类
 *           1、背景图片滚动效果
 *           2、玩家动态效果
 *           3、五种障碍物的出现
 *           4、玩家和障碍物的碰撞逻辑
 *           5、暂停、继续逻辑
 *           6、结束逻辑
 */

public class GamePanel extends JPanel implements KeyListener{
    
    
	/**2、生成动态的背景图片***/
	//2.1声明背景图片对象
	Image background;
	Image score;
	Image pause;//暂停
	Image  proceed;//继续.
	
	
	/***3.实现玩家的动态效果和移动功能***/
	//3.1创建玩家对象(类的实例化)
	Person person;
	Barrs_2 barrs_2;//宠物
	Barrs_4 barrs_4;//鱼钩等障碍物
	Barrs_5 barrs_5;//金币
	/**4.实现螃蟹障碍物*/
	//4.1
	Barrs_1[]barrs1 = {
    
    };//存储螃蟹数组(没有元素,可以扩容)
	Barrs_3[]barrs3 ={
    
    };//导弹
	Barrs_4[]barrs4={
    
    };//鱼钩
	Barrs_5[]barrs5 = {
    
    };//金币
	
	public GamePanel() {
    
    
		//3.2
		person = new Person();//调用Person类的构造方法,创建对象并赋值
		barrs_2 = new Barrs_2();
		//2.2读取图片文件
		try{
    
    
			background =ImageIO.read(new File("Image/cc.png"));//跑酷背景
			score =ImageIO.read(new File("Image/a12.png"));//得分背景
			pause = ImageIO.read(new File("Image/b2.png"));
			proceed = ImageIO.read(new File("Image/b1.png"));
		}catch(IOException e){
    
    
			e.printStackTrace();
		}
	}
	//2.5
	int x=0;//背景图片初始位置
@Override
public void paint(Graphics g) {
    
     
	super.paint(g);
	//2.7
	if(flag){
    
    
		x-=20;//图片滚动的速度
	}
		//2.3绘制背景图片(动态切换很流畅)
		g.drawImage(background, x, 0, GameFrame.WIDTH, GameFrame.HEIGHT, null);
		g.drawImage(background, x+GameFrame.WIDTH, 0, GameFrame.WIDTH, GameFrame.HEIGHT,null);
		if(x<=-GameFrame.WIDTH){
    
    //实现两张图片之间的切换
			x = 0;
		}
	
	//3.3绘制 玩家
	person.paintPerson(g);
	//绘制螃蟹
	for(int i =0;i<barrs1.length;i++){
    
    
		barrs1[i].paintBarrs(g);
	}
	//绘制宠物
	barrs_2.paintBarrs(g);
	//绘制导弹
	for(int i =0;i<barrs3.length;i++){
    
    
		barrs3[i].paintBarrs(g);
	}
	//随机绘制鱼钩障碍物
	for(int i =0;i<barrs4.length;i++){
    
    
		barrs4[i].paintBarrs(g);
	}
	//随机绘制金币
	for(int i = 0;i<barrs5.length;i++){
    
    
		barrs5[i].paintBarrs(g);
	}
	
	
//位置越往下,图层越往上
	//绘制玩家分数
	g.drawImage(score, 120, 50,null);
	g.setColor(Color.ORANGE);
	g.setFont(new Font("宋体",Font.BOLD,30 ));
	g.drawString("玩家得分:"+person.getScore()+"分", 133, 95);
	
	//绘制暂停、继续标识图片
	if(flag){
    
    
					g.drawImage(proceed, 200, 800, 90,90,null);
	}else{
    
    
				g.drawImage(pause, 200, 800, 90, 90, null);
	}
	
}

//生		成	障	碍	物	的	方	法
int index =0;
public void enteredAction(){
    
    //实现源源	不	断	生成障碍物的效果
	index++;
	//生成螃蟹障碍物
	if(index%100==0){
    
    
		//生成一个螃蟹
		Barrs_1 b1 = new Barrs_1();
		Barrs_3 b3 = new Barrs_3();
		Barrs_4 b4 = new Barrs_4();
		
		barrs1 =Arrays.copyOf(barrs1,barrs1.length+1);//数组扩容
		barrs1[barrs1.length-1]= b1;//放到数组最后一个元素的位置
		//System.out.println("测试"+barrs1.length);		
		barrs3 =Arrays.copyOf(barrs3,barrs3.length+1);
		barrs3[barrs3.length-1]= b3;
		barrs4 =Arrays.copyOf(barrs4,barrs4.length+1);
		barrs4[barrs4.length-1]= b4;
	}
	if(index%15==0){
    
    
		Barrs_5 b5 = new Barrs_5();
		barrs5 = Arrays.copyOf(barrs5, barrs5.length +1);
		barrs5[barrs5.length-1] = b5;
	}
}


//移		动	方	法
public void stepAction(){
    
    
	//3..4
		person.step();//切换玩家的图片—>动起来
		person.drop();//不断下坠
		barrs_2.drop();
		//螃蟹障碍物移动
	for(int i =0;i<barrs1.length;i++){
    
    
		barrs1[i].step();
		//判断当前障碍物是否 越界,并做越界处理
		if(barrs1[i].outofBounds()){
    
    
			//删除越界的螃蟹障碍物
			barrs1[i] = barrs1[barrs1.length - 1];//将螃蟹数组最后一个元素,赋给越界的螃蟹,覆盖了,相当于间接删除了。
			barrs1= Arrays.copyOf(barrs1, barrs1.length - 1);//数组缩容
		}
	}
	
	barrs_2.step();
	
	for(int i =0;i<barrs3.length;i++){
    
    
			barrs3[i].step();
		//删除越界的导弹障碍物
		if(barrs3[i].outofBounds()){
    
    
			barrs3[i] = barrs3[barrs3.length - 1];
			barrs3 = Arrays.copyOf(barrs3, barrs3.length - 1);
		}
	}
	
	for(int i =0;i<barrs4.length;i++){
    
    
		barrs4[i].step();
		//删除越界的鱼叉障碍物
		if(barrs4[i].outofBounds()){
    
    
		barrs4[i] = barrs4[barrs4.length - 1	];
		barrs4 = Arrays.copyOf(barrs4, barrs4.length - 1);
		}
	}
	for(int i = 0;i<barrs5.length;i++){
    
    
		barrs5[i].step();
		if(barrs5[i].outofBounds()){
    
    
			//删除越界的金币
			barrs5[i] = barrs5[barrs5.length - 1];
			barrs5 = Arrays.copyOf(barrs5, barrs5.length - 1);
		}
	}
}

//玩家和障碍物碰撞的处理方法
public void pengAction(){
    
    
	//判断玩家是否和螃蟹障碍物进行碰撞
	for(int i = 0;i<barrs1.length;i++){
    
    //上下左右都写了,下是用不到的
		if(person.getX() + Person.WIDTH >= barrs1[i].getX() &&
		person.getX() <= barrs1[i].getX()	 + Barrs_1.WIDTH  &&
		person .getY() +Person.getHeight() >= barrs1[i].getY() &&
		person.getY()	<= barrs1[i].getY () + Barrs_1.HEIGHT){
    
    
			//碰撞后的处理(遮挡类障碍物)
			if(person.getX() + Person.WIDTH <= barrs1[i].getX() + Barrs_1.WIDTH){
    
    //防止人在右边,碰撞后可以穿过障碍物
				//左碰撞
				person.setX(barrs1[i].getX()  - Barrs_1.WIDTH);
			}else{
    
    
				//右碰撞
				person.setX(barrs1[i].getX()+ Barrs_1.WIDTH	);
			}						
		}
	}
	//判断玩家是否和导弹障碍物进行碰撞
	for(int i = 0;i<barrs3.length;i++){
    
    
		if(person.getX() + Person.WIDTH >= barrs3[i].getX() &&
		person.getX() <= barrs3[i].getX()	 + Barrs_3.WIDTH  &&
		person .getY() +Person.getHeight() >= barrs3[i].getY() &&
		person.getY()	<= barrs3[i].getY () + Barrs_3.HEIGHT){
    
    
			if(person.getX() + Person.WIDTH <= barrs3[i].getX() + Barrs_3.WIDTH){
    
    //玩家的宽度(120px)是比障碍物小的
				//左碰撞
				person.setX(barrs3[i].getX()  - Barrs_3.WIDTH);
			}else{
    
    
				//右碰撞
				person.setX(barrs3[i].getX()+ Barrs_3.WIDTH	);
			}	
		}
	}
	//判断玩家是否和鱼叉障碍物进行碰撞
	for(int i = 0;i<=barrs4.length -1;i++){
    
    //小心数组越界!
		if(person.getX() + Person.WIDTH >= barrs4[i].getX() &&
		person.getX() <= barrs4[i].getX() + Barrs_4.WIDTH &&
		person.getY() + Person.HEIGHT >= barrs4[i].getY() &&
		person.getY() <= barrs4[i].getY() + Barrs_4.HEIGHT	){
    
    
			if(person.getX() + Person.WIDTH <= barrs4[i].getX() + Barrs_4.WIDTH	){
    
    
				//左碰撞
				person.setX(barrs4[i].getX() - Barrs_4.WIDTH);
			}else{
    
    
				//右碰撞
				person.setX(barrs4[i].getX()+ Barrs_4.WIDTH	);
			}	
		}
	}
	//玩家和金币的碰撞
	for(int i = 0;i<barrs5.length;i++){
    
    
		if(person.getX() + Person.WIDTH >= barrs5[i].getX() &&
		person.getX() <= barrs5[i].getX()	 + Barrs_5.WIDTH  &&
		person .getY() +Person.getHeight() >= barrs5[i].getY() &&
		person.getY()	<= barrs5[i].getY () + Barrs_5.HEIGHT){
    
    //判断玩家与金币的碰撞
			if(person.getX() + Person.WIDTH <= barrs5[i].getX() + Barrs_5.WIDTH){
    
    
				//删除当前金币
				barrs5[i]	= barrs5[barrs5.length - 1];
				barrs5 = Arrays.copyOf(barrs5, barrs5.length - 1);
				
				//玩家加分
				int score = person.getScore();
				person.setScore(score + 10);
		   }
		}
	}
		
}
//结束逻辑
	public  void gameOverAction(){
    
    
		if(person.outOfBounds()){
    
    
			//程序结束
			isGameOver = true;
			//传递数据(创建结束界面)
			new EndFrame(person);//面向对象思想
			//数据清空
			person = new Person();
			barrs1 = new Barrs_1[]{
    
    };
			barrs3 = new Barrs_3[]{
    
    };
		}
		
	}
	public static boolean isGameOver = false;
	boolean flag = true; 
//2.8	创	建	一	个	程	序	启	动	的 	方	法
public void action(){
    
    
	new Thread(){
    
    //匿名内部类
		//重写run方法
		public void run() {
    
    
			while(!isGameOver){
    
    
				//3.4
				if(flag){
    
    
						enteredAction();//细节:只有先生成了障碍物后,下面才能调用移动障碍物的方法
						stepAction();
						pengAction();//玩家和障碍物碰撞
						gameOverAction();
					
				}
				//重绘方法
				repaint();
				//线程休眠
				try {
    
    
					Thread.sleep(60);
				} catch (Exception e) {
    
    
					// TODO: handle exception
					e.printStackTrace();
				}
			}
			
		};
	}.start();//创建一个线程并启动

	}

@Override
public void keyTyped(KeyEvent e) {
    
    
	// TODO Auto-generated method stub
	
}

@Override
public void keyPressed(KeyEvent e) {
    
    
	//获取玩家当前位置坐标
	 int x = person.getX();
	 int y = person.getY();
	 int x1 = barrs_2.getX();
	 int y1 = barrs_2.getY();

	//上
		if(e.getKeyCode() == KeyEvent.VK_UP	&&		y > 10	&&		y1 > 10){
    
    
			person.setY(y-25);
			barrs_2.setY(y-25);
		}
			//下
		if(e.getKeyCode()== KeyEvent.VK_DOWN	&&		y<=560		&&		y1<560){
    
    
			person.setY(y+30);
			barrs_2.setY(y-30);
		}
		//左
		if(e.getKeyCode()==KeyEvent.VK_LEFT		&& 	x>=0	){
    
    
			person.setX(x-30);
			barrs_2.setX(x1-30);
			
		}
		//右
		if(e.getKeyCode()==KeyEvent.VK_RIGHT){
    
    
			person.setX(x+22);
			barrs_2.setX(x1+22);
			if(x>=GameFrame.WIDTH-Person.WIDTH){
    
    //如果人物到了右边界
				person.setX(GameFrame.WIDTH-Person.WIDTH);
			}
			if(x1>=GameFrame.WIDTH-barrs_2.WIDTH){
    
    //如果宠物到了右边界
				barrs_2.setX(GameFrame.WIDTH - barrs_2.WIDTH);
			}
		}
		//暂停 继续功能
		if(e.getKeyCode() == KeyEvent.VK_SPACE){
    
    
				flag = !flag;
		}
		
	}

@Override
public void keyReleased(KeyEvent e) {
    
    
	// TODO Auto-generated method stub
}
}

个人学习笔记,若有误还望不吝赐教。

猜你喜欢

转载自blog.csdn.net/qq_45909299/article/details/110306321