]>
git.siccegge.de Git - ghextris.git/blob - ghextris.py
3 # Gnome-hextris; a free rewrite of the xhextris game in Python for Gnome
4 # Copyright 2004 Mikko Rauhala <mjr@iki.fi>
6 # This program is free software; you can redistribute it and/or modify
7 # it under the terms of the GNU General Public License as published by
8 # the Free Software Foundation; either version 2 of the License, or
9 # (at your option) any later version.
11 # This program is distributed in the hope that it will be useful,
12 # but WITHOUT ANY WARRANTY; without even the implied warranty of
13 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 # GNU General Public License for more details.
16 # You should have received a copy of the GNU General Public License
17 # along with this program; if not, write to the Free Software
18 # Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
20 # This will be overwritten for the installed version:
28 from gi
.repository
import Gtk
29 from gi
.repository
import GObject
40 # self.piecewidth = 20
41 # self.piecenarrow = 20
43 self
.cols
= 13 # Must be odd or weirdness ensues
45 self
.width
= (((self
.cols
/2)+2)*self
.piecewidth
+
46 ((self
.cols
/2)+1) * self
.piecenarrow
) + 2
47 self
.height
= (self
.rows
+1) * self
.pieceheight
+ 2
49 self
.colors
= ("blue", "yellow", "red", "orange", "green", "purple",
50 "cyan", "gray45", "magenta", "lightblue")
51 self
.deltax
= (-1, -1, -1, 0, 0, 0, 0, 0, -1, -1)
52 self
.deltay
= (-1, -1, -1, 0, 0, 0, 0, 0, -1, -1)
54 (((0,), (0, 0, 1), (0, 0, 1), (0, 0, 1), (0, 0, 1)),
55 ((0,), (0, 0, 0, 1), (0, 1, 1), (1,)),
56 ((0,), (1, 1), (0, 0, 1, 1)),
57 ((0, 0, 1), (0, 0, 1), (0, 0, 1), (0, 0, 1)),
58 ((0,), (0, 0, 0, 1, 1), (0, 1, 1)),
59 ((0,), (0, 1), (0, 0, 1, 1), (0, 0, 0, 0, 1))),
60 (((0,), (0, 0, 1), (0, 0, 1, 1), (0, 0, 0, 1)),
61 ((0,), (0, 0, 0, 1), (0, 0, 1), (0, 1, 1)),
62 ((0,), (0,), (1, 1, 1, 1)),
63 ((0, 1), (0, 1), (0, 0, 1), (0, 0, 1)),
64 ((0, 0, 0, 1), (0, 0, 1), (0, 1, 1)),
65 ((0,), (0, 1, 0, 1), (0, 0, 1, 0, 1))),
66 (((0,), (0, 0, 1), (0, 1, 1), (0, 1)),
67 ((0,), (0, 1, 0, 1), (1, 0, 1, 0)),
68 ((0, 1), (0, 0, 1), (0, 0, 1, 1)),
69 ((0, 0, 0, 1), (0, 0, 0, 1), (0, 0, 1), (0, 0, 1)),
70 ((0,), (0,), (0, 1, 1, 1, 1)),
71 ((0,), (0, 1), (0, 0, 1), (0, 0, 1, 1))),
72 (((0, 1, 0), (0, 1, 0), (1, 0, 1)),
73 ((0,), (1, 1, 1), (0, 1, 0))),
74 (((0, 1), (1,), (1, 1)),
75 ((0, 1), (1, 0, 1), (1,)),
76 ((0, 1), (1, 0, 1), (0, 0, 1)),
77 ((0, 1), (0, 0, 1), (0, 1, 1)),
78 ((0,), (0, 0, 1), (1, 1, 1)),
79 ((0,), (1,), (1, 1, 1))),
80 (((0,), (0, 1), (1, 1, 1)),
81 ((0,), (1, 1), (1, 1, 0)),
82 ((0, 1), (1, 1), (1,)),
84 ((0, 1), (0, 1, 1), (0, 0, 1)),
85 ((0,), (0, 1, 1), (0, 1, 1))),
86 (((0, 1), (0, 1), (0, 1, 1)),
87 ((0,), (0, 1, 1), (1, 1)),
88 ((0,), (1, 1), (1, 0, 1)),
89 ((0, 1), (1, 1), (0, 1)),
90 ((0, 1), (0, 1, 1), (1,)),
91 ((0,), (1, 1, 1), (0, 0, 1))),
92 (((0, 1), (0, 1), (1, 1)),
93 ((0,), (1, 1, 1), (1,)),
94 ((0, 1), (1, 1), (0, 0, 1)),
95 ((0, 1), (0, 1, 1), (0, 1)),
96 ((0,), (0, 1, 1), (1, 0, 1)),
97 ((0,), (1, 1), (0, 1, 1))),
98 (((0,), (0, 0, 1), (0, 0, 1), (0, 0, 1, 1)),
99 ((0,), (0, 0, 0, 1), (0, 1, 1), (0, 1)),
100 ((0,), (0, 1), (1, 0, 1, 1)),
101 ((0, 1), (0, 0, 1), (0, 0, 1), (0, 0, 1)),
102 ((0, 0, 0, 1), (0, 0, 0, 1), (0, 1, 1)),
103 ((0,), (0, 1), (0, 0, 1, 1, 1))),
104 (((0,), (0, 0, 1), (0, 0, 1), (0, 1, 1)),
105 ((0,), (0, 0, 0, 1), (1, 1, 1)),
106 ((0, 1), (0, 1), (0, 0, 1, 1)),
107 ((0, 0, 0, 1), (0, 0, 1), (0, 0, 1), (0, 0, 1)),
108 ((0,), (0, 0, 0, 1), (0, 1, 1, 0, 1)),
109 ((0,), (0, 1), (0, 0, 1, 1), (0, 0, 0, 1)))
113 self
.speed_orig
= 400
115 self
.speed_ratio
= 0.99
116 self
.speed_reset
= False
125 self
.nextpiece
= False
129 def draw_hexagon(self
, group
, color
):
131 pts
.append ((self
.piecewidth
- self
.piecenarrow
)/2)
133 pts
.append (self
.piecewidth
- pts
[0])
135 pts
.append (self
.piecewidth
)
136 pts
.append (self
.pieceheight
/2)
138 pts
.append (self
.pieceheight
)
145 item
= group
.add ("GnomeCanvasPolygon", points
= pts
, fill_color
= color
,
146 outline_color
= "black", width_units
= 1)
149 def draw_piece(self
, group
, matrix
, color
):
150 for i
in range(len(matrix
)):
151 for j
in range(len(matrix
[i
])):
152 if matrix
[i
][j
] != 0:
153 g
= group
.add("GnomeCanvasGroup",
154 x
= (j
*(self
.piecewidth
+self
.piecenarrow
)/2),
155 y
= ((i
* (self
.pieceheight
)) +
156 ((j
%2) * self
.pieceheight
/2)))
157 self
.draw_hexagon(g
, color
)
159 def place_piece(self
, group
, matrix
, color
, x
, y
):
160 piecegroup
= group
.add("GnomeCanvasGroup",
161 x
= (x
+1)*((self
.piecewidth
+self
.piecenarrow
)/2),
162 y
= ((y
* self
.pieceheight
) -
163 (((x
%2)+1) * self
.pieceheight
/2)))
164 self
.draw_piece(piecegroup
, matrix
, color
)
167 def init_board(self
):
168 board
= self
.canvas
.root()
169 for i
in range(self
.rows
+1):
171 boardhex
= board
.add("GnomeCanvasGroup",
172 x
= j
* (self
.piecewidth
*(self
.cols
/2+1) +
173 self
.piecenarrow
*(self
.cols
/2+1)),
174 y
= i
* self
.pieceheight
)
175 self
.draw_hexagon(boardhex
, "gray")
176 for i
in range(self
.cols
/2):
177 boardhex
= board
.add("GnomeCanvasGroup",
178 x
= (i
+1) * (self
.piecewidth
+
180 y
= self
.rows
* self
.pieceheight
)
181 self
.draw_hexagon(boardhex
, "gray")
182 for i
in range(self
.cols
/2+1):
183 boardhex
= board
.add("GnomeCanvasGroup",
184 x
= (i
* (self
.piecewidth
+ self
.piecenarrow
)+
185 (self
.piecewidth
+ self
.piecenarrow
)/2),
186 y
= ((self
.rows
*2-1) * self
.pieceheight
)/2)
187 self
.draw_hexagon(boardhex
, "gray")
189 def on_new_activate(self
, event
):
190 self
.speed
= self
.speed_orig
198 if self
.board
!= False:
200 self
.board
= self
.canvas
.root().add("GnomeCanvasGroup", x
= 0, y
= 0)
203 for i
in range(self
.rows
):
204 self
.field
.append([])
205 for j
in range(self
.cols
):
206 self
.field
[i
].append(0)
209 for i
in range(self
.rows
):
210 self
.rowgroups
.append(self
.board
.add("GnomeCanvasGroup", x
= 0,
211 y
= i
* self
.pieceheight
))
213 self
.nextnum
= random
.randint(0, 9)
216 if self
.running
== False:
217 GObject
.timeout_add(self
.speed
, self
.timer_handler
)
220 self
.speed_reset
= True
224 def on_about_activate(self
, event
):
225 aTree
= self
.builder
.get_object("about")
226 about
= aTree
.get_widget("about")
227 about
.set_property("name", "Ghextris")
228 about
.set_property("version", VERSION
)
231 def on_pause_game_activate(self
, event
):
232 if self
.lost
== True:
234 if self
.paused
== True:
240 def on_quit_activate(self
, event
):
244 gnome
.init("Ghextris", VERSION
)
245 gettext
.install("ghextris")
246 self
.builder
= Gtk
.Builder()
247 self
.builder
.add_from_file(os
.path
.join(SHAREDIR
, "ghextris.builder"))
248 wTree
=self
.builder
.get_object("GhextrisApp")
249 dic
= {"on_new_activate": self
.on_new_activate
,
250 "on_pause_game_activate": self
.on_pause_game_activate
,
251 "on_quit_activate": self
.on_quit_activate
,
252 "on_about_activate": self
.on_about_activate
}
253 wTree
.signal_autoconnect(dic
)
255 win
= wTree
.get_widget("GhextrisApp")
256 self
.canvas
= wTree
.get_widget("canvas")
257 preview
= wTree
.get_widget("previewcanvas")
258 appbar
= wTree
.get_widget("appbar").get_children()[0]
259 self
.appbar
= appbar
.get_children()[0]
261 win
.connect('destroy', self
.on_quit_activate
)
263 self
.canvas
.set_size_request(self
.width
, self
.height
)
264 self
.canvas
.set_scroll_region(0, 0, self
.width
, self
.height
)
267 preview
.set_size_request(self
.piecewidth
* 4, self
.pieceheight
* 5)
269 self
.preview
= preview
.root()
271 win
.connect("key-press-event", self
.key_handler
)
280 def next_piece(self
):
281 self
.piecenum
= self
.nextnum
282 self
.nextnum
= random
.randint(0, 9)
284 self
.piece_x
= (self
.cols
/2)-1 + self
.deltax
[self
.piecenum
]
285 self
.piece_y
= -3 + self
.deltax
[self
.piecenum
]
286 self
.piece
= self
.place_piece(self
.board
, self
.pieces
[self
.piecenum
][0],
287 self
.colors
[self
.piecenum
%(len(self
.colors
)+1)],
288 self
.piece_x
, self
.piece_y
)
290 if self
.nextpiece
!= False:
291 self
.nextpiece
.destroy()
292 self
.nextpiece
= self
.place_piece(self
.preview
,
293 self
.pieces
[self
.nextnum
][0],
294 self
.colors
[self
.nextnum
%(len(self
.colors
)+1)],
295 self
.deltax
[self
.nextnum
],
296 self
.deltay
[self
.nextnum
])
298 def timer_handler(self
):
299 if self
.lost
== True:
303 if self
.paused
== True:
307 if self
.check_collisions() == True:
310 if self
.top_occupied() != True:
314 if self
.hiscore
< self
.score
:
315 self
.hiscore
= self
.score
320 self
.piece
.move(0, self
.pieceheight
)
322 if self
.speed_reset
== True:
323 self
.speed_reset
= False
324 GObject
.timeout_add(int(self
.speed
), self
.timer_handler
)
329 def update_appbar(self
):
330 self
.appbar
.set_text("%s: %d | %s: %d" % (_("Score"), self
.score
,
334 def key_handler(self
, widget
, event
=None):
335 if self
.lost
== True:
338 if event
.keyval
== Gdk
.KEY_p
and self
.lost
== False:
339 if self
.paused
== True:
345 if self
.paused
== True:
348 if event
.keyval
== Gdk
.KEY_Up
or event
.keyval
== Gdk
.KEY_Down
:
349 if event
.keyval
== Gdk
.KEY_Up
:
353 old_attitude
= self
.attitude
354 self
.attitude
= ((self
.attitude
+ attitude_change
+
355 len(self
.pieces
[self
.piecenum
])) %
356 len(self
.pieces
[self
.piecenum
]))
357 if self
.check_collisions() == True:
358 self
.attitude
= old_attitude
362 self
.piece
= self
.place_piece(self
.board
,
363 self
.pieces
[self
.piecenum
][self
.attitude
],
364 self
.colors
[self
.piecenum
%(len(self
.colors
)+1)],
365 self
.piece_x
, self
.piece_y
);
368 if event
.keyval
== Gdk
.KEY_Left
or event
.keyval
== Gdk
.KEY_Right
:
369 if event
.keyval
== Gdk
.KEY_Left
:
373 self
.piece_x
+= deltax
376 if self
.piece_x
%2 == 0:
377 deltay
+= self
.pieceheight
/2
379 deltay
-= self
.pieceheight
/2
381 if self
.check_collisions() == True:
383 self
.piece_x
-= deltax
386 deltay
+= self
.pieceheight
387 if self
.check_collisions() == True:
388 self
.piece_x
-= deltax
392 self
.piece
.move(deltax
*(self
.piecewidth
+self
.piecenarrow
)/2, deltay
)
395 if event
.keyval
== Gdk
.KEY_space
:
396 orig_piece_y
= self
.piece_y
397 while self
.check_collisions() == False:
400 self
.piece
.move(0, self
.pieceheight
*(self
.piece_y
- orig_piece_y
))
401 self
.score
+= self
.piece_y
- orig_piece_y
402 if self
.score
> self
.hiscore
:
403 self
.hiscore
= self
.score
405 if self
.top_occupied() != True:
409 if self
.hiscore
< self
.score
:
410 self
.hiscore
= self
.score
417 def check_collisions(self
):
418 for i
in range(len(self
.pieces
[self
.piecenum
][self
.attitude
])):
419 for j
in range(len(self
.pieces
[self
.piecenum
][self
.attitude
][i
])):
420 if self
.pieces
[self
.piecenum
][self
.attitude
][i
][j
] != 0:
421 if j
%2 == 0 and self
.piece_x
%2 == 1:
425 if j
+ self
.piece_x
< 0 or j
+ self
.piece_x
>= self
.cols
:
427 if ((i
+ self
.piece_y
+ deltay
> 0) and
428 (i
+ self
.piece_y
+ deltay
>= self
.rows
or
429 self
.field
[i
+ self
.piece_y
+ deltay
][j
+ self
.piece_x
] != 0)):
433 def update_field(self
):
434 for i
in range(len(self
.pieces
[self
.piecenum
][self
.attitude
])):
435 for j
in range(len(self
.pieces
[self
.piecenum
][self
.attitude
][i
])):
436 if self
.pieces
[self
.piecenum
][self
.attitude
][i
][j
] != 0:
437 if j
%2 == 0 and self
.piece_x
%2 == 1:
441 if i
+self
.piece_y
+deltay
>= 0:
442 self
.field
[i
+ self
.piece_y
+ deltay
][j
+ self
.piece_x
] = 1
443 self
.place_piece(self
.rowgroups
[i
+self
.piece_y
+deltay
],
445 self
.colors
[self
.piecenum
%(len(self
.colors
)+1)],
446 j
+ self
.piece_x
- 1, 0)
450 def collapse_rows(self
):
452 for i
in range(self
.rows
):
454 for j
in range(self
.cols
):
455 if self
.field
[i
][j
] == 0:
461 self
.speed
*= self
.speed_ratio
462 self
.speed_reset
= True
463 self
.rowgroups
[i
].destroy()
464 for j
in range(i
-1, -1, -1):
465 self
.rowgroups
[j
].move(0, self
.pieceheight
)
466 self
.rowgroups
[j
+1] = self
.rowgroups
[j
]
467 self
.field
[j
+1] = self
.field
[j
]
469 for j
in range(self
.cols
):
470 self
.field
[0].append(0)
471 self
.rowgroups
[0] = self
.board
.add("GnomeCanvasGroup", x
= 0,
474 self
.score
+= row_points
475 if self
.score
> self
.hiscore
:
476 self
.hiscore
= self
.score
479 def top_occupied(self
):
480 for i
in range(self
.cols
):
481 if self
.field
[0][i
] != 0:
485 if __name__
== '__main__':