First Love2d project

Show off your games, demos and other (playable) creations.
Post Reply
User avatar
Overlord
Prole
Posts: 4
Joined: Sun Jul 08, 2012 7:57 pm

First Love2d project

Post by Overlord »

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
Attachments
Buggy.love
(22.31 KiB) Downloaded 243 times
Random number generators can be cruel
User avatar
Robin
The Omniscient
Posts: 6506
Joined: Fri Feb 20, 2009 4:29 pm
Location: The Netherlands
Contact:

Re: First Love2d project

Post by Robin »

Nice work for a first project. Two suggestions:
  1. The right paddle goes up infinitely far. Interestingly the left paddle's okay and going down works for either.
  2. 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.
User avatar
Overlord
Prole
Posts: 4
Joined: Sun Jul 08, 2012 7:57 pm

Re: First Love2d project

Post by Overlord »

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
User avatar
Overlord
Prole
Posts: 4
Joined: Sun Jul 08, 2012 7:57 pm

Re: First Love2d project

Post by Overlord »

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?
Attachments
Tetris.love
Completely Original Game
(3.64 KiB) Downloaded 177 times
Random number generators can be cruel
User avatar
bartbes
Sex machine
Posts: 4946
Joined: Fri Aug 29, 2008 10:35 am
Location: The Netherlands
Contact:

Re: First Love2d project

Post by bartbes »

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.
Santos
Party member
Posts: 384
Joined: Sat Oct 22, 2011 7:37 am

Re: First Love2d project

Post by Santos »

Congratulations! :awesome:

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
... and instead, using the love.keypressed callback like this:

Code: Select all

function love.keypressed(key)
	if key == "left" then
		moveLeft()
	elseif key == "right" then
		moveRight()
	elseif key == " "  then
		rotate()
	end
end
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...

Code: Select all

while pieceGrid[rotation][i] ~= nil do
you could write...

Code: Select all

while pieceGrid[rotation][i] do
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:

Code: Select all

if Piece == "I" then
	if (Y == 19 or grid[Y+4][X+2] ~= " ") then
		fillIn()
		return 1
	end
... could be written like:

Code: Select all

if Piece == "I" and (Y == 19 or grid[Y+4][X+2] ~= " ") then
	fillIn()
	return 1
And also:

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.
... could be written like:

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.
Another way to write this bit:

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
... could be like this:

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
({"This works because you can access elements of literal tables like this, using parentheses."})[1]

Using this, you could write:

Code: Select all

GeneratorDefault = {"I","J","L","O","S","T","Z"}
generator = math.random(1,7)
Piece = GeneratorDefault[generator]
as...

Code: Select all

Piece = ({"I","J","L","O","S","T","Z"})[math.random(1,7)]
(If the above code made absolutely no sense, don't worry. :D)

Here is some help from the future! :o

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
Or you may not even do it like this at all. :D

Oh, and, also...
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.
So "Lua" (uncapitalised) is the preferred spelling. Fun facts! :ultrahappy:

I hope this helps!
User avatar
Overlord
Prole
Posts: 4
Joined: Sun Jul 08, 2012 7:57 pm

Re: First Love2d project

Post by Overlord »

@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). :ultrahappy: 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. :awesome:
-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
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
Random number generators can be cruel
Post Reply

Who is online

Users browsing this forum: Bing [Bot] and 2 guests