|
1 # |
|
2 # snake.py |
|
3 # |
|
4 # Copyright (c) 2005 Nokia Corporation |
|
5 # |
|
6 # Licensed under the Apache License, Version 2.0 (the "License"); |
|
7 # you may not use this file except in compliance with the License. |
|
8 # You may obtain a copy of the License at |
|
9 # |
|
10 # http://www.apache.org/licenses/LICENSE-2.0 |
|
11 # |
|
12 # Unless required by applicable law or agreed to in writing, software |
|
13 # distributed under the License is distributed on an "AS IS" BASIS, |
|
14 # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
|
15 # See the License for the specific language governing permissions and |
|
16 # limitations under the License. |
|
17 # |
|
18 |
|
19 import appuifw |
|
20 import math |
|
21 import e32 |
|
22 from key_codes import * |
|
23 from graphics import * |
|
24 import random |
|
25 |
|
26 class SnakeGame: |
|
27 deltas=((1,0),(0,-1),(-1,0),(0,1)) |
|
28 def __init__(self): |
|
29 self.direction=0 |
|
30 self.step=5 |
|
31 self.color=(0,128,0) |
|
32 self.fillarray={} |
|
33 self.exitflag=0 |
|
34 self.score=0 |
|
35 self.wormlocs=[] |
|
36 self.wormlength=10 |
|
37 self.foodloc=None |
|
38 self.fieldcolor=(192,192,128) |
|
39 self.resboxoffset=2 |
|
40 self.state='init' |
|
41 self.old_body=appuifw.app.body |
|
42 self.canvas=appuifw.Canvas(redraw_callback=self.redraw) |
|
43 self.draw=Draw(self.canvas) |
|
44 appuifw.app.body=self.canvas |
|
45 self.fieldsize=(self.canvas.size[0]/self.step,(self.canvas.size[1]-16)/self.step) |
|
46 self.canvas.bind(EKeyRightArrow,lambda:self.turnto(0)) |
|
47 self.canvas.bind(EKeyUpArrow,lambda:self.turnto(1)) |
|
48 self.canvas.bind(EKeyLeftArrow,lambda:self.turnto(2)) |
|
49 self.canvas.bind(EKeyDownArrow,lambda:self.turnto(3)) |
|
50 self.loc=[self.fieldsize[0]/2,self.fieldsize[1]/2] |
|
51 self.place_food() |
|
52 self.state='playing' |
|
53 self.redraw(()) |
|
54 def turnto(self,direction): |
|
55 self.direction=direction |
|
56 def close_canvas(self): # break reference cycles |
|
57 appuifw.app.body=self.old_body |
|
58 self.canvas=None |
|
59 self.draw=None |
|
60 appuifw.app.exit_key_handler=None |
|
61 def redraw(self,rect): |
|
62 self.draw.clear(self.fieldcolor) |
|
63 for loc in self.fillarray.keys(): |
|
64 self.draw_square(loc,self.color) |
|
65 self.draw_score() |
|
66 if self.foodloc: |
|
67 self.draw_food() |
|
68 def draw_square(self,loc,color): |
|
69 self.draw.rectangle((loc[0]*self.step, |
|
70 16+loc[1]*self.step, |
|
71 loc[0]*self.step+self.step, |
|
72 16+loc[1]*self.step+self.step),fill=color) |
|
73 def draw_score(self): |
|
74 scoretext=u"Score: %d"%self.score |
|
75 textrect=self.draw.measure_text(scoretext, font='title')[0] |
|
76 self.draw.rectangle((0,0,textrect[2]-textrect[0]+self.resboxoffset, |
|
77 textrect[3]-textrect[1]+self.resboxoffset),fill=(0,0,0)) |
|
78 self.draw.text((-textrect[0],-textrect[1]),scoretext,(0,192,0),"title") |
|
79 def draw_food(self): |
|
80 self.draw_square(self.foodloc,(255,0,0)) |
|
81 def place_food(self): |
|
82 while 1: |
|
83 self.foodloc=(random.randint(0,self.fieldsize[0]-1), |
|
84 random.randint(0,self.fieldsize[1]-1)) |
|
85 if not self.fillarray.has_key(self.foodloc): break |
|
86 self.draw_food() |
|
87 def set_exit(self): |
|
88 self.exitflag=1 |
|
89 def run(self): |
|
90 appuifw.app.exit_key_handler=self.set_exit |
|
91 while not self.exitflag: |
|
92 self.draw_square(self.loc,self.color) |
|
93 if (tuple(self.loc) in self.fillarray or |
|
94 self.loc[0]>=self.fieldsize[0] or self.loc[0]<0 or |
|
95 self.loc[1]>=self.fieldsize[1] or self.loc[1]<0): |
|
96 break |
|
97 if tuple(self.loc)==self.foodloc: |
|
98 self.score+=10 |
|
99 self.draw_score() |
|
100 self.place_food() |
|
101 self.draw_food() |
|
102 self.wormlength+=10 |
|
103 if len(self.wormlocs)>self.wormlength: |
|
104 loc=self.wormlocs[0] |
|
105 del self.wormlocs[0] |
|
106 del self.fillarray[loc] |
|
107 self.draw_square(loc,self.fieldcolor) |
|
108 self.fillarray[tuple(self.loc)]=1 |
|
109 self.wormlocs.append(tuple(self.loc)) |
|
110 e32.ao_sleep(0.08) |
|
111 self.loc[0]+=self.deltas[self.direction][0] |
|
112 self.loc[1]+=self.deltas[self.direction][1] |
|
113 self.close_canvas() |
|
114 appuifw.app.screen='full' |
|
115 playing=1 |
|
116 while playing: |
|
117 game=SnakeGame() |
|
118 game.run() |
|
119 playing=appuifw.query(u'Final score: %d - Play again?'%game.score,'query') |