- Samsung Galaxy Watch7 - kötelező kör
- Samsung Galaxy A56 - megbízható középszerűség
- Nokia 8 Sirocco - tudja, honnan fúj a szél
- iGO Primo
- iPhone topik
- Samsung Galaxy S23 Ultra - non plus ultra
- Honor Magic5 Pro - kamerák bűvöletében
- Yettel topik
- Fotók, videók mobillal
- Samsung Galaxy Watch (Tizen és Wear OS) ingyenes számlapok, kupon kódok
Új hozzászólás Aktív témák
-
joysefke
veterán
válasz
Tomi_78 #10149 üzenetére
Köszi, tehát a Count-1. Csak azt furcsállom, hogy olyan különösen viselkedik ezzel, ha másik névtérbe viszem át egy változóban a Count-1 értéket, mint most az elhelyez alprogramba, mert minden tankot elmozdít.
Próbáld meg debuggerrel megnézni, hogy mi a baj.
de az nem olyan egyszerű, ha eltérő a képek mérete.
A programodban felhasznált képeket igazítsd a programod követelményeihez és ne a programodat a képekhez. Szerintem a tankoknak meg minden entitásnak általad előre meghatározott mérete kéne legyen és ehhez a mérethez kéne a tank képét hozzáigazítanod.
Ha esetleg nem ismered, akkor itt tudsz inspirálódni:
Neon shooter:
https://github.com/MonoGame/MonoGame.Samples/tree/3.8.0/NeonShooter
tutorial:
https://code.tutsplus.com/make-a-neon-vector-shooter-in-xna-basic-gameplay--gamedev-9859tPlatformer:
https://github.com/MonoGame/MonoGame.Samples/tree/3.8.0/Platformer2D -
joysefke
veterán
válasz
Tomi_78 #10147 üzenetére
A Count megadja a List<T> aktuális elemszámát. Ha mindig a végéhez adod hozzá az újabb elemet (tehát nem beszúrsz) akkor a Count-1 fogja megadni az utolsónak hozzáadott elem indexét vagy -1-et ha nincsen még benne elem.
Debuggolni próbáltad már a programodat hogy megtaláld a hibát?
Ha a tank leesésére az animáció miatt van szükséged, az érthető. Ha viszont így akarod megkapni az induló Y koordinátáját az számomra fura. A platform elemednek van egy pozíciója az Y tengely mentén, van magassága, a tanknak is van kiterjedése ebből előre ki tudod számítani, hogy mi lesz a tank Y koordinátája.
Mondjuk én tuti úgy oldanám meg a platfom elemeket, hogy azok egy egy mezőt teljesen elfoglaljanak, tehát játék kezdetekor a pályarajz alapján triviális legyen, hogy a mozgó elemeknek mi az Y koordinátájuk.Az ütközésdetektálási kód (nem próbáltam meg értelmezni) nem tűnik bombabiztosnak, illetve nem látom, hogy miért kell neked téglalapok ütközésének detektálásához kódot írnod? A frameworkben amiben dolgozol nincsen Rectangle osztály aminek lenne bool Intersects(Rectangle other) metódusa?
-
joysefke
veterán
válasz
Tomi_78 #10110 üzenetére
A képlet első ránézésre jónak tűnik. Próbálj írni pár tesztesetet amelyek általad előre kiszámolt eseteknek a képlet által visszaadott végeredményét tesztelik az általad elvárttal szemben. Aztán ha valami nem stimmel, akkor addig kalapálod a képletedet amíg végül az összes teszteseted zöld nem lesz.
Legalább minden negyedre ([0°-90°], [90°-180°], stb ) jusson egy teszteset. A -90° a +270°-el egyenértékű a képeden. -90 mod 360 = 270 mod 360. Tehát itt a -90 nem egyenlő +90-nel.
-
joysefke
veterán
válasz
Tomi_78 #10091 üzenetére
Amúgy csupán memóriatakarékossági okból lett volna szükségem a byte típusra, mert az id és idk nem lett volna több a programban, mint 255.
Ezért mondtam, hogy érdemes lenne valami alapozó könyvet olvasgatni. Egyébként addig nincs értelme optimalizálgatni, amíg arra nincs szükség (, illetve amíg nem tudod mit csinálsz).
A programodban biztos lehetsz benne, hogy az hogy a MainForm ban egy fieldnek bool-t használsz int helyett semmi jelentősége nincsen illetve egyetlen byte-ot sem spórolsz, a MainForm byte-re pontosan ugyanakkora lesz.
Ennek az oka, hogy az objektumok fieldjei a memóriában nem feltétlenül teljesen folytonosan helyzkednek el, hanem igazítva vannak.class MyClass
{
byte B;
int Num;
}Ez például jó eséllyel a "Num" 4byteos mérete miatt 4 bytejával lesz igazítva, tehát a B is 4 byteot fog elfoglalni jó eséllyel. (futtatókörnyezet függő). Az 1byte hasznos terület után lesz 3byte foghíj. Sebességben sincsen semmi különbség két byte összeadása illetve két integer összeadása között. (Nem mintha ez bármit számítana)
De ezekkel egyelőre nincs értelme foglalkoznod.
-
joysefke
veterán
válasz
Tomi_78 #10078 üzenetére
Valami alapozó könyvet kellene olvasnod, hogy helyére kerüljenek a dolgok.
A "new" utasítással példányosítottál egy osztályt, az objektum a (heap) memóriában jött létre, a var kulcsszóval deklarált változód a stacken van (a futó metódus scopeján belül) ez a változó egy referencia ami a heapen lévő objektumra mutat. A referencián keresztül tudod elérni és használni a heapen lévő objektumodat.A var -ral deklarált változód típusa már kódszerkesztési időben ismert a fejlesztőkörnyezet számára. Ha a fejlesztőkörnyezet nem tudja a típust eldönteni, akkor be fogja azt a kódrészt pirosítani.
A var csak arra van, hogy neked kényelmesebb legyen, ne kelljen a hosszú típusnevet kiírni, illetve refaktorálásnál is előnyös lehet.var myObject = new MyClass(); esetén a myObject típusa "MyClass típusú referencia";
-
Alexios
veterán
válasz
Tomi_78 #10076 üzenetére
Fordítsuk meg a kérdést és gondold át mit kéne csináljon a program akkor ha olyan ágba kerülsz ahol nem inicializálod majd később hivatkozol rá. Vagy adsz egy default értéket (pl az if/switch blokkok előtt, int valtozo =1; ), vagy minden lehetséges úton inicializálni kell ha később hivatkozol rá.
Az utóbbinál amúgy az a baja hogy ha var-t használsz akkor egyből inicializálni kell, mert a compiler nem tudja hogy mi az. A switchen belül pl az egyik ágban számot, másikban szöveget adnál neki, honnan tudja melyik a helyes? Ez egy erősen típusos nyelv, nem lehet egy változó egyszerre több típus, tehát vagy megmondod az elején hogy milyen típus lesz és később is tudod inicializálni, vagy használod a var kulcsszot és egyből értéket adsz neki hogy tudja milyen típus kell legyen.
-
pmonitor
aktív tag
válasz
Tomi_78 #10073 üzenetére
Csak azért írtam, hogy addig olvasgasd dqdb posztját, mert a posztodból egyértelműen látszik, hogy nem értetted meg.
ezek szerint az első és legfőbb deklarálási helyen már értéket kell adni neki, még ha ez null is,
Ez rossz konzekvencia. Ugyanis abban az esetben, ha minden kódúton inicializálod a változót, akkor nem kell még null-t sem adni a deklarálás helyén. Tehát ez is jó:
int[,] palya;
switch (mostpalya)
{
case 1:
palya = new int[,] {{0,0,0,0,0,0,0,0,0,0},
{0,0,0,0,0,0,0,0,0,0},
{0,0,0,0,0,0,0,0,0,0},
{0,0,0,0,0,0,0,0,0,0},
{0,0,0,0,0,0,0,0,0,0},
{0,0,0,0,0,0,0,0,0,0},
{0,0,0,0,0,0,0,0,0,0},
{0,0,0,0,0,0,0,0,0,0},
{0,0,0,0,0,0,0,0,0,0},
{2,0,0,0,1,0,0,0,0,2},
};
break;
default:
palya = new int[,] {{0,0,0,0,0,0,0,0,0,0},
{0,0,0,0,0,0,0,0,0,0},
{0,0,0,0,0,0,0,0,0,0},
{0,0,0,0,0,0,0,0,0,0},
{0,0,0,0,0,0,0,0,0,0},
{0,0,0,0,0,0,0,0,0,0},
{0,0,0,0,0,0,0,0,0,0},
{0,0,0,0,0,0,0,0,0,0},
{0,0,0,0,0,0,0,0,0,0},
{2,0,0,0,1,0,0,0,0,2},
};
break;
}Itt a default ág miatt mindenképpen inicializálva van annak ellenére, hogy deklaráláskor nem adtam neki null-t.
-
Alexios
veterán
válasz
Tomi_78 #10070 üzenetére
másold be az egész releváns kódrészletet, pusztán hibaüzenetből nehéz látni mi a gond
De ennek így jónak kéne lennie:
int[,] palya;
switch (mostpalya) {
case 1:
palya = new int[,]{{0,0,0,0,0,0,0,0,0,0},
{0,0,0,0,0,0,0,0,0,0},
{0,0,0,0,0,0,0,0,0,0},
{0,0,0,0,0,0,0,0,0,0},
{0,0,0,0,0,0,0,0,0,0},
{0,0,0,0,0,0,0,0,0,0},
{0,0,0,0,0,0,0,0,0,0},
{0,0,0,0,0,0,0,0,0,0},
{0,0,0,0,0,0,0,0,0,0},
{2,0,0,0,1,0,0,0,0,2},
};
break;
}
-
dqdb
nagyúr
válasz
Tomi_78 #10062 üzenetére
Nem kell itt próbálkozni, ott van a
Screen.PrimaryScreen.WorkingArea
, azt kell beállítani az ablak pozíciójának, ha az első képernyőd akarod megjeleníteni, és ekkor a tálca nélküli teljes képernyőméretet kihasználod.A te megoldásod elvi szinten bukik el, mert az, hogy a tálca teteje, az esetek egy részében értelmezhető fogalom csak. A tálcát lehet balra, jobbra és felülre dokkolni, emellett el lehet rejteni automatikusan, több monitornál simán lehet, hogy csak az elsődleges monitoron van tálca, a többin nem, stb.
Screen.PrimaryScreen.WorkingArea.Height-(Screen.PrimaryScreen.WorkingArea.Height-ClientSize.Height)
Egyszerűsítsük kicsit a képletet:Screen.PrimaryScreen.WorkingArea.Height - (Screen.PrimaryScreen.WorkingArea.Height - ClientSize.Height) =
Screen.PrimaryScreen.WorkingArea.Height - Screen.PrimaryScreen.WorkingArea.Height + ClientSize.Height =
ClientSize.Height
Ez csak abban az esetben adja meg a tálca tetejének helyét, ha
1. a Windowsban a tálca alulra van beállítva
2. az ablak maximalizálva van
3. az ablaknál aFormBorderStyle = FormBorderStyle.None
van beállítva és nincsen menü -
dqdb
nagyúr
válasz
Tomi_78 #10060 üzenetére
1. Miért 864 képpont nálam C#-ban a képernyőmagasság 1080 helyett?
Mert Windowsban 125%-ra állítottad a scalinget, az alkalmazásod pedig nem jelzi, hogy high DPI támogatással bír, így a Windows a tényleges helyett a scalinggel korrigált virtuális értéket adja át neked2. Hogyan kaphatom meg csak a hasznos területet a képernyőből, tehát a Tálca és a felső menüsor magassága nélküli értéket?
A felső menüsor, az ablakfejléc és a keret az alkalmazás saját felségterülete, azzal azt kezd, amit akar, azok az ablakméreten belül vannak. A tálca nélküli téglalapot aScreen.WorkingArea
propertyben találod.Egy ablak két része szedhető szét: client area, ami a hasznos felülete (a lenti képen pirossal jelezve) és a non-client area, ahová a körítés (fejléc, menü, keret) kerülnek. A hasznos területet a Control.ClientRectangle propertyvel tudod lekérdezni, ez azt a téglalapot adja vissza, ami az ablakod szabadon használható területe.
Érdemes megjegyezni, hogy több monitor esetében mind a DPI, mind a tálca mérete, mind a rendelkezésre álló terület eltérhet, és az alkalmazásodat monitorok között dobálva ez indítás után bármikor bekövetkezhet, szóval érdemes a változásokról érkező eseményeket lekezelni.
-
-
Alexios
veterán
válasz
Tomi_78 #10047 üzenetére
Jó lesz így már, nyilván kód szervezésre nem feltétlenül ez a legjobb, vagy nevezéktanra, de ha működik akkor működik. A lényeg az hogy valahogy nyilván kell tartanod ha valami konkrétan akarsz végigiterálni, aztán erre vannak különböző módok még, de kezdésnek elég lesz szerintem ez neked.
#10046 fatal` : Hagyd, átment a saját blogjára továbbra is csak a lényegi mondandót kiforgatva olyanokról vitatkozni amit senki nem mondott
-
Tomi_78
aktív tag
válasz
Tomi_78 #10024 üzenetére
Tanácsaitok alapján végül egy List használatával oldottam meg a problémát, mégpedig így:
class JatekElemei
{
public int xhely,yhely;
}
List<JatekElemei> jatelemeilista = new List<JatekElemei>();
class Jatekos: JatekElemei
{
public Bitmap kepe;
public byte animidozito=5,lovesvsz;
};Jatekos a_jatekos;
class JatLovedekei: JatekElemei
{
public Bitmap kepe;
};
List<JatLovedekei> jatlovlista = new List<JatLovedekei>();
class Deneverek: JatekElemei
{
public int dirx,diry;
public Bitmap kepe;
public byte animidozito=5;
}List<Deneverek> deneverlista = new List<Deneverek>();
Aztán minden példányt a létrehozásakor beleteszek ebbe a jatelemeilista listába, pl.:
a_jatekos = new Jatekos();
(...)
jatelemeilista.Add(a_jatekos);S most már mehet rajta a foreach ciklus:
foreach (var jatelem in jatelemeilista) {
jatelem.xhely=...
}
Nekem jónak tűnik így, de ha láttok benne valami hibát, írjátok meg okvetlenül. -
Alexios
veterán
válasz
Tomi_78 #10027 üzenetére
Tehát ha mindennek van egy közös szülőobjektuma
Amúgy c#-ban mindennek van egy közös szülőtípusa, úgy hívják objectAkkor hozzak létre egy Listát is, amelybe belekerülnek az osztályobjektumok, és ennek a Listának a nevét adjam meg a foreach-ben az egyik JatekElemei helyett?
Igen. Foreachel, de igazából, while, for, tökmindegy mivel gyűjteményeken iterálsz végig, nem típuson.
lassanként elvész az egyszerűség, mert ezesetben ugyanúgy gondoskodni kell a Lista kezeléséről, amikor elemeket adok hozzá vagy törlök belőle.
De valakinek csak gondoskodni kell róla nem? Vagy nem teljesen értem az elképzelésed, honnan tudja az alkalmazás hogy min akarsz végigmenni, mi legyen benne vagy nem? Az hogy van egy szülőtípus az nem azt jelenti hogy ő tisztában van minden leszármazott példányáról, ez csak a típus meghatározásban segít neked.
#10026 quailstorm : igen, én is írtam hogy reflectionnel meg lehet csinálni, csak 90%-ban ha felmerül hogy reflectionnel menne, az egy rossz gondolat
Kezdőknél pedig 100%-ban rossz gondolat, kizárt hogy egy kezdőnek bármilyen szempontból _tényleg_ szüksége legyen rá.
-
quailstorm
félisten
válasz
Tomi_78 #10027 üzenetére
Az osztály egy absztrakt fogalom, egy memóriaértelmezési térkép. Abból először példányokat kellene létrehozni hogy legyen mit foreachelni. A foreach nem típusokon tud iterálni hanem típuspéldányok felsorolásán.
Az általad említett könyvben benne van a C# és úgy egyáltalán a programozás elméleti alapjának összefoglalása, de nem a legérthetőbb és néhol pongyola. Inkább menj át a Ruzsinszki könyvön és utána csak a konkrét játékprogramozós részekkel folytasd.
-
quailstorm
félisten
válasz
Tomi_78 #10024 üzenetére
Mi alapján tanulsz? Eddigi kommentjeidből úgy néz ki, hogy nem vagy birtokában stabil tudásnak, nem érted a fogalmakat és eszközöket amiket próbálsz használni, csak másolsz és csavarsz rajta valamit.
Mielőtt nekiállsz egy grafikus játéknak, legalább egy programozás könyvön rágd át magad.#10025 Alexios: amúgy ki lehet gyűjteni reflectionnel egy assemblyben egy adott típus összes implementációját. Pl. arra jó, hogy a tesztpluginunkba így elég egy új osztályt behajítani és a lefordított plugin már ki is teszi az új osztályt a UI-ra mint választható test scenario.
-
Alexios
veterán
válasz
Tomi_78 #10024 üzenetére
Min akarsz végig iterálni?
foreach (JatekElemei jatelem in JatekElemei) {itt a foreach ugye maga a ciklus. Ezek után a zárójelen belül először jön a típusa az adatoknak ami esetedben JatekElemei lenne(amúgy használhatsz var-t is ha nem akarod kiírni, de itt most pont jól látszik) aztán a ciklusváltozónév amit adsz az adott elemnek, majd magát a listát amin végig akarsz iterálni. Viszont te az objektum típusát adtad meg és nem egy listát/tömböt/valamit amin végig lehet menni.
Mivel egy gyűjteményed van az egészben, és az is más típusú, ezért ha tippelnem kéne nem erre akarod használni, viszont kicsit zavaros számomra hogy mit szeretnél akkor.
Ha a kérdésed az hogy az összes JatekElemei típusú objektumodat szeretnéd frissíteni, akkor ezeket valahol trackelned kéne és azon végigiterálni(vagy technikailag reflectionnel is meg lehet valószínűleg csinálni, de ne tedd), de ebben a kódrészletben az se világos igazából hol hozod létre azokat amiket frissíteni szeretnél itt
van egy fő osztály, amelyből minden más osztály származik a programban
Már ez a kiindulási pont is rosszul hangzik amúgy hogy miért akarsz ilyet csinálni, biztos erre van-e szükséged -
joysefke
veterán
válasz
Tomi_78 #9342 üzenetére
programot írnék SharpDevelop környezetben
Ebben az izében? https://en.wikipedia.org/wiki/SharpDevelop#/media/File:SharpDevelop.png
Visual Studio Community ingyen van. -
disy68
aktív tag
válasz
Tomi_78 #9349 üzenetére
"Az OOP lényegét is úgy mondanám el, hogy tagolva vannak benne a dolgok, az események csak azok szükségessége esetén hajtódnak végre, és nem folyamatosan, ciklikusan figyeli a program az összes tennivalót."
Hmm. Az egymondatos definíció mindig nehéz, de azért az események nem igazán tartoznak ide.
OOP alapelvek:
- Absztrakció
- Polimorfizmus
- Öröklődés
- Egységbezárás -
Keem1
veterán
válasz
Tomi_78 #9342 üzenetére
Ahogy látom, nem csak C#, hanem úgy általában objektumorientált programozási alapok is csiszolásra szorulnak. Én nem vagyok tanár, és a topik témája is bőven kimerül a tanításban, de én a következőket javasolnám neked:
- rengeteg jó forrás van (leginkább angol nyelven), mégis egy egyszerű, könnyen tanulható és magyar nyelvű könyvet javasolnék: Sipos Marianna: Programozás élesben - C# (megadja a kezdő löketet, az abszolút alapokat)
- kezdésnek én WinForms helyett console-ban gyakorolnék, alapoznék. Ha ez flottul megy, akkor jöhet az ablakozás. Az ablakozás mindaddig várhat, míg a nyelv alapjait meg nem ismered: keywordök, objektumok, névterek, metódusok, láthatóság, öröklődés, stb.Tényleg csupa jó tanácsként szánom a fentieket, és elnézést, ha tévedtem, rosszul mértem fel, hogy nem csak C#-ban, de úgy alapból OO programozásban is abszolút kezdő vagy.
Amúgy meg a C# szerintem egy szuper nyelv: egyszerű, könnyen kezelhető, de mégis sokoldalú. Főleg a rengeteg forrásanyag, tutorial, 3rd party libraryk miatt. -
Alexios
veterán
válasz
Tomi_78 #9342 üzenetére
Szia,
Nem teljesen értem a kódodat, ezt valahonnan kimásoltad? A problémák amik előjöttek azért vannak, mert olyan változókat használsz amik nincsenek sehol deklarálva.
Pl. az srcRect és units változókat miért adtad meg a DrawImage-ben, ha nincsenek is ilyenjeid?Az egydenever változót használod minden metódusban, pedig a konstruktorban, mint lokális változó hozod létre. Ha egy metóduson belül hozol létre egy változót, akkor az csak azon a metóduson belül fog élni, máshol nem, ezt javíthatod a kódon belül pl. így:
Bitmap deneverkepe1 = new Bitmap("kepei\\kisdenever1bmp.bmp");
Bitmap deneverkepe2 = new Bitmap("kepei\\kisdenever2bmp.bmp");
Deneverek[] egydenever;
majd később már csak ehhez rendelsz értéket:
egydenever = new Deneverek[3];
int svsz;De érdemes lenne első körben a nyelv alapjait is átnézned.
Illetve miért pont SharpDevelop, ami évek óta discontinued állapotban van?
Új hozzászólás Aktív témák
Hirdetés
● ha kódot szúrsz be, használd a PROGRAMKÓD formázási funkciót!
- BestBuy ruhás topik
- VR topik
- AMD K6-III, és minden ami RETRO - Oldschool tuning
- Építő/felújító topik
- Elektromos autók - motorok
- Milyen autót vegyek?
- Számtech boltosok memoárjai, azaz amikor kiborulunk...
- ZIDOO médialejátszók
- Gaming notebook topik
- Samsung Galaxy Watch7 - kötelező kör
- További aktív témák...
- DELL Universal Dock D6000 docking station (452-BCYH) (DisplayLink)
- Bomba ár! Lenovo ThinkPad T490s - i5-8GEN I 16GB I 512SSD I 14" FHD I Cam I W11 I Gari!
- Telefon felvásárlás!! iPhone 14/iPhone 14 Plus/iPhone 14 Pro/iPhone 14 Pro Max
- BESZÁMÍTÁS! AMD FX-8320 8 mag 8 szál processzor garanciával hibátlan működéssel
- 121 - Lenovo Legion Pro 5 (16ARX8) - AMD Ryzen 7 7745HX, RTX 4070 (48 hónap garancia!)
Állásajánlatok
Cég: Promenade Publishing House Kft.
Város: Budapest
Cég: CAMERA-PRO Hungary Kft
Város: Budapest