JAVA课程设计(小游戏贪吃蛇)完整源码附素材(三)

目录

JAVA课程设计(小游戏贪吃蛇)完整源码附素材(一)​​​​​​

JAVA课程设计(小游戏贪吃蛇)完整源码附素材(二)

JAVA课程设计(小游戏贪吃蛇)完整源码附素材(三)

前言

1. 任务描述

1.1  课程设计目的

1.2  课程设计内容和要求

2. 系统分析与设计

2.1 系统总体结构

 三、源代码

总结


 

前言

此文章仅代表个人平时的学习知识分享,希望能帮助到大家,如果对大家有用给个点赞+加关注谢谢!(如果有问题请在评论区指出,我会给予回复)。

1. 任务描述

1.1  课程设计目的

本次课程设计是对前面学过的所有面向对象的编程思想以及编程方法的一个总结、回顾和实践。主要目的包括但不限于:

(1)综合使用各种图形用户界面设计组件,实现常见的功能,熟悉这些组件的使用方法,如选择框,下拉列表框。

(2)掌握一个的界面布局管理技术。

(3)掌握通过互联网查找资料的能力。

1.2  课程设计内容和要求

根据以前小时候经常喜爱的小游戏贪吃蛇的游戏模式、游戏内容和游戏特色设计了本次的课程设计内容贪吃蛇游戏,因为本身也是一个比较简单的游戏,内容并不是非常的复杂,因此这次课程设计我们实现了贪吃蛇游戏的一些基本游戏内容:

 

1、设置了三种游戏难度(简单、困难和地狱)依据小蛇移动速度快慢实现。

2、设置了两种模式(穿墙模式和撞墙模式)依据是否设置边界条件实现。

3、设置游戏的吃到食物的个数计数和分数计数。

4、设置了游戏失败的判断(在撞墙模式下撞墙和蛇头碰到蛇的身体)。

5、设置了图片的读入使整个游戏界面更加美观、同时设置了背景音乐。

本程序设计就是依照这些内容构建了一款简单而充满童年回忆的小游戏贪吃蛇。

2. 系统分析与设计

2.1 系统总体结构

本系统共包括3个Java源文件。

类之间的关系如图1所示。

a20191dc13a1423a90b2d198ab6ed83d.png

 三、源代码

3、 类SnakePanel

package snake;

import javax.swing.*;
import java.awt.*;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.KeyEvent;
import java.awt.event.KeyListener; 
import java.net.URL;
import java.util.Random;
public class SnakePanel extends JPanel implements KeyListener, ActionListener {
//标题栏
ImageIcon title =new ImageIcon("statics/headerdwj.png");
//蛇头
//上
ImageIcon up =new ImageIcon("statics/up.png");
//下
ImageIcon down =new ImageIcon("statics/down.png");
//左
ImageIcon left =new ImageIcon("statics/left.png");
//右
ImageIcon right =new ImageIcon("statics/right.png");

//蛇身
ImageIcon body =new ImageIcon("statics/body.png");
//食物
ImageIcon food =new ImageIcon("statics/food.png");
//分数
int score; 
//蛇的长度
int length;
int[] snakex = new int[700];//蛇的横坐标
int[] snakey = new int[700];//蛇的纵坐标
//蛇头方向
String direction;
int speed = 1; //蛇的速度
int modern = 0; //游戏模式:0为撞墙失败,1为可穿墙

boolean isStart; //游戏启动状态
boolean isFail;  //游戏是否失败
//创建timer对象,设置刷新时间100毫秒
Timer timer = new Timer(100,this);

//定义食物的坐标
Random r = new Random();
int foodx = r.nextInt(34)*25 + 25;
int foody = r.nextInt(23)*25 + 75;
//Random.nextInt()随机产生一个数,如果有参数就是在0到参数之间产生。

public SnakePanel(){
//让当前的Jpanel能获取焦点,这样在Jpanel的键盘事件才能起作用
init();
this.setFocusable(true);
this.addKeyListener(this);//添加键盘的监听
//刷新开始,实现动画
timer.start();
//创建选项栏
JMenuBar menuBar = new JMenuBar();
//添加标题,创建按键
JButton jb1 = new JButton("退出游戏");
JButton jb3 = new JButton("简单");
JButton jb4 = new JButton("困难");
JButton jb5 = new JButton("地狱");
JButton jb6 = new JButton("穿墙模式");
JButton jb7 = new JButton("撞墙模式");
//添加按键
menuBar.add(jb1);
menuBar.add(jb3);
menuBar.add(jb4);
menuBar.add(jb5);
menuBar.add(jb6);
menuBar.add(jb7);
jb1.addActionListener(e -> {//添加jb1的监听
      System.exit(0);//退出
 });
      jb3.addActionListener(e -> {
this.requestFocus();//不获取焦点后面操作键盘都会在菜单栏里,就无法操作蛇了
speed = 0 ;
timer.stop();//把原来的timer停止
timer = new Timer(120, this);//使蛇的速度变慢
timer.start();//重新开始timer
});
jb4.addActionListener(e -> {
this.requestFocus();//不获取焦点后面操作键盘都会在菜单栏里,就无法操作蛇了
speed = 2 ;
timer.stop();//把原来的timer停止
timer = new Timer(60, this);//使蛇的速度变快一点实现难度提升
      timer.start();//重新开始timer
});
jb5.addActionListener(e -> {
this.requestFocus();//不获取焦点后面操作键盘都会在菜单栏里,就无法操作蛇了
speed = 3 ;
timer.stop();//把原来的timer停止
timer = new Timer(40, this);//使蛇的速度变快很多实现难度提升
      timer.start();//重新开始timer
});
jb6.addActionListener(e -> {
this.requestFocus();//不获取焦点后面操作键盘都会在菜单栏里,就无法操作蛇了
      modern = 1;//游戏模式:0为撞墙失败
 });
jb7.addActionListener(e -> {
     this.requestFocus();//不获取焦点后面操作键盘都会在菜单栏里,就无法操作蛇了
     modern = 0;//游戏模式:1为可穿墙
});
//添加选项栏
this.add(menuBar);
Button jb2 =  new JButton("重新开始");
jb2.addActionListener(e -> {
init();//重新开始所以重新初始化一下
repaint();//重画
this.requestFocus();
});
  this.add(jb2);
}
//初始化一些值
public void init(){
score = 0;
length = 3;
direction = "R"; //默认蛇头向右
int speed = 1; //蛇的速度
int modern = 0; //游戏模式:0为撞墙失败,1为可穿墙
//蛇头坐标
snakex[0] = 100;
snakey[0] = 100;
//第一个蛇身坐标
snakex[1] = 75;
snakey[1] = 100;
//第二个蛇身坐标
snakex[2] = 50;
snakey[2] = 100;
isStart = false; //默认游戏未启动
 isFail = false; //默认游戏未失败
 }
//获取食物坐标(排除碰巧生成在小蛇身体上的食物坐标)
public int[] Foodxy(int foodxx,int foodyy){
for (int i = 0; i <length ; i++) {
    if (foodxx == snakex[i] && foodyy == snakey[i]) { //如果食物坐标与小蛇的坐标重合,则重新取随机值
         foodxx = 25 + 25 * r.nextInt(34);
         foodyy = 75 + 25 * r.nextInt(23);
         Foodxy(foodxx, foodyy);
         }
   }
   return new int[]{foodxx,foodyy};
}
@Override
//创建画笔对象Graphics
protected void paintComponent(Graphics g) {
//调用swing类中方法,进行界面重绘,保留界面中的原本组件
super.paintComponent(g);
title.paintIcon(this,g,25,21);  //画标题
//画笔变白色
g.setColor(Color.white);
g.fillRect(25,75,850,575);  //画一个白色的背景
//画笔变黑色
g.setColor(Color.black);
//第一步、画表格
//1.画横线 总共24条线 23行格子
for (int i =0 ; i < 24 ; i++){
     g.drawLine(25,75+i*25,875,75+i*25);
    }
//2.画竖线 总共35条线 34行格子
for (int i = 0; i < 35; i++){
    g.drawLine(25 + i*25 , 75 , 25 + i *25 , 650);
   }
if(modern == 0){     //撞墙模式下的提示红线
    g.setColor(Color.RED);
    g.drawLine(25 , 75 , 25 , 650);
    g.drawLine(26 , 75 , 26 , 650);
    g.drawLine(27 , 75 , 27 , 650);
    g.drawLine(28 , 75 , 28 , 650);

    g.drawLine(872 , 75 , 872 , 650);
    g.drawLine(873 , 75 , 873 , 650);
    g.drawLine(874 , 75 , 874 , 650);
    g.drawLine(875 , 75 , 875 , 650);

    g.drawLine(25 , 75 , 875 , 75);
    g.drawLine(25 , 76 , 875 , 76);
    g.drawLine(25 , 77 , 875 , 77);
    g.drawLine(25 , 78 , 875 , 78);

    g.drawLine(25 , 647 , 875 , 647);
    g.drawLine(25 , 648 , 875 , 648);
    g.drawLine(25 , 649 , 875 , 649);
    g.drawLine(25 , 650 , 875 , 650);
    }else if (modern == 1){      //穿墙模式下的灰线
    g.setColor(Color.lightGray);
    g.drawLine(25 , 75 , 25 , 650);
    g.drawLine(875 , 75 , 875 , 650);
    g.drawLine(25 , 75 , 875 , 75);
    g.drawLine(25 , 650 , 875 , 650);
    }
     //第二步、画分数
     g.setColor(Color.white);
     g.setFont(new Font("微软雅黑",Font.BOLD,18));
     g.drawString("分数:"+ score,750,43);
     g.drawString("长度:"+ length,750,68);
     //第三步、画蛇
     //1.画蛇头
     if("R".equals(direction)){
        right.paintIcon(this , g , snakex[0] , snakey[0]);
     }else if ("L".equals(direction)){
        left.paintIcon(this , g , snakex[0] , snakey[0]);
     }else if("U".equals(direction)){
        up.paintIcon(this , g , snakex[0] , snakey[0]);
     }else if("D".equals(direction)){
        down.paintIcon(this , g , snakex[0] , snakey[0]);
     }
     //2.画蛇身
     for(int i = 1; i < length; i++){
        body.paintIcon(this , g , snakex[i] , snakey[i]);
     }

     //第四步、画食物
     food.paintIcon(this , g , foodx , foody);
     //当游戏还没有启动时
     if (isStart == false){
            g.setColor(new Color(169,166,171));
            g.setFont(new Font("微软雅黑", Font.BOLD , 36));
            g.drawString("请按空格键开始/暂停",275,300);
            g.setFont(new Font("微软雅黑", Font.BOLD , 32));
            g.drawString("(默认为正常难度,撞墙模式)",238,350);
            g.setColor(new Color(232,212,119));
            g.setFont(new Font("微软雅黑", Font.BOLD , 22));
            g.drawString("按下J键可以冲刺喔~",338,630);
     }
     if(isFail == true){
            g.setColor(Color.RED);
            g.setFont(new Font("微软雅黑", Font.BOLD , 36));
            g.drawString("游戏失败!请按空格键重新开始" , 225 , 300);
        }
    }
@Override
public void keyPressed(KeyEvent e) {    //
 int keyCode = e.getKeyCode();         //赋值
//空格键控制游戏开始暂停
 if (keyCode == KeyEvent.VK_SPACE) {
     if (isFail) {   //游戏失败,重新开始
        isFail = false;
        init();    //初始化
     } else {
        isStart = !isStart;
     }
     repaint();     //刷新界面
}
//方向键控制蛇的走向
if (keyCode == KeyEvent.VK_W || keyCode == KeyEvent.VK_UP) {
    if (!direction.equals("D")){
          direction = "U";
     }
 } else if (keyCode == KeyEvent.VK_S || keyCode == KeyEvent.VK_DOWN) {
     if (!direction.equals("U")) {
         direction = "D";
    }
} else if (keyCode == KeyEvent.VK_A || keyCode == KeyEvent.VK_LEFT) {
     if (!direction.equals("R")) {
           direction = "L";
     }
} else if (keyCode == KeyEvent.VK_D || keyCode == KeyEvent.VK_RIGHT) {
     if (!direction.equals("L")) {
           direction = "R";
     }
}

//按J可加速
if (keyCode == KeyEvent.VK_J){
       timer.stop();
       timer = new Timer(20, this);
       timer.start();
    }
}
@Override
public void actionPerformed(ActionEvent e) {
  if (isStart && isFail == false){   //游戏是启动状态,并且没有失败时
     //1.移动蛇身,后边的蛇身坐标取前一个蛇身的坐标
     for (int i = length-1 ; i > 0 ; i--){
         snakex[i] = snakex[i-1];   //后边蛇身的坐标取自于前一个蛇身的坐标
         snakey[i] = snakey[i-1];
        }
      //2.移动蛇头,根据蛇头的方向决定下一个蛇头的位置
     if (direction.equals("U")){
          snakey[0] = snakey[0] - 25; //向上移动一格
     if (snakey[0] < 75){
         if (modern == 1){
             snakey[0] = 625;    //当运动到最上面时,从最下面出来
         }else{
             isFail = true;
              }
     }
     }else if (direction.equals("D")){
           snakey[0] = snakey[0] + 25; //向下移动一格
           if(snakey[0] > 625){
               if (modern == 1){
                   snakey[0] = 75;     //当运动到最下面时,从最上面出来
               }else{
                   isFail = true;
               }
      }
     }else if (direction.equals("L")){
           snakex[0] = snakex[0] - 25; //向左移动一格
           if(snakex[0] < 25){
              if (modern == 1){
                  snakex[0] = 850;    //当运动到最左边时,从最右边出来
              }else{
                  isFail = true;
              }
   }
   }else if (direction.equals("R")){
         snakex[0] = snakex[0] + 25; //向右移动一格
         if(snakex[0] > 850){
            if (modern == 1){
              snakex[0] = 25;     //当运动到最右边时,从最左边出来
            }else{
               isFail = true;
            }
         }
  }
  //3-1.吃食物,当蛇头和食物的坐标重叠时,则代表吃到了食物
  if(snakex[0] == foodx && snakey[0]== foody){
try {
         Music foodMusic = new Music("eat.wav");
         foodMusic.start();
         Thread.sleep(100);
         foodMusic.stopPlaying();
         }catch(InterruptedException a) {
                 a.printStackTrace();
          }
         length++;
         score += 10;
         int foodxx = 25 + r.nextInt(34) * 25;
         int foodyy = 75 + r.nextInt(23) * 25;
         int[] test = Foodxy(foodxx,foodyy);
         foodx = test[0];
         foody = test[1];
     }
  //4.判断游戏是否失败(蛇头与任何一个蛇身重叠,则失败)
for (int i = 1; i < length ; i++){
       if (snakex[0] == snakex[i] && snakey[0] == snakey[i]){
            isFail = true;
        }
     }
     repaint();
   }
timer.start();
}
@Override
public void keyReleased(KeyEvent e) {
   int keyCode = e.getKeyCode();         //赋值
   if (keyCode == KeyEvent.VK_J){
       timer.stop();
       if (speed == 0){
          timer = new Timer(120, this);
       }else if (speed == 1){
          timer = new Timer(100, this);
       }else if (speed == 2){
          timer = new Timer(60, this);
       }else if (speed == 3){
          timer = new Timer(40, this);
       }
           timer.start();
        }
    }

@Override
public void keyTyped(KeyEvent e) {

}
}

总结

第一部分主要设计主类,大家可以根据注释理解代码。

 

 

  • 13
    点赞
  • 126
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 1
    评论
1.1 手机软件现状 在信息社会中,手机及其他无线设备越来越多的走进普通百姓的工作和生活,随着信息网络化的不断进展,手机及其他无线设备上网络势在必行。但是传统手机存在以下弊端: 1. 传统手机出厂时均由硬件厂商固化程序,程序不能增加、删除,有了错误也不能更新、修改,若要增加新功能必须另换一部手机。 2. 传统手机访问互联网是通过WAP(Wireless Application Protocal),所有网络资源必须接通网络才能在线访问,非常耗时、费用亦很高。 而Java技术在无线应用方面的优势非常明显: 1. 应用程序可按需下载,而不是购买由硬件商提供的套件,可升级空间大。 2. Java技术提供了一个类库,它使的应用开发商可以创建更为直觉、丰富的用户界面(GUI); 3. Java技术使网络带宽的应用更为有效,因为应用程序可以下载到器件上,并在本地运行,仅仅是在连接到服务器时才会占用网络带宽。 基于以上分析,Java手机将是未来手机的发展方向,是业界的热点。 1.2 J2ME介绍 虽然 Java 已经被用到许多企业级软体上,可是其实骨子里面还是非常适合用在嵌入式系统之中。Java平台演进到Java2后,Java平台分别针对不同领域的需求被分成四个版本,亦即J2EE、J2SE、J2ME以及JavaCard。其中J2ME定位在消费性电子产品的应用上。这个版本针对资源有限的电子消费产品的需求精简核心类库,并提供了模块化的架构让不同类型产品能够随时增加支持的能力。这个版本的应用层面相当广泛,会是未来Java平台发展的重点项目。 J2ME在1999年的JavaOne开发人员大会上初次亮相,它的目标是面向智能无线设备和小型计算机设备的开发人员。J2ME的一个关键优点是,J2ME与所有支持Java的设备都是兼容的。支持Java的设备就是任何运行Java虚拟机器的计算机。Motorola、Nokia等生产厂商都生产支持Java的设备。、 J2ME平台是由配置(Configuration)和简表(Profile)构成的。配置是提供给最大范围设备使用的最小类库集合,在配置中同时包含Java虚拟机。简表是针对一系列设备 提供的开发包集合。在J2ME中还有一个重要的概念是可选包(Optional Package),它是针对特定设备提供的类库,比如某些设备是支持蓝牙的,针对此功能J2ME中制定了JSR82(Bluetooth API)提供了对蓝牙的支持。 目前,J2ME中有两个最主要的配置,分别是Connected Limited Devices Configuration(CLDC)和Connected Devices Configuration(CDC)。 作为第一个面对小型设备的Java应用开发规范,CLDC是由包括Nokia,Motorola和Siemens在内的18家全球知名公司共同协商完成的。CLDC是J2ME核心配置中的一个,可以支持一个或多个profile。其目标主要面向小型的、网络连接速度慢、能源有限(主要是电池供电)且资源有限的设备,如手机、PDA等。 而CDC则是主要用于运算能力相对较佳、在电力供应上相对比较充足的嵌入式装置 (比方说冷气机、电冰箱、电视机机顶盒 (set-top box))

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

-凉介-一

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值