Looking for someone to critique my work as well as assist me in the final stages of my game's development

Hi,

The game I am currently working on has been in the works for almost a year now, and while I came to Corona with no prior programming experience, I’ve been able to make decent progress in terms of the game’s development - creating levels, coding scenes, writing basic functions for my various objects and animations.
However, getting certain mechanics to work seamlessly has proven to be challenging at times.


I don’t have very many levels ‘coded’ but I do have about 10 made 17 and I’m beginning to actually code each one (I use LevelHelper to create my levels). The reason I’ve hesitated to actually ‘code’ more levels is because if I were to go in and start setting up the levels, I’d have to go back and re-code certain things when I get the mechanics working better.
I’d rather wait until I have all the mechanics working how I want so then I can just copy&paste those sections of code without having to go back later and edit them… but alas I’ve decided to just start coding them and worry about any changes I have to make, later. –

 

What type of game is it? My game is based on the game ‘Tanks
My version is top-down rather than pseudo 2D.

I have all the graphical-assets - both UI and game-play as well as some sounds.
I am using Particle Candy for my animations/effects.

Some of the things I need help with are the following:

- RayCasting/radar - I utilize RayCasting as a form of ‘environmental-awareness’ for my enemy-tanks, and it needs some smoothing out. Also, each individual enemy-tank has an invisible radial-sensor that triggers the corresponding fire function when the user collides with it, the problem is when multiple radars overlap it causes some mixed results.
** I’ve figured out the problem is that the ‘ray’ can’t be incorporated into a collision filter. So, when the ray is cast towards the player, it might not fire because the ray is colliding with the tank it originates from as well as the various radars of the enemy-tanks. **
Any thoughts? is there a type of workaround for adding the ‘ray’ into a collision filter?
** Raycasting issue is solved. Everything works great. :slight_smile: **

- Mine/bomb creation - I have a button that when pressed lays a mine under the player’s current position  and unless it collides with a bullet or an enemy/player tank, it explodes after three-seconds. The problem is when I lay a second mine before the first one explodes, the timer defaults to the most recently laid mine and the first doesn’t explode.
I am also trying to create a ‘blast-zone’ that would destroy certain objects upon collision. I tried creating a radial-sensor that would appear when the mine explodes and then check for collisions, but the problem I ran into is it would not register a collision and it just simply wasn’t working… so I’d appreciate some help to get a similar feature working.

** I’ve managed to get both features working properly. :slight_smile: **

- Scene s /Audio - When I go to the options menu, mute the music and then return to the main menu the music restarts. Also if I go back to the main menu from the options menu I get the following error in the terminal window: "ERROR: physics.start() has not been called."
I don’t understand why it’s saying this, because I am calling physics at the beginning of both my .lua files.
** I haven’t actually worked on this much yet, but I saw Rob released a video all about reloading scenes so I should be able to work it all out on my own. :slight_smile: **

I am not looking for someone to take over and finish the project for me, but rather someone who would be interested in taking more of an assistant/mentor type position - an experienced person that would be available to assist in the final stages of development, whether it’s writing code or just being there to give advice/clarification on something when needed.

Tyler Glass
(aka Saerothir)

EDIT: I should clarify about the RayCasting issue - RayCasting in an of itself is working just fine, it’s how my functions are setup that is causing the issue.

Quick fix for the mine timer:

[lua]

– mine is your mine you just layed

mine.explodeTimer=timer.performWithDelay(1500, mine.explode) – Or whatever you call the explode function

– On collision with an enemy

function mine:collision(event)

  if event.other.isEnemy then

    if mine.explodeTimer then timer.cancel(mine.explodeTimer) end

  end

end

[/lua]

Obviously I haven’t seen your code, but it sounds like the issue is using one timer for multiple events. If you make the timer a property of each mine, it should work.

  • C

Thanks for the suggestion, Caleb.
Unfortunately it didn’t work. I think it’s because of how I have my function setup.
If you want to take a look, here is a textDoc with just the code relating to the PTmine: link
– Fyi Any object that doesn’t have local preceding it, has a forward declaration at the top of my code –

The way I have the function setup is how I setup most of my functions that deal with collision 'n such e.g. my bullet function/s, IGmine, radar, etc…

-Saer

I think where you’re doing your explode timer is on line #43… Correct 吗?

So if you make that a member of your PTmine (instead of having one local timer), everything should be terrifically fabulously lovely (or something around that).

  • Caleb

Actually it is on line #156
It is calling the ExplodeMine function after three seconds, which at the moment just plays an animation and removes the mine.

What’s the timer on line #43 in the code you linked to?

  • C

Here is the revised code: link

When the user taps the PTMBtn and if no collisions are detected within three seconds the mine being placed, the ExplodeMine function (lines #20 - 48) is called.
When I comment-out all the lines (In the ExplodeMine function) with the exception of the lines that play the explosion animation and the line that removes the mine, I get an error when the second mine explodes (again due to the timer defaulting to the most recently laid mine)

**"File: … Projects/DoodleTanks/LevelHelper/Nodes/LHSprite.lua
Line: 214

Bad argument #-2 to ‘originalCoronaRemoveSelf’ (Proxy expected, got nil)"**

In the past when I’ve had errors like this, it’s generally a scope issue… though in this case I don’t know what that would be.

If I try it with all the code in the function, I get this error:

**"File: …/Desktop/Application Projects/DoodleTanks/level1.lua
Line: 440

Bad argument #1 to ‘newCircle’ (number expected, got nil)"**
(line #440 is line #22 in the document you have)

On a similar note, I’ve successfully (lol I think so anyway) been able to incorporate a type of ‘blast-wave’ when my mine explodes.
Basically I’m just drawing a dynamic radial-sensor right after the mine explodes and then checking for collisions. I need to refine it a bit, but it seems to be what I need. :smiley:

As far as I can tell, you’ve only got one PTmine object. If you were to add them to a table, that would most likely do it. You could also just make them local (I’d also make your blast wave local so you can have more than one) and make sure to remove them.

[lua]

– In your onPTMBtnRelease()

local PTmine = (build PTmine)

PTmines:insert(PTmine) – Just so you can clear them all if need be

[/lua]

  • Caleb

Slightly updated code: link

I discovered something interesting - when I comment-out the line in the ExplodeMine fuction that removes the PTmine, it no longer prints an error… which would make sense since it is trying to position the PTmineBW circle at the location of an object that has, at this point, been removed.

In this short video, you’ll see how the second mine triggers two explosions - one for the first mine and the second obviously for the second instance of the timer.
Also, it’s interesting how only one explosion is played when I destroy the first mine before the second explodes. And another thing worth noting is how it throws an error when I go to destroy the second mine, before it explodes.

And btw, both the PTmine and the PTmineBW have a forward declaration at the top of my code:
[lua]
local PTmine
local PTmineBW
[/lua]
They are also both being added the main display-group.

I’ll continue to mess around with it, and hope I figure it out. :slight_smile:

Ok, so I think I’ll just give a few pointers/tips rather than go through all the code…

  1. Not so many local objects

Tables are the power of Lua. Literally. Keeping objects in a table not only keeps your code clean, but it also makes it easier to find things. If you know all of your tanks are in a table named “tanks” then you don’t have to do something both for enemyB01 and enemyB02 - you can just iterate through the “tanks” table and you know you’re getting each enemy. Likewise for a lot of your other things - keeping them in a table is  the way to go.

  1. Give each object an overall “type” (or something to that effect) value.

Instead of giving each object a “class” value (that apparently maps to their exact object) I’d opt for a “type” or “title” or something - “enemy” for the enemy tanks, “mine” for mines, etc. Then you can check against one value -

[lua]

if event.other.type == “enemy” then

  – We know it’s an enemy; explode!

end

[/lua]

  1. Nil out your objects after removing them

Stops memory leaks.

[lua]

– Yes

display.remove(myObject)

myObject = nil

– No

display.remove(myObject)

[/lua]

Anyhow, good luck!

  • Caleb

Yeah, the reason I didn’t use a table for enemy-tanks is because each tank is made up of two parts - the base and turret.
The base and turret of say the first tank are both added to a specific displayGroup and are given a .class of Etank01, so that way if I shoot a bullet and it hits the turret portion of the enemy-tank it knows it hit Etank01 and therefore calls a function that removes not just the turret but the corresponding displayGroup.
If I were to just assign each enemy-tank object a .class of “enemy”, everytime a bullet would hit just the turret portion of a tank it would only remove the event.other.class which means you’d have a tank-body roaming around without a turret… believe me, I’ve tried. :smiley:

 and btw, I give all my objects a designated .class and check for that class in my various collision functions:
[lua]
if event.other.class == “Etank01”
   then
            – display.remove(Etank01)
end
[/lua]

As far as ‘nil-ing’ out objects, I used to do that whenever I’d remove an object, but then I was reading how it’s not really necessary since everything is purged when the scene changes. I guess I’ll go back to that and nil everything. :slight_smile:

Thanks for taking the time to help me out, Caleb. I’ll figure it out. :slight_smile:

I fixed your problem of turret vs. body (not the exact problem, but a similar one - tower vs. sensor) by making each tank a display group and adding each component to it.

As for .class or .type and such, why not both? A .class for the object referencing itself, and a .type for checking whether to attack or not. (just an idea; you don’t have to do that if you don’t wish to :slight_smile: )

I make sure to nil out my objects so that I can be  absolutely  sure no memory leaks occur - why risk it? :slight_smile:

  • C

Yes, that is what I do…
Unless I’m not following you, why would I need to give an object a .class and .objType reference?

I just define a new display-group for each tank:
local Etank01 = display.newGroup()
local Etank02 = display.newGroup()
etc…

I assign a class to each object:
Ebase01 = loader:spriteWithUniqueName(“Ebase01”)
Ebase01.class = "Etank01"

Eturret01 = loader:spriteWithUniqueName(“Eturret01”)
Eturret01.class = "Etank01"

and then add the components to their corresponding group:

Etank01:insert ( Ebase01 )
Etank01:insert ( Eturret01 )

etc…

Other than becoming quite tedious when there is a high number of enemy-tanks… 21 for example ;), It seems to work without any problems.

Yeah, true. I’ll go back and nil out my objects as well. :slight_smile:

Thanks again.

-Saer

Like you said, having a lot of tanks gets tedious. Here’s what I meant by using tables:

[lua]

local tanks = {}

local function buildTank()

  local tank = display.newGroup()

    tank.body = [build tank body]

    tank.turret = [build tank turret]

    tank:insert(tank.body)

    tank:insert(tank.turret)

  – Etc.

  table.insert(tanks, tank)

end

[/lua]

.class and .type - It would just be easier for reference - you can check if event.other.type == “enemy” instead of if event.other.class == “Etank01” or event.other.class == “Etank02” or event.other.class == “Etank03” or such when more tanks exist.

  • Caleb

Okay, that helps.
Just to clarify though, does “tank.body = [build tank body]” mean the same as tankBody = display.newImage or in my case loading it from SpriteHelper, loader:spriteWithUniqueName(“tankBody”)?
This is the first time I’ve seen that form of syntax.

Ahh, I see what you’re saying…
Though how would it know, depending on what object is hit first, which turret/base to remove in addition to the object the bullet collided with? Since they all have a .type of “enemy” I can’t see how it would distinguish what objects to remove.
What I’m trying to say is “bullet hit a turret. Remove the turret and the corresponding base.” or vice versa.

From my understanding you can’t add a .class or .type to a displayGroup. If you could then I would just add the Ebase/Eturret01 to Tank1 = display.newGroup() and then assign the group an objectType - Tank1.class = “Enemy”.
In doing so I could just check if the bullet has collided with an object that has a class of “Enemy” and if so just remove even.other.class (which would be the entire Tank1 display-group)
If I could do that, then I could just create multiple display-groups for each tank and give all the groups a .class / .type of “Enemy”…
Can I achieve this via using a table?

Sorry, but other than the code in some of the libraries/modules I am utilizing, I personally have not constructed one table… I know, sad. <_<

I did that bracket-enclosed **[build tank body] and [build tank turret] **to mean however you build your body/turret, do it there. That’s not valid syntax - that’s just to show where you create your objects and add values and such to them :slight_smile:

For knowing what object to remove when a turret/body is hit, I’d use index pointers - the body has an index and the turret has an index that both point to the location of the tank object inside the tanks table.

[lua]

table.insert(tanks, tank)

local location = table.indexOf(tanks, tank) – Where is the index of “tank” in the “tanks” table?

tank.body.tankLocation = location

tank.turret.tankLocation = location

[/lua]

Then, when a collision occurs, you can find the associated tank by this:

[lua]

local location = event.other.tankLocation

local otherTank = tanks[location]

[/lua]

You can actually add any property you want to anything as long as the “anything” is a table. The .class or .type or .somethingOrOther is called a key, and it just points to where the value is - saying  tank.randomThingy = 110 basically means “store 110 at the location ‘randomThingy’”. My terminology probably isn’t correct, but it gets the point across :slight_smile:

You definitely need to get into tables… They’re really awesome (and useful!).

Okay, I figured that’s what the brackets meant. As far as the “tank.body” , what is the " ." for? Is that a way of identifying ‘body’ as a subset of the display-group tank? At first I thought it was a different form of tank:insert( body ), but then I saw tank:insert( tank.body ) in addition to the first declaration - tank.body = object

From the little bit of reading I’ve done on Tables, would the following make sense/be correct?
[lua]
local Etanks = {
    
    { tank1.body = loader:spriteWithUniqueName(“Ebase01”), tank1.turret = loader:spriteWithUniqueName(“Eturret01”) },
    
    { tank2.body = loader:spriteWithUniqueName(“Ebase02”), tank2.turret = loader:spriteWithUniqueName(“Eturret02”) }
    
    – Etc…
}

– I assume this would either mean both the base and turret have the value of Etanks[1]
– or they are just two different values that can be accessed in the first… iteration? in the table.
– If it indeed does mean they both are considered to be [1] then I’d think when I check for collisions
– I can just cycle through the table and if the bullet hit Etanks[1]
– it would remove everything defined as the [1] in Etanks{} …?
[/lua]

Sorry if this is way off from the method you’ve been explaining. :mellow:

You should really get into tables… A quick Google search reveals a couple of links that seem to be good:

http://lua-users.org/wiki/TablesTutorial

http://www.phailed.me/2011/02/learn-lua-the-hard-way-tables/

And as a side note, all display objects are tables. When you do something like…

[lua]

myImage.x = 750

[/lua]

You’re assigning 750 to the “x” value of myImage. Corona in turn translates that into a change in position.

  • C

Alright, I’ll take a look at the links.
 

Thanks for helping me out and offering some advice. :slight_smile:

-Saer

No problem :slight_smile:

  • C