Player image

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.
Post Reply
White_Silla
Prole
Posts: 2
Joined: Tue Feb 18, 2014 1:11 am

Player image

Post by White_Silla »

Hi, i'm very new to Love and i watched a couple of tutorials and i did a platformer. I did a quick sprite and then changed the image of the player, but this happened:

Image

As you can see, the player is clipping through the floor

The image of the player is 32x32:

Image

And here is the main.lua of the game:

Code: Select all

local AdvTiledLoader = require("AdvTiledLoader.Loader")
require("camera")

function love.load()
	
	playerImage = love.graphics.newImage( 'textures/player.png' )
	
	--playerImage = love.graphics.newImage( 'textures/player.png' )

    love.graphics.setBackgroundColor( 220, 220, 255 )
	AdvTiledLoader.path = "maps/"
	map = AdvTiledLoader.load("map.tmx")
	map:setDrawRange(0, 0, map.width * map.tileWidth, map.height * map.tileHeight)
	
	camera:setBounds(0, 0, map.width * map.tileWidth - love.graphics.getWidth(), map.height * map.tileHeight - love.graphics.getHeight() )

	world = 	{
				gravity = 1536,
				ground = 512,
				}
				
	player = 	{
				x = 256,
				y = 256,
				x_vel = 0,
				y_vel = 0,
				jump_vel = -1024,
				speed = 512,
				flySpeed = 700,
				state = "",
				h = 32,
				w = 32,
				standing = false,
				}
	function player:jump()
		if self.standing then
			self.y_vel = self.jump_vel
			self.standing = false
		end
	end
	
	function player:right()
		self.x_vel = self.speed
	end
	
	function player:left()
		self.x_vel = -1 * (self.speed)
	end
	
	function player:stop()
		self.x_vel = 0
	end
	
	function player:collide(event)
		if event == "floor" then
			self.y_vel = 0
			self.standing = true
		end
		if event == "cieling" then
			self.y_vel = 0
		end
	end
	
	function player:update(dt)
		local halfX = self.w / 2
		local halfY = self.h / 2
		
		self.y_vel = self.y_vel + (world.gravity * dt)
		
		self.x_vel = math.clamp(self.x_vel, -self.speed, self.speed)
		self.y_vel = math.clamp(self.y_vel, -self.flySpeed, self.flySpeed)
		
		local nextY = self.y + (self.y_vel*dt)
		if self.y_vel < 0 then
			if not (self:isColliding(map, self.x - halfX, nextY - halfY))
				and not (self:isColliding(map, self.x + halfX - 1, nextY - halfY)) then
				self.y = nextY
				self.standing = false
			else
				self.y = nextY + map.tileHeight - ((nextY - halfY) % map.tileHeight)
				self:collide("cieling")
			end
		end
		if self.y_vel > 0 then
			if not (self:isColliding(map, self.x-halfX, nextY + halfY))
				and not(self:isColliding(map, self.x + halfX - 1, nextY + halfY)) then
					self.y = nextY
					self.standing = false
			else
				self.y = nextY - ((nextY + halfY) % map.tileHeight)
				self:collide("floor")
			end
		end
		
		local nextX = self.x + (self.x_vel * dt)
		if self.x_vel > 0 then
			if not(self:isColliding(map, nextX + halfX, self.y - halfY))
				and not(self:isColliding(map, nextX + halfX, self.y + halfY - 1)) then
				self.x = nextX
			else
				self.x = nextX - ((nextX + halfX) % map.tileWidth)
			end
		elseif self.x_vel < 0 then
			if not(self:isColliding(map, nextX - halfX, self.y - halfY))
				and not(self:isColliding(map, nextX - halfX, self.y + halfY - 1)) then
				self.x = nextX
			else
				self.x = nextX + map.tileWidth - ((nextX - halfX) % map.tileWidth)
			end
		end
		
		self.state = self:getState()
	end
	
	function player:isColliding(map, x, y)
		local layer = map.tl["Solid"]
		local tileX, tileY = math.floor(x / map.tileWidth), math.floor(y / map.tileHeight)
		local tile = layer.tileData(tileX, tileY)
		return not(tile == nil)
	end
	
	function player:getState()
		local tempState = ""
		if self.standing then
			if self.x_vel > 0 then
				tempState = "right"
			elseif self.x_vel < 0 then
				tempState = "left"
			else
				tampState = "stand"
			end
		end
		if self.y_vel > 0 then
			tempState = "fall"
		elseif self.y_vel < 0 then
			tempState = "jump"
		end
		return tempState
	end
end

function love.draw()
	camera:set()
	
	love.graphics.draw( playerImage, player.x, player.y )
	
	--love.graphics.setColor( 0, 0, 0 )
    --love.graphics.rectangle("fill", player.x - player.w/2, player.y - player.h/2, player.w, player.h)
	
    --love.graphics.draw( playerImage, player.x, player.y )

	love.graphics.setColor( 255, 255, 255 )
	map:draw()
	
	camera:unset()
end

function love.update(dt)
	if dt > 0.05 then
		dt = 0.05
	end
	if love.keyboard.isDown("right") then
		player:right()
	end
	if love.keyboard.isDown("left") then
		player:left()
	end
	if love.keyboard.isDown(" ") and not(hasJumped) then
		player:jump()
	end
	
	player:update(dt)
	
	camera:setPosition( player.x - (love.graphics.getWidth()/2), player.y - (love.graphics.getHeight()/2))
end

function love.keyreleased(key)
	if (key == "left") or (key == "right") then
		player.x_vel = 0
	end
end
It seems like the hitbox of the player is poorly positioned, i have no idea why this happens, i tried everything to fix it. You can play normaly but the image is like halfway down the hitbox of the player. What is causing this? Also, sorry if i mispell something. English is not my language. Thanks!

Also, i think the pictures are down. I can't see them. I hope i'm the only one with this issue.
User avatar
micha
Inner party member
Posts: 1083
Joined: Wed Sep 26, 2012 5:13 pm

Re: Player image

Post by micha »

The players coordinates: player.x and player.y store the coordinates of the center of your player. When you use love.graphics.draw for an image, then by default, the parameters are used as the coordinates of the upper left corner (not the center). But you can easily correct this, by also handing over the coordinates of the center of the image (see here):

Code: Select all

love.graphics.draw(image,x,y,angle,sx,sy,ox,oy)
In this case you don't want to scale or rotate the player, so angle = 0 and sx and sy = 1. ox and oy are the coordinates within the image that are used as the origin /or anchor. Set these to half of the width and height of the image. In your case 32/2 = 16:

Code: Select all

love.graphics.draw( playerImage, player.x, player.y, 0, 1, 1, 16, 16)
or, more generally

Code: Select all

love.graphics.draw( playerImage, player.x, player.y, 
    0, 1, 1, 
    0.5*playerImage:getWidth(), 0.5*playerImage:getHeight)
White_Silla
Prole
Posts: 2
Joined: Tue Feb 18, 2014 1:11 am

Re: Player image

Post by White_Silla »

micha wrote:The players coordinates: player.x and player.y store the coordinates of the center of your player. When you use love.graphics.draw for an image, then by default, the parameters are used as the coordinates of the upper left corner (not the center). But you can easily correct this, by also handing over the coordinates of the center of the image (see here):

Code: Select all

love.graphics.draw(image,x,y,angle,sx,sy,ox,oy)
In this case you don't want to scale or rotate the player, so angle = 0 and sx and sy = 1. ox and oy are the coordinates within the image that are used as the origin /or anchor. Set these to half of the width and height of the image. In your case 32/2 = 16:

Code: Select all

love.graphics.draw( playerImage, player.x, player.y, 0, 1, 1, 16, 16)
or, more generally

Code: Select all

love.graphics.draw( playerImage, player.x, player.y, 
    0, 1, 1, 
    0.5*playerImage:getWidth(), 0.5*playerImage:getHeight)
Nice, it worked, thank you for explaining!
Post Reply

Who is online

Users browsing this forum: No registered users and 86 guests