项目实战之天天酷跑(四):游戏主界面

本文摘自:https://blog.csdn.net/qq_45909299/article/details/110306321

项目源码及相关图片资源,已上传至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;
    }
    
}
View Code

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;
}
  
}
View Code

需要注意的是,在创建后,记得添加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;
}

}
View Code

障碍物三、导弹

在这里插入图片描述

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;
    }
    

}
View Code

障碍物四:鱼叉等障碍物

在这里插入图片描述

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;
    }
    
}
    
View Code

障碍物五、金币

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

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;
        }

}
View Code

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    );
            }    
        }
    }
View Code

以下动图演示了玩家从右边与障碍物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
}
}
View Code
I have a dream : Sandy beach B-J-N.
原文地址:https://www.cnblogs.com/mjtabu/p/14380838.html