A few minor questions

Questions about the LÖVE API, installing LÖVE and other support related questions go here.
Forum rules
Before you make a thread asking for help, read this.
gf123
Prole
Posts: 2
Joined: Sun Apr 17, 2011 4:37 pm

A few minor questions

Post by gf123 »

Hello, I have been using Love for a day or so, and I think it is great. However there are one or two things that I have not yet figured out that may be included in the package, or may need extra coding by me:

1, A way to pause all activity in the game when a button is pressed
2, A way to reset a game once the player has lost.

Since this is likely to need user coding, this is the code I am trying to implement it with:

Code: Select all

function love.load()
	hero = {} --A table for the hero
	hero.x = 80
	hero.y = 300
	hero.width=15
	hero.height=15
	hero.speed = 300
	score = 0
	enemies = {} --A table for the enemies
	gameover = ("false")
	hero.shots = {}

	for i=0,5 do
		enemy = {}
		enemy.width=40
		enemy.height=20
		enemy.x = math.random(800,1000)
		enemy.y = math.random(150,450)
		enemy.speed = 20
		table.insert (enemies, enemy)

	end
end

function love.update(dt)
	if gameover ~= ("true") then
		if love.keyboard.isDown("left") then
			hero.x = hero.x - hero.speed*dt
		elseif love.keyboard.isDown("up") then
			hero.y = hero.y - hero.speed*dt
		elseif love.keyboard.isDown("down") then
			hero.y = hero.y + hero.speed*dt
		elseif love.keyboard.isDown("right") then
			hero.x = hero.x + hero.speed*dt
		end

		for i,v in ipairs(enemies) do

			--let them move
			v.x = v.x - (enemy.speed+0.3*score)*dt

			--stop the game when they reach the edge
			if v.x <= 0 then
				gameover = ("true")
			end
		end

		local remEnemy = {}
		local remShot = {}

		--update those shots
		for i,v in ipairs(hero.shots) do

			--move them across
			v.x = v.x + 100*dt

			-- Remove non-visible shots
			if v.x < 800 then
				table.insert(remShot, i)
			end

			-- check for collision with enemies
			for ii,vv in ipairs(enemies) do
				if CheckCollision(v.x,v.y,2,5,vv.x,vv.y,vv.width,vv.height) then
					-- mark that enemy for removal
					table.insert(remEnemy, ii)
					--generate a new one
					i=i+1
					enemy = {}
					enemy.width=40
					enemy.height=20
					enemy.x = math.random(800,1000)
					enemy.y = math.random(150,450)
					enemy.speed = 20
					table.insert (enemies, enemy)

					-- mark the shot to be removed
					table.insert(remShot, i)

				end
			end
		end

		-- remove the marked enemies
		for i,v in ipairs(remEnemy) do
			table.remove(enemies, v)
			score = math.floor(score + 5 + enemy.speed/1000)
		end

		--remove the shot
		for i,v in ipairs(remShot) do
			table.remove(hero.shots, v)
		end

		--create new enemy

	end

end

function love.draw()
	--let's draw some ground
	love.graphics.setColor(255,255,255,255)
	love.graphics.rectangle("fill", 0, 500, 800, 100)

	--let's draw some sky
	love.graphics.setColor(255,255,255,255)
	love.graphics.rectangle("fill", 0, 0, 800, 100)


	--how to play the game
	love.graphics.setColor(0,0,0,255)
	love.graphics.print("Stop the bad guys from crossing the screen!", 10, 550)
	love.graphics.print("Arrow keys to move", 10, 565)
	love.graphics.print("Press space when on top of an enemy to kill it", 10, 580)

	--let's draw our hero
	love.graphics.setColor(255,255,255,255)
	love.graphics.rectangle("fill", hero.x, hero.y, hero.width, hero.height)

	-- let's draw some enemies
	love.graphics.setColor(255,255,255,255)
	for i,v in ipairs(enemies) do
		love.graphics.rectangle("fill", v.x, v.y, v.width, v.height)
	end

	-- What are the scores
	love.graphics.setColor(0,0,0,255)
	love.graphics.print("Score:", 10, 10)
	love.graphics.print(score, 100, 10)


	-- let's draw our shots
	love.graphics.setColor(255,255,255,255)
	for i,v in ipairs(hero.shots) do
		love.graphics.rectangle("fill", v.x, v.y, 2, 2)
	end

	if gameover == ("true") then
		love.graphics.print("YOU LOSE!", 370, 295)
	end
end

function shoot()
	local shot = {}
	shot.y = hero.y + hero.height/2
	shot.x = hero.x
	table.insert(hero.shots, shot)
end

function love.keyreleased(key)
	if (key == " ") then
		shoot()
	end
	if(key == "f") then
		love.graphics.toggleFullscreen()
	end
end

function love.keypressed(k)
	if k == 'escape' then
		love.event.push('q') --quit the game
	end
end

function CheckCollision(box1x, box1y, box1w, box1h, box2x, box2y, box2w, box2h)
    if box1x > box2x + box2w - 1 or -- Is box1 on the right side of box2?
       box1y > box2y + box2h - 1 or -- Is box1 under box2?
       box2x > box1x + box1w - 1 or -- Is box2 on the right side of box1?
       box2y > box1y + box1h - 1    -- Is b2 under b1?
    then
        return false                -- No collision. Yay!
    else
        return true                 -- Yes collision. Ouch!
    end
end
The code is a bit messy and one or two things don't work that well (Because parts of it were done using tutorials), but it gets the job done.

It is all you need to run my game too, so if you want you can download it and run it, give me some feedback of my first game so far :). Thanks to anyone who helps.
User avatar
Taehl
Dreaming in associative arrays
Posts: 1025
Joined: Mon Jan 11, 2010 5:07 am
Location: CA, USA
Contact:

Re: A few minor questions

Post by Taehl »

1) One way to pause the game could work like this:

Code: Select all

-- At the top of love.update
function love.update(dt)
	if paused then return end
	-- Your normal code goes here
end

-- Press the P key to toggle pause
function love.keypressed(k)
	if k == "p" then paused = not paused end
end
2) You can reset the game very easily by reloading main.lua and calling love.load, like this:

Code: Select all

love.filesystem.load("main.lua")() love.load()
Earliest Love2D supporter who can't Love anymore. Let me disable pixel shaders if I don't use them, dammit!
Lenovo Thinkpad X60 Tablet, built like a tank. But not fancy enough for Love2D 0.10.0+.
User avatar
BlackBulletIV
Inner party member
Posts: 1261
Joined: Wed Dec 29, 2010 8:19 pm
Location: Queensland, Australia
Contact:

Re: A few minor questions

Post by BlackBulletIV »

Taehl wrote:You can reset the game very easily by reloading main.lua and calling love.load, like this:

Code: Select all

love.filesystem.load("main.lua")() love.load()
Hey I never thought of re-loading main.lua. Good idea!
User avatar
Robin
The Omniscient
Posts: 6506
Joined: Fri Feb 20, 2009 4:29 pm
Location: The Netherlands
Contact:

Re: A few minor questions

Post by Robin »

It might not be -- this also reloads all resources and such, so it won't be a good solution for a larger game.
Help us help you: attach a .love.
User avatar
Jasoco
Inner party member
Posts: 3726
Joined: Mon Jun 22, 2009 9:35 am
Location: Pennsylvania, USA
Contact:

Re: A few minor questions

Post by Jasoco »

If coded correctly, you would simply need to load love.load().

Though that would only be if you want to hard reset it. If you want to soft reset, i.e. you get game over and want to return to the title screen, do not do that.

BTW, would reloading main.lua do anything screwy with memory? Like increase its usage? Or would Löve simply just replace all memory used by the stuff that was previously loaded with the refreshly loaded stuff?
User avatar
Taehl
Dreaming in associative arrays
Posts: 1025
Joined: Mon Jan 11, 2010 5:07 am
Location: CA, USA
Contact:

Re: A few minor questions

Post by Taehl »

Lua's garbage collection would handle it all just fine. Nothing wrong with doing it that way. It may not be the ideal solution for a huge, complex game, but it's best to start with basics.
Earliest Love2D supporter who can't Love anymore. Let me disable pixel shaders if I don't use them, dammit!
Lenovo Thinkpad X60 Tablet, built like a tank. But not fancy enough for Love2D 0.10.0+.
User avatar
miko
Party member
Posts: 410
Joined: Fri Nov 26, 2010 2:25 pm
Location: PL

Re: A few minor questions

Post by miko »

Taehl wrote:Lua's garbage collection would handle it all just fine. Nothing wrong with doing it that way. It may not be the ideal solution for a huge, complex game, but it's best to start with basics.
I think the best to start with is to do it the right way from the beginning. And this would be to create a "startup function" which will set the initial state of your game (scores, positions, etc). If all your game state was in one place (say, a one table GameSettings), and if you made similar "cleanup function", you could easily save your game state and reload it later.

I have changed your code to support this. Check those keypresses:
"r" - to init the game
"1" - to save the current state
"2" - to recall last saved state

Press "1", "r", "2" in sequence to check how it works.

For saving/loading a state I would use json to encode/decode the GameState table.
Attachments
main.lua
Redesigned to use a game state
(5.01 KiB) Downloaded 131 times
My lovely code lives at GitHub: http://github.com/miko/Love2d-samples
User avatar
miko
Party member
Posts: 410
Joined: Fri Nov 26, 2010 2:25 pm
Location: PL

Re: A few minor questions

Post by miko »

Robin wrote:It might not be -- this also reloads all resources and such, so it won't be a good solution for a larger game.
And If I am not mistaken, you would need to unset package.loaded for every require()'d file, as Lua itself caches every require()'d file. So if part of your game setting was in a required file, you would miss it by only using loadfile('main.lua').
My lovely code lives at GitHub: http://github.com/miko/Love2d-samples
gf123
Prole
Posts: 2
Joined: Sun Apr 17, 2011 4:37 pm

Re: A few minor questions

Post by gf123 »

Taehl wrote:1) One way to pause the game could work like this:

Code: Select all

-- At the top of love.update
function love.update(dt)
	if paused then return end
	-- Your normal code goes here
end

-- Press the P key to toggle pause
function love.keypressed(k)
	if k == "p" then paused = not paused end
end
2) You can reset the game very easily by reloading main.lua and calling love.load, like this:

Code: Select all

love.filesystem.load("main.lua")() love.load()
Thanks for all the help.

In the end I figured out the pausing in a similar way to how you show it. The game reset was a great idea, and works well in my game anyway. Although I would really want to learn how to keep a save state.

Originally I was going to save the current best score in a file called score.txt, but it doesn't seem that the code I use in lua works with love2D =/.

So thanks miko, I will take a look at that file later and figure out how it all works.
User avatar
miko
Party member
Posts: 410
Joined: Fri Nov 26, 2010 2:25 pm
Location: PL

Re: A few minor questions

Post by miko »

gf123 wrote: In the end I figured out the pausing in a similar way to how you show it. The game reset was a great idea, and works well in my game anyway. Although I would really want to learn how to keep a save state.
Hey, it is almost implemented in the code I have attached:
- for saving a game, you need to serialize the GameState table, and save the resulting string in a file (in gameFinish()).
- for loading a game, you need to read the file, unserialize the contents, and pass it (the resulting table) as an argument to gameInit()

For serializing/deserializing a table I would use json from here: http://www-users.rwth-aachen.de/David.Kolf/json-lua
so:

Code: Select all

json=require 'dkjson'
--save:
serialized=json.encode(GameState)
io.open('savedgame.json', 'w'):write(serialized)
--load
gameInit(json.deocde(io.open('savedgame.json', 'r'):read('*a')))
(OK, you will need to check for errors, but you get the idea).
gf123 wrote:
Originally I was going to save the current best score in a file called score.txt, but it doesn't seem that the code I use in lua works with love2D =/.
It should work. Just remember, that love2d is restricted as to where it can write to. Check out the docs here: love.filesystem and here: love.filesystem.setIdentity
My lovely code lives at GitHub: http://github.com/miko/Love2d-samples
Post Reply

Who is online

Users browsing this forum: No registered users and 2 guests