Autor Beitrag
Frost
Hält's aus hier
Beiträge: 4



BeitragVerfasst: So 15.06.08 18:37 
Tag,

Also, ich hab' mir vorgenommen Tetris zu programmieren. Lief auch ganz gut bis jetzt.
Im moment hab ich ne Form, auf der jeweils ein Stein nach unten fällt und auch stehen bleibt und auch nicht die "Mauer" links und rechts überschreitet.
Jedoch Hab ich ein Problem bei dem langen Stein, da er immer zu tief fällt. Wie kann ich das besser machen? (Quelltext ist weiter unten)

Dazu hab ichs bis jetzt nur so, dass wenn ein Stein unten ist kein neuer Stein erscheint und runterfällt.
Dazu würde dieser neue Stein dann, falls er auf den alten trifft, erst wieder ab der Linie wo unten die "Mauer" ist stehenbleiben.
Also wie könnte ich das anders machen?
Ich hab mir auch schon überlegt so eine Art unsichtbare Tabelle zu erstellen aber ich wusste nicht wie. Vielleicht kann mir das ja jemand verraten. :D

Ich habe im moment mit Bildern gearbeitet von diesen Tetris-Steinen die dann immer nach unten fallen. Nur ist da auch das Problem, dass immer der weiße Hintergrund angezeigt wird und wenn ich auf die Transparentbarkeit aktiviere, wird der Stein und nicht der Hintergrund transparent. :/

Na ja, hier erstmal der Quelltext und ein Bild vom Programm
[Edit]
Mir ist noch ein Fehler aufgefallen, den ich behoben hab. Wenn der Stein auf dem Boden war konnte man ihn noch nach links und rechts bewegen.
[/Edit]

ausblenden volle Höhe Delphi-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:
unit Unit1;

interface

uses
  Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
  Dialogs, ExtCtrls, StdCtrls, ExtDlgs, ImgList;

type
  TForm1 = class(TForm)
    ShapeRechteWand: TShape;
    ShapeLinkeWand: TShape;
    ShapeUntenWand: TShape;
    TimerStein: TTimer;
    TimerZeit: TTimer;
    LabelZeit: TLabel;
    Label1: TLabel;
    Image1: TImage;
    Image2: TImage;
    TimerSteineStehen: TTimer;
    Image3: TImage;
    Image4: TImage;
    Image5: TImage;
    Image6: TImage;
    Image7: TImage;
    procedure TimerZeitTimer(Sender: TObject);
    procedure TimerSteinTimer(Sender: TObject);
    procedure FormCreate(Sender: TObject);
    procedure FormKeyDown(Sender: TObject; var Key: Word;
      Shift: TShiftState);
    procedure TimerSteineStehenTimer(Sender: TObject);
  private
    { Private-Deklarationen }
  public
    { Public-Deklarationen }
  end;
  function SteinErzeugen:TImage;

var
  Form1: TForm1;

  i,Zeit,Punkte,Level,R,R2:Integer;
  Steine: array [1..7] of TImage;
  SteineDrehen:array [1..19] of TImage;

implementation
//funktion zum Steine Erzeugen
 function SteinErzeugen:TImage;
 begin
 //Quadrat
   Steine[1]:=Form1.Image1;
 //Stange
   Steine[2]:=Form1.Image2;
 //T-Form
   Steine[3]:=Form1.Image7;
 //L-Form
   Steine[4]:=Form1.Image4;
 //L-Form umgedreht
   Steine[5]:=Form1.Image3;
 //Z-Form
   Steine[6]:=Form1.Image6;
 //Z-Form umgedreht
   Steine[7]:=Form1.Image5; 


 //R = Position des neuen Steines
 //R2 = Art des Steines
   R:=Random(430)+24;  // stellt einen zufallszahlenbereich von 24 - 430 her
   R2:=Random(7)+1;    // stellt einen zufallszahlenbereich von 1 - 7 her

   Steine[R2].parent:=form1; // auf Form1
   Steine[R2].top:=0; // wird ganz oben platziert
   Steine[R2].Left:=r; // wird irgendwo im "eingemauerten" Bereich platziert
   Steine[R2].visible:=false; // unsichtbar
 end;

 {$R *.dfm}


procedure TForm1.TimerZeitTimer(Sender: TObject);
begin
  Zeit:= Zeit+1;   // zählt die zeit hoch
  LabelZeit.Caption:= 'Zeit: '+inttostr(zeit)+''; // zeigt die vergangene zeit im spiel
end;

procedure TForm1.FormCreate(Sender: TObject);
begin
  KeyPreview:= True;
  Label1.Caption:='Drücken Sie "Leerzeichen",  '#10#13'um das Spiel zu beginnen!';
  randomize;
  SteinErzeugen;
end;

//Stein fällt
procedure TForm1.TimerSteinTimer(Sender: TObject);
begin
 Steine[R2].Visible:=true;
 Steine[R2].top:=Steine[R2].top+5;
 end;


//Spiel beginnen
procedure TForm1.FormKeyDown(Sender: TObject; var Key: Word;
  Shift: TShiftState);
begin

// Spiel beginnt
  if key = VK_Space then
    begin
      Label1.Visible:=false;    // lässt den Hinweis, dass man auf Space drücken soll verschwinden
      TimerZeit.Enabled:=true;  // aktiviert den Zeit-Zähler
      TimerStein.Enabled:=true; // aktiviert den fallenden Stein
      end;
//Bewegung des fallenden Steins

// bewegt den stein nach unten, ohne ihn in den Boden fallen zu lassen
 if Steine[R2].Top < 548 then
   begin
     if key = VK_Down then
      Steine[R2].Top:=Steine[R2].Top+15; // bewegt den stein schneller nach unten

//bewegt den stein nach links und übertritt nicht die linke mauer
 if Steine[R2].Left > 30 then
  begin
    if key = VK_Left then
     Steine[R2].left:=Steine[R2].left-10; //bewegt den stein nach links
   end
     else
      if key = VK_Left then
       begin
         Steine[R2].Left:=Steine[R2].Left-0  // setzt die bewegungsgeschwindigkeit des steins auf 0, falls dieser zu weit links ist
       end;

// bewegt den stein nach rechts und übertritt nicht die rechte mauer
  if Steine[R2].Left < 480 then
   begin
     if key = VK_Right then
      Steine[R2].Left:=Steine[R2].Left+10; // bewegt den stein nach rechts
   end
     else
      if key = VK_Right then
       begin
         Steine[R2].Left:=Steine[R2].Left+0 // setzt die bewegungsgeschwindigkeit auf 0, falls der stein zu weit rechts ist
       end;
       
   end
     else
      begin
        TimerStein.Enabled:=false; // deaktiviert, dass die steine fallen
        TimerSteineStehen.Enabled:=true; //aktiviert, dass die steine nicht fallen

        if key = VK_Down then
         begin
           Steine[R2].Top:=Steine[R2].Top+0 //setzt die fallgeschwindigkeit beim drücken von "runter" auf 0
         end;

        if key = VK_Left then
         begin
           Steine[R2].Left:=Steine[R2].Left+0
         end;

        if key = VK_Right then
         begin
           Steine[R2].Left:=Steine[R2].Left+0;
        end;
      end;
end;

//Steine bleiben stehen
procedure TForm1.TimerSteineStehenTimer(Sender: TObject);
begin
 Steine[R2].top:=Steine[R2].top+0; //setzt die fallgeschwindigkeit auf 0
end;

end.


Moderiert von user profile iconNarses: Bild als Anhang hinzugefügt

Ich hoffe ihr könnt mir helfen.

Grüße
Einloggen, um Attachments anzusehen!
Narses
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic star
Administrator
Beiträge: 10185
Erhaltene Danke: 1261

W11x64
TP3 .. D7pro .. D10.2CE
BeitragVerfasst: Mo 16.06.08 17:44 
Moin und :welcome: im Forum!

user profile iconFrost hat folgendes geschrieben:
Also, ich hab' mir vorgenommen Tetris zu programmieren. Lief auch ganz gut bis jetzt.
Ähm :? du unterschätzt möglicherweise etwas die Komplexität von Tetris... :| das sieht ja vielleicht ganz simpel aus, aber das programmiert man nicht mal eben zwischen Hauptgericht und Nachtisch. ;)

user profile iconFrost hat folgendes geschrieben:
Also wie könnte ich das anders machen?
Dein Ansatz über Images für die Steine ist - für den Anfang jedenfalls - nicht so gut gewählt. Stichwort: Kollisionserkennung! :shock: Kurz, so wird das nix. :(

Ich würde dir raten, dich vielleicht erstmal mit einem anderen Spiel zu beschäftigen, vielleicht ist 4-Gewinnt ja eine Herausforderung für dich. :idea: ;)

cu
Narses

_________________
There are 10 types of people - those who understand binary and those who don´t.
Hidden
ontopic starontopic starontopic starontopic starontopic starontopic starofftopic starofftopic star
Beiträge: 2242
Erhaltene Danke: 55

Win10
VS Code, Delphi 2010 Prof.
BeitragVerfasst: Mo 16.06.08 19:29 
Hi,
user profile iconNarses hat folgendes geschrieben:
das sieht ja vielleicht ganz simpel aus, aber das programmiert man nicht mal eben zwischen Hauptgericht und Nachtisch. ;)
Da hst du aber mein Interesse geweckt ;) Sehe jetzt nicht das Problem, hier mal mein Ansatz.

Man müsste nurnoch einen Timer laufen lassen und die einzelnen Stücke eines Steins jeweils um eins nach unten verschieben, bis die entsprechende function false zurückgibt. Dann setzt man die entsprechenden Stellen im Labyrinth und entspr GameOver-Test(beim Setzen eines Bits über Labyrinthhöhe.

Zum Drehen müsste man jeweils einen Drehpunkt definieren.
ausblenden volle Höhe Delphi-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:
unit mLogik;

interface

uses
  Windows;

const
  FeldBreite = 9;
  FeldHoehe = 19;

type
  PSpielfeld = ^TSpielfeld;
  TSpielfeld = Array[0..FeldBreite, 0..FeldHoehe] of Boolean;
  PStein = ^TStein;
  TStein = Array of TPoint;

function ReiheVoll(aReihe: Integer; Game: PSpielfeld): Boolean;
function SteinKannWeiter(S: PStein; Game: PSpielfeld): Boolean;
procedure LoescheVolleReihen(Game: PSpielfeld);
procedure LoescheReihe(aReihe: Integer; Game: PSpielfeld);

implementation

function ReiheVoll(aReihe: Integer; Game: PSpielfeld): Boolean;
var
  i: Integer;
begin
  result := true;
  for i := 0 to FeldBreite do begin
    if not Game^[i, aReihe] then begin
      result := false;
      Exit;
    end;
  end;
end;

function SteinKannWeiter(S: PStein; Game: PSpielfeld): Boolean;
var
  i: Integer;
begin
  result := true;
  for i := 0 to High(S^) do begin
    if Game^[S^[i].X, Pred(S^[i].Y)] then
      result := false;
      Exit;
  end;
end;

procedure LoescheVolleReihen(Game: PSpielfeld);
var
  i: Integer;
begin
  for i := 0 to FeldHoehe do begin
    if ReiheVoll(i, Game) then
      LoescheReihe(i, Game);
  end;
end;

procedure LoescheReihe(aReihe: Integer; Game: PSpielfeld);
var
  i, j: Integer;
begin
  for i := aReihe to FeldHoehe - 1 do begin
    for j := 0 to FeldBreite do
      Game^[i, j] := Game^[i, Succ(j)];
  end;
  for j := 0 to FeldBreite do
    Game^[FeldHoehe, j] := false;
end;

end.


mfG,

_________________
Centaur spears can block many spells, but no one tries to block if they see that the spell is a certain shade of green. For this purpose it is useful to know some green stunning hexes. (HPMoR)
Narses
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic star
Administrator
Beiträge: 10185
Erhaltene Danke: 1261

W11x64
TP3 .. D7pro .. D10.2CE
BeitragVerfasst: Mo 16.06.08 20:21 
Moin!

user profile iconHidden hat folgendes geschrieben:
Sehe jetzt nicht das Problem,
Ich sehe da einen Haufen Probleme... ;)

user profile iconHidden hat folgendes geschrieben:
hier mal mein Ansatz.
Dein "Ansatz" ist wohl eher nur ein Ansätzchenleinklein... :P Was ist mit
  • der Stein-Implementation (oder besser Cluster-Implementation)
  • Drehen der Cluster
  • Visualisierung des Spielfeldes
  • Startposition-und-Cluster-Drehen-Problem
  • Performance (nicht zuletzt der Visualisierung)
nur um mal ein paar der wirklichen Probleme zu nennen. :mrgreen: Die Logik, die du abgebildet hast, ist nicht das Problem... :tongue:

Vorsorglich: das hier soll kein Tetris-Wettbewerb werden und es geht auch immer noch um das Problem (die Probleme? :?) von user profile iconFrost. Bitte jetzt keine Quelltext-Schlachten und Machbarkeitsbeweise liefern, OK? :| Falls es jemanden in den Fingern juckt, bitte einen eigenen Thread aufmachen, danke. :)

cu
Narses

_________________
There are 10 types of people - those who understand binary and those who don´t.
Frost Threadstarter
Hält's aus hier
Beiträge: 4



BeitragVerfasst: Mo 16.06.08 22:45 
Na ja, ich hab mir schon fast gedacht, dass mein Ansatz das Thema verfehlt hat.
Nun hab ich gerade ein Einspieler-PingPong programmiert - funktioniert (fast) einwandfrei. Aber genug davon, ich will ja nicht so sehr offtopic gehen.^^
Als ich mir n paar mehr gedanken über Tetris gemacht hab ist mir auch aufgefallen, dass ich das wohl so nicht weiter kriege.
Aber ich werde mir mal weiter Gedanken machen und aufschreiben, wie ich das am besten angehe und mir dann nen "Schlachtplan" entwickeln. xD
Dann kann ich hier ja auch genauere Fragen stellen.
Bin natürlich für jegliche Art von Tipps offen. :)

ps: Man könnte theoretisch auch einen "Tetris-Wettbewerb"-Thread machen. :D Aber ich denke das wäre wohl zuviel Spam, oder?


Zuletzt bearbeitet von Frost am Di 17.06.08 13:46, insgesamt 2-mal bearbeitet
Narses
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic star
Administrator
Beiträge: 10185
Erhaltene Danke: 1261

W11x64
TP3 .. D7pro .. D10.2CE
BeitragVerfasst: Mo 16.06.08 23:03 
Moin!

user profile iconFrost hat folgendes geschrieben:
Aber ich werde mir mal weiter Gedanken machen und aufschreiben, wie ich das am besten angehe und mir dann nen "Schlachtplan" entwickeln. xD
Dann kann ich hier ja auch genauere Fragen stellen.
Selbstverständlich. ;)

user profile iconFrost hat folgendes geschrieben:
ps: Man könnte theoretisch auch einen "Tetris-Wettbewerb"-Thread machen. :D Aber ich denke das wäre wohl zuviel Spam, oder?
Nun, einen konkreten Wettbewerb müssten wir zunächst mal im Team der EE besprechen; aber wie gesagt, jeder darf gerne seine Tetris-Implementatin hier in einem eigenen Thread vorstellen. :)

cu
Narses

_________________
There are 10 types of people - those who understand binary and those who don´t.
Hidden
ontopic starontopic starontopic starontopic starontopic starontopic starofftopic starofftopic star
Beiträge: 2242
Erhaltene Danke: 55

Win10
VS Code, Delphi 2010 Prof.
BeitragVerfasst: Mo 16.06.08 23:03 
user profile iconFrost hat folgendes geschrieben:
ps: Man könnte theoretisch auch einen "Tetris-Wettbewerb"-Thread machen. :D Aber ich denke das wäre wohl zuviel Spam, oder?
Spam bestimmt nciht ;) Wenn jemand Lust hat. Ich war nur ein wenig neugierig, wenn man das so nennen kann. Allzuviel Zeit wollte ich da jetzt nicht rein investieren, insofern mit mir nicht.

mfG,

_________________
Centaur spears can block many spells, but no one tries to block if they see that the spell is a certain shade of green. For this purpose it is useful to know some green stunning hexes. (HPMoR)