RGSS: Viewport

The easiest way to understand the role of the viewport is to imagine them as layers or screens.

A viewport is a surface that can fill a portion of the display screen. In general, you’ll want to fill the whole display area with the viewport’s box: Viewport.new(0, 0, 544, 416). With that notion in mind, viewports can act like layers when juxtaposed on top of each other.

But if you want, you can split your screen with two, three, four or more viewport zones. It’s even possible to mimic the Nintendo 2DS with a bit of imagination. Sprites assigned to a viewport won’t overlap with other viewports, they’ll stay confined to the active one, unless dynamically programmed to move from one viewport to another.

The following demo split the screen in two halves and assign a sprite in them. Given that these sprites are bigger than the viewports, they’ll be cropped/clipped.

Preliminary Steps

  1. Open RPG Maker VX and open the Script Editor (F11).
  2. Delete every pieces of code there. Absolutely everything.
  3. Create a new entry and name it ‘My New Script’ or a similar title.
  4. Copy and paste the following piece of code in the editor.
viewport1 = Viewport.new(0, 0, 544/2, 416)
viewport1.z = 50

viewport2 = Viewport.new(544/2, 0, 544/2, 416)
viewport2.z = 100

my_spriteA = Sprite.new()
my_spriteA.viewport = viewport1
file = "Graphics/Battlers/Behemoth"
my_spriteA.bitmap = Bitmap.new(file)

my_spriteB = Sprite.new()
my_spriteB.viewport = viewport2
file = "Graphics/Battlers/Demon"
my_spriteB.bitmap = Bitmap.new(file)

loop { Graphics.update }

Mimic 3DS layout with viewports

We can do a fun project and mimic the layout of the 3DS handheld console for testing viewports.

### SETTINGS

screen_width = 640
screen_height = 480

Graphics.resize_screen(screen_width, screen_height)

bmp_3ds = Bitmap.new("Graphics/Pictures/nintendo_3DS")
center_x = (screen_width/2) - (bmp_3ds.width/2)

### VIEWPORT FOR FULL SCREEN (BG)

viewport_A = Viewport.new(0, 0, screen_width, screen_height)
viewport_A.ox -= center_x
viewport_A.z = 0

my_sprite_A = Sprite.new()
my_sprite_A.viewport = viewport_A
my_sprite_A.bitmap = bmp_3ds

### 3DS TOP SCREEN VIEWPORT

viewport_B = Viewport.new(center_x+79, 39, 314, 190)
viewport_B.z = 100

my_sprite_B = Sprite.new()
my_sprite_B.viewport = viewport_B
my_sprite_B.bitmap = Bitmap.new("Graphics/Battlers/Demon")

### 3DS BOTTOM SCREEN VIEWPORT

viewport_C = Viewport.new(center_x+109, 280, 254, 192)
viewport_C.z = 100

my_sprite_C = Sprite.new()
my_sprite_C.viewport = viewport_C
my_sprite_C.bitmap = Bitmap.new("Graphics/Battlers/Behemoth")

### MAIN LOOP

loop { Graphics.update }

It’s important to know that the viewport has two types of coordinates. Regular coordinates and offset coordinates. Regular coordinates can be set only during the object initialization: Viewport.new(0, 0, screen_width, screen_height). The regular coordinate is the absolute position of the viewport within the screen. Offset coordinates will shift the content inside the viewport horizontally and vertically.

I’ve created three viewports for this scene. One is covering the entire screen and is used to display the Nintendo 3DS in the background. The 3DS image itself doesn’t fill the entire screen, so used this simple formula, center_x = (screen_width/2) – (bmp_3ds.width/2), and then shifted the offset value horizontally, viewport_A.ox -= center_x, to center the image.

The two other viewports are drawn over the background viewport. Just like the 3DS screens, their contents will never get outside the boundary of the rectangular area for each viewport. In the above snapshot, the monsters have been clipped to their respective viewport.

Test top screen with gamepad or keyboard input

To see the top viewport in action, you can add the following snippet in the loop-do block:

loop {
  Graphics.update

  dir = Input.dir4
  Input.update

  case dir
  when 2
    my_sprite_B.y += 1
  when 4
    my_sprite_B.x -= 1
  when 6
    my_sprite_B.x += 1
  when 8
    my_sprite_B.y -= 1
  else
  end
}

See the end result in action here:


Posted

in

by

Tags:

Comments

Leave a Reply

Your email address will not be published. Required fields are marked *