المحاضرة عشرون
عمل لعبة ping pong
(باستخدام مكتبة turtle )
انشاء لعبة ping pong لاعبين مع تحكم من خلال keyboard حيث يمكن لكل لاعب التحكم
بالعبة من خلال ازرار محددة من لوحة المفاتيح حيث سيتم مراجعة الأساسيات في
المحاضرات السابقة كذلك سنتعلم محاور جديدة ومهمة من مكتبة turtle
لتبسيط الكود
البرمجي سنقوم بتجزيئه وتوضيح كل جزء
أولا استدعاء المكاتبة
نقوم
باستدعاء المكتبة وانشاء متغير يحمل القيمة المنطقية True يمثل حلة تشغيل اللعبة
import
turtle
game_on=True
ثانيا انشاء لوحة الرسم
لأنشاء لوحة
رسم نقوم بأنشاء كائن من الكلاس screen
ثم نقوم بتعديل خواصه
حيث يمكن
تغير قيم العنوان الرئيسي من خلال الخاصية title() ويمكن تغير زمن التأخير من خلال الخاصية tracer()
window =
turtle.Screen()
window.title("Ping
Pong ")
window.setup(width=800,
height=600)
window.tracer(0)
window.bgcolor(.1, .3, .1)
ثالثا انشاء الكرة
لأنشاء الكرة
نقوم بأنشاء مؤشر جدد من خلال الكلاس Turtle() ونقوم بتغير خواصه
لتغير شكل أي
مؤشر في turtle نستخدم الخاصية shape()
لتغير حجم
الوشر نستخدم الخاصية shapesiz()
نستخدم اخر
سطرين لتحريك الكرة
#
ball
ball =
turtle.Turtle()
ball.speed(0)
ball.shape("circle")
ball.color("white")
ball.shapesize(stretch_len=1,
stretch_wid=1)
ball.goto(x=0,
y=0)
ball.penup()
ball_dx,
ball_dy = 1, 1
ball_speed = .5
رابعا انشاء الخط الوسطي
#
center line
center_line
= turtle.Turtle()
center_line.speed(0)
center_line.shape("square")
center_line.color("white")
center_line.shapesize(stretch_len=.1,
stretch_wid=25)
center_line.penup()
center_line.goto(0, 0)
خامسا اشاء الاعب الأول
#
player1
player1 =
turtle.Turtle()
player1.speed(0)
player1.shape("square")
player1.shapesize(stretch_len=1,
stretch_wid=5)
player1.color("blue")
player1.penup()
player1.goto(x=-350,
y=0)
سادسا انشاء الاعب الثاني
#
player2
player2 =
turtle.Turtle()
player2.speed(0)
player2.shape("square")
player2.shapesize(stretch_len=1,
stretch_wid=5)
player2.color("red")
player2.penup()
player2.goto(x=350,
y=0)
سابعا انشاء النص
انشاء نص لأظهار النتيجة
#
score text
score =
turtle.Turtle()
score.speed(0)
score.color("white")
score.penup()
score.goto(x=0,
y=260)
score.write("Player1:
0 Player2: 0", align="center",
font=("Courier", 14,
"normal"))
score.hideturtle()
p1_score,
p2_score = 0, 0
ثامنا التحريك
لغرض تحريك
الاعبين نقوم بأنشاء دالتين لكل لاعب حيث نقوم بالإضافة الى الموقع الحالي للاعب
او الطرح منه لغرض التحريك للأعلى او الأسفل كذلك ننشئ دلة close لغرض اغلاق اللعبة بدون أخطاء وسيتم توضيح
هذه النقطة بشكل مفصل في الفقرات القادمة ان شاء الله تعالى
#
Players Movement ====================
players_speed
= 20
def
p1_move_up():
player1.sety(player1.ycor() +
players_speed)
def
p1_move_down():
player1.sety(player1.ycor() -
players_speed)
def
p2_move_up():
player2.sety(player2.ycor() + players_speed)
def
p2_move_down():
player2.sety(player2.ycor() -
players_speed)
def close():
global game_on
game_on=False
تاسعا التحكم
يمكن استقبال ادخال المستخدم في مكتبة turtle من خلال احدى خصائص لوحة الرسم وهي listen()
# Get users
inputs (Key Bindings)
window.listen()
window.onkeypress(p1_move_up,
"w")
window.onkeypress(p1_move_down,
"s")
window.onkeypress(p2_move_up,
"Up")
window.onkeypress(p2_move_down,
"Down")
window.onkeypress(close,
"e")
عاشرا الحلقة التكرارية الرئيسية
نقوم بأنشاء
الحلقة التكرارية الرئسية للبرنامج
نقوم بتحريك الكرة
من خلال إضافة المتغيرات التي انشأناها في الفقرة ثالثا الى موقع الكرة الحالي
while
game_on:
window.update()
# ball movement
ball.setx(ball.xcor() + (ball_dx *
ball_speed))
ball.sety(ball.ycor() + (ball_dy * ball_speed))
أحدى عشر التصادم
داخل الحلقة
التكرارية نستخدم عبارة شرطية للتحقق من التصادم بين الكرة والجدران العلوي والسفلي
او الكرة واحد الاعبان ونقوم بعكس اتجاهها من خلال تغير قيم المتغيرات ball_dx و ball_dy الى سالب واحد
#
ball & borders collisions
if(ball.ycor() > 290):
ball.sety(290)
ball_dy *= -1
if(ball.ycor() < -290):
ball.sety(-290)
ball_dy *= -1
# ball & players collisions
=====================
# collision with player 1
if ball.xcor() < -340 and ball.xcor()
> -350 and ball.ycor() > (player1.ycor()-60) and ball.ycor() <
(player1.ycor()+60):
ball.setx(-340)
ball_dx *= -1
# collision with player 2
if ball.xcor() > 340 and ball.xcor()
< 350 and ball.ycor() > (player2.ycor()-60) and ball.ycor() <
(player2.ycor()+60):
ball.setx(340)
ball_dx *= -1
اثنى عشر احتساب الاهداف
داخل الحلقة
التكرارية الرئيسية نقوم بتحديث النتيجة وتسجيل الأهداف بعد التحقق من حدوثها ثم
نعيد الكرة الى المنتصف ونعكس اتجاهها بعد تسجيل هدف جديد
#
score handling
if(ball.xcor() > 390):
ball.goto(0, 0)
ball_dx *= -1 # invert X direction
score.clear()
p1_score += 1
score.write(f"Player1: {p1_score}
Player2: {p2_score}", align="center",
font=("Courier",
14, "normal"))
if(ball.xcor() < -390):
ball.goto(0, 0)
ball_dx *= -1 # invert X direction
score.clear()
p2_score += 1
score.write(f"Player1: {p1_score}
Player2: {p2_score}", align="center",
font=("Courier", 14,
"normal")(
ملاحظة للعب
نستخدم الازرار
الاسم اسفل و
اعلى للاعب الأول
الحرف w و s للاعب الثاني
يكون
الكيبورد باللغة الإنكليزية والاحرف الصغيرة
حل الأخطاء عند الاغلاق
والان عند اغلاق
اللعبة من خلال زر الاغلاق سنلاحظ ظهور رسالة خطء بعنوان
_tkinter.TclError: invalid command name
".!canvas"
تظهر هذه
الرسالة لسبب وهو عدم اغلاق الحلقة التكرارية بالشكل الصحيح حيث تبقى الحلقة التكرارية
لانهائية وعند اغلاق البرنامج نجبر الحلقة على الاغلاق مما يسبب هذا الخطء
وهذا هو سبب
انشاء المتغير game_on
والدالة close حيث تعمل هذه الدالة على
الاغلاق السليم
تحميل ملخص المحاضرة من هنا
تعليقات
إرسال تعليق