ملاحظة: كانت معركة الدبابة هذه إعادة كتابة بعد قطعة من الكود المصدر على الإنترنت وغير متصل. لا يوجد شيء صعب للغاية في حد ذاته. تستخدم هذه الحالة الموجهة نحو كائن JS ، والتي يمكن استخدامها كبرنامج تعليمي تمهيدي لـ JS الموجهة نحو كائن.
1. إنشاء كائنات أساسية لتحقيق حركة بسيطة من الدبابات
1.1 كيفية رسم قماش في الخريطة ؟
بالنظر إلى مشكلة توافق المتصفح ، نستخدم DOM لرسم وتحديث كائنات اللعبة. كيف نقوم بتخزين خرائطنا؟ يجب أن نحفظ الخريطة كصفيف ثنائي الأبعاد. لا يوجد صفيف ثنائي الأبعاد في JS ، ولكن يمكن تحقيقه عن طريق تخزين الصفيف في صفيف أحادي البعد.
1.2 تنفيذ الكود
نقوم بتصميم القماش كصفيف ثنائي الأبعاد من 13 * 13. كل عنصر له طول وعرض مقابل في الخريطة. يمكننا أن نعتبر الخريطة بأكملها جدولًا يتكون من خلايا من حجم 40 بكسل * 40 بكسل ، وبالتالي فإن حجم قماشنا بالكامل هو 520 بكسل * 520 بكسل ؛
قبل إدخال الكود ، سأعطيك مخطط علاقة كائن:
1.2.1 إنشاء كائن المستوى الأعلى
رمز HTML:
نسخة الكود كما يلي:
<! doctype html public "-// w3c // dtd html 4.0 transitional // en">
<html>
<head>
<title> حرب الدبابة </title>
<link rel = stylesheet href = "css /main.css" />
<script src = "js/common.js"> </script>
<script src = "js/tankobject.js"> </script>
<script src = "js/mover.js"> </script>
<script src = "js/tank.js"> </script>
<script src = "js/frame.js"> </script>
<script>
window.onload = function () {
// استدعاء كائن تحميل اللعبة
var loader = new gameloader () ؛
loader.begin () ؛
}
</script>
</head>
<body>
<!-حاوية الخريطة->
<div id = "divmap">
</div>
<div id = "debuginfo">
</div>
</body>
</html>
ملف tankoBject.js:
نسخة الكود كما يلي:
// كائن المستوى الأعلى
TankObject = function () {
this.xposition = 0 ؛ // موضع الكائن في x في الخريطة (13*13)
this.yposition = 0 ؛
this.ui = null ؛ // عنصر DOM
}
// تغيير طريقة واجهة المستخدم الثابتة
tankoBject.prototype.updateui = دالة (battlfiled) {}
// تعيين الموضع ، المعلمات هي كما يلي: 1*40 ، 6*40
TankObject.Prototype.setPosition = وظيفة (LeftPosition ، Topposition) {
// جولة في موقع الخريطة Math.round
this.xposition = math.round (LeftPosition / 40) ؛
this.yposition = math.round (topposition / 40) ؛
// اضبط الموقف على النموذج
if (this.ui! = null && this.ui.style! = null) {
this.ui.style.left = leftPosition + "px" ؛
this.ui.style.top = topposition + "px" ؛
}
}
هنا نستخدم إحداثيات X و Y لتمثيل موضع الكائن على الخريطة. في وقت لاحق ، سنضع كل كائن في الخريطة في صفيف ثنائي الأبعاد ، وفي هذا الوقت ، يمكننا الحصول على الكائن المقابل من خلال إحداثيات X و Y.
ثم استخدم اليسار والأعلى في CSS للتحكم في موضع كائننا في النموذج. (كائنات مكتوبة: الدبابات ، الرصاص)
1.2.2 إنشاء كائن عام
نحتاج أيضًا إلى إنشاء كائن عام لكتابة بعض أساليبنا الشائعة الاستخدام.
common.js:
نسخة الكود كما يلي:
// أربعة اتجاهات لحركة الخزان
var enumDirection = {
UP: "0" ،
اليمين: "1" ،
أسفل: "2" ،
اليسار: "3"
} ؛
// كائن الطريقة العامة
var otilityclass = {
// إنشاء عنصر DOM في ParentNode ، حدد المعرف واسم الفئة
Create: Function (type ، id ، className ، ParentNode) {
var j = document.createElement (type) ؛
if (id) {J.id = id} ؛
if (className) {J.ClassName = className} ؛
return parentnode.appendchild (j) ؛
} ، // إزالة العناصر
إزالة: وظيفة (OBJ ، ParentNode) {
parentnode.removechild (OBJ) ؛
} ،
getFunctionName: function (السياق ، engumentcallee) {
لـ (var i في السياق) {
if (context [i] == presumentCallee) {return i} ؛
}
يعود ""؛
} ، // ربط الحدث ، وإرجاع طريقة func ، وهذا هو OBJ تم تمريره
BindFunction: Function (OBJ ، Func) {
وظيفة الإرجاع () {
func.apply (OBJ ، الحجج) ؛
} ؛
}
} ؛
1.2.3 إنشاء كائن متحرك
المحرك
نسخة الكود كما يلي:
// حرك الكائن ، ويرث من الكائن العليا
المحرك = دالة () {
this.direction = enumDirection.up ؛
this.peed = 1 ؛
}
mover.prototype = جديد TankObject () ؛
mover.prototype.move = function () {
إذا (this.lock) {
إرجاع ؛/* إلغاء تنشيط أو لا يزال قيد التقدم ، فإن العملية غير صالحة*/
}
// اضبط صورة الخلفية للخزان وفقًا للاتجاه
this.ui.style.backgroundposition = "0 -" + this.direction * 40 + "px" ؛
// إذا كان الاتجاه لأعلى ولأسفل ، فإن نائب الرئيس هو الأعلى ؛ إذا كان الاتجاه يصل إلى اليسار ، فال Val -1
var vp = ["Top" ، "Left"] [(this.direction == enumDirection.up) || (this.direction == enumDirection.down))؟ 0: 1] ؛
var val = ((this.direction == enumDirection.up) || (this.direction == enumDirection.left))؟ -1: 1 ؛
this.lock = true ؛/* lock*/
// احفظ الكائن الحالي لهذا
var هذا = هذا ؛
// سجل بدء حركة كائن
var startmovep = parseint (this.ui.style [vp]) ؛
var xp = this.xposition ، yp = this.yposition ؛
var submove = setInterval (function () {
// ابدأ في التحرك ، 5 بكسل في كل مرة
this.ui.style [vp] = parseint (this.ui.style [vp]) + 5 * val + "px" ؛
// 40 بكسل لكل خلية
if (math.abs ((parseint (this.ui.style [vp]) - startMovep))> = 40) {
ClearInterval (Submove) ؛
this.lock = false ؛/* فتح ، مما يسمح بالتخطي مرة أخرى*/
// سجل موضع الكائن في الجدول بعد نقله
this.xposition = math.round (this.ui.offsetleft / 40) ؛
this.yposition = math.round (this.ui.offsettop / 40) ؛
}
} ، 80 - this.peed* 10) ؛
}
يرث الكائن المتحرك هنا من كائننا الأعلى ، وهذا يمثل الكائن الذي يدعو طريقة التحرك.
تتحرك وظيفة كائن الحركة وفقًا لاتجاه وسرعة الكائن. في كل مرة تنتقل فيها 5 بكسل ، تحرك ما مجموعه 40 بكسل خلية واحدة. سيتم توسيع الكائن لاحقًا وسيتم إضافة اكتشاف التصادم والوظائف الأخرى.
1.2.4 إنشاء كائن دبابة
ملف tank.js:
نسخة الكود كما يلي:
// يرث كائن الخزان من المحرك
tank = function () {}
tank.prototype = new mover () ؛
// إنشاء خزان لاعب ، ويرث من كائن الخزان
selftank = function () {
this.ui = usilityclass.createe ("div" ، "" ، "itank" ، document.getElementByid ("divmap")) ؛
this.movingState = false ؛
this.peed = 4 ؛
}
selftank.prototype = new tank () ؛
// اضبط موضع الخزان
selftank.prototype.updateui = function () {
this.ui.className = "itank" ؛
// طريقة الكائن العلوي ، اضبط موضع الخزان
this.setPosition (this.xposition * 40 ، this.yposition * 40) ؛
}
الآن تم إنشاء دبابات اللاعب فقط ، وسوف نضيف دبابات العدو إليهم لاحقًا.
1.2.5 إنشاء كائن تحميل اللعبة (جوهر)
نسخة الكود كما يلي:
// تقوم اللعبة بتحميل كائن الكائن الأساسي للعبة بأكمله
gameloader = function () {
this.mapContainer = document.getElementById ("divmap") ؛ // div التي تخزن خريطة اللعبة
this._selftank = null ؛ // لاعب الخزان
this._gamelistener = null ؛ // معرف مؤقت الحلقة الرئيسي للعبة
}
gameloader.prototype = {
ابدأ: وظيفة () {
// تهيئة خزان اللاعب
var selft = جديد selftank () ؛
selft.xposition = 4 ؛
selft.yposition = 12 ؛
selft.updateui () ؛
this._selftank = selft ؛
// إضافة حدث رئيسي
var warpper = usilyclass.bindfunction (هذا ، this.onkeydown) ؛
window.onkeydown = document.body.onkeydown = warpper ؛
warpper = usilyclass.bindfunction (هذا ، this.onkeyup) ؛
window.onkeyup = document.body.onkeyup = warpper ؛
// الحلقة الرئيسية للعبة
warpper = usilityclass.bindfunction (هذا ، this.run) ؛
/*مفتاح التحكم في مراقبة التوقيت الطويل*/
this._gamelistener = setInterval (Warpper ، 20) ؛
}
// اضغط على خزان المشغل على لوحة المفاتيح لبدء التحرك
، OnKeydown: وظيفة (هـ) {
التبديل ((window.event || e) .KeyCode) {
الحالة 37:
this._selftank.direction = enumDirection.left ؛
this._selftank.movingState = true ؛
استراحة؛ //غادر
الحالة 38:
this._selftank.direction = enumDirection.up ؛
this._selftank.movingState = true ؛
استراحة؛ //على
الحالة 39:
this._selftank.direction = enumDirection.Right ؛
this._selftank.movingState = true ؛
استراحة؛ //يمين
الحالة 40:
this._selftank.direction = enumDirection.down ؛
this._selftank.movingState = true ؛
استراحة؛ //التالي
}
}
// تظهر الأزرار وتتوقف عن الحركة
، onkeyup: وظيفة (e) {
التبديل ((window.event || e) .KeyCode) {
الحالة 37:
الحالة 38:
الحالة 39:
الحالة 40:
this._selftank.movingState = false ؛
استراحة؛
}
}
/*وظيفة تشغيل الحلقة الرئيسية للعبة ، قلب اللعبة ، المحور*/
، Run: function () {
if (this._selftank.movingstate) {
this._selftank.move () ؛
}
}
} ؛
يبدو رمز كائن تحميل اللعبة كثيرًا ، ولكن في الواقع ، لا يفعل سوى شيئين:
1. إنشاء كائن دبابة لاعب.
2. إضافة حدث مراقبة مفتاح. عندما يضغط اللاعب على مفتاح الهاتف المحمول ، اتصل بطريقة نقل الخزان لنقل الخزان.
ملخص: في هذه المرحلة ، يمكن أن تتحرك خزاننا بحرية عن طريق الضغط على الأزرار. الخطوة التالية نحتاج إلى تحسين الخريطة والكشف عن التصادم.