How would you make a radar system?

Hello everyone, I am currently trying to develop a radar system, but I have no idea where to start.

I know I have to do the following:

  • Get the positions and calculate the distances between the player and other objects
  • Scale down those values into a little circle-like display

But right now, I am not sure how to get the positions of these objects. My project is very module-based so everything is separated into its own files. 

Any ideas would be great!

PS: Not really expecting a solid answer, just ideas and possibly sample projects.

I don’t know if this will help, but I made this as an answer to a similar question a long time ago (not sure why it wasn’t on RG Free Stuff in the 'Ask Ed’section, but it is now…)

View Full Screen To See Clearly

https://www.youtube.com/watch?v=QGqvLti9m5A&feature=youtu.be

https://github.com/roaminggamer/RG_FreeStuff/raw/master/AskEd/2017/10/enemyHUD.zip

Wow, thanks! 

I am having a problem though. Recall that the creation of my ship and asteroids are in different files. So, how would I create the radar in main.lua and the apply the functions to ship.lua and asteroid.lua, respectively. I tried globals and they did not work.

Note: You have to modify the module to suit your needs, but I think it is pretty easy to modify.

  1. Modify  enemyHud.lua like this:

    … ---------------------------------------------------------------------- – The Module ---------------------------------------------------------------------- local public = {} public.create = createHUD public.destroy = destroyHUD public.watchObject = watchObject public.ignoreObject = ignoreObject public.getHUD() return theHUD end – NEW FUNCTION TO GET HUD object. return public

  2. Create the HUD before creating enemies. Where you do this is up to you.

    local enemyHUD = require “enemyHUD” enemyHUD.create( someGroup, nil, nil, 45, display.contentHeight * 1.5 )

  3. Now, in your modules, simply do this:

    – enemy.lua local enemyHUD = require “enemyHUD” local enemyM = {} function playerM.create( group, x, y, … more args as needed ) local enemy = display.newImageRect( … ) hud = enemyHUD.getHUD() hud.watchObject( enemy, { 1, 0, 0, 0.5 } ) end return enemyM

Note: I wish I could spend more time helping with this, but I am super busy… so I hope you’ll work it out and/or I hope someone else can give help after looking at the code:

https://github.com/roaminggamer/RG_FreeStuff/tree/master/AskEd/2017/10/enemyHUD

No problem, thank you for helping! This HUD system is great.

I tried this but I got a nil error saying “Attempt to call field ‘watchObject’ (a nil value)”. 

Whenever you have time, please respond with your suggestions.

Thank you. :slight_smile:

Also, this is how I modified the enemyHUD.lua file, as your suggestion was giving me an error:

getHUD = function(self) return theHUD end public.getHUD = getHUD

This is not directly related to your radar question, but it seems you could use a little help to structure your code. For the moment it looks like you are not able to access all info from different objects when you want to.

The easiest way to go about this is:

  1. Create a “master” module or object in main.lua - i always call this object appEngine

  2. Let appEngine create the objects needed for a level for you, using separate modules of course.

  3. When you create multiple asteroids, create an object or module “above” the single asteroids called “asteroidManager” manager or something like that. “asteroidManager” needs a variable table called “asteroidList” containing the multiple asteroids. This helps tremendously in organizing your code.

  4. Everytime you create an object, make sure you pass the “parent” object to it as a variable. This way, every object will be able to “talk to” or access the objects above it in the hierarchy.

An example: let’s say you create “appEngine”, appEngine create “asteroidManager”, and this asteroidManager creates multiple "asteroid"s kept in a table.

If you pass “parent” objects to child objects and store them in a variable call self.super, every asteroid will be able to talk to the asteroidManager by using “self.super”, and to “appEngine” by using “self.super.super”

Then, if the ship is also a child of “appEngine”, asteroids can talk to the ship (or see it’s x and y variable) by using “self.super.super.ship.x” for example.

The other way around, the ship’s super is appEngine, so a ship can talk to the first asteroid in asteroidManager’s list by using “self.super.asteroidManager.asteroidList[1]”

Does this make sense, or is it complete nonsense to you?

I can kind of see the gist of it. Is it possible you could show this with code, so I can see for myself? Just a simple example would be great.

@roaminggamer, do you understand thomas6’s response? It seems very interesting.

There are other things you can do as well. For instance, you could use queryRegion to find all physics objects in an area. That seems like an easy way to make a mini-map/radar. If you want you could then calculate the distance from the center to have things not show in corners so you get a more round “radar” look.

Rob

See PM.

So I have done this so far:

--levelmanager.lua local M = {} function M.createLevel(radarGroup, group, numOfAsteroids) local masterM = require "levels-management.moduleaccessor" local player = masterM.ship.new(group) masterM.asteroids.new(group, numOfAsteroids) masterM.enemyHUD.create(radarGroup, nil, nil, 45, display.contentHeight \* 1.5) end return M --moduleaccessor.lua local masterM = {} masterM.ship = require "ship.ship" masterM.asteroids = require "other.asteroid" masterM.enemyHUD = require "other.enemyHUD" return masterM --asteroid.lua function M.new(group, numOfAsteroids) local masterM = require "levels-management.moduleaccessor" for i = 1, numOfAsteroids do --asteroid creation code hud = masterM.enemyHUD.getHUD() hud.watchObject(asteroid, {1,0,0,0.5}) --error line end end

I get an error saying “Attempt to index global hud (a nil value)”. What do I do here?

Things that could be happening:

  • M.new() called before M.createLevel()
  • M.new() called after deleting the hud
  • You may have incorrectly modified the module.

Try this:

function M.createLevel(radarGroup, group, numOfAsteroids) local masterM = require "levels-management.moduleaccessor" local player = masterM.ship.new(group) masterM.asteroids.new(group, numOfAsteroids) masterM.enemyHUD.create(radarGroup, nil, nil, 45, display.contentHeight \* 1.5) local hud = masterM.enemyHUD.getHUD() print("\>\>\>\>\>\>\>\>\>\>\>\>\>\>\>\>\>\>\>HUD = ", hud) end return M

Then look in the console to see what the message says

Other than that, you need to add more messages to your code to debug what is going on,

-OR-

You need to get someone (a mentor?) to help you hands on with your whole project. 

It is hard to get a complete view of what you’re doing from just the code you posted.

Ok, I got it, I was creating the asteroids before I was creating the HUD. 

Say, how could I modify your program to have the radar actually track a center object (in this case, the ship). 

By this, I mean that as the ship moves the objects around it in the radar move as well based on the camera.

I see you have a centerObject parameter on your create() function but I don’t see it used. 

Smart Alec answer , by modifying the code to do that.

_ Honest answer _… I wrote that code a LONG time ago and can’t afford the time to answer this question.  However it is well commented so I think you should be able to work this out.

All it took was some basic math :0

--enemyHUD.lua createHUD = function(...) theHUD.object = centerObject end updateHUD = function( self ) -- localize for speedup local cx = theHUD.cx local cy = theHUD.cy local objectOffsetX = (theHUD.object.x - display.contentCenterX) \* theHUD.distScale local objectOffsetY = (theHUD.object.y - display.contentCenterY) \* theHUD.distScale local squareRadius = theHUD.radius2 for k, v in pairs( currentPips ) do local x = k.x - cx local y = k.y - cy x = x \* theHUD.distScale + objectOffsetX y = y \* theHUD.distScale + objectOffsetY v.x = x v.y = y -- Hide the pip if it is 'off radar' (beyond the HUD radius) v.isVisible = squareRadius \> vecSquareLen( x, y ) end end --levelmanager.lua local M = {} function M.createLevel(radarGroup, group, numOfAsteroids) masterM.enemyHUD.create(radarGroup, nil, nil, 100, display.contentHeight \* 1.5, nil, nil, player) end return M

Is there anything I can/should do to make it better? I mean, I am quite satisfied for now. :slight_smile:

Oh wait, something’s wrong…

If you’re happy, that is enough.  Glad you figured it out!