完全用链表实现的贪吃蛇Word文档下载推荐.docx
《完全用链表实现的贪吃蛇Word文档下载推荐.docx》由会员分享,可在线阅读,更多相关《完全用链表实现的贪吃蛇Word文档下载推荐.docx(23页珍藏版)》请在冰点文库上搜索。
unsigned
curr_status;
7.
(*game_handler)
pad*
8.
(*key_handler)
this,
key);
9.
(*random_gen_food)
10.
(*random_gen_fence)
11.
(*eat)
12.};
该数据结构囊括了整个游戏的面板以及操作。
2.4.代码初步实现
有了上述的数据结构,实现代码就很简单了
首先,go_on的逻辑就是当前位置加上方向矢量
1.void
gen_go_on(struct
this)
2.{
sb->
pos.x
+=
direct.x;
pos.y
direct.y;
5.}
键盘处理就是根据不同的按键来生成方向信息
gen_key_handler(struct
game,
key)
//{0,-1},{0,1},{-1,0},{1,0}
//这几个是静态的方向数据,全部是posision结构体
//ALLOC
->
cb
list_add
(cb,
&
(game->
changes));
6.}
食物生成比较复杂,但是最简单的实现就是随机在面板的空闲链表中取出一个加入食物链表,我的这个贪吃蛇实现中,不但食物一次可以有多份,体现蛇的贪婪,并且还可以设置物体障碍,表现蛇玩命贪吃。
gen_random_gen_food(struct
game)
//random
pos
avoid
snake_body
or
kill_body
fb
(fb,
food));
最重要的就是以下这个game_handler了,它处理游戏的中心逻辑
1.unsigned
game_handler()
*snake;
//以下的遍历判断蛇节点是否需要拐弯
list_for_each(snake,
(g_pad->
snake_body)){
*sb
=
list_entry(snake,
body,
list);
*change;
list_for_each(change,
changes)){
*cp
list_entry(change,
if
(sb->
==
cp->
pos.y)
direct
12.
(snake->
next
snake_body)
13.
list_del
(change);
14.
}
15.
break;
16.
17.
18.
(*sb->
go_on)(sb);
19.
20.
//以下的遍历判断蛇头是否碰到自身或者边墙
21.
*head
snake_body.next;
22.
*kb;
23.
list_for_each(kb,
kill_body)){
24.
list_entry(kb,
25.
(head->
head->
26.
g_pad->
curr_status
1;
27.
28.
29.
//以下的遍历判断蛇头是否碰到了食物,然后吃掉它
30.
*fd;
31.
list_for_each(fd,
food)){
32.
list_entry(fd,
33.
34.
(cp);
35.
(cp,
snake_body));
36.
(*g_pad->
eat)(g_pad);
37.
random_gen_food)(g_pad);
38.
39.
40.}
最后需要一个处理按键的函数
key_handler()
//get
key
key_handler)(g_pad,
key_pos);
最终我们发现还缺点什么,那就是这个实现测试起来很麻烦,还需要单独抽取linux内核的list.h。
3.Java实现
由于用C语言编写的代码在测试的时候需要图形库,而我最烦的就是GUI编程了,关键是因为自己太懒了,而GUI环境部署又需要一定的工作量,因此难耐了。
在别人看来,部署一个qt开发环境是小菜一碟,在我看来比登天还难...
后来想在Windows平台搞,可以编译起来出了那么多的问题,不是缺这就是少那...最终,还是java是避开GUI环境的好办法。
java的好处是环境部署最简单,因此还是用java来实现吧,和2004年实现的那个一样。
虽然java中没有list_head,但是由于其本身就是面向对象的,且容器支持泛型,因此使用LinkedList也是不错的。
由于贪吃蛇的中心逻辑不在UI,因此也就只是简单的实现了一个UI,代码如下:
1.import
java.awt.*;
2.import
java.awt.event.*;
3.import
javax.swing.*;
4.import
java.util.*;
6.class
public
posision(){}
posision(int
x,
y)
this.x
this.y
14.}
15./**
*
静态数据,保存所有的位置和方向信息
这原本是可以定义到各个使用类内部以内部类实现的
@author
marywangran
*/
20.class
static_pos
static
LEFT
new
posision(-1,
0);
RIGHT
posision(1,
UP
posision(0,
-1);
DOWN
1);
HALT
pos[][];
setpos
(int
width,
height)
i
0,
j
0;
num
width*height;
posision[width][height];
for
(i
<
width;
i++)
(j
height;
j++)
pos[i][j]
posision(i,
j);
go_on(posision
curr,
direct)
return
pos[curr.x
+
direct.x][curr.y
direct.y];
41./**
42.
游戏中所有的元素都是链表,定义为body类
43.
44.
45.class
extends
Object{
46.
47.
48.
extension
ext;
49.
body(){}
50.
(posision
pos,
direct){
51.
this.pos
52.
this.direct
53.
54.
boolean
go_on
(boolean
change,
pos)
55.
(change)
56.
static_pos.go_on(this.pos,
this.direct);
57.
else
58.
(static_pos.go_on(this.pos,
this.direct).x
pos.x)&
59.
this.direct).y
pos.y);
60.
61.
true;
62.
63.
set_extension(extension
ext)
64.
this.ext
65.
66.
get_extension()
67.
this.ext;
68.
69.
//void
70.}
71./**
72.
对应于C代码的void
每一个节点的可能有的所有属性
73.
74.
75.interface
76.
set_timeout(int
timeout);
77.
long
get_timeout();
78.
star_time();
79.
set_score(int
score);
80.
get_score();
81.}
82./**
83.
食物的属性
84.
85.
86.
87.class
food_extension
implements
88.
time_out;
89.
score;
90.
start;
91.
timeout)
92.
this.time_out
timeout*1000;
93.
this.start
System.currentTimeMillis();
94.
95.
get_timeout()
96.
this.time_out;
97.
98.
star_time(){
99.
this.start;
100.
101.
score)
102.
this.score
103.
104.
get_score()
105.
this.score;
106.
107.}
108./**
109.
完全由链表实现的贪吃蛇游戏类,其本质就是处理body链表
110.
111.
112.class
Snake_Game_Pad
113.
LinkedList<
body>
114.
change_body;
115.
116.
food_body;
117.
free_body;
118.
posision>
replace_body;
119.
120.
curr_level;
121.
curr_score;
122.
123.
()
124.
LinkedList();
125.
change_body
126.
127.
food_body
128.
free_body
129.
replace_body
130.
131.
/**
132.
贪吃蛇游戏初始化
133.
@param
width
横向元素数量
134.
height
纵向元素数量
135.
init_length
初始蛇长度
136.
137.
init(int
height,
init_length)
138.
this.width
139.
this.height
140.
141.
this.width;
i++){
142.
this.height;
++)
143.
144.
free_body.add(new
body(static_pos.pos[j][i],
static_pos.HALT));
145.
146.
147.
148.
kb1
free_body.get(0);
149.
kb2
free_body.get(free_body.size()-1);
150.
free_body.remove(kb1);
151.
kill_body.add(kb1);
152.
free_body.remove(kb2);
153.
kill_body.add(kb2);
154.
155.
this.height-2;
156.
free_body.get(i*(this.width-2));
157.
free_body.get(i*(this.width-2)+this.width-1);
158.
159.
160.
free_body.r