"Questions that don't deserve their own thread" thread

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.
User avatar
Tjakka5
Party member
Posts: 243
Joined: Thu Dec 26, 2013 12:17 pm

Re: "Questions that don't deserve their own thread" thread

Post by Tjakka5 »

4aiman wrote:Is there a way to load and display some image from a web server?
Something like

Code: Select all

love.graphics.newImage("http://server.com/imgs/pic1.png")
?
I messed around with this when building my Hentai app (Dont ask).

Use luasocket's http.request to get the file, then just load it as a image.
Note that you may want to use threads when doing this, as it may take a long time.
You should also do some error checking / fall back when the server doesn't respond for whatever reason.

Code: Select all

love.math.setRandomSeed(os.time())
love.graphics.setDefaultFilter("nearest", "nearest")

local Http        = require "socket.http"

-- This URL is a .php script which returns the amount of images at that url.
local TotalImages = Http.request("http://tjakka5.sorunome.de/Extern%20Files/Projects/Data/GabeBot/Images")


local function loadImage(i)
   i = i or love.math.random(1, TotalImages)

   -- Load a random url and load it as an image
   local a, b, c = Http.request("http://tjakka5.sorunome.de/Extern%20Files/Projects/Data/GabeBot/Images/"..i..".png")
   local file = love.filesystem.newFileData(a, "image.png")
   return love.graphics.newImage(file)
end

-- load our image
local image = loadImage()

-- Draw the image
function love.draw()
   love.graphics.draw(image)
end
!! I do not guarantee that these url's will work in the future !!
User avatar
Positive07
Party member
Posts: 1014
Joined: Sun Aug 12, 2012 4:34 pm
Location: Argentina

Re: "Questions that don't deserve their own thread" thread

Post by Positive07 »

Tjakka5 wrote: I messed around with this when building my Hentai app (Dont ask).
Now you got us interested ;) ;) ;) ;)
for i, person in ipairs(everybody) do
[tab]if not person.obey then person:setObey(true) end
end
love.system.openURL(github.com/pablomayobre)
User avatar
ken.athomos
Citizen
Posts: 77
Joined: Fri Aug 05, 2016 10:13 am
Location: Philippines

Re: "Questions that don't deserve their own thread" thread

Post by ken.athomos »

I wanna ask how to stop the game from running in the background while in another gamestate.

I'm still coding my first project - an endless runner (see Post1 and Post2). I've only been able to recode again around this time because first semester ended.

Anyways, here's the scenario:

My game has self-coded gamestates. I'm not using any libraries. So I play the game, collision when true, and now I'm on the game over screen. So far so good. However, whenever I try to restart a new game, I don't start a new "game". What I mean by this is that, whenever I press "R" to restart the game, instead of resetting everything as you'd expect it, the game still plays during the game over state. See the gif below.

Image

As you can see, you don't immediately restart a new game and they aren't resetting. The same thing happens when you reach the game over screen, press escape to return to main menu, and then press enter to start a new game.

To be honest, I kind of expected this to happen since I only change gamestates whenever the appropriate key is pressed.

I was wondering how to do that?

My first idea of the implementation was to turn some functions to nil when the state is gameover (or another way I thought of doing this was making the functions nil when collision happened). Something along the lines of this:

Code: Select all

if gamestate == gameover then
   function = nil
   if key was pressed then
      gamestate = game
   end
end
However, the problem would the be how to reset everything because if I don't, the functions would still be considered nil and it would return a value nil error.

I would like some help with this. If it's okay, I would prefer not using a library like HUMP for this one. As stated earlier, this is still my very first project, and I personally would like to code everything from scratch for experience and learning.

Here's the full code of what I consider are the concerned files. I have removed the turning of functions to nil on this one.

main.lua

Code: Select all

-- main.lua
require 'menu'
require 'ground'
require 'player'
require 'obstacle'
require 'score'
require 'gameover'

function love.load()
	-- Sets the current gamestate to menu.
	gamestate = 'menu'
	-- Loads all needed assets and variables.
	menu_load()
	ground_load()
	player_load()
	obstacle_load()
	score_load()
	gameover_load()
end

function love.update(dt)
	-- If the gamestate is the game, we then go to the game.
	if gamestate == 'game' then
		ground_update()
		player_update(dt)
		obstacle_update(dt)
		score_update()
	end
	-- If the gamestate is gameover, we then go to the gameover.
	if gamestate == 'gameover' then
		gameover_update()
	end

end

function love.draw()
	-- If gamestate is menu, we go to the menu.
	if gamestate == 'menu' then
		menu_draw()
	end
	-- If the gamestate is tgame, we go to the game.
	if gamestate == 'game' then
		ground_draw()
		player_draw()
		obstacle_draw()
		score_draw()
	end
	-- If the gamestate is gameover, we go to the gameover screen.
	if gamestate == 'gameover' then
		gameover_draw()
	end
end

function love.keypressed(key)
	-- Controls for Menu State.
	if gamestate == 'menu' then
		-- For starting a new game.
		if key == 'return' then
			gamestate = 'game'
		-- For quitting game.
		elseif key == 'escape'then
			love.event.quit()
		end
	end
	-- Controls for Game State.
	if gamestate == 'game' then
		-- For jumping.
		if key == 'space' and player.isJumping == 'false' then
			player.isJumping = 'true'
			if player.y_velocity == 0 then
				player.y_velocity = player.jump_height
			end
		end
		-- For dashing.
		if player.canDash <= 0 then
			if key == 'z' and player.isJumping == 'true' then
				player.canDash = player.maxCanDash
				player.isDashing = 'true'
				player.y_velocity = 0
			end
		end
		-- For dash canceling.
		if player.isDashing == 'true' and player.isJumping == 'true' then
			if key == 'x' then
				player.isDashing = 'false'
				player.isDashCanceling = 'true'
				player.airTime = 0
			end
		end
	end
	-- Controls for Gameover State.
	if gamestate == 'gameover' then
		-- For restarting.
		if key == 'r' then
			gamestate = 'game'
		end
		-- For quitting to menu.
		if key == 'escape' then
			gamestate = 'menu'
		end
	end
end
gameover.lua (For the meantime, please disregard the empty functions. Thanks.)

Code: Select all

--gameover.lua
function gameover_load()

end

function gameover_update()

end

function gameover_draw()
	love.graphics.print('Game Over!', 0, 0)
	love.graphics.print('Your final score is: ' .. score, 0, 20)
	love.graphics.print('Press [R] to Restart.', 0, 40)
	love.graphics.print('Press [Escape] to Go Back to Menu', 0, 60)
end
I'll also add the .love file for those who want to try it.

Press the associated buttons to navigate the menu. (Not the final way of dealing with the menu).
Space - to jump
Z - to dash
X - to dash cancel
[Game #1] - Endless Runner.love
First coded with 0.10.1.
Continued coding with 0.10.2.
(4.17 KiB) Downloaded 69 times
Thanks in advance everyone :)
User avatar
Beelz
Party member
Posts: 234
Joined: Thu Sep 24, 2015 1:05 pm
Location: New York, USA
Contact:

Re: "Questions that don't deserve their own thread" thread

Post by Beelz »

I also prefer to write everything myself(except for certain things like animations and Tiled maps). This is a simplified way of how I handle states:

main.lua

Code: Select all

local states = {
	menu = require 'states.menu',
	game = require 'states.game',
	gameover = require 'states.gameover'
}

local cur = 'menu'

-- Global function 
function switchState(scn)
	if states[scn] then
		if states[cur].onExit then states[cur].onExit() end
		local prev = cur
		cur = scn
		if states[cur].onEnter then states[cur].onEnter(prev) end
	end
end

function love.update(...)			if states[cur].update then states[cur].update(...) end end
function love.draw(...) 			if states[cur].draw then states[cur].draw(...) end end
function love.keypressed(...) 		if states[cur].keypressed then states[cur].keypressed(...) end
function love.keyreleased(...) 		if states[cur].keyreleased then states[cur].keyreleased(...) end
function love.mousepressed(...)		if states[cur].mousepressed then states[cur].mousepressed(...) end
function love.mousereleased(...) 	if states[cur].mousereleased then states[cur].mousereleased(...) end
Then each state gets it's own file, only defining the functions it needs:

Code: Select all

local state = {}
function state.init()  end
function state.update(dt) end
function state.draw() end

function state.onEnter(prev) end
function state.onLeave() end

return state, state.init()

Code: Select all

if self:hasBeer() then self:drink()
else self:getBeer() end
GitHub -- Website
User avatar
Positive07
Party member
Posts: 1014
Joined: Sun Aug 12, 2012 4:34 pm
Location: Argentina

Re: "Questions that don't deserve their own thread" thread

Post by Positive07 »

ken.athomos wrote:- snip -
You need to reset the state of your game, that is, the score, player position, obstacles, etc.

To do this I created a reset function that calls the load function of each state. This function is called whenever you go from the gameover state to another state (so whenever "r" or "escape" is pressed while gamestate == "gameover")

I modified main.lua to this:

Code: Select all

require 'menu'
require 'ground'
require 'player'
require 'obstacle'
require 'score'
require 'gameover'

function reset () --ADDED FUNCTION
	--This function resets all the different states
	--Used on love.load and when "r" or "escape" is pressed in the gameover state
	menu_load()
	ground_load()
	player_load()
	obstacle_load()
	score_load()
	gameover_load()
end

function love.load()
	-- Sets the current gamestate to menu.
	gamestate = 'menu'
	-- Loads all needed assets and variables.
	reset() --USED HERE
end

function love.update(dt)
	-- If the gamestate is the game, we then go to the game.
	if gamestate == 'game' then
		ground_update()
		player_update(dt)
		obstacle_update(dt)
		score_update()
	end
	-- If the gamestate is gameover, we then go to the gameover.
	if gamestate == 'gameover' then
		gameover_update()
	end

end

function love.draw()
	-- If gamestate is menu, we go to the menu.
	if gamestate == 'menu' then
		menu_draw()
	end
	-- If the gamestate is tgame, we go to the game.
	if gamestate == 'game' then
		ground_draw()
		player_draw()
		obstacle_draw()
		score_draw()
	end
	-- If the gamestate is gameover, we go to the gameover screen.
	if gamestate == 'gameover' then
		gameover_draw()
	end
end

function love.keypressed(key)
	-- Controls for Menu State.
	if gamestate == 'menu' then
		-- For starting a new game.
		if key == 'return' then
			gamestate = 'game'
		-- For quitting game.
		elseif key == 'escape'then
			love.event.quit()
		end
	end
	-- Controls for Game State.
	if gamestate == 'game' then
		-- For jumping.
		if key == 'space' and player.isJumping == 'false' then
			player.isJumping = 'true'
			if player.y_velocity == 0 then
				player.y_velocity = player.jump_height
			end
		end
		-- For dashing.
		if player.canDash <= 0 then
			if key == 'z' and player.isJumping == 'true' then
				player.canDash = player.maxCanDash
				player.isDashing = 'true'
				player.y_velocity = 0
			end
		end
		-- For dash canceling.
		if player.isDashing == 'true' and player.isJumping == 'true' then
			if key == 'x' then
				player.isDashing = 'false'
				player.isDashCanceling = 'true'
				player.airTime = 0
			end
		end
	end
	-- Controls for Gameover State.
	if gamestate == 'gameover' then
		-- For restarting.
		if key == 'r' then
			gamestate = 'game'
			reset() --USED HERE
		end
		-- For quitting to menu.
		if key == 'escape' then
			gamestate = 'menu'
			reset() --USED HERE
		end
	end
end
Note that this is not ideal! For example if you were loading images, fonts or other asset, you don't want to do so every time you change from gameover to other state, you just need that on love.load. I recommend you add a function reset to each state, and use those functions instead.
for i, person in ipairs(everybody) do
[tab]if not person.obey then person:setObey(true) end
end
love.system.openURL(github.com/pablomayobre)
User avatar
ken.athomos
Citizen
Posts: 77
Joined: Fri Aug 05, 2016 10:13 am
Location: Philippines

Re: "Questions that don't deserve their own thread" thread

Post by ken.athomos »

Positive07 wrote:
ken.athomos wrote:- snip -
- snip -
Dude thanks a lot! I will definitely try this now :awesome:
nyenye
Citizen
Posts: 62
Joined: Fri Dec 02, 2016 1:44 pm

Re: "Questions that don't deserve their own thread" thread

Post by nyenye »

Okay I have two different questions. First of all say that it's a Top-Down view kind of game.

The first one is about "collisions" and the second one deals with Jumper and STI.
  • Collisions - I am using Hardon Collider, and till now very pleased, but right now I am dealing with collisions between two 'dynamic' entities and I get a not expected behaviour. The 'enemy' pushes the 'player'. Is this normal? Attached a video.

    Code: Select all

    function CollisionManager:resolveCollisions()
      -- For every dynamic collider do
      for _, dyn in ipairs(self.dynamics) do
        -- Check if active. If not active then it doesn't collide
        if dyn.is_active then -- if active then
          -- HardonCollider returns all collisions with the current dynamic collider (dyn)
          local collisions = self.hc:collisions(dyn)
          -- For each collision...
          for other, sv in pairs(collisions) do
          	-- If other active...
            if other.is_active
              and ( dyn.mask[other.group] or dyn.mask[Globals.MASK_ALL]) then -- mask filters collisions. Player and Enemy always collide
              if other.mode == Globals.COLLIDER_DYNAMIC then -- If other is dynamic too...
                CollisionManager.resolveDynVsDyn(dyn, other, sv) -- resolve collision for dynamic objects.
              else
                CollisionManager.resolveDynVsOther(dyn, other, sv)
              end
            end
          end
        end
      end
    end
    
    In this code below 'shape_a' is always the one colliding, and the one which should be separated.

    Code: Select all

    function CollisionManager.resolveDynVsDyn(shape_a, shape_b, sv)
      local entity_a = shape_a.entity
      local entity_b = shape_b.entity
      -- In the original code I had more things but it didn't work, so I simplified 
      --   to the minimum (more or less like a dynamic vs static collision)
      entity_a:move(sv.x, sv.y)
    end
    
    Maybe what happens is that the collision is checked two times? One for the player against enemy and second enemy against player. But I don't think it should because when it's resolved one time, its resolved for the two, right?
  • Jumper / STI - Has anyone dealt with Jumper and STI? Is there a standard way to do it? Or do you have to make a matrix map with walkable tiles each time you change a map on Tiled? Or does anyone have a trick to make it more or less dynamic?
Thanks in advance.
PD: game.love is attached
Attachments
game.love
(2.04 MiB) Downloaded 78 times
video.webm
(699.09 KiB) Not downloaded yet
User avatar
ken.athomos
Citizen
Posts: 77
Joined: Fri Aug 05, 2016 10:13 am
Location: Philippines

Re: "Questions that don't deserve their own thread" thread

Post by ken.athomos »

Quick question everyone.

Lets assume that I have a tank. I can move this tank with the left and right arrow keys. I can also aim its turret with the "Z"(aim left) and "C"(aim right) keys.

What's the best thing to do for all of the animations?

Should I:
a) Create a sprite batch of the tank that contains BOTH the moving animations and the aiming animations. Draw the tank.
OR
b) Create a sprite batch of the tank WITHOUT the turret that contains the moving animations. Then create a stick that will serve as the tank turret and give it the aiming animations. Draw the tank. Then draw the stick above it.
User avatar
raidho36
Party member
Posts: 2063
Joined: Mon Jun 17, 2013 12:00 pm

Re: "Questions that don't deserve their own thread" thread

Post by raidho36 »

You can just do the math on that one:

If you have X frames of tank animation and Y frames of turret animation, then you need X × Y frames if you use merged sprites, and X + Y if you use separate sprites. If you have 16 frames for both, then that's 256 frames vs. 32 frames.
User avatar
Sir_Silver
Party member
Posts: 286
Joined: Mon Aug 22, 2016 2:25 pm
Contact:

Re: "Questions that don't deserve their own thread" thread

Post by Sir_Silver »

With regards to the turret portion of the tank, I wouldn't have that be a part of any animation system, rather I'd just have an image for the turret loaded and then rotate the drawing of that image based on what angle it should be at.
Locked

Who is online

Users browsing this forum: Ahrefs [Bot], Google [Bot] and 43 guests