![Devil >:]](./images/smilies/devilish.png)
Voilà, j'était en train de faire un Mr.flap en lua. J'était là, peinard, sans rien demander à personne, quad tout à coup: ATTAQUE DE BUG NINJA!
Mon programme actuel consiste en un repère polaire avec plusieurs objets: des balles (j'ai pas mis d'oiseaux, pasque voilà), des murs, et un sol.
Mais, mon (seul) problème est toujours le même: les collisions (ça me pose problème dans toutes les dimensions et représentations).
Je ne sais pas du tout où ça va pas (mais je pense que c'est dans la fonction qui calcule les collisions), mais les balles se heurtent à des murs invisibles qui n'existent pas, et du coup cela réduit grandement la chance de n'en toucher aucun).
J'ai même tenté de redessiner le jeu en repère euclidien, mais je ne trouve toujours pas ce qui bug.
- Code: Select all
-- x = d*cos(a)
-- y = d*sin(a)
-- a = atan (x/y)
-- d = x/cos(a)
function on.resize (ww, hh)
w, h = ww, hh
t = 1
pi = math.pi
cx, cy = w/2, h/2
floor = 32
friction = 0.7
rfriction = math.sqrt (friction)
obj = {}
for a = 1, 1 do
obj[a] = ball (
math.random (0, math.pi*2)
, math.random (floor, floor+64)
, math.random (-pi, pi)/16
, math.random (-4, 4)
, 4
)
end
for a = 1, 1 do
table.insert (obj,
wall (math.random (0, 2*math.pi)
, floor
, math.random (16, 128)))
end
timer.start (0.04)
end
ball = class ()
function ball: init (a, d, ma, md, r)
self.t = "ball"
self.a = a
self.d = d
self.ma = ma
self.md = md
self.r = r
end
function ball: move ()
local old = {a=self.a-self.r, d=self.d-self.r}
self.md = self.md-1
self.a = self.a+self.ma
self.d = self.d+self.md
if self.a >=2*pi then self.a = 0 end
if self.a < 0 then self.a = self.a+2*pi end
for _, b in pairs (obj) do
if b.t == "wall" then
local i = inter (b, old, self)
if i then
self.ma = -self.ma
end
end
end
if self.d-self.r < floor then
self.d = floor+self.r
self.md = math.abs (self.md)
end
end
function inter (wl, p1, p2)
local l1 = { a = { x = wl.d*math.cos (wl.a)
, y = wl.d*math.sin (wl.a)}
, b = { x = (wl.d+wl.h)*math.cos (wl.a)
, y = (wl.d+wl.h)*math.sin (wl.a)}
}
local l2 = { a = { x = p1.d*math.cos (p1.a)
, y = p1.d*math.sin (p1.a)}
, b = { x = p2.d*math.cos (p2.a)
, y = p2.d*math.sin (p2.a)}
}
local rect = {}
rect.xmin = math.max (math.min (l1.a.x, l1.b.x), math.min (l2.a.x, l2.b.x))
rect.xmax = math.min (math.max (l1.a.x, l1.b.x), math.max (l2.a.x, l2.b.x))
rect.ymin = math.max (math.min (l1.a.y, l1.b.y), math.min (l2.a.y, l2.b.y))
rect.ymax = math.min (math.max (l1.a.y, l1.b.y), math.max (l2.a.y, l2.b.y))
a1 = (l1.a.y-l1.b.y)/(l1.a.x-l1.b.x)
b1 = l1.a.y-a1*l1.a.x
a2 = (l2.a.y-l2.b.y)/(l2.a.x-l2.b.x)
b2 = l2.a.y-a2*l2.a.x
x = (b2-b1)/(a1-a2)
y = a1*x+b1
if x > rect.xmin
and x < rect.xmax
and y > rect.ymin
and y < rect.ymax then
return {a=wl.a, d=p1.d}
else
return false
end
end
function ball: paint (gc)
local x = self.d*math.cos (self.a)
local y = self.d*math.sin (self.a)
gc: fillArc ((x-self.r)/t+cx, (y-self.r)/t+cy, self.r/t*2, self.r/t*2, 0, 360)
end
wall = class ()
function wall: init (a, d, h)
self.t = "wall"
self.a = a
self.d = d
self.h = h
end
function wall: move ()
self.a = self.a+pi/90
if self.a >= 2*pi then self.a = 0 end
end
function wall: paint (gc)
gc: drawLine ( self.d*math.cos (self.a)/t+w/2
, self.d*math.sin (self.a)/t+h/2
, (self.d+self.h)*math.cos (self.a)/t+w/2
, (self.d+self.h)*math.sin (self.a)/t+h/2
)
end
function on.timer ()
platform.window: invalidate ()
end
function on.paint (gc)
for a, b in pairs (obj) do
b: move ()
b: paint (gc)
end
gc: drawString (obj[1].a, 4, 16)
gc: drawString (obj[1].d, 4, 32)
gc: drawString (obj[1].a-obj[2].a, 4, 48)
gc: setColorRGB (150, 150, 150)
gc: fillArc (cx-floor/t, cy-floor/t, floor/t*2, floor/t*2, 0, 360)
paint2 (gc)
end
function paint2 (gc)
gc: fillRect (0, h-floor, 180, floor)
gc: fillRect (obj[2].a/(2*pi)*180, h-obj[2].d-floor, 1, obj[2].h)
gc: setColorRGB (0)
gc: fillArc ( obj[1].a/(2*pi)*180-obj[1].r
, h-obj[1].d-obj[1].r
, obj[1].r*2, obj[1].r*2, 0, 360)
end
function on.enterKey ()
for a, b in pairs (obj) do
if b.t == "ball" then
b.md = 4
b.d = b.d+8
end
end
end