Display an image

Hello, I’m practically brand new at developing for Roku and I need some help. What I need is a script that displays an image on the screen that can be moved around with the arrows(like the simple2d example). I wanted to just strip down the simple2d example until all it did was display a ball. But I ran into some trouble.

Thanks

Prolly the best place to get started is by downloading the Picnic Defense app that someone posted to the forum a few months ago:

viewtopic.php?f=34&t=40243&start=0&hilit=picnicdefense

But just to give you some hints:

  1. create an roscreen. for beginner, don’t use doublebuffering (useful later when you are trying to extract the most performance you can get out of the CPU)
  2. create a bitmap from a file
  3. create a region from the bitmap
  4. create a sprite from the region using rocompositor
  5. create a port
  6. assign roscreen to port
  7. listen for input from port, use that to determine which way to move your sprite
  8. use rosprite moveto or moveoffset to move the sprite. with offset, you can just put in the amount to move, with moveto, you give the coordinates to moveto
  • Joel

Here is what I have so far:

Function Main()
   while true
      Draw()     
   end while
end Function

Function Draw()
    screen = CreateObject("roscreen", false, 640,480)
     player = CreateObject("robitmap","pkg:/images/truck.png")
     region = createobject("roregion", player, 0,0,64,64)
     compositor = createobject("rocompositor","pkg:/images/truck.png")
     compositor.draw()
     screen.drawobject(0,0,player)
     return true
end Function

And it doesn’t work. What am I doing wrong?

I see two problems right off…

  • the constructor for roCompositor only takes one parameter, the debug console reports this problem immediately.

    BrightScript Component function call does not have the correct number of parameters. (runtime error &hf5) in ...AA9QwPvk/pkg:/source/Main.brs(18)
    018:      compositor = createobject("rocompositor","pkg:/images/truck.png")
    
    
  • You don’t want to recreate the screen, bitmaps, etc every time you envoke your Draw() routine. You want to create those things once, hold them in memory, and use them to update the screen from your Draw() routine.

I’ve been working quite a bit with basic roscreens. Do you plan on using an animated sprite?

For a non-animated image, this would work. In fact, it is a piece of one of my games. I’m using double buffering.


Sub Main()
    W = 640
    H = 480
    screen=CreateObject("roScreen", true, W, H)
    if type(screen) <> "roScreen"
        print "Unable to open screen"
        return
    endif
    msgport = CreateObject("roMessagePort")
    screen.SetPort(msgport)
    DrawImg(screen)
End Sub

Sub DrawImg(scr as object)
    port = scr.GetPort()
    cw = int(scr.getwidth()/2)
    ch = int(scr.getheight()/2)
    logo = CreateObject("roBitmap", "pkg:/images/logo.png")
    while true
        BackGround(scr)
        scr.drawobject(cw-280, ch-160, logo)
        scr.swapbuffers()
        msg = wait(0, port)
        if type(msg) = "roUniversalControlEvent" then
            if (i = 6) then
                exit while
            end if            
        end if
    end while
end sub

Sub Background(scr as object)
    scr.clear(0)
    cw = int(scr.getwidth()/2)
    ch = int(scr.getheight()/2)
    bg = CreateObject("roBitmap", "pkg:/images/background.png")
    scr.drawobject(cw-360, ch-240, bg)
End Sub

Try that. It should be enough to get you a background plus an image on your screen. If you want to do more complex things, you will need to study what jbrave said.

Thanks for the help YungBlood, But I have another question: How would I make the image transparent? I’m using a png with transparency, but there’s still a black box around the image. By the way, is there any information about roscreens in the documentation?

“AngelWire” wrote:
Thanks for the help YungBlood, But I have another question: How would I make the image transparent? I’m using a png with transparency, but there’s still a black box around the image. By the way, is there any information about roscreens in the documentation?

Use screen.setalphaenable(true) for an image that has transparent sections, or if drawing to a bitmap, mybitmap.setalphaenable(true)

If mixing transparent and non transparent images, set true for the transparent and false for the non-transparent. Here is an example from a 2D Defender style game I’m working on:

while true
'...do a bunch of calculations.... 
' now draw everything:
		screen.setalphaenable(false)   'set transparent alph blend OFF
		starsregion.offset((movex/2),0,0,0)   'move background starfield
		screen.drawobject(0,-150,starsregion) 'draw starfield at new position
		screen.setalphaenable(true) 'set transparency ON
		earthregion.Offset(movex,0,0,0) 'move earth 
		screen.drawobject(0,-250,earthregion) 'draw landscape on top of starfield
		playsprite.moveto(ps.posx,ps.posy) 'move player's character
		compositor.drawall() 'draw all sprites 
		screen.SwapBuffers() 'swap screen buffers
end while

For more info on roscreen, get the latest beta SDK here:
http://forums.roku.com/viewtopic.php?f=34&t=39272#p260031

Thanks everyone for your help but I’m still having some problems.

Sub Main()
    W = 640
    H = 480

    screen=CreateObject("roScreen", true, W, H)
    if type(screen) <> "roScreen"
        print "Unable to open screen"
        return
    endif
    msgport = CreateObject("roMessagePort")
    screen.SetPort(msgport)
    DrawImg(screen)
End Sub

Sub DrawImg(scr as object)
    x = int(128)
    y = int(128)
    port = scr.GetPort()
    cw = int(scr.getwidth()/2)
    ch = int(scr.getheight()/2)
    logo = CreateObject("roBitmap", "pkg:/images/corporal.png")
    while true
         BackGround(scr)      
        scr.drawobject(x, y, logo)  
        scr.swapbuffers()
        msg = wait(0, port)
        if type(msg) = "roUniversalControlEvent" then
            if (i = 3) then
                scr.setalphaenable(true)
            else
                scr.setalphaenable(false)
            end if           
        end if
    end while
end sub

Sub Background(scr as object)
    scr.clear(0)
    cw = int(scr.getwidth()/2)
    ch = int(scr.getheight()/2)
    bg = CreateObject("roBitmap", "pkg:/images/grass.png")
    scr.drawobject(cw-360, ch-240, bg)
End Sub

Here’s the problem: I’ll run my program on the roku, and if I press a button it will go back to the main screen. I’ll run the program again and press a button nothing happens. So I press the home button, run the program again, press a button and it will end. So it just goes back and forth like that.

And I also have a question, instead of using moveto(), could I just draw the object at x and y and change their values?
Thanks for your help once again.

Are you using port 8085 to see the debugging output? Trying to write an app without the debug output is like driving blind. If you look at the debug output when you run your app, you will see this:


Use of uninitialized variable. (runtime error &he9) in ...aaNP9/pkg:/source/appMain.brs(29)
029:                 if (i = 3) then

which immediately points to the problem (you did not initialize the variable “i” anywhere).

–Mark

Thanks RokuMarkn, that helps a lot! One last question(I hope), how do I check if a button on the remote is pressed? I’ve looked through the examples and documentation but I can’t get anything to work.

See page 58 of the Brightscript 3.0 Reference. The roUniversalControlEvent object that you receive has a GetInt method that returns the id of the key pressed.

–Mark

I finally got it working, but how would I check if the button is still being held instead of just pressed?
This is what I have so far but it’s not working:

while true
        x = x+xto
        y = y+yto
        scr.setalphaenable(true)
        BackGround(scr)      
        scr.drawobject(x, y, logo)
        scr.swapbuffers()                
        msg = wait(0, port)
if type(msg) = "roUniversalControlEvent" then
        if msg.getint()= 2
           yto = -5
        else if msg.getint()= 3
           yto = 5
       else	if msg.getint()= 4
           xto = -5
        else	if msg.getint()= 5
           xto = 5
        else if msg.getint()= 102
           yto = 0
       else if msg.getint()= 103
           yto = 0
        else	if msg.getint()= 104
           xto = 0
        else	if msg.getint()= 105
           xto = 0
       end if
end if
end while

“AngelWire” wrote:
I finally got it working, but how would I check if the button is still being held instead of just pressed?

Alright, I got that fixed, but now I figured out that the background is taking a ton of memory and causing the game to run super slow(from 59.9 fps to 8 ). Any suggestions?

When you press a button, you will get 2 events. First, you will get the press event (i.e. 2), then you release the button, you get the release event (i.e. 102). That allows a lot of flexibility. If you want to enforce only receiving “presses”, then just set a release var when you get the press event, and clear it when you get the release event. (If you’re not sure what I mean, I can give you a piece of code)

Also, I don’t know if it makes a difference to roku, but I recommend making a small change to your code. Instead of using:


   if msg.getint() = 2 then
     ...
   else if msg.getint() = 3 then
    ...

Use this instead:


    key = msg.getint()
    if key = 2 then
        ....
    else if key = 3 then
        ...

“AngelWire” wrote:
Alright, I got that fixed, but now I figured out that the background is taking a ton of memory and causing the game to run super slow. Any suggestions?

Good question. I’m noticing that a bit on the HD version of my memory match game. I don’t have the solution yet, but I am looking into speed improvements. I’ll keep you posted with that I find.

Thanks YungBlood. The problem was msg = wait(0, port), I changed it to msg = port.getmessage() and it works fine.
EDIT:
I fixed the speed issue, the problem was bg = CreateObject(“roBitmap”, “pkg:/images/grass.png”) was in the while loop. I moved it and now it’s running at 60 fps.

Good to know you got it running better. I don’t have the create object in my loop, but my code runs a bit slow in HD. Could simply be the number of objects I’m drawing…