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 Clear Lights with Clock

EDIT LOG:

I get an error as well its the way the accessors in Class Light are set up, they should be
Code:
 

attr_accessor :old_x

attr_accessor :old_y

 

instead of

Code:
 

attr_accessor: old_x

attr_accessor: old_y

 


EDIT:


I honestly think it would be easier to do this in VX/RGSS2 because you would be able to clear_rect, and set the rect as the portions between graphics in contact, then use the blt function to set the graphic without lag. I did so in XP, minus the clearing of rects, I also tried using sprites with the same idea, and clearing their bitmap contact location with the fill_rect(rect, Color.new(0,0,0,0)) function it worked, but parts of the graphic still mixed up with others creating an area that was darker than the dark itself, theoretically, this could work if you didnt mind making the darkness only be a set opacity of 255, so total darkness with parts of sprites cut up to match up with others.

EDIT 2: Because that .sub function just kills the render speed, I even tried speeding up the frame rate, I tried only subbing ones the player is in contact with, but again same killer frame rate >< of 4 frames a sec lol
 
Ok so I tried it again but I am getting an error on this line:


Code:
   alias dns_dispose dispose

Line 533

undefined method 'dispose' for class 'Nighttime::Spriteset_Map'

Now it could be some confliction with some other script I use (Probably blizz abs) just like gubbid edited version of this script that has functional lights going off without having to leave the map or open/close menu to update if visible or not but I just wanted to point it out.
 
Try switching out the

Code:
 alias dns_dispose dispose

with your own and replacing the dns_dispose with your own,it could be conflicting

try using
Code:
 

alias reaper0001_dispose dispose

def dispose

[...]

reaper0001_dispose

[...]

end

 

#instead of:

 

alias dns_dispose dispose

def dispose

[...]

dns_dispose

[...]

end

 

 

[...] Is just my way of substituting prior content. SO find dns_dispose in the def dispose and change it as well.
 

regi

Sponsor

PandoraShock":1lrr61yf said:
I honestly think it would be easier to do this in VX/RGSS2 because you would be able to clear_rect, and set the rect as the portions between graphics in contact, then use the blt function to set the graphic without lag. I did so in XP, minus the clearing of rects, I also tried using sprites with the same idea, and clearing their bitmap contact location with the fill_rect(rect, Color.new(0,0,0,0)) function it worked, but parts of the graphic still mixed up with others creating an area that was darker than the dark itself, theoretically, this could work if you didnt mind making the darkness only be a set opacity of 255, so total darkness with parts of sprites cut up to match up with others.

EDIT 2: Because that .sub function just kills the render speed, I even tried speeding up the frame rate, I tried only subbing ones the player is in contact with, but again same killer frame rate >< of 4 frames a sec lol
Hey, thanks for trying! Out of curiosity, could you post the code for using sprites and the fill_rect(rect, Color.new(0,0,0,0)) function? I'd like to see how you did it (and in my project, the darkness is always 255 anyway :P).
 
regi":1lu3wvyw said:
PandoraShock":1lu3wvyw said:
I honestly think it would be easier to do this in VX/RGSS2 because you would be able to clear_rect, and set the rect as the portions between graphics in contact, then use the blt function to set the graphic without lag. I did so in XP, minus the clearing of rects, I also tried using sprites with the same idea, and clearing their bitmap contact location with the fill_rect(rect, Color.new(0,0,0,0)) function it worked, but parts of the graphic still mixed up with others creating an area that was darker than the dark itself, theoretically, this could work if you didnt mind making the darkness only be a set opacity of 255, so total darkness with parts of sprites cut up to match up with others.

EDIT 2: Because that .sub function just kills the render speed, I even tried speeding up the frame rate, I tried only subbing ones the player is in contact with, but again same killer frame rate >< of 4 frames a sec lol
Hey, thanks for trying! Out of curiosity, could you post the code for using sprites and the fill_rect(rect, Color.new(0,0,0,0)) function? I'd like to see how you did it (and in my project, the darkness is always 255 anyway :P).



FUUUUU!!! XD I deleted it, and CCleaned b4 getting on HBgames, Q_Q I'm so sorry! When I get some time I'll re-do it!

EDIT: Working on it now, I'm going to try to use Graphics.frame_reset to help speed it up, as well as try to set it up in RGSS2

EDIT 2:

c66eaf695a16c5ebea6d6e649f14eab9.png
That is the problem Im talking about. But I have a solution... Instead of drawing all this stuff in a Sprite single... sprite, we could draw each glow on its own Sprite, then have a fill.. which would be 640, 480 in size (doesnt need to scale to the map), the glow sprites would clear... or fill a rect with Color.new(0,0,0,0) at their location in the fill for the night, something like:

Code:
 

@fillnight.bitmap.full_rect(light_rect, Color.new(0,0,0,0))

 

Then we could have a for loop, for catching if any of the lights are in another lights area, and if they are they cut out the touching portions of each light touching.

its either that... or we could make the light its own... Autotile?, and have it draw itself as if it was an auto tile, so parts that connect would move together to create 1 light instead of 2+, I kinda like this idea better because it would take less sprites and.. would look pretty damn cool...

Just my thoughts here is my current edit of the 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 = 24

 

 

# 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 = 1

 

 

# 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 = 2

 

# 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

DEFAULT_RADIUS = 200

 

 

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

#Bitmap

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

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

 

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

#end Bitmap

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

 

 

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

#Game_System

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

class Game_System  

  alias init_gme_sys initialize

  def initialize

    init_gme_sys

    @timer_working = true

    @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

 

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

#end Game_System

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

 

 

 

 

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

#Sprite_Timer

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

class Sprite_Timer < Sprite

  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

  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

 

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

#end Sprite_Timer

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

 

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

#Game_Event

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

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

 

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

#end Game_Event

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

 

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

#Sprite_Nighttime

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

 

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(ox=nil, nx=nil, oy=nil, ny=nil, size=nil)

    self.bitmap.clear

    create_lights if @change == nil

    fillnight(ox, nx, oy, ny, size)

  end

  

  def create_lights

    

    if $game_switches[CAVE_SWITCH] == true

      @lights[$game_player] = Light.new($game_player, DEFAULT_RADIUS)

    elsif @lights[$game_player] != nil

      @lights.delete($game_player)

    end

    

    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(ox=nil, nx=nil, oy=nil, ny=nil, size=nil)

    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))

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

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

    #base_rect = image_sub.rect

   # lwidth = (size/100.0)

   # s = base_rect.width*lwidth

   # self.bitmap.fill_rect(ox, oy, s, s, Color.new(0,0,0,0))

    self.opacity = startop

    # Now subtract out the lights

    # Testing with a single light at tile 7,11

    apply_lights(nx, ny)

  end

  def apply_lights(nx, ny)

    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

        

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

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

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

      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

  

  @oswitch =  false if @oswitch == nil

  

  if $game_switches[CAVE_SWITCH] == true

  @oswitch = true

else

  @oswitch = false

  @change = nil

  @time = nil

  end

  

  if @time != nil and @time == 1

    @change = true

    @time += 1

  end

 

  for light in @lights.values

      if light.x != light.old_x or light.y != light.old_y or (@oswitch == true and @times == nil)

      refresh(light.x, light.old_x, light.y, light.old_y, light.size)

      Graphics.frame_reset 

      @oswitch = false

      @times = 1

      return

      end

    

     

  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

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

 

class Light

  attr_reader :old_x

  attr_reader :old_y

  

  def initialize(event, size)

    @event = event

    @size = size

    @old_x = self.x

    @old_y = self.y

  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

 

 

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

#end Sprite_Nighttime

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

 

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

#Spriteset_Map

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

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

    @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 @hour_day != $game_variables[HOUR_VARIABLE]

      $game_map.refresh

      @hour_day = $game_variables[HOUR_VARIABLE]

      end

    if @map_idd != $game_map.map_id

      @nighttime.refresh

      @map_idd = $game_map.map_id

      end

    @nighttime.update

  end

end

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

#end Spriteset_Map

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

 
 
I get a no method error on line 299 with your version pandora.

Undefined method 'size' for nil:NilCLass

On one map I didn't get an error but when I tried on another map that error pops up.
 

regi

Sponsor

The autotile is a pretty cool idea, but sadly, only works if there's no/less of an opacity gradient, because the image is too small to capture (e.g. see Wachunga's fog of war: there's no gradient, it just goes from darkness to clear):
687474703a2f2f7338383338373234332e6f6e6c696e65686f6d652e75732f726d78702f666f675f6f665f7761722f666f675f6f665f7761722e6a7067


Unless we rewrite a new autotile feature that uses a larger image, it's going to be difficult to work :\
(Here's the one I tried to make, you can check it out and see the glitches for yourself.)
LightBLT.png


EDIT: working on a new one that's a larger sprite, gotta fix the upper-right corner but I'll see how it turns out later today:
LightBLT1.png


I definitely like your idea of drawing each sprite separately and filling the map with darkness, though.
 
Looks nice Regi, ill take a look at some coding for the autotiles see how they are put together in script.

:)

EDIT: Ill also take a look at the sprite version too
 
When i saw that autotile I thought you could do the lights like the script by using it while creating maps but it only makes small circles hehe

If someone manages to make an almost lag free light around the character with the possibility on increasing it's range with a script call I was thinking on the possibility of having my project set during the night all the time.
 
Maybe what you could do with the lights is instead of setting the rbg value of each pixel, you could add to it. That would stop all the messed up overlaps.

Edit. Ignore this post. I just checked the source.
 

regi

Sponsor

Still haven't given up on the lighting system. I've been thinking of a new method that could possibly have MUCH less lag.

Rather than redrawing the entire darkness sprite, each light would have its unique sprite, just like Sprite_Character. We would then use @blend_type = 2 (subtraction) to use the built-in subtraction feature. My only question is would "sub" work for non-character and non-picture sprites? I have little experience working with graphics, and would much appreciate any assistance.
 
So sprites have a blend_type variable? I'll get to work on this, it sounds really easy.

Edit. I might have made it work... maybe...
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 = 24

     

     

    # 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 = 1

     

     

    # 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 = 2

     

    # 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

    

    # Set this switch to on to give the player a light

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

    FLASHLIGHT_SWITCH = 12

    FLASHLIGHT_SIZE = 100

     

     

     

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

    #Bitmap

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

    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

     

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

    #end Bitmap

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

     

     

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

    #Game_System

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

    class Game_System  

      alias init_gme_sys initialize

      def initialize

        init_gme_sys

        @timer_working = true

        @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

     

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

    #end Game_System

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

     

     

     

     

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

    #Sprite_Timer

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

    class Sprite_Timer < Sprite

      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

      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

     

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

    #end Sprite_Timer

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

     

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

    #Game_Event

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

    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

     

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

    #end Game_Event

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

     

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

    #Sprite_Nighttime

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

     

    class Nighttime < Sprite

      def initialize(x,y)

        super()

        @width      = $game_map.width * 32

        @height     = $game_map.height * 32

        @lights     = {}

        @sprites    = []

        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

          unless event.erased or event.list == nil

          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

      if $game_switches[FLASHLIGHT_SWITCH] and $game_switches[CAVE_SWITCH]

        @lights[$game_player] = Light.new($game_player, FLASHLIGHT_SIZE)

      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

        show_lights

      end

      def show_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)

          sprite = Sprite.new

          sprite.bitmap = image_blt

          sprite.x, sprite.y = light_rect.x, light_rect.y

          sprite.z_index = 2001

          sprite.blend_type = 2

          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

     

     

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

    #end Sprite_Nighttime

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

     

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

    #Spriteset_Map

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

    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

        @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 @hour_day != $game_variables[HOUR_VARIABLE]

          $game_map.refresh

          @hour_day = $game_variables[HOUR_VARIABLE]

          end

        if @map_idd != $game_map.map_id

          @nighttime.refresh

          @map_idd = $game_map.map_id

          end

        @nighttime.update

      end

    end

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

    #end Spriteset_Map

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

 
 

regi

Sponsor

Unfortunately, the sprite's blend_type doesn't seem to subtract from the darkness, which is why I'm trying to figure out how "sub" works.
 

regi

Sponsor

Sadly, no. I tried it with pictures and it didn't seem to work, which is why I suspect "sub" only subtracts from tiles and characters, not other bitmaps. It would be great if a scripting guru could confirm, though, or maybe explain how blend_type works.
 

regi

Sponsor

I have no idea, but it's worth a shot! I figure there must be some way to do it, though, since it's built in to the RPG engine for charactersets at least.
 

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