I decided to give Love2d and LUA a shot today, and started work on a cool, new game with sfx and sounds and...ok it is a Pong clone. I found free art on opengameart.org and programmed my own clone. I am really impressed by LOVE. My biggest sin is my laziness and I managed to write my first game in an afternoon. I mean, I hate Pascal because it forces me to declare variables in the header. And even my fork bomb asked users to wait 30 seconds. All that typing...
And I had no problem writing in LOVE and LUA. Everything makes sense. Everything is short and clear. I just added one part, tested and added the next one. That's why it is called Buggy, until I drew trigonometric circle and angles on a piece of paper it didn't function properly.
Back to the game.
-I decided not to implement victory system, so it can be played till the end of the world (December 2012)
-Keys to move: W/S and Up/Down
-Keep an eye on the ball. It has a mind of its own
My next project is probably going to be Tic-Tac-Toe or Minesweeper. And after that, maybe time to combine it with this one and make a Breakout clone.
Again, great piece of software, and love 1984 reference on the forums.
End of obligatory show-off post
First Love2d project
First Love2d project
- Attachments
-
- Buggy.love
- (22.31 KiB) Downloaded 243 times
Random number generators can be cruel
- Robin
- The Omniscient
- Posts: 6506
- Joined: Fri Feb 20, 2009 4:29 pm
- Location: The Netherlands
- Contact:
Re: First Love2d project
Nice work for a first project. Two suggestions:
- The right paddle goes up infinitely far. Interestingly the left paddle's okay and going down works for either.
- The paddles are a bit slow. Increasing the speed will make the game feel more interesting and make players feel more empowered.
Help us help you: attach a .love.
Re: First Love2d project
So much of debugging. Forgot to put end in the IF statement before that. It placed the upper border only when you were pressing down Buggy lives up to its name. Increased the speed for both the paddles and the ball twice. You are right. It does feel more empowering.
- Attachments
-
- Buggy.love
- (22.31 KiB) Downloaded 154 times
Random number generators can be cruel
Re: First Love2d project
Time for an update on my progress in love world. After Pong I programmed TicTacToe, BreakOut and my newest monstro... creation: Tetris Clone.
-Left and Right to move
-Up and Down for drops
-Space for rotation
It has been a fun project. Halfway I realized that I could use loops to check for rotation and movement, but decided to keep if/else statements. Ugly, but it works. I used tetris to learn code segmentation and texture atlases. My next project is probably gonna be top down shoot em up. The goal is learning classes in LUA.
I have a few questions if anyone is willing to answer:
-If I have a large 1D table (bullet list in this case), should I use bulletList = nil to remove bullet or table.remove(bulletList,i). Is there significant difference in performance between these 2? In case of Bullet Hell Shmup, that is.
-What is faster: creating a new bullet or moving the old one, reseting its position, orientation and speed?
-Random tips about gameplay, mechanics and programming?
-Left and Right to move
-Up and Down for drops
-Space for rotation
It has been a fun project. Halfway I realized that I could use loops to check for rotation and movement, but decided to keep if/else statements. Ugly, but it works. I used tetris to learn code segmentation and texture atlases. My next project is probably gonna be top down shoot em up. The goal is learning classes in LUA.
I have a few questions if anyone is willing to answer:
-If I have a large 1D table (bullet list in this case), should I use bulletList = nil to remove bullet or table.remove(bulletList,i). Is there significant difference in performance between these 2? In case of Bullet Hell Shmup, that is.
-What is faster: creating a new bullet or moving the old one, reseting its position, orientation and speed?
-Random tips about gameplay, mechanics and programming?
- Attachments
-
- Tetris.love
- Completely Original Game
- (3.64 KiB) Downloaded 177 times
Random number generators can be cruel
- bartbes
- Sex machine
- Posts: 4946
- Joined: Fri Aug 29, 2008 10:35 am
- Location: The Netherlands
- Contact:
Re: First Love2d project
Overlord wrote: -If I have a large 1D table (bullet list in this case), should I use bulletList = nil to remove bullet or table.remove(bulletList,i). Is there significant difference in performance between these 2? In case of Bullet Hell Shmup, that is.
The former should be the faster of the two, I wouldn't be able to tell you whether it's significant.
Overlord wrote:
-What is faster: creating a new bullet or moving the old one, reseting its position, orientation and speed?
Moving one is probably faster, but I'm pretty sure this would be negligible unless you're completely filling the screen a few times over.
Re: First Love2d project
Congratulations!
Now for some RANDOM TIPS!
For a more responsive feel for moving and rotating pieces, I'd suggest removing the following lines...
... and instead, using the love.keypressed callback like this:
Instead of returning 1 from lockDown, I'd return true. That way, if I forgot how lockDown works, I wouldn't get confused about what 1 actually meant. Also, I could write if not lockDown() then which reads really nicely (you could also replace if loose == false then with if not loose then.)
Also, (unless I'm mistaken), in Lua, everything which isn't nil or false is a true condition, so instead of...
you could write...
For slightly more accurate timing, I think, you could replace timer = 0 with timer = timer - 0.2.
Using variables instead of literal numbers can make things more readable and flexible. For example, instead of using 0.20, you could use fallTime or something, or maybe BLOCK_SIZE instead of 32 (the capital letters being a convention for global variables which aren't expected to change).
You might want to consider stringing together conditions with and:
... could be written like:
And also:
... could be written like:
Another way to write this bit:
... could be like this:
({"This works because you can access elements of literal tables like this, using parentheses."})[1]
Using this, you could write:
as...
(If the above code made absolutely no sense, don't worry. )
Here is some help from the future!
When looping through tables and removing elements (such as bullets from a tables of bullets), consider using a "reverse" numeric for loop instead of ipairs (apparently using ipairs and removing elements can cause problems.).
Or you may not even do it like this at all.
Oh, and, also...
I hope this helps!
Now for some RANDOM TIPS!
For a more responsive feel for moving and rotating pieces, I'd suggest removing the following lines...
Code: Select all
if love.keyboard.isDown("left") then
moveLeft()
elseif love.keyboard.isDown("right") then
moveRight()
elseif love.keyboard.isDown(" ") then
rotate()
end
Code: Select all
function love.keypressed(key)
if key == "left" then
moveLeft()
elseif key == "right" then
moveRight()
elseif key == " " then
rotate()
end
end
Also, (unless I'm mistaken), in Lua, everything which isn't nil or false is a true condition, so instead of...
Code: Select all
while pieceGrid[rotation][i] ~= nil do
Code: Select all
while pieceGrid[rotation][i] do
Using variables instead of literal numbers can make things more readable and flexible. For example, instead of using 0.20, you could use fallTime or something, or maybe BLOCK_SIZE instead of 32 (the capital letters being a convention for global variables which aren't expected to change).
You might want to consider stringing together conditions with and:
Code: Select all
if Piece == "I" then
if (Y == 19 or grid[Y+4][X+2] ~= " ") then
fillIn()
return 1
end
Code: Select all
if Piece == "I" and (Y == 19 or grid[Y+4][X+2] ~= " ") then
fillIn()
return 1
Code: Select all
if rotation == 1 then
if Piece == "I" then
if (Y == 21 or grid[Y+2][X] ~= " " or grid[Y+2][X+1]~= " " or grid[Y+2][X+2]~=" " or grid[Y+2][X+3]~=" ") then
fillIn()
return 1
end
elseif Piece == "J" then
if (Y == 21 or grid[Y+2][X] ~= " " or grid[Y+2][X+1] ~= " " or grid[Y+2][X+2] ~= " ") then
fillIn()
return 1
end
-- etc.
Code: Select all
if rotation == 1 then
if Piece == "I" and (Y == 21 or grid[Y+2][X] ~= " " or grid[Y+2][X+1] ~= " " or grid[Y+2][X+2] ~= " " or grid[Y+2][X+3]~=" ") or
Piece == "J" and (Y == 21 or grid[Y+2][X] ~= " " or grid[Y+2][X+1] ~= " " or grid[Y+2][X+2] ~= " ") or
Piece == "L" and (Y == 21 or grid[Y+2][X] ~= " " or grid[Y+2][X+1] ~= " " or grid[Y+2][X+2] ~= " ") or
Piece == "O" and (Y == 21 or grid[Y+2][X] ~= " " or grid[Y+2][X+1] ~= " ") or
Piece == "S" and (Y == 21 or grid[Y+2][X] ~= " " or grid[Y+2][X+1] ~= " " or grid[Y+1][X+2] ~= " ") or
Piece == "T" and (Y == 21 or grid[Y+2][X] ~= " " or grid[Y+2][X+1] ~= " " or grid[Y+2][X+2] ~= " ") or
Piece == "Z" and (Y == 21 or grid[Y+1][X] ~= " " or grid[Y+2][X+1] ~= " " or grid[Y+2][X+2] ~= " ") then
fillIn()
return 1
end
-- etc.
Code: Select all
for j = 1, #pieceGrid[rotation][i] do
local c = pieceGrid[rotation][i]:sub(j,j)
if c == "O" then
love.graphics.drawq(blocks,orange,(X+j-2)*32,(Y+i-4)*32)
elseif c == "Y" then
love.graphics.drawq(blocks,yellow,(X+j-2)*32,(Y+i-4)*32)
elseif c == "B" then
love.graphics.drawq(blocks,blue,(X+j-2)*32,(Y+i-4)*32)
-- etc.
end
end
Code: Select all
for j = 1, #pieceGrid[rotation][i] do
local c = pieceGrid[rotation][i]:sub(j,j)
if c ~= " " then
local color = ({
O = orange,
Y = yellow,
B = blue,
G = green,
C = cyan,
P = purple,
R = red,
})[c]
love.graphics.drawq(blocks,color,(X+j-2)*32,(Y+i-4)*32)
end
end
Using this, you could write:
Code: Select all
GeneratorDefault = {"I","J","L","O","S","T","Z"}
generator = math.random(1,7)
Piece = GeneratorDefault[generator]
Code: Select all
Piece = ({"I","J","L","O","S","T","Z"})[math.random(1,7)]
Here is some help from the future!
When looping through tables and removing elements (such as bullets from a tables of bullets), consider using a "reverse" numeric for loop instead of ipairs (apparently using ipairs and removing elements can cause problems.).
Code: Select all
for i = #bullets, 1, -1 do
if bullets[i]:isOffscreen() then
table.remove(bullets, i)
end
end
Oh, and, also...
So "Lua" (uncapitalised) is the preferred spelling. Fun facts!http://www.lua.org/about.html wrote:"Lua" (pronounced LOO-ah) means "Moon" in Portuguese. As such, it is neither an acronym nor an abbreviation, but a noun. More specifically, "Lua" is a name, the name of the Earth's moon and the name of the language.
I hope this helps!
Re: First Love2d project
@bartbes Thx for a quick reply. I will try using nil. Garbage collector should kick in sometimes. As for moving, I will try it with manager class
@Santos Thx for the post. Sorry about code readability, forgot to comment it
- I have some background in C++, so 1 as true kinda slipped. When I remembered, I was in process of creating .love file.
-I was thinking about merging all conditions into one, but my hand got trigger happy (Ctrl+C,Ctrl+V). Yay for laziness, even though it makes code run slower. Kudos for your patience
-I didn't know that about tables. That is real useful. In one post you shortened the code for 100 lines minimum.
-Now when I think about it, keyPressed does sound like a solution to be used. At the time, I was worried that people will abuse it by pressing it 1000 times/second
-And now for the last one. And I give you salutes. You are a mind reader. In tetris, I used ipairs, remove row, add empty row, and hoped for the best. As it turned out -1+1 = 0, and I was saved. But in BH SHMUP I wont be able to add empty bullets (That doesn't even make sense). So loop comes in perfect. But I was thinking (better yet: had been thinking) about using while loop eg.
That was my genius idea. It would never have occurred to me to use reverse loop. It eliminated re-numeration problem completely.
Thanks for the time it took you to write the post and dig through the code
@Santos Thx for the post. Sorry about code readability, forgot to comment it
- I have some background in C++, so 1 as true kinda slipped. When I remembered, I was in process of creating .love file.
-I was thinking about merging all conditions into one, but my hand got trigger happy (Ctrl+C,Ctrl+V). Yay for laziness, even though it makes code run slower. Kudos for your patience
-I didn't know that about tables. That is real useful. In one post you shortened the code for 100 lines minimum.
-Now when I think about it, keyPressed does sound like a solution to be used. At the time, I was worried that people will abuse it by pressing it 1000 times/second
-And now for the last one. And I give you salutes. You are a mind reader. In tetris, I used ipairs, remove row, add empty row, and hoped for the best. As it turned out -1+1 = 0, and I was saved. But in BH SHMUP I wont be able to add empty bullets (That doesn't even make sense). So loop comes in perfect. But I was thinking (better yet: had been thinking) about using while loop eg.
Code: Select all
while i < #list do
if list[i] == doneFor then
table.remove(list,i) --This will renumber every element after it, so there is no need to increment i
else
i = i+1
end
end
Thanks for the time it took you to write the post and dig through the code
Random number generators can be cruel
Who is online
Users browsing this forum: No registered users and 0 guests