Envision, Create, Share

Welcome to HBGames, a leading amateur game development forum and Discord server. All are welcome, and amongst our ranks you will find experts in their field from all aspects of video game design and development.

Day/Night and Onscreen Clock! Plus Clear Lights

Star

Sponsor

Idea1.png

This is me taking a screenshot of my game and putting it in a paint program and making my own lights using another layer

Idea2.png

This is me having lights appear at night in my game. As you can see the lights go over top of the dark layer and don't actually clear it up. I wanna able to open up the dark layer.

Any ideas on how I could go about working around this?
 
Thanks, we're focusing on the technique to get the lights to display correctly, and efficiently right now.
It won't take a whole lot to make it 'marketable' once we have the details worked out.

By "Current Time", do you mean in-game clock time? or your computer's real time?
Right now the "Game Time" is being controlled outside of the script with a game variable set to 'minutes' (so, 1440 per day)
That way the game developer can set it any way they want to.
It would be pretty easy to throw in a couple methods in a Module probably to expose the 'month', 'day', 'hour', 'minute'....

TTFN
 

Star

Sponsor

Brewmeister":dipnaqhr said:
Thanks, we're focusing on the technique to get the lights to display correctly, and efficiently right now.
It won't take a whole lot to make it 'marketable' once we have the details worked out.

By "Current Time", do you mean in-game clock time? or your computer's real time?
Right now the "Game Time" is being controlled outside of the script with a game variable set to 'minutes' (so, 1440 per day)
That way the game developer can set it any way they want to.
It would be pretty easy to throw in a couple methods in a Module probably to expose the 'month', 'day', 'hour', 'minute'....

TTFN
http://www.mediafire.com/download.php?07pt3aylwi3738q

You didn't see my current version of the test. I have the game time being controlled by the script. With an on screen clock. I hope I'm not invisible here :P

I also spruced it up ready for a release the the pub. I'm sure we could get more, but version updates are always an option.
 
I meant ingame time... real time is only fancy for a script like this if you play a game for hours and hours, and even then you probably wouldn't notice. That being said, it's not like it wouldn't be a 2 minutes copy&paste job :p

Game variable is questionable, though... as the name states, their intention is to be used ingame. While being slightly more effort-taking on the user (and only if they're not used working with the script input fields of the conditional branches), I'd switch it to Game_System or something of the sort, which gives you about as easy access with more transparency... well, in theory, as most people would probably be confused by a justified variable alignment rather than by a game variable used for time... but yeah, that's my two cents ^^
 

Star

Sponsor

Code:
=begin

---------------------------------------------

DAY_NIGHT_LIGHT_SYSTEM

---------------------------------------------

by 

- Brewmeister

- Gubid

- Star 

---------------------------------------------

=end

 

 

#-----------------------------------

# Editing of the Script

#-----------------------------------

 

 

# If Flickercolon is true the : in the 00:00 flashes every second

#-----------------------------------

FLICKERCOLON = true

 

# Hour_variable is the variable of the current hour

#-----------------------------------

HOUR_VARIABLE = 9

 

# Inside_Switch is the switch set to make insides darker, not meant for caves

#-----------------------------------

 

INSIDE_SWITCH = 9

 

 

# Cave_Switch is the switch set meant for caves

#-----------------------------------

CAVE_SWITCH = 11

 

# if AM_AND_PM is true, everything is not in military time

#-----------------------------------

AM_AND_PM = true

 

# Starthour is the hour the game starts at

#-----------------------------------

STARTHOUR = 1

 

# New_hour is the variable that changes the current hour.  You must use this in

# order to change the hour.  It will not tell you the current hour, only

# Hour_variable can tell the current hour.

#-----------------------------------

NEW_HOUR = 10

 

# Set this switch to on in order to hide the clock

#-----------------------------------

INVISIBLE_TIMER_SWITCH = 10

 

 

Code:
class Bitmap

  def sub(ox,oy,light)

    ox -= (light.width / 2)

    oy -= (light.height / 2)

    for x in 0...light.width

      for y in 0...light.height

        lt_color = light.get_pixel(x,y)

        ds_color = self.get_pixel(x + ox,y + oy)

        ds_color.alpha -= lt_color.alpha

        self.set_pixel(x + ox,y + oy,ds_color)

      end

    end

  end

end

Code:
class Star_lighting

  def initialize

  $game_variables[HOUR_VARIABLE] = STARTHOUR

  end

end

Code:
class Game_System  

  attr_reader   :map_interpreter          # map event interpreter

  attr_reader   :battle_interpreter       # battle event interpreter

  attr_accessor :timer                    # timer

  attr_accessor :timer_working            # timer working flag

  attr_accessor :save_disabled            # save forbidden

  attr_accessor :menu_disabled            # menu forbidden

  attr_accessor :encounter_disabled       # encounter forbidden

  attr_accessor :message_position         # text option: positioning

  attr_accessor :message_frame            # text option: window frame

  attr_accessor :save_count               # save count

  attr_accessor :magic_number             # magic number

  #--------------------------------------------------------------------------

  # * Object Initialization

  #--------------------------------------------------------------------------

  def initialize

    @map_interpreter = Interpreter.new(0, true)

    @battle_interpreter = Interpreter.new(0, false)

    @timer = STARTHOUR * 2400

    @timer_working = true

    @save_disabled = false

    @menu_disabled = false

    @encounter_disabled = false

    @message_position = 2

    @message_frame = 0

    @save_count = 0

    @magic_number = 0

    @timer_remember = 0

  end

def update

    # reduce timer by 1

    if @timer_working

      if @timer > 57600

        @timer = 0

      else

          if @timer_remember != 0 and @timer != @timer_remember

          @timer = @timer_remember

          @timer_remember = 0

          else

          @timer += 1

          end

      end

    elsif @timer_remember != @timer

      @timer_remember = @timer

    end

  end

end

Code:
#==============================================================================

# ** Sprite_Timer

#------------------------------------------------------------------------------

#  This sprite is used to display the timer.It observes the $game_system

#  class and automatically changes sprite conditions.

#==============================================================================

 

class Sprite_Timer < Sprite

  #--------------------------------------------------------------------------

  # * Object Initialization

  #--------------------------------------------------------------------------

  def initialize

    super

    self.bitmap = Bitmap.new(120, 20)

    self.bitmap.font.name = "Arial"

    self.bitmap.font.size = 15

    self.x = 620 - self.bitmap.width

    self.y = 0

    self.z = 2000

    @flicker = true

    update

  end

  #--------------------------------------------------------------------------

  # * Dispose

  #--------------------------------------------------------------------------

  def dispose

    if self.bitmap != nil

      self.bitmap.dispose

    end

    super

  end

  #--------------------------------------------------------------------------

  # * Frame Update

  #--------------------------------------------------------------------------

 

  def update

    super

    # Set timer to visible if working

    if $game_switches[INVISIBLE_TIMER_SWITCH] == true

    self.visible = false 

  else

    self.visible = true

    end

        if $game_variables[NEW_HOUR] != 0 and

          $game_variables[NEW_HOUR] != $game_variables[HOUR_VARIABLE]

      $game_system.timer = $game_variables[NEW_HOUR] * 2400

      if  $game_system.timer > 57600

        $game_system.timer = -57600

      end

      $game_variables[NEW_HOUR] = 0

      end

    # If timer needs to be redrawn

    if $game_system.timer / Graphics.frame_rate != @total_sec and $game_system.timer_working

      # Clear window contents

      self.bitmap.clear

      # Calculate total number of seconds

      @total_sec = $game_system.timer / Graphics.frame_rate

      # Make a string for displaying the timer

      case $game_variables[HOUR_VARIABLE]

      when 0,1,2,3,4,5,18,19,20,21,22,23 

      moon_and_sun = RPG::Cache.picture("Moon")

      cw = moon_and_sun.width 

      ch = moon_and_sun.height 

      rect = Rect.new(0, 0, cw, ch)

      when 6,7,8,9,10,11,12,13,14,15,16,17

      moon_and_sun = RPG::Cache.picture("Sun")

      cw = moon_and_sun.width 

      ch = moon_and_sun.height 

      rect = Rect.new(0, 0, cw, ch)

      end

      if AM_AND_PM == true

        if $game_variables[HOUR_VARIABLE] > 12

          min = (@total_sec - 720) / 60

          sec = @total_sec % 60

        else

          min = @total_sec / 60

          sec = @total_sec % 60

        end

            if $game_variables[HOUR_VARIABLE] > 11 and $game_variables[HOUR_VARIABLE] != 23

              setting = "PM"

            else

              setting = "AM"

            end

            if FLICKERCOLON == true and @flicker == false

            text = sprintf("%02d %02d " + setting, min, sec)

             @flicker = true

          else

            text = sprintf("%02d:%02d " + setting, min, sec)

            if FLICKERCOLON == true

              @flicker = false

            end

          end

      else

        min = @total_sec / 60

        sec = @total_sec % 60

        text = sprintf("%02d:%02d", min, sec)

        end

      if $game_variables[HOUR_VARIABLE] > 12 and AM_AND_PM == true

      $game_variables[HOUR_VARIABLE] = min + 12

      else

      $game_variables[HOUR_VARIABLE] = min

      end

      $sec = sec

      # Draw timer

      rect2 = Rect.new(1, 1, 120, 20)

      self.bitmap.font.color.set(0, 0, 0)

      self.bitmap.draw_text(rect2, text, 1)

      self.bitmap.font.color.set(255, 255, 255)

      self.bitmap.draw_text(self.bitmap.rect, text, 1)

      self.bitmap.blt(90, 0, moon_and_sun, rect)

      end

  end

end

 

Code:
class Game_Event < Game_Character

  attr_reader :erased

  attr_accessor :is_light

  alias init_gm_evnt_lights initialize

  def initialize(*args)

    init_gm_evnt_lights(*args)

    @is_light = false

  end

  alias refresh_gm_evnt_lights refresh

  def refresh

    tmp_page = @page

    refresh_gm_evnt_lights

    if tmp_page != @page

      @is_light = false

    end

  end

end

Code:
 

class Nighttime < Sprite

  def initialize(x,y)

    super()

    @width = $game_map.width * 32

    @height = $game_map.height * 32

    @lights = {}

    self.x = x

    self.y = y

    self.bitmap = Bitmap.new(@width, @height)

    self.bitmap.clear

    fillnight

  end

  def refresh

    self.bitmap.clear

    create_lights

    fillnight

  end

  

  def create_lights

    for event in $game_map.events.values

      for i in 0...event.list.size

        if event.list[i].code == 108 #comment

          if event.erased and event.list[i].parameters[0].include?("light")

            @lights.delete(event)

            next

          elsif event.list[i].parameters[0].include?("light")

            size = event.list[i].parameters[0].delete("light").to_i #convert text to interger

            @lights[event] = Light.new(event, size) unless @lights.keys.include?(event)

            event.is_light = true

            next

          end

        end

      end

      #in the event page is changed and it is no longer a light.. remove it. 

      if @lights[event] != nil and event.is_light == false

        @lights.delete(event)

      end

    end

  end

  def fillnight

    if $sec == nil

      $sec = 0

    end

    if $game_switches[INSIDE_SWITCH] == true

      extralpha = 10

    else

      extralpha = 0

      end

     case $game_variables[HOUR_VARIABLE] 

    when 0, 1, 23

    startop = 210 - extralpha

    when 2

    startop = 210 - ($sec / 2) + extralpha

    when 3

    startop = 180 - ($sec / 2) + extralpha

    when 4

    startop = 150 - ($sec / 2) + extralpha

    when 5

    startop = 120 - ($sec / 2) + extralpha

    when 6

    startop = 90 - ($sec / 2) + extralpha

    when 7

    startop = 60 - ($sec / 2) + extralpha

    when 8

    startop = 30 - ($sec / 2) + extralpha

    when 9, 10, 11, 12, 13, 14, 15, 16

    startop = 0 + extralpha

    when 17

    startop = 30 + ($sec / 2) + extralpha

    when 18

    startop = 60 + ($sec / 2) + extralpha

    when 19

    startop = 90 + ($sec / 2) + extralpha

    when 20

    startop = 120 + ($sec / 2) + extralpha

    when 21

    startop = 150 + ($sec / 2) + extralpha

    when 22

    startop = 180 + ($sec / 2) + extralpha

  end

  if $game_switches[CAVE_SWITCH] == true

    startop = 210

    end

    

    self.bitmap.fill_rect(0, 0, @width, @height, Color.new(0,0,0,255))

    self.opacity = startop

    # Now subtract out the lights

    # Testing with a single light at tile 7,11

    apply_lights

  end

  def apply_lights

    applied_space = []

    for light in @lights.values

      image_sub = RPG::Cache.picture("LightSUB").clone

      image_blt = RPG::Cache.picture("LightBLT").clone

      base_rect = image_sub.rect

      overlapLights = []

      size = (light.size/100.0)

      lwidth = base_rect.width*size

      light_rect = Rect.new(light.x-(lwidth/2), light.y-(lwidth/2), lwidth, lwidth)

      for applied_rect in applied_space

        if light_rect.overlap?(applied_rect)

          overlapLights << light_rect.area_in_overlap(applied_rect)

        end

      end

      #now draw it 

      if overlapLights.size == 0 #no overlap detected.. then just BLT it into the image

        self.bitmap.fill_rect(light_rect, Color.new(0,0,0,0))

        self.bitmap.stretch_blt(light_rect, image_blt, base_rect) 

      else

        self.bitmap.sub(light.x,light.y,image_sub)

      end

      applied_space << light_rect

      image_sub.dispose

      image_blt.dispose

    end

  end

  def update

    if $game_switches[INSIDE_SWITCH] == true

      extralpha = 10

    else

      extralpha = 0

      end

    case $game_variables[HOUR_VARIABLE] 

    when 0, 1, 23

    self.opacity = 210 - extralpha

    when 2

    self.opacity = 210 - ($sec / 2) + extralpha

    when 3

    self.opacity = 180 - ($sec / 2) + extralpha

    when 4

    self.opacity = 150 - ($sec / 2) + extralpha

    when 5

    self.opacity = 120 - ($sec / 2) + extralpha

    when 6

    self.opacity = 90 - ($sec / 2) + extralpha

    when 7

    self.opacity = 60 - ($sec / 2) + extralpha

    when 8

    self.opacity = 30 - ($sec / 2) + extralpha

    when 9, 10, 11, 12, 13, 14, 15, 16

    self.opacity = 0 + extralpha

    when 17

    self.opacity = 30 + ($sec / 2) + extralpha

    when 18

    self.opacity = 60 + ($sec / 2) + extralpha

    when 19

    self.opacity = 90 + ($sec / 2) + extralpha

    when 20

    self.opacity = 120 + ($sec / 2) + extralpha

    when 21

    self.opacity = 150 + ($sec / 2) + extralpha

    when 22

    self.opacity = 180 + ($sec / 2) + extralpha

    end

      if $game_switches[CAVE_SWITCH] == true

    startop = 210

    end

    end

end

class Rect

  def overlap?(rect)

    corners = []

    corners << [rect.x, rect.y] #UL

    corners << [rect.x+rect.width, rect.y] #UR

    corners << [rect.x+rect.width, rect.y+height] #LR

    corners << [rect.x, rect.y+height] #LL

    for corner in corners

      if corner[0].between?(self.x, self.x+width) and corner[1].between?(self.y, self.y+height)

        return true

      end

    end

    return false

  end

  def area_in_overlap(rect)

    return rect

  end

end

class Light

  def initialize(event, size)

    @event = event

    @size = size

  end

  def size

    return @size

  end

  def x

    return @event.real_x/4 + 16

  end

  def y

    return @event.real_y/4 + 16

  end

end

 

Code:
 

 

class Spriteset_Map

  alias init_spr_map_lights initialize 

  def initialize

    # Make nighttime sprite

    @nighttime = Nighttime.new(0,0)

    @nighttime.z = 2000

    init_spr_map_lights

    @inside_dark = true

    @second_counter = 60

    @nighttime.refresh

    @map_idd = $game_map.map_id

  end

   alias dns_dispose dispose

   def dispose

     dns_dispose

     @nighttime.dispose

   end

  alias upd_spr_map_lights update

  def update

    upd_spr_map_lights 

    # Update nighttime sprite

    @nighttime.ox = $game_map.display_x / 4

    @nighttime.oy = $game_map.display_y / 4

    if @inside_dark == true and $game_switches[INSIDE_SWITCH] == true

      @inside_dark = false

      @nighttime.refresh

    elsif @inside_dark == false and $game_switches[INSIDE_SWITCH] == false

      @inside_dark = true

      @nighttime.refresh

    end

    if @map_idd != $game_map.map_id

      @nighttime.refresh

      @map_idd = $game_map.map_id

      end

    if @second_counter == nil

      @second_counter = 60

    end

    if $game_system.timer_working and $sec != nil

      if $sec < @second_counter

      @nighttime.update  

      @second_counter = $sec

      end

      end

    @nighttime.update

  end

end

Oh right, you don't have an editor. Here's the script. Yeah, I've been using Game_System. I've yet to figure out a formula to where a person could make how many real time minutes they want in a day, but I think I got it close in my head so people won't have to stick with 24 min = game day. It'll also be real easy to add Game_Day_Number += 1 to

here

Code:
      if  $game_system.timer > 57600

        $game_system.timer = -57600

      end
and here
Code:
 

    if @timer_working

      if @timer > 57600

        @timer = 0
 
Looking good!!!

If you add this to DNS EDIT:

# Set GAMEDAY to the number of real minutes in a game day.
#-----------------------------------
GAMEDAY = 24
# don't edit FPD (frames per day)
FPD = GAMEDAY * Graphics.frame_rate * 60


Then replace 57600 with FPS
and replace 2400 with (FPS / 24)

for compatibility, we should probably make a copy of Game_System.timer (maybe: dns_timer)
and a copy of Sprite_Timer (maybe: Sprite_Clock)
so that the default timer can still be used.

I think the graphic needs to be modified to 'fade out' more as it approaches the edges, but the user can implement their own light graphic.

I don't quite understand...

if  $game_system.timer > 57600
$game_system.timer = -57600
end

in Sprite_Timer.update

did you mean to use: $game_system.timer -= 57600
if so, the conditional should probably be >=

Or, instead of the if statement, just use

$game_system.timer % 57600
now..
$game_system.timer % FPD
 

Star

Sponsor

Brewmeister":1taa3rkd said:
Looking good!!!

If you add this to DNS EDIT:

# Set GAMEDAY to the number of real minutes in a game day.
#-----------------------------------
GAMEDAY = 24
# don't edit FPD (frames per day)
FPD = GAMEDAY * Graphics.frame_rate * 60


Then replace 57600 with FPS
and replace 2400 with (FPS / 24)

I was thinking this. But then I tried it and ran into further problems. I ended up doing it a really simple way I never thought of before.. It was this

@timer += (1 * (24/GAME_DAY_IN_REAL_MINUTES))

Increasing the @timer faster depending on if minutes was less



Brewmeister":1taa3rkd said:
for compatibility, we should probably make a copy of Game_System.timer (maybe: dns_timer)
and a copy of Sprite_Timer (maybe: Sprite_Clock)
so that the default timer can still be used.
I couldn't figure out how to do this without adding further compatiablity issues, but I'm all ears. How do I make @Sprite_Timer = @Sprite_Clock.new in Spriteset_Map and the Interpreter Commands for starting and stopping timer without using or overwriting the whole method from the original class.


Brewmeister":1taa3rkd said:
I think the graphic needs to be modified to 'fade out' more as it approaches the edges, but the user can implement their own light graphic.
I also think the graphic should go underneath priority of 2 or greater on the map, but I haven't the faintest clue how to do that xD

Brewmeister":1taa3rkd said:
I don't quite understand...

if  $game_system.timer > 57600
$game_system.timer = -57600
end

in Sprite_Timer.update

did you mean to use: $game_system.timer -= 57600
if so, the conditional should probably be >=

Or, instead of the if statement, just use

$game_system.timer % 57600
now..
$game_system.timer % FPD
Epic fail on my part, nice catch.

Here's the newest Script
Code:
=begin

---------------------------------------------

DAY_NIGHT_LIGHT_SYSTEM

---------------------------------------------

by 

- Brewmeister

- Gubid

- Star 

---------------------------------------------

=end

 

 

#-----------------------------------

# Editing of the Script

#-----------------------------------

 

 

# How many real time minutes does it take for a whole gameday to go by?

# Normal time would be 24 minutes so a minute in game goes by every second.

#-----------------------------------

GAME_DAY_IN_REAL_MINUTES = 4

 

 

# Current_Game_Day is the variable of the current day

#-----------------------------------

CURRENT_GAME_DAY = 15

 

# Day you want Game_Day to start at.

#-----------------------------------

INTIALIZE_GAME_DAY = 11

 

 

# If Flickercolon is true the : in the 00:00 flashes every second

#-----------------------------------

FLICKERCOLON = true

 

# Hour_variable is the variable of the current hour

#-----------------------------------

HOUR_VARIABLE = 9

 

# Inside_Switch is the switch set to make insides darker, not meant for caves

#-----------------------------------

INSIDE_SWITCH = 9

 

# Inside_Opacity is the opacity set to increase when entering insides

#-----------------------------------

INSIDE_OPACITY = 10

 

# Cave_Switch is the switch set meant for caves

#-----------------------------------

CAVE_SWITCH = 11

 

# Cave_Opacity is the total opacity you want when entering caves.  Generally

# Should be set higher than the highest darkness.

#-----------------------------------

CAVE_OPACITY = 220

 

# if AM_AND_PM is true, everything is not in military time

#-----------------------------------

AM_AND_PM = true

 

# Starthour is the hour the game starts at

#-----------------------------------

STARTHOUR = 20

 

# New_hour is the variable that changes the current hour.  You must use this in

# order to change the hour.  It will not tell you the current hour, only

# Hour_variable can tell the current hour.

#-----------------------------------

NEW_HOUR = 10

 

# Set this switch to on in order to hide the clock

#-----------------------------------

INVISIBLE_TIMER_SWITCH = 10

 

 

 
Code:
class Bitmap

  def sub(ox,oy,light)

    ox -= (light.width / 2)

    oy -= (light.height / 2)

    for x in 0...light.width

      for y in 0...light.height

        lt_color = light.get_pixel(x,y)

        ds_color = self.get_pixel(x + ox,y + oy)

        ds_color.alpha -= lt_color.alpha

        self.set_pixel(x + ox,y + oy,ds_color)

      end

    end

  end

end
Code:
class Game_System  

  attr_reader   :map_interpreter          # map event interpreter

  attr_reader   :battle_interpreter       # battle event interpreter

  attr_accessor :timer                    # timer

  attr_accessor :timer_working            # timer working flag

  attr_accessor :save_disabled            # save forbidden

  attr_accessor :menu_disabled            # menu forbidden

  attr_accessor :encounter_disabled       # encounter forbidden

  attr_accessor :message_position         # text option: positioning

  attr_accessor :message_frame            # text option: window frame

  attr_accessor :save_count               # save count

  attr_accessor :magic_number             # magic number

  #--------------------------------------------------------------------------

  # * Object Initialization

  #--------------------------------------------------------------------------

  def initialize

    @map_interpreter = Interpreter.new(0, true)

    @battle_interpreter = Interpreter.new(0, false)

    @timer_working = true

    @save_disabled = false

    @menu_disabled = false

    @encounter_disabled = false

    @message_position = 2

    @message_frame = 0

    @save_count = 0

    @magic_number = 0

    @timer_remember = 0

    @timer = STARTHOUR * 2400

  end

def update

    # reduce timer by 1

    if @timer_working

      if @timer > 57600

        @timer = 0

         $game_variables[CURRENT_GAME_DAY] += 1

      else

          if @timer_remember != 0 and @timer != @timer_remember

          @timer = @timer_remember

          @timer_remember = 0

          else

          @timer += (1 * (24/GAME_DAY_IN_REAL_MINUTES))

          end

      end

    elsif @timer_remember != @timer and @timer_working == false

      @timer_remember = @timer

    end

  end

end
Code:
#==============================================================================

# ** Sprite_Timer

#------------------------------------------------------------------------------

#  This sprite is used to display the timer.It observes the $game_system

#  class and automatically changes sprite conditions.

#==============================================================================

 

class Sprite_Timer < Sprite

  #--------------------------------------------------------------------------

  # * Object Initialization

  #--------------------------------------------------------------------------

  def initialize

    super

    self.bitmap = Bitmap.new(120, 20)

    self.bitmap.font.name = "Arial"

    self.bitmap.font.size = 15

    self.x = 620 - self.bitmap.width

    self.y = 0

    self.z = 2000

    @flicker = true

    if $game_variables[CURRENT_GAME_DAY] < INTIALIZE_GAME_DAY

      $game_variables[CURRENT_GAME_DAY] = INTIALIZE_GAME_DAY

      end

    update

  end

  #--------------------------------------------------------------------------

  # * Dispose

  #--------------------------------------------------------------------------

  def dispose

    if self.bitmap != nil

      self.bitmap.dispose

    end

    super

  end

  #--------------------------------------------------------------------------

  # * Frame Update

  #--------------------------------------------------------------------------

 

  def update

    super

    # Set timer to visible if working

    if $game_switches[INVISIBLE_TIMER_SWITCH] == true

    self.visible = false 

  else

    self.visible = true

    end

        if $game_variables[NEW_HOUR] != 0 and

           $game_variables[NEW_HOUR] != $game_variables[HOUR_VARIABLE]

      $game_system.timer = $game_variables[NEW_HOUR] * 2400

      if  $game_system.timer > 57600

        $game_system.timer % 57600

        $game_variables[CURRENT_GAME_DAY] += 1

      end

      $game_variables[NEW_HOUR] = 0

      end

    # If timer needs to be redrawn

      if $game_system.timer / Graphics.frame_rate != @total_sec and $game_system.timer_working

      # Clear window contents

      self.bitmap.clear

      # Calculate total number of seconds

      @total_sec = $game_system.timer / Graphics.frame_rate

      # Make a string for displaying the timer

      case $game_variables[HOUR_VARIABLE]

      when 0,1,2,3,4,5,18,19,20,21,22,23,24

      moon_and_sun = RPG::Cache.picture("Moon")

      cw = moon_and_sun.width 

      ch = moon_and_sun.height 

      rect = Rect.new(0, 0, cw, ch)

      when 6,7,8,9,10,11,12,13,14,15,16,17

      moon_and_sun = RPG::Cache.picture("Sun")

      cw = moon_and_sun.width 

      ch = moon_and_sun.height 

      rect = Rect.new(0, 0, cw, ch)

    end

      if $game_variables[HOUR_VARIABLE] > 24

      moon_and_sun = RPG::Cache.picture("Moon")

      cw = moon_and_sun.width 

      ch = moon_and_sun.height 

      rect = Rect.new(0, 0, cw, ch)

      end

      if AM_AND_PM == true

        if $game_variables[HOUR_VARIABLE] > 12

          min = (@total_sec - 720) / 60

          sec = @total_sec % 60

        else

          min = @total_sec / 60

          sec = @total_sec % 60

        end

            if $game_variables[HOUR_VARIABLE] > 11 and $game_variables[HOUR_VARIABLE] != 24

              setting = "PM"

            else

              setting = "AM"

            end

            if FLICKERCOLON == true and @flicker == false

            text = sprintf("%02d %02d " + setting, min, sec)

             @flicker = true

          else

            text = sprintf("%02d:%02d " + setting, min, sec)

            if FLICKERCOLON == true

              @flicker = false

            end

          end

      else

        min = @total_sec / 60

        sec = @total_sec % 60

        text = sprintf("%02d:%02d", min, sec)

        end

      if $game_variables[HOUR_VARIABLE] > 12 and AM_AND_PM == true

      $game_variables[HOUR_VARIABLE] = min + 12

      else

      $game_variables[HOUR_VARIABLE] = min

      end

      $sec = sec

      # Draw timer

      rect2 = Rect.new(1, 1, 120, 20)

      self.bitmap.font.color.set(0, 0, 0)

      self.bitmap.draw_text(rect2, text, 1)

      self.bitmap.font.color.set(255, 255, 255)

      self.bitmap.draw_text(self.bitmap.rect, text, 1)

      self.bitmap.blt(90, 0, moon_and_sun, rect)

      end

  end

end

 
Code:
class Game_Event < Game_Character

  attr_reader :erased

  attr_accessor :is_light

  alias init_gm_evnt_lights initialize

  def initialize(*args)

    init_gm_evnt_lights(*args)

    @is_light = false

  end

  alias refresh_gm_evnt_lights refresh

  def refresh

    tmp_page = @page

    refresh_gm_evnt_lights

    if tmp_page != @page

      @is_light = false

    end

  end

end
Code:
 

class Nighttime < Sprite

  def initialize(x,y)

    super()

    @width = $game_map.width * 32

    @height = $game_map.height * 32

    @lights = {}

    self.x = x

    self.y = y

    self.bitmap = Bitmap.new(@width, @height)

    self.bitmap.clear

    fillnight

  end

  def refresh

    self.bitmap.clear

    create_lights

    fillnight

  end

  

  def create_lights

    for event in $game_map.events.values

      for i in 0...event.list.size

        if event.list[i].code == 108 #comment

          if event.erased and event.list[i].parameters[0].include?("light")

            @lights.delete(event)

            next

          elsif event.list[i].parameters[0].include?("light")

            size = event.list[i].parameters[0].delete("light").to_i #convert text to interger

            @lights[event] = Light.new(event, size) unless @lights.keys.include?(event)

            event.is_light = true

            next

          end

        end

      end

      #in the event page is changed and it is no longer a light.. remove it. 

      if @lights[event] != nil and event.is_light == false

        @lights.delete(event)

      end

    end

  end

  def fillnight

    if $sec == nil

      $sec = 0

    end

    if $game_switches[INSIDE_SWITCH] == true

      extralpha = INSIDE_OPACITY

    else

      extralpha = 0

      end

     case $game_variables[HOUR_VARIABLE] 

    when 0, 1, 23

    startop = 210 - extralpha

    when 2

    startop = 210 - ($sec / 2) + extralpha

    when 3

    startop = 180 - ($sec / 2) + extralpha

    when 4

    startop = 150 - ($sec / 2) + extralpha

    when 5

    startop = 120 - ($sec / 2) + extralpha

    when 6

    startop = 90 - ($sec / 2) + extralpha

    when 7

    startop = 60 - ($sec / 2) + extralpha

    when 8

    startop = 30 - ($sec / 2) + extralpha

    when 9, 10, 11, 12, 13, 14, 15

    startop = 0 + extralpha

    when 16

    startop = 0 + ($sec / 2) + extralpha

    when 17

    startop = 30 + ($sec / 2) + extralpha

    when 18

    startop = 60 + ($sec / 2) + extralpha

    when 19

    startop = 90 + ($sec / 2) + extralpha

    when 20

    startop = 120 + ($sec / 2) + extralpha

    when 21

    startop = 150 + ($sec / 2) + extralpha

    when 22

    startop = 180 + ($sec / 2) + extralpha

  end

  if $game_switches[CAVE_SWITCH] == true

    startop = CAVE_OPACITY

    end

    

    self.bitmap.fill_rect(0, 0, @width, @height, Color.new(0,0,0,255))

    self.opacity = startop

    # Now subtract out the lights

    # Testing with a single light at tile 7,11

    apply_lights

  end

  def apply_lights

    applied_space = []

    for light in @lights.values

      image_sub = RPG::Cache.picture("LightSUB").clone

      image_blt = RPG::Cache.picture("LightBLT").clone

      base_rect = image_sub.rect

      overlapLights = []

      size = (light.size/100.0)

      lwidth = base_rect.width*size

      light_rect = Rect.new(light.x-(lwidth/2), light.y-(lwidth/2), lwidth, lwidth)

      for applied_rect in applied_space

        if light_rect.overlap?(applied_rect)

          overlapLights << light_rect.area_in_overlap(applied_rect)

        end

      end

      #now draw it 

      if overlapLights.size == 0 #no overlap detected.. then just BLT it into the image

        self.bitmap.fill_rect(light_rect, Color.new(0,0,0,0))

        self.bitmap.stretch_blt(light_rect, image_blt, base_rect) 

      else

        self.bitmap.sub(light.x,light.y,image_sub)

      end

      applied_space << light_rect

      image_sub.dispose

      image_blt.dispose

    end

  end

  def update

    if $game_switches[INSIDE_SWITCH] == true

      extralpha = INSIDE_OPACITY

    else

      extralpha = 0

      end

    case $game_variables[HOUR_VARIABLE] 

    when 0, 1, 23

    self.opacity = 210 - extralpha

    when 2

    self.opacity = 210 - ($sec / 2) + extralpha

    when 3

    self.opacity = 180 - ($sec / 2) + extralpha

    when 4

    self.opacity = 150 - ($sec / 2) + extralpha

    when 5

    self.opacity = 120 - ($sec / 2) + extralpha

    when 6

    self.opacity = 90 - ($sec / 2) + extralpha

    when 7

    self.opacity = 60 - ($sec / 2) + extralpha

    when 8

    self.opacity = 30 - ($sec / 2) + extralpha

    when 9, 10, 11, 12, 13, 14, 15

    self.opacity = 0 + extralpha

    when 16

    self.opacity = 0 + ($sec / 2) + extralpha

    when 17

    self.opacity = 30 + ($sec / 2) + extralpha

    when 18

    self.opacity = 60 + ($sec / 2) + extralpha

    when 19

    self.opacity = 90 + ($sec / 2) + extralpha

    when 20

    self.opacity = 120 + ($sec / 2) + extralpha

    when 21

    self.opacity = 150 + ($sec / 2) + extralpha

    when 22

    self.opacity = 180 + ($sec / 2) + extralpha

    end

      if $game_switches[CAVE_SWITCH] == true

    startop = CAVE_OPACITY

    end

    end

end

class Rect

  def overlap?(rect)

    corners = []

    corners << [rect.x, rect.y] #UL

    corners << [rect.x+rect.width, rect.y] #UR

    corners << [rect.x+rect.width, rect.y+height] #LR

    corners << [rect.x, rect.y+height] #LL

    for corner in corners

      if corner[0].between?(self.x, self.x+width) and corner[1].between?(self.y, self.y+height)

        return true

      end

    end

    return false

  end

  def area_in_overlap(rect)

    return rect

  end

end

class Light

  def initialize(event, size)

    @event = event

    @size = size

  end

  def size

    return @size

  end

  def x

    return @event.real_x/4 + 16

  end

  def y

    return @event.real_y/4 + 16

  end

end

 
Code:
class Spriteset_Map
  alias init_spr_map_lights initialize 
  def initialize
    # Make nighttime sprite
    @nighttime = Nighttime.new(0,0)
    @nighttime.z = 2000
    init_spr_map_lights
    @inside_dark = true
    @second_counter = 60
    @nighttime.refresh
    @map_idd = $game_map.map_id
  end
   alias dns_dispose dispose
   def dispose
     dns_dispose
     @nighttime.dispose
   end
  alias upd_spr_map_lights update
  def update
    upd_spr_map_lights 
    # Update nighttime sprite
    @nighttime.ox = $game_map.display_x / 4
    @nighttime.oy = $game_map.display_y / 4
    if @inside_dark == true and $game_switches[INSIDE_SWITCH] == true
      @inside_dark = false
      @nighttime.refresh
    elsif @inside_dark == false and $game_switches[INSIDE_SWITCH] == false
      @inside_dark = true
      @nighttime.refresh
    end
    if @map_idd != $game_map.map_id
      @nighttime.refresh
      @map_idd = $game_map.map_id
      end
    if @second_counter == nil
      @second_counter = 60
    end
    if $game_system.timer_working and $sec != nil
      if $sec < @second_counter
      @nighttime.update  
      @second_counter = $sec
      end
      end
    @nighttime.update
  end
end[code][/spoiler]

I've added several options like 

Current Game Day
Starting Game Day
Cave Opacity
Inside Opacity

and fixed several bugs
 
I noticed a bit of a problem in the overlap code. I will see about cleaning it up so that we can do better detects and possibly do cleaner slicing for blt/sub's to 'sections' of the bmp rather than the whole thing. I need to also review how to make them allow following the player or event rather than being just static as well.
 

Thank you for viewing

HBGames is a leading amateur video game development forum and Discord server open to all ability levels. Feel free to have a nosey around!

Discord

Join our growing and active Discord server to discuss all aspects of game making in a relaxed environment. Join Us

Content

  • Our Games
  • Games in Development
  • Emoji by Twemoji.
    Top