Nennt mich Chuck!

Wir alle wissen, dass nur Chuck Norris Java im Browser starten kann… ohne Java Plugin. Also dann, nennt mich Chuck!

Habt Ihr das Easter Egg auf http://jayday.de schon gefunden? Wenn ja, vielleicht interessiert Euch der Source Code:


import java.util.ArrayList;
import org.apidesign.bck2brwsr.htmlpage.api.*;
import static org.apidesign.bck2brwsr.htmlpage.api.OnEvent.*;
import org.apidesign.bck2brwsr.htmlpage.api.Page;
import org.apidesign.bck2brwsr.htmlpage.api.Property;
@Page(xhtml = "index.html", className = "Index", properties = {
@Property(name = "name", type = String.class)
})
public class App {

static int score = 0;
static boolean gameover = false;
static final int INVISIBLE = -1000;
static final Sprite duke;
static final Sprite bullet;
static final ArrayList sprites;
static final ArrayList enemySprites;
static int dx = 0;
static int velocity = 2;
static String background = "#000000";
static int width = 1000;
static int height = 288;
static final int[][] enemies = new int[][]{
{30, 30, 30, 30, 30, 30, 30, 30, 30, 30},
{20, 20, 20, 20, 20, 20, 20, 20, 20, 20},
{20, 20, 20, 20, 20, 20, 20, 20, 20, 20},
{10, 10, 10, 10, 10, 10, 10, 10, 10, 10}
};
private static Timer t;
private static int level = 2;

static {
Index model = new Index();

duke = new ImageSprite(350, height - 38, 32, 32, model.DUKE, new int[]{0});
bullet = new Sprite(INVISIBLE, INVISIBLE, 6, 10) {
@Override
public void render(GraphicsContext g, float alpha, long pulse) {
g.setFillStyle("#ff0000");
g.fillRect(x, y, width, height);
}
};
sprites = new ArrayList<>();
sprites.add(duke);
sprites.add(bullet);
enemySprites = new ArrayList<>();
for (int i = 0; i < enemies.length; i++) {
int[] is = enemies[i];
for (int j = 0; j < is.length; j++) {
Enemy sprite = null;
if (is[j] == 30) {
sprite = new Enemy(30, 40 + (40 * j), 40 + (40 * i), 32, 32, model.ANDROID, new int[]{0, 1});
} else if (is[j] == 20) {
sprite = new Enemy(20, 40 + (40 * j), 40 + (40 * i), 32, 32, model.ANDROID, new int[]{2, 3});
} else {
sprite = new Enemy(10, 40 + (40 * j), 40 + (40 * i), 32, 32, model.ANDROID, new int[]{4, 5});
}
enemySprites.add(sprite);
}
}
model.setName("World");
}

@On(event = CLICK, id = "canvas")
static void start(final Index index) {
if (gameover) {
index.CANVAS.getContext().drawImage(index.BACK, 0, 0);
} else if (t == null) {
t = Timer.create(new GameLoop(index), 30);
}
}

@On(event = CLICK, id = "left")
static void left(final Index m, String bla, String bli) {
if (gameover) {
return;
}
checkInit(m);
dx = -4;
}

@On(event = CLICK, id = "right")
static void right(final Index m, String bla, String bli) {
if (gameover) {
return;
}
checkInit(m);
dx = 4;
}

@On(event = DBL_CLICK, id = "right")
static void rightUp(final Index m, String bla, String bli) {

checkInit(m);
dx = 0;
}

@On(event = CLICK, id = "fire")
static void fire(final Index m, String bla, String bli) {
if (gameover) {
return;
}

checkInit(m);
int x = duke.getX();
if (bullet.getX() != INVISIBLE) {
return;
}
bullet.x = x + (duke.width / 2);
bullet.y = duke.getY();
}

public static void checkInit(final Index m) {
if (t == null) {
}
}

public static void levelup(Index model) {
level++;
velocity = level;
for (int i = 0; i < enemies.length; i++) {
int[] is = enemies[i];
for (int j = 0; j < is.length; j++) { Enemy sprite = null; if (is[j] == 30) { sprite = new Enemy(30, 40 + (40 * j), 40 + (40 * i), 32, 32, model.ANDROID, new int[]{0, 1}); } else if (is[j] == 20) { sprite = new Enemy(20, 40 + (40 * j), 40 + (40 * i), 32, 32, model.ANDROID, new int[]{2, 3}); } else { sprite = new Enemy(10, 40 + (40 * j), 40 + (40 * i), 32, 32, model.ANDROID, new int[]{4, 5}); } enemySprites.add(sprite); } } } private static abstract class Sprite { int height; int width; int x; int y; public Sprite(int x, int y, int width, int height) { this.height = height; this.width = width; this.x = x; this.y = y; } public int getX() { return x; } public int getY() { return y; } public abstract void render(GraphicsContext g, float alpha, long pulse); } private static class Enemy extends App.ImageSprite { int points; public Enemy(int points, int x, int y, int width, int height, Image image, int... indices) { super(x, y, width, height, image, indices); this.points = points; } } private static class ImageSprite extends Sprite { int idx = 0; Image image; int[] indices; public ImageSprite(int x, int y, int width, int height, Image image, int... indices) { super(x, y, width, height); this.image = image; this.indices = indices; } public void render(GraphicsContext g, float alpha, long pulse) { if (animate) { idx++; } if (idx >= indices.length) {
idx = 0;
}
g.drawImage(image, indices[idx] * width, 0, width, height, x, y, width, height);

}
}
static long lastAnimationFrame;
static boolean animate = false;

private static class GameLoop implements Runnable {

public static final int ANIMATIONSPEED = 500;
private final Index m;

public GameLoop(Index m) {
this.m = m;
}

@Override
public void run() {
long currentTimeMillis = System.currentTimeMillis();
long timeElapsed = currentTimeMillis - lastAnimationFrame;
if (timeElapsed > ANIMATIONSPEED) {
lastAnimationFrame = currentTimeMillis;
animate = true;
}
GraphicsContext context = m.CANVAS.getContext();
context.setFillStyle(background);
context.fillRect(0, 0, width, height);

if (!(duke.x + dx >= (width - duke.width) || duke.x + dx duke.x += dx;
}
if (bullet.getY() != INVISIBLE) {
bullet.y -= 12;
if (bullet.getY()  width - sprite.width - 20 || sprite.x < 20) { velocity = -velocity; if (velocity > 0 && velocity < 4) { velocity += 1; } invert = true; break; } } for (Sprite sprite : enemySprites) { sprite.x += velocity; if (invert) { sprite.y += 20; if (sprite.y >= height - sprite.height - duke.height) {
velocity = 0;
gameover = true;
}
}
}
if (gameover) {
context.setFillStyle("#ff0000");
context.setFont("40px Calibri");
context.fillText("Game over!", (width / 2) - 50, height / 2);
}
for (Sprite sprite : sprites) {
sprite.render(context, 1, 1);
}
for (Sprite sprite : enemySprites) {
sprite.render(context, 1, 1);
}
context.setFillStyle("#ffffff");
context.setFont("12px Calibri");
context.fillText("Score: " + score, width - 60, 10);
animate = false;
if (gameover) {
t.close();
}
if (enemySprites.isEmpty()) {
levelup(m);
}
}

private boolean collision(Sprite sprite, Sprite bullet) {
return isCollision(sprite.getX(), sprite.getY(), sprite.width, sprite.height, bullet.x, bullet.y, bullet.width, bullet.height);
}

boolean isCollision(double x0, double y0, double w0, double h0, double x2, double y2, double w1, double h1) {
double x1 = x0 + w0;
double y1 = y0 + h0;

double x3 = x2 + w1;
double y3 = y2 + h1;

return !(x1 < x2 || x3 < x0 || y1 < y2 || y3 < y0);
}
}
}

Das ist alles. 200 Zeilen reiner Java code. Und zwar nicht nach JavaScript kompiliert, sonder schön verpackt als JAR file und von einer JVM geladen. Der einzige Unterschied ist, dass die JVM selbst in JavaScript geschrieben ist. Cool? Dann schaut mal rein bei bck2brwsr, und kommt zum JayDay um mehr zu lernen über “Duke’s Revenge”.

Hinterlasse eine Antwort

Deine E-Mail-Adresse wird nicht veröffentlicht. Erforderliche Felder sind markiert *

Du kannst folgende HTML-Tags benutzen: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <strike> <strong>