Page 1 of 1

Coding a radar, and a bunch of other stuff perhaps.

Posted: Thu Sep 26, 2019 8:31 am
by jinxtengu
Hey all,
I am interested in coding a radar showing the positions of enemies in relation to the player, similar to the old game Battlezone

here's a screenshot of battlezone, you see the radar in the top right hand of the screen.
Image

Does anyone know the formula to achieve this?
I'm thinking it requires some kind of atan biz, syncing objects that have their position divided by the size of the radar screen in relation to the full screen.

Also another question, and I believe I have asked this before but I don't have a fully working code to do this. Anyhow can someone supply me with a code to make an object face the camera (and centered in the view of the camera) at all times,
the primary use of this would be for a Gui or a cross hair.
:)
Btw I plan to release some cool games made with z game editor real soon. Hoping I can get more support to allow me to build better stuff.
The past support from Kjell and Ville has been invaluable :D :D

Re: Coding a radar, and a bunch of other stuff perhaps.

Posted: Thu Sep 26, 2019 2:03 pm
by Kjell
Hi jinxtengu,
jinxtengu wrote:
Thu Sep 26, 2019 8:31 am
I am interested in coding a radar showing the positions of enemies in relation to the player, similar to the old game Battlezone
Personally i wouldn't call what Battlezone 2000 on ATARI Lynx does a "radar" .. it's more like a mini-map. A radar only updates the location of objects it detects once per revolution, while in Battlezone 2000 objects are updated continuously. Anyway, semantics aside .. here's a example ( use arrow keys to navigate ).

Code: Select all

<?xml version="1.0" encoding="iso-8859-1" ?>
<ZApplication Name="App" Caption="Radar" ScreenMode="0" CameraPosition="0 0.25 0" LightPosition="0 1 0.25" ViewportRatio="3" FileVersion="2">
  <OnLoaded>
    <ZExternalLibrary ModuleName="opengl32">
      <Source>
<![CDATA[//

void glViewport(int x, int y, int width, int height){}

//

void glBegin(int mode){}
void glEnd(){}

void glColor3f(float red, float green, float blue){}
void glTexCoord2f(float s, float t){}
void glVertex2f(float x, float y){}]]>
      </Source>
    </ZExternalLibrary>
    <ZExpression>
      <Expression>
<![CDATA[//

for(int i=0; i<8; i++)
{
  Enemy.Position.X = floor(rnd()*16)-7.5;
  Enemy.Position.Z = floor(rnd()*16)-7.5;

  Enemy.Rotation.Y = floor(rnd()*4)*0.25;

  createModel(Enemy);
}]]>
      </Expression>
    </ZExpression>
  </OnLoaded>
  <OnUpdate>
    <Repeat Name="AxisRepeat" Count="2" WhileExp="//">
      <OnIteration>
        <ZExpression>
          <Expression>
<![CDATA[//

int i = AxisRepeat.Iteration;

//

Axis[i] = 0;

//

AxisPositive.CharCode = AxisMap[i,0];
AxisNegative.CharCode = AxisMap[i,1];]]>
          </Expression>
        </ZExpression>
        <KeyPress Name="AxisPositive" CharCode="38">
          <OnPressed>
            <ZExpression>
              <Expression>
<![CDATA[//

Axis[AxisRepeat.Iteration]++;]]>
              </Expression>
            </ZExpression>
          </OnPressed>
        </KeyPress>
        <KeyPress Name="AxisNegative" CharCode="40">
          <OnPressed>
            <ZExpression>
              <Expression>
<![CDATA[//

Axis[AxisRepeat.Iteration]--;]]>
              </Expression>
            </ZExpression>
          </OnPressed>
        </KeyPress>
      </OnIteration>
    </Repeat>
    <ZExpression>
      <Expression>
<![CDATA[// Declare local variables

float t, a, sinA, cosA, x, z, dx, dz, sx, sy;

// Cache variables for performance & convenience

t = App.DeltaTime;

// Camera controls

App.CameraRotation.Y += Axis[0]*0.125*t;

a = App.CameraRotation.Y*PI*2;

sinA = sin(a);
cosA = cos(a);

App.CameraPosition.X += Axis[1]*sinA*t;
App.CameraPosition.Z -= Axis[1]*cosA*t;

// More caching ;-)

x = App.CameraPosition.X;
z = App.CameraPosition.Z;

// Calculate radar dots

model[] enemies;
getModels(enemies, 0);

Dot.SizeDim1 = 0;

for(int i=0; i<enemies.SizeDim1; i++)
{
  dx = enemies[i].Position.X-x; // Calculate distance from enemy to camera
  dz = enemies[i].Position.Z-z;

  sx = (dx*cosA+dz*sinA)*0.125; // Calculate screen-space coordinate of dot
  sy = (dx*sinA-dz*cosA)*0.125;

  if(sqrt(sx*sx+sy*sy) < 0.95)  // If dot is within radius add to Dot array
  {
    int d = Dot.SizeDim1++;

    Dot[d,0] = sx;
    Dot[d,1] = sy;
  }
}]]>
      </Expression>
    </ZExpression>
  </OnUpdate>
  <OnRender>
    <Group Comment="Floor">
      <Children>
        <UseMaterial Material="FloorMaterial"/>
        <RenderMesh Mesh="FloorMesh"/>
      </Children>
    </Group>
    <Group Comment="Radar">
      <Children>
        <ZExpression>
          <Expression>
<![CDATA[// Reset matrices

mat4 m;

for(int i=0; i<4; i++)
{
  m[i,i] = 1;
}

setMatrix(0, m);
setMatrix(1, m);

// Set viewport to top-right corner ( size based on vertical resolution )

int s = App.ViewportHeight/4;

glViewport(App.ViewportX+App.ViewportWidth-s, App.ViewportY+App.ViewportHeight-s, s, s);]]>
          </Expression>
        </ZExpression>
        <UseMaterial Material="CircleMaterial"/>
        <RenderMesh Mesh="CircleMesh"/>
        <UseMaterial Material="DotMaterial"/>
        <Repeat Name="DotRepeat">
          <OnIteration>
            <ZExpression>
              <Expression>
<![CDATA[//

int i = DotRepeat.Iteration;

//

DotTransform.Translate.X = Dot[i,0];
DotTransform.Translate.Y = Dot[i,1];]]>
              </Expression>
            </ZExpression>
            <RenderTransformGroup Name="DotTransform" Translate="0.4579 0.4321 0">
              <Children>
                <RenderMesh Mesh="DotMesh"/>
              </Children>
            </RenderTransformGroup>
          </OnIteration>
          <WhileExp>
<![CDATA[//

return Iteration < Dot.SizeDim1;]]>
          </WhileExp>
        </Repeat>
        <ZExpression>
          <Expression>
<![CDATA[// Reset viewport

glViewport(App.ViewportX, App.ViewportY, App.ViewportWidth, App.ViewportHeight);]]>
          </Expression>
        </ZExpression>
      </Children>
    </Group>
  </OnRender>
  <Content>
    <Group Comment="Axis">
      <Children>
        <Array Name="Axis" SizeDim1="2"/>
        <Array Name="AxisMap" Type="4" Dimensions="1" SizeDim1="2" SizeDim2="2" Persistent="255">
          <Values>
<![CDATA[78DA535755D300000183009B]]>
          </Values>
        </Array>
      </Children>
    </Group>
    <Group Comment="Floor">
      <Children>
        <Mesh Name="FloorMesh">
          <Producers>
            <MeshBox Scale="8 8 1" Grid2DOnly="255"/>
            <MeshExpression AutoNormals="0" HasTexCoords="255">
              <Expression>
<![CDATA[//

TexCoord.X = V.X*0.5;
TexCoord.Y = V.Y*0.5;

//

V.Z = -V.Y;
V.Y =      0;
V.X =  V.X;]]>
              </Expression>
            </MeshExpression>
          </Producers>
        </Mesh>
        <Bitmap Name="FloorBitmap" Width="2" Height="2" Filter="1">
          <Producers>
            <BitmapExpression>
              <Expression>
<![CDATA[//

if(X+Y != 1)
{
  Pixel.R = 1;
  Pixel.G = 1;
  Pixel.B = 1;
}
else
{
  Pixel.R = 0;
  Pixel.G = 0;
  Pixel.B = 1;
}]]>
              </Expression>
            </BitmapExpression>
          </Producers>
        </Bitmap>
        <Material Name="FloorMaterial" Shading="1" Light="0">
          <Textures>
            <MaterialTexture Texture="FloorBitmap" TextureWrapMode="1" TexCoords="1"/>
          </Textures>
        </Material>
      </Children>
    </Group>
    <Group Comment="Enemy">
      <Children>
        <Model Name="Enemy" Position="1.5 0 7.5" Rotation="0 0.25 0">
          <OnRender>
            <UseMaterial Material="EnemyMaterial"/>
            <RenderMesh Mesh="EnemyMesh"/>
          </OnRender>
        </Model>
        <Mesh Name="EnemyMesh">
          <Producers>
            <MeshImport HasVertexColors="1">
              <MeshData>
<![CDATA[78DAE590BD4A034114858F31092AFE4410C14EC156B00F9880AD4F60B59585557C03CB6DC45E84B54865E503046D2C17B6B50B2858098A26B8A8C9F1FECC689EC0C65DE6CCDDC3CC77EEDD36804DE8737C6D1B5E746F01173B40A78564F7F6E48199E9E9C67DB740C774FBF270F549FDFD2B20DF2359A883844C53D29C8CEC35D5E935D551BA2A6FD274EB0E6DD5409E7062A272B416BE67159E38C1376648B11E3CDD133D2BF49345FDE94766393AD7595CBB45986E1D38780C34278873B6C6BEA9277A7A5F4FFA1F709A137CA240F6FE93E8081F91206ACC5FBED01873454327D3A8C83BE6980D34B022F5BBD46FFCE288339843C90FCE62090B781677C8AADC989245714BD6F0C945D4C4A962C0D2EE8C5891EF79BC72C03A968DA909AAF53FAAF33CFFD7EB1BDD01E882]]>
              </MeshData>
            </MeshImport>
          </Producers>
        </Mesh>
        <Material Name="EnemyMaterial" Shading="1" DrawBackFace="255"/>
      </Children>
    </Group>
    <Group Comment="Radar">
      <Children>
        <Group Comment="Dot">
          <Children>
            <Array Name="Dot" Dimensions="1" SizeDim1="5" SizeDim2="2"/>
            <Mesh Name="DotMesh">
              <Producers>
                <MeshBox Scale="0.05 0.05 1" Grid2DOnly="255"/>
              </Producers>
            </Mesh>
            <Bitmap Name="DotBitmap" Filter="2">
              <Producers>
                <BitmapExpression>
                  <Expression>
<![CDATA[//

float u, v;

u = 0.5-X;
v = 0.5-Y;

Pixel.R = 1;
Pixel.A = 16-sqrt(u*u+v*v)*32;]]>
                  </Expression>
                </BitmapExpression>
              </Producers>
            </Bitmap>
            <Material Name="DotMaterial" Shading="1" Light="0" Blend="1" ZBuffer="0">
              <Textures>
                <MaterialTexture Texture="DotBitmap" TexCoords="1"/>
              </Textures>
            </Material>
          </Children>
        </Group>
        <Group Comment="Circle">
          <Children>
            <Mesh Name="CircleMesh">
              <Producers>
                <MeshBox Grid2DOnly="255"/>
              </Producers>
            </Mesh>
            <Bitmap Name="CircleBitmap" Width="128" Height="128" Filter="2">
              <Producers>
                <BitmapExpression>
                  <Expression>
<![CDATA[//

float u, v, s;

u = 0.5-X;
v = 0.5-Y;

s = sqrt(u*u+v*v);

Pixel.R = 1;
Pixel.G = 1;
Pixel.B = 1;
Pixel.A = clamp(32-s*64, 0, 0.5) - clamp(1-s*64, 0, 1);]]>
                  </Expression>
                </BitmapExpression>
              </Producers>
            </Bitmap>
            <Material Name="CircleMaterial" Light="0" Blend="1" ZBuffer="0">
              <Textures>
                <MaterialTexture Texture="CircleBitmap" TexCoords="1"/>
              </Textures>
            </Material>
          </Children>
        </Group>
      </Children>
    </Group>
  </Content>
</ZApplication>
jinxtengu wrote:
Thu Sep 26, 2019 8:31 am
Also another question, and I believe I have asked this before but I don't have a fully working code to do this. Anyhow can someone supply me with a code to make an object face the camera (and centered in the view of the camera) at all times, the primary use of this would be for a Gui or a cross hair.
You did ask this before yes .. here is the thread :wink:

K

Re: Coding a radar, and a bunch of other stuff perhaps.

Posted: Fri Sep 27, 2019 7:50 am
by VilleK
Every time someone asks Kjell for help he ends up writing an example that is already half the game :). Looks real nice. Great work as usual Kjell!