Skip to content

Instantly share code, notes, and snippets.

@Johnicholas
Created August 5, 2017 18:52
Show Gist options
  • Save Johnicholas/c759a4bdee8ecd15bcc9041c56ff3eaf to your computer and use it in GitHub Desktop.
Save Johnicholas/c759a4bdee8ecd15bcc9041c56ff3eaf to your computer and use it in GitHub Desktop.
Example of simple AI
// utility functions
function dist(a, b) {
let dx = a.x - b.x;
let dy = a.y - b.y;
return Math.sqrt(dx * dx + dy * dy);
}
// GLOBALS GLOBALS GLOBALS
var canvas = document.getElementById("myCanvas");
var ctx = canvas.getContext("2d");
var keys = [];
let ENEMY_SPEED = 150; // pixels per second
let PLAYER_SPEED = 150; // pixels per second
// the enemy's reaction speed in ms
let REACTION_TIME = 50;
// the enemy's averag dwell time while browsing, in ms
let BROWSING_DWELL = 500;
var player = { x: 0, y: 0 };
var enemy = { x: 100, y: 100 };
var target = { x: 100, y: 100 };
var nest = { x: canvas.width * 0.8, y: canvas.height * 0.2 };
// update the player's position, 8-way movement at PLAYER_SPEED
function update_player(dt) {
var distance = (PLAYER_SPEED / 1000) * dt;
let dx = 0
let dy = 0
if (keys[39] || keys[68]) {
dx += distance;
}
if (keys[37] || keys[65]) {
dx -= distance;
}
if (keys[38] || keys[87]) {
dy -= distance;
}
if (keys[40] || keys[83]) {
dy += distance;
}
player.x += dx;
player.y += dy;
}
// update the target's position
function update_target(dt) {
if (Math.random() < (dt / REACTION_TIME)) {
if (dist(player, enemy) > 200) {
enemy.text = 'player far';
if (Math.random() < (dt / BROWSING_DWELL)) {
target.x = Math.random() * canvas.width;
target.y = Math.random() * canvas.height;
}
for (var i = 0; i < 100; i++) {
if (dist(enemy, target) < 200 && dist(target, nest) < 200) {
break;
}
target.x = Math.random() * canvas.width;
target.y = Math.random() * canvas.height;
}
} else {
enemy.text = 'player near';
// player is near, flee to somewhere further away from player
for (var i = 0; i < 100; i++) {
if (dist(player, target) > 200 && dist(player, target) > dist(enemy, target)) {
// acceptable
break;
}
target.x = Math.random() * canvas.width;
target.y = Math.random() * canvas.height;
}
}
}
}
// update the enemy's position, 8-way movement toward target at ENEMY_SPEED
function update_enemy(dt) {
// update the enemy's position, 8-way movement at ENEMY_SPEED
var distance = (ENEMY_SPEED / 1000) * dt;
if (Math.abs(enemy.x - target.x) < distance) {
enemy.x = target.x;
} else {
enemy.x += distance * Math.sign(target.x - enemy.x);
}
if (Math.abs(enemy.y - target.y) < distance) {
enemy.y = target.y;
} else {
enemy.y += distance * Math.sign(target.y - enemy.y);
}
}
function update(dt) {
update_player(dt);
update_target(dt);
update_enemy(dt);
}
function draw() {
// clear the canvas to black
ctx.beginPath();
ctx.rect(0, 0, canvas.width, canvas.height);
ctx.fillStyle = "black";
ctx.fill();
// draw the player (a blue rectangle)
ctx.beginPath();
ctx.rect(player.x, player.y, 50, 50);
ctx.fillStyle = "blue";
ctx.fill();
// draw the enemy's nest
ctx.beginPath();
ctx.rect(nest.x, nest.y, 50, 50);
ctx.fillStyle = "green";
ctx.fill();
// draw the enemy (a red rectangle)
ctx.beginPath();
ctx.rect(enemy.x, enemy.y, 50, 50);
ctx.fillStyle = "red"
ctx.fill();
// draw the enemy's mind state as text
if (enemy.text) {
ctx.font = "30px Arial";
ctx.fillStyle = "white";
ctx.fillText(enemy.text, enemy.x, enemy.y + 50);
}
}
// at the top level, the game state sees these events
// the game starts (start playing the attract mode / splash)
// the player starts playing
// the player finishes a play session, win or lose
var previous_timestamp = null;
function frame(timestamp) {
if (previous_timestamp) {
let dt = (timestamp - previous_timestamp);
update(dt);
}
previous_timestamp = timestamp;
draw();
requestAnimationFrame(frame);
};
requestAnimationFrame(frame);
document.body.addEventListener("keydown", function (e) {
if (e.keyCode == 39
|| e.keyCode == 68
|| e.keyCode == 37
|| e.keyCode == 65
|| e.keyCode == 38
|| e.keyCode == 87
|| e.keyCode == 40
|| e.keyCode == 83
|| e.keyCode == 32) {
e.preventDefault();
keys[e.keyCode] = true;
//if (e.keyCode == 32) {
// currentState.action();
//}
}
});
document.body.addEventListener("keyup", function (e) {
keys[e.keyCode] = false;
});
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment