1.5 Spēles laukuma izveide
Stundas uzdevums: Pabeigt Pong laukumu un ieviest abu rakešu vadību, bumbas kustību un atlēkšanu.
80 min plāns: Ievads (~10 min) · laukuma robežas (~20 min) · rakešu vadība (~25 min) · bumbas atlēkšana (~20 min) · saglabāšana (~5 min).
Pirms sāc: vajadzīgas 1.4 scēnas un Paddle.cs ar Speed un ievades nosaukumiem. Šodien laukums kļūs kustīgs: pārbaudīsi raketes un bumbu. Punktu uzskaite un spēles vadība būs 1.6 stundā.
Darba ritms: pēc katra uzdevuma saglabā un pārbaudi rezultātu. Kad projektam pievienots C# skripts, pirms palaišanas nospied Build. Kļūdu gadījumā sāc ar pirmo sarkano kļūdu, nevis nākamo uzdevumu.
Teorija: koordinātes, ātrums un sadursme
1280 × 720 laukumā centrs ir (640,360). X pieaug pa labi, Y — uz leju. Saknes Position novieto objektu laukumā, bet tās bērnu Visual un CollisionShape2D pozīcijas paliek (0,0). Fizikas saknes Scale atstāj (1,1); izmēru maina formā.
Velocity glabā ātrumu pikseļos sekundē. Raketei MoveAndSlide() laiku ņem vērā pats. Bumbai MoveAndCollide(Velocity * (float)delta) nododam viena soļa pārbīdi. Tāpēc delta šajās divās metodēs lieto atšķirīgi.
Ja MoveAndCollide atgriež sadursmi, Velocity.Bounce(collision.GetNormal()) aprēķina atlēkušo ātrumu. Bez sadursmes rezultāts ir null. Fizikas kustība notiek _PhysicsProcess. Godot kustības un atlēkšanas dokumentācija.
| Objekts | Layer ķeksīši | Mask ķeksīši |
|---|---|---|
| WallTop, WallBottom (StaticBody2D) | tikai 1 | neviens |
| PaddleLeft, PaddleRight (CharacterBody2D) | tikai 2 | tikai 1 |
| Ball (CharacterBody2D) | tikai 3 | 1 un 2 |
Tabulā ir Inspector ķeksīšu numuri. .tscn failā 3. slāņa bitu vērtība ir 4. Ball Mask 1 un 2 bitu vērtība ir 3. Raketēm bumbas slāni Mask neieslēdzam: bumba pati nosaka sadursmi ar raketi.
1. uzdevums -
Izveido redzamas laukuma robežas
- Atver Main.tscn. Pārbaudi PaddleLeft (60,360), PaddleRight (1220,360), Ball (640,360). Main sakne paliek (0,0).
- Main pievieno
StaticBody2DbērnuWallTop, Position =(640,10). Tam pievieno CollisionShape2D ar New RectangleShape2D, Size =(1280,20); formas mezgla Position = (0,0). - WallTop pievieno Polygon2D bērnu Visual ar punktiem
(-640,-10), (640,-10), (640,10), (-640,10)un redzamu krāsu. Sienas fizikas forma viena pati spēlē nav redzama. - Dublē visu WallTop par
WallBottom, saknes Position =(640,710). Abām sienām Layer tikai 1, Mask neviena ķeksīša. No dublēšanas kopīgs Shape ir derīgs, kamēr abām vajadzīgs vienāds izmērs. - Pievieno Main bērnu
Line2Dar nosaukumuCenterLine, Points =(640,20)un(640,700), Width = 2, neuzkrītošu krāsu. Tā ir dekorācija un nedrīkst apturēt bumbu. - Pārbaudi visu objektu Layer un Mask pēc tabulas. Palaid F5: redzamas divas sienas, raketes un bumba. Šim fiksētajam laukumam Camera2D nav vajadzīga.
Gatavs, kad: attēls un sadursmes ir vienā vietā, sienas iet gar augšu un apakšu, sānu malas paliek atvērtas punktiem.
2. uzdevums -
Pievieno vadību abām raketēm
- Project → Project Settings → Input Map ar Add izveido visas sešas tabulas darbības; ar + pievieno attiecīgo taustiņu. Pārbaudi mazos burtus un pasvītrojumus.
- Paddle.cs saglabā _Ready un esošos laukus. Klases iekšpusē pievieno
_PhysicsProcessno pilnā faila zemāk. Ja izmanto visu failu, aizstāj esošo saturu, neveido otru Paddle klasi. - Saglabā un Build. Main scēnā PaddleRight Input Up/Down joprojām jābūt p2_up/p2_down, kreisajai — p1_up/p1_down; Speed abām 420.
- Ar F5 pārbaudi W/S un ↑/↓ atsevišķi un vienlaikus. Turot abus viena spēlētāja pretējos virzienus, rakete apstājas. Atlaižot taustiņus, tai arī jāapstājas.
- Turi katru raketi pret augšējo un apakšējo sienu. Tām jāpaliek laukumā: raketes centra Y robežas ir aptuveni 80 un 640 (siena 20 px + raketes pusaugstums 60 px).
| Darbība | Taustiņš |
|---|---|
p1_up | W |
p1_down | S |
p2_up | ↑ |
p2_down | ↓ |
serve | Space — izmantosim 1.6 |
restart | R — izmantosim 1.6 |
1.5 Paddle.cs ar kustību — pilns fails salīdzināšanai
Lejupielādēt Paddle.cs. Aizstāj tikai atbilstošā faila saturu; neveido otru tāda paša nosaukuma klasi.
using Godot;
public partial class Paddle : CharacterBody2D
{
[Export] public float Speed = 420.0f;
[Export] public string InputUp = "p1_up";
[Export] public string InputDown = "p1_down";
public bool IsActive { get; set; } = true;
public override void _Ready()
{
GD.Print($"{Name}: ātrums {Speed}, vadība {InputUp}/{InputDown}, aktīva {IsActive}");
}
public override void _PhysicsProcess(double delta)
{
if (!IsActive)
{
Velocity = Vector2.Zero;
return;
}
float direction = Input.GetAxis(InputUp, InputDown);
Velocity = new Vector2(0, direction * Speed);
MoveAndSlide();
}
}
Gatavs, kad: divi spēlētāji vienlaikus vada savas raketes un neviena neiziet cauri sienām.
3. uzdevums -
Pievieno bumbas kustību un atlēkšanu
- Atver Ball.tscn un tās saknei pievieno
res://Scripts/Ball.cs. Aizstāj saturu ar pilno failu zemāk. Base Speed = 420, Motion Mode = Floating. Saglabā un Build. - Palaid Main ar F5. Ball _Ready sāk bumbas kustību pa labi ar nelielu nejaušu vertikālo komponenti. Normalized saglabā kopējo ātrumu 420 px/s.
- Pārbaudi atlēkšanu no abām raketēm un abām sienām. Redzamā viduslīnija bumbu neaptur. Ja vajag, atkārto F5 vairākas reizes, lai novērotu abus vertikālos virzienus.
- Ļauj bumbai iziet aiz labās vai kreisās malas. Kad tā pilnībā atstāj laukumu, tā apstājas; ExitSide kļūst par 1 vai -1. Šajā stundā turpināšanai apturi un palaid F5 no jauna. Nākamajā stundā šo vērtību nolasīs Game, piešķirs punktu un sagatavos jaunu servi.
- README.md pieraksti, kāpēc bumbai pārbīdi reizina ar delta, bet raketes Velocity pirms MoveAndSlide — ne. Saglabā video ar vadību un atlēkšanu.
1.5 Ball.cs — pilns fails salīdzināšanai
Lejupielādēt Ball.cs. Aizstāj tikai atbilstošā faila saturu; neveido otru tāda paša nosaukuma klasi.
using Godot;
public partial class Ball : CharacterBody2D
{
[Export] public float BaseSpeed = 420.0f;
public bool IsMoving { get; private set; } = false;
// -1: bumba izgājusi pa kreisi; 1: pa labi; 0: nav iziešanas.
public int ExitSide { get; private set; } = 0;
public override void _Ready()
{
ResetBall();
Serve(1); // 1.5 stundā bumba sāk kustēties pati.
}
public void ResetBall()
{
Stop();
Position = new Vector2(640, 360);
ExitSide = 0;
}
public void Serve(int horizontalDirection)
{
float verticalDirection = (float)GD.RandRange(0.25, 0.6);
if (GD.Randf() < 0.5f) verticalDirection = -verticalDirection;
Velocity = new Vector2(horizontalDirection, verticalDirection).Normalized() * BaseSpeed;
IsMoving = true;
}
public void Stop()
{
IsMoving = false;
Velocity = Vector2.Zero;
}
public override void _PhysicsProcess(double delta)
{
if (!IsMoving) return;
KinematicCollision2D collision = MoveAndCollide(Velocity * (float)delta);
if (collision != null)
Velocity = Velocity.Bounce(collision.GetNormal());
if (Position.X < -10)
{
ExitSide = -1;
Stop();
}
else if (Position.X > 1290)
{
ExitSide = 1;
Stop();
}
}
}
Gatavs, kad: abas raketes kustas, bumba atlec un pēc iziešanas apstājas; punktu sistēmai ir skaidri definēts ExitSide.
Papildu uzdevums — izmēģini spēles tempu
Ball instancei pamēģini Base Speed 350 un 500, katru reizi izspēlējot vairākas atlēkšanas. Pieraksti, kuru ātrumu ir vieglāk spēlēt. Pirms nākamās stundas atjauno 420; vēlāk savu izvēli vari pamatot kā dizaina lēmumu.
Ko sagatavo
Stundas mērķis: pirms noslēguma stundas fizika un ievade jau ir pārbaudītas.
GitHub krātuvē jābūt:
Paddle.cs,Ball.cs, atjauninātas scēnas un Input Map.- Video ar abām vadībām un atlēkšanām; README.md delta un sānu iziešanas skaidrojums.
Saglabā projekta iestatījumus, izveidotās scēnas un resursus; no 1.3 stundas arī C# skriptus un projekta failus (.csproj u.c.). .gitignore ieraksti .godot/, bin/ un obj/ katru savā rindā.
Kā iesniedz: veic commit un push. Skolotāja norādītajā vietā iesniedz GitHub krātuves saiti; README.md un pārbaudes pierādījumiem jābūt krātuvē.
Ja kaut kas nestrādā
| Pazīme | Ko pārbaudīt |
|---|---|
| Rakete vai bumba iziet cauri sienai | Pārbaudi CollisionShape2D Shape, izmēru, Layer/Mask un to, vai pozīcija piešķirta saknei tikai vienreiz. |
| Abas raketes vada W/S | Main scēnā PaddleRight ievades laukus maini uz p2_up/p2_down. |
| Rakete ļoti lēna | Velocity pirms MoveAndSlide papildus ar delta nereizina. |
| Bumba pazūd pēc iziešanas | 1.5 posmā tas ir paredzēts: tā gaida punktu apstrādi, ko pievienosi 1.6. Pārbaudi ar jaunu F5 palaišanu. |
| Izmēri vai pozīcijas neatbilst | Pārbaudi 1280 × 720, sakņu Scale (1,1) un bērnu Position (0,0). |