以前的Java练手,尽量写的细一些,希望有人有所收获。
思路
一:创建窗体和画布
二:画网格
(1) 确定画竖线39条,横线27条
(2) 使用两个for循环画出网格
三:画蛇并且移动
(1) 在paint方法中使用for循环遍历集合并调用画蛇的方法
(2) 定义一个蛇移动的方法,注意:继承键盘监听器,在按压键盘的方法中完成上下左右对蛇的状态的控制.
(3) 写一个蛇移动的方法,根据蛇的状态改变坐标
(4) 在实现runable接口,完成run方法对蛇移动方法的调用
(5) 获取焦点,添加键盘监听,启动线程
四:游戏的结束
(1) 写一个游戏结束的方法,方法的返回值是boolean,参数是蛇对象,根据if条件判断什么时候该结束游戏,游戏结束返回true,否则返回flase
(2) 在paint方法中根据游戏结束的方法的返回值来确定画游戏结束字体
(3) 将run方法中的while循环条件修改成方法的返回值
五:画食物
(1) 随机生成食物坐标
(2) 循环判断食物和集合中的每一个蛇的坐标是否一致,不一致就要重新生成.并重新比较
六:吃食物
(1) 蛇头和食物坐标一致表示吃食物
(2) 吃食物蛇集合就应该增加一个蛇对象
(3) New的蛇对象的坐标是前一个蛇对象保留下的坐标
(4) 返回去在蛇移动的时候就应该修改成先保留在移动
(5) 迟到食物,食物开关标识flase,与此同时在run方法中if判断食物消失,调用创建食物的方法,创建食物,食物标识就应该改为true
七:蛇身移动
(1) 蛇身移动之前应该保留坐标
(2) 赋值的坐标是前一个蛇对象保留下的坐标
初版程序与注释
SnakeJFrame.java
package snake;
import javax.swing.JFrame;
public class SnakeJFrame extends JFrame{
public SnakeJFrame() {
this.setTitle("贪吃蛇");//设置窗体标题
this.setSize(1000, 700);//设置窗体大小
this.setLocationRelativeTo(null);//居中
this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);//关闭程序与停止dos运行没有设置的话,默认点关闭时只是隐藏窗体,在后台进程中还可以看到,如果有多个窗口,只是销毁调用dispose的窗口,其他窗口仍然存在,整个应用程序还是处于运行状态。
this.setResizable(false);//设置此窗体不可由用户调整大小
SnakeJPanel panel=new SnakeJPanel();
this.add(panel);
this.setVisible(true);//设置可见
}
public static void main(String[] args) {
new SnakeJFrame();
}
}
SnakeJPanel.java
package snake;
import java.awt.BasicStroke;
import java.awt.Color;
import java.awt.Font;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.event.KeyEvent;
import java.awt.event.KeyListener;
import java.util.ArrayList;
import javax.swing.JPanel;
public class SnakeJPanel extends JPanel implements KeyListener,Runnable{
//网格大小25*25 横着画38 竖着画26个
int size=25;
int across=38;//横格
int vertical=26;//竖格
//定义一个集合存放蛇
ArrayList snakes=new ArrayList();
//定义蛇可能走的四个方向
int UP=0;
int DOWN=1;
int LEFT=2;
int RIGHT=3;
//定义蛇的初始方向
int StartF=-1;
//创建一个线程
Thread t=new Thread(this);
//设置一个开关来声明是否有食物(标识窗体中是否有食物)
boolean hadFood=true;
//创建食物坐标
int food_x;
int food_y;
public SnakeJPanel() {
//在构造方法中生成蛇
Snake snake=new Snake((int)(Math.random()*across)*size+4, (int)(Math.random()*vertical)*size+4);
snakes.add(snake);
setFocusable(true);//获取键盘焦点
addKeyListener(this);//添加键盘监听
t.start();
creat_food();//创建食物
}
@Override
public void paint(Graphics g) {
super.paint(g);//paint(g)函数会重绘图像,要加上super.paint(g),表示在原来图像的基础上,再画图。如果不加super.paint(g),重绘时,会将原有的绘制清空,再根据paing(g)函数绘制。
//画网格
//画横线 用竖格变量
for (int i = 0; i <=vertical; i++) {
g.drawLine(4, 4+size*i, 4+across*size, 4+size*i);//在此图形的坐标系中,使用当前颜色在点 (x1, y1) 和 (x2, y2) 之间画一条线。
}
//画竖线 用横格变量
for (int i = 0; i <=across; i++) {
g.drawLine(4+size*i, 4, 4+size*i, 4+vertical*size);
}
//画蛇
for (int i = 0; i < snakes.size(); i++) {
Snake snake=(Snake) snakes.get(i);
snake.drawSnake(g);
}
//游戏结束
if(GameOver((Snake)snakes.get(0))){
//写艺术字
for (int i = 0; i < 10; i++) {
g.setFont(new Font("微软雅黑", Font.BOLD, 70));
g.setColor(new Color((int)(Math.random()*255), (int)(Math.random()*255), (int)(Math.random()*255)));
g.drawString("游戏结束", 300-i, 300-i);
}
}
//画食物
if(hadFood){
g.fillRect(food_x, food_y, size, size);
}
/*
//画边框
Graphics2D g2=(Graphics2D) g;
g2.setColor(Color.BLACK);
g2.setStroke(new BasicStroke(8));
g2.drawRect(0, 0, 958, 658);
*/
}
@Override
public void keyPressed(KeyEvent e) {
if(e.getKeyCode()==KeyEvent.VK_LEFT){//判断按键是否为←, VK_LEFT是左方向键默认的值
if(StartF==-1 || StartF==UP ||StartF==DOWN){
StartF=LEFT;
}
}
if(e.getKeyCode()==KeyEvent.VK_RIGHT){
if(StartF==-1 || StartF==UP ||StartF==DOWN){
StartF=RIGHT;
}
}
if(e.getKeyCode()==KeyEvent.VK_UP){
if(StartF==-1 || StartF==LEFT ||StartF==RIGHT){
StartF=UP;
}
}
if(e.getKeyCode()==KeyEvent.VK_DOWN){
if(StartF==-1 || StartF==LEFT ||StartF==RIGHT){
StartF=DOWN;
}
}
}
@Override
public void run() {
while (!GameOver((Snake)snakes.get(0))) {
moveSnake();//蛇头的移动
moveSnake2();//蛇身的移动
eatFood();//吃到食物
if(!hadFood){
creat_food();
}
try {
Thread.sleep(100);//每100毫秒重绘一次
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
repaint();
}
}
//定义蛇头移动的方法
//把蛇头的坐标保存下作为蛇身移动用
//定义一个蛇移动的方法
public void moveSnake(){
if(StartF==LEFT){
Snake snake=(Snake) snakes.get(0);
snake.Oldx=snake.x;//将蛇移动之前的坐标留下
snake.Oldy=snake.y;//将蛇移动之前的坐标留下
snake.x-=size;
}
if(StartF==RIGHT){
Snake snake=(Snake) snakes.get(0);
snake.Oldx=snake.x;//将蛇移动之前的坐标留下
snake.Oldy=snake.y;//将蛇移动之前的坐标留下
snake.x+=size;
}
if(StartF==UP){
Snake snake=(Snake) snakes.get(0);
snake.Oldx=snake.x;//将蛇移动之前的坐标留下
snake.Oldy=snake.y;//将蛇移动之前的坐标留下
snake.y-=size;
}
if(StartF==DOWN){
Snake snake=(Snake) snakes.get(0);
snake.Oldx=snake.x;//将蛇移动之前的坐标留下
snake.Oldy=snake.y;//将蛇移动之前的坐标留下
snake.y+=size;
}
}
//蛇身移动的方法
public void moveSnake2(){
for (int i = 1; i < snakes.size(); i++) {
//在移动之前将坐标保留,做下一个蛇身移动
Snake snake=(Snake) snakes.get(i);
snake.Oldx=snake.x;
snake.Oldy=snake.y;
//前一个蛇的坐标
Snake snake2=(Snake) snakes.get(i-1);
snake.x=snake2.Oldx;
snake.y=snake2.Oldy;
}
}
//写一个方法判断游戏结束
public boolean GameOver(Snake snake){
if(snake.x<0 || snake.x>925 || snake.y<0 || snake.y>625){
return true;//游戏结束返回true
}
return false;//游戏没结束返回false
}
//创建食物的方法
public void creat_food(){
food_x=(int) (Math.random()*across)*size+4;
food_y=(int) (Math.random()*vertical)*size+4;
for (int i = 0; i < snakes.size(); i++) {
Snake snake=(Snake) snakes.get(i);
if(food_x==snake.x && food_y==snake.y){
food_x=(int) (Math.random()*across)*size+4;
food_y=(int) (Math.random()*vertical)*size+4;
i=0;
}
}
hadFood=true;
}
//定义一个蛇吃食物的方法
public void eatFood(){
//蛇头和食物完全重合标识吃到食物
Snake snake=(Snake) snakes.get(0);
if(snake.x==food_x && snake.y==food_y){
Snake snake2=(Snake) snakes.get(snakes.size()-1);
Snake snake3=new Snake(snake2.Oldx, snake2.Oldy);
snakes.add(snake3);
hadFood=false;
//蛇身肯定是新new一个snake对象,蛇吃食物的一瞬间,前一次移动的最后一格坐标是吃了食物后的最后一格坐标
}
}
//keyTyped,keyReleased,keyPressed实现KeyListener类时生成的函数 作用是监听键盘 我们是需要用第二 即键盘按下时的反映
@Override
public void keyTyped(KeyEvent e) {
// TODO Auto-generated method stub
}
@Override
public void keyReleased(KeyEvent e) {
// TODO Auto-generated method stub
}
}
Snake.java
package snake;
import java.awt.Color;
import java.awt.Font;
import java.awt.Graphics;
public class Snake {
int x,y;//定义蛇的坐标
int Oldx,Oldy;//定义两个变量来保存蛇在走之前留下的坐标
public Snake(int x,int y) {
this.x=x;
this.y=y;
}
//画蛇的方法
public void drawSnake(Graphics g){
g.setColor(Color.red);
g.fillRect(x, y, 25, 25);//用预定的颜色填充一个矩形,得到一个着色的矩形块。
}
}
实现过程
创建窗体和画布
SnakeJFrame.java
package snank;
import javax.swing.JFrame;
public class SnakeJFrame extends JFrame{
public SnakeJFrame() {
this.setTitle("贪吃蛇");
this.setSize(978, 700);
this.setLocationRelativeTo(null);
this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
this.setResizable(false);
this.setVisible(true);
}
public static void main(String[] args) {
new SnakeJFrame();
}
}
画网格
(1) 确定画竖线39条,横线27条
(2) 使用两个for循环画出网格
SnakeJFrame.java
package snank;
import javax.swing.JFrame;
public class SnakeJFrame extends JFrame{
public SnakeJFrame() {
this.setTitle("贪吃蛇");
this.setSize(978, 700);
this.setLocationRelativeTo(null);
this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
this.setResizable(false);
SnakeJPanel panel=new SnakeJPanel();
this.add(panel);
this.setVisible(true);
}
public static void main(String[] args) {
new SnakeJFrame();
}
}
SnakeJFrame.java已完成。
SnakeJPanel.java
package snank;
import java.awt.Graphics;
import javax.swing.JPanel;
public class SnakeJPanel extends JPanel{
int size = 25;
int across = 38;
int vertical = 26;
public void paint(Graphics g) {
super.paint(g);
for (int i = 0; i <=vertical; i++) {
g.drawLine(6, 6+size*i, 6+across*size, 6+size*i);
}
for (int i = 0; i <=across; i++) {
g.drawLine(6+size*i, 6, 6+size*i, 6+vertical*size);
}
}
}
画蛇并且移动
(1) 在paint方法中使用for循环遍历集合并调用画蛇的方法
SnakeJFrame.java
package snank;
import javax.swing.JFrame;
public class SnakeJFrame extends JFrame{
public SnakeJFrame() {
this.setTitle("贪吃蛇");
this.setSize(978, 700);
this.setLocationRelativeTo(null);
this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
this.setResizable(false);
SnakeJPanel panel=new SnakeJPanel();
this.add(panel);
this.setVisible(true);
}
public static void main(String[] args) {
new SnakeJFrame();
}
}
SnakeJPanel.java
package snank;
import java.awt.Graphics;
import java.util.ArrayList;
import javax.swing.JPanel;
public class SnakeJPanel extends JPanel{
int size = 25;
int across = 38;
int vertical = 26;
ArrayList snakes = new ArrayList();
public void paint(Graphics g) {
super.paint(g);
for (int i = 0; i <=vertical; i++) {
g.drawLine(6, 6+size*i, 6+across*size, 6+size*i);
}
for (int i = 0; i <=across; i++) {
g.drawLine(6+size*i, 6, 6+size*i, 6+vertical*size);
}
for (int i = 0; i < snakes.size(); i++) {
Snake snake=(Snake) snakes.get(i);
snake.drawSnake(g);
}
}
public SnakeJPanel() {
Snake snake=new Snake((int)(Math.random()*across)*size+6, (int)(Math.random()*vertical)*size+6);
snakes.add(snake);
}
}
Snake.java
package snank;
import java.awt.Color;
import java.awt.Graphics;
public class Snake {
int x,y;
public Snake(int x,int y) {
this.x=x;
this.y=y;
}
public void drawSnake(Graphics g) {
g.setColor(Color.red);
g.fillRect(x, y, 25, 25);
}
}
(2) 定义一个蛇移动的方法,注意:继承键盘监听器,在按压键盘的方法中完成上下左右对蛇的状态的控制.
(3) 写一个蛇移动的方法,根据蛇的状态改变坐标
(4) 在实现runable接口,完成run方法对蛇移动方法的调用
(5) 获取焦点,添加键盘监听,启动线程
SnakeJFrame.java
package snank;
import javax.swing.JFrame;
public class SnakeJFrame extends JFrame{
public SnakeJFrame() {
this.setTitle("贪吃蛇");
this.setSize(978, 700);
this.setLocationRelativeTo(null);
this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
this.setResizable(false);
SnakeJPanel panel=new SnakeJPanel();
this.add(panel);
this.setVisible(true);
}
public static void main(String[] args) {
new SnakeJFrame();
}
}
SnakeJPanel.java
package snank;
import java.awt.Graphics;
import java.awt.event.KeyEvent;
import java.awt.event.KeyListener;
import java.util.ArrayList;
import javax.swing.JPanel;
public class SnakeJPanel extends JPanel implements KeyListener,Runnable{
int size = 25;
int across = 38;
int vertical = 26;
ArrayList snakes = new ArrayList();
int UP=0;
int DOWN=1;
int LEFT=2;
int RIGHT=3;
int StartF=-1;
Thread t = new Thread(this);
public void paint(Graphics g) {
super.paint(g);
for (int i = 0; i <=vertical; i++) {
g.drawLine(6, 6+size*i, 6+across*size, 6+size*i);
}
for (int i = 0; i <=across; i++) {
g.drawLine(6+size*i, 6, 6+size*i, 6+vertical*size);
}
for (int i = 0; i < snakes.size(); i++) {
Snake snake=(Snake) snakes.get(i);
snake.drawSnake(g);
}
}
public SnakeJPanel() {
Snake snake=new Snake((int)(Math.random()*across)*size+6, (int)(Math.random()*vertical)*size+6);
snakes.add(snake);
setFocusable(true);
addKeyListener(this);
t.start();
}
public void keyPressed(KeyEvent e) {
if(e.getKeyCode()==KeyEvent.VK_LEFT){
if(StartF==-1 || StartF==UP ||StartF==DOWN){
StartF=LEFT;
}
}
if(e.getKeyCode()==KeyEvent.VK_RIGHT){
if(StartF==-1 || StartF==UP ||StartF==DOWN){
StartF=RIGHT;
}
}
if(e.getKeyCode()==KeyEvent.VK_UP){
if(StartF==-1 || StartF==LEFT ||StartF==RIGHT){
StartF=UP;
}
}
if(e.getKeyCode()==KeyEvent.VK_DOWN){
if(StartF==-1 || StartF==LEFT ||StartF==RIGHT){
StartF=DOWN;
}
}
}
@Override
public void keyTyped(KeyEvent e) {
// TODO 自动生成的方法存根
}
@Override
public void keyReleased(KeyEvent e) {
// TODO 自动生成的方法存根
}
public void run() {
while (!GameOver((Snake)snakes.get(0))) {
moveSnake();
moveSnake2();
try {
Thread.sleep(100);
} catch (InterruptedException e) {
e.printStackTrace();
}
repaint();
}
}
private boolean GameOver(snank.Snake snake) {
// TODO 自动生成的方法存根
return false;
}
public void moveSnake(){
if(StartF==LEFT){
Snake snake=(Snake) snakes.get(0);
snake.Oldx=snake.x;
snake.Oldy=snake.y;
snake.x-=size;
}
if(StartF==RIGHT){
Snake snake=(Snake) snakes.get(0);
snake.Oldx=snake.x;
snake.Oldy=snake.y;
snake.x+=size;
}
if(StartF==UP){
Snake snake=(Snake) snakes.get(0);
snake.Oldx=snake.x;
snake.Oldy=snake.y;
snake.y-=size;
}
if(StartF==DOWN){
Snake snake=(Snake) snakes.get(0);
snake.Oldx=snake.x;
snake.Oldy=snake.y;
snake.y+=size;
}
}
public void moveSnake2(){
for (int i = 1; i < snakes.size(); i++) {
Snake snake=(Snake) snakes.get(i);
snake.Oldx=snake.x;
snake.Oldy=snake.y;
Snake snake2=(Snake) snakes.get(i-1);
snake.x=snake2.Oldx;
snake.y=snake2.Oldy;
}
}
}
Snake.java
package snank;
import java.awt.Color;
import java.awt.Graphics;
public class Snake {
int x,y;
int Oldx,Oldy;
public Snake(int x,int y) {
this.x=x;
this.y=y;
}
public void drawSnake(Graphics g) {
g.setColor(Color.red);
g.fillRect(x, y, 25, 25);
}
}
Snake.java已完成。
游戏的结束
(1) 写一个游戏结束的方法,方法的返回值是boolean,参数是蛇对象,根据if条件判断什么时候该结束游戏,游戏结束返回true,否则返回flase
(2) 在paint方法中根据游戏结束的方法的返回值来确定画游戏结束字体
(3) 将run方法中的while循环条件修改成方法的返回值
SnakeJPanel.java
package snank;
import java.awt.Color;
import java.awt.Font;
import java.awt.Graphics;
import java.awt.event.KeyEvent;
import java.awt.event.KeyListener;
import java.util.ArrayList;
import javax.swing.JPanel;
public class SnakeJPanel extends JPanel implements KeyListener,Runnable{
int size = 25;
int across = 38;
int vertical = 26;
ArrayList snakes = new ArrayList();
int UP=0;
int DOWN=1;
int LEFT=2;
int RIGHT=3;
int StartF=-1;
Thread t = new Thread(this);
public void paint(Graphics g) {
super.paint(g);
for (int i = 0; i <=vertical; i++) {
g.drawLine(6, 6+size*i, 6+across*size, 6+size*i);
}
for (int i = 0; i <=across; i++) {
g.drawLine(6+size*i, 6, 6+size*i, 6+vertical*size);
}
for (int i = 0; i < snakes.size(); i++) {
Snake snake=(Snake) snakes.get(i);
snake.drawSnake(g);
}
if(GameOver((Snake)snakes.get(0))){
//写艺术字
for (int i = 0; i < 10; i++) {
g.setFont(new Font("微软雅黑", Font.BOLD, 70));
g.setColor(new Color((int)(Math.random()*255), (int)(Math.random()*255), (int)(Math.random()*255)));
g.drawString("游戏结束", 300-i, 300-i);
}
}
}
public SnakeJPanel() {
Snake snake=new Snake((int)(Math.random()*across)*size+6, (int)(Math.random()*vertical)*size+6);
snakes.add(snake);
setFocusable(true);
addKeyListener(this);
t.start();
}
public void keyPressed(KeyEvent e) {
if(e.getKeyCode()==KeyEvent.VK_LEFT){
if(StartF==-1 || StartF==UP ||StartF==DOWN){
StartF=LEFT;
}
}
if(e.getKeyCode()==KeyEvent.VK_RIGHT){
if(StartF==-1 || StartF==UP ||StartF==DOWN){
StartF=RIGHT;
}
}
if(e.getKeyCode()==KeyEvent.VK_UP){
if(StartF==-1 || StartF==LEFT ||StartF==RIGHT){
StartF=UP;
}
}
if(e.getKeyCode()==KeyEvent.VK_DOWN){
if(StartF==-1 || StartF==LEFT ||StartF==RIGHT){
StartF=DOWN;
}
}
}
@Override
public void keyTyped(KeyEvent e) {
// TODO 自动生成的方法存根
}
@Override
public void keyReleased(KeyEvent e) {
// TODO 自动生成的方法存根
}
public void run() {
while (!GameOver((Snake)snakes.get(0))) {
moveSnake();
moveSnake2();
try {
Thread.sleep(100);
} catch (InterruptedException e) {
e.printStackTrace();
}
repaint();
}
}
public boolean GameOver(Snake snake){
if(snake.x<0 || snake.x>956 || snake.y<0 || snake.y>656){
return true;
}
return false;
}
public void moveSnake(){
if(StartF==LEFT){
Snake snake=(Snake) snakes.get(0);
snake.Oldx=snake.x;
snake.Oldy=snake.y;
snake.x-=size;
}
if(StartF==RIGHT){
Snake snake=(Snake) snakes.get(0);
snake.Oldx=snake.x;
snake.Oldy=snake.y;
snake.x+=size;
}
if(StartF==UP){
Snake snake=(Snake) snakes.get(0);
snake.Oldx=snake.x;
snake.Oldy=snake.y;
snake.y-=size;
}
if(StartF==DOWN){
Snake snake=(Snake) snakes.get(0);
snake.Oldx=snake.x;
snake.Oldy=snake.y;
snake.y+=size;
}
}
public void moveSnake2(){
for (int i = 1; i < snakes.size(); i++) {
Snake snake=(Snake) snakes.get(i);
snake.Oldx=snake.x;
snake.Oldy=snake.y;
Snake snake2=(Snake) snakes.get(i-1);
snake.x=snake2.Oldx;
snake.y=snake2.Oldy;
}
}
}
画食物
(1) 随机生成食物坐标
(2) 循环判断食物和集合中的每一个蛇的坐标是否一致,不一致就要重新生成.并重新比较
package snank;
import java.awt.Color;
import java.awt.Font;
import java.awt.Graphics;
import java.awt.event.KeyEvent;
import java.awt.event.KeyListener;
import java.util.ArrayList;
import javax.swing.JPanel;
public class SnakeJPanel extends JPanel implements KeyListener,Runnable{
int size = 25;
int across = 38;
int vertical = 26;
ArrayList snakes = new ArrayList();
int UP=0;
int DOWN=1;
int LEFT=2;
int RIGHT=3;
int StartF=-1;
Thread t = new Thread(this);
boolean hadFood=true;
int food_x;
int food_y;
public void paint(Graphics g) {
super.paint(g);
for (int i = 0; i <=vertical; i++) {
g.drawLine(6, 6+size*i, 6+across*size, 6+size*i);
}
for (int i = 0; i <=across; i++) {
g.drawLine(6+size*i, 6, 6+size*i, 6+vertical*size);
}
for (int i = 0; i < snakes.size(); i++) {
Snake snake=(Snake) snakes.get(i);
snake.drawSnake(g);
}
if(GameOver((Snake)snakes.get(0))){
//写艺术字
for (int i = 0; i < 10; i++) {
g.setFont(new Font("微软雅黑", Font.BOLD, 70));
g.setColor(new Color((int)(Math.random()*255), (int)(Math.random()*255), (int)(Math.random()*255)));
g.drawString("游戏结束", 300-i, 300-i);
}
}
if(hadFood){
g.fillRect(food_x, food_y, size, size);
}
}
public SnakeJPanel() {
Snake snake=new Snake((int)(Math.random()*across)*size+6, (int)(Math.random()*vertical)*size+6);
snakes.add(snake);
setFocusable(true);
addKeyListener(this);
t.start();
creat_food();
}
public void keyPressed(KeyEvent e) {
if(e.getKeyCode()==KeyEvent.VK_LEFT){
if(StartF==-1 || StartF==UP ||StartF==DOWN){
StartF=LEFT;
}
}
if(e.getKeyCode()==KeyEvent.VK_RIGHT){
if(StartF==-1 || StartF==UP ||StartF==DOWN){
StartF=RIGHT;
}
}
if(e.getKeyCode()==KeyEvent.VK_UP){
if(StartF==-1 || StartF==LEFT ||StartF==RIGHT){
StartF=UP;
}
}
if(e.getKeyCode()==KeyEvent.VK_DOWN){
if(StartF==-1 || StartF==LEFT ||StartF==RIGHT){
StartF=DOWN;
}
}
}
@Override
public void keyTyped(KeyEvent e) {
// TODO 自动生成的方法存根
}
@Override
public void keyReleased(KeyEvent e) {
// TODO 自动生成的方法存根
}
public void run() {
while (!GameOver((Snake)snakes.get(0))) {
moveSnake();
moveSnake2();
try {
Thread.sleep(100);
} catch (InterruptedException e) {
e.printStackTrace();
}
repaint();
}
}
public boolean GameOver(Snake snake){
if(snake.x<0 || snake.x>956 || snake.y<0 || snake.y>656){
return true;
}
return false;
}
public void moveSnake(){
if(StartF==LEFT){
Snake snake=(Snake) snakes.get(0);
snake.Oldx=snake.x;
snake.Oldy=snake.y;
snake.x-=size;
}
if(StartF==RIGHT){
Snake snake=(Snake) snakes.get(0);
snake.Oldx=snake.x;
snake.Oldy=snake.y;
snake.x+=size;
}
if(StartF==UP){
Snake snake=(Snake) snakes.get(0);
snake.Oldx=snake.x;
snake.Oldy=snake.y;
snake.y-=size;
}
if(StartF==DOWN){
Snake snake=(Snake) snakes.get(0);
snake.Oldx=snake.x;
snake.Oldy=snake.y;
snake.y+=size;
}
}
public void moveSnake2(){
for (int i = 1; i < snakes.size(); i++) {
Snake snake=(Snake) snakes.get(i);
snake.Oldx=snake.x;
snake.Oldy=snake.y;
Snake snake2=(Snake) snakes.get(i-1);
snake.x=snake2.Oldx;
snake.y=snake2.Oldy;
}
}
public void creat_food(){
food_x=(int) (Math.random()*across)*size+6;
food_y=(int) (Math.random()*vertical)*size+6;
for (int i = 0; i < snakes.size(); i++) {
Snake snake=(Snake) snakes.get(i);
if(food_x==snake.x && food_y==snake.y){
food_x=(int) (Math.random()*across)*size+6;
food_y=(int) (Math.random()*vertical)*size+6;
i=0;
}
}
hadFood=true;
}
}
吃食物
(1) 蛇头和食物坐标一致表示吃食物
(2) 吃食物蛇集合就应该增加一个蛇对象
(3) New的蛇对象的坐标是前一个蛇对象保留下的坐标
(4) 返回去在蛇移动的时候就应该修改成先保留在移动
(5) 迟到食物,食物开关标识flase,与此同时在run方法中if判断食物消失,调用创建食物的方法,创建食物,食物标识就应该改为true
package snank;
import java.awt.Color;
import java.awt.Font;
import java.awt.Graphics;
import java.awt.event.KeyEvent;
import java.awt.event.KeyListener;
import java.util.ArrayList;
import javax.swing.JPanel;
public class SnakeJPanel extends JPanel implements KeyListener,Runnable{
int size = 25;
int across = 38;
int vertical = 26;
ArrayList snakes = new ArrayList();
int UP=0;
int DOWN=1;
int LEFT=2;
int RIGHT=3;
int StartF=-1;
Thread t = new Thread(this);
boolean hadFood=true;
int food_x;
int food_y;
public void paint(Graphics g) {
super.paint(g);
for (int i = 0; i <=vertical; i++) {
g.drawLine(6, 6+size*i, 6+across*size, 6+size*i);
}
for (int i = 0; i <=across; i++) {
g.drawLine(6+size*i, 6, 6+size*i, 6+vertical*size);
}
for (int i = 0; i < snakes.size(); i++) {
Snake snake=(Snake) snakes.get(i);
snake.drawSnake(g);
}
if(GameOver((Snake)snakes.get(0))){
//写艺术字
for (int i = 0; i < 10; i++) {
g.setFont(new Font("微软雅黑", Font.BOLD, 70));
g.setColor(new Color((int)(Math.random()*255), (int)(Math.random()*255), (int)(Math.random()*255)));
g.drawString("游戏结束", 300-i, 300-i);
}
}
if(hadFood){
g.fillRect(food_x, food_y, size, size);
}
}
public SnakeJPanel() {
Snake snake=new Snake((int)(Math.random()*across)*size+6, (int)(Math.random()*vertical)*size+6);
snakes.add(snake);
setFocusable(true);
addKeyListener(this);
t.start();
creat_food();
}
public void keyPressed(KeyEvent e) {
if(e.getKeyCode()==KeyEvent.VK_LEFT){
if(StartF==-1 || StartF==UP ||StartF==DOWN){
StartF=LEFT;
}
}
if(e.getKeyCode()==KeyEvent.VK_RIGHT){
if(StartF==-1 || StartF==UP ||StartF==DOWN){
StartF=RIGHT;
}
}
if(e.getKeyCode()==KeyEvent.VK_UP){
if(StartF==-1 || StartF==LEFT ||StartF==RIGHT){
StartF=UP;
}
}
if(e.getKeyCode()==KeyEvent.VK_DOWN){
if(StartF==-1 || StartF==LEFT ||StartF==RIGHT){
StartF=DOWN;
}
}
}
@Override
public void keyTyped(KeyEvent e) {
// TODO 自动生成的方法存根
}
@Override
public void keyReleased(KeyEvent e) {
// TODO 自动生成的方法存根
}
public void run() {
while (!GameOver((Snake)snakes.get(0))) {
moveSnake();
moveSnake2();
eatFood();
if(!hadFood){
creat_food();
}
try {
Thread.sleep(100);
} catch (InterruptedException e) {
e.printStackTrace();
}
repaint();
}
}
public boolean GameOver(Snake snake){
if(snake.x<0 || snake.x>956 || snake.y<0 || snake.y>656){
return true;
}
return false;
}
public void moveSnake(){
if(StartF==LEFT){
Snake snake=(Snake) snakes.get(0);
snake.Oldx=snake.x;
snake.Oldy=snake.y;
snake.x-=size;
}
if(StartF==RIGHT){
Snake snake=(Snake) snakes.get(0);
snake.Oldx=snake.x;
snake.Oldy=snake.y;
snake.x+=size;
}
if(StartF==UP){
Snake snake=(Snake) snakes.get(0);
snake.Oldx=snake.x;
snake.Oldy=snake.y;
snake.y-=size;
}
if(StartF==DOWN){
Snake snake=(Snake) snakes.get(0);
snake.Oldx=snake.x;
snake.Oldy=snake.y;
snake.y+=size;
}
}
public void moveSnake2(){
for (int i = 1; i < snakes.size(); i++) {
Snake snake=(Snake) snakes.get(i);
snake.Oldx=snake.x;
snake.Oldy=snake.y;
Snake snake2=(Snake) snakes.get(i-1);
snake.x=snake2.Oldx;
snake.y=snake2.Oldy;
}
}
public void creat_food(){
food_x=(int) (Math.random()*across)*size+6;
food_y=(int) (Math.random()*vertical)*size+6;
for (int i = 0; i < snakes.size(); i++) {
Snake snake=(Snake) snakes.get(i);
if(food_x==snake.x && food_y==snake.y){
food_x=(int) (Math.random()*across)*size+6;
food_y=(int) (Math.random()*vertical)*size+6;
i=0;
}
}
hadFood=true;
}
public void eatFood(){
Snake snake=(Snake) snakes.get(0);
if(snake.x==food_x && snake.y==food_y){
Snake snake2=(Snake) snakes.get(snakes.size()-1);
Snake snake3=new Snake(snake2.Oldx, snake2.Oldy);
snakes.add(snake3);
hadFood=false;
}
}
}
修订版
SnakeJFrame.java
package snank;
import javax.swing.JFrame;
public class SnakeJFrame extends JFrame{
public SnakeJFrame() {
this.setTitle("贪吃蛇");
this.setSize(978, 700);
this.setLocationRelativeTo(null);
this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
this.setResizable(false);
SnakeJPanel panel=new SnakeJPanel();
this.add(panel);
this.setVisible(true);
}
public static void main(String[] args) {
new SnakeJFrame();
}
}
SnakeJPanel.java
package snank;
import java.awt.Color;
import java.awt.Font;
import java.awt.Graphics;
import java.awt.event.KeyEvent;
import java.awt.event.KeyListener;
import java.util.ArrayList;
import javax.swing.JPanel;
public class SnakeJPanel extends JPanel implements KeyListener,Runnable{
int size = 25;
int across = 38;
int vertical = 26;
ArrayList snakes = new ArrayList();
int UP=0;
int DOWN=1;
int LEFT=2;
int RIGHT=3;
int Shop=-1;
int StartF=-1;
Thread t = new Thread(this);
boolean hadFood=true;
int food_x;
int food_y;
int temp = 0;
public void paint(Graphics g) {
super.paint(g);
for (int i = 0; i <=vertical; i++) {
g.drawLine(6, 6+size*i, 6+across*size, 6+size*i);
}
for (int i = 0; i <=across; i++) {
g.drawLine(6+size*i, 6, 6+size*i, 6+vertical*size);
}
for (int i = 0; i < snakes.size(); i++) {
Snake snake=(Snake) snakes.get(i);
snake.drawSnake(g);
g.setColor(Color.GREEN);
}
if(GameOver((Snake)snakes.get(0))){
//写艺术字
for (int i = 0; i < 10; i++) {
g.setFont(new Font("微软雅黑", Font.BOLD, 70));
g.setColor(new Color((int)(Math.random()*255), (int)(Math.random()*255), (int)(Math.random()*255)));
g.drawString("游戏结束", 300-i, 300-i);
}
}
if(hadFood){
g.fillRect(food_x, food_y, size, size);
}
if(StartF == -1) {
if(temp==0) {
for (int j = 0; j < 10; j++) {
g.setFont(new Font("微软雅黑", Font.BOLD, 70));
g.setColor(new Color((int)(Math.random()*255), (int)(Math.random()*255), (int)(Math.random()*255)));
g.drawString("按方向键游戏开始", 180-j, 320-j);
}
}else {
for (int j = 0; j < 10; j++) {
g.setFont(new Font("微软雅黑", Font.BOLD, 70));
g.setColor(new Color((int)(Math.random()*255), (int)(Math.random()*255), (int)(Math.random()*255)));
g.drawString("游戏暂停", 300-j, 300-j);
}
}
}
}
public SnakeJPanel() {
Snake snake=new Snake((int)(Math.random()*across)*size+6, (int)(Math.random()*vertical)*size+6);
snakes.add(snake);
setFocusable(true);
addKeyListener(this);
t.start();
creat_food();
}
public void keyPressed(KeyEvent e) {
if(e.getKeyCode()==KeyEvent.VK_LEFT){
if(StartF==-1 || StartF==UP ||StartF==DOWN){
StartF=LEFT;
}
}
if(e.getKeyCode()==KeyEvent.VK_RIGHT){
if(StartF==-1 || StartF==UP ||StartF==DOWN){
StartF=RIGHT;
}
}
if(e.getKeyCode()==KeyEvent.VK_UP){
if(StartF==-1 || StartF==LEFT ||StartF==RIGHT){
StartF=UP;
}
}
if(e.getKeyCode()==KeyEvent.VK_DOWN){
if(StartF==-1 || StartF==LEFT ||StartF==RIGHT){
StartF=DOWN;
}
}
if(e.getKeyCode()==KeyEvent.VK_SPACE) {
if(StartF==LEFT ||StartF==RIGHT || StartF==UP ||StartF==DOWN) {
StartF=Shop;
temp++;
}
}
}
@Override
public void keyTyped(KeyEvent e) {
// TODO 自动生成的方法存根
}
@Override
public void keyReleased(KeyEvent e) {
// TODO 自动生成的方法存根
}
public void run() {
while (!GameOver((Snake)snakes.get(0))) {
moveSnake();
moveSnake2();
eatFood();
if(!hadFood){
creat_food();
}
try {
Thread.sleep(100);
} catch (InterruptedException e) {
e.printStackTrace();
}
repaint();
}
}
public boolean GameOver(Snake snake){
if(snake.x<0 || snake.x>950 || snake.y<0 || snake.y>650){
return true;
}
return false;
}
public void moveSnake(){
if(StartF==LEFT){
Snake snake=(Snake) snakes.get(0);
snake.Oldx=snake.x;
snake.Oldy=snake.y;
snake.x-=size;
}
if(StartF==RIGHT){
Snake snake=(Snake) snakes.get(0);
snake.Oldx=snake.x;
snake.Oldy=snake.y;
snake.x+=size;
}
if(StartF==UP){
Snake snake=(Snake) snakes.get(0);
snake.Oldx=snake.x;
snake.Oldy=snake.y;
snake.y-=size;
}
if(StartF==DOWN){
Snake snake=(Snake) snakes.get(0);
snake.Oldx=snake.x;
snake.Oldy=snake.y;
snake.y+=size;
}
}
public void moveSnake2(){
for (int i = 1; i < snakes.size(); i++) {
Snake snake=(Snake) snakes.get(i);
snake.Oldx=snake.x;
snake.Oldy=snake.y;
Snake snake2=(Snake) snakes.get(i-1);
snake.x=snake2.Oldx;
snake.y=snake2.Oldy;
}
}
public void creat_food(){
food_x=(int) (Math.random()*across)*size+6;
food_y=(int) (Math.random()*vertical)*size+6;
for (int i = 0; i < snakes.size(); i++) {
Snake snake=(Snake) snakes.get(i);
if(food_x==snake.x && food_y==snake.y){
food_x=(int) (Math.random()*across)*size+6;
food_y=(int) (Math.random()*vertical)*size+6;
i=0;
}
}
hadFood=true;
}
public void eatFood(){
Snake snake=(Snake) snakes.get(0);
if(snake.x==food_x && snake.y==food_y){
Snake snake2=(Snake) snakes.get(snakes.size()-1);
Snake snake3=new Snake(snake2.Oldx, snake2.Oldy);
snakes.add(snake3);
hadFood=false;
}
}
}
Snake.java
package snank;
import java.awt.Color;
import java.awt.Graphics;
public class Snake {
int x,y;
int Oldx,Oldy;
public Snake(int x,int y) {
this.x=x;
this.y=y;
}
public void drawSnake(Graphics g) {
g.setColor(Color.red);
g.fillRect(x, y, 25, 25);
}
public void drawFood(Graphics g) {
g.setColor(new Color((int)(Math.random()*255), (int)(Math.random()*255), (int)(Math.random()*255)));
}
}