You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
Web-Dev-For-Beginners/translations/sw/6-space-game/3-moving-elements-around/README.md

402 lines
14 KiB

<!--
CO_OP_TRANSLATOR_METADATA:
{
"original_hash": "23f088add24f0f1fa51014a9e27ea280",
"translation_date": "2025-08-28T03:52:30+00:00",
"source_file": "6-space-game/3-moving-elements-around/README.md",
"language_code": "sw"
}
-->
# Jenga Mchezo wa Anga Sehemu ya 3: Kuongeza Mwendo
## Jaribio la Kabla ya Somo
[Jaribio la kabla ya somo](https://ff-quizzes.netlify.app/web/quiz/33)
Michezo haiwi ya kufurahisha sana hadi pale unapokuwa na viumbe wa kigeni wakizunguka kwenye skrini! Katika mchezo huu, tutatumia aina mbili za mwendo:
- **Mwendo wa Kibodi/Panya**: pale mtumiaji anaposhirikiana na kibodi au panya ili kusogeza kitu kwenye skrini.
- **Mwendo unaosababishwa na mchezo**: pale mchezo unapohamisha kitu kwa muda maalum.
Kwa hiyo, tunahamishaje vitu kwenye skrini? Yote inahusu kuratibu kwa kutumia mfumo wa Cartesian: tunabadilisha eneo (x, y) la kitu na kisha kuchora tena skrini.
Kwa kawaida, unahitaji hatua zifuatazo ili kufanikisha *mwendo* kwenye skrini:
1. **Weka eneo jipya** la kitu; hii inahitajika ili kuonekana kama kitu kimesogea.
2. **Futa skrini**, skrini inahitaji kufutwa kati ya michoro. Tunaweza kuifuta kwa kuchora mstatili na kuujaza kwa rangi ya mandharinyuma.
3. **Chora tena kitu** kwenye eneo jipya. Kwa kufanya hivi, tunafanikisha kusogeza kitu kutoka eneo moja hadi jingine.
Hivi ndivyo inavyoweza kuonekana kwenye msimbo:
```javascript
//set the hero's location
hero.x += 5;
// clear the rectangle that hosts the hero
ctx.clearRect(0, 0, canvas.width, canvas.height);
// redraw the game background and hero
ctx.fillRect(0, 0, canvas.width, canvas.height)
ctx.fillStyle = "black";
ctx.drawImage(heroImg, hero.x, hero.y);
```
✅ Je, unaweza kufikiria sababu kwa nini kuchora tena shujaa wako mara nyingi kwa sekunde kunaweza kusababisha gharama za utendaji? Soma kuhusu [mbadala wa muundo huu](https://developer.mozilla.org/en-US/docs/Web/API/Canvas_API/Tutorial/Optimizing_canvas).
## Kushughulikia Matukio ya Kibodi
Unashughulikia matukio kwa kuambatanisha matukio maalum na msimbo. Matukio ya kibodi huchochewa kwenye dirisha lote wakati matukio ya panya kama `click` yanaweza kuunganishwa na kubofya kipengele maalum. Tutatumia matukio ya kibodi katika mradi huu wote.
Ili kushughulikia tukio, unahitaji kutumia njia ya `addEventListener()` ya dirisha na kuipatia vigezo viwili vya pembejeo. Kigezo cha kwanza ni jina la tukio, kwa mfano `keyup`. Kigezo cha pili ni kazi ambayo inapaswa kuitwa kama matokeo ya tukio kutokea.
Hapa kuna mfano:
```javascript
window.addEventListener('keyup', (evt) => {
// `evt.key` = string representation of the key
if (evt.key === 'ArrowUp') {
// do something
}
})
```
Kwa matukio ya funguo, kuna mali mbili kwenye tukio unazoweza kutumia kuona ni funguo gani ilibonyezwa:
- `key`, hii ni uwakilishi wa kamba wa funguo iliyobonyezwa, kwa mfano `ArrowUp`
- `keyCode`, hii ni uwakilishi wa nambari, kwa mfano `37`, inahusiana na `ArrowLeft`.
✅ Udhibiti wa matukio ya funguo ni muhimu hata nje ya maendeleo ya michezo. Je, unaweza kufikiria matumizi mengine ya mbinu hii?
### Funguo Maalum: Tahadhari
Kuna funguo zingine *maalum* ambazo huathiri dirisha. Hii inamaanisha kuwa ikiwa unasikiliza tukio la `keyup` na unatumia funguo hizi maalum kusogeza shujaa wako, pia itasababisha kurasa kusogea kwa usawa. Kwa sababu hiyo, unaweza kutaka *kuzima* tabia hii ya kawaida ya kivinjari unapojenga mchezo wako. Unahitaji msimbo kama huu:
```javascript
let onKeyDown = function (e) {
console.log(e.keyCode);
switch (e.keyCode) {
case 37:
case 39:
case 38:
case 40: // Arrow keys
case 32:
e.preventDefault();
break; // Space
default:
break; // do not block other keys
}
};
window.addEventListener('keydown', onKeyDown);
```
Msimbo hapo juu utahakikisha kuwa funguo za mishale na funguo ya nafasi zimezimwa tabia yao ya *kawaida*. Utaratibu wa *kuzima* hutokea tunapopiga `e.preventDefault()`.
## Mwendo Unaosababishwa na Mchezo
Tunaweza kufanya vitu visogee vyenyewe kwa kutumia vipima muda kama vile kazi ya `setTimeout()` au `setInterval()` ambayo inasasisha eneo la kitu kwa kila muda maalum. Hivi ndivyo inavyoweza kuonekana:
```javascript
let id = setInterval(() => {
//move the enemy on the y axis
enemy.y += 10;
})
```
## Mzunguko wa Mchezo
Mzunguko wa mchezo ni dhana ambayo kimsingi ni kazi inayochochewa kwa vipindi vya kawaida. Unaitwa mzunguko wa mchezo kwa sababu kila kitu kinachopaswa kuonekana kwa mtumiaji kinachorwa ndani ya mzunguko. Mzunguko wa mchezo hutumia vitu vyote vya mchezo ambavyo ni sehemu ya mchezo, kuchora vyote isipokuwa kwa sababu fulani havipaswi kuwa sehemu ya mchezo tena. Kwa mfano, ikiwa kitu ni adui aliyepigwa na miale ya laser na kulipuka, hakipo tena katika mzunguko wa sasa wa mchezo (utajifunza zaidi kuhusu hili katika masomo yanayofuata).
Hivi ndivyo mzunguko wa mchezo unavyoweza kuonekana, ukiwakilishwa kwa msimbo:
```javascript
let gameLoopId = setInterval(() =>
function gameLoop() {
ctx.clearRect(0, 0, canvas.width, canvas.height);
ctx.fillStyle = "black";
ctx.fillRect(0, 0, canvas.width, canvas.height);
drawHero();
drawEnemies();
drawStaticObjects();
}, 200);
```
Mzunguko hapo juu unachochewa kila baada ya milisekunde `200` ili kuchora tena canvas. Una uwezo wa kuchagua muda bora unaofaa kwa mchezo wako.
## Kuendelea na Mchezo wa Anga
Utachukua msimbo uliopo na kuupanua. Ama anza na msimbo uliokamilisha wakati wa sehemu ya I au tumia msimbo katika [Sehemu ya II - mwanzo](../../../../6-space-game/3-moving-elements-around/your-work).
- **Kusogeza shujaa**: utaongeza msimbo kuhakikisha unaweza kusogeza shujaa kwa kutumia funguo za mishale.
- **Kusogeza maadui**: pia utahitaji kuongeza msimbo kuhakikisha maadui wanasogea kutoka juu kwenda chini kwa kasi fulani.
## Hatua Zinazopendekezwa
Tafuta faili ambazo zimeundwa kwa ajili yako kwenye folda ndogo ya `your-work`. Inapaswa kuwa na yafuatayo:
```bash
-| assets
-| enemyShip.png
-| player.png
-| index.html
-| app.js
-| package.json
```
Anzisha mradi wako kwenye folda ya `your_work` kwa kuandika:
```bash
cd your-work
npm start
```
Hii itaanzisha Seva ya HTTP kwenye anwani `http://localhost:5000`. Fungua kivinjari na uweke anwani hiyo, kwa sasa inapaswa kuonyesha shujaa na maadui wote; hakuna kinachosogea - bado!
### Ongeza Msimbo
1. **Ongeza vitu maalum** kwa `hero`, `enemy`, na `game object`, vinapaswa kuwa na mali za `x` na `y`. (Kumbuka sehemu kuhusu [Urithi au muundo](../README.md)).
*KIDOKEZO* `game object` inapaswa kuwa na `x` na `y` na uwezo wa kujichora kwenye canvas.
>kidokezo: anza kwa kuongeza darasa jipya la GameObject na mjengo wake kama ifuatavyo, kisha ichore kwenye canvas:
```javascript
class GameObject {
constructor(x, y) {
this.x = x;
this.y = y;
this.dead = false;
this.type = "";
this.width = 0;
this.height = 0;
this.img = undefined;
}
draw(ctx) {
ctx.drawImage(this.img, this.x, this.y, this.width, this.height);
}
}
```
Sasa, panua GameObject ili kuunda Hero na Enemy.
```javascript
class Hero extends GameObject {
constructor(x, y) {
...it needs an x, y, type, and speed
}
}
```
```javascript
class Enemy extends GameObject {
constructor(x, y) {
super(x, y);
(this.width = 98), (this.height = 50);
this.type = "Enemy";
let id = setInterval(() => {
if (this.y < canvas.height - this.height) {
this.y += 5;
} else {
console.log('Stopped at', this.y)
clearInterval(id);
}
}, 300)
}
}
```
2. **Ongeza vishughulikia matukio ya funguo** kushughulikia urambazaji wa funguo (sogeza shujaa juu/chini kushoto/kulia).
*KUMBUKA* ni mfumo wa Cartesian, kona ya juu-kushoto ni `0,0`. Pia kumbuka kuongeza msimbo wa kusimamisha *tabia ya kawaida*.
>kidokezo: unda kazi yako ya onKeyDown na uambatanishe kwenye dirisha:
```javascript
let onKeyDown = function (e) {
console.log(e.keyCode);
...add the code from the lesson above to stop default behavior
}
};
window.addEventListener("keydown", onKeyDown);
```
Angalia koni ya kivinjari chako kwa wakati huu, na uangalie funguo zinazobonyezwa zikiripotiwa.
3. **Tekeleza** [Mfumo wa Pub sub](../README.md), hii itahakikisha msimbo wako unasalia safi unapofuata sehemu zinazobaki.
Ili kufanya sehemu hii ya mwisho, unaweza:
1. **Ongeza msikilizaji wa tukio** kwenye dirisha:
```javascript
window.addEventListener("keyup", (evt) => {
if (evt.key === "ArrowUp") {
eventEmitter.emit(Messages.KEY_EVENT_UP);
} else if (evt.key === "ArrowDown") {
eventEmitter.emit(Messages.KEY_EVENT_DOWN);
} else if (evt.key === "ArrowLeft") {
eventEmitter.emit(Messages.KEY_EVENT_LEFT);
} else if (evt.key === "ArrowRight") {
eventEmitter.emit(Messages.KEY_EVENT_RIGHT);
}
});
```
1. **Unda darasa la EventEmitter** kuchapisha na kujiandikisha kwa ujumbe:
```javascript
class EventEmitter {
constructor() {
this.listeners = {};
}
on(message, listener) {
if (!this.listeners[message]) {
this.listeners[message] = [];
}
this.listeners[message].push(listener);
}
emit(message, payload = null) {
if (this.listeners[message]) {
this.listeners[message].forEach((l) => l(message, payload));
}
}
}
```
1. **Ongeza vigezo vya kudumu** na usanidi EventEmitter:
```javascript
const Messages = {
KEY_EVENT_UP: "KEY_EVENT_UP",
KEY_EVENT_DOWN: "KEY_EVENT_DOWN",
KEY_EVENT_LEFT: "KEY_EVENT_LEFT",
KEY_EVENT_RIGHT: "KEY_EVENT_RIGHT",
};
let heroImg,
enemyImg,
laserImg,
canvas, ctx,
gameObjects = [],
hero,
eventEmitter = new EventEmitter();
```
1. **Anzisha mchezo**
```javascript
function initGame() {
gameObjects = [];
createEnemies();
createHero();
eventEmitter.on(Messages.KEY_EVENT_UP, () => {
hero.y -=5 ;
})
eventEmitter.on(Messages.KEY_EVENT_DOWN, () => {
hero.y += 5;
});
eventEmitter.on(Messages.KEY_EVENT_LEFT, () => {
hero.x -= 5;
});
eventEmitter.on(Messages.KEY_EVENT_RIGHT, () => {
hero.x += 5;
});
}
```
1. **Sanidi mzunguko wa mchezo**
Rekebisha kazi ya window.onload ili kuanzisha mchezo na kusanidi mzunguko wa mchezo kwa muda mzuri. Pia utaongeza miale ya laser:
```javascript
window.onload = async () => {
canvas = document.getElementById("canvas");
ctx = canvas.getContext("2d");
heroImg = await loadTexture("assets/player.png");
enemyImg = await loadTexture("assets/enemyShip.png");
laserImg = await loadTexture("assets/laserRed.png");
initGame();
let gameLoopId = setInterval(() => {
ctx.clearRect(0, 0, canvas.width, canvas.height);
ctx.fillStyle = "black";
ctx.fillRect(0, 0, canvas.width, canvas.height);
drawGameObjects(ctx);
}, 100)
};
```
5. **Ongeza msimbo** wa kusogeza maadui kwa muda fulani
Rekebisha kazi ya `createEnemies()` ili kuunda maadui na kuwasukuma kwenye darasa jipya la gameObjects:
```javascript
function createEnemies() {
const MONSTER_TOTAL = 5;
const MONSTER_WIDTH = MONSTER_TOTAL * 98;
const START_X = (canvas.width - MONSTER_WIDTH) / 2;
const STOP_X = START_X + MONSTER_WIDTH;
for (let x = START_X; x < STOP_X; x += 98) {
for (let y = 0; y < 50 * 5; y += 50) {
const enemy = new Enemy(x, y);
enemy.img = enemyImg;
gameObjects.push(enemy);
}
}
}
```
na ongeza kazi ya `createHero()` kufanya mchakato sawa kwa shujaa.
```javascript
function createHero() {
hero = new Hero(
canvas.width / 2 - 45,
canvas.height - canvas.height / 4
);
hero.img = heroImg;
gameObjects.push(hero);
}
```
na hatimaye, ongeza kazi ya `drawGameObjects()` ili kuanza kuchora:
```javascript
function drawGameObjects(ctx) {
gameObjects.forEach(go => go.draw(ctx));
}
```
Maadui wako wanapaswa kuanza kusonga kuelekea kwenye chombo cha anga cha shujaa wako!
---
## 🚀 Changamoto
Kama unavyoona, msimbo wako unaweza kuwa 'msimbo wa tambi' unapoongeza kazi, vigezo, na madarasa. Unawezaje kupanga msimbo wako vizuri zaidi ili uwe rahisi kusoma? Chora mfumo wa kupanga msimbo wako, hata kama bado unakaa kwenye faili moja.
## Jaribio la Baada ya Somo
[Jaribio la baada ya somo](https://ff-quizzes.netlify.app/web/quiz/34)
## Mapitio na Kujisomea
Ingawa tunaandika mchezo wetu bila kutumia mifumo, kuna mifumo mingi ya JavaScript inayotegemea canvas kwa ajili ya maendeleo ya michezo. Chukua muda kufanya [usomaji kuhusu hizi](https://github.com/collections/javascript-game-engines).
## Kazi
[Toa maoni kwenye msimbo wako](assignment.md)
---
**Kanusho**:
Hati hii imetafsiriwa kwa kutumia huduma ya kutafsiri ya AI [Co-op Translator](https://github.com/Azure/co-op-translator). Ingawa tunajitahidi kuhakikisha usahihi, tafadhali fahamu kuwa tafsiri za kiotomatiki zinaweza kuwa na makosa au kutokuwa sahihi. Hati ya asili katika lugha yake ya awali inapaswa kuzingatiwa kama chanzo cha mamlaka. Kwa taarifa muhimu, tafsiri ya kitaalamu ya binadamu inapendekezwa. Hatutawajibika kwa kutoelewana au tafsiri zisizo sahihi zinazotokana na matumizi ya tafsiri hii.