Log In  
Log In  

I'm making a game using the dev kit mouse and want a line to go from the character to the mouse location

But I can't figure out what place that the line needs to end in order for the line to end before it gets to the player

http://imgur.com/a/vscVn
on the top is what I have, and on the bottom is what I want

How do I find/get the variable to stop the line short of the player?

Sorry for all the questions I've been asking recently

P#43303 2017-08-16 20:44 ( Edited 2017-08-17 17:01)

two ways I can think of off the top of my head:

  1. use vectors (you'd have to add a whole 2D vector class/library to your code, but this can be super useful for lots of gamedev things so you might consider it). this way you can do something like the following (assuming you have player position and mouse position stored as 2D vectors):
local dir = player.position - mouse.position
dir:setmagnitude(15)

local dest = mouse.position + dir
line(mouse.x, mouse.y, dest.x, dest.y)
  1. draw a line manually, pixel by pixel. the bresenham line algorithm is popular and easily googleable. then you can just stop drawing pixels early when you hit a certain length. this is perhaps simpler than the vector approach because it doesn't require adding a whole library to your game, just one function. or I guess you could also do that for the vector math stuff...distill it down to just one function that you need
P#43305 2017-08-16 20:55 ( Edited 2017-08-17 01:01)

Since the background is all blue you could:

  1. Draw the line between the player and the mouse location.
  2. Draw a blue circle at the player position with the radius you want.
  3. Draw the player character on top of the circle.

However, if you're going to use tiles for the background later then this solution won't work.

P#43306 2017-08-16 21:24 ( Edited 2017-08-17 01:24)
:: enargy

Hey pixel.. these suggestions would work but here are some simpler ideas.

Is the line always going to be in the top right corner of the character sprite? If so..

line(mouse, mousey, player.x+7,player.y-1,7)

If your character isn't 8 pixels wide then just adjust the number you add to player.x.

Or if you want something even easier, just draw the line, THEN draw your sprite on top of it. That way you'll just draw over the parts of the line that overlap with your sprite.

Hope that helps..

EDIT: Oops, I thought you had the last image and wanted it to work like the first.

P#43307 2017-08-17 00:48 ( Edited 2017-08-17 19:28)
:: Felice

I'm not going to write code for you, but I'll tell you the sequence to use. Learning any necessary math is left as an exercise, but on the bright side, nothing here is very difficult and plenty of resources to learn the math are available.

  • Pick a minimum distance. If you're using an 8x8 player sprite and the player location is in the center of the sprite, then the longest distance that's still inside the sprite is from the center to a corner. The length of a line to the corner is √2 (or about 1.41) longer than a line to the edge. In an 8x8 sprite the line from center to edge is 4 pixels long, so if you pick at least 6 (1.5x) you should be outside of the player, even diagonally. Or be generous and pick 8 or 10 to leave a definite gap.

  • Use the pythagorean theorem to get the linear distance between the mouse cursor and the player center.

  • Now you know the length of the entire line (we'll call it L), and the length you want to chop off at the player end (we'll call it P). You can slide a point from the player location to the mouse cursor using linear interpolation, or lerp for short. Lerping uses a fraction to say where the point is between the two, e.g. 0.1 is close to the player and 0.9 is close to the camera. You'll want to use a fraction that represents your desired distance relative to the current distance, so interpolate from the player towards the mouse by the fractional value P/L. For instance, if you picked a minimum distance of 10 and the mouse is 50 pixels away from the player this frame, interpolate with 10/50 or 0.2 for this frame.

  • Draw a line between the mouse position and your interpolated position. You might want to make sure the overall length L is greater than P to begin with so your math doesn't go funny, trying to draw in the wrong direction. If it is, maybe just don't draw the line.

  • Done.
P#43310 2017-08-17 01:57 ( Edited 2017-08-17 05:57)

@enargy

What would "player" be?

P#43324 2017-08-17 11:32 ( Edited 2017-08-17 15:32)
:: jeb

As mentioned you can use a vector, or (similarily) you can use the angle towards the player:

local angle=atan2(player.x-mouse.x,player.y-mouse.y)
line(mouse.x,mouse.y,mouse.x+cos(angle)*8,mouse.y+sin(angle)*8,7)

"*8" is the length of the line. Limiting the length so it doesn't cross the player requires a distance check.

P#43329 2017-08-17 11:57 ( Edited 2017-08-17 15:57)
:: Felice

Actually, that post I made is TL;DR material and thus useless for learning.

Here's a complete demo, with comments to learn from, instead:

--mouse enable
poke(0x5f2d,1)

--initial player pos
px,py=64,64

--inner circle size
mindist=10

function _update60()
  --sample mouse pos
  mx,my=stat(32),stat(33)
end

function _draw()
  cls()

  --============================
  -- begin code you care about
  --============================

  --vector from player to mouse
  local dx,dy=mx-px,my-py

  --get length of vector via
  --pythagorean theorem
  local dist=sqrt(dx*dx+dy*dy)

  --only draw a line if mouse
  --is outside inner circle
  if dist>mindist then

    --how much of the line our
    --inner circle chops off
    local frac=mindist/dist

    --new point on inner circle
    local ix,iy=px+dx*frac,py+dy*frac

    --render line from inner 
    --circle to mouse
    line(ix,iy,mx,my,12)
  end

  --============================
  -- end code you care about
  --============================

  --draw player sprite,
  --centered across px,py
  spr(0,px-4,py-4)

  --draw a mouse cursor
  line(mx,my,mx+4,my+4,7)
  line(mx,my,mx,my+6)
  line(mx+3,my+4,mx,my+5)
end

Note:

this is the way I'd want to do it on a real platform, because aside from the sqrt(), this is simple math that runs very quickly on a real processor. Using other code, such as the bit suggested using atan2()/cos()/sin(), may actually be more appropriate in some cases on pico-8, because trigonometric functions run quite quickly on pico-8, but slowly on a real platform.

I prefer to suggest methods that are universal, but sometimes on pico-8 you're better off taking advantage of its special characteristics, which is also a valuable skill for a game dev to have.

P#43333 2017-08-17 13:01 ( Edited 2017-08-17 17:08)

[Please log in to post a comment]

X
About | Contact | Updates | Terms of Use
Follow Lexaloffle:        
Generated 2018-12-12 13:52 | 0.029s | 2097k | Q:24