Pohyb kurzoru – Delphi – Fórum – Programujte.com
 x   TIP: Přetáhni ikonu na hlavní panel pro připnutí webu

Pohyb kurzoru  – Delphi – Fórum – Programujte.comPohyb kurzoru – Delphi – Fórum – Programujte.com

 

Skornos0
Newbie
18. 5. 2010   #1
-
0
-

Zdravím!

Pracuju na hře, ve které by se měl kurzor pohybovat po hrací ploše a nepřesáhnout hranice předem dané cesty. Mapy a cesty si může uživatel tvořit sám pomocí textového souboru, který má 20 řádků a sloupců a 0 přestavuje plné okno takže zátaras a 1 volnou cestu. Začnete výběrem mapy, kliknete na tlačítko a tím se vykreslí mapa a panáček/kurzor se přesune na danou pozici, která je volná. Problém, který teď řeším je, jak ošetřit, aby při překročení vymezené hranice byl konec hry. V uvedeném zdrojovém kódu se to snažím dělat tak, že si načítám znaky textového souboru a dokud je 0, tak se nic neděje, ale jamile se objeví v cestě 1, tak chci zaznamenat souřadnici právě té předcházející 0, ale netuším, jak na to. Předem děkuju

unit Unit1;


interface

uses
Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
Dialogs, Menus, ExtCtrls, StdCtrls, jpeg;

type
TForm1 = class(TForm)
OpenDialog1: TOpenDialog;
MainMenu1: TMainMenu;
Button1: TButton;
MMOtevri: TMenuItem;
procedure MMOtevriClick(Sender: TObject);
procedure FormCreate(Sender: TObject);
procedure Button1Click(Sender: TObject);
procedure FormMouseMove(Sender: TObject; Shift: TShiftState; X,
Y: Integer);
private
polec:array [1..20,1..20] of integer;
poleo:array [1..20,1..20] of TImage;
x,y:integer;
{ Private declarations }
public
{ Public declarations }
end;

var
Form1: TForm1;
Poloha : Tpoint;
f:textfile;
z:char;
i,j:integer;
implementation

{$R *.dfm}

procedure TForm1.MMOtevriClick(Sender: TObject); //otevírá obrázek

begin

{otevírání souboru a načítání znaků do polec}

if opendialog1.Execute then assignFile(f,opendialog1.FileName);
reset(f);
button1.Enabled:=true; //at neaktivuju mapu před načtením
j:=1;
while not eof(f) do begin
i:=1;
while not eoln(f) do begin
read (f,z);
polec[i,j]:=strtoint(z);
i:=i+1;
end;
readln(f);
j:=j+1;
end;

{zjištění souřadnic hranice mezi 0 a 1}
{j:=0;
for j:=1 to 20 do begin
i:=1;
while polec[i,j]=0 do i:=i+1;}
//zjistit pozici kurzoru

closefile(f);
end;

procedure TForm1.FormCreate(Sender: TObject);
begin
Button1.Enabled:=false;
end;

procedure TForm1.Button1Click(Sender: TObject);

var i,j:integer;
kurzor: THandle;
cesta: PChar;
begin
Poloha.X:=Left+295;
Poloha.Y:=Top+100;

i:=0;
j:=0;
for i:=1 to 20 do begin
for j:=1 to 20 do
begin
poleo[i,j]:=TImage.create(self);
case polec[i,j] of
0: poleo[i,j].picture.bitmap.loadfromresourcename (HInstance, 'ZED');
1: poleo[i,j].picture.bitmap.loadfromresourcename (HInstance, 'PRAZDNO');
2: begin
poleo[i,j].Picture.LoadFromFile('finish.jpg');
end;
end;

poleo[i,j].Top:=j*28-28;
poleo[i,j].Left:=i*28+28;
poleo[i,j].parent:=self;
end;
end;

SetCursorPos (Poloha.X, Poloha.Y); //Poloha.X - horizontální pozice, Poloha.Y - vertikální pozice

cesta:=PChar('Pacman.cur');
kurzor:=LoadImage(0, cesta, IMAGE_CURSOR, 0, 0, LR_DEFAULTSIZE or LR_LOADFROMFILE);
Screen.Cursors[1] := kurzor;
Form1.Cursor := 1;
end;


procedure TForm1.FormMouseMove(Sender: TObject; Shift: TShiftState; X,
Y: Integer);
begin
GetCursorPos(Poloha);
end;

end.

Nahlásit jako SPAM
IP: 89.103.201.–
liborb
~ Redaktor
+18
Guru
18. 5. 2010   #2
-
0
-

Spíše než pole obrázků bych použil vykreslení do Canvasu. Obrázky zeď/volno vykresloval dle mapy hracího pole, tj. vždy s ofsetem daným rozměry obrázků. Pozici kurzoru pak stejným způsobem přepočítávat na hrací pole, kde zjistíš, jestli je to zeď nebo ne. Následně detekovat všechny stavy, které chceš.

Nahlásit jako SPAM
IP: 195.189.143.–
zdenda
~ Anonymní uživatel
257 příspěvků
18. 5. 2010   #3
-
0
-

Chápu správně, že chceš zjistit souřadnice/rozměry cesty a detekovat, když myš vyjede mimo?

Na to se vykašli a normálně přepočítej souřadnice kurzoru na souřadnice v hrací ploše, vyděl je velikostí políčka a dostaneš souřadnice (indexy) na mapě (polec). A pak jen otestuješ, co na tom místě je.

Nahlásit jako SPAM
IP: 213.211.51.–
zdenda
~ Anonymní uživatel
257 příspěvků
18. 5. 2010   #4
-
0
-

Jo, pardon, on už to liborb napsal. Splynulo mi to s curobotí reklamou.

Nahlásit jako SPAM
IP: 213.211.51.–
Skornos0
Newbie
18. 5. 2010   #5
-
0
-

Takže vykreslování pole přepíšu tak, že volno/zeď vždycky vykreslím pomocí Canvasu podle obsahu texťáku (0 nebo 1). Potom souřadnice kurzoru najdu zase pomocí GetCursorPos (ty se mi zjišťují při jakémkoliv pohybu myši po formuláři pomocí FormMouseMove) a vydělím je velikostí zdi/volné cesty a dále se ztrácím :(

Nahlásit jako SPAM
IP: 89.103.201.–
zdenda
~ Anonymní uživatel
257 příspěvků
19. 5. 2010   #6
-
0
-

No, dejme tomu, že platí máš toto:

Plocha := canvas cele herni plochy nebo prvni timage

plocha_min_x := 1; // rozmery mapy
plocha_min_y := 1;
plocha_max_x := 20;
plocha_max_y := 20;

sirkapolicka := 28; // rozmery jednoho policka herni plochy
vyskapolicka := 28;

GetCursorPos(mys);
Tak pak uděláš jen toto:
pos := Plocha.ScreenToClient(mys); // souradnice mysi v herni plose

x := plocha_min_x + (pos.X / sirkapolicka); // souradnice v mape
y := plocha_min_y + (pos.Y / vyskapolicka);

if x < plocha_min_x or x > plocha_max_x or y < plocha_min_y or y > plocha_max_y
then exit //mys neni nad herni plochou

if polec[x,y] = zed then bum; // test obsahu mapy

Nahlásit jako SPAM
IP: 213.211.51.–
Skornos0
Newbie
19. 5. 2010   #7
-
0
-

Děkuju, a ještě ta Plocha by měla být jaký datový typ?

Nahlásit jako SPAM
IP: 89.103.201.–
Skornos0
Newbie
19. 5. 2010   #8
-
0
-

Omluvám se za double post, ale nechcu, ať moje otázka upadne v zapomění

Nahlásit jako SPAM
IP: 89.103.201.–
zdenda
~ Anonymní uživatel
257 příspěvků
19. 5. 2010   #9
-
0
-

Máš akvárko? :smile1:

Jednak jsem to tam napsal, druhak se to dá snadno zjistit, a nakonec ji ani nepotřebuješ. Neopisuj to bezhlavě a zkus to pochopit, je to jen pár řádků a ještě mockrát se ti to bude hodit.

Nahlásit jako SPAM
IP: 213.211.51.–
Anonymní uživatel
~ Anonymní uživatel
0 příspěvků
29. 5. 2010   #10
-
0
-

Zdravím!

Tak můj současný kód vypadá takto:



unit Unit1;

interface

uses
Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
Dialogs, Menus, ExtCtrls, StdCtrls, jpeg;


type

TForm1 = class(TForm)
OpenDialog1: TOpenDialog;
MainMenu1: TMainMenu;
MMOtevri: TMenuItem;
procedure MMOtevriClick(Sender: TObject);
procedure FormMouseMove(Sender: TObject; Shift: TShiftState; X,
Y: Integer);
private
polec:array [1..20,1..20] of integer;
poleo:array [1..20,1..20] of TImage;
x,y:integer;
{ Private declarations }
public
{ Public declarations }
end;

var
Form1: TForm1;
Poloha, mys : Tpoint;
f:textfile;
z:char;
i,j:integer;
Plocha_min_x,Plocha_min_y,Plocha_max_x,Plocha_max_y:integer;
a,b:real;
implementation

{$R *.dfm}

procedure TForm1.MMOtevriClick(Sender: TObject); //otevírá obrázek
var i,j:integer;
kurzor: THandle;
cesta: PChar;
pos:TPoint;


begin


{otevírání souboru a načítání znaků do polec}

if opendialog1.Execute then assignFile(f,opendialog1.FileName);
reset(f);
j:=1;
while not eof(f) do begin
i:=1;
while not eoln(f) do begin
read (f,z);
polec[i,j]:=strtoint(z);
i:=i+1;
end;
readln(f);
j:=j+1;
end;
closefile(f);

mys.X:=Left+270;
mys.Y:=Top+100;
Plocha_min_x:=Form1.Left;
Plocha_min_y:=Form1.Top;
Plocha_max_x:=Form1.Left+i*24+24;
Plocha_max_y:=Form1.Top+j*24+24;

Form1.Width:=Plocha_max_x;
Form1.Height:=Plocha_max_y;

i:=0;
j:=0;
for i:=1 to 20 do begin
for j:=1 to 20 do
begin
poleo[i,j]:=TImage.create(self);
case polec[i,j] of
0: begin
{poleo[i,j].Canvas.Brush.Color:=clblack;
poleo[i,j].Canvas.Pen.Color:=clblack;
poleo[i,j].Canvas.Rectangle(29*i-28,29*i-28,(29*i-28)+26,(29*i-28)+26); //platné pro první sloupec }
poleo[i,j].Picture.Bitmap.loadfromresourcename (HInstance, 'ZED');
end;
1: begin
{poleo[i,j].Canvas.Brush.Color:=clwhite;
poleo[i,j].Canvas.Pen.Color:=clwhite;
poleo[i,j].Canvas.Rectangle(i,j,i+24,j+24); }
poleo[i,j].Picture.Bitmap.loadfromresourcename (HInstance, 'PRAZDNO');
end;
2: begin
poleo[i,j].Picture.LoadFromFile('finish.jpg');
end;
end;

poleo[i,j].Top:=j*24-24;
poleo[i,j].Left:=i*24+24;
poleo[i,j].parent:=self;
end;
end;




SetCursorPos (mys.X, mys.Y);

cesta:=PChar('Pacman.cur');
kurzor:=LoadImage(0, cesta, IMAGE_CURSOR, 0, 0, LR_DEFAULTSIZE or LR_LOADFROMFILE);
Screen.Cursors[1] := kurzor;
Form1.Cursor := 1;

end;

procedure TForm1.FormMouseMove(Sender: TObject; Shift: TShiftState; X,
Y: Integer);
begin
Form1.ScreenToClient(Poloha);
a := Plocha_max_x + (mys.X / 24);
b := Plocha_max_y + (mys.Y / 24);

if (a < Plocha_min_x) or (a > Plocha_max_x) or (b < Plocha_min_y) or (b > Plocha_max_y)
then showmessage('KONEC');

end;

end.


Řeším teď problém, proč při prvním zapnutí se mi formulář vykreslí v pořádku, ale při každém dalším se x-ová i y-ová souřadnice levého horního rohu o něco zvětší takže se posune a navíc se zvětší i samotný formulář, ale to všechno jenom 10x a pak zase je na původním místě

Nahlásit jako SPAM
IP: 89.103.201.–
zdenda
~ Anonymní uživatel
257 příspěvků
30. 5. 2010   #11
-
0
-

Zase máš zmatek v souřadnicích.

Nahlásit jako SPAM
IP: 213.211.51.–
Skornos0
Newbie
30. 5. 2010   #12
-
0
-

páni, díky moc, už jsem se v tom zorientoval a více to chápu :)

Nahlásit jako SPAM
IP: 89.103.201.–
Skornos0
Newbie
20. 6. 2010   #13
-
0
-

Předělal jsem to podle Zdendy (díky moc, ta grafika je taky super), ale ted jsem zjistil, že mi to nečte souřadnice myši, když jezdím po tom poli ale jenom mimo něho. Bordel v souřadnicích bych už neměl mít.

Nahlásit jako SPAM
IP: 89.103.201.–
zdenda
~ Anonymní uživatel
257 příspěvků
21. 6. 2010   #14
-
0
-

Vytvoření obrázků (TImage) a nastavení jejich OnMouseMove už je ve FormCreate.
Při načítání mapy v MMOtevriClick vytváříš nové obrázky - ten řádek vyhoď.

Předpokládám, že zatím jen zkoušíš a do finální verze to ještě pročistíš, ale připomenu jednu věc - Width a Height formuláře není to, co chceš nastavovat. Třeba výška zahrnuje i menu (a to může být různě velké). Použij ClientWidth a ClientHeight.

Nahlásit jako SPAM
IP: 213.211.51.–
Skornos0
Newbie
21. 6. 2010   #15
-
0
-

Už to funguje, díky za tu radu s ClientWidth, vůbec jsem si to neuvědomil :) tak ted už to zmáknu dodělat, vážně moc díky

Nahlásit jako SPAM
IP: 89.103.201.–
Zjistit počet nových příspěvků

Přidej příspěvek

Toto téma je starší jak čtvrt roku – přidej svůj příspěvek jen tehdy, máš-li k tématu opravdu co říct!

Ano, opravdu chci reagovat → zobrazí formulář pro přidání příspěvku

×Vložení zdrojáku

×Vložení obrázku

Vložit URL obrázku Vybrat obrázek na disku
Vlož URL adresu obrázku:
Klikni a vyber obrázek z počítače:

×Vložení videa

Aktuálně jsou podporována videa ze serverů YouTube, Vimeo a Dailymotion.
×
 
Podporujeme Gravatara.
Zadej URL adresu Avatara (40 x 40 px) nebo emailovou adresu pro použití Gravatara.
Email nikam neukládáme, po získání Gravatara je zahozen.
-
Pravidla pro psaní příspěvků, používej diakritiku. ENTER pro nový odstavec, SHIFT + ENTER pro nový řádek.
Sledovat nové příspěvky (pouze pro přihlášené)
Sleduj vlákno a v případě přidání nového příspěvku o tom budeš vědět mezi prvními.
Reaguješ na příspěvek:

Uživatelé prohlížející si toto vlákno

Uživatelé on-line: 0 registrovaných, 2 hosté

Podobná vlákna

Sledování kurzoru — založil Jakub Vojáček

Zmena kurzoru — založil giro

Změna kurzoru — založil Pavel Synek

 

Hostujeme u Českého hostingu       ISSN 1801-1586       ⇡ Nahoru Webtea.cz logo © 20032024 Programujte.com
Zasadilo a pěstuje Webtea.cz, šéfredaktor Lukáš Churý