post

So here the fifth part finally is!

Hello guys,
Let me introduce you what we will be doing in the fifth part of this tutorial series:

  • Add buildings to buy in the shop
  • Make money by having a money generate building
  • Give the user money every hour.

License Agreement by downloading.
——————–
You may not sell this nor making a tutorial with the same code as i do.
You may alter the code and sell a complete php game without having to pay or credit me (only if you want to ;))
This is an open source project please share your modifications with the rest of the readers.
You must have fun scripting!
By downloading the files you agree with these terms.

Live DemoCheck it!

DownloadIts free!

 

Can’t open file? Download the extractor
——————–

First things first.

Some of my readers have done some wonderful jobs for the tutorial and sended me some assets!
The logo is designed by ShinDesign.
The template is designed by ShinDesign.
Some military units are designed by Mazing Studios.
WommbLogo_footer
I have added these assets to the tutorial and are downloadable in the download files of this part of the tutorial.
Just overwrite them in your webfolder. If you got your own template already then just follow the steps!

Lets get started with part 5!
Let’s start with adding some of the new building types where we can make money with.

Go to “http://localhost/phpmyadmin/” log in and select your database.

step1

Select the table: game_buildingtypes and add a new row with the given settings in the image.

Then add a new building to the “game_buildings” table with the settings in in the image

Now that we have done that we can create a new model to insert the buildings into the database for the right user who have bought them.

Create a new model with the name “game_buildings“.
And insert the basic commands for a new model file.

game_buildings.php

<?php if ( ! defined('BASEPATH')) exit('No direct script access allowed');

class Game_buildings extends CI_Model {

  function __construct() {
    parent::__construct();
  }

  function getItem($id = null) {
    
  }

  function getCost($id) {
    
  }

}

?>

New models we need to define in the configs.
So open up autoload.php found in ‘application/config/autoload.php
and change this line $autoload[‘model’] = array(‘game_users’, ‘game_units’, ‘game_army’);
to this:

autoload.php

$autoload['model'] = array('game_users', 'game_units', 'game_army', 'game_buildings');

We got the basic now prepared, lets start extending it and subtract the money from the player when he buy’s units.

First thing now we need is a new database table that holds the players buildings we keep this seperate from the army table to not bloat the table with much data.
Lets create the table and name it “game_base” with the following fields as given in the image:

tut5-3
before we can get it to work we need to create a new model “game_basemodel and lets add the following standard code to it.

game_base.php

<?php if ( ! defined('BASEPATH')) exit('No direct script access allowed');

class Game_base extends CI_Model {

  function __construct() {
    parent::__construct();
  } 

  function getBuildings($userID) {
    
  }

  function addBuildings($userID, $buildingID, $buildingAmount) {
    
  }

  function subtractBuildings($userID, $buildingID, $buildingAmount) {

  }

}

?>

New models we need to define in the configs.
So open up autoload.php found in ‘application/config/autoload.php
and change this line $autoload[‘model’] = array(‘game_users’, ‘game_units’, ‘game_army’, ‘game_buildings’);
to this:

autoload.php

$autoload['model'] = array('game_users', 'game_units', 'game_army', 'game_buildings', 'game_base');

Now that all is loaded and the base has been made we can actually start to code now.
Open up the model “game_base.php” and change the addbuildings() function into:

game_base.php

function addBuildings($userID, $buildingID, $buildingAmount) {
  if ( $userID == null || $buildingID == null || $buildingAmount == null ) {
    return json_encode(array('msg'=>'Something went wrong, please try again later.'));
  }
  $userMoney = $this->game_users->getMoney($userID);
  $buildingCost = $this->game_buildings->getCost($buildingID);
  $buildingTotalCost = $buildingAmount * $buildingCost;
  if ( $userMoney >= $buildingTotalCost ) {
    $query = $this->db->get_where('game_base',array('user'=>$userID, 'building_id'=>$buildingID));
    if ( $query->num_rows() > 0 ) {
      //update the current amount of units for the player
      $result = $this->db->set('building_amount', 'building_amount+'.$buildingAmount, FALSE)->where(array('user'=>$userID,'building_id'=>$buildingID))->update('game_base');
    } else {
      //first time have this units, create a clean army for the player
      $result = $this->db->insert("game_base", array('user'=>$userID,'building_id'=>$buildingID,'building_amount'=>$buildingAmount));
    }
    if ( $result ) {
      $this->game_users->subtractMoney($userID,$buildingTotalCost);
      return json_encode(array('msg'=>'You have bought new buildings.'));
    } else {
      return json_encode(array('msg'=>'Something went wrong, please try again later.'));
    }
  } else {
    return json_encode(array('msg'=>'You don\'t have enough money to buy these buildings.'));
  }
}

To make this script work we need to edit the model “game_buildings”.

Since we allready made a script like the one we want we can copy it and change it a bit (see the game_units model), open the modelgame_buildings” and change these functions with this code:

game_buildings.php

function getItem($id = null) {
  if( $id === null ) {
    $this->db->order_by("buildingcost","asc");
    $query = $this->db->get("game_buildings");
    return $query->result();
  } else {
    $query = $this->db->get_where('game_buildings', array('id' => $id));
    if ( $query->num_rows() > 0 ) {
      return $query->row(); 
    }
    return null;
  }
}

function getCost($id) {
  if ( $id == null ) {
    return null;
  }
  $query = $this->db->get_where('game_buildings', array('id' => $id));
  if ( $query->num_rows() > 0 ) {
    $row = $query->row(); 
    return $row->buildingcost;
  }
  return null;
}

We can now buy buildings, lets activate it in the controller of the shop’s buy button.
We need to change some code from the index() function in the controller named “shop.php
Change the “if statement” code to this code:

shop.php

if ( $this->input->post() ) {
  $loggedUser = $this->game_users->getByUsername($this->session->userdata('game_username'));
  $userID = $loggedUser->id;
  $buying = explode("-",key($this->input->post()));
  $id = $buying[1];
  $amount = 0+intval($this->input->post(key($this->input->post())));

  if ( $buying[0] == 'game_units' ) {
    $return = json_decode($this->game_army->addArmy($userID, $id, $amount));
  } elseif ( $buying[0] == 'game_buildings' ) {
    $return = json_decode($this->game_base->addBuilding($userID, $id, $amount));
  }

  if ( $return ) {
    $this->smarty_lib->assign('loginMessage', "<div class='errorMsg'><p>{$return->msg}</p></div><br/>");
  }
}

And add this just before the $this->smarty_lib calls:

shop.php

$content .= "<h3>Shop (buildings)</h3><table cellpadding='0' cellspacing='0' style='width: 100%;'>";
$content .= "<thead><tr><th>&nbsp;</th><th>Name:</th><th>Attack:</th><th>Defense:</th><th>Health:</th><th>Price:</th><th></th></tr></thead><tbody>";
foreach ( $this->game_buildings->getItem() as $item ) {
  $content .= "<tr>";
  $content .= "<td>".$item->image."</td>";
  $content .= "<td>".$item->name."</td>";
  $content .= "<td>".$item->attackpoints."</td>";
  $content .= "<td>".$item->defensepoints."</td>";
  $content .= "<td>".$item->healthpoints."</td>";
  $content .= "<td>".$item->buildingcost."</td>";
  $content .= "<td><form method='post'><input type='text' name='game_buildings-{$item->id}' /> <input type='submit' value='Buy'></form></td>";
  $content .= "</tr>";
}
$content .= "</tbody></table>";

Now the shop is extended with buildings! We can buy buildings but they dont appear in our overview yet.
Lets update our overview with buildings that we (or others) have bought.

Open the controller named “player.php” and add this code just before the $this->smarty_lib calls again.

player.php

$content .= '<br/>
  <strong>Buildings</strong><br/>
  <table cellpadding="0" cellspacing="0" style="width: 100%;"><thead><tr><th>&nbsp;</th><th>Name:</th><th>Amount:</th></tr></thead><tbody>'
;
$playersBase = $this->game_base->getBuildings($player->id);
if ( isset($playersBase) && !empty($playersBase) ) {
  foreach( $playersBase as $base ) {
    $baseBuilding = $this->game_buildings->getItem($base->building_id);
    $content .= "<tr>";
    $content .= "<td>".$baseBuilding->image."</td>";
    $content .= "<td>".$baseBuilding->name."</td>";
    $content .= "<td>".$base->building_amount."</td>";
    $content .= "</tr>";
  }
}
$content .= "</tbody></table>";

The overview page is working for the player.
Check if it is all still working for you (if not try to fix the error’s or leave me a post with the error you get)

 

Now that we copy, paste and edited this part for the buildings we want to generate money for the player for each ‘Oil Platform (in my example)‘ .
Let’s say that the player earn’s 100 coins each hour in a day without having any building that generates money so he can buy units / buildings when the players Oil Platforms are destroyed.
So the player can continue the game, but is less valueble for the player to attack.
And an additional 10 coins for each Oil Platform the player has.

 To make a timer that calculates like everything, there are multiple options and the best one is with a cronjob but this can only be achieved if your host support it. Also we could do it by httprequest and calculate the time diffrence but also for this option we can only do it if our host supports it.
To help everyone (i hope) with this problem about what to use, we will calculate time diffrences but not with httprequest! we will use javascript for this cause everyone can run javascript on their host.

To create something that is robust enough for this so everyone gets its money by the money buildings he owns and the default salary every hour we have to code many new things.
Grab yourself a drink and something to snack before you start with this quest.
If at the end of this tutorial you (still) have errors on your screen or things arn’t working like my example, dont be affraid to leave your problem in this post!

Ok lets do this!

Lets start by creating a new database, open your ” phpMyAdmin” and fill in the same settings as in the image:

tut5-4

We should create a fake cronjob controller we can call and with a little change could attach to a real cronjob.
Create a new file in the controller directory and call it cronjob.php.
I have commented this part so it will take lesser space in the tutorial and hopefully easier to understand.

cronjob.php

<?php if ( ! defined('BASEPATH')) exit('No direct script access allowed');

class Cronjob extends CI_Controller {

  function __construct() {
    parent::__construct();
  }

  function index() {
    // Only run this script when a user is logged in, minimize the request data for every guest on the site.
    if($this->session->userdata('game_username')) {
      //Only load the model when we need it and that is only in this script.
      $this->load->model("game_cronjoblog");
      // Get the last cron run record for the type 'money'
      $result = $this->game_cronjoblog->getLastCron("money");
      if( isset($result) ){
        // the time now in unix standard minus the last executed cron time is the time left for a new cron call.
        $timepast = ( strtotime(date('Y-m-d H:i:s')) - $result->executed_time );
        // if 1 hour or more has passed since last call.
        if( $timepast >= 3600 ){
          // calculate how many hours have past since the last call.
          $payoutTimes = floor($timepast/3600);
          // for every hour times the money earned is the payout a player gets without any buildings, 100 is the standard money the player gets each hour.
          $cleanPayout = $payoutTimes * 100;
          // grab all the buildings from the database that have been flagged as money generators
          $playersActive = $this->game_base->getMoneyBuildings();
          $payout = array();
          // go throught the player list of players with atleast one money building.
          foreach($playersActive as $key => $value) {
            // calculate the money a player gets and store it in an array.
            if( !isset($payout[$value->user]) ){
              $payout[$value->user] = 0+$value->earn;
            }else{
              $payout[$value->user] = ($payout[$value->user]+$value->earn);
            }
          }
          // loop through the stored array with players and their money
          foreach($payout as $user_id => $money) {
            // give every player his earned cash!
            $this->game_users->addMoney($user_id,$money);
          }

          // give every player the standard money
          $this->game_users->addMoney(null,$cleanPayout);
          // and as last we need to update the cron log as we just ran a new cronjob.
          $this->game_cronjoblog->setLastCron("money");
          echo 'You got paid!';
        }else{
          echo date("i:s",3600-$timepast);
        }
      }else{
        // if no cronjob log is found, create one as startpoint for the cronjob.
        $this->game_cronjoblog->setLastCron("money");
        echo 'Out of sync!';
      }
    } else {
      echo '';
    }
  }

}
?>

That is it for the controller, now we need to create the model to get and set the database data.
Make a new model and call it game_cronjoblog.php

game_cronjoblog.php

<?php if ( ! defined('BASEPATH')) exit('No direct script access allowed');

class Game_cronjoblog extends CI_Model {

  function __construct() {
    parent::__construct();
  }

  //Get the last cronjob log with the action named ...
  function getLastCron($action = null) {
    if ( $action === null ) {
      return null;
    } else {
      $query = $this->db->order_by('executed_time', 'DESC')->limit(1)->get_where('game_cronjoblog', array('action' => $action));
      if ( $query->num_rows() > 0 ) {
        return $query->row();
      }
      return null;
    }
  }

  //Set a new cronjob log with the action named ...
  function setLastCron($action = null) {
    if ( $action === null ) {
      return null;
    } else {
      $data = array(
        'executed_at' => strtotime(date('Y-m-d H:i:s')),
        'executed_time' => strtotime(date('Y-m-d H:00:00')),
        'action' => $action
      );

      $this->db->insert('game_cronjoblog', $data);
      return true;
    }
  }

}
?>

We are almost there, lets call the controller with javascript now and hopefull we will see the database get updated.

Open the template in views named “template_footer.tpl” and add the next code just before the </body> tag

template_footer.tpl

{if $this->session->userdata('game_username')}
  {literal}
    <script>
      var xhr = new XMLHttpRequest();
      xhr.open("GET","{/literal}{$smarty.const.BASE_URL}{literal}cronjob",true);
      xhr.addEventListener('load',function(){
        if(xhr.status === 200){
          jQuery("#menu p").append("<div id='timer'>Salary timer: "+xhr.response+"</div>");
          var timer = xhr.response.split(':');
          var minutes = parseInt(timer[0], 10);
          var seconds = parseInt(timer[1], 10);
          var interval = setInterval(function() {
            seconds = seconds-1;
            if(seconds <= 0 && minutes > 0){
              minutes = minutes-1;
              seconds = 59;
            }
            jQuery('#timer').html('Salary timer: '+ minutes + ':' + seconds);
            if (parseInt(minutes, 10) == 0 && parseInt(seconds, 10) == 0)
              clearInterval(interval);
          }, 1000);
        }
      },false);
      xhr.send();
    </script>
  {/literal}
{/if}

At this point we have a script that calls our cronjob code, and the cronjob code checks the database for values needed to calculate if the time has passed to update the players money.
We only need a call to the datebase and get all the buildings that gives us money. 
Lets add the function, open the model named “game_base.php” and add the next function.

game_base.php

function getMoneyBuildings() {
  $sql = "SELECT game_base.user, game_buildings.name, (game_base.building_amount * game_buildings.value) as earn FROM `game_base` left join game_buildings on game_base.building_id = game_buildings.id inner join game_buildingtypes on game_buildings.type = game_buildingtypes.id where game_buildingtypes.name = 'Money'";
  return $this->db->query($sql)->result();
}

And finally open the model named “game_users.php” and add the function:

game_users.php

function addMoney($userID, $total){
  $result = $this->db->set('money', 'money+'.$total, FALSE)->where('id', $userID)->update('game_users');
  if ( $result ) {
    return true;
  } else {
    return false;
  }
}

And in the same script change the “getMoney($userID)”  function to:

game_users.php

function getMoney($userID) {
  if( $userID == null ) {
    return null;
  }
  $query = $this->db->get_where('game_users', array('id' => $userID));
  if ($query->num_rows() > 0){
    $row = $query->row();
    return $row->money;
  }
  return null;
}

Damn we just added many codes to our game. Dont forget to save all of your hard work and test if its working!


Voila! we did it again, part 5 of the tutorial added something new and cool to the game but we do not have a game yet! Next part we will focus on some new parts of the game.
Thank you for reading this part, i hope you liked it.
In the next part we finally be able to attack eachother! so stay tuned and prepare your army for the next update 😉

For those design people out there reading this and think the demo looks ugly, just send me some icons/design’s etc. to make this tutorial better to look at for everyone 😉 just like some guy’s have done already to create a nice playable community game! Also leave your comments about what u think of the game and what you would like to see changed in the future.

License Agreement by downloading.
——————–
You may not sell this nor making a tutorial with the same code as i do.
You may alter the code and sell a complete php game without having to pay or credit me (only if you want to ;))
This is an open source project please share your modifications with the rest of the readers.
You must have fun scripting!
By downloading the files you agree with these terms.

Live DemoCheck it!

DownloadIts free!

 

Can’t open file? Download the extractor
——————–

Facebook Comments