Sony Playstation Portable Lua Programming: Images
So far all of our programs have been text only applications. I think by getting your feet wet with basic programming first it will make everything else a bit easier to take in. In this tutorial I will introduce using images, and some commands you can use for getting information about images.
As for what we are going to make? Well, we will make a program that will actually start to look like a game. It won't do anything flashy or exciting, but will serve the purpose of this tutorial, images. There are a lot more image commands available than the ones we will learn here. We will learn more of these in later tutorials. Feel free to look them up on your own in the luaplayer documentation.
Our finished product will include a moveable character that can move around the screen, but will not be able to walk past the edges of the screen.
Using Images In Lua
The first thing you should do is save the images below to the folder you're working in. These pictures are just simple samples and it is very much OK to use your own. LuaPlayer can load PNG and JPEG images. For the most part, I would always use PNG over JPEG, especially when you need to use transparency. Now save these iamges:
Click Here To Download Images
Unzip those to the folder you're working in. You should have three images:
player.png
grass.png
flower.png
Now, once again, for the first part of the tutorial just follow along, and we will later start our code.
Loading Images:
In order to use an image in lua you must first load it into your program, into a variable (or table). You can do this at the beginning of your program, or later on depending on when the image is needed. We will pre-load our images near the top of the code when we start a bit later.
Here is an example of loading an image:
grass = Image.load("grass.png")
This will load the image file "grass.png" into the variable "grass". In order for this image to load it would have to be in our main project folder with our lua script file. If you had the image in a subfolder such as "Images" then you would use "Images/grass.png" instead of "grass.png".
Be sure that you use the exact case in text as shown. Capitalize the "I" in image, and make the "l" in load lowercase. Very easy to load an image huh?!
Display Images:
To display an image to the screen really isn't any harder than loading one. Here's the full command:
screen:blit(x, y, Image source, [sourcex, sourcey, width, height], [alpha = true])
There is a lot of information to fill in there! You will not always need all of those arguments, and you can completely omit the ones in square brackets if you don't need them. Now let's explain.
The code starts with screen:blit which is the command that says paste this image to the screen.
Now, inside the parentheses the fun begins.
x and y are the same as with the print command. This will be where on the screen the image will be pasted.
Image source will be the image to be pasted. For example, from above we loaded an image called grass, so we could use grass for our image source.
[sourcex, sourcey, width, height] is optional. This is used for loading a section of an image from a large image. A tilesheet is the perfect example. You may have a single image with several dozen tiles on it. With this code you paste one little section of that image. sourcex and sourcey are the x and y coordinates of the image where the section of the tile image starts. Not the whole image, but the smaller one inside the image.
width and height is the width and height of the piece of image you're taking from the main image. The last part of the command is the alpha argument. This is used to make transparency in images. True will make them transparent (which means the background will be see through with no color) and false will display the image as it is originally.
We will not be using all of these arguments in this tutorial.
Getting Image Size:
Getting the size of the images you have loaded can sometimes be very useful. There are two commands we can use for this, to get the width and height of an image. Here they are:
image:width()
image:height()
To use these you replace the word image with the image you want to get the width or height for. For example, to get the width and height of our grass image we would use:
grass:width()
grass:height()
Let's Make Something:
Let's go ahead and get started on our program.
The very first thing we're going to do is load our images into our program. Start up a new file and enter this code:
grass = Image.load("grass.png")
player = Image.load("player.png")
flower = Image.load("flower.png")
There. We have loaded our three images into our program.
Now, we're going to put those image size commands to use. Put in the following code, then I will explain. I'd also like to note that you will do yourself much more good actually typing code out instead of copying and pasting it. You will memorize the commands much better this way. Anyway, put this in:
screenwidth = 480 - player:width()
screenheight = 272 - player:width()
What point is this? Well, here's what we are using this for.
This bit of code will help us stop the player when it reaches the edge of the screen, when going left to right (horizontally).
We know that 480 is the width of the PSP's screen. But if we make the boundary of the screen at 480, then our character will go offscreen by 32 pixels, since our character is 32 pixels wide.
player:width() is the width of the player image, which is 32 pixels. This amount is subtracted from the screen width and height to stop the image at the edge of the screen.
Next, we are going to create a table to store our player character's information. The only information we will need for this example program will be the player's x and y position on the screen. Enter in this code:
Player = { }
Player[1] = { x = 200, y = 50 }
This will store our player's x and y position on the screen. We will start our player at x position 200, and y position 50.
Now, let's start our main loop. Enter this code:
while true do
pad = Controls.read()
screen:clear()
Now, in our next section of code I will introduce a new looping command. This is the "for" loop. Let me give you an example of this to show you how it works. Do NOT use this in your code. This sample could print 5 players weapons to the screen by using only one small loop.
for a = 1,5 do
screen:print(10, 10, Player[a].weapon, green)
end
To use the for loop you will give a temporary variable a starting value and an ending value.
In the above we said "for a = 1,5 do"
This is creating a loop that will give the variable "a" a starting value of 1, and an ending value of 5. You can think of this line as saying "a is equal to 1 through 5".
Then inside the loop we are printing the player's weapon to the screen.
The last line has the "end" statement which must be used to end a loop.
Now, this loop will repeat over and over until the ending value of "a" is met, and then the loop will terminate. The first time the loop performs "a" will equal 1. The next time "a" will be 2, then 3, then 4, and finally 5. This would quickly print the weapons of players 1 through 5 to the screen. Although, to really do this you would need to change the screen coordinates of the print command so that it doesn't all print in one spot. But this shows the use of the command. You are also free to use "if" statements within the "for" loops if needed.
We will use this method to tile our grass image across the entire screen. Put in the code below and I will explain. Also, keep in mind that to make a more complex game with scrolling and such, using a tile engine will be a much better approach, but for now we don't need it.
for a = 0, 14 do
for b = 0,8 do
screen:blit(32 * a, 32 * b, grass)
end
end
This has a "for" loop within another "for" loop! This will paste the grass image across the entire screen. It will paste 15 images horizontally and 9 images vertically. Notice we start with zero instead of 1 so that the images get pasted at the very left edge of the screen.
Now, let's paste a few more images.
screen:blit(100,100,flower)
screen:blit(300,220,flower)
screen:blit(Player[1].x,Player[1].y,player)
This will simply paste two of the flower images to the screen, as well as our player. Shortly, when we use our movement keys we will change the player's coordinates in each loop if we're pressing the button. Using the above blit command our player's image will get automatically pasted to the correct area of the screen.
Now, let's add in those keys to detect if we're pressing the directional keys. Enter this code:
if pad:left() and Player[1].x > 0 then
Player[1].x = Player[1].x - 2
end
if pad:right() and Player[1].x < screenwidth then
Player[1].x = Player[1].x + 2
end
if pad:up() and Player[1].y > 0 then
Player[1].y = Player[1].y - 2
end
if pad:down() and Player[1].y < screenheight then
Player[1].y = Player[1].y + 2
end
These codes will check to see if we're pressing up, down, left or right. Using the "and" statement we will also check to make sure we our not leaving the boundary of the screen. Since the very left of the screen and the very top of the screen is at the coordinate zero, we can simply see if our position is greater than zero.
For the others we use screenwidth for going right and screenheight for going down. We set up these variables earlier. If our position passes the "if" test then our player's x or y coordinates will be added or subtracted by 2. Each time the main loop runs it will paste our player image to the new position given to it.
Finally, let's end our loop. Use this code:
screen.waitVblankStart()
screen.flip()
end
Save your work and run it. Use the directional keys to move across the screen. You should not be allowed to go past the edge of the screen.
Expressions |
Functions
|