贪吃蛇第四弹
内容: 创建一个界面,并在界面中画单元格,添加一个线程控制重画,添加键盘方向键来控制蛇的移动,并使小蛇初始时就朝一个方向移动,并添加一个食物类
代码:
package snake;
import java.awt.Color;
import java.awt.Graphics;
import java.awt.Rectangle;
import java.util.Random;
public class Egg {
private static final int width = Snake.width; //食物的横轴
private static final int height = Snake.height; //食物的纵轴
private int xwidth; //确定窗口有多少根纵线
private int xheight; //确定窗口有多少跟横线
private static final Random r = new Random(); //调用随机函数,使食物随机出现
private Color color = Color.RED; //确定食物的初始颜色
public Egg(int xwidth, int xheight) {
//创建含有2个参数的构造函数
this.xwidth = xwidth;
this.xheight = xheight;
}
public Egg() {
this((r.nextInt(SnakeMain.xwidth - 2)) + 2, (r.nextInt(SnakeMain.xheight - 2)) + 2);
}
public void reAppear() {
this.xwidth = (r.nextInt(SnakeMain.xwidth - 2)) + 2;
this.xheight = (r.nextInt(SnakeMain.xheight - 2) + 2);
}
//画食物
public void draw(Graphics g) {
//调用画笔
Color c = g.getColor();
g.setColor(color);//设置画笔颜色
g.fillOval(width * xwidth, height * xheight, width, height);
//绘制有有填充颜色的椭圆,但是当横轴与纵轴相等时为圆形
g.setColor(c);//确定填充的颜色
//使食物的颜色随时间而改变
if (color == Color.RED) {
color = Color.YELLOW;
} else {
color = Color.RED;
}
}
package snake;
public enum Direction {
L,U,R ,D,STOP //枚举列出4个方向LEFT,UP,RIGHT,DOEN
}
package snake;
import java.awt.Color;
import java.awt.Graphics;
import java.awt.event.KeyEvent;
public class Snake {
// 确定蛇的位置
private int x;
private int y;
// 确定蛇的大小
public static final int width = 25;
public static final int height = 25;
// 实例化方向类
private Direction dir = Direction.D;
// 调用SnakeMain类
private SnakeMain sankeMain;
// 构造带3个参数的方法
public Snake(int x, int y, SnakeMain snakeMain) {
this.x = x;
this.y = y;
this.sankeMain = snakeMain;
}
// 构造带4个参数的方法
public Snake(int x, int y, Direction dir, SnakeMain snakeMain) {
this(x, y, snakeMain);
this.dir = dir;
}
public void draw(Graphics g) {
// 调用画笔
Color c = g.getColor();
g.setColor(Color.BLACK);// 设置画笔颜色
g.setColor(c);
g.fillRect(x, y, width, height);// 画填充了颜色矩形小蛇
move();
}
// 此代码使小蛇没有按键时就不动
// public void keyPressed(KeyEvent e) {
// // 获取键盘上的键入的方向事件
// int key = e.getKeyCode();
// switch (key) {
// case KeyEvent.VK_LEFT: // 键入为左
// this.x = x - width; // 相对原位置减一个宽度
// break;
// case KeyEvent.VK_UP: // 键入为上
// this.y = y - height; // 相对原位置减一个高度
// break;
// case KeyEvent.VK_RIGHT: // 键入为右
// this.x = x + width; // 相对原位置加一个宽度
// break;
// case KeyEvent.VK_DOWN: // 键入为下
// this.y = y + height;// 相对原位置加一个高度
// break;
// }
// 此代码使小蛇没有按键时就按照初始化方向移动
public void keyPressed(KeyEvent e) {
// 获取键盘上的键入的方向事件
int key = e.getKeyCode();
switch (key) {
case KeyEvent.VK_LEFT: // 键入为左
this.dir = Direction.L;
break;
case KeyEvent.VK_UP: // 键入为上
this.dir = Direction.U;
break;
case KeyEvent.VK_RIGHT: // 键入为右
this.dir = Direction.R;
break;
case KeyEvent.VK_DOWN: // 键入为下
this.dir = Direction.D;
break;
default:
this.dir = Direction.STOP;
break;
}
}
public void move() {
if (dir == Direction.L) {
x = x - width;// 相对原位置减一个宽度
} else if (dir == Direction.U) {
y = y - height;// 相对原位置减一个高度
} else if (dir == Direction.R) {
x = x + width;// 相对原位置加一个宽度
} else if (dir == Direction.D) {
y = y + height;// 相对原位置加一个高度
}
// 边界控制
if (x <= 0)
{
x = 0;
} else if (x > SnakeMain.SNAKE_WIDTH - width) {
x = SnakeMain.SNAKE_WIDTH - width;
}
if (y <= 0) {
y = 0;
} else if (y > SnakeMain.SNAKE_HEIGHT - height) {
y = SnakeMain.SNAKE_HEIGHT - width;
}
}
}
package snake;
import java.awt.Color;
import java.awt.Frame;
import java.awt.Graphics;
import java.awt.event.KeyAdapter;
import java.awt.event.KeyEvent;
import java.awt.event.WindowAdapter;
import java.awt.event.WindowEvent;
/**
* 项目名称:Snake
* 创建人:YM
* 类描述: 创建一个界面,并在界面中画单元格,添加一个线程控制重画,添加键盘方向键来控制蛇的移动
* 并使小蛇初始时就朝一个方向移动,并添加一个食物类
* 创建时间:2019年1月16日 下午2:59:06
*
*/
public class SnakeMain extends Frame {
static final int SNAKE_WIDTH = 1000; // 定义组件的宽度
static final int SNAKE_HEIGHT = 600; // 定义组件的高度
private static final int squareSize = 25; // 用来确定单元格的大小
public static final int xwidth = SNAKE_WIDTH / squareSize;
public static final int xheight = SNAKE_HEIGHT / squareSize;
Snake s = new Snake(50,50,Direction.D,this);//实例化一个对象,确定蛇的位置,并确定蛇的初始移方向
private Egg egg=new Egg();
public static void main(String[] args) {
SnakeMain s = new SnakeMain(); // 构建SnakeMai类的一个实例,并命名为s
s.launchFrame(); // 调用实例中的launchFrame()方法
}
private void launchFrame() {
this.setLocation(100, 100); // 确定组件位置
this.setSize(SNAKE_WIDTH, SNAKE_HEIGHT); // 确定组件大小
this.setBackground(Color.WHITE); // 确定组件背景颜色
this.setTitle("我的贪吃蛇"); // 设置窗口的标题
// 添加关闭的处理事件
this.addWindowListener(new WindowAdapter() {
// 添加一个窗口监听
@Override
public void windowClosing(WindowEvent e) {
System.exit(0); // 窗口关闭事件
}
});
// 禁止改变窗的大小
this.setResizable(false);
this.setVisible(true);
//通过调用线程运行启动线程
new Thread(new MyPaintThread()).start();
//通过添加指定的按键侦听器,以接收此组件的按键事件
this.addKeyListener(new MyKeyListener());
}
@Override
public void paint(Graphics g) {
// 调用画笔
Color c = g.getColor();
g.setColor(Color.GRAY); // 设置画笔颜色
g.setColor(c);
// 画线
for (int i = 0; i < xwidth; i++) {
g.drawLine(i * squareSize, 0, i * squareSize, SNAKE_HEIGHT);
} // 画纵向的线
for (int i = 0; i < xheight; i++) {
g.drawLine(0, i * squareSize, SNAKE_WIDTH, i * squareSize);
} // 画横向的线
s.draw(g); //调用画小蛇的方法
egg.draw(g);
}
private class MyPaintThread implements Runnable{
//通过新建一个MyPaintThread类来实现Runnable接口
//重画线程
@Override
public void run() {
//线程的入口
//每隔80ms重画一次
while(true){
repaint();//会自动调用paint方法
try {
//指定捕获异常的类型
Thread.sleep(80);//可以通过此处控制小蛇移动的速度
} catch (InterruptedException e)
//InterruptedException异常是指当一个当一个正在执行的线程被中断
{
e.printStackTrace();//在命令行中打印异常信息在程序中出错的位置既原因
}
}
}
}
private class MyKeyListener extends KeyAdapter{
// 键盘监听类
@Override
public void keyPressed(KeyEvent e) {
s.keyPressed(e);
}
}
}
从贪吃蛇第四弹中学到的知识点:
1,Java中的随机函数有两种:
1,java.lang.Math.random():Math。random()方法中返回一个0–1之间的随机double型数据
2,java.until.Random() 构造一个无参的随机数生成器,使用系统时间的毫秒为默认的种子,其方法有
1,boolean nextBoolean():Random.nextBoolean()返回下一个伪随机数,它取自随机数生成器序列均匀分布的boolean值
2,double nextDouble():Random.nextDouble()返回下一个伪随机数,它取自随机数生成器序列,在0–1之间均匀分布的double值
3,float nextFloat():Random.nextFloat()返回下一个伪随机数,它取自随机数生成器序列,在0–1之间均匀分布的float值
4,int nextInt():Random.nextInt()返回下一个伪随机数,它取自随机数生成器序列均匀分布的int值
5,long nextLong():Random.nextLong()返回下一个伪随机数,它取自随机数生成器序列均匀分布的long值