(solvedish) 40 obj limit crushes my game...different way to format it?

Started by slatkabundeva, Fri 09/02/2018 01:47:04

Previous topic - Next topic

slatkabundeva

So I am aiming to make a Harvest moon-esque game. I'm trying to hash out the farming mechanics before I go to far, now I'm wondering if it's even possible.

Initially I wanted to make the farming using a grid with hotspots and objects (ie using the hoe on the hotspot makes object dry soil visible, using the inventory object seed makes sowed soil visible. This may seem like a lot of objects but it's the scripting I have an easier time grasping, if it weren't for the object limit it would be possible.

Here is my layout with the temporary/working grid background. I then thought of changing to 150x150 squares instead of 50x50. then there would only be 32 plots. The problem is I need several objects for each plot (dry soil/ wet soil/ the  different phases of plants)which makes it over 40 items quickly. Is there an easy solution, or at least easyish enough to learn?
(screen size is set to 1280x720)


https://pasteboard.co/H6LPjBj.png

Code: ags

 ////////////////////       A1     /////////////////
//garden variables


  int A1tu ; ///A1 refers to square A1 which will be the top left square. tu is referring to tilled/untilled
  int A1wd ;  //// wd is referring to wet/dry




//player uses rusty hoe on the grass in A1 which tills the soil

function h1a_UseInv()             /////////hotspot for a1
{
if ((player.ActiveInventory == irustyhoe) && (A1tu < 3))

     {     A1tu += 1;
           vStam -=5;}
     
else if ((player.ActiveInventory == irustyhoe) && (A1tu == 3))
     {  oDryA1.Visible=true;
     vStam -=5;}

}
//  Sow Strawberry seeds

function oDryA1_UseInv()

{
if (player.ActiveInventory == iseedstrawberry) 
{
oSowA1.Visible=true;
vStam -=5;
player.LoseInventory (iseedstrawberry);
  }
}
 
//Water Strawberrys with Rusty can 

function oSowA1_UseInv()
{
  if ((player.ActiveInventory == irustyWC)&& (A1wd < 3))
  
  {A1wd += 1;
  vStam -=5;}
  
  else if ((player.ActiveInventory == irustyWC)&& (A1wd == 3))
  
  { oDryA1.Visible=false;
  oWetA1.Visible=true;}
  
 }

Gilbert

(I think a goal for the development of AGS is to remove such limits but I'm not sure whether this is in a released version, or whether it's being worked on yet.)

You may use characters to fake objects, but IMO this may not be the best solution.

As the stuff are put on a grid you may make a dynamic sprite the size of the field, assign it to a single object, and then use drawing surface commands to place tiles on it. If you what to which tile the player has clicked on the field you may use relatively simple calculation from coordinates of the cursor to determine.

Khris

Yes, this definitely calls for drawing the background yourself. I just want to add that an object is not necessary here; all that's required is to draw a tile anew when its state has changed.

You should also definitely look into using structs and arrays (arrays at the very least). The code for each square is exactly the same, which means it should only exist exactly once.


slatkabundeva

Thank you for the feedback. I've been reading the manual and starting to understand what these can do and how they can be better than objects for my purposes.
Are there any tutorials or simple demos anyone knows of to learn them better?

Khris

Not that I know of, but I can give you some example code. Best put this in a new script.

Code: ags
// header

enum SeedType { eSeedNone = 0, eSeedStrawberries = 1, eSeedCorn = 2 };

struct FieldTile {
  bool tilled, watered;
  SeedType seeds;
};

import FieldTile tile[100];


Code: ags
// main script

FieldTile tile[100]; // create tile[0] to tile[99]
export tile;


You can now do any of these from any script further down, i.e. Global or Room:

Code: ags
  tile[0].tilled = true;
  tile[56].watered = true;
  tile[4].seeds = eSeedStrawberries;


This way you can store all the tile info.

When it comes to drawing, you need to "convert" coordinates to a tile index and back.
Say you have 10x10 tiles of size 50, with the top left corner at 20,60
Code: ags
// handle mouse click
  int x = (mouse.x - 20) / 50;
  int y = (mouse.y - 60) / 50;
  int tile_index = x + y * 10;
  if (x < 0 || x >= 10 || y < 0 || y >= 10) return; // do nothing
  Display("you clicked on tile #%d", tile_index);

Two Tales

Quote from: slatkabundeva on Fri 09/02/2018 01:47:04
The problem is I need several objects for each plot (dry soil/ wet soil/ the  different phases of plants)which makes it over 40 items quickly. Is there an easy solution

Instead of several objects on 1 plot you can use 1 object and just keep changing it's view based on what's happening.

slatkabundeva

#6
Thanks for taking the time to help me. I have combined advice and implemented it in a way that works. My brain is mad at me but I am happy to have been pushed to learn a little more :)

I'm starting to understand the enums and arrays a little better. I did put the // handle mouse click part into my room and it does what it say "you clicked on tile." I'm just not sure how to combine that with the actual players interaction, so I will just use hotspots, but I no longer need to use objects :). I also applied using arrays to my friendship levels for npcs.  Now onto all the other challenges xD

Here's my new room script if curious
Code: ags

//garden variables for tool progress 
//(rusty hoe will take 3 "hits" as opposed gleaming hoe which only needs 1, ect.)


  int tillprog0;
  int wetprog0;



/////////
function h1a_UseInv()
{
  
  //rusty hoe
   if ((player.ActiveInventory == irustyhoe)&&(tile[0].tilled == false)&&(tillprog0 <3)){
   vStam -=5;
   tillprog0+=1; }
 
if ((player.ActiveInventory == irustyhoe)&&(tile[0].tilled == false)&&(tillprog0==3)){
tile[0].tilled = true;
 vStam -=5;
  }
 
 
 //Seeds
if ((tile[0].tilled == true)&&(player.ActiveInventory==iseedstrawberry)&&(tile[0].sowed==false)) {
  vStam -=5;
  tile[0].seeds=eSeedStrawberries; 
  tile[0].sowed=true;
}
 
 if ((tile[0].tilled == true)&&(player.ActiveInventory==iseedcorn)&&(tile[0].sowed==false)) {
  vStam -=5;
  tile[0].seeds=eSeedCorn; 
  tile[0].sowed=true;
}
 
 

// rusty watering can  
if ((player.ActiveInventory == irustyWC) && (tile[0].sowed ==true)&&(wetprog0<3)){
  vStam-=5;
  wetprog0 +=1;
}
 
 if ((player.ActiveInventory == irustyWC)&&(tile[0].tilled == true)&&(wetprog0==3)){

tile[0].watered=true;
vStam -=5;
 }
  
  
  
}


function room_RepExec()
{
  
  //     tile 0  Graphics       //
 if (tile[0].tilled == true)
 {
DrawingSurface *surface = Room.GetDrawingSurfaceForBackground();
surface.DrawImage(50,50, 64);
 surface.Release();   }
 
 
 if (tile[0].seeds==eSeedStrawberries)
 {
  DrawingSurface *surface = Room.GetDrawingSurfaceForBackground();
surface.DrawImage(50,50, 66);
 surface.Release();  }
 
 if (tile[0].watered==true)
 {
 DrawingSurface *surface = Room.GetDrawingSurfaceForBackground();
surface.DrawImage(50,50, 65, 50);
 surface.Release();  }


SMF spam blocked by CleanTalk