فى هذه الجزئية سننشئ نسخة من لعبة الثعبان
لعبة الثعبان لعبة فيديو كلاسيكية من اواخر السبعينيات ثم تم استقدامها للحاسب الشخصى، فى هذه اللعبة يتحكم اللاعب فى ثعبان وهدفها هو اكل اكثر عدد ممكن من التفاح، وكلما يأكل الثعبان يكبر حجم جسمه فيجب محاولة تفادى الإصطدام بالحائظ او بجسمه
جزء كل قطع الثعبان 10px ويتم التحكم فيه عن طريق الأسهم، ويبدأ الثعبان ب3 قطع وتبدأ اللعبة بالضغط على اى من الأسهم وعند انتهاء اللعبة نعرض Game Over فى منتصف اللوحة
snake.py #!/usr/bin/python # ZetCode PyGTK tutorial # # This is a simple snake game # clone # # author: jan bodnar # website: zetcode.com # last edited: February 2009 import sys import gtk import cairo import random import glib WIDTH = 300 HEIGHT = 270 DOT_SIZE = 10 ALL_DOTS = WIDTH * HEIGHT / (DOT_SIZE * DOT_SIZE) RAND_POS = 26 x = [0] * ALL_DOTS y = [0] * ALL_DOTS class Board(gtk.DrawingArea): def __init__(self): super(Board, self).__init__() self.modify_bg(gtk.STATE_NORMAL, gtk.gdk.Color(0, 0, 0)) self.set_size_request(WIDTH, HEIGHT) self.connect("expose-event", self.expose) self.init_game() def on_timer(self): if self.inGame: self.check_apple() self.check_collision() self.move() self.queue_draw() return True else: return False def init_game(self): self.left = False self.right = True self.up = False self.down = False self.inGame = True self.dots = 3 for i in range(self.dots): x[i] = 50 - i * 10 y[i] = 50 try: self.dot = cairo.ImageSurface.create_from_png("dot.png") self.head = cairo.ImageSurface.create_from_png("head.png") self.apple = cairo.ImageSurface.create_from_png("apple.png") except Exception, e: print e.message sys.exit(1) self.locate_apple() glib.timeout_add(100, self.on_timer) def expose(self, widget, event): cr = widget.window.cairo_create() if self.inGame: cr.set_source_rgb(0, 0, 0) cr.paint() cr.set_source_surface(self.apple, self.apple_x, self.apple_y) cr.paint() for z in range(self.dots): if (z == 0): cr.set_source_surface(self.head, x[z], y[z]) cr.paint() else: cr.set_source_surface(self.dot, x[z], y[z]) cr.paint() else: self.game_over(cr) def game_over(self, cr): w = self.allocation.width / 2 h = self.allocation.height / 2 (x, y, width, height, dx, dy) = cr.text_extents("Game Over") cr.set_source_rgb(65535, 65535, 65535) cr.move_to(w - width/2, h) cr.show_text("Game Over") self.inGame = False def check_apple(self): if x[0] == self.apple_x and y[0] == self.apple_y: self.dots = self.dots + 1 self.locate_apple() def move(self): z = self.dots while z > 0: x[z] = x[(z - 1)] y[z] = y[(z - 1)] z = z - 1 if self.left: x[0] -= DOT_SIZE if self.right: x[0] += DOT_SIZE if self.up: y[0] -= DOT_SIZE if self.down: y[0] += DOT_SIZE def check_collision(self): z = self.dots while z > 0: if z > 4 and x[0] == x[z] and y[0] == y[z]: self.inGame = False z = z - 1 if y[0] > HEIGHT - DOT_SIZE: self.inGame = False if y[0] < 0: self.inGame = False if x[0] > WIDTH - DOT_SIZE: self.inGame = False if x[0] < 0: self.inGame = False def locate_apple(self): r = random.randint(0, RAND_POS) self.apple_x = r * DOT_SIZE r = random.randint(0, RAND_POS) self.apple_y = r * DOT_SIZE def on_key_down(self, event): key = event.keyval if key == gtk.keysyms.Left and not self.right: self.left = True self.up = False self.down = False if key == gtk.keysyms.Right and not self.left: self.right = True self.up = False self.down = False if key == gtk.keysyms.Up and not self.down: self.up = True self.right = False self.left = False if key == gtk.keysyms.Down and not self.up: self.down = True self.right = False self.left = False class Snake(gtk.Window): def __init__(self): super(Snake, self).__init__() self.set_title('Snake') self.set_size_request(WIDTH, HEIGHT) self.set_resizable(False) self.set_position(gtk.WIN_POS_CENTER) self.board = Board() self.connect("key-press-event", self.on_key_down) self.add(self.board) self.connect("destroy", gtk.main_quit) self.show_all() def on_key_down(self, widget, event): key = event.keyval self.board.on_key_down(event) Snake() gtk.main()
اولا، نعرف الثوابت فى اللعبة.
WIDTH, HEIGHT ثوابت العرض والإرتفاع لتحديد مساحة اللوحة
DOT_SIZE لتحديد حجم التفاحة (النقط)
ALL_DOTS اكبر عدد ممكن من النقط
RAND_POS ثابت يحسب موقع عشوائى للتفاحة
DELAY ثابت يحدد سرعة اللعبة
x = [0] * ALL_DOTS y = [0] * ALL_DOTS
المصفوفتين يخزنو كل احداثيات ال x, y لمكونات الثعبان
الطريقة init_game .. تنشئ المتغيرات وتحمل الصور وتبدأ دالة ال timeout
These two lists store x, y coordinates of all possible joints of a snake.
The init_game() method initializes variables, loads images and starts a timeout function.
self.left = False self.right = True self.up = False self.down = False self.inGame = True self.dots = 3
فى بداية اللعبة، الثعبان لديه 3 قطع ورأسه لليمين
When the game starts, the snake has three joints. And it is heading to the right.
الطريقة Move، فيها نستخدم الأسهم للتحكم فى اتجاه حركة الثعبان (بإستخدام القطعة الأولى للثعبان) ثم يليها القطع الباقية
while z > 0: x[z] = x[(z - 1)] y[z] = y[(z - 1)] z = z - 1
هذا الكود يحرك المكونات فى سلسلة
if self.left: x[0] -= DOT_SIZE
يحرك الرأس لليسار
فى الطريقة checkCollision نختبر عملية التصادم (سواء بنفسه او بالحوائط)
while z > 0: if z > 4 and x[0] == x[z] and y[0] == y[z]: self.inGame = False z = z - 1
ننهى اللعبة فى حال اصطدام الرأس بأى من مكونات الجسم
if y[0] > HEIGHT - DOT_SIZE: self.inGame = False
ننهى اللعبة اذا اصطدم الثعبان بأسفل اللوحة
The locate_apple() method locates an apple randomly on the form.
r = random.randint(0, RAND_POS)نحصل على رقم عشوائى من 0 الى RAND_POS - 1
self.apple_x = r * DOT_SIZE ... self.apple_y = r * DOT_SIZE
تحدد احداثيات ال س ، ص للتفاحة
self.connect("key-press-event", self.on_key_down) ... def on_key_down(self, widget, event): key = event.keyval self.board.on_key_down(event)
نصطاد الضغة على اى من المفاتيح ونعالجها فى on_key_down التابعة للصف Board لنحدد اى مفتاح ضغطه اللاعب
We catch the key press event in the Snake class, and delegate the processing to the board object.
if key == gtk.keysyms.Left and not self.right: self.left = True self.up = False self.down = False
اذا ضغطنا على سهم يسار ، نقوم بإسناد قيمة True للمتغير self.left المستخدم فى الطريقة move لنغير احداثات الثعبان، لاحظ ايضا عندما يكون الثعبان متجه لليمين لانستطيع تحويله مباشرة لليسار
Figure: Snake
هذه كانت لعبة الثعبان، تم كتابتها ب PyGTK
Home Contents Top of Page