Closed SJMakin closed 8 years ago
Looking at Main_Out.js it looks like it should just be a case of wrapping the registerEvent function for split/shoot. Not sure about moving though.
You can split and shoot mass even without expose, by sending fake space
and W
key events. See minimal example for split:
window.onkeydown({
keyCode: 32, // space
target: document.getElementById("canvas"),
preventDefault:() => undefined,
})
However, moving using sending mouse events to canvas is inconvenient: you have to translate move destination world coordinates to canvas pixel coordinates. So, most likely, I will add functions/hooks to control cell movement.
That would be most excellent. Thanks.
I have succesfully used the $(window).mousemove() to control cell movement. To convert to canvas coordinates, all I did was add half the window dimensions so the origin of the mouse was in the center of the window. This works perfectly if you are only a single cell, however if you are split, I think the center may be a bit off. This method seems good enough at least until the movement hooks are added. I can try to find an example of the code if you are interested.
If you can provide a simple example of moving to the nearest cell or even '0,0', using the window.agar information, that would be splendid.
Unfortunately agar is down right now and I don't currently have access to the original code so I am not entirely sure whether or not this will work. Either way this is essentially it
Using JQuery:
function moveCell(x,y){
$(window).trigger('mousemove', {
clientX: x + $(window).width()/2,
clientY: y + $(window).height()/2
});
}
Pure JS:
function moveCell(x,y){
window.onmousemove({
clientX: x + window.innerWidth/2,
clientY: y + window.innerHeight/2
});
}
moveCell(0, -10) = Up moveCell(10, 0) = Right
Whoops, Agar is back up and I tested it. Turns out I needed to use canvas instead of window.
I'm going to have to mess around with this a bit more but for now it is in world coordinates so moveCell(0,0) brings you to the center of the map.
function moveCell(x,y){
$('canvas').trigger('mousemove', {
clientX: x + $('canvas').width()/2,
clientY: y + $('canvas').height()/2
});
}
Try it again but change my function to
function moveCell(x,y){
$('canvas').trigger('mousemove', {
clientX: x,
clientY: y
});
Oh BTW, you can use the for-of loop instead of for-in. Its not necessary but I thought it was a pretty cool function when I found out about it. Plus it saves a line of code
for (var cell of window.agar.allCells) {
var cell = window.agar.allCells[c];
You can transtate coordinates using toPixelCoords
function. I don't have
access to PC right now, so it is untested.
var transform = {scale:1, x:0, y:0}
agar.hooks.beforeTransform = (ctx, t1x, t1y, s, t2x, t2y) => {
transform = {scale:s, x:t2x*s + t1x, y:t2y*s + t1y}
}
function toWorldCoords(pixelCoords) {
var x = (pixelCoords.x - transform.x) / transform.scale
var y = (pixelCoords.y - transform.y) / transform.scale
return {x, y}
}
function toPixelCoords(worldCoords) {
var x = worldCoords.x*transform.scale + transform.x
var x = worldCoords.y*transform.scale + transform.y
return {x, y}
}
OK - I believe those conversion methods work a charm, but I am still not able to correctly move the players cell to the food. I added a method to draw a line between the player and and nearest food, and that looks great (when it displays - i should really use the drawing hooks I know) but the cell goes off in another direction entirely. I have tried both of the movement functions above and neither seems to work.
I tried for .. of but it didnt seem to work. Good to know about though :)
I am probably missing something silly. Any issues/questions please let me know.
// ==UserScript==
// @name SJMBot
// @namespace SJMBot
// @include http://agar.io/*
// @include https://agar.io/*
// @version 0.01
// @grant none
// @author SJMakin@Github
// ==/UserScript==
//Sample code
image = new Image();
image.crossOrigin = 'anonymous';
image.src = 'http://i.imgur.com/V8EOXwT.png';
window.agar.hooks.cellSkin = function(cell, old_skin) {
if (old_skin) return old_skin;
if (cell.isVirus) return image;
return null;
}
console.log('Loaded Virus Image Switch');
//START - Helper methods
function computeDistance(x1, y1, x2, y2, s1, s2) {
s1 = s1 || 0;
s2 = s2 || 0;
var xdis = x1 - x2;
var ydis = y1 - y2;
var distance = Math.sqrt(xdis * xdis + ydis * ydis) - (s1 + s2);
return distance;
}
function isMe(cell){
for (var i = 0; i < window.agar.myCells.length; i++){
if (window.agar.myCells[i] == cell.id){
return true;
}
}
return false;
}
var transform = {scale:1, x:0, y:0}
window.agar.hooks.beforeTransform = (ctx, t1x, t1y, s, t2x, t2y) => { transform = {scale:s, x:t2x*s + t1x, y:t2y*s + t1y} }
function toWorldCoords(pixelCoords) {
var x = (pixelCoords.x - transform.x) / transform.scale;
var y = (pixelCoords.y - transform.y) / transform.scale;
console.log('PC x: ' + pixelCoords.x + ' PC y: ' + pixelCoords.y + ' WC x ' + x + ' WC y ' + y)
return [x, y]
}
function toPixelCoords(worldCoords) {
var x = worldCoords.x*transform.scale + transform.x;
var y = worldCoords.y*transform.scale + transform.y;
console.log('WC x: ' + worldCoords.x + ' WC y: ' + worldCoords.y + ' PC x ' + x + ' PC y ' + y);
return [x, y]
}
function moveCell(x,y){
$('canvas').trigger('mousemove', {
clientX : x + $('canvas').width()/2,
clientY : y + $('canvas').height()/2
});
console.log('Moving cell - x:' + x + ' y: ' + y);
}
function moveCell2(x,y){
$('canvas').trigger('mousemove', {
clientX: x,
clientY: y
});
console.log('Moving cell 2 - x:' + x + ' y: ' + y);
}
function drawLine(startX, startY, endX, endY){
var canvas = document.getElementById("canvas");
var context = canvas.getContext('2d');
context.beginPath();
context.moveTo(startX, startY);
context.lineTo(endX, endY);
context.lineWidth = 4;
context.stroke();
console.log('Line drawn');
return true;
}
//END - Helper methods
//START - UI Customisation
window.agar.minScale = 0.5;
window.agar.drawGrid = false;
//END - UI Customisation
//START - Bot control
function processGameState(){
//console.debug("SJMBot processGameState");
var food = [];
var virus = [];
var me = [];
var other = [];
//console.dir(window.agar.allCells);
for (var key in window.agar.allCells){
var cell = window.agar.allCells[key];
//console.log(cell.id);
if (isMe(cell)){
me.push(cell);
} else if (cell.size < 15) {
food.push(cell);
} else if (cell.isVirus){
virus.push(cell);
} else {
//Its not me, a virus or food, so it is another player
other.push(cell);
}
}
//console.log(me.length);
if (me.length > 0 && food.length > 0){
var closest = 99999999;
var target = {};
for (var z = 0; z < food.length; z++){
var dist = computeDistance(me[0].x, me[0].y, food[z].x, food[z].y);
if (dist < closest){
closest = dist;
target = food[z];
}
}
//console.dir(me);
//console.dir(food);
var position = toPixelCoords(target);
moveCell(position[0], position[1]);
var myPosition = toPixelCoords(me[0]);
drawLine (myPosition[0], myPosition[1], position[0], position[1]);
}
}
setInterval(processGameState, 30);
//END - Bot control
console.log("SJMBot loaded");
Replacing moveCell
with
function moveCell(x,y){
document.getElementById('canvas').onmousemove({clientX:x, clientY:y})
}
works for me. I'm not into jQuery and can't say why $('canvas').trigger('mousemove', ...
does not work.
Whey :+1: that works great! Thanks xzfc, you are a star!
Feel free to close this now, but it may still be worth considering adding a hook and/or documenting this for reference. Thanks again.
Really like this project.
Would be even better if the API exposed cell controls, such as move/split/shoot mass.
I have no idea if this is viable (or already possible!) but if it could be included in a future release I would be extremely grateful.