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.
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++.
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
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
>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.
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å?
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!!
262 ms totalt · 4 externa anrop · v20260731065814-full.1dc6f849