PDA

View Full Version : Help, with colisions



spyke00
26-11-2006, 03:16 AM
Hello programmers!

I'v Searched on the forum for a simple collision in delphiX, but i can't find something good.
i need something to my RPG, like tibia...
i need a colision to colide with rock's, wall's and more!

please help-me!

thx

a hug!

czar
26-11-2006, 03:45 AM
Well it depends on what you are doing. You don't provide much info

If you have a simple array of x and y coords where each cell hols one object then obviously before you move to a new cell you check if something else is in the next square.

You could also test the distance between objects - when they are very close then treat as a collision.

Another way would be to have a rectangle surrounding all of your objects. When you move check to see if one or more points fall within a rectangle. You could optimize this by only testing objects that are likely to be close.

There are many other ways of testing for collisions. Unless you are wanting to use some internal collision detection method most collision methods are independent of which graphics system you are using to display the objects.

spyke00
26-11-2006, 04:14 AM
well... my idea is:
Make a simple next block collider....
i need this to colide on wall.
anyone have an example?!

a huG

Traveler
26-11-2006, 12:06 PM
Have a looksee at the tiles and especially the platform tutorials on my site. They'll get you on your way.

spyke00
27-11-2006, 01:48 PM
THX brother!
i'v did it on myself!
i will post my source! a hug brothers!

buttt.... my problem now is select an NPC with mouse =( anyone can help with this?!
Unit Principal:

{
************************************************** **************
* BASE para um RPG tipo tibia *
* Criado por: Mauricio Barros Scotton[SpykE]. *
* Todos os direitos reservados a SpykeSoft 2006 *
* Por Favor, mantenha os cr?İditos *
************************************************** **************
}
unit Unit1;

interface

uses
Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs,
StdCtrls, ExtCtrls, Menus, DXClass, DXSprite, DXInput, DXDraws,
DXSounds;

type
//TILE pack rec. para os items existentes no mapa (?°rvores e etc...)
TTile = Packed Record
Textura: String;
Bloqueado: Boolean;
end;
//ImageSprite para os items existentes no mapa (ligado a PACK REC.) (?°rvores e etc...)
TLayerItems = class(TImageSprite)
private
FCounter: Double;
FS: Integer;
procedure Hit;
public
procedure DoMove(MoveCount: Integer); override;
end;
TForm1 = class(TForm)
Button1: TButton;
DXDraw: TDXDraw;
DXTimer1: TDXTimer;
DXSpriteEngine: TDXSpriteEngine;
DXInput: TDXInput;
DXImageList1: TDXImageList;
MAPA: TDXImageList;
OBJETOS: TDXImageList;
procedure DXTimer1Timer(Sender: TObject; LagCount: Integer);
procedure FormCreate(Sender: TObject);
procedure DXDrawInitialize(Sender: TObject);
procedure DXDrawMouseMove(Sender: TObject; Shift: TShiftState; X,
Y: Integer);
private
FMoveMode: Boolean;
MouseX, MouseY : Integer;
public
{ Public declarations }
end;

var
Form1: TForm1;
lcnam:string;
ItmXMax:integer=7;
ItmYMax:integer=8;
posx,posy:double;
mapsizex,mapsizey:integer;
//================================================== ======================
//====// Declara?ß?µes dos mapas //======
//================================================== ======================

Mapa_ITEM: Array[0..17, 0..17] of TTile;
//ch?£o
Mapa_CHAO: Array[0..17, 0..17] of INTEGER =(
(0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0),
(0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0),
(0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0),
(0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0),
(0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0),
(0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0),
(0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0),
(0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0),
(0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0),
(0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0),
(0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0),
(0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0),
(0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0),
(0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0),
(0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0),
(0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0),
(0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0),
(0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0) );

implementation

Uses
Unit_basics;

{$R *.dfm}
//================================================== ======================
//====// Tipos dos objetos utilizados //======
//================================================== ======================
type
TPlayer = class(TImageSprite)
protected
procedure DoCollision(Sprite: TSprite; var Done: Boolean); override;
procedure DoMove(MoveCount: Integer); override;
end;
//================================================== ======================
//====// Procedimentos do startamento de sprites ->delphiX //======
//================================================== ======================

procedure TLayerItems.Hit;
begin
//procedimento para dar hit em um objeto que sofreu a colis?£o
end;
procedure TPlayer.DoCollision(Sprite: TSprite; var Done: Boolean);
begin
if Sprite is TLayerItems then begin
//fazer algo ap??s detectar colis?£o
end;
Done := true;
end;
procedure TLayerItems.DoMove(MoveCount: Integer);
begin
inherited DoMove(MoveCount);
PixelCheck := True;
FCounter := FCounter + (100/1000)*MoveCount;

if not Collisioned then
begin
Inc(FS, MoveCount);
if FS>200 then Dead;
end;
end;
procedure TPlayer.DoMove(MoveCount: Integer);
var
sprite: Tsprite;
NX,NY:integer;
begin
inherited DoMove(MoveCount);

Collision;

if &#40;Form1.DXInput.Joystick.X<>0&#41; or &#40;Form1.DXInput.Joystick.Y<0>=0&#41; and &#40;ny>=0&#41; and &#40;nx<=mapsizex&#41; and &#40;ny<mapsizey>=0&#41; and &#40;ny>=0&#41; and &#40;nx<=mapsizex&#41; and &#40;ny<mapsizey>=0&#41; and &#40;ny>=0&#41; and &#40;nx<=mapsizex&#41; and &#40;ny<mapsizey>=0&#41; and &#40;ny>=0&#41; and &#40;nx<=mapsizex&#41; and &#40;ny<=mapsizey&#41; and &#40;CheckTile&#40;nx,ny&#41; = false&#41; then
X &#58;= X + 32;
end;
end;
PixelCheck&#58;=True;
Engine.X &#58;= -X+Engine.Width div 2-Width div 2;
Engine.Y &#58;= -Y+Engine.Height div 2-Height div 2;
posx&#58;=x;
posy&#58;=y;
end;

//================================================== ======================
//====// Procedimentos do delphi //======
//================================================== ======================
procedure TForm1.DXTimer1Timer&#40;Sender&#58; TObject; LagCount&#58; Integer&#41;;
begin

if not DXDraw.CanDraw then exit;
DXInput.Update;
if FMoveMode then
LagCount &#58;= 1000 div 60;
DXSpriteEngine.Move&#40;LagCount&#41;;
DXSpriteEngine.Dead;
DXDraw.Surface.Fill&#40;0&#41;;
DXSpriteEngine.Draw;
//coloca o cursor
DXImageList1.Items&#91;0&#93;.Draw&#40; DXDraw.Surface, MouseX, MouseY, 0 &#41;;
//impres?£o dos textos
DysplayText&#40;'FPS&#58; '+inttostr&#40;DXTimer1.FrameRate&#41;, BSClear, clWhite, 10, 0, 0&#41;;
DysplayText&#40;'Sprite&#58; '+inttostr&#40;DXSpriteEngine.Engine.AllCount&#41;, BSClear, clWhite, 10, 0, 15&#41;;
DysplayText&#40;'Draw&#58; '+inttostr&#40;DXSpriteEngine.Engine.DrawCount&#41;, BSClear, clWhite, 10, 0, 30&#41;;
DysplayText&#40;'X&#58;'+floattostr&#40;posx/32&#41;+'&#91;'+floattostr&#40;posx&#41;+'&#93;'+', Y&#58;'+floattostr&#40;posy/32&#41;+'&#91;'+floattostr&#40;posy&#41;+'&#93;', BSClear, clWhite, 10, 0, 60&#41;;
if FMoveMode then
DysplayText&#40;'Time mode&#58; 60 FPS', BSClear, clWhite, 10, 0, 45&#41;
else
DysplayText&#40;'Time mode&#58; Real time', BSClear, clWhite, 10, 0, 45&#41;;
//flip =D
DXDraw.Flip;
end;

procedure TForm1.FormCreate&#40;Sender&#58; TObject&#41;;
var
PlayerSPR&#58; TSprite;
i1,i2&#58;integer;
begin
mapsizex&#58;=17;
mapsizey&#58;=17;
DXDraw.cursor&#58;=crNone;
//LoadOneLayer&#40;123456789,i1,i2,50,true&#41;;

lcnam&#58;=extractfilepath&#40;application.ExeName&#41;;
//randomiza os objetos
Mapa_ITEM&#91;1,1&#93;.Textura&#58;='2';
Mapa_ITEM&#91;1,1&#93;.Bloqueado&#58;=true;
Mapa_ITEM&#91;16,1&#93;.Textura&#58;='2';
Mapa_ITEM&#91;16,1&#93;.Bloqueado&#58;=true;
Mapa_ITEM&#91;1,16&#93;.Textura&#58;='2';
Mapa_ITEM&#91;1,16&#93;.Bloqueado&#58;=true;
Mapa_ITEM&#91;16,16&#93;.Textura&#58;='2';
Mapa_ITEM&#91;16,16&#93;.Bloqueado&#58;=true;

&#123; Mapa_ITEM&#91;1,2&#93;.Textura&#58;='pilar1';
Mapa_ITEM&#91;1,2&#93;.Bloqueado&#58;=true;
Mapa_ITEM&#91;1,3&#93;.Textura&#58;='pilar2';
Mapa_ITEM&#91;1,3&#93;.Bloqueado&#58;=true;
Mapa_ITEM&#91;1,4&#93;.Textura&#58;='pilar3';
Mapa_ITEM&#91;1,4&#93;.Bloqueado&#58;=true;
Mapa_ITEM&#91;2,2&#93;.Textura&#58;='pilar1';
Mapa_ITEM&#91;2,2&#93;.Bloqueado&#58;=true;
Mapa_ITEM&#91;2,3&#93;.Textura&#58;='pilar2';
Mapa_ITEM&#91;2,3&#93;.Bloqueado&#58;=true;
Mapa_ITEM&#91;2,4&#93;.Textura&#58;='pilar3';
Mapa_ITEM&#91;2,4&#93;.Bloqueado&#58;=true; &#125;
&#123; for i1&#58;=0 to 7 do begin
for i2&#58;=0 to 8 do begin
randomize;
Mapa_ITEM&#91;i1,i2&#93;.Textura&#58;=random&#40;2&#41;;
if Mapa_ITEM&#91;i1,i2&#93;.Textura = 1 then
Mapa_ITEM&#91;i1,i2&#93;.Bloqueado&#58;=true;
end;
end; &#125;
//load no ch?£o
for i1&#58;=0 to 17 do begin
for i2&#58;=0 to 17 do begin
LoadOneLayer&#40;inttostr&#40;Mapa_CHAO&#91;i1,i2&#93;&#41;,i1,i2,-3,false&#41;
end;
end;
//load nos itens do ch?£o &#40;?°rvores e etc...&#41;
for i1&#58;=0 to 17 do begin
for i2&#58;=0 to 17 do begin
if &#40;Mapa_ITEM&#91;i1,i2&#93;.Textura <> '0'&#41;and &#40;Mapa_ITEM&#91;i1,i2&#93;.Textura <> ''&#41; then begin
LoadOneLayer&#40;Mapa_ITEM&#91;i1,i2&#93;.Textura,i1,i2,-2,true&#41;;
LoadOneLayer&#40;'Colisor',i1,i2,-1,true&#41;;
end;
end;
end;
//abre o jogador
PlayerSPR&#58;= TPlayer.Create&#40;DXSpriteEngine.Engine&#41;;
with TPlayer&#40;PlayerSPR&#41; do
begin
Image &#58;= DXImageList1.Items.Find&#40;'player_down'&#41;;
Height&#58;= 48; Width &#58;= 32;
Visible&#58;=true;
X &#58;= 0;
Y &#58;= 0;
Z &#58;= 2;
end;
end;

procedure TForm1.DXDrawInitialize&#40;Sender&#58; TObject&#41;;
begin
DXTimer1.Enabled &#58;= True;
end;

procedure TForm1.DXDrawMouseMove&#40;Sender&#58; TObject; Shift&#58; TShiftState; X,
Y&#58; Integer&#41;;
begin
MouseX &#58;= X;
MouseY &#58;= Y;
end;

end.


Unit de Fun?ß?µes

&#123;
************************************************** **************
* BASE para um RPG tipo tibia *
* Criado por&#58; Mauricio Barros Scotton&#91;SpykE&#93;. *
* Todos os direitos reservados a SpykeSoft 2006 *
* Por Favor, mantenha os cr?İditos *
************************************************** **************
&#125;
unit Unit_basics;

interface

uses
Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
Dialogs, DXDraws, DXSprite, DXClass, DXInput, StdCtrls, Buttons, ExtCtrls;

//da um load em apenas um SQM
Procedure LoadOneLayer&#40;tilename&#58;string;Xx,Yy,Zz&#58;integer;item &#58;boolean&#41;;
//imprime um texto na tela
Procedure DysplayText&#40;Texto&#58;String; Estilo&#58;TBrushStyle; Cor&#58;Tcolor; Tamanho,X,Y&#58;Integer&#41;;
//Checa um TILE no pac rec, e devolve se ele ?İ bloqueado ou n?£o;
Function CheckTile&#40;X,Y&#58;integer&#41;&#58;boolean;

//================================================== ======================
implementation
//================================================== ======================
Uses
Unit1;
//================================================== ======================
Function CheckTile&#40;X,Y&#58;integer&#41;&#58;boolean;
Begin
result&#58;= Mapa_ITEM&#91;X,Y&#93;.Bloqueado;
end;
Procedure DysplayText&#40;Texto&#58;String; Estilo&#58;TBrushStyle; Cor&#58;Tcolor; Tamanho,X,Y&#58;Integer&#41;;
Begin
with Form1.DXDraw.Surface.Canvas do begin
Brush.Style &#58;= Estilo;
Font.Color &#58;= cor;
Font.Size &#58;= tamanho;
Textout&#40;X, Y, Texto&#41;;
Release;
end;
end;

Procedure LoadOneLayer&#40;tilename&#58;string;Xx,Yy,Zz&#58;integer;item &#58;boolean&#41;;
begin
if item = false then begin
with TBackgroundSprite.Create&#40;Form1.DXSpriteEngine.Engi ne&#41; do begin
SetMapSize&#40;1,1&#41;;
Image &#58;=Form1.MAPA.Items.find&#40;tilename&#41;;
Height&#58;= 32; Width &#58;= 32;
Visible&#58;=true;
X &#58;= Xx*32;
Y &#58;= Yy*32;
Z &#58;= Zz;
end;
end
else
if item then begin
with TLayerItems.Create&#40;Form1.DXSpriteEngine.Engine&#41; do begin
Image &#58;=Form1.OBJETOS.Items.find&#40;tilename&#41;;
Height&#58;= 32; Width &#58;= 32;
Visible&#58;=true;
X &#58;= Xx*32;
Y &#58;= Yy*32;
Z &#58;= Zz;
end;
end
end;

end.


-------------------------
Some screens
http://img292.imageshack.us/img292/5655/fotogamels6.png
http://img73.imageshack.us/img73/8660/fotogame2vi9.png
http://img73.imageshack.us/img73/5917/fotoeditspritesqm5.png

Traveler
27-11-2006, 05:06 PM
The easiest way is to go through all visible sprites on the screen and check whether the mouse is over them while the mouse button is down.

czar
27-11-2006, 07:08 PM
Or, on mousedown store the X and Y coordinates - then when you come to draw each object you can test if the mouse clicked on that area.

You can also store store the x and y of the mouse in mousemove so when you draw the object if the mouse is above it you can draw a highlight or whatever to indicate to the user that they can click on that object.

As an aside - the FPS says 10 - have you limited the game to 10 FPS? Or have you got really low spec machine?

spyke00
27-11-2006, 07:30 PM
store i know but check where i clicked... thats the problem =/

Traveler
27-11-2006, 08:10 PM
I'm sorry, I kind of messed up you post there as I wanted to quote you, but instead I hit the edit button. I was able to save most of it, but the sentence with your system specs got lost. :(


store i know but check where i clicked... thats the problem =/

Hopefully I can make it up by giving you a solution



type TMyMouse = record
x &#58; word;
y &#58; word;
clickX &#58; word;
clickY &#58; word;
button &#58; TMouseButton;
pressed &#58; boolean;
end;

var
Form1&#58; TForm1;
myMouse &#58; TMyMouse;

implementation

&#123;$R *.dfm&#125;

procedure TForm1.DXTimer1Timer&#40;Sender&#58; TObject; LagCount&#58; Integer&#41;;
begin
form1.DXDraw1.surface.fill&#40;0&#41;;
if myMouse.pressed then
case myMouse.button of
mbRight &#58; form1.DXDraw1.Surface.Canvas.TextOut&#40;10,50, 'Right Mouse button clicked at '+inttostr&#40;myMouse.clickX&#41;+', '+inttostr&#40;myMouse.clickY&#41;&#41;;
mbLeft &#58; form1.DXDraw1.Surface.Canvas.TextOut&#40;10,50, 'Left Mouse button clicked at '+inttostr&#40;myMouse.clickX&#41;+', '+inttostr&#40;myMouse.clickY&#41;&#41;;
mbMiddle &#58; form1.DXDraw1.Surface.Canvas.TextOut&#40;10,50, 'Middle Mouse button clicked at '+inttostr&#40;myMouse.clickX&#41;+', '+inttostr&#40;myMouse.clickY&#41;&#41;;
end;

form1.DXDraw1.Surface.Canvas.TextOut&#40;10,10, inttostr&#40;myMouse.X&#41;+', '+inttostr&#40;myMouse.Y&#41;&#41;;
form1.DXDraw1.Surface.Canvas.release;
form1.DXDraw1.Flip
end;

procedure TForm1.DXDraw1MouseDown&#40;Sender&#58; TObject; Button&#58; TMouseButton;
Shift&#58; TShiftState; X, Y&#58; Integer&#41;;
begin
myMouse.button &#58;= Button;
myMouse.clickX &#58;= x;
myMouse.clickY &#58;= y;
myMouse.pressed &#58;= true;
end;

procedure TForm1.DXDraw1MouseMove&#40;Sender&#58; TObject; Shift&#58; TShiftState; X,
Y&#58; Integer&#41;;
begin
myMouse.x &#58;= x;
myMouse.y &#58;= y;
end;

procedure TForm1.DXDraw1MouseUp&#40;Sender&#58; TObject; Button&#58; TMouseButton;
Shift&#58; TShiftState; X, Y&#58; Integer&#41;;
begin
myMouse.pressed &#58;= false;
end;

end.

spyke00
27-11-2006, 10:32 PM
no problem brother!