Improved ropes
This commit is contained in:
		
							
								
								
									
										13
									
								
								main.go
									
									
									
									
									
								
							
							
						
						
									
										13
									
								
								main.go
									
									
									
									
									
								
							@ -32,20 +32,21 @@ func start() {
 | 
			
		||||
	w4.PALETTE[1] = 0x012824
 | 
			
		||||
	w4.PALETTE[2] = 0x265935
 | 
			
		||||
	w4.PALETTE[3] = 0xff4d6d
 | 
			
		||||
	player = &Player{
 | 
			
		||||
		Position: Vector{80, 80},
 | 
			
		||||
		Speed:    Vector{},
 | 
			
		||||
		Gamepad:  w4.GAMEPAD1,
 | 
			
		||||
	}
 | 
			
		||||
	for i := 0; i < 4; i++ {
 | 
			
		||||
		p, s := CreateRope(
 | 
			
		||||
			Vector{0, rand.Float64()*40 + float64(i*40)},
 | 
			
		||||
			Vector{160, rand.Float64()*40 + float64(i*40)},
 | 
			
		||||
			15,
 | 
			
		||||
			10,
 | 
			
		||||
		)
 | 
			
		||||
		points = append(points, p...)
 | 
			
		||||
		sticks = append(sticks, s...)
 | 
			
		||||
	}
 | 
			
		||||
	player = &Player{
 | 
			
		||||
		Position:     Vector{80, 80},
 | 
			
		||||
		Speed:        Vector{},
 | 
			
		||||
		Gamepad:      w4.GAMEPAD1,
 | 
			
		||||
		StickGrabbed: sticks[rand.Intn(len(sticks)-1)],
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
//go:export update
 | 
			
		||||
 | 
			
		||||
							
								
								
									
										74
									
								
								player.go
									
									
									
									
									
								
							
							
						
						
									
										74
									
								
								player.go
									
									
									
									
									
								
							@ -1,13 +1,17 @@
 | 
			
		||||
package main
 | 
			
		||||
 | 
			
		||||
import "cart/w4"
 | 
			
		||||
import (
 | 
			
		||||
	"cart/w4"
 | 
			
		||||
	"math"
 | 
			
		||||
)
 | 
			
		||||
 | 
			
		||||
type Player struct {
 | 
			
		||||
	Position Vector
 | 
			
		||||
	Speed    Vector
 | 
			
		||||
	PointGrabbed *Point
 | 
			
		||||
	//PointGrabbed *Point
 | 
			
		||||
	StickGrabbed *Stick
 | 
			
		||||
	StickOffset  float64
 | 
			
		||||
	GrabTimeout  uint
 | 
			
		||||
	Offset       float64
 | 
			
		||||
	Gamepad      *uint8
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
@ -23,32 +27,74 @@ func (p *Player) Update() {
 | 
			
		||||
		p.Speed.X += 1
 | 
			
		||||
	}
 | 
			
		||||
	isJumping := *p.Gamepad&w4.BUTTON_DOWN == 0
 | 
			
		||||
	p.Speed.Y += gravity
 | 
			
		||||
	if p.PointGrabbed != nil {
 | 
			
		||||
	p.Speed.Y = math.Min(4, p.Speed.Y+gravity)
 | 
			
		||||
	if p.StickGrabbed != nil {
 | 
			
		||||
		p.Speed.Y = 0
 | 
			
		||||
		p.Position = p.PointGrabbed.Position
 | 
			
		||||
		//		p.Position = p.PointGrabbed.Position
 | 
			
		||||
		if *p.Gamepad&w4.BUTTON_LEFT != 0 {
 | 
			
		||||
			p.StickOffset -= 0.1
 | 
			
		||||
		}
 | 
			
		||||
		if *p.Gamepad&w4.BUTTON_RIGHT != 0 {
 | 
			
		||||
			p.StickOffset += 0.1
 | 
			
		||||
		}
 | 
			
		||||
		if p.StickOffset < 0 {
 | 
			
		||||
			point := p.StickGrabbed.PointA
 | 
			
		||||
			if len(point.Sticks) == 1 {
 | 
			
		||||
				p.StickOffset = 0
 | 
			
		||||
			} else {
 | 
			
		||||
				p.StickGrabbed = point.Sticks[0]
 | 
			
		||||
				p.StickOffset += 1
 | 
			
		||||
			}
 | 
			
		||||
		}
 | 
			
		||||
		if p.StickOffset > 1 {
 | 
			
		||||
			point := p.StickGrabbed.PointB
 | 
			
		||||
			if len(point.Sticks) == 1 {
 | 
			
		||||
				p.StickOffset = 1
 | 
			
		||||
			} else {
 | 
			
		||||
				p.StickGrabbed = point.Sticks[1]
 | 
			
		||||
				p.StickOffset -= 1
 | 
			
		||||
			}
 | 
			
		||||
		}
 | 
			
		||||
		p.Position = p.StickGrabbed.GetPosition(p.StickOffset)
 | 
			
		||||
		if *p.Gamepad&w4.BUTTON_2 != 0 {
 | 
			
		||||
			p.GrabTimeout = 10
 | 
			
		||||
			if isJumping {
 | 
			
		||||
				p.GrabTimeout = 5
 | 
			
		||||
				p.Speed.Y = -4.5
 | 
			
		||||
				impulse := p.Speed.MulScalar(-1)
 | 
			
		||||
				p.StickGrabbed.PointA.Position.MoveVec(impulse)
 | 
			
		||||
				p.StickGrabbed.PointB.Position.MoveVec(impulse)
 | 
			
		||||
			}
 | 
			
		||||
			p.PointGrabbed = nil
 | 
			
		||||
			p.StickGrabbed = nil
 | 
			
		||||
		}
 | 
			
		||||
	} else {
 | 
			
		||||
		p.Position.Move(p.Speed.X, p.Speed.Y)
 | 
			
		||||
		if *p.Gamepad&w4.BUTTON_DOWN == 0 && p.GrabTimeout == 0 {
 | 
			
		||||
			distance := math.MaxFloat64
 | 
			
		||||
			var selectedPoint *Point
 | 
			
		||||
			for _, point := range points {
 | 
			
		||||
				diff := p.Position.Sub(point.Position)
 | 
			
		||||
				if diff.LenSquared() < 25 {
 | 
			
		||||
					// nearPoints = append(nearPoints, p)
 | 
			
		||||
					*w4.DRAW_COLORS = 0x44
 | 
			
		||||
					w4.Rect(int(point.Position.X), int(point.Position.Y), 3, 3)
 | 
			
		||||
					p.PointGrabbed = point
 | 
			
		||||
					point.PreviousPosition.Move(-p.Speed.X*2, -p.Speed.Y*2)
 | 
			
		||||
					break
 | 
			
		||||
				dSquared := diff.LenSquared()
 | 
			
		||||
				if dSquared < distance {
 | 
			
		||||
					distance = dSquared
 | 
			
		||||
					selectedPoint = point
 | 
			
		||||
				}
 | 
			
		||||
			}
 | 
			
		||||
			stickDistance := math.MaxFloat64
 | 
			
		||||
			var selectedStick *Stick
 | 
			
		||||
			for _, stick := range selectedPoint.Sticks {
 | 
			
		||||
				distance := stick.GetDistance(p.Position)
 | 
			
		||||
				if distance < stickDistance {
 | 
			
		||||
					stickDistance = distance
 | 
			
		||||
					selectedStick = stick
 | 
			
		||||
				}
 | 
			
		||||
			}
 | 
			
		||||
			if stickDistance < 4 {
 | 
			
		||||
				p.StickGrabbed = selectedStick
 | 
			
		||||
				p.StickOffset = selectedStick.GetOffset(p.Position)
 | 
			
		||||
				p.StickGrabbed.PointA.Position.MoveVec(p.Speed)
 | 
			
		||||
				p.StickGrabbed.PointB.Position.MoveVec(p.Speed)
 | 
			
		||||
			}
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
							
								
								
									
										47
									
								
								ropes.go
									
									
									
									
									
								
							
							
						
						
									
										47
									
								
								ropes.go
									
									
									
									
									
								
							@ -3,7 +3,6 @@ package main
 | 
			
		||||
import (
 | 
			
		||||
	"cart/w4"
 | 
			
		||||
	"math"
 | 
			
		||||
	"strconv"
 | 
			
		||||
)
 | 
			
		||||
 | 
			
		||||
type Point struct {
 | 
			
		||||
@ -11,6 +10,16 @@ type Point struct {
 | 
			
		||||
	PreviousPosition Vector
 | 
			
		||||
	IsLocked         bool
 | 
			
		||||
	TimeOffset       uint64
 | 
			
		||||
	Sticks           []*Stick
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func (p *Point) AddStick(stick *Stick) *Point {
 | 
			
		||||
	p.Sticks = append(p.Sticks, stick)
 | 
			
		||||
	return p
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func (p *Point) GetMotion() Vector {
 | 
			
		||||
	return p.Position.Sub(p.PreviousPosition)
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func (p *Point) Draw() {
 | 
			
		||||
@ -31,6 +40,39 @@ type Stick struct {
 | 
			
		||||
	Length float64
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func (s *Stick) GetVector() Vector {
 | 
			
		||||
	return s.PointB.Position.Sub(s.PointA.Position)
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func (s *Stick) GetDistance(point Vector) float64 {
 | 
			
		||||
	ab := s.GetVector()
 | 
			
		||||
	ap := point.Sub(s.PointA.Position)
 | 
			
		||||
	bp := point.Sub(s.PointB.Position)
 | 
			
		||||
 | 
			
		||||
	abbp := (ab.X*bp.X + ab.Y*bp.Y)
 | 
			
		||||
	abap := (ab.X*ap.X + ab.Y*ap.Y)
 | 
			
		||||
 | 
			
		||||
	if abbp > 0 {
 | 
			
		||||
		return bp.Len()
 | 
			
		||||
	} else if abap < 0 {
 | 
			
		||||
		return ap.Len()
 | 
			
		||||
	}
 | 
			
		||||
	mod := ab.Len()
 | 
			
		||||
	return math.Abs(ab.X*ap.Y-ab.Y*ab.X) / mod
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func (s *Stick) GetPosition(offset float64) Vector {
 | 
			
		||||
	diff := s.GetVector()
 | 
			
		||||
	return s.PointA.Position.Sum(diff.MulScalar(offset))
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func (s *Stick) GetOffset(p Vector) float64 {
 | 
			
		||||
	ab := s.GetVector()
 | 
			
		||||
	ap := p.Sub(s.PointA.Position)
 | 
			
		||||
	projection := ap.ProjectTo(ab)
 | 
			
		||||
	return projection.Len() / ab.Len()
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func (s *Stick) Draw() {
 | 
			
		||||
	*w4.DRAW_COLORS = 0x3
 | 
			
		||||
	w4.Line(int(s.PointA.Position.X), int(s.PointA.Position.Y),
 | 
			
		||||
@ -90,12 +132,13 @@ func CreateRope(start Vector, end Vector, divisions int) ([]*Point, []*Stick) {
 | 
			
		||||
			diffX := pos.X - lastPoint.Position.X
 | 
			
		||||
			diffY := pos.Y - lastPoint.Position.Y
 | 
			
		||||
			len := math.Sqrt(diffX*diffX + diffY*diffY)
 | 
			
		||||
			w4.Trace("Length between points is " + strconv.FormatFloat(len, 'f', 3, 64))
 | 
			
		||||
			stick := Stick{
 | 
			
		||||
				PointA: lastPoint,
 | 
			
		||||
				PointB: &point,
 | 
			
		||||
				Length: len,
 | 
			
		||||
			}
 | 
			
		||||
			stick.PointA.AddStick(&stick)
 | 
			
		||||
			stick.PointB.AddStick(&stick)
 | 
			
		||||
			sticks = append(sticks, &stick)
 | 
			
		||||
		}
 | 
			
		||||
		points = append(points, &point)
 | 
			
		||||
 | 
			
		||||
							
								
								
									
										21
									
								
								vectors.go
									
									
									
									
									
								
							
							
						
						
									
										21
									
								
								vectors.go
									
									
									
									
									
								
							@ -10,6 +10,13 @@ type Vector struct {
 | 
			
		||||
	Y float64
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func Vec(x float64, y float64) Vector {
 | 
			
		||||
	return Vector{
 | 
			
		||||
		x,
 | 
			
		||||
		y,
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func (v *Vector) String() string {
 | 
			
		||||
	return "(" + strconv.FormatFloat(v.X, 'f', 3, 64) + "; " + strconv.FormatFloat(v.Y, 'f', 3, 64) + ")"
 | 
			
		||||
}
 | 
			
		||||
@ -57,7 +64,21 @@ func (v *Vector) Normalized() Vector {
 | 
			
		||||
	return Vector{x, y}
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func (v *Vector) Dot(v2 Vector) float64 {
 | 
			
		||||
	return v.X*v2.X + v.Y*v2.Y
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func (v *Vector) ProjectTo(v2 Vector) Vector {
 | 
			
		||||
	abdot := v.Dot(v2)
 | 
			
		||||
	bbdot := v2.Dot(v2)
 | 
			
		||||
	return v2.MulScalar(abdot / bbdot)
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func (v *Vector) Move(x float64, y float64) {
 | 
			
		||||
	v.X += x
 | 
			
		||||
	v.Y += y
 | 
			
		||||
}
 | 
			
		||||
func (v *Vector) MoveVec(v2 Vector) {
 | 
			
		||||
	v.X += v2.X
 | 
			
		||||
	v.Y += v2.Y
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
		Reference in New Issue
	
	Block a user