-
Notifications
You must be signed in to change notification settings - Fork 0
/
Vehicle.py
177 lines (142 loc) · 5.15 KB
/
Vehicle.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
# The Nature of Code
# Daniel Shiffman
# http://natureofcode.com
# The "Vehicle" class
from Food import Food
import time
import math
MAX_SPEED = 2
TILE_SIZE = 20
class Vehicle():
def __init__(self, x, y, vel):
self.acceleration = PVector(0, 0)
self.velocity = vel
self.position = PVector(x, y)
self.r = 6
self.maxspeed = MAX_SPEED
self.maxforce = 0.2
self.food_location = PVector(-1,-1)
self.score = 0
self.path = []
self.speed = 0.5
self.angle = PI/2
def set_path(self, path):
self.path = path
def getPosition(self):
return self.position
def eat(self):
self.score = self.score + 1
def change_speed(self, type):
if type == -1:
self.speed = 0.0
elif type == 0:
self.speed = 0.25
elif type == 1:
self.speed = 0.45
elif type == 2:
self.speed = 0.8
def checkCollision(self, food):
foodPosition = food.getPosition()
foodWidth = food.r
cl = foodPosition.x - foodWidth/2; # left corner
cr = foodPosition.x + foodWidth/2; # right corner
if (abs(cl - self.position.x) < self.r or abs(cr - self.position.x) < self.r):
ct = foodPosition.y - foodWidth/2; # Top corner
cb = foodPosition.y + foodWidth/2; # Bottom corner
if (abs(ct - self.position.y) < self.r or abs(cb - self.position.y) < self.r):
return True
return False
def locate_food(self, food):
for y in range(0,height):
for x in range(0,width):
p = str(hex(get(x,y)))
if p == 'FFFF0000':
self.food_location = PVector(x + food.r/2,y + food.r/2)
print('found food on' + str(self.food_location))
return
def set_angle(self, p):
positionX = int(math.floor(self.position.x / TILE_SIZE))
positionY = int(math.floor(self.position.y / TILE_SIZE))
ang = (positionX - p[0], positionY - p[1])
print(ang)
if ang == (1,0):
self.angle = -PI/2
elif ang == (0,1):
self.angle = 0.0
elif ang == (-1,0):
self.angle = PI/2
elif ang == (0,-1):
self.angle = PI
# A method that calculates a steering force towards a target
# STEER = DESIRED MINUS VELOCITY
def arrive(self, location):
target = location
# A vector pointing from the location to the target
desired = target - self.position
d = desired.mag()
# Scale with arbitrary damping within 100 pixels
if (d < 100):
m = map(d, 0, 100, 0, self.maxspeed)
desired.setMag(m)
else:
desired.setMag(self.maxspeed)
# Steering = Desired minus velocity
steer = desired - self.velocity
steer.limit(self.maxforce) # Limit to maximum steering force
self.applyForce(steer)
# A method that calculates a steering force towards a target
# STEER = DESIRED MINUS VELOCITY
def seek(self, target):
# A vector pointing from the location to the target
desired = target - self.position
# Scale to maximum speed
desired.setMag(self.maxspeed)
steer = desired - self.velocity
steer.limit(self.maxforce) # Limit to maximum steering force
self.applyForce(steer)
# Method to update location
def update(self):
# Update velocity
self.velocity.add(self.acceleration)
# Limit speed
self.velocity.limit(self.maxspeed)
self.position.add(self.velocity)
# Reset accelerationelertion to 0 each cycle
self.acceleration.mult(0)
def applyForce(self, force):
# We could add mass here if we want A = F / M
self.acceleration.add(force)
def display(self):
# Draw a triangle rotated in the direction of velocity
fill(0)
theta = self.angle
# print(theta)
fill(127)
noStroke()
strokeWeight(1)
with pushMatrix():
translate(self.position.x, self.position.y)
rotate(theta)
beginShape()
vertex(0, -self.r * 2)
vertex(-self.r, self.r * 2)
vertex(self.r, self.r * 2)
endShape(CLOSE)
def draw_path(self):
"""Receives path based on the grid matrix
-> draws the path
"""
stroke(0)
for i in range(0,len(self.path)-1):
p1 = self.path[i] * TILE_SIZE
p2 = self.path[i+1] * TILE_SIZE
line((p1[0] * TILE_SIZE) + TILE_SIZE/2,
(p1[1] * TILE_SIZE) + TILE_SIZE/2,
(p2[0] * TILE_SIZE) + TILE_SIZE/2,
(p2[1] * TILE_SIZE) + TILE_SIZE/2)
def drive(self):
p = self.path.pop(0)
self.set_angle(p)
target = PVector((p[0] * TILE_SIZE) + TILE_SIZE/2, (p[1] * TILE_SIZE) + TILE_SIZE/2)
print(target)
self.position = target