সুচিপত্র:

জয়স্টিক এবং আইআর রিসিভারের সাথে আরডুইনো-নিয়ন্ত্রিত প্ল্যাটফর্মার গেম: 3 টি ধাপ (ছবি সহ)
জয়স্টিক এবং আইআর রিসিভারের সাথে আরডুইনো-নিয়ন্ত্রিত প্ল্যাটফর্মার গেম: 3 টি ধাপ (ছবি সহ)

ভিডিও: জয়স্টিক এবং আইআর রিসিভারের সাথে আরডুইনো-নিয়ন্ত্রিত প্ল্যাটফর্মার গেম: 3 টি ধাপ (ছবি সহ)

ভিডিও: জয়স্টিক এবং আইআর রিসিভারের সাথে আরডুইনো-নিয়ন্ত্রিত প্ল্যাটফর্মার গেম: 3 টি ধাপ (ছবি সহ)
ভিডিও: Arduino LCD Game Project #arduino #arduinoproject 2024, জুলাই
Anonim
Arduino- নিয়ন্ত্রিত Platformer গেম জয়স্টিক এবং IR রিসিভার সহ
Arduino- নিয়ন্ত্রিত Platformer গেম জয়স্টিক এবং IR রিসিভার সহ

আজ, আমরা একটি সহজ C #- ভিত্তিক প্ল্যাটফর্মার গেম নিয়ন্ত্রণ করতে একটি Arduino মাইক্রোকন্ট্রোলার ব্যবহার করতে যাচ্ছি। আমি একটি জয়স্টিক মডিউল থেকে ইনপুট নিতে Arduino ব্যবহার করছি, এবং সেই ইনপুটটি C# অ্যাপ্লিকেশনে পাঠান যা একটি সিরিয়াল সংযোগে ইনপুট শোনে এবং ডিকোড করে। যদিও প্রজেক্টটি সম্পন্ন করার জন্য ভিডিও গেম তৈরিতে আপনার পূর্বের কোন অভিজ্ঞতার প্রয়োজন নেই, তবে "গেম লুপ" এর মধ্যে চলমান কিছু জিনিসকে শোষণ করতে কিছু সময় লাগতে পারে, যা আমরা পরে আলোচনা করব।

এই প্রকল্পটি সম্পন্ন করতে আপনার প্রয়োজন হবে:

  • ভিজ্যুয়াল স্টুডিও কমিউনিটি
  • একটি Arduino Uno (বা অনুরূপ)
  • একটি জয়স্টিক কন্ট্রোলার মডিউল
  • ধৈর্য

আপনি যদি শুরু করতে প্রস্তুত হন, চালিয়ে যান!

ধাপ 1: জয়স্টিক এবং আইআর এলইডি হুক আপ করুন

হুক আপ দ্য জয়স্টিক এবং আইআর এলইডি
হুক আপ দ্য জয়স্টিক এবং আইআর এলইডি
হুক আপ দ্য জয়স্টিক এবং আইআর এলইডি
হুক আপ দ্য জয়স্টিক এবং আইআর এলইডি

এখানে, hookup মোটামুটি সহজ। আমি ডায়াগ্রামগুলি অন্তর্ভুক্ত করেছি যা শুধুমাত্র জয়স্টিক সংযুক্ত থাকে, সেইসাথে আমি যে সেটআপটি ব্যবহার করছি, যার মধ্যে রয়েছে রয়মট কন্ট্রোল দিয়ে গেমটি নিয়ন্ত্রণ করার জন্য জয়স্টিক প্লাস একটি ইনফ্রারেড এলইডি, যা অনেক Arduino কিট সহ আসে। এটি alচ্ছিক, তবে ওয়্যারলেস গেমিং করতে সক্ষম হওয়ার জন্য এটি একটি দুর্দান্ত ধারণা বলে মনে হয়েছিল।

সেটআপে ব্যবহৃত পিনগুলি হল:

  • A0 (এনালগ) <- অনুভূমিক বা X- অক্ষ
  • A1 (এনালগ) <- উল্লম্ব বা Y- অক্ষ
  • পিন 2 <- জয়স্টিক সুইচ ইনপুট
  • পিন 2 <- ইনফ্রারেড LED ইনপুট
  • VCC <- 5V
  • গ্রাউন্ড
  • গ্রাউন্ড #2

ধাপ 2: একটি নতুন স্কেচ তৈরি করুন

একটি নতুন স্কেচ তৈরি করুন
একটি নতুন স্কেচ তৈরি করুন

আমরা আমাদের Arduino স্কেচ ফাইল তৈরি করে শুরু করব। এটি পরিবর্তনের জন্য জয়স্টিক নির্বাচন করে, এবং সেই পরিবর্তনগুলি C# প্রোগ্রামে প্রতি কয়েক মিলিসেকেন্ডে পাঠায়। একটি প্রকৃত ভিডিও গেমে, আমরা ইনপুটের জন্য একটি গেম লুপে সিরিয়াল পোর্টটি পরীক্ষা করতাম, কিন্তু আমি একটি পরীক্ষা হিসাবে গেমটি শুরু করেছিলাম, তাই ফ্রেমরেট আসলে সিরিয়াল পোর্টের ইভেন্টের সংখ্যার উপর ভিত্তি করে। আমি আসলে আরডুইনো বোন প্রকল্প, প্রসেসিং -এ প্রকল্পটি শুরু করেছিলাম, কিন্তু দেখা গেল এটি অনেক, অনেক ধীর এবং স্ক্রিনে বাক্সের সংখ্যা পরিচালনা করতে পারছে না।

সুতরাং, প্রথমে Arduino কোড এডিটর প্রোগ্রামে একটি নতুন স্কেচ তৈরি করুন। আমি আমার কোড দেখাব এবং তারপরে এটি কী তা ব্যাখ্যা করবে:

#অন্তর্ভুক্ত "IRremote.h"

// IR ভেরিয়েবল int রিসিভার = 3; // IR রিসিভারের সিগন্যাল পিন IRrecv irrecv (রিসিভার); // 'irrecv' decode_results ফলাফলের উদাহরণ তৈরি করুন; // 'decode_results' এর উদাহরণ তৈরি করুন // জয়স্টিক/গেম ভেরিয়েবল int xPos = 507; int yPos = 507; বাইট joyXPin = A0; বাইট joyYPin = A1; বাইট joySwitch = 2; উদ্বায়ী বাইট clickCounter = -1; int minMoveHigh = 530; int minMoveLow = 490; int currentSpeed = 550; // ডিফল্ট = একটি গড় গতি int speedIncrement = 25; // Y ইনপুট স্বাক্ষরবিহীন দীর্ঘ বর্তমান = 0 দিয়ে গতি বৃদ্ধি/হ্রাস করার পরিমাণ = 0; // বর্তমান টাইমস্ট্যাম্প int অপেক্ষা = 40; // ms বার্তাগুলির মধ্যে অপেক্ষা করতে // বোতামটি অকার্যকর সেটআপ () {Serial.begin (9600); pinMode (joySwitch, INPUT_PULLUP); attachInterrupt (0, লাফ, FALLING); বর্তমান = মিলিস (); // বর্তমান সময় সেট করুন // ইনফ্রারেড রিসিভার সেট আপ করুন: irrecv.enableIRIn (); // রিসিভার শুরু করুন} // সেটআপ অকার্যকর লুপ () {int xMovement = analogRead (joyXPin); int yPos = analogRead (joyYPin); // সময় নির্বিশেষে জয়স্টিক এক্স মুভমেন্ট পরিচালনা করুন: যদি (xMovement> minMoveHigh || xMovement current + wait) {currentSpeed = yPos> minMoveLow && yPos <minMoveHigh // যদি শুধু একটু সরানো হয়…? currentSpeed //… শুধু বর্তমান গতি ফিরিয়ে দিন: getSpeed (yPos); // শুধুমাত্র yPos পরিবর্তন করুন যদি জয়স্টিক উল্লেখযোগ্যভাবে সরানো হয় // int দূরত্ব =; Serial.print ((String) xPos + "," + (String) yPos + ',' + (String) currentSpeed + '\ n'); বর্তমান = মিলিস (); }} // লুপ int getSpeed (int yPos) {// নেতিবাচক মান নির্দেশ করে জয়স্টিক যদি উপরে উঠে যায় (yPos 1023? 1023: currentSpeed + speedIncrement;} অন্যথায় যদি (yPos> minMoveHigh) // ব্যাখ্যা করা হয় "ডাউন" {// সুরক্ষা থেকে 0 এর অধীনে যাচ্ছে currentSpeed - speedIncrement <0? 0: currentSpeed - speedIncrement;}} // getSpeed void jump () {buttonPressed = true; // Indicate button was pressed।} // jump // when a button is pressed on the দূরবর্তী, সঠিক প্রতিক্রিয়া অকার্যকর অনুবাদ আইআর (decode_results ফলাফল) // আইআর কোড প্রাপ্তির উপর ভিত্তি করে পদক্ষেপ নেয় {সুইচ (results.value) {কেস 0xFF18E7: //Serial.println("2 "); break; case 0xFF10EF: //Serial.println("4 "); xPos = -900; break; case 0xFF38C7: //Serial.println("5"); jump (); break; case 0xFF5AA5: // সিরিয়াল। println ("6"); xPos = 900; break; case 0xFF4AB5: //Serial.println("8 "); currentSpeed -= speedIncrement * 2; break; default: //Serial.println (" other button "); বিরতি;} // শেষ সুইচ} // END translateIR

আমি বেশিরভাগ স্ব-ব্যাখ্যামূলক হওয়ার জন্য কোডটি তৈরি করার চেষ্টা করেছি, তবে উল্লেখযোগ্য কয়েকটি জিনিস রয়েছে। একটি জিনিস যা আমি হিসাব করার চেষ্টা করেছি তা নিম্নলিখিত লাইনগুলিতে ছিল:

int minYMoveUp = 520;

int minYMoveDown = 500;

যখন প্রোগ্রাম চলমান থাকে, জয়স্টিক থেকে এনালগ ইনপুট প্রায় লাফাতে থাকে, সাধারণত 507 এর কাছাকাছি থাকে। এর জন্য সংশোধন করার জন্য, ইনপুটটি পরিবর্তিত হয় না যদি না এটি minYMoveUp এর চেয়ে বড় হয়, অথবা minYMoveDown এর চেয়ে ছোট হয়।

pinMode (joySwitch, INPUT_PULLUP);

attachInterrupt (0, লাফ, FALLING);

AttachInterrupt () পদ্ধতি আমাদের যেকোনো সময় স্বাভাবিক লুপকে বাধাগ্রস্ত করতে দেয়, যাতে আমরা ইনপুট নিতে পারি, যেমন জয়স্টিক বোতামটি ক্লিক করার সময় বোতাম টিপুন। এখানে, আমরা পিনমোড () পদ্ধতি ব্যবহার করে এর আগে লাইনে ইন্টারাপ্ট সংযুক্ত করেছি। এখানে একটি গুরুত্বপূর্ণ নোট হল যে Arduino Uno- এ একটি বাধা সংযুক্ত করতে, আপনাকে 2 বা 3 পিন ব্যবহার করতে হবে। দ্বিতীয় প্যারামিটার কলব্যাক পদ্ধতির জন্য, এখানে একটি ISR বা "ইন্টারাপ্ট সার্ভিস রুটিন" বলা হয়। এটি কোন প্যারামিটার নেওয়া বা কিছু ফেরত দেওয়া উচিত নয়।

সিরিয়াল.প্রিন্ট (…)

এই লাইনটি আমাদের ডেটা C# গেমটিতে পাঠাবে। এখানে, আমরা X- অক্ষ পাঠ, Y- অক্ষ পাঠ, এবং একটি গতি পরিবর্তনশীল খেলা পাঠান। গেমটিকে আরও আকর্ষণীয় করে তুলতে অন্যান্য ইনপুট এবং রিডিং অন্তর্ভুক্ত করার জন্য এই রিডিংগুলি প্রসারিত করা যেতে পারে, তবে এখানে আমরা কেবল একটি দম্পতি ব্যবহার করব।

আপনি যদি আপনার কোড পরীক্ষা করার জন্য প্রস্তুত হন, তাহলে এটি Arduino তে আপলোড করুন এবং সিরিয়াল মনিটরটি খুলতে [Shift] + [Ctrl] + [M] টিপুন এবং দেখুন আপনি কোন আউটপুট পাচ্ছেন কিনা। আপনি যদি Arduino থেকে ডেটা পাচ্ছেন, আমরা কোডের C# অংশে যাওয়ার জন্য প্রস্তুত …

ধাপ 3: C# প্রকল্প তৈরি করুন

আমাদের গ্রাফিক্স প্রদর্শন করার জন্য, আমি প্রথমে প্রক্রিয়াকরণে একটি প্রকল্প শুরু করেছিলাম, কিন্তু পরবর্তীতে সিদ্ধান্ত নিয়েছিলাম যে আমাদের প্রদর্শনের জন্য প্রয়োজনীয় সমস্ত বস্তু দেখানো খুব ধীর হবে। সুতরাং, আমি সি#ব্যবহার করতে বেছে নিয়েছি, যা আমাদের ইনপুট পরিচালনা করার সময় অনেক মসৃণ এবং আরও প্রতিক্রিয়াশীল হয়ে উঠেছে।

প্রকল্পের C# অংশের জন্য,.zip ফাইলটি ডাউনলোড করে নিজের ফোল্ডারে এক্সট্র্যাক্ট করা, তারপর এটি সংশোধন করা ভাল। জিপ ফাইলে দুটি ফোল্ডার আছে। ভিজ্যুয়াল স্টুডিওতে প্রকল্পটি খুলতে, উইন্ডোজ এক্সপ্লোরারে RunnerGame_CSharp ফোল্ডারে প্রবেশ করুন। এখানে,.sln (সমাধান) ফাইলে ডাবল ক্লিক করুন, এবং ভিএস প্রকল্পটি লোড করবে।

গেমের জন্য আমার তৈরি করা বিভিন্ন ক্লাস আছে। আমি প্রতিটি ক্লাসের সমস্ত বিবরণে যাব না, তবে প্রধান ক্লাসগুলি কী সেগুলির একটি সংক্ষিপ্ত বিবরণ দেব।

বক্স ক্লাস

আমি একটি সহজ আয়তক্ষেত্র বস্তু তৈরি করতে আপনাকে বক্স ক্লাস তৈরি করেছি যা একটি উইন্ডো আকারে পর্দায় আঁকা যায়। ধারণাটি এমন একটি শ্রেণী তৈরি করা যা অন্য শ্রেণীর ব্যবহার করে বাড়ানো যেতে পারে যা হয়তো কোনো ধরনের গ্রাফিক্স আঁকতে চায়। "ভার্চুয়াল" কীওয়ার্ড ব্যবহার করা হয় যাতে অন্য ক্লাসগুলি তাদের ওভাররাইড করতে পারে ("ওভাররাইড" কীওয়ার্ড ব্যবহার করে)। এই ভাবে, প্লেয়ার ক্লাস এবং প্ল্যাটফর্ম ক্লাসের জন্য আমরা যখন প্রয়োজন তখন একই আচরণ পেতে পারি, এবং বস্তুগুলিকেও পরিবর্তন করতে পারি যা আমাদের প্রয়োজন।

সমস্ত বৈশিষ্ট্য এবং কলগুলি সম্পর্কে খুব বেশি চিন্তা করবেন না। আমি এই ক্লাসটি লিখেছি যাতে আমি ভবিষ্যতে যে কোনো গেম বা গ্রাফিক্স প্রোগ্রামের জন্য এটিকে প্রসারিত করতে পারি। যদি আপনার কেবল উড়ে একটি আয়তক্ষেত্র আঁকতে হয়, তাহলে আপনাকে এর মতো একটি বড় শ্রেণী লিখতে হবে না। সি# ডকুমেন্টেশনে এটি কীভাবে করা যায় তার ভাল উদাহরণ রয়েছে।

যাইহোক, আমি আমার "বক্স" ক্লাসের কিছু যুক্তি তুলে ধরব:

পাবলিক ভার্চুয়াল বুল IsCollidedX (বাক্স অন্যঅবজেক্ট) {…}

এখানে আমরা এক্স-দিকের বস্তুর সাথে সংঘর্ষের জন্য পরীক্ষা করি, কারণ প্লেয়ারকে কেবল Y দিকের (উপরে এবং নিচে) সংঘর্ষের জন্য পরীক্ষা করতে হবে যদি সে পর্দায় এটির সাথে সারিবদ্ধ থাকে।

পাবলিক ভার্চুয়াল বুল IsCollidedY (বাক্স অন্যঅবজেক্ট) {…}

যখন আমরা অন্য গেম অবজেক্টের উপরে বা অধীনে থাকি, আমরা Y সংঘর্ষের জন্য পরীক্ষা করি।

পাবলিক ভার্চুয়াল বুল ইসকোলাইড (বাক্স অন্যঅবজেক্ট) {…}

এটি এক্স এবং ওয়াই সংঘর্ষকে একত্রিত করে, এই বস্তুর সাথে কোন বস্তুর সংঘর্ষ হয় কিনা তা ফিরিয়ে দেয়।

পাবলিক ভার্চুয়াল ভয়েড অনপেইন্ট (গ্রাফিক্স গ্রাফিক্স) {…}

উপরের পদ্ধতিটি ব্যবহার করে, আমরা যে কোন গ্রাফিক্স বস্তুকে প্রবেশ করি এবং প্রোগ্রামটি চলার সময় এটি ব্যবহার করি। আমরা যে কোনো আয়তক্ষেত্র তৈরি করি যা আঁকার প্রয়োজন হতে পারে। যদিও এটি বিভিন্ন অ্যানিমেশনের জন্য ব্যবহার করা যেতে পারে। আমাদের উদ্দেশ্যে, আয়তক্ষেত্র প্ল্যাটফর্ম এবং প্লেয়ার উভয়ের জন্যই ভালো করবে।

চরিত্র শ্রেণী

ক্যারেক্টার ক্লাস আমার বক্স ক্লাস প্রসারিত করে, তাই আমাদের বাক্সের বাইরে কিছু পদার্থবিজ্ঞান আছে। আমরা সংঘর্ষের জন্য আমাদের তৈরি করা সকল প্ল্যাটফর্ম দ্রুত চেক করার জন্য "CheckForCollisions" পদ্ধতি তৈরি করেছি। "জাম্প" পদ্ধতিটি প্লেয়ারের wardর্ধ্বমুখী গতিকে জাম্পস্পিড ভেরিয়েবলে সেট করে, যা তারপর মেইন উইন্ডো ক্লাসে ফ্রেম-বাই-ফ্রেম পরিবর্তন করা হয়।

বক্স ক্লাসের তুলনায় এখানে সংঘর্ষ কিছুটা ভিন্নভাবে পরিচালিত হয়। আমি এই গেমটিতে সিদ্ধান্ত নিয়েছি যে যদি উপরের দিকে লাফ দেওয়া হয়, আমরা একটি প্ল্যাটফর্ম দিয়ে লাফ দিতে পারি, কিন্তু এটি আমাদের খেলোয়াড়কে ধাক্কা দিলে নিচে নামবে।

প্ল্যাটফর্ম ক্লাস

এই গেমটিতে, আমি কেবল এই শ্রেণীর কনস্ট্রাক্টর ব্যবহার করি যা একটি ইন-ইনপুট হিসাবে একটি এক্স-কো-অর্ডিনেট নেয়, মেইন উইন্ডো ক্লাসের প্ল্যাটফর্মের X অবস্থানগুলি গণনা করে। প্রতিটি প্ল্যাটফর্ম র্যান্ডম ওয়াই-কোঅর্ডিনেটে 1/2 থেকে পর্দা পর্যন্ত 3/4 পর্দার উচ্চতা পর্যন্ত স্থাপন করা হয়। উচ্চতা, প্রস্থ এবং রঙও এলোমেলোভাবে উত্পন্ন হয়।

মেইন উইন্ডো ক্লাস

গেমটি চলাকালীন আমরা এখানে সমস্ত যুক্তি ব্যবহার করি। প্রথমত, কনস্ট্রাকটরে, আমরা প্রোগ্রামের জন্য উপলব্ধ সমস্ত COM পোর্টগুলি মুদ্রণ করি।

foreach (SerialPort. GetPortNames () এ স্ট্রিং পোর্ট)

Console. WriteLine ("AVAILABLE PORTS:" + port);

আপনার Arduino ইতিমধ্যেই কোন পোর্ট ব্যবহার করছে তা অনুসারে আমরা কোনটি যোগাযোগ গ্রহণ করব তা বেছে নিই:

SerialPort = নতুন SerialPort (SerialPort. GetPortNames () [2], 9600, Parity. None, 8, StopBits. One);

কমান্ডের দিকে মনোযোগ দিন: SerialPort. GetPortNames () [2]। [2] কোন সিরিয়াল পোর্ট ব্যবহার করতে হবে তা নির্দেশ করে। উদাহরণস্বরূপ, যদি প্রোগ্রামটি "COM1, COM2, COM3" প্রিন্ট করে, আমরা COM3 এ শুনব কারণ সংখ্যাটি অ্যারেতে 0 থেকে শুরু হয়।

এছাড়াও কন্সট্রাকটারে, আমরা আধা-এলোমেলো ব্যবধান এবং স্ক্রিনে Y দিকের বসানো সহ সমস্ত প্ল্যাটফর্ম তৈরি করি। সমস্ত প্ল্যাটফর্মগুলি একটি তালিকা বস্তুর সাথে যুক্ত করা হয়, যা C# এ একটি অ্যারের মত ডেটা স্ট্রাকচার পরিচালনার একটি খুব ব্যবহারকারী বান্ধব এবং দক্ষ উপায়। তারপর আমরা প্লেয়ার তৈরি করি, যা আমাদের অক্ষর বস্তু, স্কোর 0 সেট করুন এবং গেমওভারকে মিথ্যাতে সেট করুন।

ব্যক্তিগত স্ট্যাটিক অকার্যকর DataReceived (বস্তু প্রেরক, SerialDataReceivedEventArgs e)

সিরিয়াল পোর্টে যখন ডেটা পাওয়া যায় তখন এই পদ্ধতিটি বলা হয়। এখানেই আমরা আমাদের সমস্ত পদার্থবিজ্ঞান প্রয়োগ করি, সিদ্ধান্ত নিই যে গেমটি প্রদর্শন করা উচিত, প্ল্যাটফর্মগুলি সরানো, ইত্যাদি। রিফ্রেশ এই গেমটিতে, DataReceived পদ্ধতিটি গেম লুপ হিসেবে কাজ করে, শুধুমাত্র পদার্থবিজ্ঞানকে হেরফের করে নিয়ন্ত্রক থেকে তথ্য প্রাপ্ত হওয়ায়। এটি প্রধান উইন্ডোতে টাইমার সেট করা, এবং প্রাপ্ত তথ্যের উপর ভিত্তি করে বস্তু রিফ্রেশ করার জন্য এটি আরও ভাল কাজ করতে পারে, কিন্তু যেহেতু এটি একটি Arduino প্রকল্প, আমি একটি গেম তৈরি করতে চেয়েছিলাম যা আসলে এটি থেকে আসা ডেটার উপর ভিত্তি করে চালানো হয়েছিল ।

উপসংহারে, এই সেটআপটি ব্যবহারযোগ্য কিছুতে গেমটি সম্প্রসারিত করার জন্য একটি ভাল ভিত্তি দেয়। যদিও পদার্থবিজ্ঞান পুরোপুরি নিখুঁত নয়, এটি আমাদের উদ্দেশ্যগুলির জন্য যথেষ্ট ভাল কাজ করে, যা প্রত্যেকের পছন্দের জন্য Arduino ব্যবহার করা হয়: গেম খেলে!

প্রস্তাবিত: