Help making a little "menu?"
Forum rules
Before you make a thread asking for help, read this.
Before you make a thread asking for help, read this.
-
- Prole
- Posts: 7
- Joined: Sun Jan 06, 2013 2:50 am
Help making a little "menu?"
Basically I'm trying to make a "menu" that will spawn a button when I hold down a button("q" for right now.) I could swear the code should work, but for some reason it isn't. I've attached a .zip file with all the current files I have for it. So far all it has is Link running around in 4 directions, without being able to leave the screen. There's a file called "runescreen.lua" that has code in that SHOULD allow me to spawn an image at the coordinates I specify. I'm really sorry if my code is unclear. I don't think it should be an issue for you, but if it is, I'll gladly tell you whatever you need to know. I'm obviously not going to be using any of these sprites or positions etc, but I'm really new to Love and just testing what I can do.
Any help is more than welcome. Thanks a ton in advance, guys.
Any help is more than welcome. Thanks a ton in advance, guys.
- Attachments
-
- test.rar
- (816.01 KiB) Downloaded 99 times
-
- Party member
- Posts: 235
- Joined: Sat Dec 15, 2012 6:54 am
Re: Help making a little "menu?"
Hi there,
Your main problem is that you were going about this the wrong way. I'll show you what I mean by explaining my corrections.
Here is my version of your "runescreen.lua" file:
I also made a minor adjustment to your "love.load" callback in "main.lua":
The problem with your original code was two-fold. First, you were using "love.graphics.newImage" once every frame for each rune in your "runes" table, creating an endless amount of Image objects. Second of all, you were never actually drawing the images.
You see, "love.graphics.newImage" does not draw an image, instead it defines an Image object. It is not meant to be called over and over again. The function is usually used like this:
[there are a few other ways that you can use the function (see: https://love2d.org/wiki/love.graphics.newImage ), but they're not important right now.]
No matter how many times you draw an Image object, you only have to define it ONCE. So, you may have 20 "shadow runes" being drawn, but you only have to define the shadow rune image object once.
Now we need to draw the image object. We can do this a few different ways, but for now we will use "love.graphics.draw()". This function draws "drawable objects" onto the screen. A "drawable object" is usually an image object, but it can also be other things (see here if you're curious: https://love2d.org/wiki/Drawable ).
Here is the function and its various arguments:
So, let's say we define the shadow rune image like so:
That creates a new image object using the shadow rune image file, and then it "stores" this image object in the shadowRuneImage variable.
Now, to draw the shadowRuneImage at (100,100), we might use this code:
Get it?
With all of that in mind, my correct code above should make a lot of sense. Let me explain a couple of things about it though...
First of all, I setup a table called "runeImages" to store all of your rune image objects. Each entry into this table should have a key referring to its type. For example:
If you wanted to add a fire rune image object to the table, you might write:
This allows you to refer to these image objects later by referencing that entry in the table. So if you want to draw the shadow rune image at (100,100), you might write:
These leads to my version of your runeDraw() function:
This now references the runeImages table to draw the appropriate rune image. This should be pretty self-explanatory, but you may notice another change I made - I got rid of the "img" key/column from your runes table, as well as removed any references to it in your functions. Why? Because, with the runeImages table in place, "id" now serves both its original purpose and the purpose of "img."
For example, take a look at my adjustment to your love.load callback (in main.lua) again:
Instead of writing:
You just write:
Because the image object is already created and stored in the runeImages table, and the id that you write when calling your runeCreate function (in this case, "shadow") references that entry in the runeImages table (since the string you put as the id is the same).
So, if you had added a fire rune image object to the runeImages table like so:
You could create a new fire rune like this:
Ok, and with that it should be working now.
Oh, I did make one other change in runescreen.lua: in the runeCreate() function, I changed...
to:
This does almost the same thing (for your uses, it should have the exact same results), and is faster.
Ok, well hopefully that all made sense! Just in case you aren't able to get my changes above to work, I've attached my modified version of your project to this post.
Cheers!
-Ben
PS: If you want to add the "img" property back to the runes table (e.g. if there are cases where the id and the corresponding runeImages key are not the same), then feel free!
Your main problem is that you were going about this the wrong way. I'll show you what I mean by explaining my corrections.
Here is my version of your "runescreen.lua" file:
Code: Select all
runes = {}
runeImages = {}
runeImages["shadow"] = love.graphics.newImage("images/runes/shadow.png")
function runeCreate(x, y, id)
runes[#runes + 1] = {x=x, y=y, id=id}
end
function runeDraw()
for i,v in ipairs(runes) do
love.graphics.draw(runeImages[v.id], v.x, v.y)
end
end
function activaterune(key)
if key == "q" then
gamestate = "rune"
end
end
function deactivaterune(key)
if key == "q" then
gamestate = "play"
end
end
Code: Select all
function love.load()
gamestate = "play"
--loading up teh runes
runeCreate(100, 100, "shadow")
end
You see, "love.graphics.newImage" does not draw an image, instead it defines an Image object. It is not meant to be called over and over again. The function is usually used like this:
Code: Select all
image = love.graphics.newImage( filename )
--image is the variable which will contain the Image object, this is so that you can reference the Image object later
--filename most be a string and should be the filepath to the image file
No matter how many times you draw an Image object, you only have to define it ONCE. So, you may have 20 "shadow runes" being drawn, but you only have to define the shadow rune image object once.
Now we need to draw the image object. We can do this a few different ways, but for now we will use "love.graphics.draw()". This function draws "drawable objects" onto the screen. A "drawable object" is usually an image object, but it can also be other things (see here if you're curious: https://love2d.org/wiki/Drawable ).
Here is the function and its various arguments:
Code: Select all
love.graphics.draw( drawable object, x position, y position, rotation/orientation in radians, x-axis scale factor, y-axis scale factor, x-axis origin offset, y-axis origin offset, x-axis shearing factor, y-axis shearing factor )
Code: Select all
shadowRuneImage = love.graphics.newImage("images/runes/shadow.png")
Now, to draw the shadowRuneImage at (100,100), we might use this code:
Code: Select all
function love.draw()
love.graphics.draw(shadowRuneImage, 100, 100)
end
With all of that in mind, my correct code above should make a lot of sense. Let me explain a couple of things about it though...
First of all, I setup a table called "runeImages" to store all of your rune image objects. Each entry into this table should have a key referring to its type. For example:
Code: Select all
runeImages["shadow"] = love.graphics.newImage("images/runes/shadow.png")
Code: Select all
runeImages["fire"] = love.graphics.newImage("images/runes/firerune.png")
Code: Select all
function love.draw()
love.graphics.draw(runeImages["shadow"], 100, 100)
end
Code: Select all
function runeDraw()
for i,v in ipairs(runes) do
love.graphics.draw(runeImages[v.id], v.x, v.y)
end
end
For example, take a look at my adjustment to your love.load callback (in main.lua) again:
Code: Select all
function love.load()
gamestate = "play"
--loading up teh runes
runeCreate(100, 100, "shadow")
end
Code: Select all
runeCreate(100, 100, ""images/runes/shadow.png", "shadow")
Code: Select all
runeCreate(100, 100, "shadow")
So, if you had added a fire rune image object to the runeImages table like so:
Code: Select all
runeImages["fire"] = love.graphics.newImage("images/runes/firerune.png")
Code: Select all
runeCreate(100, 100, "fire")
Oh, I did make one other change in runescreen.lua: in the runeCreate() function, I changed...
Code: Select all
table.insert(runes, {x=x, y=y, id=id})
Code: Select all
runes[#runes + 1] = {x=x, y=y, id=id}
Ok, well hopefully that all made sense! Just in case you aren't able to get my changes above to work, I've attached my modified version of your project to this post.
Cheers!
-Ben
PS: If you want to add the "img" property back to the runes table (e.g. if there are cases where the id and the corresponding runeImages key are not the same), then feel free!
- Attachments
-
- test.zip
- (819.09 KiB) Downloaded 108 times
-
- Prole
- Posts: 7
- Joined: Sun Jan 06, 2013 2:50 am
Re: Help making a little "menu?"
Holy crap, man. You are awesome. Thank you so much. I definitely understand everything you changed and why it had to be changed. You're a freaking life savor.
-
- Party member
- Posts: 235
- Joined: Sat Dec 15, 2012 6:54 am
Re: Help making a little "menu?"
Great! I'm glad I could helpdementia_patient wrote:Holy crap, man. You are awesome. Thank you so much. I definitely understand everything you changed and why it had to be changed. You're a freaking life savor.
-
- Prole
- Posts: 7
- Joined: Sun Jan 06, 2013 2:50 am
Re: Help making a little "menu?"
Any ideas on how I might be able to fix that blur that happens when he runs? Is it just because the sprite is small and 16 bit? Or is there something I'm missing that I could fix?scutheotaku wrote:Great! I'm glad I could helpdementia_patient wrote:Holy crap, man. You are awesome. Thank you so much. I definitely understand everything you changed and why it had to be changed. You're a freaking life savor.
-
- Party member
- Posts: 235
- Joined: Sat Dec 15, 2012 6:54 am
Re: Help making a little "menu?"
Hmm, strange, LOVE does seem to be sometimes blurring your image whether your player is moving or not. You see this by quickly tapping the same direction button several times in a row (e.g. tap "d" "d" "d" "d"). I may be missing something in your code, but I'm not sure why it's doing this. I suspect that this may have to do with changing images so often, but that's sort of strange...maybe a more experienced LOVE user (I almost said "LOVEr"...haha) could help here? I've yet to do much experimentation with animation myselfdementia_patient wrote:Any ideas on how I might be able to fix that blur that happens when he runs? Is it just because the sprite is small and 16 bit? Or is there something I'm missing that I could fix?scutheotaku wrote:Great! I'm glad I could helpdementia_patient wrote:Holy crap, man. You are awesome. Thank you so much. I definitely understand everything you changed and why it had to be changed. You're a freaking life savor.
That being said, you may want to look into a few different ways of doing your animation. These may or may not fix your blurring issues...
I'll show you one way to do this based on your current setup, as well as two animation libraries. All three of these methods involve having your Link sprites in a spritesheet - just an image that holds all the different animation frames. Generally, each of the frames will be aligned to an invisible (or visible) grid. For more info on spritesheets, see: http://www.codeandweb.com/what-is-a-sprite-sheet & http://spritedatabase.net/tutorial_sheet.php . Also, while I haven't personally used it, here is a fairly popular program for generating spritesheets from sprites you've already drawn: http://www.codeandweb.com/sprite-sheet-maker
Your "Zelda3Sheet1.gif" file is a spritesheet, though I'm not sure if it's setup on a fixed-width/height grid.
So the first way to do this animation would be very similar to what you're doing now, except that you'll be using quads.
A quad is a "quadrilateral (a polygon with four sides and four corners) with texture coordinate information."
You create a quad similar to how you create an Image object:
Code: Select all
quad = love.graphics.newQuad( x, y, width, height, sw, sh )
--number x
--The top-left position along the x-axis.
--number y
--The top-left position along the y-axis.
--number width
--The width of the Quad. (Must be greater than 0.)
--number height
--The height of the Quad. (Must be greater than 0.)
--number sw
--The reference width, the width of the Image. (Must be greater than 0.)
--number sh
--The reference height, the height of the Image. (Must be greater than 0.)
--if your spritesheet is 128x256, then sw should be 128 and sh should be 256
To draw a quad, you use love.graphics.drawq():
Code: Select all
https://love2d.org/wiki/love.graphics.drawq
The thing about quads is that you can use them to draw only a portion of an image, like so:
Code: Select all
img = love.graphics.newImage("mushroom-64x64.png")
-- Let's say we want to display only the top-left
-- 32x32 quadrant of the Image:
top_left = love.graphics.newQuad(0, 0, 32, 32, 64, 64)
-- And here is bottom left:
bottom_left = love.graphics.newQuad(0, 32, 32, 32, 64, 64)
function love.draw()
love.graphics.drawq(img, top_left, 50, 50)
love.graphics.drawq(img, bottom_left, 50, 200)
end
So, you may do your animation something like this... (just an example):
Code: Select all
playerSpriteSheet = love.graphics.newImage("images/link.png")
playerRight = {}
playerRight[1] = love.graphics.newQuad(0, 0, 32, 32, 128, 128)
playerRight[2] = love.graphics.newQuad(32, 0, 32, 32, 128, 128)
playerRight[3] = love.graphics.newQuad(64, 0, 32, 32, 128, 128)
playerRight[4] = love.graphics.newQuad(96, 0, 32, 32, 128, 128)
playerRight[5] = love.graphics.newQuad(0, 32, 32, 32, 128, 128)
playerRight[6] = love.graphics.newQuad(32, 32, 32, 32, 128, 128)
playerRight[7] = love.graphics.newQuad(64, 32, 32, 32, 128, 128)
player.quad = playerRight[1]
Code: Select all
function playerMove(dt)
if love.keyboard.isDown("d") then
player.x = player.x + player.speed * dt
player.quad = playerRight[player.pnum]
player.animtimer = player.animtimer + dt
if player.animtimer > 0.08 then
player.pnum = player.pnum + 1
player.animtimer = 0
end
if player.pnum > 7 then
player.pnum = 1
end
end
end
Code: Select all
function player.draw()
love.graphics.setColor(255, 255, 255)
love.graphics.drawq(playerSpriteSheet, player.quad, player.x, player.y)
end
Though that's just one way to do animations.
Instead of that, you could try a LOVE animation library. Here are two popular ones:
https://love2d.org/wiki/anim8
https://love2d.org/wiki/AnAL
There's probably other methods too - like I said, I'm new to animating in LOVE also!
As for if anything above will fix your blurring...maybe? Sorry I don't have a concrete answer
Who is online
Users browsing this forum: Google [Bot] and 7 guests