Note that this code is in the process of debugging, so some parts may be embarrasingly redundant (I'm only a beginner after all):
import java.awt.*;
import java.awt.geom.*;
import java.util.*;
public class Luge extends java.applet.Applet implements Runnable
{
double x = 100;
double y = 75;
double speed = 100;
double angle = 0;
double turnangle = 0;
int tatb = 0;
double nextangle = 0;
boolean readytorun = false;
Random r = new Random();
Thread runner;
Image track;
Image l1;
Image l2;
Image r1;
Image r2;
Image s1;
Image s2;
Image cart;
Image warptrack;
Image track2;
Image mybuffer;
Graphics t2;
Graphics g;
public void init()
{
track = getImage(getCodeBase(),"track.gif"

;
l1 = getImage(getCodeBase(),"l1.gif"

;
l2 = getImage(getCodeBase(),"l2.gif"

;
r1 = getImage(getCodeBase(),"r1.gif"

;
r2 = getImage(getCodeBase(),"r2.gif"

;
s1 = getImage(getCodeBase(),"s1.gif"

;
s2 = getImage(getCodeBase(),"s2.gif"

;
cart = getImage(getCodeBase(),"cart.gif"

;
track2 = createImage(200,400);
warptrack = createImage(200,400);
mybuffer = createImage(400,400);
requestFocus();
while ((!imageloaded(track))||(!imageloaded(l1))||(!imageloaded(l2))||(!imageloaded(r1))||(!imageloaded(r2))||(!imageloaded(s1))||(!imageloaded(s2))||(!imageloaded(cart))||(!imageloaded(track2))||(!imageloaded(mybuffer))||(!imageloaded(warptrack)))
{}
t2 = track2.getGraphics();
g = mybuffer.getGraphics();
readytorun=true;
}
private boolean imageloaded(Image i)
{
if((i.getHeight(this)==-1)||(i.getWidth(this)==-1))
return false;
else
return true;
}
public void start()
{
if (runner == null)
{
runner = new Thread(this);
runner.start();
}
}
public void stop()
{
runner = null;
}
public void pause(int time)
{
try {Thread.sleep(time);} catch (InterruptedException e) {System.out.println("Interruption!"

;}
}
public void run()
{
Thread thisThread = Thread.currentThread();
while (runner == thisThread)
{
double rr = r.nextDouble();
if (rr > .999)
tatb=35;
if ((rr > .4995)&&(rr < .5005))
tatb=0;
if (rr < .001)
tatb=-35;
if (turnangle > tatb)
turnangle -= .1;
if (turnangle < tatb)
turnangle += .1;
if (nextangle != angle)
angle += (((nextangle-angle)/Math.abs(nextangle-angle))*.1)/(.5+Math.tan(Math.toRadians(angle)));
speed += 10;
if (x<20)
{
speed /= 1.1;
x=20;
}
if (x>155)
{
speed /= 1.1;
x = 155;
}
double sp = speed;
speed = sp-(Math.abs(sp*Math.sin(Math.toRadians((angle-turnangle)))))/50;
x+=((sp*Math.sin(Math.toRadians((angle-turnangle))))*Math.cos(Math.toRadians((angle-turnangle))))/100;
y += speed/100;
//pause(50);
//angle += .1;
repaint();
pause(50);
}
}
// My input methods
public boolean keyDown(Event evt, int key)
{
System.out.println("Keydown"

;
if (key == Event.LEFT)
{
angle -= 3/(.5+Math.tan(Math.toRadians(angle)));
}
if (key == Event.RIGHT)
{
angle += 3/(.5+Math.tan(Math.toRadians(angle)));
}
nextangle=angle;
repaint();
return true;
}
public boolean mouseDrag(Event evt,int xx,int yy)
{
System.out.println("Mousedrag"

;
if ((yy<250)||(xx<200))
nextangle = -Math.atan((xx-x)/(yy-250))*(180/Math.PI);
return true;
}
public boolean mouseDown(Event evt,int xx,int yy)
{
System.out.println("Mousedown"

;
if ((yy<250)||(xx<200))
nextangle = -Math.atan((xx-x)/(yy-250))*(180/Math.PI);
System.out.println(nextangle);
System.out.println(xx);
System.out.println(x);
System.out.println(yy);
System.out.println(180/Math.PI);
return true;
}
public void paint(Graphics gg)
{
if (readytorun)
{
t2 = track2.getGraphics();
g = mybuffer.getGraphics();
g.setColor(Color.white);
g.fillRect(0,0,400,400);
t2.drawImage(track,0,(int)((int)

%400),this);
t2.drawImage(track,0,(int)(((int)

%400)-400),this);
// All this junk is the image-warping thing
g.drawImage(track2,
0, 0, (int)(((int)(100+turnangle*2))/2), (int)(200/2),
0, 0, (int)((200/2)*.25), (int)((400/2)*.25),
this);
g.drawImage(track2,
(int)(((int)(100+turnangle*2))/2), 0, ((int)(100+turnangle*2)), (int)(200/2),
(int)((200/2)*.25), 0, (int)(200/2), (int)((400/2)*.25),
this);
g.drawImage(track2,
0, (int)(200/2), (int)(((int)(100+turnangle*2))/2), 200,
0, (int)((400/2)*.25), (int)((200/2)*.25), (int)(400/2),
this);
g.drawImage(track2,
(int)(((int)(100+turnangle*2))/2), (int)(200/2), ((int)(100+turnangle*2)), 200,
(int)((200/2)*.25), (int)((400/2)*.25), (int)(200/2), (int)(400/2),
this);
//quarter #2
g.drawImage(track2,
((int)(100+turnangle*2)), 0, (int)((((int)(100+turnangle*2))+200)/2), (int)(200/2),
(int)(200/2), 0, (int)(200-.25*(200/2)), (int)((400/2)*.25),
this);
g.drawImage(track2,
((int)(100+turnangle*2)), (int)(200/2), (int)((((int)(100+turnangle*2))+200)/2), 200,
(int)(200/2), (int)((400/2)*.25), (int)(200-(200/2)*.25), (int)(400/2),
this);
g.drawImage(track2,
(int)((200+((int)(100+turnangle*2)))/2), 0, 200, (int)(200/2),
(int)(200-(200/2)*.25), 0, 200, (int)((400/2)*.25),
this);
g.drawImage(track2,
(int)((200+((int)(100+turnangle*2)))/2), (int)(200/2), 200, 200,
(int)(200-.25*(200/2)), (int)((400/2)*.25), 200, (int)(400/2),
this);
//quarter #3
g.drawImage(track2,
0, 200, (int)((int)(100+turnangle*2))/2, (int)((400+200)/2),
0, (int)(400/2), (int)((200/2)*.25), (int)(400-(400/2)*.25),
this);
g.drawImage(track2,
(int)(((int)(100+turnangle*2))/2), 200, ((int)(100+turnangle*2)), (int)((400+200)/2),
(int)((200/2)*.25), (int)(400/2), (int)(200/2), (int)(400-(400/2)*.25),
this);
g.drawImage(track2,
0, (int)((400+200)/2), (int)((int)(100+turnangle*2))/2, 400,
0, (int)(400-(400/2)*.25), (int)((200/2)*.25), 400,
this);
g.drawImage(track2,
(int)(((int)(100+turnangle*2))/2), (int)((400+200)/2), ((int)(100+turnangle*2)), 400,
(int)((200/2)*.25), (int)(400-(400/2)*.25), (int)(200/2), 400,
this);
//quarter #4
g.drawImage(track2,
((int)(100+turnangle*2)), 200, (int)((200+((int)(100+turnangle*2)))/2), (int)((400+200)/2),
(int)(200/2), (int)(400/2), (int)(200-(200/2)*.25), (int)(400-(400/2)*.25),
this);
g.drawImage(track2,
(int)((200+((int)(100+turnangle*2)))/2), 200, 200, (int)((400+200)/2),
(int)(200-(200/2)*.25), (int)(400/2), 200, (int)(400-(400/2)*.25),
this);
g.drawImage(track2,
((int)(100+turnangle*2)), (int)((400+200)/2), (int)((200+((int)(100+turnangle*2)))/2), 400,
(int)(200/2), (int)(400-(400/2)*.25), (int)(200-(200/2)*.25), 400,
this);
g.drawImage(track2,
(int)((200+((int)(100+turnangle*2)))/2), (int)((400+200)/2), 200, 400,
(int)(200-(200/2)*.25), (int)(400-(400/2)*.25), 200, 400,
this);
//WarpImage(track2,(int)(100+turnangle*2),200,.75,false);
//g.drawImage(warptrack,0,0,this);
if (turnangle <= -35)
g.drawImage(l2,85,5,this);
if (turnangle == 0)
g.drawImage(s2,85,5,this);
if (turnangle >= 35)
g.drawImage(r2,85,5,this);
if ((turnangle>-35)&&(turnangle<=-5))
g.drawImage(l1,85,5,this);
if ((turnangle>-5)&&(turnangle<5))
g.drawImage(s1,85,5,this);
if ((turnangle>=5)&&(turnangle<35))
g.drawImage(r1,85,5,this);
g.setColor(Color.black);
g.drawString("Speed: "+(double)((double)Math.round(speed)/100)+" m/s",210,30);
//System.out.println("Speed: "+((int)speed)/100+" m/s"

;
g.drawString("Distance: "+(int)(y/50)+" m",210,45);
//System.out.println("Distance: "+(int)(y/50)+" m"

;
Graphics2D g2 = (Graphics2D)g;
g2.translate(x,250.0);
g2.rotate(Math.toRadians(angle));
g2.translate(-25.0,-50.0);
g2.drawImage(cart,0,0,this);
gg.drawImage(mybuffer,0,0,this);
}
}
public void update(Graphics g)
{
paint(g);
}
} ***
Dammit Jim, I'm a programmer, not a doctor.