本文實例為大家分享了java貪吃蛇游戲展示的具體代碼,供大家參考,具體內容如下
1、采用MVC(model、view、control)框架模式
2、包和類的關系樹形圖為:
3、源碼:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
|
package com.huai; import Java.awt.Color; import java.awt.Graphics; import java.awt.Point; import java.util.HashSet; import java.util.LinkedList; import java.util.Set; import com.huai.listener.SnakeListener; import com.huai.util.Constant; public class Snake { //和蛇的監聽器有關 Set<SnakeListener> snakeListener = new HashSet<SnakeListener>(); //用鏈表保存蛇的身體節點 LinkedList<Point> body = new LinkedList<Point>(); private boolean life = true ; //默認速度為400ms private int speed = 400 ; private Point lastTail = null ; private boolean pause = false ; //定義各個方向 public static final int UP = 1 ; public static final int DOWN = - 1 ; public static final int LEFT = 2 ; public static final int RIGHT = - 2 ; int newDirection = RIGHT; int oldDirection = newDirection; public Snake(){ initial(); } public void initial(){ //先清空所有的節點 body.removeAll(body); int x = Constant.WIDTH/ 2 ; int y = Constant.HEIGHT/ 2 ; //蛇的默認長度為7 for ( int i = 0 ; i < 7 ; i++){ body.add( new Point(x--, y)); } } public void setSpeed( int speed){ this .speed = speed; } public void setLife( boolean life){ this .life = life; } public boolean getLife(){ return this .life; } public boolean getPause(){ return this .pause; } public void setPause( boolean pause){ this .pause = pause; } public void move(){ //蛇移動的實現所采用的數據結構為:蛇尾刪除一個節點,蛇頭增加一個節點。 System.out.println( "snake move" ); if (!(oldDirection + newDirection == 0 )){ oldDirection = newDirection; } lastTail = body.removeLast(); int x = body.getFirst().x; int y = body.getFirst().y; switch (oldDirection){ case UP: y--; break ; case DOWN: y++; break ; case LEFT: x--; break ; case RIGHT: x++; break ; } Point point = new Point(x, y); body.addFirst(point); } //當吃到一個食物的時候,把刪掉的蛇尾節點增加回來 public void eatFood(){ System.out.println( "snake eat food" ); body.addLast(lastTail); } public boolean isEatItself(){ for ( int i = 2 ; i < body.size(); i++){ if (body.getFirst().equals(body.get(i))){ return true ; } } return false ; } public void drawMe(Graphics g){ System.out.println( "draw snake" ); //循環打印蛇的各個身體節點 for (Point p:body){ if (p.equals(body.getFirst())){ //當是蛇頭的時候,就設置顏色為橘色 g.setColor(Color.orange); } else { g.setColor(Color.pink); } g.fill3DRect(p.x * Constant.CELL_SIZE, p.y * Constant.CELL_SIZE, Constant.CELL_SIZE, Constant.CELL_SIZE, true ); } } public void changeDirection( int direction){ System.out.println( "snake changeDirection" ); this .newDirection = direction; } //內部類,新增一個游戲線程 public class DriveSnake implements Runnable{ @Override public void run() { while (life){ if (!pause){ //只要讓蛇不動就可以暫停游戲 move(); } //監聽蛇每次移動的情況 for (SnakeListener listener : snakeListener){ listener.snakeMove(Snake. this ); } try { Thread.sleep(speed); } catch (InterruptedException e) { e.printStackTrace(); } } } } public void startMove(){ new Thread( new DriveSnake()).start(); } //增加監聽器的方法 public void addSnakeListener(SnakeListener listener){ if (listener != null ){ snakeListener.add(listener); } } //返回蛇的第一個身體節點 public Point getHead(){ return body.getFirst(); } //返回蛇的所有身體節點 public LinkedList<Point> getSnakeBody(){ return this .body; } public boolean died(){ this .life = false ; return true ; } } |
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
|
package com.huai; import java.awt.Color; import java.awt.Graphics; import java.awt.Point; import com.huai.util.Constant; public class Food { private int x = 0 ; private int y = 0 ; //設置食物的默認顏色為紅色 private Color color = Color.red; public void newFood(Point point){ x = point.x; y = point.y; } //判斷是否被吃到 public boolean isAte(Snake snake){ if (snake.getHead().equals( new Point(x, y))){ System.out.println( "food isAte" ); return true ; } return false ; } public void setFoodColor(Color color){ this .color = color; } public Color getFoodColor(){ return this .color; } public void drawMe(Graphics g){ System.out.println( "draw food" ); g.setColor( this .getFoodColor()); g.fill3DRect(x * Constant.CELL_SIZE, y * Constant.CELL_SIZE, Constant.CELL_SIZE, Constant.CELL_SIZE, true ); } } |
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
|
package com.huai; import java.awt.Color; import java.awt.Graphics; import java.awt.Point; import java.util.LinkedList; import java.util.Random; import com.huai.util.Constant; public class Ground { //在二維數組中,當為1,表示是磚塊 private int [][] rock = new int [Constant.WIDTH][Constant.HEIGHT]; private boolean drawLine = true ; public boolean isDrawLine() { return drawLine; } public void setDrawLine( boolean drawLine) { this .drawLine = drawLine; } public Ground(){ for ( int x = 0 ; x < Constant.WIDTH; x++){ for ( int y = 0 ; y < Constant.HEIGHT; y++){ rock[ 0 ][y] = 1 ; rock[x][ 0 ] = 1 ; rock[Constant.WIDTH- 1 ][y] = 1 ; rock[y][Constant.HEIGHT- 1 ] = 1 ; } } } //打印游戲的網格 public void drawGrid(Graphics g){ for ( int x = 2 ; x < Constant.WIDTH; x++){ g.drawLine(x * Constant.CELL_SIZE, 0 , x*Constant.CELL_SIZE, Constant.CELL_SIZE * Constant.HEIGHT); } for ( int y = 2 ; y < Constant.HEIGHT; y++){ g.drawLine( 0 , y * Constant.CELL_SIZE, Constant.WIDTH*Constant.CELL_SIZE, y*Constant.CELL_SIZE); } } public void drawMe(Graphics g){ System.out.println( "draw ground" ); //打印圍墻 g.setColor(Color.pink); for ( int x = 0 ; x < Constant.WIDTH; x++){ for ( int y = 0 ; y < Constant.HEIGHT; y++){ if (rock[x][y] == 1 ){ g.fill3DRect(x * Constant.WIDTH, y * Constant.HEIGHT, Constant.CELL_SIZE, Constant.CELL_SIZE, true ); } } } if (isDrawLine()){ g.setColor(Color.yellow); this .drawGrid(g); } } //得到一個隨機點 public Point getRandomPoint(Snake snake, Thorn thorn){ Random random = new Random(); boolean isUnderSnakebody = false ; boolean isUnderThorn = false ; int x,y = 0 ; LinkedList<Point> snakeBody = snake.getSnakeBody(); LinkedList<Point> thorns = thorn.getThorns(); do { x = random.nextInt(Constant.WIDTH); y = random.nextInt(Constant.HEIGHT); for (Point p:snakeBody){ if (x == p.x && y == p.y){ isUnderSnakebody = true ; } } for (Point point : thorns){ if (x == point.x && y == point.y){ isUnderThorn = true ; } } } while (rock[x][y] == 1 && !isUnderSnakebody && !isUnderThorn); return new Point(x, y); } public boolean isSnakeHitRock(Snake snake){ System.out.println( "snack hit rock" ); for ( int i = 0 ; i < Constant.WIDTH; i++){ for ( int j = 0 ; j < Constant.HEIGHT; j++){ if (snake.getHead().x == i && snake.getHead().y == j && rock[i][j] == 1 ){ return true ; } } } return false ; } } |
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
|
package com.huai import java.awt.Color; import java.awt.Graphics; import java.awt.Point; import java.util.LinkedList; import com.huai.util.Constant; public class Thorn { int x, y; private LinkedList<Point> thorns = new LinkedList<Point>(); //返回所有荊棘的鏈表 public LinkedList<Point> getThorns(){ return this .thorns; } public void newThorn(Point point){ x = point.x; y = point.y; thorns.add( new Point(x, y)); } public void drawMe(Graphics g){ System.out.println( "draw thorns" ); for (Point p: thorns){ int [] xb = {p.x*Constant.CELL_SIZE, (p.x*Constant.CELL_SIZE +Constant.CELL_SIZE/ 2 ), (p.x*Constant.CELL_SIZE+Constant.CELL_SIZE), (p.x*Constant.CELL_SIZE+Constant.CELL_SIZE/ 4 * 3 ), (p.x*Constant.CELL_SIZE+Constant.CELL_SIZE), (p.x*Constant.CELL_SIZE+Constant.CELL_SIZE/ 2 ), p.x*Constant.CELL_SIZE, (p.x*Constant.CELL_SIZE+Constant.CELL_SIZE/ 4 ), p.x*Constant.CELL_SIZE}; int [] yb = {p.y*Constant.CELL_SIZE, (p.y*Constant.CELL_SIZE+Constant.CELL_SIZE/ 4 ), p.y*Constant.CELL_SIZE, (p.y*Constant.CELL_SIZE+Constant.CELL_SIZE/ 2 ), (p.y*Constant.CELL_SIZE+Constant.CELL_SIZE), ( int )(p.y*Constant.CELL_SIZE+Constant.CELL_SIZE* 0.75 ), (p.y*Constant.CELL_SIZE+Constant.CELL_SIZE), (p.y*Constant.CELL_SIZE+Constant.CELL_SIZE/ 2 ), p.y*Constant.CELL_SIZE}; g.setColor(Color.darkGray); g.fillPolygon(xb, yb, 8 ); } } public boolean isSnakeHitThorn(Snake snake){ for (Point points : thorns){ if (snake.getHead().equals(points)){ System.out.println( "hit thorn" ); return true ; } } return false ; } } |
1
2
3
4
5
6
7
8
9
10
|
package com.huai.listener; import com.huai.Snake; public interface SnakeListener { public void snakeMove(Snake snake); } package com.huai.util; public class Constant { public static int CELL_SIZE = 20 ; public static int WIDTH = 20 ; public static int HEIGHT = 20 ; } |
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
|
package com.huai.view; import java.awt.Color; import java.awt.Graphics; import javax.swing.JPanel; import com.huai.Food; import com.huai.Ground; import com.huai.Snake; import com.huai.Thorn; import com.huai.util.Constant; public class GamePanel extends JPanel{ /** * */ private static final long serialVersionUID = 1L; Snake snake; Food food; Ground ground; Thorn thorn; public void display(Snake snake, Food food, Ground ground, Thorn thorn){ this .snake = snake; this .food = food; this .ground = ground; this .thorn = thorn; System.out.println( "display gamePanel" ); this .repaint(); } @Override protected void paintComponent(Graphics g) { if (snake != null && food != null && ground != null ){ g.setColor(Color.lightGray); g.fillRect( 0 , 0 , Constant.WIDTH*Constant.CELL_SIZE, Constant.HEIGHT*Constant.CELL_SIZE); snake.drawMe(g); food.drawMe(g); ground.drawMe(g); thorn.drawMe(g); } else { System.out.println( "snake = null || food = null || ground = null" ); } } } |
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
|
package com.huai.controller; import java.awt.event.KeyAdapter; import java.awt.event.KeyEvent; import com.huai.Food; import com.huai.Ground; import com.huai.Snake; import com.huai.Thorn; import com.huai.listener.SnakeListener; import com.huai.view.GamePanel; public class Controller extends KeyAdapter implements SnakeListener{ /** * 整個游戲的控制類,屬于MVC設計框架中的Controller * 其中包括控制游戲的監聽事件和游戲邏輯 */ Snake snake; Food food; Ground ground; GamePanel gamePanel; Thorn thorn; public Controller(){} //利用構造方法初始化對象 public Controller(Snake snake, Food food, Ground ground, GamePanel gamePanel, Thorn thorn) { super (); this .snake = snake; this .food = food; this .ground = ground; this .gamePanel = gamePanel; this .thorn = thorn; } @Override public void keyPressed(KeyEvent e) { switch (e.getKeyCode()){ case KeyEvent.VK_UP: snake.changeDirection(Snake.UP); snake.setSpeed( 150 ); break ; case KeyEvent.VK_DOWN: snake.changeDirection(Snake.DOWN); snake.setSpeed( 150 ); break ; case KeyEvent.VK_LEFT: snake.changeDirection(Snake.LEFT); snake.setSpeed( 150 ); break ; case KeyEvent.VK_RIGHT: snake.changeDirection(Snake.RIGHT); snake.setSpeed( 150 ); break ; case KeyEvent.VK_ENTER: if (!snake.getPause() && snake.getLife()){ //暫停游戲 snake.setPause( true );; } else if (!snake.getLife()){ //重新開始游戲 snake.setLife( true ); snake.initial(); snake.changeDirection(Snake.UP); thorn.getThorns().removeAll(thorn.getThorns()); this .startGame(); } else { snake.setPause( false ); } break ; case KeyEvent.VK_L: //當按下L按鈕時,是否顯示游戲網格 if (ground.isDrawLine()){ ground.setDrawLine( false ); } else { ground.setDrawLine( true ); } break ; } } @Override public void keyReleased(KeyEvent e) { switch (e.getKeyCode()){ case KeyEvent.VK_UP: snake.setSpeed( 400 ); break ; case KeyEvent.VK_DOWN: snake.setSpeed( 400 ); break ; case KeyEvent.VK_LEFT: snake.setSpeed( 400 ); break ; case KeyEvent.VK_RIGHT: snake.setSpeed( 400 ); break ; } } //這是實現SnakeListener監聽器所Override的方法 @Override public void snakeMove(Snake snake) { //顯示snake ,food,ground,和thorn gamePanel.display(snake, food, ground, thorn); if (ground.isSnakeHitRock(snake)){ snake.died(); } if (snake.isEatItself()){ snake.died(); } if (food.isAte(snake)){ snake.eatFood(); food.newFood(ground.getRandomPoint(snake, thorn)); thorn.newThorn(ground.getRandomPoint(snake, thorn)); } if (thorn.isSnakeHitThorn(snake)){ snake.died(); } } public void startGame(){ snake.startMove(); //這個將會啟動一個新的線程 food.newFood(ground.getRandomPoint(snake, thorn)); thorn.newThorn(ground.getRandomPoint(snake, thorn)); } } |
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
|
package com.huai.game; import java.awt.BorderLayout; import java.awt.Color; import javax.swing.JFrame; import javax.swing.JLabel; import com.huai.Food; import com.huai.Ground; import com.huai.Snake; import com.huai.Thorn; import com.huai.controller.Controller; import com.huai.util.Constant; import com.huai.view.GamePanel; public class Game { public static void main(String args[]){ Snake snake = new Snake(); Food food = new Food(); GamePanel gamePanel = new GamePanel(); Ground ground = new Ground(); Thorn thorn = new Thorn(); Controller controller = new Controller(snake, food, ground, gamePanel, thorn); JFrame frame = new JFrame( "懷哥的小小蛇兒游戲" ); frame.add(gamePanel); frame.setBackground(Color.magenta); frame.setSize(Constant.WIDTH*Constant.CELL_SIZE+ 6 , Constant.HEIGHT*Constant.CELL_SIZE+ 40 ); gamePanel.setSize(Constant.WIDTH*Constant.CELL_SIZE, Constant.HEIGHT*Constant.CELL_SIZE); frame.add(gamePanel); frame.setResizable( false ); //不可改變窗口大小 frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); frame.setVisible( true ); gamePanel.addKeyListener(controller); snake.addSnakeListener(controller); frame.addKeyListener(controller); JLabel label1 = new JLabel(); label1.setBounds( 0 , 400 , 400 , 100 ); label1.setText( " ENTER=>>PAUSE or AGAIN; " + " L=>DRAWGRID" ); label1.setForeground(Color.BLACK); frame.add(label1, BorderLayout.SOUTH); controller.startGame(); } } |
以上就是本文的全部內容,希望對大家的學習有所幫助,也希望大家多多支持服務器之家。