| Autor |
Beitrag |
lk1990
Hält's aus hier
Beiträge: 9
|
Verfasst: Sa 08.03.14 15:34
Hi
Ich habe letztens angefangen ein rundenbasiertes 2D Seekriegsspiel in C# zu programmieren. Die grafische Ausgabe soll über übereinandergelegte Pictureboxen mit teilweise transparenten Inhalten in Form von -png Bildern erfolgen. Bisher habe ich folgendes unter Benutzung dieses Lösungsansatzes implementiert:
Es gibt einen Hintergrund als PictureBox.
Über diesem Hintergrund liegt eine PictureBox, die die Grafik des Spielerschiffs (semi-transparente .png Grafik) enthält, wobei nach Beendigung eines jeden Spielzuges die Position dieser PictureBox bezogen auf die Position des Schiffs am Ende des vorhergehenden Spielzuges geändert wird:
C#-Quelltext 1: 2: 3: 4:
| pictureBoxPlayerShip1.BackColor = Color.Transparent; pictureBoxPlayerShip1.Parent = pictureBoxBackground;
pictureBoxPlayerShip1.Location = new Point(Convert.ToInt32(NewStorage.RestorePlayerPosXNm()), Convert.ToInt32(NewStorage.RestorePlayerPosYNm())); |
Zusätzlich zu der Grafik für das Spielerschiff habe ich auch bereits eine Grafik für die Darstellung eines Granateinschlages auf der Wasseroberfläche mit oben beschriebener Methode zu implementieren versucht:
C#-Quelltext 1: 2: 3: 4: 5: 6: 7: 8:
| pictureBoxSplash.BackColor = Color.Transparent; pictureBoxSplash.Parent = pictureBoxBackground; pictureBoxSplash.Visible = false;
pictureBoxSplash.Visible = true; pictureBoxSplash.Location = new Point(Convert.ToInt32(NewStorage.RestoreImpactPointXNm()), Convert.ToInt32(NewStorage.RestoreImpactPointYNm())); |
Die beiden bisher eingebauten PictureBoxen werden zum Zeitpunkt des 0-ten Spielzuges mit bestimmten Initialwerten dargestellt.
Der 0-te Spielzug wird als vollständiger Spielzug behandelt, nur dass eben statt irgendwelcher Berechnungsverfahren zur Ermittlung der Positionen der Grafiken einfach vordefinierte Initialwerte verwendet werden.
Mein Problem sieht jetzt wie folgt aus:
Bei allen Spiezügen, die auf den 0-ten folgen, wird die pictureBoxSplash Grafik nicht mehr am Bildschirm angezeigt, während des 0-ten Spielzuges jedoch schon (auch an der Position der vordefinierten Initialwerte, vorausgesetzt der Initialwert von PictureBoxSlpash.Visible wurde zwecks Debugging standardmäßig auf true gesetzt). Woran kann das liegen? Die Umpositionierung meiner PictureBoxPlayerShip1 funktioniert einwandfrei. Ich habe bereits folgende Fehlerquellen untersucht und definitiv ausgeschlossen:
Die Werte, die pictureBoxSplash.Location = new Point(); übergeben werden, liegen ausserhalb des darstellenbaren Bereichs.
Die PictureBoxPlayerShip1 sorgt für Probleme der Darstellung der PictureBoxSplash (ausgeschlossen durch vollständiges entfernen der PictureBoxPlayerShip1 aus dem Code - das Problem mit der PictureBoxSplash tritt trotzdem auf).
Die PictureBoxSplash.Location existiert nur lokal zwischen zwei geschwungenen Klammern eines If{} Statements - Der Bug tritt unabhängig von der Position der PictureBoxSplash im Code auf, vorausgesetzt der Code ist so weit korrekt geschrieben, dass er vom Compiler aktzeptiert wird.
Kann mir vielleicht irgendhemand einen Tipp geben?
Vielen Dank im voraus!
|
|
Th69
      

Beiträge: 4805
Erhaltene Danke: 1061
Win10
C#, C++ (VS 2017/19/22)
|
Verfasst: Sa 08.03.14 17:10
Hallo,
da sich ja pictureBoxPlayerShip1 und pictureBoxSplash eigentlich gleich verhalten sollen, kann es nur sein, daß du doch irgendwo einen kleinen Fehler in deinem Code hast (in dem hier geposteten sehe ich aber keinen - sofern du sicher bist, daß die Location-Werte richtig sind).
In welcher Ereignismethode führst du denn den Spielzug aus (Button_Click)?
Generell ist es jedoch nicht die beste Möglichkeit, mit PictureBox-Objekten bei einem Spielprojekt zu arbeiten (insbesondere wenn sie überlappen und/oder es viele Objekte sind). Besser wäre es, die gesamten Grafik selber zu zeichnen (im Paint-Ereignis der Form oder eines Panels).
|
|
lk1990 
Hält's aus hier
Beiträge: 9
|
Verfasst: Sa 08.03.14 19:03
Danke für deine Antwort.
Die Locationwerte der PictureBoxSplash sind IMO korrekt. Das Spielfeld hat 600x600 Pixel größe und die Locationberechnung d. PictureBoxSplashwerte hat mir bei meinen Tests immer Werte zurückgeben, die innerhalb dieses Bereichs liegen. Aber ich werde noch versuchen anstatt der berechneten Werte für den 0+nten Spielzug einfach mit Sicherheit korrekte vordefinierte Standardwerte für alle Spielzüge zu verwenden. Wenn der Bug dann noch immer auftritt, so kann es nicht an den Locationwerten liegen.
Ich führe den Spielzug in der Button_Click Erignismethode aus. Ursprünglich wollte ich Spielmechanik und GUI zwar strikt voneinander trennen, da ich jedoch noch relativ wenig Erfahrung im Programmieren habe, lässt mein Programmkonzept das nicht ohne signifikante Änderungen zu (ich weiss aber inzwischen, wie ich es richtig machen würde, möchte aber nicht den bereits geschrieben Code zu stark verändern, da dieses Spiel ohnehin nur Lernhilfe für mich selbst dient und nicht veröffentlicht werden soll).
Was genau meinst du mit selbst zeichnen? Zur Laufzeit, mit System.Drawing.Pen zum Beispiel? Ich möchte gerne meine eigenen, mit Photoshop erstellten Grafiken einbinden, da ich mir so die größte Freiheit bei der Darstellung meiner 2D Spielgrafiken erhoffe.
EDIT: Hier noch der Code der Form in der die Darstllung erfolgen soll:
1: 2: 3: 4: 5: 6: 7: 8: 9: 10: 11: 12: 13: 14: 15: 16: 17: 18: 19: 20: 21: 22: 23: 24: 25: 26: 27: 28: 29: 30: 31: 32: 33: 34: 35: 36: 37: 38: 39: 40: 41: 42: 43: 44: 45: 46: 47: 48: 49: 50: 51: 52: 53: 54: 55: 56: 57: 58: 59: 60: 61: 62: 63: 64: 65: 66: 67: 68: 69: 70: 71: 72: 73: 74: 75: 76: 77: 78: 79: 80: 81: 82: 83: 84: 85: 86: 87: 88: 89: 90: 91: 92: 93: 94: 95: 96: 97: 98: 99: 100: 101: 102: 103: 104: 105: 106: 107: 108: 109: 110: 111: 112: 113: 114: 115: 116: 117: 118: 119: 120: 121: 122: 123: 124: 125: 126: 127: 128: 129: 130: 131: 132: 133: 134: 135: 136: 137: 138: 139: 140: 141: 142: 143: 144: 145: 146: 147: 148: 149: 150: 151: 152: 153: 154: 155: 156: 157: 158: 159: 160: 161: 162: 163: 164: 165: 166: 167: 168: 169: 170: 171: 172: 173: 174: 175: 176: 177: 178: 179: 180: 181: 182: 183: 184: 185: 186: 187: 188: 189: 190: 191: 192: 193: 194: 195: 196: 197: 198: 199: 200: 201: 202: 203: 204: 205: 206: 207: 208: 209: 210: 211: 212: 213: 214: 215: 216: 217: 218: 219: 220: 221: 222: 223: 224: 225: 226: 227: 228: 229: 230: 231: 232: 233: 234: 235: 236: 237: 238: 239: 240: 241: 242: 243: 244: 245: 246: 247: 248: 249: 250: 251: 252: 253: 254: 255: 256: 257: 258: 259: 260: 261: 262: 263: 264: 265: 266: 267: 268: 269: 270: 271: 272: 273: 274: 275: 276: 277: 278: 279: 280: 281: 282: 283: 284: 285: 286: 287: 288: 289: 290: 291: 292: 293: 294: 295: 296: 297: 298: 299: 300: 301: 302: 303: 304: 305: 306: 307: 308: 309: 310: 311: 312: 313: 314: 315: 316: 317: 318: 319: 320: 321: 322: 323: 324: 325: 326: 327: 328: 329: 330: 331: 332: 333: 334: 335: 336: 337: 338: 339: 340: 341: 342: 343: 344: 345:
| using System; using System.Collections.Generic; using System.ComponentModel; using System.Data; using System.Drawing; using System.Linq; using System.Text; using System.Threading.Tasks; using System.Windows.Forms; using Battleships.General; using Battleships.Ships; using Battleships.PhysicalEnvironment;
namespace Battleships { public partial class MainScreen : Form { InternalStorage NewStorage = new InternalStorage(); GlobalEnvironment NewEnvironment = new GlobalEnvironment(); InOutCheck NewCheck = new InOutCheck(); InOutConvert NewConvert = new InOutConvert(); PlayerShip NewPlayerShip = new PlayerShip(); TurnCountCalculation NewTurnCountCalculation = new TurnCountCalculation(); PositionCalculation NewPositionCalculation = new PositionCalculation(); BallisticCalculation NewBallisticCalculation = new BallisticCalculation(); AmmoCountCalculation NewAmmoCountCalculation = new AmmoCountCalculation();
public MainScreen() { InitializeComponent(); }
private void MainScreen_Load(object sender, EventArgs e) { int FirstTurn = 1; NewStorage.StoreCurrentNumberOfTurns(FirstTurn); this.TurnCounterBox.Text = Convert.ToString(NewStorage.RestoreCurrentNumberOfTurns());
if (NewStorage.RestoreCurrentNumberOfTurns() == 1) { NewStorage.StorePlayerPosXM(NewPlayerShip.InitialPositionX); NewStorage.StorePlayerPosYM(NewPlayerShip.InitialPositionY); double CurrentPlayerPosXNauticalMiles = NewConvert.ConvertMetersToNauticalMiles(NewStorage.RestorePlayerPosXM(), NewEnvironment.ConversionFactorMetersToNauticalMiles); double CurrentPlayerPosYNauticalMiles = NewConvert.ConvertMetersToNauticalMiles(NewStorage.RestorePlayerPosYM(), NewEnvironment.ConversionFactorMetersToNauticalMiles);
int CurrentPlayerAmmoCount = NewAmmoCountCalculation.CalculateCurrentAmmoAmount(NewPlayerShip.InitialAmmo, 0); NewStorage.StorePlayerCurrentAmmoCount(CurrentPlayerAmmoCount); this.AmmoBox.Text = Convert.ToString(NewStorage.RestorePlayerCurrentAmmoCount());
pictureBoxPlayerShip1.BackColor = Color.Transparent; pictureBoxSplash.BackColor = Color.Transparent;
pictureBoxPlayerShip1.Parent = pictureBoxBackground; pictureBoxSplash.Parent = pictureBoxBackground;
pictureBoxPlayerShip1.Location = new Point(Convert.ToInt32(CurrentPlayerPosXNauticalMiles), Convert.ToInt32(CurrentPlayerPosYNauticalMiles));
pictureBoxSplash.Visible = true; pictureBoxSplash.Location = new Point(Convert.ToInt32(0), Convert.ToInt32(0));
} }
private void ApplySpeed_Click(object sender, EventArgs e) { bool IsInt = NewCheck.CheckIfInt(this.SpeedBox.Text);
if (IsInt == true) { bool IsInRange = NewCheck.CheckIfIntWithinRange(this.SpeedBox.Text, NewPlayerShip.MaxSpeedKts, NewPlayerShip.MinSpeedKts);
if (IsInRange == true) { NewStorage.StorePlayerSpeedKts(Convert.ToInt32(this.SpeedBox.Text)); this.SpeedBox.Text = Convert.ToString(NewStorage.RestorePlayerSpeedKts()); } else { MessageBox.Show("Speed either exceeds maximum speed or is negative. Maximum Speed for this vessel is: " + NewPlayerShip.MaxSpeedKts, "Wrong Speed"); }
} else { if (IsInt == false) { MessageBox.Show("Input must be Integer.", "Wrong Format"); } } }
private void ApplyCourse_Click(object sender, EventArgs e) { bool IsInt = NewCheck.CheckIfInt(this.CourseBox.Text);
if (IsInt == true) { bool IsInRange = NewCheck.CheckIfIntWithinRange(this.CourseBox.Text, NewPlayerShip.MaxCourseDegrees, NewPlayerShip.MinCourseDegrees);
if (IsInRange == true) { NewStorage.StorePlayerCourseDegrees(Convert.ToInt32(this.CourseBox.Text)); this.CourseBox.Text = Convert.ToString(NewStorage.RestorePlayerCourseDegrees()); } else { MessageBox.Show("Course either exceeds maximum angle or is negative. Course must be between 0 and 360 degrees." , "Wrong Course"); }
} else { if (IsInt == false) { MessageBox.Show("Input must be Integer.", "Wrong Format"); } } }
private void ApplyGunAzimuth_Click(object sender, EventArgs e) { bool IsDouble = NewCheck.CheckIfDouble(this.GunHorizontalBox.Text);
if (IsDouble == true) { bool IsInRange = NewCheck.CheckIfDoubleWithinRange(this.GunHorizontalBox.Text, NewPlayerShip.MaxGunAzimuthDegrees, NewPlayerShip.MinGunAzimuthDegrees);
if (IsInRange == true) { NewStorage.StorePlayerGunAzimuthDegrees(Convert.ToInt32(this.GunHorizontalBox.Text)); this.GunHorizontalBox.Text = Convert.ToString(NewStorage.RestorePlayerGunAzimuthDegrees()); } else { MessageBox.Show("Gun azimuth either exceeds maximum or minimum angle for this vessel. Gun azimuth must be between 0 and " + NewPlayerShip.MaxGunAzimuthDegrees, "Wrong Angle"); }
} else { if (IsDouble == false) { MessageBox.Show("Input must be Real Number", "Wrong Format"); } } }
private void ApplyGunElevation_Click(object sender, EventArgs e) { bool IsDouble = NewCheck.CheckIfDouble(this.GunVerticalBox.Text);
if (IsDouble == true) { bool IsInRange = NewCheck.CheckIfDoubleWithinRange(this.GunVerticalBox.Text, NewPlayerShip.MaxGunElevationDegrees, NewPlayerShip.MinGunElevationDegrees);
if (IsInRange == true) { NewStorage.StorePlayerGunElevationDegrees(Convert.ToInt32(this.GunVerticalBox.Text)); this.GunVerticalBox.Text = Convert.ToString(NewStorage.RestorePlayerGunElevationDegrees()); } else { string _LocalString1 = Convert.ToString(NewPlayerShip.MaxGunElevationDegrees) + Convert.ToString(NewPlayerShip.MinGunElevationDegrees); MessageBox.Show("Gun elevation either exceeds maximum or minimum angle for this vessel. Gun elevation must be between: " + _LocalString1, "Wrong Angle"); }
} else { if (IsDouble == false) { MessageBox.Show("Input must be Real Number", "Wrong Format"); } } }
private void ApplyGunCharges_Click(object sender, EventArgs e) { bool IsInt = NewCheck.CheckIfInt(this.GunPropellingBox.Text);
if (IsInt == true) { bool IsInRange = NewCheck.CheckIfIntWithinRange(this.GunPropellingBox.Text, NewPlayerShip.MaxGunPropellingChargesAmount, NewPlayerShip.MinGunPropellingChargesAmount);
if (IsInRange == true) { NewStorage.StorePlayerGunPropellingChargesAmount(Convert.ToInt32(this.GunPropellingBox.Text)); this.GunPropellingBox.Text = Convert.ToString(NewStorage.RestorePlayerGunPropellingChargesAmount()); } else { MessageBox.Show("Amount of propelling charges either exceeds maximum or minimum for this vessels guns. Number of Propelling Charges mus be between 1 and " + NewPlayerShip.MaxGunPropellingChargesAmount, "Wrong Amount"); }
} else { if (IsInt == false) { MessageBox.Show("Input must be Integer", "Wrong Format"); } } }
private void FireGunSalvo_Click(object sender, EventArgs e) { bool _LocalBool = true; NewStorage.StorePlayerGunFireThisTurn(_LocalBool); }
private void RadarTurnOn_Click(object sender, EventArgs e) { bool _LocalBool = true; NewStorage.StorePlayerRadarStatus(_LocalBool); }
private void RadarTurnOff_Click(object sender, EventArgs e) { bool _LocalBool = false; NewStorage.StorePlayerRadarStatus(_LocalBool); }
private void EndTurn_Click(object sender, EventArgs e) { double _LocalSpeedMs = NewConvert.ConvertKtsToMs(NewStorage.RestorePlayerSpeedKts()); NewStorage.StorePlayerSpeedMs(_LocalSpeedMs);
double _LocalSpeedVectorX = NewConvert.ConvertPolarTo2DX(NewStorage.RestorePlayerCourseDegrees(), NewStorage.RestorePlayerSpeedMs()); NewStorage.StorePlayerSpeedVectorXMs(_LocalSpeedVectorX);
double _LocalSpeedVectorY = NewConvert.ConvertPolarTo2DY(NewStorage.RestorePlayerCourseDegrees(), NewStorage.RestorePlayerSpeedMs()); NewStorage.StorePlayerSpeedVectorYMs(_LocalSpeedVectorY);
double _LocalTotalInitialVelocity = NewConvert.ConvertPropellingChargesToTotalv0(NewStorage.RestorePlayerGunPropellingChargesAmount(), NewPlayerShip.VelocityPerChargeMs); NewStorage.StorePlayerGunTotalInitialVelocity(_LocalTotalInitialVelocity);
double _LocalInitialVelocityVectorXMs = NewConvert.ConvertSphericalTo3DX(NewStorage.RestorePlayerGunTotalInitialVelocity(), NewStorage.RestorePlayerGunElevationDegrees(), NewStorage.RestorePlayerGunAzimuthDegrees()); NewStorage.StorePlayerInitialVelocityVectorXMs(_LocalInitialVelocityVectorXMs);
double _LocalInitialVelocityVectorYMs = NewConvert.ConvertSphericalTo3DY(NewStorage.RestorePlayerGunTotalInitialVelocity(), NewStorage.RestorePlayerGunElevationDegrees(), NewStorage.RestorePlayerGunAzimuthDegrees()); NewStorage.StorePlayerInitialVelocityVectorYMs(_LocalInitialVelocityVectorYMs);
double _LocalInitialVelocityVectorZMs = NewConvert.ConvertSphericalTo3DZ(NewStorage.RestorePlayerGunTotalInitialVelocity(), NewStorage.RestorePlayerGunElevationDegrees()); NewStorage.StorePlayerInitialVelocityVectorZMs(_LocalInitialVelocityVectorZMs);
int PreviousTurn = NewStorage.RestoreCurrentNumberOfTurns(); int CurrentTurn = NewTurnCountCalculation.CalculateCurrentTurnNumber(PreviousTurn); NewStorage.StoreCurrentNumberOfTurns(CurrentTurn); this.TurnCounterBox.Text = Convert.ToString(NewStorage.RestoreCurrentNumberOfTurns());
int CurrentTimeScaleMins = 6; double CurrentPlayerPosXMeters = NewPositionCalculation.CalculateNewPosX(NewStorage.RestorePlayerPosXM(), NewStorage.RestorePlayerSpeedVectorXMs(), CurrentTimeScaleMins); double CurrentPlayerPosYMeters = NewPositionCalculation.CalculateNewPosY(NewStorage.RestorePlayerPosYM(), NewStorage.RestorePlayerSpeedVectorYMs(), CurrentTimeScaleMins); double CurrentPlayerPosXNauticalMiles = NewConvert.ConvertMetersToNauticalMiles(CurrentPlayerPosXMeters, NewEnvironment.ConversionFactorMetersToNauticalMiles); double CurrentPlayerPosYNauticalMiles = NewConvert.ConvertMetersToNauticalMiles(CurrentPlayerPosYMeters, NewEnvironment.ConversionFactorMetersToNauticalMiles); NewStorage.StorePlayerPosXM(CurrentPlayerPosXMeters); NewStorage.StorePlayerPosYM(CurrentPlayerPosYMeters); NewStorage.StorePlayerPosXNm(CurrentPlayerPosXNauticalMiles); NewStorage.StorePlayerPosYNm(CurrentPlayerPosYNauticalMiles);
pictureBoxPlayerShip1.Location = new Point(Convert.ToInt32(NewStorage.RestorePlayerPosXNm()), Convert.ToInt32(NewStorage.RestorePlayerPosYNm()));
if (NewStorage.RestorePlayerGunFireThisTurn() == true) { bool AmmoAvailable; if (NewCheck.CheckIntIfAboveZero(NewStorage.RestorePlayerCurrentAmmoCount())) { AmmoAvailable = true; } else { AmmoAvailable = false; }
if (AmmoAvailable == true) { int CurrentPlayerAmmoCount = NewAmmoCountCalculation.CalculateCurrentAmmoAmount(NewStorage.RestorePlayerCurrentAmmoCount(), NewStorage.RestorePlayerGunPropellingChargesAmount()); NewStorage.StorePlayerCurrentAmmoCount(CurrentPlayerAmmoCount); this.AmmoBox.Text = Convert.ToString(NewStorage.RestorePlayerCurrentAmmoCount()); double _LocalTimeOfImpactSeconds = NewBallisticCalculation.CalculateImpactTimeZSeconds(NewStorage.RestorePlayerInitialVelocityVectorZMs(), NewEnvironment.ConstantGravitationalAccelerationMs2, NewPlayerShip.DeckHeightMeters, NewPlayerShip.ProjectileMassKg); double _LocalImpactPointYMeters = NewBallisticCalculation.CalculateImpactPointYMeters(NewStorage.RestorePlayerInitialVelocityVectorYMs(), 0, NewStorage.RestorePlayerPosYM(), _LocalTimeOfImpactSeconds, NewPlayerShip.ProjectileMassKg); double _LocalImpactPointXMeters = NewBallisticCalculation.CalculateImpactPointXMeters(NewStorage.RestorePlayerInitialVelocityVectorXMs(), 0, NewStorage.RestorePlayerPosXM(), _LocalTimeOfImpactSeconds, NewPlayerShip.ProjectileMassKg); double _LocalImpactPointXNm = NewConvert.ConvertMetersToNauticalMiles(_LocalImpactPointXMeters, NewEnvironment.ConversionFactorMetersToNauticalMiles); double _LocalImpactPointYNm = NewConvert.ConvertMetersToNauticalMiles(_LocalImpactPointYMeters, NewEnvironment.ConversionFactorMetersToNauticalMiles); NewStorage.StoreImpactPointXNm(_LocalImpactPointXNm); NewStorage.StoreImpactPointYNm(_LocalImpactPointYNm);
bool TargetIsHit = false; if (TargetIsHit == true) { bool _LocalSplashThisTurn = false; NewStorage.StoreIfPlayerSplash(_LocalSplashThisTurn); }
else { bool _LocalSplashThisTurn = true; NewStorage.StoreIfPlayerSplash(_LocalSplashThisTurn); } } else { bool _LocalBool = false; NewStorage.StorePlayerGunFireThisTurn(_LocalBool); FireGunSalvo.Enabled = false; this.AmmoBox.Text = Convert.ToString(0); }
} else { bool SplashThisTurn = false; NewStorage.StoreIfPlayerSplash(SplashThisTurn); } pictureBoxSplash.Visible = NewStorage.RestoreIfPlayerSplash(); pictureBoxSplash.Location = new Point(Convert.ToInt32(NewStorage.RestoreImpactPointXNm()), Convert.ToInt32(NewStorage.RestoreImpactPointYNm())); } } } |
|
|
lk1990 
Hält's aus hier
Beiträge: 9
|
Verfasst: Sa 08.03.14 20:05
Hi,
ich habe das Problem soeben gelöst. Sollte es jemand anderem mit einem ähnlichen Problem vielleicht weiterhelfen:
Die beiden PictureBoxen (Ship1 & Splash) haben sich bei jedem meiner Testläufe immer überlagert und Ship1 hat dabei Splash verdeckt. Das Spielfeld ist mit 600 x 600 nautischen Meilen (dargestellt auf 600 x 600 Pixeln) so groß, dass bei realistischen Mündingsgeschwindigkeiten (ca 890 m/s, die ballistische Berechnung erfolgt im Gegensatz zur Dartsellung in 3D) das Projektil nie ausserhalb der ca 15x15 Pixel großen Schiffsgrafik laden konnte.
Daraus ergibt sich dann direkt das nächste Problem, das man wohl unter Verwenbdung der PictureBoxen nicht lösen kann.
|
|
Th69
      

Beiträge: 4805
Erhaltene Danke: 1061
Win10
C#, C++ (VS 2017/19/22)
|
Verfasst: So 09.03.14 10:07
Hallo,
das ist eben das Problem mit WinForms-Controls und Transparenz (bei sich überlagernden Objekten ist nur das "oberste" zu sehen - Stichworte: Z-Achse sowie BringToFront/SendToBack etc.).
Zum selber Zeichnen meine ich wie z.B. unter myCSharp-Forum: [Tutorial] Zeichnen in Windows-Forms-Programmen (Paint/OnPaint, PictureBox) beschrieben, d.h. alle Objekte werden in einer Paint-Methode gezeichnet (und für Grafiken kannst du dann selber e.Graphics.DrawImage(...) aufrufen).
Ist zwar initial etwas mehr Arbeit, da man nun selber die Datenstrukturen und Logik der Objekte (Grafiken etc.) verwalten muß, man hat dann jedoch komplette Kontrolle über das Zeichnen.
Für dein bisheriges Projekt (wie du selber schreibst: Lernhilfe) würde ich das jedoch ersteinmal nicht mehr machen. Wenn du jedoch neue Projekte dieser Art angehen möchtest, dann solltest du diesen Ansatz wählen (das hat den weiteren Vorteil, daß du so gleich GUI und Logik von vornherein trennen kannst!).
Viel Erfolg noch mit deinem Projekt (bzw. deinen Projekten).
|
|
lk1990 
Hält's aus hier
Beiträge: 9
|
Verfasst: Di 11.03.14 12:26
Danke für den Link zu dem Tutorial. Ich habe das Problem mit den sich nicht richtig überlagern wollenden transparenten Bildern zwischenzeitlich so gelöst:
C#-Quelltext 1: 2: 3: 4: 5: 6: 7: 8: 9: 10: 11: 12: 13: 14: 15:
| private void button1_Click(object sender, EventArgs e) { var src = new Bitmap("C:/Users/aspire 1/Documents/Visual Studio 2013/Projects/Battleships/Battleships/ship1.png"); var src1 = new Bitmap("C:/Users/aspire 1/Documents/Visual Studio 2013/Projects/Battleships/Battleships/back2.png"); var src2 = new Bitmap("C:/Users/aspire 1/Documents/Visual Studio 2013/Projects/Battleships/Battleships/splash1.png"); var bmp = new Bitmap(250, 250, PixelFormat.Format32bppPArgb); var gr = Graphics.FromImage(bmp); gr.DrawImage(src1, new Rectangle(0, 0, bmp.Width, bmp.Height)); gr.DrawImage(src, new Rectangle(0, 0, 15, 15)); gr.DrawImage(src2, new Rectangle(20, 20, 15, 15));
this.pictureBox1.Image = bmp; } |
Ist das eine korrekte bzw auch bei größeren 2D Anwendungen sinnvolle vorgehenweise, oder sollte ich doch lieber genau wie in dem Tutorial beschrieben vorgehen, um Probleme bei der Darstellung zu vermeiden (sprich: die PictureBox komplett zu vermeiden versuchen)? Sorry für die vielleicht trivial erscheinende Frage, aber ich meine Programmiererfahrung beträgt insgesamt höchstens 3 Wochen.
|
|
Th69
      

Beiträge: 4805
Erhaltene Danke: 1061
Win10
C#, C++ (VS 2017/19/22)
|
Verfasst: Di 11.03.14 16:03
Hallo,
bei größeren Projekten würde ich komplett auf PictureBoxen verzichten, aber solange es jetzt seinen Zweck in deinem Projekt erfüllt, kannst du es so lassen.
Nur einen Tipp noch zu den Bildern:
Statt diese mit absoluten Pfadangaben anzusprechen, kannst du zum einen relative Pfade benutzen:
C#-Quelltext 1: 2:
| Path.Combine(Application.StartupPath, "ship1.png"); |
Dann solltest du diese Bilder direkt zu deinem VS-Projekt hinzufügen und bei deren Eigenschaft "CopyToOutputDir" auf "Copy if newer" stellen (bei einem deutschen VS entsprechende Bezeichnungen). So werden sie dann automatisch beim Kompilieren in das "bin/Debug" bzw. "bin/Release"-Verzeichnis kopiert). So kannst du dann auch die gesamte Anwendung auf einem anderen Rechner starten, indem du einfach dieses Verzeichnis kopierst.
Und die andere Möglichkeit ist das Hinterlegen der Bilder als Ressourcen ( Hinzufügen und Bearbeiten von Ressourcen (Visual C#)).
Du kannst dann die Bilder direkt schon als Bitmap ansprechen, z.B.
C#-Quelltext 1:
| var src = Properties.Resources.Ship1; |
(und brauchst so die Bilder dann nicht mehr in das Ausgabeverzeichnis kopieren, da sie jetzt direkt in der Anwendung enthalten sind - auch wenn diese dann entsprechend größer wird).
|
|
|