- Apple Watch Sport - ez is csak egy okosóra
- Itt a Galaxy S26 széria: az Ultra fejlődött, a másik kettő alig
- Garmin Venu 4 - a nagy ugrás
- iPhone topik
- Apple iPhone 16 - ígéretek földje
- Samsung Galaxy Watch6 Classic - tekerd!
- Sokkal jobb ajánlat lett elődjénél az iPhone 17e
- Nothing Phone 2a - semmi nem drága
- Samsung Galaxy S23 Ultra - non plus ultra
- Google Pixel topik
Új hozzászólás Aktív témák
-
#39560925
törölt tag
Érdekes problémába ütköztem, nem tudom mi lehet a gond. Van az űrhajós játékomban 5 féle ellenség. Mindegyik más-más frekvenciával és amplitúdóval cikázik jobbra-balra. Legalábbis kellene nekik, de tök érthetetlenül mozognak.
x és y int változók tárolják a pillanatnyi helyüket, de oly módon, hogy elvileg csak 0 és 100 közötti értéket vehetnek fel, mert ez alapján relatívan számolom ki a pozíciójukat az ablak méretétől függően.
A GameArea (ami a JPanel leszármazottja) osztály drawEnemies() metódusa iterál végig az ellenséges hajókat tároló listán, és rajzolja ki őket.
public void drawEnemies (Graphics g) {
Iterator<Enemy> it = EnemyList.iterator();
while (it.hasNext()) {
Enemy enemy = (Enemy) it.next();
if (enemy.getHealth() > 0)
g.drawImage (enemy.getImage(), (int) (this.getWidth()*enemy.getX()/100), (int) (this.getHeight()*enemy.getY()/100), (int) (this.getWidth()*0.05), (int) (this.getHeight()*0.05), this);
else
DestroyEnemy (enemy);
}
}Amikor csak 1-1 hajót rajzolgattam ki, akkor ez rendben is működött, mindig ott volt a kép kirajzolva ahova terveztem, úgyhogy ezzel elvileg nincsen gond.
Mind az összes "Enemy"-nek van egy saját Move() metódusa, amit ha 20 milliszekundumonként hívnak meg, akkor ennek elvileg az általam tervezett módon kéne az űrhajó koordinátáit módosítania. Például itt van az Enemy0 Move() methodja:
// this method has to be called in every 20 milliseconds
public void Move () {
// in even seconds this enemy will go right
long time = System.currentTimeMillis();
if ((((time % 10000) - (time % 1000)) / 1000) % 2 == 0) {
x = (int) (x + GA.getWidth()*0.003);
y = (int) (y + GA.getHeight()*0.001);
}
// else it will go left
else {
x = (int) (x - GA.getWidth()*0.003);
y = (int) (y + GA.getHeight()*0.001);
}
}Ennek elvileg a páros másodpercekben jobbra, a páratlanokban balra kéne mennie, és egy másodperc alatt oldalirányban az ablak szélességének 15%-át megtennie.
Pl. legyen az ablak 540*540-es felbontású. Ekkor az 1 másodperc alatti horizontális irányú elmozdulás pixelben kifejezve 540*0.003*1000/20 = 81, és 81/540 = 0,15, tehát az ablak szélességének 15%-a.
1000/20-szal való szorzás úgy jött, hogy mint ahogy azt már említettem, 20ms-onként kell meghívódnia. Ami meg is történik itt:
public void run() {
while (true) {
repaint();
animator.animationCycle();
try {
Thread.sleep(20);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}Az animator ismeri a tárolót amiben az Enemy-k vannak, és végigiterálva rajtuk, meghívja mindnek a Move() metódusát az animationCycle() metóduson belül. Ezt megteszi minden 20ms-os alvás között.
Mégis a következő képpen mozognak az ellenséges hajók:

Az A-val jelölt hajók egy pillanat alatt lejönnek fentről, és kimennek a pályáról, a B-vel jelöltek meg abban a magasságban cikáznak jobbra balra, de jóval nagyobb amplitúdóval és sebességgel, mint amire számítottam a kód alapján. Ezt a képet csak úgy tudtam megcsinálni, hogy 900-ra állítottam a Thread.sleep()-et a run metódusban. Egyébként túl gyorsan cikáznának, főleg az A-val jelöltek, mert azok egyből el is repülnek.
Ha 20ms-os alvással futtatom, akkor a B csoport hajói egy másodpercenként visszajönnek a látható pályára, egyszer jobb-, egyszer baloldalról érkezve, ugyanis akkora az amplitúdójuk, hogy idejük nagyját a pályán kívül töltik.
Van valakinek ötlete, hogy kéne ezt debuggolni?

Bemásolom még az ötféle Enemy Move() metódusát:
Elsőé:
// this method has to be called in every 20 milliseconds
public void Move () {
// in even seconds this enemy will go right
long time = System.currentTimeMillis();
if ((((time % 10000) - (time % 1000)) / 1000) % 2 == 0) {
x = (int) (x + GA.getWidth()*0.003);
y = (int) (y + GA.getWidth()*0.001);
}
// else it will go left
else {
x = (int) (x - GA.getWidth()*0.003);
y = (int) (y + GA.getWidth()*0.001);
}
}Másodiké:
// this method has to be called in every 20 milliseconds
public void Move () {
// in uneven seconds this enemy will go right
long time = System.currentTimeMillis();
if ((((time % 10000) - (time % 1000)) / 1000) % 2 == 1) {
x = (int) (x + GA.getWidth()*0.0045);
y = (int) (y + GA.getWidth()*0.002);
}
// else it will go left
else {
x = (int) (x - GA.getWidth()*0.0045);
y = (int) (y + GA.getWidth()*0.002);
}
}Harmadiké:
public void Move () {
// in even seconds this enemy will go right
long time = System.currentTimeMillis();
if ((((time % 10000) - (time % 1000)) / 1000) % 2 == 0) {
x = (int) (x + GA.getWidth()*0.01);
y = (int) (y + GA.getWidth()*0.0015);
}
// else it will go left
else {
x = (int) (x - GA.getWidth()*0.01);
y = (int) (y + GA.getWidth()*0.0015);
}
}Negyediké:
public void Move () {
// in even seconds this enemy will go right
long time = System.currentTimeMillis();
if ((((time % 10000) - (time % 1000)) / 1000) % 2 == 0) {
x = (int) (x + GA.getWidth()*0.012);
y = (int) (y + GA.getWidth()*0.002);
}
// else it will go left
else {
x = (int) (x - GA.getWidth()*0.012);
y = (int) (y + GA.getWidth()*0.002);
}
}Ötödiké:
public void Move () {
// in even seconds this enemy will go right
long time = System.currentTimeMillis();
if ((((time % 10000) - (time % 1000)) / 1000) % 2 == 0) {
x = (int) (x + GA.getWidth()*0.012);
y = (int) (y + GA.getWidth()*0.002);
}
// else it will go left
else {
x = (int) (x - GA.getWidth()*0.012);
y = (int) (y + GA.getWidth()*0.002);
}
}B csoportba az van első és a harmadik Enemy, A csoportban a többi 3.
Új hozzászólás Aktív témák
A topicot kiemeltem. Valaki nem akar egy nyitó hsz-t írni?:))
- Formula-1
- Apple Watch Sport - ez is csak egy okosóra
- Itt a Galaxy S26 széria: az Ultra fejlődött, a másik kettő alig
- TCL LCD és LED TV-k
- Milyen billentyűzetet vegyek?
- Genshin Impact (PC, PS4, Android, iOS)
- Garmin Venu 4 - a nagy ugrás
- Intel Core i5 / i7 / i9 "Alder Lake-Raptor Lake/Refresh" (LGA1700)
- iPhone topik
- sziku69: Fűzzük össze a szavakat :)
- További aktív témák...
- Samsung LH55CSPLBC 55" LCD monitor
- Gamer PC-Számítógép! Csere-Beszámítás! I7 7700K / GTX 1080 8GB / 16GB DDR4 / 500GB SSD
- Apple iPhone 12 Pro / 128GB / Kártyafüggetlen / 12Hó Garancia
- 255 - Lenovo LOQ (15IRX10) - Intel Core i7-13700HX, RTX 5060
- Újszerű Dell XPS 13 9310 - 13.4" FHD+ i7-1185G7 - 16GB - 1TB - Win11 PRO
Állásajánlatok
Cég: Laptopműhely Bt.
Város: Budapest



