Entwickler-Ecke

Open Source Projekte - Kleines Tennisspiel


Karlson - Mo 18.10.04 00:42
Titel: Kleines Tennisspiel
Moin,

Ich hatte heute zuviel Zeit und hab mich mal hingesetzt und versucht ein kleines Tennisspiel zu schreiben.

Das ist bei rausgekommen, für Anfänger bestimmt ganz intressant.

http://www.8ung.at/forumwatcher/Tennis.rar


.Chef - Mo 18.10.04 09:28

Ich habs mir mal angeschaut, und muss leider sagen, dass es durch zuviele Bugs unspielbar ist:

- Der Ball verfängt sich gelegentlich im(!) Schläger und bleibt drin hängen.
- Wenn ich das Optionsfenster öffne, wird mein Schläger sehr klein, so dass ich danach nicht mehr spielen kann. Also er wird auch nicht wieder groß, wenn ich das Fenster schließe.
- Du solltest unbedingt einbauen, dass man durch die Schlägerbewegung Einfluss auf die Flugrichtung des Balles nehmen kann. So, wie es jetzt ist, prallt der Ball einfach nur ab, egal, was man macht, und es ist nicht möglich, seinen Gegner auszuspielen.

Und nochn Tipp: WIe ich sehe, hast du ein Panel als Ball. Setz doch ein rundes Shape auf das Panel. ;-)

Gruß,
Jörg


Karlson - Mo 18.10.04 15:52

Hi Jörg,

zu 1.) Stimmt, das ist sche****, es liegt daran das ich die X-Fläche der Schläger nicht abfrage.

zu 2.) Ja :mrgreen: Tu mir denGefallen und schau dir den Code an und sag mir warum dieser verdammte Schläger klein wird. Entweder seh ich den Wald vor lauter Bäumen nicht mehr oder ich bin einfach nur blöd ;) Ich hab ne halbe Stunde in dem (wirklich kleinem) Code gesucht, finde aber den Fehler nicht...kein Wunder bei dem Saustall im Quellcode. :rolleyes:

zu 3.) Das wäre wirklich gut aber mir ging es nicht darum ein schönes Spiel zu schreiben. Es geht allgemein um die Bewegung des Balls und wie er auf Schläger und Wand reagiert. Das wäre schon cool wenn man auf die Ballbewegung Einfluss nehmen könnte, aber mein Vorbildspiel hat so eine funktion auch nicht :)

Vielleicht hat ja jemand Lust am Programm weiterzuarbeiten, der kann das ja dann umsetzten.


gruss


.Chef - Mo 18.10.04 20:03

Zu 2.)Ich tippe mal ganz stark auf eine der zwei(!) Stellen in Unit2, wo du die Panel-Höhe des linken Schlägers einstellst.


GTA-Place - Mo 18.10.04 20:38

1. Was soll den Trackbar4, wenn die unsichtbar ist??

2.procedure TForm2.TrackBar5Change(Sender: TObject);
Es gibt keine TrackBar5.

3.

Delphi-Quelltext
1:
2:
3:
4:
procedure TForm1.Button2Click(Sender: TObject);
procedure TForm1.Button3Click(Sender: TObject);
procedure TForm1.Button4Click(Sender: TObject);
procedure TForm1.Button5Click(Sender: TObject);

Es gibt keinen Button2, Button3, Button4 und Button5.

4.

Delphi-Quelltext
1:
2:
procedure SetPort(address, Value: Word);
function GetPort(address: Word): Word;

Wieso denn einfach, wenns auch kompliziert geht. Muss das über den internen PC-Lautsprecher sein?

5. 2 Timer und 1 Label sind umsonst.

6. Ich hab mit Formatierung aus ca. 270 Zeilen, genau 150 Zeilen gemacht.

7. Gib doch den Panels und Buttons und sonst was Namen. Ich hasse es, wenn die alle keinen Namen haben.


Karlson - Mo 18.10.04 23:04

GTA-Place hat folgendes geschrieben:
1. Was soll den Trackbar4, wenn die unsichtbar ist??

2.procedure TForm2.TrackBar5Change(Sender: TObject);
Es gibt keine TrackBar5.

3.

Delphi-Quelltext
1:
2:
3:
4:
procedure TForm1.Button2Click(Sender: TObject);
procedure TForm1.Button3Click(Sender: TObject);
procedure TForm1.Button4Click(Sender: TObject);
procedure TForm1.Button5Click(Sender: TObject);

Es gibt keinen Button2, Button3, Button4 und Button5.

4.

Delphi-Quelltext
1:
2:
procedure SetPort(address, Value: Word);
function GetPort(address: Word): Word;

Wieso denn einfach, wenns auch kompliziert geht. Muss das über den internen PC-Lautsprecher sein?

5. 2 Timer und 1 Label sind umsonst.

6. Ich hab mit Formatierung aus ca. 270 Zeilen, genau 150 Zeilen gemacht.

7. Gib doch den Panels und Buttons und sonst was Namen. Ich hasse es, wenn die alle keinen Namen haben.


Stimmt schon alles, aber die meisten Objekte wie die 2 Timer und das Label und die paar Buttons hab ich während dem Programmieren für Tests benutzt. Wie ich oben bereits schrieb, geht es um die grobe Kolisionabfrage usw, der Rest ist doch ganz ehrlich scheissegal.

Die Beschriftungen hätte ich machen können, aber es sollte doch hoffentlich nicht zu schwer sich vier verschiedenen Panels zu merken.


F34r0fTh3D4rk - Fr 04.02.05 17:20

bei mir ist das fenster zu groß ich kann den rechten schläger net sehen, ansonsten war das problem mit dem hängenbleiben bei meinem tennis auch, aber die lösung funzt irgendwie net und bei mir ist der ball auch manchmal durchgebrochen


araX - Fr 04.02.05 17:51

Schade das der DL nicht mehr funktioniert


uall@ogc - Fr 04.02.05 18:01

der download funktioniert bei mir noch, aber "lohnend" isses nicht gerade (hoffe ich greif niemanden an ;>)


Karlson - Fr 04.02.05 18:18

Ne es is wirklich nicht lohnend :lol:

Habs mir auch grad mal wieder angeschaut, und es ist sche**** geworden...


F34r0fTh3D4rk - Fr 04.02.05 21:07

mit tastatur steuerung ist eh besser ^^

ist es möglich eine art bot dafür zu schreiben also ein externes cheat tool welches die position des balls erkennt und automatisch mit einer tastendruck simulation reagiert ?


en!gma - Fr 04.02.05 21:48

naja ok für anfänger? =)
ich weiss nich, hab mir den code nich angeschaut, aber wenn wirklich noch überflüssige buttons usw drin sind,
werden die anfänger wohl doch nur mehr verwirrt als alles andere.

und
@F34r0fTh3D4rk:
sollte eigentlich gehen, aber was für ein tastendruck? läuft doch mit der maus


F34r0fTh3D4rk - Fr 04.02.05 21:50

meines aber net ^^


Karlson - Fr 04.02.05 21:50

Klar, warum sollte das nicht möglich sein?

Die Adresse für den Top liegt bei mir bei $BF4A78
Die Adresse für die Left liegt bei $BF4A74

@en1gma: Mit Anfängern meinte ich nicht das Programm, sondern wie ich auch schonmal schrieb den Code für die Ballbewegung usw. Damit habe ich auch angefangen. Hab erst aus Spass einen Ball rumfliegen lassen, dann noch einen Schläger dazu, dann noch einen Schläger, dann eine KI :lol: Dementsprechend sieht das alles auch aus. Intressant ist im Grunde nur der Code des Timer1.


F34r0fTh3D4rk - Fr 04.02.05 21:52

und wie lese ich die aus ?

wie man sie verändert weiß ich (gibt aber bestimmt fehler :D)


Karlson - Fr 04.02.05 21:53

F34r0fTh3D4rk hat folgendes geschrieben:
und wie lese ich die aus ?

wie man sie verändert weiß ich (gibt aber bestimmt fehler :D)


Nö, eigentlich nicht. Der Timer überprüft ja jedesmal aufs neue. Ich habs nicht ausprobiert, aber es müsste klappen.

Auslesen mit Suche in: Delphi-Forum, Delphi-Library READPROCESSMEMORY


en!gma - Fr 04.02.05 21:54

mit Suche in: Delphi-Forum, Delphi-Library READPROCESSMEMORY

//edit
1. ups zu spät
2. und dann auch noch falsch geschrieben ;D


F34r0fTh3D4rk - Fr 04.02.05 21:55

mit fehler meine ich dass es net geht, grade wegen des timers


unter readprocessmemory findet er nischt :?


Karlson - Fr 04.02.05 21:58

F34r0fTh3D4rk hat folgendes geschrieben:
mit fehler meine ich dass es net geht, grade wegen des timers

Auswelchem Grunde sollte es nicht gehen? Du könntest du Adresse ja mal nopen, dann bleibt der Ball hängen. Genauso kannst du die Adressen doch auch umschreiben. Der Timer verändert die Ballpos. ja mit ball.left := ball.left + 1. Ob da jetzt in der letzen millisekunde ein Sprung gemacht wurde, ist dem Timer ja wurscht.


F34r0fTh3D4rk - Fr 04.02.05 21:58

lol die suche geht nimmer :o


Karlson - Fr 04.02.05 21:59

Findet bei mir 37 Einträge :?


F34r0fTh3D4rk - Fr 04.02.05 21:59

ich finde keinen beitrag weil die suche bei mir nicht mehr geht :roll:


Karlson - Fr 04.02.05 22:17

Zitat:
Orginal geschrieben von Obstkutsche

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:
var   
 Read: DWORD;   
 OldProtect: DWORD;   
 Buf: Pointer;   
begin   
 // Lese & Schreibrechte holen   
 if VirtualProtectEx(Prozess, Adresse, Groesse, PAGE_EXECUTE_READWRITE, OldProtect) then   
 begin   
  // Speicher reservieren   
  getmem(Buf, Groesse);   
  try   
   // Daten lesen   
   if ReadProcessMemory(Prozess, Adresse, Buf, Groesse, Read) then   
    if Read = Groesse then   
    begin   
     // Spaß haben   
    end;   
  finally   
   // Wieder alte Rechte setzen   
   VirtualProtectEx(Prozess, Adresse, Groesse, OldProtect, OldProtect)   
   freemem(Buf);   
  end;   
 end;   
end;



Na dann will ich mal nicht so sein ;)


F34r0fTh3D4rk - Fr 04.02.05 22:20

was kommt bei spass haben rein und welcher wert (also von welcher speicheradresse) wird jetzt an welche variable übergeben ?


F34r0fTh3D4rk - Fr 04.02.05 22:21

achso spass haben, da kommt rein was man damit macht und der rest ist einsetzen oda ?
kannst mal n beispiel geben, was muss zb bei größe rein ?

der titel das programms zum testen ist bei mir galgenmännchen, die adresse ist:

45FCCC

Den Wert möchte ich gerne auslesen


Karlson - Fr 04.02.05 23:35

Ich hab mal vor ein paar Monaten die Function gebraucht. ich habs damals irgendwie hingekriegt, weiss aber noch das dass ein ziemliches gewurschtel war. Ich glaub so in der Richtung:


Delphi-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:
16:
17:
18:
19:
20:
21:
procedure TForm1.Button1Click(Sender: TObject);
var fensterhandle, processhandle : THandle;
    ProcessID : Cardinal;
    puffer : array of byte;
    read : cardinal;
    i : integer;
begin
 fensterhandle := FindWindow(nil'Project1');
 Getwindowthreadprocessid(Fensterhandle, @Processid);
 processhandle := OpenProcess(PROCESS_ALL_ACCESS, false, ProcessId);
 setLength(puffer, 4);
  readprocessmemory(processhandle, ptr($BF4A78),puffer, 4, read);
 if read = 4 then
  begin
  for i := 0 to length(puffer) do
   begin
    memo1.lines.add(inttostr(puffer[i]));
 end;
 end;
end;
end;


*ungetestet* bin mir auch absolut nicht mehr sicher. :oops:


uall@ogc - Fr 04.02.05 23:39

1. um readprocessmemory muss kein try, lieber checken ob die anzahl der bytes die gelesen wurden (letzer parameter) mit denen übereinstimmt die gelesen werden sollten

2. $BF4A78 liegt ausserhalb des speicherbereiches der EXE, wird somit sehr wahrscheinlich mit HeapAlloc freigemacht und ist deshalb auch bei unterschiedlichen system anders (letzen 2 bytes werden gleich sein, da nur die ersten die page angeben)


Karlson - Fr 04.02.05 23:43

okay. Hab das mal soweit geändert. merci!
Preisfrage die ich mich schon immer gefragt habe: Wenn unsere Adresse ausserhalb dem Bereich der Exe liegt (woran siehst du das überhaupt? :lol: ), wie kann man diese dann überhaupt mit einem Trainer ansprechen?


uall@ogc - Fr 04.02.05 23:46

normalerweise (bei 99.99% aller EXE dateien) ist die standart base adresse bei 0x00400000 und dein BF ist weit davon weg ;> so groß kann die exe nicht sein


Karlson - Fr 04.02.05 23:52

okay, klingt logisch...und die andere Frage? :lol:


uall@ogc - Fr 04.02.05 23:55

irgendwo gibt es im speicher der EXE eine variable die auf den den allocierten speicher zeigt, oder api hook auf HeapAlloc etc. blub bla halt, 1000 wege sehr kompliziert und lange zu erklären


Karlson - Sa 05.02.05 00:33

mkay...dann wirds doch etwas schwerer das Spiel zu manipulieren ;)


F34r0fTh3D4rk - Sa 05.02.05 13:12

ok wenn ich diese procedure nehme kommt in mein memo sowas:


Quelltext
1:
2:
3:
4:
5:
0
0
0
0
140


der wert 0 ist korrekt aber was soll der rest ?

ich möchte schließlich nur einen integer auslesen um da nen bot für zu machen :?

also der 1. wert ist immer der gesuchte ?

ich hab das mal so gemacht:


Delphi-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:
16:
17:
function ReadProcess(Title: string; Address: integer): integer;
var
 winhandle, processhandle : THandle;
 ProcessID : Cardinal;
 puffer : array of byte;
 read : cardinal;
begin
 winhandle := FindWindow(nil, pchar(Title));
 Getwindowthreadprocessid(winhandle, @Processid);
 processhandle := OpenProcess(PROCESS_ALL_ACCESS, false, ProcessId);
 setLength(puffer, 4);
  readprocessmemory(processhandle, ptr(Address),puffer, 4, read);
 if read = 4 then
  begin
    result:= puffer[0];
  end;
end;


aber da kommt völliger müll raus, warum ?

Moderiert von user profile iconraziel: Beiträge zusammengefasst


uall@ogc - Sa 05.02.05 13:33


Delphi-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:
16:
17:
18:
function ReadProcess(Title: string; Address: integer): integer;   
var   
 winhandle, processhandle : THandle;   
 ProcessID : Cardinal;   
 buffer : integer;   
 read : cardinal;   
begin   
  winhandle := FindWindow(nil, pchar(Title));   
  Getwindowthreadprocessid(winhandle, @Processid);   
  processhandle := OpenProcess(PROCESS_ALL_ACCESS, false, ProcessId);   
  if processhandle > 0 then
  begin 
    readprocessmemory(processhandle, pointer(Address),@buffer, sizeof(buffer), read);   
    if read = sizeof(buffer) then   
      result := buffer else result := 0;  
    closehandle(processhandle);
  end;
end;


F34r0fTh3D4rk - Sa 05.02.05 13:39

oh danke (hab ich wohl wieder etwas geschlampt :lol: )
funzt perfekt danke, der meister hats mal wieder hinbekommen :flehan:


Kraut - Mi 08.03.06 15:00

Der Link funktioniert nicht mehr =(