ソースを参照

lots of game-y game.

master
mort 8年前
コミット
2ef9d0e8d9
6個のファイルの変更283行の追加2行の削除
  1. 1
    1
      Makefile
  2. 216
    0
      es/game.js
  3. 7
    0
      es/script.js
  4. 49
    0
      index.html
  5. 0
    1
      js/script.js
  6. 10
    0
      js/view.js

+ 1
- 1
Makefile ファイルの表示

@@ -1,2 +1,2 @@
build:
browserify -t babelify --outfile bundle.js js/*.js
browserify -t babelify --outfile bundle.js es/*.js

+ 216
- 0
es/game.js ファイルの表示

@@ -0,0 +1,216 @@
function randint(min, max) {
return Math.floor(Math.random() * (max - min + 1)) + min;
}

function background(ctx, camera) {
if (!background.cache) {
let cache = [];
for (let i = 0; i < window.innerWidth; ++i) {
cache.push({
x: randint(0, window.innerWidth * 5),
y: randint(0, window.innerHeight * 5)
});
}
background.cache = cache;
}

let cx = camera.x;
let cy = camera.y;
let cache = background.cache;

let fs = ctx.fillStyle;
ctx.fillStyle = "#FFFFFF";
for (let i = 0, len = cache.length; i < len; ++i) {
let p = cache[i];
ctx.beginPath();
let x = Math.floor(((p.x - cx) / 5) % window.innerWidth);
let y = Math.floor(((p.y - cy) / 5) % window.innerHeight);
ctx.arc(x, y, 1, 0, 2*Math.PI);
ctx.closePath();
ctx.fill();
}
ctx.fillStyle = fs;
}

class Entity {
constructor(x, y, width, height, id) {
this.pos = {x: x, y: y};
this.vel = {x: 0, y: 0};
this.width = width;
this.height = height;

this.id = id;
}

draw(ctx) {}

set(obj) {
this.pos = obj.pos;
this.vel = obj.vel;
}

update(dt) {
this.pos.x += this.vel.x * dt;
this.pos.y += this.vel.y * dt;
}
}

class Bullet extends Entity {
constructor(x, y, vel, id, ownerId) {
super(x, y, 5, 5, id);
this.vel = vel;
this.ownerId = ownerId;
}

draw(ctx, selfId) {
if (selfId == this.ownerId) {
ctx.fillStyle = "#FFFFFF";
} else {
ctx.fillStyle = "#FF0000";
}

ctx.beginPath();
ctx.arc(-(this.width/2), -(this.height/2), this.width/2, 0, 2*Math.PI);
ctx.closePath();
ctx.fill();
}

set(obj) {
super.set(obj);
}
}

class Player extends Entity {
constructor(x, y, id, rot) {
super(x, y, 25, 60, id);
this.rot = rot;
this.rotVel = 0;
}

draw(ctx, selfId) {
if (selfId == this.id) {
ctx.fillStyle = "#FFFFFF";
} else {
ctx.fillStyle = "#FF0000";
}

ctx.rotate(this.rot);
ctx.beginPath();
ctx.moveTo(0, -(this.height/2));
ctx.lineTo(-this.width, this.height/2);
ctx.lineTo(this.width, this.height/2);
ctx.closePath();
ctx.fill();
}

set(obj) {
super.set(obj);
this.rot = obj.rot;
this.rotVel = obj.rotVel;
}

update(dt) {
super.update(dt);
this.rot += this.rotVel * dt;
}
}

function createEntity(obj) {
if (obj.type == "player") {
return new Player(obj.pos.x, obj.pos.y, obj.id, obj.rot);
} else if (obj.type == "bullet") {
return new Bullet(obj.pos.x, obj.pos.y, obj.vel, obj.id, obj.ownerId);
} else {
throw new Error("Unknown entity type: "+obj.type);
}
}

export default class Game {
constructor(sock, canvas) {
this.sock = sock;
this.canvas = canvas;
this.ctx = canvas.getContext("2d");
this.id = null;
this.camera = {x: 0, y: 0};
this.raf = null;
this.prevTime = new Date().getTime();
this.player = null;

this.keymap = [];
this.keymap[40] = "down";
this.keymap[38] = "up";
this.keymap[37] = "left";
this.keymap[39] = "right";
this.keymap[32] = "shoot";

this.entities = [];

sock.on("ready", () => {
sock.send("get_id", {}, (err, res) => {
this.id = res.id;
});
});

sock.on("set", (msg) => {
console.log(msg);
if (!this.entities[msg.id])
this.entities[msg.id] = createEntity(msg);
else
this.entities[msg.id].set(msg);
});

sock.on("despawn", (msg) => {
delete this.entities[msg.id];
});

window.addEventListener("keydown", (evt) => {
if (this.keymap[evt.keyCode]) {
evt.preventDefault();
this.sock.send("keydown", {
key: this.keymap[evt.keyCode]
});
}
});

window.addEventListener("keyup", (evt) => {
if (this.keymap[evt.keyCode]) {
this.sock.send("keyup", {
key: this.keymap[evt.keyCode]
});
}
});

this.update();
}

update() {
let dt = new Date().getTime() - this.prevTime;
this.prevTime = new Date().getTime();

this.canvas.width = window.innerWidth;
this.canvas.height = window.innerHeight;

background(this.ctx, this.camera);

let player = this.entities[this.id];
if (player) {
this.camera = {
x: player.pos.x - (window.innerWidth / 2),
y: player.pos.y - (window.innerHeight / 2)
};
}

this.ctx.translate(-this.camera.x, -this.camera.y);
this.entities.forEach((ent) => {
this.ctx.save();
this.ctx.translate(ent.pos.x, ent.pos.y);
ent.draw(this.ctx, this.id);
this.ctx.restore();

ent.update(dt);
});
this.ctx.translate(this.camera.x, this.camera.y);

this.raf = window.requestAnimationFrame(this.update.bind(this));
}
}

+ 7
- 0
es/script.js ファイルの表示

@@ -0,0 +1,7 @@
let Game = require("./game.js");

document.querySelector("#startGameBtn").addEventListener("click", () => {
view("game");
let sock = new SockSugar("ws://localhost:8081");
let game = new Game(sock, document.getElementById("canvas"));
});

+ 49
- 0
index.html ファイルの表示

@@ -1,10 +1,59 @@
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width">
<title>GameJam Game</title>

<style>
body {
margin: 0px;
padding: 0px;
background-color: #000;
color: #ccc;
overflow: hidden;
}
.view {
display: none;
}
.view.current {
display: block;
width: 100%;
height: 100%;
}

.view.pre.current {
max-width: 900px;
margin: auto;
}

x-script {
display: none;
}
</style>
</head>
<body>
<div class="view pre">
<p>Umbreosyl. Once a peaceful paradise, your home planet is now shredded by the mighty blow of The Deathers and their powerful Death Moon.</p>

<p>Umbreosylians are a fickle race. At the first sign of danger, of course, everyone you knew flew away to migrate to a safe place. Except you. You overslept, missed the ships, and are now abandoned.</p>

<p>You barely managed to enter your ship, lift off, and get to a somewhat safe distance from the planet, before The Deathers destroyed Umbreosyl. You're currently sitting in your space ship, blood boiling, watching the debris from your beloved home planet encounter you from behind, and ships from The Deathers from ahead.</p>

<button id="startGameBtn">Start</button>
</div>

<div class="view game">
<canvas id="canvas">Your browser is bad and you should feel bad.</canvas>
</div>

<script src="js/view.js"></script>
<script src="node_modules/socksugar/client.js"></script>
<script src="bundle.js"></script>

<script>
view("pre");

</script>
</body>
</html>

+ 0
- 1
js/script.js ファイルの表示

@@ -1 +0,0 @@
window.sock = new SockSugar("ws://localhost:8081");

+ 10
- 0
js/view.js ファイルの表示

@@ -0,0 +1,10 @@
window.view = function(name) {
var current = document.querySelector(".view.current");
var newElem = document.querySelector(".view."+name);

if (current)
current.className = current.className.replace(" current", "");

if (newElem.className.indexOf(" current") === -1)
newElem.className += " current";
};

読み込み中…
キャンセル
保存