Love2D WebPlayer (WebGL)

Discuss any ports of LÖVE to different platforms.
User avatar
hyouko
Prole
Posts: 11
Joined: Wed May 07, 2014 11:50 pm

Re: Love2D WebPlayer (WebGL)

Post by hyouko »

SiENcE wrote:I think ghoulsblade put this webplayer on hold. Because most basic features of love are working.

Read the Readme to know what works and what not.
https://github.com/ghoulsblade/love-webplayer

@SalteMishel
What you get:
error during shader int:ReferenceError:gShaderCode_Fragment is not defined
It means Shaders/Fragment Shaders are not yet implemented (not defined)! So you need to remove that from your game to make it work with love-webplayer.
I got that same error at first, and I'm pretty sure it actually has nothing to do with shaders being implemented. That happens when you attempt to run the HTML file locally straight in your browser, because the Javascript makes an Ajax request at some point that assumes it's talking to a webserver.

Some quick notes from my testing so far that might be helpful to folks in the future looking to test their game in the webserver:
  • If you want to test locally, install an HTTP server - Apache will do. From there, go into the config file (conf/httpd.conf) and set DocumentRoot to wherever your lua-webplayer stuff lives, set that directory to be accessible, and start Appache running (bin/httpd.exe on Windows). You can check your stuff by pointing your browser at 127.0.0.1:8080 (or 80 if that's what you set the port to)
  • The thing that will most immediately foul up attempts to run a more recent Love project are width/height in the conf.lua file. Change those from t.window.width to t.screen.width and t.window.height to t.screen.height.
  • Other stuff I've observed that explicitly fouls up the webplayer includes joysticks and attempting to get the width / height of the screen.
  • Fonts don't work (from what I've seen so far). Won't crash, but it won't render your text either.
  • Math functions (math.random(), trig functions, etc.) and complex logic appear to be much slower. Maybe avoid them?
User avatar
IndieLöver
Prole
Posts: 29
Joined: Mon Jun 10, 2013 8:49 am

Re: Love2D WebPlayer (WebGL)

Post by IndieLöver »

Few questions here (my apologies if they were already answered, too lazy to read all the text :ehem: )

1.Any chance to get this by the next Ludum Dare (at december)? :)
2.Are the web versions of games coded with Lua as well?
3.Amazing work, keep it up! (not really a question) :awesome:
get52
Prole
Posts: 36
Joined: Wed Sep 04, 2013 1:53 pm

Re: Love2D WebPlayer (WebGL)

Post by get52 »

link is kill
Only douchebags tell the admins to delete threads once they get they're answer. :awesome:
User avatar
Ulydev
Party member
Posts: 445
Joined: Mon Nov 10, 2014 10:46 pm
Location: Paris
Contact:

Re: Love2D WebPlayer (WebGL)

Post by Ulydev »

Is this still supported ? If not, is there any way to get a working Löve2D web port ? That'd be so useful, especially for jams.
User avatar
SiENcE
Party member
Posts: 792
Joined: Thu Jul 24, 2008 2:25 pm
Location: Berlin/Germany
Contact:

Re: Love2D WebPlayer (WebGL)

Post by SiENcE »

Here is my working testlink for love-webplayer.
http://sience.schattenkind.net/love2d/


You have two choices.

older, on hold
https://github.com/ghoulsblade/love-webplayer

newer project, on hold?
https://github.com/TannerRogalsky/punchdrunk

You should support punchdrunk if you want a working webport of löve.

cheers
User avatar
Ulydev
Party member
Posts: 445
Joined: Mon Nov 10, 2014 10:46 pm
Location: Paris
Contact:

Re: Love2D WebPlayer (WebGL)

Post by Ulydev »

SiENcE, thank you for the links. I tried looking into love-webplayer but it seems like the API is outdated. As I couldn't help with Javascript nor web languages, I will look into punchdrunk for sure.

Have a nice day !
Hodor88
Prole
Posts: 2
Joined: Thu Mar 10, 2016 9:51 am

Re: Love2D WebPlayer (WebGL)

Post by Hodor88 »

Having some issues with webplayer:

Code: Select all

error during love.update(0.08) : Error: attempt to index field 'random' in a nil value : Error: attempt to index field 'random' in a nil value at lua_tableget (http://www.onelostpixel.de/wp-content/games/love/js/lua-parser.js:1593:11) at lua_tablegetcall (http://www.onelostpixel.de/wp-content/games/love/js/lua-parser.js:1303:14) at eval (eval at lua_load (http://www.onelostpixel.de/wp-content/games/love/js/lua-parser.js:35:21), :262:50) at lua_rawcall (http://www.onelostpixel.de/wp-content/games/love/js/lua-parser.js:1289:17) at lua_call (http://www.onelostpixel.de/wp-content/games/love/js/lua-parser.js:1320:12) at call_love_callback_guarded (http://www.onelostpixel.de/wp-content/games/love/js/main.js:307:10) at call_love_update (http://www.onelostpixel.de/wp-content/games/love/js/main.js:366:46) at MainStep (http://www.onelostpixel.de/wp-content/games/love/js/main.js:418:3) at MainRunAfterPreloadFinished (http://www.onelostpixel.de/wp-content/games/love/js/main.js:547:2) at PreLoadImageFinishOne (http://www.onelostpixel.de/wp-content/games/love/js/main.js:487:2)

Isn't is possible to use random?

Here is the Code:

Code: Select all

--debug = true;
--local utf8 = require("utf8")

OBJ_Player = {	
				x = love.graphics:getWidth()/2, 
				y = love.graphics:getHeight()-100, 
				speed = 150, 
				img = nil,
				img_idle = nil, 
				img_up = nil, 
				img_down = nil, 
				img_left = nil, 
				img_right = nil, 
				isAlive = false, 
				health = 100 
			 }

-- Objekt Vorlagen
Prefab_Enemy = {x = 200, y = 0, speed = 40, img = nil, health = 100, score = 10}
Prefab_Bullet = { damage = 35, speed = 500, img = nil }
Prefab_EnemyBullet = { damage = 15, speed = 300, img = nil }
Prefab_AstroidBig = { img = nil, speed = 25, health = 500, angle = 1, score = 15}
Prefab_AstroidSmall = { img = nil, speed = 72, health = 50, angle = 1, score = 5 }

-- Game Einstellungen
score = 0
alreadyPlayed = false;
playerName = "";
byteoffset = nil;

-- Timers
canShoot = true
canShootTimerMax = 0.1 
canShootTimer = canShootTimerMax

canSpawn = true;
canSpawnTimerMax = 3
canSpawnTimer = canSpawnTimerMax

StarcanSpawn = true;
StarcanSpawnTimerMax = 2
StarcanSpawnTimer = StarcanSpawnTimerMax

EnemycanShoot = true
EnemycanShootTimerMax = 1.2
EnemycanShootTimer = EnemycanShootTimerMax
starBG_img = nil

SmallAstroidcanSpawn = true;
SmallAstroidcanSpawnTimerMax = 3
SmallAstroidcanSpawnTimer = SmallAstroidcanSpawnTimerMax

BigAstroidcanSpawn = true;
BigAstroidcanSpawnTimerMax = 6
BigAstroidcanSpawnTimer = BigAstroidcanSpawnTimerMax

-- Listen
bullets = {}
enemies = {}
enemybullets = {}
stars = {}
astroids_small = {}
astroids_big = {}

function love.load(arg)
	OBJ_Player.img = love.graphics.newImage('plane.png')
	OBJ_Player.img_idle = love.graphics.newImage('plane.png')
	OBJ_Player.img_up = love.graphics.newImage('player_up.png')
	OBJ_Player.img_down = love.graphics.newImage('player_down.png')
	OBJ_Player.img_left = love.graphics.newImage('player_left.png')
	OBJ_Player.img_right = love.graphics.newImage('player_right.png')
	
	Prefab_AstroidBig.img = love.graphics.newImage('asteroid_big.png')
	Prefab_AstroidSmall.img = love.graphics.newImage('asteroid_small.png')
	
	
	Prefab_Bullet.img = love.graphics.newImage('bullet.png')
	Prefab_EnemyBullet.img = love.graphics.newImage('enemybullet.png')
	Prefab_Enemy.img = love.graphics.newImage('enemyShip01.png');
	starBG_img = love.graphics.newImage('star.png');
end

function love.draw(dt)

	if OBJ_Player.isAlive then
		-- Sterne hintergrund
		for i, star in ipairs(stars) do
			love.graphics.draw(star.img, star.x, star.y)
		end
		
		-- Asteroiden
		for i, astroid in ipairs(astroids_small) do
			love.graphics.draw(astroid.img, astroid.x, astroid.y, astroid.angle,1,1, astroid.img:getWidth()/2, astroid.img:getHeight()/2)
		end
		
		for i, astroid in ipairs(astroids_big) do
			love.graphics.draw(astroid.img, astroid.x, astroid.y, astroid.angle,1,1, astroid.img:getWidth()/2, astroid.img:getHeight()/2)
		end
		
		-- Spieler
		love.graphics.draw(OBJ_Player.img, OBJ_Player.x, OBJ_Player.y)
		love.graphics.print("Pilot: ".. playerName, 15, 15)
		love.graphics.print("Score: ".. tostring(score), 15, love.graphics:getHeight()-20)
		love.graphics.print("Shield: ".. tostring(OBJ_Player.health), love.graphics:getWidth()- 80, love.graphics:getHeight()-20)
		
		-- Spieler Schüsse
		for i, bullet in ipairs(bullets) do
			love.graphics.draw(bullet.img, bullet.x, bullet.y)
		end
		
		-- Feindlicher Laser
		for i, bullet in ipairs(enemybullets) do
			love.graphics.draw(bullet.img, bullet.x, bullet.y)
		end
		
		-- Feinde
		for i, enemy in ipairs(enemies) do
			love.graphics.draw(enemy.img, enemy.x, enemy.y)
		end

	else
		if alreadyPlayed then
			love.graphics.print("Your Score: ".. tostring(score), love.graphics:getWidth()/2-30, love.graphics:getHeight()/2-30)
			love.graphics.print("Press 'R' to restart", love.graphics:getWidth()/2-50, love.graphics:getHeight()/2-10)
			love.graphics.print("www.onelostpixel.de", 15, love.graphics:getHeight()-20)
			
			-- TODO: Interstial Anzeigen!
		else
			love.graphics.print("Enter your Name and Press Enter to Start:", love.graphics:getWidth()/2-50, love.graphics:getHeight()/2-10)
			love.graphics.print("Name: "..playerName, love.graphics:getWidth()/2-25, love.graphics:getHeight()/2+10)
			love.graphics.print("www.onelostpixel.de", 15, love.graphics:getHeight()-20)
		end
	end
end

function CheckPlayerAlive()
	-- Ist Spieler verstorben?
	if OBJ_Player.health <= 0 then
		--local file = love.filesystem.newFile("highscore.lua", love.file_write)
	    --love.filesystem.open(file)
	    --love.filesystem.write(file, playerName..":"..score)
	    --love.filesystem.close(file)

		OBJ_Player.isAlive = false;
		alreadyPlayed = true;
	end
end

function PlayerReset() 
		bullets = {}
		enemies = {}
		enemybullets = {}
		astroids_small = {}
		astroids_big = {}

		-- reset timers
		canShootTimer = canShootTimerMax
		createEnemyTimer = createEnemyTimerMax

		-- move player back to default position
		OBJ_Player.x = love.graphics:getWidth()/2
		OBJ_Player.y = love.graphics:getHeight()-100
		OBJ_Player.health = 100
		
		-- Random initial stars
		stars = {}
		for i=1, 100 do
			OBJ_Star = { x = love.math.random(1, love.graphics:getWidth()-1), y = love.math.random(1, love.graphics:getHeight()-1), img = starBG_img, speed = 12 }
			table.insert(stars, OBJ_Star)
		end
		
		-- reset our game state
		score = 0
		OBJ_Player.isAlive = true
end

function love.textinput(t)
	--byteoffset = utf8.offset(playerName, -1)
	playerName = playerName..t;
	--byteoffset = utf8.offset(playerName, -1)
end

-- Updating
function love.update(dt)

	CheckPlayerAlive()
	if not OBJ_Player.isAlive and not alreadyPlayed then
		--love.keyboard.setTextInput(true);
		if love.keyboard.isDown("backspace") then
			--playerName = string.sub(playerName, 1, byteoffset - 1)
		end
		if love.keyboard.isDown("kpenter") or love.keyboard.isDown("return") then
			PlayerReset();
			--love.keyboard.setTextInput(false);
		end
	end
	
	if alreadyPlayed and not OBJ_Player.isAlive and love.keyboard.isDown('r') then
		PlayerReset();
	end

	if love.keyboard.isDown('escape') then
		love.event.push('quit')
	end

	if love.keyboard.isDown('left','a') then
		if OBJ_Player.x > 0 then
			OBJ_Player.img = OBJ_Player.img_left;
			OBJ_Player.x = OBJ_Player.x - (OBJ_Player.speed*dt)
		end
	elseif love.keyboard.isDown('right','d') then
		if OBJ_Player.x < love.graphics.getWidth()-100 then
			OBJ_Player.img = OBJ_Player.img_right;
			OBJ_Player.x = OBJ_Player.x + (OBJ_Player.speed*dt)
		end
	elseif love.keyboard.isDown('up', 'w') then
		if OBJ_Player.y > love.graphics:getHeight()/2 then
			OBJ_Player.img = OBJ_Player.img_up;
			OBJ_Player.y = OBJ_Player.y - (OBJ_Player.speed*dt)
		end
	elseif love.keyboard.isDown('down', 's') then
		if OBJ_Player.y < love.graphics:getHeight()-100 then
			OBJ_Player.img = OBJ_Player.img_down;
			OBJ_Player.y = OBJ_Player.y + (OBJ_Player.speed*dt)
		end
	else
		OBJ_Player.img = OBJ_Player.img_idle;
	end
	
	canShootTimer = canShootTimer - (1 * dt)
	if canShootTimer < 0 then
	  canShoot = true
	end
	
	if love.keyboard.isDown(' ', 'rctrl', 'lctrl', 'ctrl') and canShoot then
	
		OBJ_Bullet = { x = OBJ_Player.x + (OBJ_Player.img:getWidth()/2), 
					   y = OBJ_Player.y, 
					   img = Prefab_Bullet.img, 
					   damage = Prefab_Bullet.damage, 
					   speed = Prefab_Bullet.speed 
					 }
					 
		table.insert(bullets, OBJ_Bullet)
		canShoot = false
		canShootTimer = canShootTimerMax

		for i, bullet in ipairs(bullets) do
	  		love.graphics.draw(bullet.img, bullet.x, bullet.y)
		end
	end

	for i, bullet in ipairs(bullets) do
		bullet.y = bullet.y - (bullet.speed * dt)

	  	if bullet.y < 0 then -- remove bullets when they pass off the screen
			table.remove(bullets, i)
		end
	end
	
	canSpawnTimer = canSpawnTimer - (1 * dt)
	if canSpawnTimer < 0 then
	  canSpawn = true
	end
	
	if canSpawn then
		OBJ_Enemy = { 
					x = love.math.random(50, love.graphics:getWidth()-100), 
					y = 0, 
					img = Prefab_Enemy.img, 
					damage = Prefab_Enemy.damage, 
					speed = Prefab_Enemy.speed, 
					health = Prefab_Enemy.health, 
					score = Prefab_Enemy.score 
					}
					
		table.insert(enemies, OBJ_Enemy)
		canSpawn = false
		canSpawnTimer = canSpawnTimerMax
	end

	StarcanSpawnTimer = StarcanSpawnTimer - (1 * dt)
	if StarcanSpawnTimer < 0 then
	  StarcanSpawn = true
	end
	
	if StarcanSpawn then
		OBJ_Star = { 
					x = love.math.random(50, love.graphics:getWidth()-100), 
					y = 0, 
					img = starBG_img, 
					speed = 12 
					}
				
		table.insert(stars, OBJ_Star)
		StarcanSpawn = false
		StarcanSpawnTimer = StarcanSpawnTimerMax
	end
	
	for i, star in ipairs(stars) do
		star.y = star.y + (star.speed * dt)
		
		if star.y > love.graphics:getHeight() then
			table.remove(stars, i)
		end
	end
	
	for i, enemy in ipairs(enemies) do
		enemy.y = enemy.y + (enemy.speed * dt)
		
		-- Kollision prüfen ob Feind getroffen wurde
		for j, bullet in ipairs(bullets) do
			if CheckCollision(enemy.x, enemy.y, enemy.img:getWidth(), enemy.img:getHeight(), bullet.x, bullet.y, bullet.img:getWidth(), bullet.img:getHeight()) then
				enemy.health = enemy.health - bullet.damage
				if enemy.health <= 0 then
					score = score + enemy.score
					table.remove(enemies, i)
				end
				table.remove(bullets, j)
			end
		end
		
		EnemycanShootTimer = EnemycanShootTimer - (1 * dt)
		if EnemycanShootTimer < 0 then
		   EnemycanShoot = true
		end
		
		if EnemycanShoot then
			OBJ_EnemyBullet = { 
								x = enemy.x + (enemy.img:getWidth()/2), 
								y = enemy.y, 
								img = Prefab_EnemyBullet.img, 
								damage = Prefab_EnemyBullet.damage, 
								speed = Prefab_EnemyBullet.speed 
							   }
							   
			table.insert(enemybullets, OBJ_EnemyBullet)
			EnemycanShoot = false
			EnemycanShootTimer = EnemycanShootTimerMax
		end
		
	  	if enemy.y > love.graphics:getHeight() then -- remove enemy when they pass off the screen
			table.remove(enemies, i)
		end
		
		-- Kollision prüfen ob feindl. Raumschiff mit Spieler kollidiert
		if CheckCollision(enemy.x, enemy.y, enemy.img:getWidth(), enemy.img:getHeight(), OBJ_Player.x, OBJ_Player.y, OBJ_Player.img:getWidth(), OBJ_Player.img:getHeight()) 
		and OBJ_Player.isAlive then
			table.remove(enemies, i)
			OBJ_Player.isAlive = false;
			alreadyPlayed = true;
		end
	end
			
	for i, bullet in ipairs(enemybullets) do
		if CheckCollision(OBJ_Player.x, OBJ_Player.y, OBJ_Player.img:getWidth(), OBJ_Player.img:getHeight(), bullet.x, bullet.y, bullet.img:getWidth(), bullet.img:getHeight()) then
			OBJ_Player.health = OBJ_Player.health - bullet.damage;
			table.remove(enemybullets, i)
		end
	
		bullet.y = bullet.y + (bullet.speed * dt)

	  	if bullet.y > love.graphics:getHeight() then -- remove bullets when they pass off the screen
			table.remove(enemybullets, i)
		end
	end
	
	SmallAstroidcanSpawnTimer = SmallAstroidcanSpawnTimer - (1 * dt)
	if SmallAstroidcanSpawnTimer < 0 then
	  SmallAstroidcanSpawn = true
	end
	
	if SmallAstroidcanSpawn then
		OBJ_SAstroid = { x = love.math.random(50, love.graphics:getWidth()-100), y = 0, img = Prefab_AstroidSmall.img, speed = Prefab_AstroidSmall.speed, health = Prefab_AstroidSmall.health, angle = Prefab_AstroidSmall.angle, score = Prefab_AstroidSmall.score }
		table.insert(astroids_small, OBJ_SAstroid)
		SmallAstroidcanSpawn = false
		SmallAstroidcanSpawnTimer = SmallAstroidcanSpawnTimerMax
	end
	
	for i, astroid in ipairs(astroids_small) do
		astroid.y = astroid.y + (astroid.speed * dt)
		astroid.angle = astroid.angle + dt * math.pi/6
		astroid.angle = astroid.angle % (6*math.pi)
		for j, bullet in ipairs(bullets) do
			if CheckCollision(astroid.x, astroid.y, astroid.img:getWidth(), astroid.img:getHeight(), bullet.x, bullet.y, bullet.img:getWidth(), bullet.img:getHeight()) then
				astroid.health = astroid.health - bullet.damage
				if astroid.health <= 0 then
					score = score + astroid.score
					table.remove(astroids_small, i)
				end
				table.remove(bullets, j)
			end
		end
		
		if astroid.y > love.graphics:getHeight() then
			table.remove(astroids_small, i)
		end
	end
	
	BigAstroidcanSpawnTimer = BigAstroidcanSpawnTimer - (1 * dt)
	if BigAstroidcanSpawnTimer < 0 then
	  BigAstroidcanSpawn = true
	end
	
	if BigAstroidcanSpawn then
		OBJ_SAstroid = { x = love.math.random(50, love.graphics:getWidth()-100), y = 0, img = Prefab_AstroidBig.img, speed = Prefab_AstroidBig.speed, health = Prefab_AstroidBig.health, angle = Prefab_AstroidBig.angle, score = Prefab_AstroidBig.score }
		table.insert(astroids_big, OBJ_SAstroid)
		BigAstroidcanSpawn = false
		BigAstroidcanSpawnTimer = BigAstroidcanSpawnTimerMax
	end
	
	for i, astroid in ipairs(astroids_big) do
		astroid.y = astroid.y + (astroid.speed * dt)
		
		astroid.angle = astroid.angle + dt * math.pi/20
		astroid.angle = astroid.angle % (20*math.pi)
		
		for j, bullet in ipairs(bullets) do
			if CheckCollision(astroid.x, astroid.y, astroid.img:getWidth(), astroid.img:getHeight(), bullet.x, bullet.y, bullet.img:getWidth(), bullet.img:getHeight()) then
				astroid.health = astroid.health - bullet.damage
				if astroid.health <= 0 then
					score = score + astroid.score
					
					for i=1, love.math.random(5)+1 do
						
						if love.math.random(1) == 1 then
							posx = astroid.x + love.math.random(35)
						else
							posx = astroid.x - love.math.random(35)
						end
						
						if love.math.random(1) == 1 then
							posy = astroid.y + love.math.random(35)
						else
							posy = astroid.y - love.math.random(35)
						end
						
						OBJ_SAstroid = { x = posx, 
										 y = posy, 
										 img = Prefab_AstroidSmall.img, 
										 speed = Prefab_AstroidSmall.speed, 
										 health = Prefab_AstroidSmall.health,
										 angle = Prefab_AstroidSmall.angle,
										 score = Prefab_AstroidSmall.score
										}
										
						table.insert(astroids_small, OBJ_SAstroid)
					end
					
					table.remove(astroids_big, i)
				end
				table.remove(bullets, j)
			end
		end
		
		if astroid.y > love.graphics:getHeight() then
			table.remove(astroids_big, i)
		end
	end
end

function CheckCollision(x1,y1,w1,h1, x2,y2,w2,h2)
  return x1 < x2+w2 and
         x2 < x1+w1 and
         y1 < y2+h2 and
         y2 < y1+h1
end
User avatar
T-Bone
Inner party member
Posts: 1492
Joined: Thu Jun 09, 2011 9:03 am

Re: Love2D WebPlayer (WebGL)

Post by T-Bone »

Wouldn't love.js be a better and more modern Löve-to-web tool to use? I think this one is pretty outdated.
User avatar
alberto_lara
Party member
Posts: 372
Joined: Wed Oct 30, 2013 8:59 pm

Re: Love2D WebPlayer (WebGL)

Post by alberto_lara »

Hi, is this project still getting support? It doesn't look like :(
Last edited by alberto_lara on Mon Apr 04, 2016 3:15 am, edited 1 time in total.
Post Reply

Who is online

Users browsing this forum: No registered users and 17 guests