Entwickler-Ecke

Sonstiges (.NET) - HILFE Anfänger am Werk Spiel programmieren


Anfänger92 - So 24.10.10 00:24
Titel: HILFE Anfänger am Werk Spiel programmieren
Hallo erstmal,
ist mein erster Beitrag hier im Forum, hoffe ich hab den hier richtig plaziert, wenn nicht sagt mir bescheid...
Also es geht um folgendes... ich soll bis Montag von der Schule aus ein Programm fertig stellen, nachdem ich jetzt den Samstag damit verbracht habe, dabei weiter zu kommen, es aber nicht geschafft habe wende ich mich jetzt mal an die Experten, ich denke ihr könnt mir weiterhelfen.

Also erstmal zu konzept vom Programm. Es soll im prinzip nach der Vorlage von Pakman sein. Es soll also eine Spielfigur geben und (mindestens) einen Gegner, der Gegner verfolgt die Spielfigur die man naütlich selbst über die Pfeiltasten steuern kann und wenn er einen hat, dann hat man verloren. Damit man gewinnen kann soll die Spielfigur einen Art Bomben-Ablege-Funktion haben, die eine Bombe plaziert. Berührt der Gegner die Bombe, dann explodiert er. Hoffe ich hab dass alles soweit verständlich erklärt...

Zur Programmierumgebung... wir benutzen SharpDevelop Version 3.2, das Spiel wird als Konsolenanwendung dargestellt, ist ja auch ein "Anfänger-Projekt". Hier der Programmtext:


C#-Quelltext
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:
using System;

namespace Pakman
{
  class Program
  {
    public static void Main(string[] args)
    {
      Spiel spiel = new Spiel();
      spiel.spielen();
      
      
      Console.Write("Press any key to continue . . . ");
      Console.ReadKey(true);
    }
  }
  
  class Spielfigur
  {
    public int x;
    public int y;
    string name;
    public char zeichen;
    int gew;
    bool status;
    int richtung;
    
    public void setSpieler(int x, int y, string name, char zeichen)
    {
      this.x=x;
      this.y=y;
      this.name=name;
      this.zeichen=zeichen;
    }
    
    public void bewegen(char auswahl)
    {
      if(auswahl=='w') y--;                          <span style="color: green">//Soll wie schon gesagt noch mit den Pfeil-</span>
      else if(auswahl=='s') y++;                     <span style="color: green">//tasten gemacht werden und auch ohne </span>
      else if(auswahl=='a') x--;                     <span style="color: green">//Return nach jeder Eingabe Arbeiten...</span>
      else if(auswahl=='d') x++;
    }
  }
  
  class Gegner
  {
    public int x;
    public int y;
    public char zeichen = 'g';
    int gew;
    bool status;
    int richtung;
    
    
    
    public Gegner()
    {
      Random r = new Random();                <span style="color: green">//der Gegner soll sich natürlich auch nicht zufällig</span>
      x=r.Next(0,40);                         <span style="color: green">//bewegen sondern der Spielfigur folgen</span>
      Random s = new Random();
      y=s.Next(0,10);  
      
    }
    
    public void bewegen()
    {
      Random t = new Random();
      int z= x=t.Next(0,4);
      if(z==0) y--;
      else if(z==1) y++;
      else if(z==2) x--;
      else if(z==3) x++;
    }
  }
  
  class Bombe
  {
    public int x=10;                               <span style="color: green"//Bei der Bombe fehlt bisher noch alles, der Gegner ist</span>
    public int y=10;                               <span style="color: green"//schließlich nichteinmal fertig</span>
    public char zeichen = 'b';
    string name;
    bool status;
    
    
  }
  class Spiel
  {
    
    Spielfeld s = new Spielfeld();
    Spielfigur spieler1 = new Spielfigur();
    Gegner gegner1 = new Gegner();
    
    
    public void init_Spiel()
    {
      Console.WriteLine("Bitte geben Sie ein Zeichen für den Spieler ein");
      char zeichen=char.Parse(Console.ReadLine());
      Console.WriteLine("Bitte geben Sie eine x-Koordinate (maximal 39) ein");
      int x = int.Parse(Console.ReadLine());
      Console.WriteLine("Bitte geben Sie eine y-Koordinate (maximal 9) ein)");
      int y = int.Parse(Console.ReadLine());
      Console.WriteLine("Bitte geben Sie einen Namen ein");
      string name =Console.ReadLine();
      spieler1.setSpieler(x,y,name,zeichen);
      s.feld[y*s.breite+x]=zeichen;
      s.anzeigen();

    }
    
    public void spielen()
    {
      init_Spiel();
      
      while(true)
      {
        spieler1.bewegen(char.Parse(Console.ReadLine()));
        gegner1.bewegen();
        s.clear();
        Console.Clear();
        setSpielfiguren();
        s.anzeigen();
      }
    }
    
    public void setSpielfiguren()
    {
      s.feld[spieler1.y*s.breite+spieler1.x]=spieler1.zeichen;
      s.feld[gegner1.y*s.breite+gegner1.x]=gegner1.zeichen;

    }
    
  }
  
  class Spielfeld                            <span style="color: green">//und das Spielfeld soll einfach nur eine Konsole sein mit den Buch-</span>
  {                                          <span style="color: green">//staben für Gegner und den Spieler bzw die Bombe</span>
    public int laenge;
    public int breite;
    public char [] feld;
    
    public void clear()
    {
      for(int i=0; i<laenge;i++)
      {
        for(int j=0; j<breite; j++)
        {
          feld[i*breite+j]=' ';
        }
      }
    }
    
    public Spielfeld()
    {
      laenge=10;
      breite=40;
      feld = new char[laenge*breite];
      clear();
    }
    
    public void anzeigen()
    {
      for(int i=0; i<laenge;i++)
      {
        for(int j=0; j<breite; j++)
        {
          Console.Write(feld[i*breite+j]);
        }
        Console.WriteLine();
      }
      
    }
  }
}



Danke auf jeden Fall schonmal für die Aufmerksamkeit. Ich weis es ist viel und durcheinander, aber ich bin zuversichtlich, dass ihr mir helfen könnt das ganze fertig zu stellen.

Moderiert von user profile iconMartok: Quote- durch C#-Tags ersetzt
Moderiert von user profile iconKha: Topic aus Algorithmen, Optimierung und Assembler verschoben am So 24.10.2010 um 11:43


jaenicke - So 24.10.10 09:08

Hallo und :welcome:

Wo ist denn deine Frage? Also was ist denn eigentlich das Problem? :gruebel:


Anfänger92 - So 24.10.10 11:15

1.)Also mein erstes Problem wäre es erstmal hinzubekommen, dass sich Spielfigur und Gegner bewegen, ohne dass man nach jeder eingabeReturn drücken muss...
2.)Als nächstes würde ich gern wissen, wie ich den Gegner dazu bekomme, dass der sich hinter meiner Spielfigur hinterher bewegt
3.)Und das dritte was ich nicht hinbekomme ist die Bombe mit einzubinden...
Also ganz konkret wäre jetzt die Frage, ob ihr mir vielleicht ersteinmal zeogen könnt, wie man diese Punkte lösen könnte


Greenberet - So 24.10.10 12:52

1) Statt ReadLine rufst du einfach ReadChar auf( da brauchst dann auch kein char.Parse mehr )
2) Dafür musst du einen Pfadsuchalgorithmus schreiben( Beispiel A* [http://de.wikipedia.org/wiki/A*-Algorithmus] und anhand von dem die Position des Gegners setzen
3) Hier solltest du dir mal überlegen was für ne Art Bombe ist. Ich geh mal von einer Mine aus.
Zum setzen Drückst du einfach eine Taste. bsp X Nur musst du die Eingabe hier jetzt von der Bewegen entkoppeln da du sonst keinen Wirklichen Zugriff darauf hast.
In Jedem Spielzug überprüfst du ob sich ein Spieler/Gegner auf der Bombe befindet. Wenn Ja -> Spieler verletzt/Tod


Anfänger92 - So 24.10.10 13:05

Danke auf jeden fall schonmal für die Antwort, aber ich könnte mehr damit anfangen, wenn du mir das ganze "ein bisschen weich kaust" ich meine die Grundidee ist sicher ne hilfe nur ich bekomme das nicht in Quelltext umgebaut... ich kann nochnichtmal vernünftig mit Set und Get arbeiten und bekomme demnach auch die parameter nicht richtig gesetzt, wie schon geschrieben bin noch ein Anfänger und eigentlich ist die Aufgabe auch noch ein bisschen viel für mich....
(Ich hab den Kurs gewechselt und kam mit Info vorher ganz gut klar, aber jetzt arbeiten wir mit C# statt mit Java und in Sharp Develop, statt mit den "Kinderprogrammen", die wir vorher benutzt haben, wo man Buntstifte bewegen sollte und sowas)

Ich weis ist fast schon wieder unverschämt hier nach nem fertigen Quelltext bzw Code zu fragen, aber ich machs trotzdem mal und hoffe auf Verständnis und Hilfe ...


DuxGladii - Mo 25.10.10 14:28

Ich glaub kaum, dass dir hier jemand nen kompletten Code von Pacman liefert. Stell eine konkrete Frage, dann kann dir besser geholfen werden.


VampireSilence - So 07.11.10 20:02

Ok 1. Erstell ein neues Projekt (name: Pacman),
2. Lege die Größe der Form auf 488x512 fest,
3. Erstelle einen Timer namens "tmrTick",
4. Kopiere folgenden Code in die Form1:


C#-Quelltext
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:
346:
347:
348:
349:
350:
351:
352:
353:
354:
355:
356:
357:
358:
359:
360:
361:
362:
363:
364:
365:
366:
367:
368:
369:
370:
371:
372:
373:
374:
375:
376:
377:
378:
379:
380:
381:
382:
383:
384:
385:
386:
387:
388:
389:
390:
391:
392:
393:
394:
395:
396:
397:
398:
399:
400:
401:
402:
403:
404:
405:
406:
407:
408:
409:
410:
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;

namespace Pacman
{
    public partial class Form1 : Form
    {
        Keys _PressedKey = Keys.None;
        Enemy[] _Enemies = new Enemy[2];
        Coin[] _Coins = new Coin[10];
        Player _Me = new Player();
        Random _Rnd = new Random();
        int _FieldHeight = 20;
        int _FieldWidth = 20;
        int _CollectedCoins = 0;
        float _EnemyMovement = 0;
        float _EnemyFactor = 0.5f;
        bool _GameOver = false;

        Graphics _GFX;

        public Form1()
        {
            InitializeComponent();

            // setup graphics
            _GFX = this.CreateGraphics();
            _GFX.CompositingQuality = System.Drawing.Drawing2D.CompositingQuality.HighQuality;
            _GFX.InterpolationMode = System.Drawing.Drawing2D.InterpolationMode.HighQualityBicubic;
            _GFX.SmoothingMode = System.Drawing.Drawing2D.SmoothingMode.HighQuality;
            _GFX.TextRenderingHint = System.Drawing.Text.TextRenderingHint.AntiAlias;

            // start game
            this.StartNewGame();
        }

        private void StartNewGame()
        {
            this._GameOver = false;

            for (int i = 0; i < _Enemies.Length; i++)
            {
                _Enemies[i] = new Enemy();
                _Enemies[i].X = _Rnd.Next(0, _FieldWidth - 1);
                _Enemies[i].Y = _Rnd.Next(0, _FieldHeight - 1);
                _Enemies[i].Direction = _Rnd.Next(03) * 90;
            }

            for (int i = 0; i < _Coins.Length; i++)
            {
                _Coins[i] = new Coin();
                _Coins[i].X = _Rnd.Next(0, _FieldWidth - 1);
                _Coins[i].Y = _Rnd.Next(0, _FieldHeight - 1);
            }

            _Me.X = _Rnd.Next(0, _FieldWidth - 1);
            _Me.Y = _Rnd.Next(0, _FieldHeight - 1);
            _Me.Direction = _Rnd.Next(03) * 90;

            this.tmrTick.Start();
        }

        private void Form1_KeyDown(object sender, KeyEventArgs e)
        {
            this._PressedKey = e.KeyCode;

            if (e.KeyCode == Keys.Return && this._GameOver)
            {
                this._CollectedCoins = 0;
                this.StartNewGame();
            }
        }

        private void Form1_KeyUp(object sender, KeyEventArgs e)
        {
            this._PressedKey = Keys.None;
        }

        private void tmrTick_Tick(object sender, EventArgs e)
        {
            // make synchrone
            this.tmrTick.Stop();

            switch (this._PressedKey)
            {
                case Keys.Up:
                    this._Me.Direction = 0;
                    break;

                case Keys.Right:
                    this._Me.Direction = 90;
                    break;

                case Keys.Down:
                    this._Me.Direction = 180;
                    break;

                case Keys.Left:
                    this._Me.Direction = 270;
                    break;

            }

            // process AI
            this.ProcessAI();

            // update world
            this.UpdateWorld();

            // update graphics
            this.UpdateGraphics();

            // check win
            this.CheckWin();

            // check collision
            if (this.CheckCollision() == 1)
            {
                this.GameOver();
            }
            else
            {
                // restart synchrone
                this.tmrTick.Start();
            }
        }

        private void GameOver()
        {
            string GameOverText = "Game Over !";
            string ScoreText = "Your Score: " + this._CollectedCoins.ToString();

            Font GameOverFont = new Font(FontFamily.GenericSansSerif, 24);
            Font ScoreFont = new Font(FontFamily.GenericSansSerif, 14);

            Size GameOverSize = TextRenderer.MeasureText(GameOverText, GameOverFont);
            Size ScoreSize = TextRenderer.MeasureText(ScoreText, ScoreFont);

            float GameOverX = (this.Width - GameOverSize.Width) / 2;
            float ScoreX = (this.Width - ScoreSize.Width) / 2;

            float GameOverY = (this.Height - GameOverSize.Height - ScoreSize.Height - 6) / 2;
            float ScoreY = GameOverY + GameOverSize.Height + 6;

            _GFX.DrawString(GameOverText, GameOverFont, Brushes.PowderBlue, GameOverX, GameOverY);
            _GFX.DrawString(ScoreText, ScoreFont, Brushes.White, ScoreX, ScoreY);

            this._GameOver = true;
        }

        private void CheckWin()
        {
            foreach (Coin c in this._Coins)
            {
                if (!c.Collected)
                {
                    return;
                }
            }

            this.StartNewGame();
        }

        private int CheckCollision()
        {
            // check collision between enemy <-> player
            foreach (Enemy e in this._Enemies)
            {
                if (e.X == _Me.X && e.Y == _Me.Y)
                {
                    return 1;
                }
            }

            // check collision between coins <-> player
            foreach (Coin c in this._Coins)
            {
                if (c.X == _Me.X && c.Y == _Me.Y)
                {
                    c.Collected = true;
                    this._CollectedCoins++;
                    return 2;
                }
            }

            return 0;
        }

        private void ProcessAI()
        {
            // give move points
            this._EnemyMovement += this._EnemyFactor;

            // direct enemy

            foreach (Enemy e in this._Enemies)
            {
                int[] OptionsX = new int[] {
                    Math.Abs( e.X - _Me.X ),
                    Math.Abs( e.X - _Me.X + this._FieldWidth ),
                    Math.Abs( e.X - _Me.X - this._FieldWidth )
                    };

                int[] OptionsY = new int[] {
                    Math.Abs( e.Y - _Me.Y ),
                    Math.Abs( e.Y - _Me.Y + this._FieldHeight ),
                    Math.Abs( e.Y - _Me.Y - this._FieldHeight )
                    };

                int ChosenOptionX = OptionsX.Min();
                int ChosenOptionY = OptionsY.Min();

                int[] Options = new int[] {
                    ChosenOptionX,
                    ChosenOptionY
                    };

                int ChosenOption = Options.Max();

                if (ChosenOptionX > ChosenOptionY)
                {
                    if (OptionsX[0] == ChosenOptionX)
                    {
                        if (e.X - _Me.X > 0)
                        {
                            e.Direction = 270;
                        }
                        else
                        {
                            e.Direction = 90;
                        }
                    }
                    else
                    {
                        if (e.X - _Me.X > 0)
                        {
                            e.Direction = 90;
                        }
                        else
                        {
                            e.Direction = 270;
                        }
                    }
                }
                else
                {
                    if (OptionsY[0] == ChosenOptionY)
                    {
                        if (e.Y - _Me.Y > 0)
                        {
                            e.Direction = 0;
                        }
                        else
                        {
                            e.Direction = 180;
                        }
                    }
                    else
                    {
                        if (e.Y - _Me.Y > 0)
                        {
                            e.Direction = 180;
                        }
                        else
                        {
                            e.Direction = 0;
                        }
                    }
                }
            }
        }

        private void UpdateWorld()
        {
            // check if enemies move
            if (this._EnemyMovement < 1)
            {
                // dont move !
            }
            else
            {
                this._EnemyMovement--;

                // move Enemies
                foreach (Enemy e in this._Enemies)
                {
                    switch (e.Direction)
                    {
                        case 0:
                            e.Y = (e.Y + this._FieldHeight - 1) % this._FieldHeight;
                            break;

                        case 90:
                            e.X = (e.X + 1) % this._FieldWidth;
                            break;

                        case 180:
                            e.Y = (e.Y + 1) % this._FieldHeight;
                            break;

                        case 270:
                            e.X = (e.X + this._FieldWidth - 1) % this._FieldWidth;
                            break;
                    }
                }
            }

            // move Player
            switch (_Me.Direction)
            {
                case 0:
                    _Me.Y = (_Me.Y + this._FieldHeight - 1) % this._FieldHeight;
                    break;

                case 90:
                    _Me.X = (_Me.X + 1) % this._FieldWidth;
                    break;

                case 180:
                    _Me.Y = (_Me.Y + 1) % this._FieldHeight;
                    break;

                case 270:
                    _Me.X = (_Me.X + this._FieldWidth - 1) % this._FieldWidth;
                    break;
            }
        }

        private void UpdateGraphics()
        {
            this.Text = "VampireSilence Pacman (Your Score: " + this._CollectedCoins + ")";

            _GFX.Clear(Color.Black);

            // draw Enemies
            foreach (Enemy e in this._Enemies)
            {
                _GFX.DrawPie(new Pen(e.ForeColor), e.X * 24, e.Y * 242424, e.Direction + 300300);
            }

            foreach (Coin c in this._Coins)
            {
                c.Draw(_GFX);
            }

            // draw Player
            _GFX.DrawPie(new Pen(this._Me.ForeColor), this._Me.X * 24this._Me.Y * 242424this._Me.Direction + 300300);
        }
    }

    // Game Objects

    public class Person
    {
        public int X, Y;
        public Color ForeColor;
        public int Direction;
    }

    public class Enemy : Person
    {
        public Enemy()
        {
            this.ForeColor = Color.Yellow;
        }
    }

    public class Player : Person
    {
        public Player()
        {
            this.ForeColor = Color.Red;
        }
    }

    public class Coin
    {
        public int X, Y;
        public bool Collected;
        bool Site;
        Random Random = new Random();

        public void Draw(Graphics g)
        {
            if (!Collected)
            {
                Site ^= true;

                if (Site)
                {
                    g.FillEllipse(Brushes.Orange, X * 24 + 8, Y * 24 + 4816);
                }
                else
                {
                    g.FillEllipse(Brushes.PaleGoldenrod, X * 24 + 4, Y * 24 + 41616);
                }
            }
            else
            {
                g.FillEllipse(Brushes.DarkGray, X * 24 + 4, Y * 24 + 41616);
            }
        }
    }
}


5. Herzlichen Glückwunsch zu deinem eigenen Pacman. ;)
Gibt natürlich noch einige Dinge, die man verbessern könnten (z.B. Wände), aber das soll im Grunde auch nur ein Beispiel sein, aus dem du dir Textstellen zur Inspiration herauskopieren kannst. Ich hoffe es hilft.

mfg
- VampireSilence