جستجو برای:
سبد خرید 0
  • خانه
  • دوره های آموزشی
    • دوره های حضوری و آنلاین
      • دوره جامع برنامه نویسی اندروید
      • دوره جامع برنامه نویسی فلاتر
      • دوره برنامه نویسی React Native
      • دوره آموزشی برنامه نویسی iOS
    • دوره های متخصص و حرفه ای
      • دوره متخصص اندروید (پروژه محور)
      • دوره متخصص فلاتر (پروژه محور)
      • دوره آموزش امنیت در اندروید
      • دوره درآمدزایی دلاری از گوگل پلی در ایران
  • آموزش رایگان
    • دوره رایگان اندروید
    • دوره رایگان فلاتر
  • مشاورهجدید
  • دوره VIP
  • وبلاگ
ورود
گذرواژه خود را فراموش کرده اید؟
عضویت

اطلاعات شخصی شما برای پردازش سفارش شما استفاده می‌شود، و پشتیبانی از تجربه شما در این وبسایت، و برای اهداف دیگری که در سیاست حفظ حریم خصوصی توضیح داده شده است.

ارسال مجدد کد یکبار مصرف (00:60)
  • 02188945907
  • info@amooznegar.com
  • لیست علاقه مندی ها
آکادمی آموزنگار
  • خانه
  • دوره های آموزشی
    • دوره های حضوری و آنلاین
      • دوره جامع برنامه نویسی اندروید
      • دوره جامع برنامه نویسی فلاتر
      • دوره برنامه نویسی React Native
      • دوره آموزشی برنامه نویسی iOS
    • دوره های متخصص و حرفه ای
      • دوره متخصص اندروید (پروژه محور)
      • دوره متخصص فلاتر (پروژه محور)
      • دوره آموزش امنیت در اندروید
      • دوره درآمدزایی دلاری از گوگل پلی در ایران
  • آموزش رایگان
    • دوره رایگان اندروید
    • دوره رایگان فلاتر
  • مشاورهجدید
  • دوره VIP
  • وبلاگ
شروع کنید
آخرین اطلاعیه ها
لطفا برای نمایش اطلاعیه ها وارد شوید
0

وبلاگ

آکادمی آموزنگار > اخبار > برنامه نویسی > فلاتر > ساخت یک بازی دو بعدی با فلاتر

ساخت یک بازی دو بعدی با فلاتر

1400-10-20
ارسال شده توسط آموزنگار
فلاتر
ساخت یک بازی دو بعدی با فلاتر

ظهور و رشد Flutter باعث توسعه طراحی بازی های کراس پلتفرم شده است. بازی های فلاتر را می توان تنها با چند خط کد ، طراحی و بر اساس منطق ایجاد کرد، در عین حال که UI/UX عالی را حفظ کرد.

فلاتر قابلیت رندر تا 60 فریم بر ثانیه را دارد. شما می توانید از این قابلیت برای ساخت یک بازی ساده دو بعدی یا حتی سه بعدی استفاده کنید. به خاطر داشته باشید که بازی های پیچیده تر برای توسعه در Flutter ایده خوبی نخواهد بود، زیرا بیشتر توسعه دهندگان به سمت توسعه native برای برنامه های پیچیده می روند.

ساخت بازی دو بعدی با فلاتر

در این آموزش، یکی از اولین بازی های کامپیوتری که تا به حال ساخته شده است را بازسازی خواهیم کرد: Pong.  یک بازی ساده است، بنابراین یک موقعیت عالی برای شروع است. این مقاله به دو بخش اصلی تقسیم شده است: منطق بازی و UI، تا با تمرکز بر بخش های مهم به طور جداگانه، مراحل ساخت کمی واضح تر شود.

قبل از اینکه وارد ساخت بازی شویم، بیایید پیش نیازها و تنظیمات را مرور کنیم.

پیش نیازهای ساخت بازی با فلاتر

برای درک پروژه و کدنویسی ، به موارد زیر نیاز دارید:

فلاتر روی دستگاه شما نصب شده باشد

دانش کار با دارت و فلاتر

یک ویرایشگر متن (text editor)

شروع کار برنامه نویسی بازی دو بعدی با فلاتر

در اینجا ما از Alignment(x,y) به عنوان نمایشی از Vector(x,y) برای موقعیت محور X و Y صفحه استفاده می کنیم که به توسعه ساختار بازی کمک می کند. ما همچنین برای برخی از متغیرهای خود ویجت‌های stateless ایجاد می‌کنیم و آنها را در فایل homepage.dart تعریف می‌کنیم تا کد،  حجم کمتری داشته باشد و درک آن آسان شود.

ابتدا یک پروژه فلاتر ایجاد کنید. سپس کد پیش‌فرض فایل main.dart را پاک کنید و پکیج material.dart را برای گنجاندن ویجت‌های Material در برنامه import کنید.

در مرحله بعد، یک کلاس به نام MyApp() ایجاد کنید و MaterialApp  را return کنید، سپس یک ویجت stateful ، با نام HomePage() ایجاد کنید و آن را به پارامتر home در  MaterialApp مانند زیر ارسال کنید:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
import 'package:flutter/material.dart';
import 'package:pong/homePage.dart';
void main() {
 runApp(MyApp());
}
class MyApp extends StatelessWidget {
 @override
 Widget build(BuildContext context) {
  return MaterialApp(
   debugShowCheckedModeBanner:false,
   home: HomePage(),
  );
 }
}

منطق بازی (Game logic)

در داخل HomePage()، باید توابع و متدهایی بنویسیم تا عملیات مربوط به ریاضی و فیزیک و ساختار را پشتیبانی و handle کنیم. اینها شامل رسیدگی به برخوردها(collisions)، شتاب گیری یا کاهش سرعت (accelerating or decelerating) و مسیریابی (navigation) در بازی است.

اما ابتدا باید برخی از پارامترها را تعریف کنیم که نشان‌دهنده هم‌ترازی موقعیت توپ، بازیکنان و امتیاز اولیه هر دو بازیکن است. کد پارامترها باید در زیر _HomePageState قرار گیرد که در ادامه مقاله به آن اشاره خواهیم کرد:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
//player variations
double playerX = -0.2;
double brickWidth = 0.4;
int playerScore = 0;
// enemy variable
double enemyX = -0.2;
int enemyScore = 0;
//ball
double ballx = 0;
double bally = 0;
var ballYDirection = direction.DOWN;
var ballXDirection = direction.RIGHT;
bool gameStarted = false;
...

سپس، enum برای جهت حرکت توپ و آجر ارائه می کنیم:

1
2
enum direction { UP, DOWN, LEFT, RIGHT }
...

برای اینکه این بازی کار کند، باید جاذبه مصنوعی ایجاد کنیم تا وقتی توپ به آجر بالایی (0.9) یا آجر پایینی (0.9-) برخورد کرد، در جهت مخالف حرکت کند. در غیر این صورت، اگر به هیچ یک از آجرها برخورد نکند و به بالای (1) یا پایین (1-) زمین بازی برود، آن را به عنوان باخت (loss) بازیکن ثبت می کند.

هنگامی که توپ در سمت چپ (1) یا راست (-1) به دیوار برخورد می کند، در جهت مخالف می رود:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
void startGame() {
 gameStarted = true;
 Timer.periodic(Duration(milliseconds: 1), (timer) {
  updatedDirection();
  moveBall();
  moveEnemy();
  if (isPlayerDead()) {
   enemyScore++;
   timer.cancel();
   _showDialog(false);
   // resetGame();
  }
   if (isEnemyDead()) {
   playerScore++;
   timer.cancel();
   _showDialog(true);
   // resetGame();
  }
 });
}
...

در کد بالا، با یک تابع startGame() شروع کردیم که gameStarted boolean را به true تغییر می‌دهد، پس از آن یک Timer() با مدت زمان یک ثانیه فراخوانی می‌کنیم.

نحوه خروجی گرفتن ios در فلاتر بدونه امضا و بدونه نیاز به اکانت
خواندن این مقاله
قدرت گرفته از افزونه نوشته‌های مرتبط هوشمند

در تایمر، توابعی مانند updatedDirection()،moveBall()، و moveEnemy() در کنار یک دستور if ارسال می شوند تا بررسی شود که آیا هر یک از بازیکنان شکست خورده اند یا خیر. در این صورت، امتیاز جمع می شود، تایمر cancel می شود و یک dialog نشان داده می شود.

توابع زیر تضمین می‌کنند که توپ از 0.9 فراتر نمی‌رود و زمانی که توپ با آجر تماس پیدا می‌کند، فقط در جهت مخالف حرکت می‌کند:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
void updatedDirection() {
 setState(() {
  //update vertical dirction
  if (bally >= 0.9 && playerX + brickWidth>= ballx && playerX <= ballx) {
   ballYDirection = direction.UP;
  } else if (bally <= -0.9) {
   ballYDirection = direction.DOWN;
  }
  // update horizontal directions
  if (ballx >= 1) {
   ballXDirection = direction.LEFT;
  } else if (ballx <= -1) {
   ballXDirection = direction.RIGHT;
  }
 });
}
void moveBall() {
 //vertical movement
 setState(() {
  if (ballYDirection == direction.DOWN) {
   bally += 0.01;
  } else if (ballYDirection == direction.UP) {
   bally -= 0.01;
  }
 });
 //horizontal movement
 setState(() {
  if (ballXDirection == direction.LEFT) {
   ballx -= 0.01;
  } else if (ballXDirection == direction.RIGHT) {
   ballx += 0.01;
  }
 });
}
...

همچنین اگر توپ به سمت چپ یا راست زمین برخورد کند، در جهت مخالف می رود:

1
2
3
4
5
6
7
8
9
10
11
12
13
void moveLeft() {
 setState(() {
  if (!(playerX - 0.1 <= -1)) {
   playerX -= 0.1;
  }
 });
}
void moveRight() {
 if (!(playerX + brickWidth >= 1)) {
  playerX += 0.1;
 }
}
...

توابع moveLeft() و moveRight() به کنترل حرکت آجرها از چپ به راست با استفاده از فلش صفحه کلید (keyboard arrow) کمک می کند. این توابع با یک عبارت if کار می کنند تا اطمینان حاصل شود که آجرها از عرض هر دو محور محدوده فراتر نمی روند.

تابع resetGame() بازیکنان و توپ را به موقعیت های پیش فرضشان برمی گرداند:

1
2
3
4
5
6
7
8
9
10
11
void resetGame() {
 Navigator.pop(context);
 setState(() {
  gameStarted = false;
  ballx = 0;
  bally = 0;
  playerX = -0.2;
  enemyX =- 0.2;
 });
}
...

در مرحله بعد، دو تابع isEnemyDead() و isPlayerDead() ایجاد می کنیم که یک مقدار boolean را برمی گرداند. آنها بررسی می کنند که آیا هر یک از بازیکنان شکست خورده اند یا خیر (بررسی اینکه توپ به بخش عمودی پشت آجر برخورد کرده است):

1
2
3
4
5
6
7
8
9
10
11
12
13
bool isEnemyDead(){
 if (bally <= -1) {
  return true;
 }
 return false;
}
bool isPlayerDead() {
 if (bally >= 1) {
  return true;
 }
 return false;
}
...

در نهایت، تابع _showDialog زمانی که هر یک از بازیکنان برنده می‌شوند، دیالوگی را نمایش می‌دهد. برای متمایز کردن زمانی که یک بازیکن بازنده می شود، از متغیرboolean با نام enemyDied می فرستد . سپس اعلام می‌کند که بازیکنی که بازنده نیست راند را برده است و از رنگ بازیکن برنده برای متن نمایش داده شده «play again» استفاده می‌کند.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
void _showDialog(bool enemyDied) {
 showDialog(
   context: context,
   barrierDismissible: false,
   builder: (BuildContext context) {
    // return object of type Dialog
    return AlertDialog(
     elevation: 0.0,
     shape: RoundedRectangleBorder(
       borderRadius: BorderRadius.circular(10.0)),
     backgroundColor: Colors.purple,
     title: Center(
      child: Text(
       enemyDied?"Pink Wins": "Purple Wins",
       style: TextStyle(color: Colors.white),
      ),
     ),
     actions: [
      GestureDetector(
       onTap: resetGame,
       child: ClipRRect(
        borderRadius: BorderRadius.circular(5),
        child: Container(
          padding: EdgeInsets.all(7),
          color: Colors.purple[100],
          child: Text(
           "Play Again",
           style: TextStyle(color:enemyDied?Colors.pink[300]: Colors.purple[000]),
          )),
       ),
      )
     ],
    );
   });
}

رابط کاربری (User Interface)

اکنون توسعه رابط کاربری را آغاز می کنیم.داخل ویجت build در فایل homePage.dart، کد زیر را اضافه کنید:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
return RawKeyboardListener(
 focusNode: FocusNode(),
 autofocus: false,
 onKey: (event) {
  if (event.isKeyPressed(LogicalKeyboardKey.arrowLeft)) {
   moveLeft();
  } else if (event.isKeyPressed(LogicalKeyboardKey.arrowRight)) { 
moveRight();
  }
 },
 child: GestureDetector(
  onTap: startGame,
  child: Scaffold(
    backgroundColor: Colors.grey[900],
    body: Center(
      child: Stack(
     children: [
      Welcome(gameStarted),
      //top brick
      Brick(enemyX, -0.9, brickWidth, true),
      //scoreboard
      Score(gameStarted,enemyScore,playerScore),
      // ball
      Ball(ballx, bally),
      // //bottom brick
      Brick(enemyX, 0.9, brickWidth, false)
     ],
    ))),
 ),
);

در کد،  RawKeyboardListener()را return می کنیم که حرکت از چپ به راست را در حین ساختن در وب ارائه می‌کند. این را می توان برای دستگاه های Touchscreen نیز تکرار کرد.

نقشه راه برنامه نویسی فلاتر
خواندن این مقاله
قدرت گرفته از افزونه نوشته‌های مرتبط هوشمند

ویجت GestureDetector() عملکرد onTap را ارائه می دهد که برای فراخوانی تابع startGame() که در بالا در منطق برنامه نوشته شده است، استفاده می شود. یک فرزند(child)، Scaffold() نیز برای مشخص کردن رنگ پس‌زمینه و بدنه برنامه نوشته شده است.

در مرحله بعد، یک کلاس به نام Welcome  ایجاد کنید و در یک Boolean ،pass  دهید تا بررسی کنید که آیا بازی شروع شده است یا خیر. اگر بازی شروع نشده باشد، متن “tap to play” قابل مشاهده خواهد بود:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
class Welcome extends StatelessWidget {
  
 final bool gameStarted;
 Welcome(this.gameStarted);
 @override
 Widget build(BuildContext context) {
  return Container(
    alignment: Alignment(0, -0.2),
    child: Text(
     gameStarted ? "": "T A P T O P L A Y",
     style: TextStyle(color: Colors.white),
    ));
 }
}

اکنون می‌توانیم کلاس دیگری به نام Ball ایجاد کنیم تا با استفاده از Alignment(x,y) طرح توپ و موقعیت آن را در هر نقطه از محدوده  مدیریت کنیم. ما این پارامترها را از طریق یک سازنده برای ایجاد قابلیت جابجایی و تحرک pass می دهیم، مانند:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
class Ball extends StatelessWidget {
 final x;
 final y;
 Ball(this.x, this.y);
 @override
 Widget build(BuildContext context) {
  return Container(
   alignment: Alignment(x, y),
   child: Container(
    decoration: BoxDecoration(shape: BoxShape.circle, color: Colors.white),
    width: 20,
    height: 20,
   ),
  );
 }
}

حالا بیایید کلاس Brick (آجر) را طوری طراحی کنیم که طرح آجر (brick design)، رنگ، موقعیت(position) و نوع بازیکن را مدیریت کند.

در اینجا، ما از یک معادله ریاضی (Alignment((2* x +brickWidth)/(2-brickWidth), y)) برای عبور از موقعیت محور x و y استفاده می کنیم:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
class Brick extends StatelessWidget {
 final x;
 final y;
 final brickWidth;
 final isEnemy;
 Brick( this.x, this.y, this.brickWidth, this.isEnemy);
 @override
 Widget build(BuildContext context) {
  return Container(
    alignment: Alignment((2* x +brickWidth)/(2-brickWidth), y),
    child: ClipRRect(
     borderRadius: BorderRadius.circular(10),
     child: Container(
       alignment: Alignment(0, 0),
       color: isEnemy?Colors.purple[500]: Colors.pink[300],
       height: 20,
       width:MediaQuery.of(context).size.width * brickWidth/ 2,
       ),
    ));
 }

در نهایت، کلاس Score باید مستقیماً در زیر ویجت build در فایل homepage.dart قرار گیرد. که این کلاس امتیاز هر بازیکن را نشان می دهد.

یک سازنده برای متغیرهای armiqScore و playerScore ایجاد کنید تا امتیاز هر بازیکن را کنترل کند، و gameStarted برای بررسی اینکه آیا بازی شروع شده است یا خیر. در نهایت یک محتوای Stack()، یا یک Container()  خالی نمایش می دهد.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
class Score extends StatelessWidget {
 final gameStarted;
 final enemyScore;
 final playerScore;
 Score(this.gameStarted, this.enemyScore,this.playerScore, );
 @override
 Widget build(BuildContext context) {
  return gameStarted? Stack(children: [
   Container(
     alignment: Alignment(0, 0),
     child: Container(
      height: 1,
      width: MediaQuery.of(context).size.width / 3,
      color: Colors.grey[800],
     )),
   Container(
     alignment: Alignment(0, -0.3),
     child: Text(
      enemyScore.toString(),
      style: TextStyle(color: Colors.grey[800], fontSize: 100),
     )),
   Container(
     alignment: Alignment(0, 0.3),
     child: Text(
      playerScore.toString(),
      style: TextStyle(color: Colors.grey[800], fontSize: 100),
     )),
  ]): Container();
 }
}

gif زیر یک تست از بازی را نشان می دهد:

بازی دوبعدی فلاتر

نتیجه گیری

در این مقاله، alignment، RawKeyboardListener، ویجت‌ها، Boolean ها ، ClipRect برای container ها و توابع ریاضی را در کد خود پوشش دادیم که همگی برای بازسازی بازی Pong استفاده می‌شوند. بازی همچنین می تواند با افزایش تعداد توپ ها یا کاهش طول آجر بهبود یابد و آن را پیچیده تر کند.

امیدوارم این مقاله به اندازه ساختن و مستندسازی آن مفید و سرگرم کننده بوده باشد.

قبلی مسیر تبدیل شدن به یک برنامه نویس اپلیکیشن موبایل
بعدی 25 برنامه Remote Desktop برای اندروید

1 دیدگاه

اولین کسی باشید که در مورد این مطلب اظهار نظر می کند.

  • بردیا گفت:
    1403-03-24 در 13:02

    درود وقت بخیر
    مقاله خیلی خوبی بود ولی برام سواله که میشه از فلاتر برای ساخت بازی به عنوان یه تخصص نگاه کرد؟

    پاسخ

دیدگاهتان را بنویسید لغو پاسخ

جستجو برای:
دسته‌ها
  • GoLang
  • jetpack compose
  • PHP
  • اپلیکیشن
  • امنیت
  • اندروید
  • اوپن سورس
  • برنامه نویسی
  • برنامه نویسی iOS
  • برنامه نویسی react native
  • پادکست صوتی
  • تکنولوژی
  • جاوا
  • طراح رابط کاربری
  • طراحی رابط کاربری
  • طراحی وب
  • عمومی
  • فریلنسر
  • فلاتر
  • فناوری
  • کاتلین
  • کتاب های آموزشی
  • کسب و کار
  • هوش مصنوعی
  • وردپرس
برچسب‌ها
admob coroutine dagger dagger-hilt jetpack nft rxandroid rxjava spring swift ارز دیجیتال امنیت در اندروید دارت فایربیس فوشیا مصاحبه کاری معماری mvi نقشه راه برنامه نویسی کاتلین گوگل

آکادمی آموزنگار، جایی برای آغاز یک سفر شگفت‌انگیز در دنیای برنامه‌نویسی است. آموزنگار تلاش می‌کند تا هر فردی را از هر سطحی از زندگی و تجربه به دنیای جذاب برنامه‌نویسی وارد کند.

دسترسی سریع
  • درباره ما
  • تماس با ما
  • حریم خصوصی
  • سوالات متداول
نمادها
شبکه های اجتماعی
Facebook Twitter Youtube icon--white Whatsapp

تهران، میدان ولی عصر،خیابان شهیدان سازش،کوچه سوم پلاک 5 طبقه سوم واحد 31

021-88945907

تمامی حقوق برای آکادمی آموزنگار محفوظ می باشد

اشتراک گذاری در شبکه های اجتماعی
ارسال به ایمیل
https://amooznegar.com/?p=11315
  • Afghanistan (+93)
  • Albania (+355)
  • Algeria (+213)
  • American Samoa (+1)
  • Andorra (+376)
  • Angola (+244)
  • Anguilla (+1)
  • Antigua (+1)
  • Argentina (+54)
  • Armenia (+374)
  • Aruba (+297)
  • Australia (+61)
  • Austria (+43)
  • Azerbaijan (+994)
  • Bahrain (+973)
  • Bangladesh (+880)
  • Barbados (+1)
  • Belarus (+375)
  • Belgium (+32)
  • Belize (+501)
  • Benin (+229)
  • Bermuda (+1)
  • Bhutan (+975)
  • Bolivia (+591)
  • Bonaire, Sint Eustatius and Saba (+599)
  • Bosnia and Herzegovina (+387)
  • Botswana (+267)
  • Brazil (+55)
  • British Indian Ocean Territory (+246)
  • British Virgin Islands (+1)
  • Brunei (+673)
  • Bulgaria (+359)
  • Burkina Faso (+226)
  • Burundi (+257)
  • Cambodia (+855)
  • Cameroon (+237)
  • Canada (+1)
  • Cape Verde (+238)
  • Cayman Islands (+1)
  • Central African Republic (+236)
  • Chad (+235)
  • Chile (+56)
  • China (+86)
  • Colombia (+57)
  • Comoros (+269)
  • Cook Islands (+682)
  • Côte d'Ivoire (+225)
  • Costa Rica (+506)
  • Croatia (+385)
  • Cuba (+53)
  • Curaçao (+599)
  • Cyprus (+357)
  • Czech Republic (+420)
  • Democratic Republic of the Congo (+243)
  • Denmark (+45)
  • Djibouti (+253)
  • Dominica (+1)
  • Dominican Republic (+1)
  • Ecuador (+593)
  • Egypt (+20)
  • El Salvador (+503)
  • Equatorial Guinea (+240)
  • Eritrea (+291)
  • Estonia (+372)
  • Ethiopia (+251)
  • Falkland Islands (+500)
  • Faroe Islands (+298)
  • Federated States of Micronesia (+691)
  • Fiji (+679)
  • Finland (+358)
  • France (+33)
  • French Guiana (+594)
  • French Polynesia (+689)
  • Gabon (+241)
  • Georgia (+995)
  • Germany (+49)
  • Ghana (+233)
  • Gibraltar (+350)
  • Greece (+30)
  • Greenland (+299)
  • Grenada (+1)
  • Guadeloupe (+590)
  • Guam (+1)
  • Guatemala (+502)
  • Guernsey (+44)
  • Guinea (+224)
  • Guinea-Bissau (+245)
  • Guyana (+592)
  • Haiti (+509)
  • Honduras (+504)
  • Hong Kong (+852)
  • Hungary (+36)
  • Iceland (+354)
  • India (+91)
  • Indonesia (+62)
  • Iran (+98)
  • Iraq (+964)
  • Ireland (+353)
  • Isle Of Man (+44)
  • Israel (+972)
  • Italy (+39)
  • Jamaica (+1)
  • Japan (+81)
  • Jersey (+44)
  • Jordan (+962)
  • Kazakhstan (+7)
  • Kenya (+254)
  • Kiribati (+686)
  • Kuwait (+965)
  • Kyrgyzstan (+996)
  • Laos (+856)
  • Latvia (+371)
  • Lebanon (+961)
  • Lesotho (+266)
  • Liberia (+231)
  • Libya (+218)
  • Liechtenstein (+423)
  • Lithuania (+370)
  • Luxembourg (+352)
  • Macau (+853)
  • Macedonia (+389)
  • Madagascar (+261)
  • Malawi (+265)
  • Malaysia (+60)
  • Maldives (+960)
  • Mali (+223)
  • Malta (+356)
  • Marshall Islands (+692)
  • Martinique (+596)
  • Mauritania (+222)
  • Mauritius (+230)
  • Mayotte (+262)
  • Mexico (+52)
  • Moldova (+373)
  • Monaco (+377)
  • Mongolia (+976)
  • Montenegro (+382)
  • Montserrat (+1)
  • Morocco (+212)
  • Mozambique (+258)
  • Myanmar (+95)
  • Namibia (+264)
  • Nauru (+674)
  • Nepal (+977)
  • Netherlands (+31)
  • New Caledonia (+687)
  • New Zealand (+64)
  • Nicaragua (+505)
  • Niger (+227)
  • Nigeria (+234)
  • Niue (+683)
  • Norfolk Island (+672)
  • North Korea (+850)
  • Northern Mariana Islands (+1)
  • Norway (+47)
  • Oman (+968)
  • Pakistan (+92)
  • Palau (+680)
  • Palestine (+970)
  • Panama (+507)
  • Papua New Guinea (+675)
  • Paraguay (+595)
  • Peru (+51)
  • Philippines (+63)
  • Poland (+48)
  • Portugal (+351)
  • Puerto Rico (+1)
  • Qatar (+974)
  • Republic of the Congo (+242)
  • Romania (+40)
  • Reunion (+262)
  • Russia (+7)
  • Rwanda (+250)
  • Saint Helena (+290)
  • Saint Kitts and Nevis (+1)
  • Saint Pierre and Miquelon (+508)
  • Saint Vincent and the Grenadines (+1)
  • Samoa (+685)
  • San Marino (+378)
  • Sao Tome and Principe (+239)
  • Saudi Arabia (+966)
  • Senegal (+221)
  • Serbia (+381)
  • Seychelles (+248)
  • Sierra Leone (+232)
  • Singapore (+65)
  • Sint Maarten (+1)
  • Slovakia (+421)
  • Slovenia (+386)
  • Solomon Islands (+677)
  • Somalia (+252)
  • South Africa (+27)
  • South Korea (+82)
  • South Sudan (+211)
  • Spain (+34)
  • Sri Lanka (+94)
  • St. Lucia (+1)
  • Sudan (+249)
  • Suriname (+597)
  • Swaziland (+268)
  • Sweden (+46)
  • Switzerland (+41)
  • Syria (+963)
  • Taiwan (+886)
  • Tajikistan (+992)
  • Tanzania (+255)
  • Thailand (+66)
  • The Bahamas (+1)
  • The Gambia (+220)
  • Timor-Leste (+670)
  • Togo (+228)
  • Tokelau (+690)
  • Tonga (+676)
  • Trinidad and Tobago (+1)
  • Tunisia (+216)
  • Turkey (+90)
  • Turkmenistan (+993)
  • Turks and Caicos Islands (+1)
  • Tuvalu (+688)
  • U.S. Virgin Islands (+1)
  • Uganda (+256)
  • Ukraine (+380)
  • United Arab Emirates (+971)
  • United Kingdom (+44)
  • United States (+1)
  • Uruguay (+598)
  • Uzbekistan (+998)
  • Vanuatu (+678)
  • Venezuela (+58)
  • Vietnam (+84)
  • Wallis and Futuna (+681)
  • Western Sahara (+212)
  • Yemen (+967)
  • Zambia (+260)
  • Zimbabwe (+263)
مرورگر شما از HTML5 پشتیبانی نمی کند.

سوالی دارید؟ از ما بپرسید، کارشناسان ما در اسرع وقت با شما تماس می گیرند.

آموزنگار

آکادمی آموزنگار

  • 021-88945907
  • شنبه تا چهارشنبه از ساعت 8 تا 17
  • info@amooznegar.com
ورود
استفاده از شماره تلفن
استفاده از آدرس ایمیل
آیا هنوز عضو نشده اید؟ ثبت نام کنید
بازیابی رمز عبور
استفاده از شماره تلفن
استفاده از آدرس ایمیل
ثبت نام
استفاده از شماره تلفن
استفاده از ایمیل
قبلا عضو شده اید؟ ورود به سیستم
محافظت توسط