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

So no progress on moveable light sources?

Damn I really want to implement a flash light but using a picture as light won't make the area brighter since the script tints everything :/
 
Rmxp

Sure there are flash light scripts I could even do it eventwise but this script darks the whole map so it wouldn't work.
 
I've been working to reduce the lag, and created a function to just refresh certain lights. I feel like it's much faster than before, but that could be just me. I'll be working on a dll to further reduce the lag too. Here's my version 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 = 100

 

 

 

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

#Bitmap

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

class Bitmap

  def sub(ox,oy,light,lwidth)

    tmp = Bitmap.new(lwidth, lwidth)

    tmp.stretch_blt(tmp.rect, light, light.rect)

    light = tmp.clone

    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

    self.bitmap.clear

    create_lights

    fillnight

  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

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

      end

      applied_space << light_rect

      image_sub.dispose

      image_blt.dispose

    end

    @applied_space = applied_space

  end

  def refresh_lights(lights)

    for light in lights

      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

      old_rect = Rect.new(light.old_x - lwidth / 2, light.old_y - lwidth / 2, lwidth, lwidth)

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

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

      tmp = @applied_space.clone

      obj = tmp.detect { |i| i == old_rect }

      found = false

      tmp.delete_if { |i|

        break if found

        found = i == old_rect

      }

      tmp.each { |applied_rect|

        if light_rect.overlap?(applied_rect)

          overlapLights << [old_rect.area_in_overlap(applied_rect), applied_rect]

        end

      }

      tmp << light_rect

      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

        overlapLights.each { |i|

          real_bmap = Bitmap.new(i[1].width, i[1].width)

          real_bmap.stretch_blt(real_bmap.rect, image_blt, base_rect)

          x, y = 0, 0

          if i[1].x < i[0].x

            x = i[1].width - i[1].x + i[0].x

          end

          if i[1].y < i[0].y

            y = i[1].height - i[1].y + i[0].y

          end

          self.bitmap.fill_rect(i[1], Color.new(0, 0, 0, 0))

          self.bitmap.stretch_blt(i[1], image_blt, base_rect)

        }

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

      end

      @applied_space = tmp.clone

    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

    

    lights = []

    @lights.each_value { |light|

      if light.x != light.old_x or light.y != light.old_y

        lights.push(light)

      end

    }

    

    refresh_lights(lights) if lights.length > 0

    lights.each { |light|

      light.old_x, light.old_y = light.x, light.y

    }

  end

end

class Rect

  def overlap?(rect)

    corners = []

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

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

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

    corners << [rect.x-1, rect.y+rect.height-1] #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

    corners = []

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

    corners << [self.x+self.width-1, self.y] #UR

    corners << [self.x+self.width-1, self.y+self.height-1] #LR

    corners << [self.x, self.y+self.height-1] #LL

    for corner in corners

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

        return true

      end

    end

    return false

  end

  def area_in_overlap(rect)

    args = Array.new(4) { 0 }

    # rect's corners

    opos = [rect.x,rect.y,rect.x+rect.width-1,rect.y+rect.height-1]

    # self's corners

    spos = [self.x,self.y,self.x+self.width-1,self.y+self.height-1]

    args[0] = [opos[0], spos[0]].max

    args[1] = [opos[1], spos[1]].max

    args[2] = [opos[2], spos[2]].min - args[0] + 1

    args[3] = [opos[3], spos[3]].min - args[1] + 1

    return Rect.new(*args)

  end

  

  def equal?(rect)

    return (x == rect.x and y == rect.y and width == rect.width and height == rect.height)

  end

end

 

class Light

  attr_accessor :old_x, :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 an error when I try your version thallion.

On line 307 Not method error.

undefined method 'size' for nil:NilClass

line:

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

Could be some other script conflicting no idea tough I really wish the version that let's the lights go away when you update their event page to work on my project but sadly it gives me errors :/

Only the one on the first page doesn't.
 
Actually, I just realized that my method was completely useless b/c I was testing it on a map with only one light. However, I finished the dll and it runs really fast on my computer w/261 Mg of ram.
 

regi

Sponsor

I know it's been ages since anyone's worked on this, but I wanted to check on how that dll's going? Otherwise, I will probably start a new venture and script something up from scratch (after analyzing a lot of other lighting scripts, of course).
 
Hi there, first of all really really sorry for bumping a 3 year old topic but i need help with this topic. I'm a noob to RPGMAKER XP but that being said i have used other game engines and picked up the basics really fast in RPGMaker XP because of this.

The day/night cycle script that was been posted in this topic works fine but i have two little issues i can not seem to figure out. In the description it says;

Switches to make screen dark for caves and screens darker for houses

Setting the clock visible or invisible at start-up and by switch

I am unable to find any switches for these. I want it to always be dark in places like caves and to also completely hide the clock forever, i don't need the clock on-screen at all, however when i do what it says and set the switch to "on" (to hide the clock) i get a module error.

I downloaded the guys demo to see how he set things up but even the demo as no switches. So now am confused. I just need to switch i can toggle so i can make caves etc dark when needed and a switch for making the clock invisible or even help altering a value directly in the script to disable the clock showing on the hud.

Once again sorry for bumping such an old topic but this is what i need help with.

Thank you.
 
*edit*

I took a look at this script and due to the lack of support, popularity, and the low quality of this script, I decided to write my own Dynamic Lighting Script (with lights, Day / Night, and a clock) that addressed many of the issues, as well as adding a ton of new features.

Heretic's Dynamic Lighting Script [XP]
http://forum.chaos-project.com/index.php/topic,15417.msg194701.html#msg194701 (obsolete)

EDIT: Full Version 1.0 is available in my Collection
http://forum.chaos-project.com/index.ph ... 682.0.html

LightInside.gif


PenLight.gif


My script is still in development. Mostly dll work and I really only need some help with the C++ side of this (image quality), but you should be able to use this script for development in its current state. Due to some features not working the way I want just yet, I havent allowed legal distribution of the script at the time of this Post Edit (July 12th, 2016), but you can use and play with it. I will admit that the Demo for download listed above is not truly a proper demo as not all of the features are well explained or documented so some things may be a bit confusing.

If you need support for my script, have some time to work with C++ code for functionality that I need, please PM me or start a new thread. However, if you would like to compare both scripts, I believe this would be a more appropriate thread to post in.

---

*** original post prior to edit ***

@o0Sniper0o

Due to lack of support for this script, you might find an alternative here:
http://forum.chaos-project.com/index.ph ... 284.0.html

---

Edit: Monday, July 17th, 2017

Not sure how I forgot to update this post but my script is complete and released for legal distribution, including in commercial projects. The script I wrote is available in the link above in Heretic's Collection of Art and 100% Compatible Scripts. It is much faster, more stable, and has a TON of features that should knock your socks off!

Support for the original script of the OP should remain here, for support for my script, feel free to start a new thread so this thread remains dedicated to the script for which it was intended.
 

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