Tower defense tutorial. sort of

7 posts Page 1 of 1
Chelaru
Posts: 200
Joined: Wed Jul 01, 2015 10:33 am
by Chelaru » Mon Feb 26, 2018 8:22 pm
Hello, the following is work in progress tower defense. You can follow the tutorial, some stuff are useful.

Camera Setup

First we're going to set up our camera mode framework. In scripts/server/commands.cs we're going to add some functions to set and toggle our camera modes. The following code can sit at the end of the script file:

Code: Select all

// ---------------------------------------------------------------------------- // Camera commands // ---------------------------------------------------------------------------- function serverCmdorbitCam(%client) { %client.camera.setOrbitObject(%client.player, mDegToRad(20) @ "0 0", 0, 5.5, 5.5); %client.camera.camDist = 5.5; %client.camera.controlMode = "OrbitObject"; } function serverCmdoverheadCam(%client) { %client.camera.position = VectorAdd(%client.player.position, "0 0 30"); %client.camera.lookAt(%client.player.position); %client.camera.controlMode = "Overhead"; %client.camera.position = Cam1.position; %client.camera.rotation = Cam1.rotation; } function serverCmdtoggleCamMode(%client) { if(%client.camera.controlMode $= "Overhead") { %client.camera.setOrbitObject(%client.player, mDegToRad(20) @ "0 0", 0, 5.5, 5.5); %client.camera.camDist = 5.5; %client.camera.controlMode = "OrbitObject"; } else if(%client.camera.controlMode $= "OrbitObject") { %client.camera.controlMode = "Overhead"; %client.camera.position = VectorAdd(%client.player.position, "0 0 30"); %client.camera.lookAt(%client.player.position); } } function serverCmdadjustCamera(%client, %adjustment) { if(%client.camera.controlMode $= "OrbitObject") { if(%adjustment == 1) %n = %client.camera.camDist + 0.5; else %n = %client.camera.camDist - 0.5; if(%n < 0.5) %n = 0.5; if(%n > 15) %n = 15.0; %client.camera.setOrbitObject(%client.player, %client.camera.getRotation(), 0, %n, %n); %client.camera.camDist = %n; } if(%client.camera.controlMode $= "Overhead") { %client.camera.position = VectorAdd(%client.camera.position, "0 0 " @ %adjustment); } }
Additionally, in scripts/client/default.bind.cs we'll add some keybinds and utility functions to assist in controlling the camera:

Code: Select all

function toggleCameraMode(%val) { if (%val) commandToServer('toggleCamMode'); } moveMap.bind( keyboard, "ctrl m", toggleCameraMode); function mouseZoom(%val) { if(%val > 0) { commandToServer('adjustCamera', -1); } else { commandToServer('adjustCamera', 1); } } moveMap.bind(mouse, "zaxis", mouseZoom);
Ensure that any other binds for zaxis and alt m are commented out to avoid conflicts.  Also, if the file scripts/client/config.cs exists it will need to be deleted before changes to default.bind.cs can take effect.

Mouse Setup
The following code will change the way mouse input affects movement and click interaction.

Mouse Cursor Toggling
Normally, the camera is controlled by an actor in FPS (aim) mode. To focus on just mouse and camera work, we need to change how the default camera is controlled. Open game/scripts/server/gameCore.cs. In function GameCore::preparePlayer(%game, %client), locate the following line:

Code: Select all

%game.spawnPlayer(%client, %playerSpawnPoint);
Change this code by adding a third argument to the function call:

Code: Select all

%game.spawnPlayer(%client, %playerSpawnPoint, false);
The function call being modified is GameCore::spawnPlayer(%game, %this, %spawnPoint, %noControl), located in game/core/scripts/server/gameCore.cs. The last two arguments determine the location of spawning (%spawnPoint) and whether or not the actor object controls the camera (%noControl). We need to address that next.
Immediately below the %game.spawnPlayer() function, add the following code:

Code: Select all

// Set camera to Overhead mode commandToServer('overheadCam');
If you run the game, you will now be using an orbit camera instead of an FPS view controlled by the actor. Next, we need to be able to control the on/off state of the in-game mouse cursor. Open game/scripts/client/default.bind.cs. At the end of the file, add the following:

Code: Select all

// Turn mouse cursor on or off // If %val is true, the button was pressed in // If %val is false, the button was released function toggleMouseLook(%val) { // Check to see if button is pressed if(%val) { // If the cursor is on, turn it off. // Else, turn it on if(Canvas.isCursorOn()) hideCursor(); else showCursor(); } } // Bind the function toggleMouseLook to the keyboard 'm' key moveMap.bind(keyboard, "m", "toggleMouseLook");
Next, open your file browser and delete scripts/client/config.cs, if it exists. This file contains custom keybinds created for your game. It will override the variables and functions you add to default.bind.cs. However, if you delete this file and run your game, a new one will be regenerated with your updated keybinds.

If you start the game now, it will still default to a free flying (mouse look) camera. By hitting the 'm' key you will be able to toggle "mouse look" mode. If mouse look is on, you can control your view direction by moving the mouse. If it is off, you can move your cursor around on the screen. You can switch back to an actor controlled camera by pressing Alt + C.

We will go ahead and force the cursor to be on as soon as the level loads. Open game/art/gui/playGui.gui. You can edit .gui files just like any other script file. Look for the noCursor field. Make the following change to this field:

Code: Select all

noCursor = "0";
Now that you've freed up the mouse from aiming duties, it's time to put it to other uses.
Placing Structures Using The GUI
First, open art/gui/PlayGui.gui and find new GuiControl(DamageHUD) toward the end of the file and remove the entire block of code (ensure that you do not delete the main block's closing brace - it's the one with the semi-colon after it).  It occupies the center of the screen when you are in play mode and it will block mouse clicks to that area.

Optionally, you can remove this control element using the Gui Editor.

Next, open the GUI Editor by pressing F10 or by clicking the GUI Editor button from the World Editor
Image

Open the Library tab, pull down the Buttons rollout,  then click and drag the GuiBitmapButtonCtrl onto the GUI to create a new button.
Image
Select your new button and change the settings as follows:
Image
Browse to your project's art/gui folder and select the orcburrow.png ,or any image that you have, file for the button image.
Image
If you close the GUI Editor ( F10 ) you should now see your button in the game UI.
Image
Next, open scripts/gui/playGui.cs and add the following code at the end:

Code: Select all

Next, open scripts/gui/playGui.cs and add the following code at the end: // onMouseDown is called when the left mouse // button is clicked in the scene // %pos is the screen (pixel) coordinates of the mouse click // %start is the world coordinates of the camera // %ray is a vector through the viewing // frustum corresponding to the clicked pixel function PlayGui::onMouseDown(%this, %pos, %start, %ray) { // If we're in building placement mode ask the server to create a building for // us at the point that we clicked. if (%this.placingBuilding) { // Clear the building placement flag first. %this.placingBuilding = false; // Request a building at the clicked coordinates from the server. commandToServer('createBuilding', %pos, %start, %ray); } else { // Ask the server to let us attack a target at the clicked position. commandToServer('checkTarget', %pos, %start, %ray); } } // This function is the callback that handles our new button. When you click it // the button tells the PlayGui that we're now in building placement mode. function orcBurrowButton::onClick(%this) { PlayGui.placingBuilding = true; }
Then, in scripts/server/commands.cs add the following function to the end:

Code: Select all

function serverCmdcreateBuilding(%client, %pos, %start, %ray) { // find end of search vector %ray = VectorScale(%ray, 2000); %end = VectorAdd(%start, %ray); // set up to look for the terrain %searchMasks = $TypeMasks::TerrainObjectType; // search! %scanTarg = ContainerRayCast( %start, %end, %searchMasks); // If the terrain object was found in the scan if( %scanTarg ) { // get the world position of the click %pos = getWords(%scanTarg, 1, 3); // Note: getWord(%scanTarg, 0) will get the SimObject id of the object // that the button click intersected with. This is useful if you don't // want to place buildings on certain other objects. For instance, you // could include TSStatic objects in your search masks and check to see // what you clicked on - then don't place if it's another building. // spawn a new object at the intersection point %obj = new TSStatic() { position = %pos; shapeName = "art/shapes/building/orcburrow.dts"; collisionType = "Visible Mesh"; scale = "0.5 0.5 0.5"; }; // Add the new object to the MissionCleanup group MissionCleanup.add(%obj); } }
If you run the game now, you should be able to click the button, then click on the ground to place a new orc burrow.

Image

Optionally, you can remove the DamageHUD element from the PlayGui - it is not useful in a strategy game and it happens to block mouse clicks.

Image

In the level editor select SpawnSphere and change :

Image

Move your camera to the position you want your first marker to be and get your angle dialed in.  Once your camera is in position, open the Library tab of the Scene Tree, browse to the Level tab's Level folder and double click the Player Spawn Sphere item to create a new Spawn Sphere.

Image

Name your new Spawn Sphere Cam1.

Image

Pull down the Object menu and select Drop Location > at Camera w/Rotation.

Image

Now you can drop your Spawn Sphere so that it will be in the correct place and face the correct direction by selecting Object > Drop Selection with Cam1 selected.  You can optionally use the shortcut CTRL-D.

Image

You may see your screen turn green.  This is not a bug, you've just pulled the Spawn Sphere over your head and you're seeing the world through emerald-tinted glasses.  The Spawn Sphere should be placed and facing exactly the way the camera currently is, so this is a good sign.

Now, to create the panning camera:
Go in to Gui Editor-> Library and create one GuiButtonBaseCtrl.

Click on the GUI tab and follow the picture :

Image

Now this Gui button will be set on the upper side of the screen. If you select it you should see some thing like this :

Image

If you click and hold on it you should see a cross. Now drag it to the middle of the screen and squar should appear :

Image

Resize the square to fit the width of the screen :

Image

Now move it to the upper side of the screen untile you get some thing like this :

Image

The are that is market red will be the are that is sensitive to the cursor.

Now that we made the Up part is time to make the Down part.
Repeat the steps on making the GuiButtonBaseCtrl. But now use the following settings:

Image

And move it on the lower part of the screen.
Let’s do the Left and Right.

For Left you have :

Image

Don’t forget to resize it and move it to the left side :D
For right you have :

Image

Remember to move it to the right.
Now for the last part:


Open: scripts\gui\PlayGui.cs . At the end of the file paste the following :

Code: Select all

function panUp::onMouseEnter(%this) { echo("- movement UP enter " @ %this.Name); //commandToServer('adjustCamera', 1); setSpeed(100); moveforward(1); } function panUp::onMouseLeave(%this) { echo("- movement UP exit " @ %this.Name); setSpeed(100); moveforward(0); } function panDown::onMouseEnter(%this) { echo("- movement DOWN enter " @ %this.Name); //commandToServer('adjustCamera', -1); setSpeed(100); movebackward(1); } function panDown::onMouseLeave(%this) { echo("- movement DOWN exit " @ %this.Name); setSpeed(100); movebackward(0); } function panLeft::onMouseEnter(%this) { echo("- movement LEFT enter " @ %this.Name); setSpeed(100); moveleft(1); //yaw(10); } function panLeft::onMouseLeave(%this) { echo("- movement LEFT exit " @ %this.Name); //yaw(0); moveleft(0); } function panRight::onMouseEnter(%this) { echo("- movement RIGHT enter " @ %this.Name); setSpeed(100); moveright(1); } function panRight::onMouseLeave(%this) { echo("- movement RIGHT exit " @ %this.Name); setSpeed(100); moveright(0); }
Now one last thing. In the same file look for the function :

Code: Select all

function PlayGui::onWake(%this)
You should comment out the following:

Code: Select all

if ( isObject( MainChatHud ) ) { Canvas.pushDialog( MainChatHud ); chatHud.attach(HudMessageVector); }
Now we are going to add a turrets to the game

Remember the old function “serverCmdcreateBuilding”. We need to change that to add a new turret.

Code: Select all

function serverCmdcreateBuilding(%client, %pos, %start, %ray) { // find end of search vector %ray = VectorScale(%ray, 2000); %end = VectorAdd(%start, %ray); // set up to look for the terrain %searchMasks = $TypeMasks::TerrainObjectType; // search! %scanTarg = ContainerRayCast( %start, %end, %searchMasks); // If the terrain object was found in the scan if( %scanTarg ) { // get the world position of the click %pos = getWords(%scanTarg, 1, 3); // Note: getWord(%scanTarg, 0) will get the SimObject id of the object // that the button click intersected with. This is useful if you don't // want to place buildings on certain other objects. For instance, you // could include TSStatic objects in your search masks and check to see // what you clicked on - then don't place if it's another building. // spawn a new object at the intersection point %obj = new AITurretShape() { datablock = AITurret;//%client; //rotation = "0 0 1 " @ getWord(%rot, 2); count = 1; position = %pos; //sourceObject = %user; //client = %user.client; isAiControlled = true; }; MissionGroup.add(%obj); // Add the new object to the MissionCleanup group //MissionCleanup.add(%obj); } }
Now that we have turrets we must add a cost counter.
First you will need to add a GuiTextCtrl so the user can see the money.
To create a GuiTextCtrl press F10 or go to the gui editor -> click on the Library->expand Text and click on the GuiTextCtrl.
Click on GUI on the tree you should see Image
Click it.
On the “name” field add a name, in my case “TotalMoney”.
On the “text” field you could add a default text, if you want to.
Now is time for scrypt, modification.
Go back in the file commands.cs (this is temporary) .
A bit of info: to make global variables in Torque scrypt you must use “$” at the begining of every variable. For the local variables use “%” at the begining of the variable.
With that knowledge we shall define a variable $money :D .
And add some functions for later:

Code: Select all

$money = 9000; Function PrintMoney() { echo("Money = " @ $money); } function SetMoney(%val) { $money = %val; } function SetMoney(%val) { $money = %val; MoneyGuiPrinter($money); } function AddMoney(%val) { $money = $money + %val; } function SubtractMoney(%val) { if($money >= %val) { $money = $money - %val; } } function MoneyGuiPrinter(%val) {//Used to set the text value of the gui text element TotalMoney.setText("Money : " @ %val ); }
Now to show the money
Go in the function “serverCmdcreateBuilding” after “MissionGroup.add(%obj);” add
MoneyGuiPrinter($money);

Run the game, add a turret. You should see: Image

Let’s create a system for the cost of the turrets.
The idea: Every turret has a cost, the user will have a bank account called “$money” in scrypt(you could change its name).
If the cost of the turret is greater then the amount of money in the user account the game will show a warning message. For now we will just change the text from ower text box.

Code: Select all

If the cost of the turret is greater then the amount of money in the user account the game will show a warning message. For now we will just change the text from ower text box. function serverCmdcreateBuilding(%client, %pos, %start, %ray) { // find end of search vector %ray = VectorScale(%ray, 2000); %end = VectorAdd(%start, %ray); %cost = 200; // set up to look for the terrain %searchMasks = $TypeMasks::TerrainObjectType; // search! %scanTarg = ContainerRayCast( %start, %end, %searchMasks); // If the terrain object was found in the scan if( ( %scanTarg ) && (%cost <= $money) ) { // get the world position of the click %pos = getWords(%scanTarg, 1, 3); // Note: getWord(%scanTarg, 0) will get the SimObject id of the object // that the button click intersected with. This is useful if you don't // want to place buildings on certain other objects. For instance, you // could include TSStatic objects in your search masks and check to see // what you clicked on - then don't place if it's another building. // spawn a new object at the intersection point %obj = new AITurretShape() { datablock = AITurret;//%client; //rotation = "0 0 1 " @ getWord(%rot, 2); count = 1; position = %pos; //sourceObject = %user; //client = %user.client; isAiControlled = true; }; SubtractMoney(%cost); MoneyGuiPrinter($money); // Add the new object to the MissionCleanup group MissionCleanup.add(%obj); } else if(%cost > $money) { MoneyGuiPrinter("Insufficient funds"); } }
You can see the new “if” statemen : “if( ( %scanTarg ) && (%cost <= $money) )” and the “ else if ” statement: “ else if(%cost > $money) “.

Run the game. Add some turrets until you have no money. If the cost of the turret is greater then amount of money in the user account the textbox will change the text to : “Insufficient funds”.

Go to game\scrypt\server\gameCore.cs find “function GameCore::onClientEnterGame(%game, %client)” add %client.team = 1; in there.

Find datablock AITurretShapeData(AITurret) and add team = 0;

Code: Select all

function serverCmdcreateBuilding(%client, %pos, %start, %ray) // spawn a new object at the intersection point %obj = new AITurretShape() { datablock = AITurret;//%client; //rotation = "0 0 1 " @ getWord(%rot, 2); count = 1; position = %pos; //sourceObject = %user; //client = %user.client; isAiControlled = true; team = %client.team; // this is added to make the turret be on the same team as the player. };
Now for some code changes. Open Visual Studio -> go in the file shapeBase.h and look for F32 mEnergy;

Delete F32 mEnergy and replace it with:

F32 mTeamId:

Code: Select all

public: F32 mTeamId; protected: F32 mEnergy; ///< Current enery level.
Go in shapeBase.cpp

Look for “ mFadeDelay( 0.0f ), “ and under it add “ mTeamId(0),

In the same file look for “ addField( "isAiControlled", TypeBool, Offset(mIsAiControlled, ShapeBase),

Under it add :

addField( "team", TypeF32, Offset(mTeamId, ShapeBase),

Now go in to aiTurretShape.cpp

Look for “ AITurretShape* turret = (AITurretShape*)data;

And in the If statement add:

Code: Select all

if ((shape->mTeamId == 0)||(shape->mTeamId == turret->mTeamId)) return;
Should look like :

Code: Select all

if (shape && shape->getDamageState() == ShapeBase::Enabled) { if ((shape->mTeamId == 0) || (shape->mTeamId == turret->mTeamId)) return; Point3F targetPos = shape->getBoxCenter();

Go in to game/script/server and open aiPlayer.cs . Look for “function AIPlayer::spawnAtLocation(%name, %spawnPoint)

Code: Select all

function AIPlayer::spawnAtLocation(%name, %spawnPoint) { // Create the demo player object %player = new AiPlayer() { dataBlock = DemoPlayer; path = ""; team = 2; }; MissionCleanup.add(%player); %player.setShapeName(%name); %player.setTransform(%spawnPoint); return %player; }

Go in to game/script/server and open aiPlayer.cs . Look for “function AIPlayer"

This is to make the ai enemy be on the a different team. In this way the turrets will kill them.

Now that we have a working killing force we need somethink to kill.

For this demo we are going to make a simple spown Ai player (enemy) at one location in the scene and make them move to some point.


Create a new simgroup (library -> level -> system -> simGroup) and call it "aiSpawnGroup" (the name can be changed in the Inspector after left clicking on the simgroup in the Name field.

We want to add two WayPoints(StartPoint,EndPoint). WayPoint can be found with SpawnSphere in (library -> scripted -> misc). Once you have a load in, if they're not inside "aiSpawnGroup" you want to select them all and drag them in.

The simgroup is if you want to have more then one spown point for the enemies.

Now to create a function that will spawn some enemies.

Go to game\scripts\server and open aiPlayer.cs and add this function :

Code: Select all

function spawnAi() { %index = 0; //In case you have more then one spawnpoint you can use a random function to select the next spawn point %count = aiSpawnGroup.getCount(); %spawnPoint = aiSpawnGroup.getObject(%index).getTransform(); %player = new AiPlayer() { dataBlock = DemoPlayer; path = ""; team = 2; position = %spawnPoint; }; %player.setMoveSpeed(0.5); if(%count > 1) { %player.setMoveDestination(aiSpawnGroup.getObject( (%count - 1) ).getTransform()); } else { echo("ERROR: you need more elements in aiSpawnGroup"); } MissionCleanup.add(%player); }
Now to create a function that will spawn some enemies.

This function will create the ai enemies and order them to go to the EndPoint.

Now we need one more thing. After killing the something the player should receive some money.

For this just copy the following function after the one from above:

Code: Select all

function DemoPlayer::onDamage(%this,%obj, %delta) { %val = 200; if(%obj.getstate() $="Dead") { //when ai enemy is dead the player will receive some money AddMoney(%val); } }
For this just copy the following function after the one from above:

Now open the game, press the “ ` “ (tilda) and write spawnAi() then press “Enter” from keyboard. Should see AI soldiers runnig across the map to the EndPoint.
Add some turrets, have some fun.

If you remember we changed the code to make the turrets be friendly to the other turrets.

The following example will use the build in ignoreList of the Ai turret.

Remember the “serverCmdcreateBuilding” function from commands.cs .

We will change it a bit :D.

First we will create a global list of friendly units like this.

You must do this out side of a function. ” $mySSet = new SimSet();

Example:

Image

Now in the function “serverCmdcreateBuilding” below

Code: Select all

%obj = new AITurretShape() { datablock = AITurret;//%client; //rotation = "0 0 1 " @ getWord(%rot, 2); //count = 1; position = %pos; //sourceObject = %user; //client = %user.client; isAiControlled = true; team = %client.team; // <- TEAM };
Add

Code: Select all

//This code is meant to use the build in ignore list of the turret. But we need to make some List management. By management i want to say the we need to delete the dead units from the list. Soo Ai Enemy on dead :D echo("XXX Turret Count : ",$mySSet.getCount()); for (%i=0; %i<$mySSet.getCount(); %i++) { %TeamMate = $mySSet.getObject(%i); //All the units will ignore this unit %TeamMate.addToIgnoreList(%obj); //Read all the objects that are friends and add them to the ignore list of the turret. In this way the turret will ignore the team mates. %obj.addToIgnoreList(%TeamMate); } $mySSet.add(%obj);
Now you can start the game without changing the C++ code .

For debug purpuoes enter in the GUI editor and add "GuiButtonCtrl" from Library->Buttons.
Place it somewhere in the scene, give it a name, and in the Control tab you should find the "command" line, in the right column write (or call ) spawnAi();
With this function we can call enemies more easily.

Now is time to make a more advance path for the AI. For this we use the path system from torque 3d.

Go in to the Library - > Level.

Double click on the Path item. This action will place an Path object in the Scene Tree. Go back in the Scene Tree select the new path and rename it to MyPath( you can name it as you want).
This step is important: right mouse click on the Path and selet "Add New Objects Here", done select anything after.
Navigate back to the Library->Level and double click on the Path Node. It should be in the Path tree from the Scene Tree.

Image

Remember to deselect isLooping.

Now you can select every marker one by one and make a path with them.

I made a triangle :

Image

Now some script modification:

Open aiPlayer.cs and add a new function

Code: Select all

function spawnAiAtPath() { %path = "MissionGroup/MyPath"; %name = "AiEnemy"; %player = new AiPlayer() { dataBlock = DemoPlayer; path = ""; team = 2; }; if (!isObject(%path)) { echo("ERROR: you need to add a path"); return 0; } %node = %path.getObject(0); //Spawn the player at the first node of the path %player = AIPlayer::spawnAtLocation(%name, %node.getTransform()); %player.setMoveSpeed(0.5); //Sets the target node index of the path to be "-1". We wil take care of this later %player.followPath("MissionGroup/MyPath",-1); MissionCleanup.add(%player); }
Some small changes in the onReachDestination function. At the beginning of the function add this code :.

Code: Select all

if(%obj.currentNode >= (%obj.path.getCount() - 1)) { //TODO: should kill the AiEnemy and remove some lives from player %obj.damage(0, 0, 100000, 0); }
This code should be the first in the function.

Let's test it :

Go in the GUI editor and change the command that is called by the SpawnAi button to "spawnAiAtPath();"

You should see that the Ai player followed the path and at the end died. This gives us a problem, the money indicator went up and it should not do that.

As we increment the money value in the onDamage we need to check that the id of the AIAgent that triggered the function call (onDamage) is not killed by us when they complete the path.
To do this we create a variable to store the index of the object

Code: Select all

$var = 0; function DemoPlayer::onReachDestination(%this,%obj) { //echo( %obj @ " onReachDestination" ); // Moves to the next node on the path. // Override for all player. Normally we'd override this for only // a specific player datablock or class of players. if(%obj.currentNode >= (%obj.path.getCount() - 1)) { $var = %obj.getId(); //TODO: should kill the AiEnemy and remove some lives from player %obj.damage(0, 0, 100000, 0); $var = 0; } if (%obj.path !$= "") { if (%obj.currentNode == %obj.targetNode) { %this.onEndOfPath(%obj,%obj.path); } else { %obj.moveToNextNode(); } } }
Change the onDamage function to this :

Code: Select all

function DemoPlayer::onDamage(%this,%obj, %delta) { %val = 200; if(%obj.getstate() $="Dead") { //when ai enemy is dead the player will receive some money if($var != %obj.getId() ) { AddMoney(%val); } } }
Johxz
Posts: 443
Joined: Sat Feb 07, 2015 11:37 pm
by Johxz » Mon Feb 26, 2018 9:09 pm
oh wow nice! very handy.
Duion
Posts: 1082
Joined: Sun Feb 08, 2015 1:51 am
 
by Duion » Mon Feb 26, 2018 9:30 pm
Are you making a tower defense game?
Chelaru
Posts: 200
Joined: Wed Jul 01, 2015 10:33 am
by Chelaru » Mon Feb 26, 2018 9:38 pm
oh wow nice! very handy.
Thank you.
Are you making a tower defense game?
I try to. The best approach would be to write something in the code, but i wanted to show all the steps i did, all the mistakes.
Duion
Posts: 1082
Joined: Sun Feb 08, 2015 1:51 am
 
by Duion » Mon Feb 26, 2018 10:01 pm
@
User avatar
Chelaru

Ist it a hobby project or something commercial?

I think your approach is a bit too complicated, as you can just use the FPS camera and players, but instead use a free camera like spectator mode and placing of turrets is just made by where you shoot at. It would also be beneficial to have a more free camera as this shows the 3 dimensions better than just having a top down view you could also have in a 2D game.
Chelaru
Posts: 200
Joined: Wed Jul 01, 2015 10:33 am
by Chelaru » Mon Feb 26, 2018 10:35 pm
@Chelaru
Ist it a hobby project or something commercial?

I think your approach is a bit too complicated, as you can just use the FPS camera and players, but instead use a free camera like spectator mode and placing of turrets is just made by where you shoot at. It would also be beneficial to have a more free camera as this shows the 3 dimensions better than just having a top down view you could also have in a 2D game.

I'm just learning now.

The fixed up camera is only the first part, after some steps, i change the angle of the camera, to something more like starcraft 2 camera. The best approach would be to write some new controls for this type of player, as the current implementation uses some buttons to make to camera pan when the mouse is at the edge of the screen.
Jason Campbell
Posts: 266
Joined: Fri Feb 13, 2015 2:51 am
 
by Jason Campbell » Tue Feb 27, 2018 1:44 am
Thanks Chelaru, this is pretty cool. Very thorough yet concise. This would be a good exercise for anyone using T3D.
7 posts Page 1 of 1

Who is online

Users browsing this forum: No registered users and 1 guest