Alpha IIMedlem sedan maj 20002 993 inlägg Delphi/pascal är ett helvete! x(
i game.pas ligger själva spelet.
PlayerC ligger i game.pas uses.
Terrain ligger också i game.pas uses.
PlayerC behöver använda en funktion som ligger i terrain som returnerar ett svar beroende på vad en variabel som också ligger i terrain, är ställd till.
Hur ska jag kunna använda funktionen ifrån playerC? Om jag lägger till terrain i playerc uses fungerar det väl inte?!
Förut låg koden som nu ligger i PlayerC i game.pas men det var inte speciellt snyggt, ochd et blir en massa kod.... PlayerC innehåller btw en klass som heter player och dess funktioner.
*Känns som jag alltid har samma problem* :OO
UlfTMedlem sedan maj 20018 027 inlägg Inte så bra på Delphi, men en gissning är att Terrain kommer först efter PlayerC. Då känner inte PlayerC till Terrain. Det skulle du kunna lösa genom att deklarera prototyper (i början av filen) av funktionerna i Terrain. Vet inte om det går i Delphi, men så gör man i C/C++.
Alpha IIMedlem sedan maj 20002 993 inlägg Det går inte eftersom i c/c++ inkluderar man filerna i filen, men i uses så kan man bara använda funktionerna och variablerna i filen den inkluderas inte i huvudfilen... tror inte det iaf :OO
UlfTMedlem sedan maj 20018 027 inlägg Ok, men vad var det för fel på att ha dina klasser i andra filer? Jag tycker det normalt blir snyggare om man har varje klass i sin egna fil.
Alpha IIMedlem sedan maj 20002 993 inlägg Jo jag vet det tycker jag också... men det är ju då det blir problem eftersom delphi suger!! (dvs jag vet inte hur man gör)
Alpha IIMedlem sedan maj 20002 993 inlägg Jag skcippade terrain klassen och la funktionen GetHeight() i game.pas, hur får jag tag på den ifrån player (ligger i game.pas uses) då? Jag vill ju inte lägga till game i players uses.... det fungerar heller inte..
Skulle jag kunna lägga in player i game.pas genom {$include player.pas}, jt sa förut i nån liknande tråd att det var onödigt krångligt :OO
jtMedlem sedan juni 2000350 inlägg >Jag vill ju inte lägga till game i players ...
Om du inte vill göra detta så fär du väl planerar ditt projekt lite anorlunda. Men det går, flytta "uses game" från interface delen till implementations delen.
unit Players;
interface
implementation
uses
Game;
Kanske jag missförstår ditt problem pga av att jag har svårt att hänga med i dina förklaringar.
Alpha IIMedlem sedan maj 20002 993 inlägg Vad är det för skillnad om man har det i interface eller implementation?
Alpha IIMedlem sedan maj 20002 993 inlägg Förklaring
Jag vet inte riktigt hur jag ska förklara men jag kan ju visa lite kod!
Game.pas (rensad på det mesta som inte har någonting med player att göra)
unit Game;
interface
uses
Windows,
Classes,
OpenGL12,
TGATexture,
Math,
Math3D,
Octree,
Player; // Innehåller klassen player och dess funktioner!
var
[snip]
// Game vars
HeightMap : array of GLfloat;
implementation
function Ind(const X,Y: integer): integer;
begin
result := X+Y*MapSize;
end;
function GetHeight(getx: GLfloat; getz: GLfloat): GLfloat;
var
p1: TVector3;
p2: TVector3;
p3: TVector3;
p4: TVector3;
begin
getx := getx / 10;
getz := getz / 10;
p1.X := Floor(getx);
p1.Y := HeightMap[ind(Floor(getx), Floor(getz))];
p1.Z := Floor(getz);
p2.X := Floor(getx)+1;
p2.Y := HeightMap[ind(Floor(getx)+1, Floor(getz))];
p2.Z := Floor(getz);
p3.X := Floor(getx);
p3.Y := HeightMap[ind(Floor(getx), Floor(getz)+1)];
p3.Z := Floor(getz)+1;
p4.X := Floor(getx)+1;
p4.Y := HeightMap[ind(Floor(getx)+1, Floor(getz)+1)];
p4.Z := Floor(getz)+1;
getx := getx - floor(getx);
getz := getz - floor(getz);
result := (getx * getz * p1.y) +
((1-getx) * getz * p2.y) +
((1-getx) * (1-getz) * p3.y) +
(getx * (1-getz) * p4.y);
// p1-------p2
// | / |
// | / |
// | / |
// | / |
// p3-------p4
end;
[snip]
procedure SetAngleByMouse();
var
mousePos : TPoint;
middleX : GLfloat;
middleY : GLfloat;
angle : GLfloat;
begin
angle := 0.0;
middleX := ScrWidth shr 1;
middleY := ScrHeight shr 1;
GetCursorPos(mousePos);
if (mousePos.X = middleX) then Exit;
SetCursorPos(Round(middleX), Round(middleY));
angle := (middleX - mousePos.X) / 10;
g_Player.Rotate(angle);
end;
procedure Look();
begin
gluLookAt(g_Player.Pos.x-Sin(g_Player.Angle*(Pi*2)/360)*10, g_Player.Pos.y+15, g_Player.Pos.z-Cos(g_Player.Angle*(Pi*2)/360)*10,
g_Player.Pos.x, g_Player.Pos.y+10, g_Player.Pos.z,
0, 1, 0);
end;
procedure glDrawScene();
begin
LastFrame := getTickCount();
glClear(GL_COLOR_BUFFER_BIT or GL_DEPTH_BUFFER_BIT);
glLoadIdentity();
g_Player.Update();
Look();
DrawOctree();
end;
procedure ProcessInput();
begin
SetAngleByMouse();
if Keys[VK_UP] then g_Player.Move(5);
if Keys[VK_DOWN] then g_Player.Move(-5);
if (Keys[VK_SPACE]) and (g_Player.IsOnGround()) then g_Player.Jump();
end;
end.
Player.pas
unit Player;
interface
uses
Math3D,
OpenGL12;
type
TPlayer = class
private
FPos : TVector3;
FLastPos : TVector3;
FVel : TVector3;
FAngle : GLfloat;
FBoundX : GLfloat;
FBoundZ : GLfloat;
public
procedure SetPos(V: TVector3);
procedure Jump();
procedure Move(Speed: GLfloat);
procedure Rotate(Speed: GLfloat);
procedure Update();
procedure PlaceInBound();
function IsOnGround(): Boolean;
property Pos: TVector3 read FPos;
property Angle: GLfloat read FAngle;
end;
implementation
procedure TPlayer.SetPos(V: TVector3);
begin
FPos.X := V.X;
FPos.Y := V.Y;
FPos.Z := V.Z;
end;
procedure TPlayer.Jump();
begin
FVel.Y := -2;
end;
procedure TPlayer.Move(Speed: GLfloat);
begin
if not IsOnGround() then Speed := Speed / 2;
FPos.X := Pos.X+Sin(FAngle*(Pi*2)/360)*Speed;
FPos.Z := Pos.Z+Cos(FAngle*(Pi*2)/360)*Speed;
end;
procedure TPlayer.Rotate(Speed: GLfloat);
begin
FAngle := FAngle + Speed;
end;
procedure TPlayer.Update();
var
H: Glfloat;
begin
FPos := VectorSub(FPos, FVel);
// H := GetHeight(Pos.X, Pos.Z); // !!!!!!!!!!!
if FPos.Y > H then FVel.Y := FVel.Y + 0.2;
if FPos.Y < H then FPos.Y := H;
// PlaceInBound();
end;
procedure TPlayer.PlaceInBound();
begin
if (FPos.X < 1) then FPos.X := 1;
if (FPos.X > FBoundX) then FPos.X := FBoundX;
if (FPos.Z < 1) then FPos.Z := 1;
if (FPos.Z > FBoundZ) then FPos.Z := FBoundZ;
end;
function TPlayer.IsOnGround(): Boolean;
begin
// if FPos.Y = GetHeight(Pos.X, Pos.Z) then Result := true //!!!!!!!!!!!!!
// else result := false;
end;
end.
Förstår du nu? Jag tog bort terrain klassen som låg i terrain.pas och la de nödvändiga sakerna som funktioner i game.pas. Men nu vill jag ändå komma åt funktionerna.... Hur gör jag det då?
jtMedlem sedan juni 2000350 inlägg I Game filen måste du exportera funktionen GetHeight, detta gör du genom att deklarera funktionen i interface delen.
unit Game;
interface
........
........
//Gör det möjligt för andra "unitar" att använda funktionen
function GetHeight(getx: GLfloat; getz: GLfloat): GLfloat;
implementation
function GetHeight(getx: GLfloat; getz: GLfloat): GLfloat;
begin
....
end;
Sedan lägger du till "uses Game;" direkt under implementation i player filen.
Nu borde det väl fungera?
Läs tips:
Marco Cantù's Essential Pascal Chapter 11 Program and Units
http://www.marcocantu.com/EPascal/English/ch11unit.htm
Alpha IIMedlem sedan maj 20002 993 inlägg Men det kan väl inte fungera? Eftersom GetHeight() returnerar olika svar beroende på vad variabeln HeightMap är!
Alpha IIMedlem sedan maj 20002 993 inlägg Hallå! Ingen som vet eller? Går det inte att inkludera en unit som global så att alla unit filer pekar på samma version av uniten, så att man skulle kunna ha variabeln g_HeightMap i den filen och diverse funktioner som har med det o göra?
Jobbigt med så mkt problem för att göra koden kortare och snyggare..... eller ska jag lägga in TPlayer klassen i game.pas?! Vill heslt inte göra det!!